Commit Graph

4270 Commits

Author SHA1 Message Date
YeonGyu-Kim 98659783c0 fix(security): confine file resolution to project roots
Block traversal, out-of-root absolute path, and symlink escapes for @file references, file:// URIs, and config skill file loading while logging rejected attempts.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-02 14:55:35 +09:00
YeonGyu-Kim e8c5727a22 fix(mcp): restrict env var expansion in MCP configs
Block sensitive env var interpolation in MCP config expansion so repo and plugin MCP definitions cannot exfiltrate secrets by default.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-02 14:55:01 +09:00
YeonGyu-Kim 4fe49a6151 fix(skill-mcp-manager): filter merged MCP env before spawn
Apply env filtering after customEnv merge to prevent filtered
variables (API keys, secrets) from being reintroduced through
custom environment configuration.
2026-04-02 14:52:02 +09:00
YeonGyu-Kim b151ebbc17 chore: remove test artifacts from worker run 2026-04-02 13:57:14 +09:00
YeonGyu-Kim 5bf3aa1cfb fix(test): remove mock.module tests that corrupt other test suites
Bun's mock.module() leaks across test files in single-process runs,
causing 357 unrelated test failures. Removing these tests for now.
The code fix is correct and verified manually.
2026-04-02 13:57:05 +09:00
YeonGyu-Kim 5d68de79d0 fix(types): return type RemoteMcpConfig | undefined for createWebsearchConfig 2026-04-02 13:55:21 +09:00
YeonGyu-Kim bc07c21e50 fix(test): rewrite prometheus tests to verify behavior not log messages 2026-04-02 13:54:52 +09:00
YeonGyu-Kim a695730891 fix(mcp): handle missing Tavily API key gracefully
Previously, when websearch was configured with Tavily provider and the
TAVILY_API_KEY environment variable was not set, the entire plugin would
fail to load with no visible error to the user.

Changes:
1. createWebsearchConfig now returns undefined when Tavily key is missing
2. Added warning log: '[websearch] Tavily API key not found, skipping websearch MCP'
3. createBuiltinMcps now skips undefined configs instead of adding them
4. Added tests for both missing and present Tavily API key scenarios

Fixes #2996
2026-04-02 13:32:44 +09:00
YeonGyu-Kim 4c4efc416a fix(grep): enable ripgrep auto-download when not found in PATH
The auto-download mechanism for ripgrep existed but was never called.
When 'rg' wasn't in PATH, the grep tool silently fell back to GNU grep,
which wastes ~10% token budget due to noisy results.

Changes:
1. Wired up resolveGrepCliWithAutoInstall() in the CLI resolution path
2. When 'rg' is not found in PATH, auto-downloads ripgrep v14.1.1
3. Caches the downloaded binary in OpenCode data directory
4. Falls back to GNU grep only if auto-download fails (with warning)

Fixes #3003
2026-04-02 13:32:23 +09:00
YeonGyu-Kim 649a83d046 fix(mcp): user config overrides Claude Code .mcp.json with collision warning
Previously, Claude Code's .mcp.json would silently override OpenCode user
config when MCP server names collided. This was unexpected behavior since
users expect their explicit OpenCode configuration to take precedence.

Changes:
1. Swapped merge order: Claude Code .mcp.json is now merged BEFORE user
   config, so user config wins on collision
2. Added warning log when user config overrides a Claude Code MCP server:
   'warning: MCP server X from user config overrides Claude Code .mcp.json'
3. Added comprehensive tests for collision scenarios

Fixes #2946
2026-04-02 13:32:11 +09:00
YeonGyu-Kim 680bd682c7 fix(prometheus): respect fallback chain when no explicit model configured
Previously, Prometheus always used params.currentModel (UI-selected model)
when no explicit configuration existed. This bypassed the intended fallback
chain (claude-opus-4-6 → gpt-5.4 → glm-5 → gemini-3.1-pro).

Now, the UI-selected model is only used if it matches one of the models
in Prometheus's fallback chain. Otherwise, the fallback chain resolution
takes over and finds an available model.

Fixes #2986
2026-04-02 13:32:00 +09:00
YeonGyu-Kim 2440ed9a6f fix(hook): add tool_use/tool_result pair validator to prevent API errors
Adds a defensive tool-pair-validator hook that runs as the final step in
the messages transform pipeline. When compaction or context-window recovery
removes user messages containing tool_result blocks without removing the
preceding assistant message with tool_use blocks, this validator detects
the mismatch and either:

