feat: resync from upstream oh-my-opencode v3.14.0 (3185 commits)#1
feat: resync from upstream oh-my-opencode v3.14.0 (3185 commits)#1frankxai wants to merge 3188 commits into
Conversation
- Check disabled_tools for 'question' in tool-config-handler permission logic - Strip Question tool code examples from Prometheus prompts when disabled - Pass disabled_tools through prometheus agent config builder pipeline - Add tests for disabled_tools question permission handling
fix: validate serverUrl port before tmux pane spawn (fixes #2729)
fix: clarify Prometheus file permission error message (fixes #2150)
fix: respect OPENCODE_DISABLE_CLAUDE_CODE env vars (fixes #2037)
fix: add oh-my-openagent.jsonc config file detection (fixes #2624)
fix: skip keyword injection for non-OMO agents (fixes #2024)
fix: trigger compaction before continue after session error recovery (fixes #390)
fix: respect disabled_tools config in agent prompts (fixes #2742)
fix: emit formatter events from hashline-edit tool (fixes #2117)
The first test case 'non-TUI mode: should show warning but continue when OpenCode binary not found' was missing a globalThis.fetch mock, causing it to make a real HTTP request to npm registry via fetchNpmDistTags(). The npm fetch timeout (5s) collided with the test timeout (5s), causing flaky CI failures. Added the same fetch mock pattern already used by the other two test cases. Test runtime dropped from 5000ms+ to ~2ms.
…zy validation (fixes #2740)
…ncellation messages (fixes #2684)
Tests 'should use default timeout when config not provided' (manager.test.ts) and 'should use DEFAULT_MESSAGE_STALENESS_TIMEOUT_MS when not configured' (task-poller.test.ts) failed in CI because Date.now() drifted between test setup (when creating timestamps like Date.now() - 46*60*1000) and actual execution inside checkAndInterruptStaleTasks(). On slower CI machines, this drift pushed borderline values across the threshold, causing tasks that should be stale to remain 'running'. Fix: Mock Date.now with spyOn to return a fixed time, ensuring consistent timeout calculations regardless of execution speed.
fix: add fetch mock to install test to prevent CI timeout
…ut-defaults fix: stabilize background-agent stale timeout tests (Date.now race condition)
… deep task refusal - #2741: Pass inheritedModel as fallback in subagent-resolver when user hasn't configured an override, ensuring custom provider models take priority - #2648: Fix getPlanProgress to treat plans with 0 checkboxes as incomplete instead of complete (total > 0 && completed === total) - #2779: Relax Hephaestus single-task guard to accept multi-step sub-tasks from Atlas delegation, only rejecting genuinely independent tasks Fixes #2741, fixes #2648, fixes #2779
- Remove leading pipe characters (|) from duplicated CORRECT block - Remove duplicated ## Hard Constraints and ### Task Scope Clarification sections - Properly place Task Scope Clarification section between CORRECT list and Hard Constraints Addresses review comments by cubic-dev-ai[bot] on PR #2780
Same issue as gpt.ts and gpt-5-4.ts: duplicated CORRECT block with pipe characters and duplicated Hard Constraints/Task Scope Clarification sections.
Models frequently hallucinate a 'directory' parameter alongside filePath, causing hard failures. Instead of rejecting, accept directory as an alias for filePath and gracefully handle when both are provided (prefer filePath). This prevents the 'filePath and directory are mutually exclusive' error that users hit when models pass both parameters. Fixes model confusion with lsp_diagnostics tool parameters.
- Document object-style fallback_models with per-model settings - Add model-settings compatibility normalization docs - Document file:// URI support for prompt and prompt_append - Add deterministic core-agent order (Tab cycling) docs - Update rename compatibility notes (legacy plugin warning) - Document doctor legacy package name detection - Add models.dev-backed capability cache documentation - Update Hephaestus default to gpt-5.4 (medium) - Correct MiniMax M2.7/M2.5 usage across all docs - Update all agent/category provider chain tables - Fix stale CLI install/doctor options to match source - Add refresh-model-capabilities command to CLI reference Co-authored-by: Sisyphus <sisyphus@oh-my-opencode>
- fix(context-limit): check modelContextLimitsCache for all Anthropic models, not just GA-model set; user config/cache wins over 200K default (fixes #2836) - fix(agent-key-remapper): preserve config key aliases alongside display names so `opencode run --agent sisyphus` resolves correctly (fixes #2858) - fix(tool-config): respect host permission.skill=deny by disabling skill/skill_mcp tools when host denies them (fixes #2873) - test: update context-limit and agent-key-remapper tests to match new behavior
…ubagents - fix(switcher): use lastIndexOf for multi-slash model IDs (e.g. aws/anthropic/claude-sonnet-4) - fix(model-resolution): same lastIndexOf fix in doctor parseProviderModel - fix(call-omo-agent): resolve model from agent config and forward to both background and sync executors via DelegatedModelConfig - fix(subagent-resolver): inherit category model/variant when agent uses category reference without explicit model override - test: add model override forwarding tests for call-omo-agent - test: add multi-slash model ID test for switcher
…moval When .sisyphus/ is gitignored, task state written during worktree execution is lost when the worktree is removed. Fix: - add worktree-sync.ts: syncSisyphusStateFromWorktree() copies .sisyphus/ contents from worktree to main repo directory - update start-work.ts template: documents the sync step as CRITICAL when worktree_path is set in boulder.json - update work-with-pr/SKILL.md: adds explicit sync step before worktree removal - export from boulder-state index - test: 5 scenarios covering no-.sisyphus, nested dirs, overwrite stale state
…rocess The server-health module used module-level state for inProcessServerRunning, which doesn't survive when Bun loads separate module instances in the same process. Fix: use globalThis with Symbol.for key so the flag is truly process-global. - server-health.ts: replace module-level boolean with globalThis[Symbol.for()] - export markServerRunningInProcess from tmux-utils barrel - test: verify flag skips HTTP fetch, verify globalThis persistence
…re try lastCompactionTime was only set on successful compaction. When compaction failed (rate limit, timeout, etc.), no cooldown was recorded, causing immediate retries in an infinite loop. Fix: set lastCompactionTime before the try block so both success and failure respect the cooldown window. - test: add failed-compaction cooldown enforcement test - test: fix timeout retry test to advance past cooldown
Background subagents (explore/librarian) failed with auth errors because resolveModelForDelegateTask() always picked the first fallback entry when availableModels was empty — often an unauthenticated provider like xai or opencode-go. Fix: when connectedProvidersCache is populated, iterate fallback chain and pick the first entry whose provider is in the connected set. Legacy behavior preserved when cache is null (not yet populated). - model-selection.ts: use readConnectedProvidersCache to filter fallback chain - test: 4 new tests for connected-provider-aware resolution
Two issues fixed: 1. process-cleanup.ts used fire-and-forget void Promise for shutdown handlers — now properly collects and awaits all cleanup promises via Promise.allSettled, with dedup guard to prevent double cleanup 2. TmuxSessionManager was never registered for process cleanup — now registered in create-managers.ts via registerManagerForCleanup Also fixed setTimeout().unref() which could let the process exit before cleanup completes.
- logLegacyPluginStartupWarning now emits console.warn (visible to user, not just log file) when oh-my-opencode is detected in opencode.json - Auto-migrates opencode.json plugin entry from oh-my-opencode to oh-my-openagent (with backup) - plugin-config.ts: add console.warn when loading legacy config filename - test: 10 tests covering migration, console output, edge cases
When a subagent session disappears from the status registry (process crashed), the main agent was waiting the full stale timeout before acting. Fix: - Add sessionGoneTimeoutMs config option (default 60s, vs 30min normal) - task-poller: use shorter timeout when session is gone from status - manager: verify session existence when gone, fail crashed tasks immediately with descriptive error - Add legacy-plugin-toast hook for #2823 migration warnings - Update schema with new config option
- completedTaskSummaries now includes status and error info - notifyParentSession: noReply=false for failed tasks so parent reacts - Batch notification distinguishes successful vs failed/cancelled tasks - notification-template updated to show task errors - task-poller: session-gone tests (85 new lines) - CI: add Bun shim to PATH for legacy plugin migration tests
…ault model subagent-resolver: when falling back to matchedAgent.model for custom subagents, verify the model is actually available via fuzzyMatchModel before setting it as categoryModel. Prevents delegate_task from using an unavailable model when the user's custom agent config references a model they don't have access to. Test updated to include the target model in available models mock.
…untime TTL (pruneStaleTasksAndNotifications) now resets on last activity: - Uses task.progress.lastUpdate as TTL anchor for running tasks (was always using startedAt, causing 30-min hard deadline) - Added taskTtlMs config option for user-adjustable TTL - Error message shows actual TTL duration, not hardcoded '30 minutes' - 3 new tests for the new behavior
…kill paths resolveSkillPathReferences: add looksLikeFilePath() guard that requires a file extension or trailing slash before resolving @scope/package references. npm packages like @mycom/my_mcp_tools@beta were incorrectly being rewritten to absolute paths in skill templates. 2 new tests.
task_system now defaults to true instead of false. Users on opencode-go or other plans were unable to invoke oracle or use subagent delegation because experimental.task_system defaulted off. The task system is the primary mechanism for oracle, explore, and other subagent invocations — it should not be behind an experimental flag. Users can still explicitly set experimental.task_system: false to opt out.
The skill tool previously only merged disk-discovered skills and preloaded options.skills, so skills registered natively via ctx.skills (for example from config.skills.paths or other plugins) were prompt-visible but not discoverable by skill(). Fix: - pass ctx.skills from tool-registry into createSkillTool - extend SkillLoadOptions with nativeSkills accessor - merge nativeSkills.all() results into getSkills() - add test covering native PluginInput skill discovery
skill-context already filtered browser-related skills using the configured browser provider, but the skill tool rebuilt discovery without forwarding browserProvider. That caused skills like agent-browser to be prompt-visible while skill() could still fail to resolve them unless browser_automation_engine.provider was explicitly threaded through both paths. Fix: - pass skillContext.browserProvider from tool-registry into createSkillTool - extend SkillLoadOptions with browserProvider - forward browserProvider to getAllSkills() - add regression tests for execution and description visibility
The installer wrapper and postinstall script still hardcoded the old oh-my-opencode-* platform package family. When users installed the renamed npm package oh-my-openagent (for example via npx oh-my-openagent install on WSL2/Linux), the main package installed correctly but the wrapper looked for nonexistent optional binaries like oh-my-opencode-linux-x64. Fix: - derive packageBaseName from package.json at runtime in wrapper/postinstall - thread packageBaseName through platform package candidate resolution - keep legacy oh-my-opencode default as fallback - add regression test for renamed package family
…solation Verified: bun test src/plugin/event.test.ts src/hooks/runtime-fallback/index.test.ts -- 68/68 pass. tsc clean.
Merge 3185 upstream commits from code-yeongyu/oh-my-opencode dev branch. Accept upstream structural refactors while preserving Arcanea branding in package.json. Arcanea agent overlay files preserved in src/agents/arcanea/. Resolved conflicts: - package.json: keep Arcanea name/URLs, accept upstream deps/version - src/agents/: accept upstream restructure (utils.ts deleted, builtin-agents.ts added) - src/config/schema.ts: accept modular schema/ directory restructure - src/shared/config-path.ts: removed (upstream deleted, functionality moved) - src/tools/lsp/utils.ts: removed (upstream deleted, functionality split) Co-Authored-By: claude-flow <ruv@ruv.net>
|
Thank you for your contribution! Before we can merge this PR, we need you to sign our Contributor License Agreement (CLA). To sign the CLA, please comment on this PR with: This is a one-time requirement. Once signed, all your future contributions will be automatically accepted. I have read the CLA Document and I hereby sign the CLA 2 out of 3 committers have signed the CLA. |
There was a problem hiding this comment.
Code Review
This pull request introduces significant updates to the project, including a rename from oh-my-opencode to oh-my-openagent, the addition of a new arXiv MCP, and the implementation of a pre-publish review system. My feedback highlights a potential data loss issue in the gh_fetch.py pagination logic and suggests reverting the repository URL change in CONTRIBUTING.md until the rename is fully consistent across the entire repository to avoid confusion.
| """Fetch ALL items with exhaustive pagination.""" | ||
| all_items: list[dict] = [] | ||
| page = 1 | ||
|
|
||
| progress.update(task_id, description=f"[cyan]Fetching {item_type}s page {page}...") | ||
| items = await fetch_items_page(repo, item_type, state, BATCH_SIZE) | ||
| fetched_count = len(items) | ||
| all_items.extend(items) | ||
|
|
||
| console.print(f"[dim]Page {page}: fetched {fetched_count} {item_type}s[/dim]") | ||
|
|
||
| while fetched_count == BATCH_SIZE: | ||
| page += 1 | ||
| progress.update( | ||
| task_id, description=f"[cyan]Fetching {item_type}s page {page}..." | ||
| ) | ||
|
|
||
| last_created = all_items[-1].get("createdAt", "") | ||
| if not last_created: | ||
| break | ||
|
|
||
| search_filter = f"created:<{last_created}" | ||
| items = await fetch_items_page( | ||
| repo, item_type, state, BATCH_SIZE, search_filter | ||
| ) | ||
| fetched_count = len(items) | ||
|
|
||
| if fetched_count == 0: | ||
| break | ||
|
|
||
| existing_numbers = {item["number"] for item in all_items} | ||
| new_items = [item for item in items if item["number"] not in existing_numbers] | ||
| all_items.extend(new_items) | ||
|
|
||
| console.print( | ||
| f"[dim]Page {page}: fetched {fetched_count}, added {len(new_items)} new (total: {len(all_items)})[/dim]" | ||
| ) | ||
|
|
||
| if page > 20: | ||
| console.print("[yellow]Safety limit reached (20 pages)[/yellow]") | ||
| break | ||
|
|
||
| if hours is not None: | ||
| cutoff = datetime.now(UTC) - timedelta(hours=hours) | ||
| cutoff_str = cutoff.isoformat() | ||
|
|
||
| original_count = len(all_items) | ||
| all_items = [ | ||
| item | ||
| for item in all_items | ||
| if item.get("createdAt", "") >= cutoff_str | ||
| or item.get("updatedAt", "") >= cutoff_str | ||
| ] | ||
| filtered_count = original_count - len(all_items) | ||
| if filtered_count > 0: | ||
| console.print( | ||
| f"[dim]Filtered out {filtered_count} items older than {hours} hours[/dim]" | ||
| ) | ||
|
|
||
| return all_items |
There was a problem hiding this comment.
The pagination logic in fetch_all_items relies on filtering by created:<{last_created}, which is not a reliable method for exhaustive pagination. If multiple items share the same creation timestamp at a page boundary, some items may be missed. This could lead to incomplete triage results.
For more robust pagination, consider using cursor-based pagination via the gh api command with the --paginate flag. This is the recommended approach for iterating through all items in a list from the GitHub API and will prevent potential data loss.
| git clone https://github.com/code-yeongyu/oh-my-openagent.git | ||
| cd oh-my-openagent |
There was a problem hiding this comment.
The repository URL in the clone command has been updated to oh-my-openagent, but other parts of the project, including the PR description and other files, still refer to oh-my-opencode. This inconsistency can be confusing for new contributors. While FIX-BLOCKS.md acknowledges this as a "Package Identity Split-Brain", it would be better to either make the rename consistent throughout this PR or add a note to the PR description clarifying the transition status. To maintain consistency for now, I suggest reverting this change until the rename is complete across the repository.
| git clone https://github.com/code-yeongyu/oh-my-openagent.git | |
| cd oh-my-openagent | |
| git clone https://github.com/code-yeongyu/oh-my-opencode.git | |
| cd oh-my-opencode |
…gents architecture Wire all Arcanea agents (4 dev, 4 creative, 4 writing, 4 research, 1 master orchestrator, 1 orchestrator) into the new BuiltinAgentName type, agentSources registry, and agentMetadata map following the exact upstream factory pattern with static .mode properties. Co-Authored-By: claude-flow <ruv@ruv.net>
|
Important Review skippedToo many files! This PR contains 294 files, which is 144 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (6)
📒 Files selected for processing (294)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c6de52e67c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| log("Running on-complete hook", { command: trimmedCommand }) | ||
|
|
||
| try { | ||
| const proc = spawnWithWindowsHide(["sh", "-c", trimmedCommand], { |
There was a problem hiding this comment.
Use a platform-native shell for on-complete hooks
Hardcoding "sh", "-c" here makes --on-complete unreliable on Windows environments that do not have a POSIX shell installed (common outside Git Bash/MSYS). In that case the hook command fails before execution and is silently downgraded to a log entry, so users do not get their completion automation even though the run itself succeeds.
Useful? React with 👍 / 👎.
| - name: Download artifact | ||
| id: download | ||
| if: steps.check.outputs.skip_all != 'true' | ||
| continue-on-error: true |
There was a problem hiding this comment.
Fail publish job when required artifact download fails
Marking artifact download as continue-on-error: true lets this matrix leg finish successfully even when an artifact is missing or download fails, and the later publish steps are then skipped by steps.download.outcome == 'success'. That can produce a green workflow with one or more platform packages silently unpublished when skip_all is false.
Useful? React with 👍 / 👎.
- Add arcanea-buddy hook (src/hooks/arcanea-buddy/index.ts) - Reads shared buddy state from tmpdir - Injects <arcanea-buddy> context into chat messages - Tracks tool usage → feeds buddy XP - Session lifecycle integration (streak, XP) - Wire buddy hook into create-hooks.ts plugin pipeline - Fix persona.ts pre-existing type error (local PersonaConfig) - Update opencode.json with 7 free Zen models: - mimo-v2-pro-free (build), qwen3.6-plus-free (plan), - minimax-m2.5-free (debug), big-pickle (review), - nemotron-3-super-free (quick) - Add Guardian → model routing for all agents Co-Authored-By: claude-flow <ruv@ruv.net>
Summary
Follow-up needed
Test plan
🤖 Generated with claude-flow