1. Injects missing tool_result parts into the next user message, or
2. Creates a synthetic user message with placeholder tool_results

This prevents Anthropic API errors like 'tool_use ids found without
tool_result blocks immediately after'.

Fixes #3014
2026-04-02 13:31:48 +09:00
YeonGyu-Kim a637cca702 Merge pull request #3013 from code-yeongyu/fix/issue-2971-skill-shortname
fix(skill): resolve namespaced skills by short name
2026-04-02 10:43:52 +09:00
YeonGyu-Kim 4d751d110b Merge pull request #3012 from code-yeongyu/fix/issue-3010-commands-file
fix(command-discovery): skip non-directory .claude/commands path
2026-04-02 10:43:50 +09:00
YeonGyu-Kim 2275d87a16 fix(skill): resolve namespaced skills by short name
When a skill has a namespaced name like 'superpowers/systematic-debugging',
users see the short name 'systematic-debugging' in the listing but can't
invoke it — the resolver only accepts exact full names.

Add short-name fallback: if exact match fails, try matching the basename
of namespaced skills. Only resolves when unambiguous (single match).

- Exact match still takes priority
- Ambiguous short names (multiple namespaces) fall through to error
- 4 new tests covering all cases

Fixes #2971
2026-04-02 10:40:11 +09:00
YeonGyu-Kim bb85e40a78 fix(command-discovery): skip non-directory .claude/commands path
When .claude/commands exists as a file instead of a directory,
readdirSync throws ENOTDIR and crashes command discovery, stalling
OMO initialization. Add statSync().isDirectory() guard with a
warning log.

Fixes #3010
2026-04-02 10:36:18 +09:00
YeonGyu-Kim 941e265aa1 Merge branch 'fix/p0-2-atomic-migration' into dev 2026-04-01 18:34:05 -07:00
YeonGyu-Kim 9418927162 fix(config): make plugin entry migration atomic with temp-file + rename
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 18:33:29 -07:00
YeonGyu-Kim 5bd0b5fa08 fix(tests): align agent-config test with task_system default revert 2026-04-01 18:26:12 -07:00
YeonGyu-Kim 98c1c72fff Merge branch 'fix/p0-9-remove-ai-slops' into dev 2026-04-01 18:23:18 -07:00
YeonGyu-Kim fa8a9f8669 Merge branch 'fix/p0-7-tmux-cleanup' into dev 2026-04-01 18:23:18 -07:00
YeonGyu-Kim 56cd1edb11 Merge branch 'fix/p0-5-task-system-default' into dev 2026-04-01 18:23:18 -07:00
YeonGyu-Kim 985c72d8d3 Merge branch 'fix/p0-4-omo-agent-variant' into dev 2026-04-01 18:23:18 -07:00
YeonGyu-Kim 842434c81f fix(commands): use dynamic base branch and safe rollback in remove-ai-slops
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 18:21:00 -07:00
YeonGyu-Kim 624a6becc7 fix(config): revert task_system default to false to avoid breaking change 2026-04-01 18:20:05 -07:00
YeonGyu-Kim db23533adf fix(tmux): properly cleanup isolated container pane on first subagent deletion
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 18:18:32 -07:00
YeonGyu-Kim 9c85ef446e fix(call-omo-agent): use variant-aware model parsing for overrides
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 18:17:15 -07:00
YeonGyu-Kim 43023b1eb4 fix(delegate-task): preserve inline variant from category model string
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 18:16:37 -07:00
YeonGyu-Kim 51d9685571 fix(start-work): use Atlas list key in command config 2026-04-01 17:45:16 -07:00
YeonGyu-Kim f4b8e1c365 fix(claude-code-hooks): cache idle hook config and parent lookups
Reduce repeated session.idle work by reusing hook config loads across a short TTL and by retrying parent session lookup instead of permanently caching transient failures.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 17:43:00 -07:00
YeonGyu-Kim 724d21b3cc fix(start-work): restore atlas-first slash discovery
Static slash-command discovery runs before agent registration, so /start-work regressed to Sisyphus even though config-time wiring still needed Atlas-aware fallback. Split builtin command resolution so discovery stays Atlas-first while command config remains availability-aware.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 17:32:46 -07:00
YeonGyu-Kim 1fed569cab fix(ulw-loop): read loop task from user_message
Preserve the actual /ulw-loop task text from the skill tool payload instead of falling back to the default prompt when command arguments are passed separately.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 17:19:45 -07:00
YeonGyu-Kim 8fe057b34a fix(start-work): restore atlas native command routing
Route the builtin /start-work command to Atlas when Atlas is available so OpenCode resolves the native command agent correctly before plugin hooks run.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-01 17:19:37 -07:00
YeonGyu-Kim ea14a1a346 fix(auto-slash-command): resolve project commands from session dir
Use the plugin session directory instead of process.cwd() when resolving project slash commands. This restores project and opencode-project slashcommand behavior when the runtime cwd differs from the actual session workspace.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-31 22:24:54 -07:00
YeonGyu-Kim 7f846b2da3 fix(start-work): restore atlas handoff
Keep native /start-work resolvable on Sisyphus, but switch the work session back to Atlas when Atlas is registered. Stamp the outgoing agent with Atlas's actual list-display key so config→start-work execution resolves correctly and still falls back to Sisyphus when Atlas is unavailable.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-31 22:24:54 -07:00
YeonGyu-Kim 1316a7d8d1 fix(agents): make sisyphus, hephaestus, atlas primary-only (not callable as subagents)
These agents should only be usable as primary session agents, not as
subagent targets via call_omo_agent/task(). Previously MODE was 'all'
which allowed them to be spawned as subagents, leading to confusing
behavior (e.g. Atlas delegating to Hephaestus as a subagent).

Subagent-callable agents remain: oracle, explore, librarian,
multimodal-looker, metis, momus, sisyphus-junior.

Note: Prometheus is not a BuiltinAgentName and is only invoked via
slash commands, so no change needed there.
2026-04-01 14:15:08 +09:00
YeonGyu-Kim a3f9eb1337 fix(start-work): fall back to sisyphus without atlas
/start-work should leave plan mode even when Atlas is unavailable. This prevents Prometheus from being persisted into boulder state and keeping resumed work sessions in md-only mode.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-31 18:52:09 -07:00
YeonGyu-Kim dc1c410405 fix(delegate-task): update test category references from deep to quick
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 18:11:29 -07:00
YeonGyu-Kim 256aaba482 fix(anthropic-recovery): improve executor test coverage and assertions
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 18:11:28 -07:00
YeonGyu-Kim 366ebb33c4 feat(openclaw): improve dispatcher and integration
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:45 -07:00
YeonGyu-Kim 94a2b8ec2c feat(lsp): add extension inference and improve diagnostics
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:42 -07:00
YeonGyu-Kim 3c77c048dd fix(comment-checker): improve pending calls handling and add tests
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:38 -07:00
YeonGyu-Kim 439c9a6499 feat(claude-code-hooks): improve session handling and add tests
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:29 -07:00
YeonGyu-Kim a720ef5334 feat(context-injector): enhance context collector functionality
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:26 -07:00
YeonGyu-Kim 116b1f9e4e fix(anthropic-recovery): fix retry timer memory leak in context window recovery
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:24 -07:00
YeonGyu-Kim 990095d22e fix(dispose): improve hook disposal and plugin cleanup
🤖 Generated with assistance of OhMyOpenCode
2026-03-31 17:33:19 -07:00
YeonGyu-Kim 9795cc5b3d docs: update deep category model references from gpt-5.3-codex to gpt-5.4 2026-03-31 17:26:40 -07:00
YeonGyu-Kim 3d56df4e1b feat(deep): upgrade default model from gpt-5.3-codex to gpt-5.4
Deep category now uses gpt-5.4 as its default model across all providers
(openai, github-copilot, venice, opencode), matching Hephaestus's GPT 5.4
upgrade. The requiresModel constraint is removed since gpt-5.4 is widely
available. Adds openai/gpt-5.3-codex -> openai/gpt-5.4 config migration
for existing user configs. Deep category prompt optimized for GPT 5.4's
stronger native capabilities (leaner, less verbose).
2026-03-31 17:26:30 -07:00
YeonGyu-Kim ce0d3581f0 fix: revert delegate-task to string category schema, fix mock isolation and restore UB7 originals 2026-03-31 17:25:00 -07:00
YeonGyu-Kim 92d70cff5b feat: add review-work and ai-slop-remover as built-in skills, add remove-ai-slops command
Embed user-level skills into the plugin's built-in system so they ship
with the product rather than requiring per-user configuration.

- review-work: 5-agent parallel post-implementation review orchestrator
- ai-slop-remover: per-file AI-generated code smell detector and remover
- /remove-ai-slops: command that orchestrates parallel ai-slop-remover runs
2026-03-31 17:22:34 -07:00