feat(call-omo-agent): support custom agents via dynamic resolution#2299
Conversation
|
All contributors have signed the CLA. Thank you! ✅ |
There was a problem hiding this comment.
3 issues found across 4 files
Confidence score: 2/5
- There is a high-confidence compatibility bug in
src/tools/call-omo-agent/constants.ts: agent directories point to.claude/agents/instead of Opencode paths (~/.config/opencode/agents/and.opencode/agents/), which can prevent custom agents from being discovered at runtime. src/tools/call-omo-agent/tools.tsalso documents the wrong directories with high confidence, increasing the chance users configure the feature incorrectly and experience failures even if code paths are corrected elsewhere.- The
subagent_typewording insrc/tools/call-omo-agent/tools.tsis lower-confidence and lower-severity, but it still conflicts with dynamic agent resolution and may mislead usage. - Pay close attention to
src/tools/call-omo-agent/constants.tsandsrc/tools/call-omo-agent/tools.ts- directory path compatibility and related guidance need to be aligned with Opencode behavior.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/tools/call-omo-agent/tools.ts">
<violation number="1" location="src/tools/call-omo-agent/tools.ts:19">
P2: Custom agent: **Opencode Compatibility**
The documentation incorrectly references Claude Code's agent directories (`~/.claude/agents/` and `.claude/agents/`) instead of Opencode's agent directories. According to the Opencode documentation, custom agents are loaded from `~/.config/opencode/agents/` and `.opencode/agents/`.</violation>
<violation number="2" location="src/tools/call-omo-agent/tools.ts:51">
P2: `subagent_type` description still claims "explore or librarian only" even though agents are now dynamically resolved; this contradicts the new capability and can mislead tool usage.</violation>
</file>
<file name="src/tools/call-omo-agent/constants.ts">
<violation number="1" location="src/tools/call-omo-agent/constants.ts:16">
P1: Custom agent: **Opencode Compatibility**
Incorrect agent directory paths. OpenCode loads custom agents from `~/.config/opencode/agents/` and `.opencode/agents/`, not `.claude/agents/`.</violation>
</file>
Since this is your first cubic review, here's how it works:
- cubic automatically reviews your code and comments on bugs and improvements
- Teach cubic by replying to its comments. cubic learns from your replies and gets better over time
- Add one-off context when rerunning by tagging
@cubic-dev-aiwith guidance or docs links (includingllms.txt) - Ask questions if you need clarification on any suggestion
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
1 issue found across 18 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/plugin-handlers/agent-config-handler.ts">
<violation number="1" location="src/plugin-handlers/agent-config-handler.ts:209">
P2: Global agents overwrite project-level agents due to incorrect spread order. Project-level configuration should take precedence over global configuration, but the current order means global agents overwrite project agents.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/plugin-handlers/agent-config-handler.ts">
<violation number="1" location="src/plugin-handlers/agent-config-handler.ts:209">
P1: Custom agent: **Opencode Compatibility**
The configuration merge priority violates OpenCode's standard configuration precedence, where project-level configurations must always override global/user-level configurations.
In OpenCode, local configurations always win. However, this PR's object spread order causes two precedence violations:
1. `userAgents` (global) incorrectly overrides `projectAgents` (local).
2. `opencodeGlobalAgents` (global) incorrectly overrides `projectAgents` (local).
To follow OpenCode's "Project > Global" approach while maintaining your "OpenCode format > Claude format" precedence, all global agents should be spread before any project agents. Note: This incorrect ordering appears in both `applyAgentConfig` return blocks, so the fix should be applied to both.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
The CLA agent seems to be broken - it's looking at a "@brandon Webb" as the user (which is not my account) instead of "@brandonwebb-vista" |
I think the first commit was done with the local git config which had another user than your GitHub one Thank you for the contribution! omo is amazing |
|
@alexmhtop I realized that my email wasn't configured correctly in git global, so that's the reason for the difference. Short of recreating this MR, I'm hoping we can just force skip the CLA Assistant? It should be clear that I did sign the CLA |
4273e7b to
523e9a6
Compare
|
@code-yeongyu this MR should be ready to go |
|
Awesome feature, expect code merge 👍 |
|
@code-yeongyu when can we expect to get this merged? |
Looking forward to this feature merger!!! |
There was a problem hiding this comment.
4 issues found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/shared/agent-tool-restrictions.ts">
<violation number="1" location="src/shared/agent-tool-restrictions.ts:58">
P1: Custom agent: **Opencode Compatibility**
Revert the default fallback to `UNRESTRICTED` to allow custom dynamic agents to use write and edit tools.</violation>
<violation number="2" location="src/shared/agent-tool-restrictions.ts:58">
P2: Inconsistent fallback logic between `hasAgentToolRestrictions` and `getAgentToolRestrictions` for unknown agents. The `getAgentToolRestrictions` function returns `EXPLORATION_AGENT_DENYLIST` for unknown agents, but `hasAgentToolRestrictions` (which was not updated) returns `false` for the same input, creating a logical inconsistency.</violation>
</file>
<file name="src/tools/call-omo-agent/agent-resolver.ts">
<violation number="1" location="src/tools/call-omo-agent/agent-resolver.ts:24">
P1: Custom agent: **Opencode Compatibility**
Add `{ throwOnError: true }` to the SDK call so that actual API errors are caught and logged, rather than throwing a generic `TypeError` when `.filter()` is called on the error object.</violation>
<violation number="2" location="src/tools/call-omo-agent/agent-resolver.ts:36">
P2: Merging logic fails to preserve canonical casing from registry. The function iterates `[...ALLOWED_AGENTS, ...dynamicAgents]`, but ALLOWED_AGENTS contains lowercase names. When agents overlap, the lowercase version is added first and the registry's canonical casing is discarded due to case-insensitive deduplication. To honor the documented "Returns canonical names" contract, iterate `[...dynamicAgents, ...ALLOWED_AGENTS]` instead.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
2 issues found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/tools/call-omo-agent/agent-resolver.ts">
<violation number="1" location="src/tools/call-omo-agent/agent-resolver.ts:36">
P2: Dynamic agents with different casing can shadow built-in agents' canonical lowercase names. The spread order prioritizes dynamicAgents over ALLOWED_AGENTS, so when a dynamic agent shares a name (case-insensitively) with a built-in agent but uses different casing, the built-in agent's canonical name is omitted from the returned list. To preserve canonical naming for built-in agents, swap the spread order to `[...ALLOWED_AGENTS, ...dynamicAgents]`.</violation>
</file>
<file name="src/shared/agent-tool-restrictions.ts">
<violation number="1">
P1: Removal of fail-safe tool restrictions grants fully unrestricted tool access to unknown agents. The fallback in `getAgentToolRestrictions` was changed from `EXPLORATION_AGENT_DENYLIST` (which denied write/edit/task/call_omo_agent) to `{}` (no restrictions). This means any misspelled agent name, future unregistered agent, or validation bypass will silently receive unrestricted access to all tools including sensitive operations.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
Addressing remaining cubic findings from latest review: P1 (agent-tool-restrictions.ts P2 (merge order / canonical casing): Built-in agents in P1 (throwOnError): @cubic-dev-ai please re-review |
@code-yeongyu I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
3 issues found across 10 files
Confidence score: 2/5
- There is a high-confidence compatibility risk in
src/tools/call-omo-agent/tools.test.ts: the mock shape forclient.app.agents()(array) does not match the Opencode SDK response contract (dataobject), which can mask real integration failures. src/plugin-handlers/agent-config-handler.tsappears to invertcustomAgentSummariesmerge order versus SDK priority, so system prompts may use overridden/incorrect agent descriptions at runtime.- Given two concrete, high-severity (8/10) Opencode compatibility issues plus a validation gap in
src/tools/call-omo-agent/agent-resolver.ts(namenot validated), this carries meaningful regression risk before merge. - Pay close attention to
src/plugin-handlers/agent-config-handler.ts,src/tools/call-omo-agent/tools.test.ts,src/tools/call-omo-agent/agent-resolver.ts- SDK contract/order mismatches and missingnamevalidation can break agent resolution behavior.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/tools/call-omo-agent/agent-resolver.ts">
<violation number="1" location="src/tools/call-omo-agent/agent-resolver.ts:30">
P2: Missing validation on agent `name` property can cause dynamic resolution failure</violation>
</file>
<file name="src/tools/call-omo-agent/tools.test.ts">
<violation number="1" location="src/tools/call-omo-agent/tools.test.ts:10">
P1: Custom agent: **Opencode Compatibility**
The mock for `client.app.agents()` returns an array directly, but the Opencode SDK returns a response object with a `data` property.</violation>
</file>
<file name="src/plugin-handlers/agent-config-handler.ts">
<violation number="1" location="src/plugin-handlers/agent-config-handler.ts:105">
P1: Custom agent: **Opencode Compatibility**
The `customAgentSummaries` array order is inverted compared to the actual SDK merge priority, causing the system prompt to receive overridden agent descriptions instead of the active ones.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
Really need this feature. When can the current PR be merged |
0d818c8 to
27bce77
Compare
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/shared/agent-tool-restrictions.ts">
<violation number="1" location="src/shared/agent-tool-restrictions.ts:50">
P2: `getAgentToolRestrictions` now defaults unknown agents to a denylist, but `hasAgentToolRestrictions` still returns false for those same agents, creating an inconsistent exported API that can bypass restriction gating.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
aaba861 to
1e759ab
Compare
|
@code-yeongyu can we merge this? |
I am also waiting for this PR merger |
|
@code-yeongyu can we merge? it's becoming a chore to continually come back and update/resolve merge conflicts |
…d JSON agent loader Wave 1 of agent definitions enhancement (PR code-yeongyu#2299): Schema & Configuration: - Add agent_definitions field to oh-my-opencode config schema - Support list of file paths to .md or .json agent definition files - Add to PARTIAL_STRING_ARRAY_KEYS for Set-union merge semantics - Implement eager path resolution in loadPluginConfig() before merging Path Resolution: - Create resolve-agent-definition-paths.ts helper - User-level paths resolve from ~/.config/opencode/ (no containment) - Project-level paths resolve from project root (with containment check) - Homedir expansion, absolute/relative path handling JSON Agent Loader: - Create parseJsonAgentFile() for .json/.jsonc agent definitions - Validate required fields (name, prompt) - Support tools as string (comma-separated) or array - Map model via mapClaudeModelToOpenCode() - Comprehensive test suite (7 test cases, all passing) Type Extensions: - Extend AgentScope: add 'definition-file' and 'opencode-config' - Add AgentJsonDefinition interface for JSON agent schema All automated checks passing: - lsp_diagnostics clean on all changed files - json-agent-loader.test.ts: 7/7 passing - Full typecheck: zero new errors - QA evidence saved to .sisyphus/evidence/
There was a problem hiding this comment.
5 issues found across 16 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/features/claude-code-agent-loader/agent-definitions-loader.ts">
<violation number="1" location="src/features/claude-code-agent-loader/agent-definitions-loader.ts:31">
P2: Markdown fallback name extraction is case-sensitive, so `.MD`/mixed-case files keep the extension in the agent key.</violation>
</file>
<file name="src/plugin-config.ts">
<violation number="1" location="src/plugin-config.ts:258">
P2: Project `agent_definitions` are resolved against the workspace root instead of the project config directory, so relative paths from `.opencode` will point to the wrong location.</violation>
</file>
<file name="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts">
<violation number="1" location="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts:21">
P2: Hardcoded config directory paths bypass standard OPENCODE_CONFIG_DIR and XDG_CONFIG_HOME overrides.</violation>
<violation number="2" location="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts:112">
P2: Global inline agents will incorrectly overwrite project-level agents with the same name.</violation>
<violation number="3" location="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts:127">
P2: Agent precedence is inconsistent across config sources: inline agents use overwrite semantics, while `agent_definitions` only fill missing names, so collisions resolve differently depending on declaration style.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
1 issue found across 5 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts">
<violation number="1" location="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts:99">
P2: Using `in` on a plain object causes valid agent names that match inherited properties to be skipped.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts">
<violation number="1" location="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts:99">
P1: Use a null-prototype accumulator or explicitly reject `__proto__` here; `Object.hasOwn` allows a crafted agent name to mutate the result object's prototype. The same pattern appears again in the definition-agents merge below.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
@code-yeongyu can we get this merged? Or perhaps you can open up OmA to collaborators? |
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: Large PR (2860 lines) fundamentally changing agent resolution and validation logic. Changes default tool restriction behavior. High complexity makes it impossible to guarantee 0% regressions.
|
[sisyphus-bot] Hey @brandonwebb — first off, thank you so much for this PR! This is a really solid contribution. The dynamic agent resolution architecture is exactly the direction we wanted to go, and the test coverage (70+ new tests) is impressive. The precedence chain design is clean and the backward compatibility story is well thought out. We ran two independent code reviews (security-focused + architecture-focused) and here is the consolidated feedback: Blocking Issues (must fix before merge)B1: Tool restriction bypass for custom agents (CRITICAL)File: The fallback to
B2: Prototype pollution inconsistencyFile:
B3: Custom agent bash access undocumentedFile: The B4: Two test failures in new codeFile:
Non-blocking Issues (nice to have)N1: Path containment gap in opencode-config-agents-reader
N2: No caching in resolveCallableAgentsCalled per tool invocation with no caching. A session-scoped cache would eliminate redundant SDK IPC calls. N3: parseToolsConfig duplicated 4xFour near-identical implementations across loaders. Extract a single shared implementation into N4: agent_definitions path schema too permissive
N5: No test coverage for resolveAgentDefinitionPathsSecurity-sensitive function (path traversal boundary) with zero tests. Edge cases: symlink escape, N6: Mode type assertion without validation
VerdictArchitecture: Strong. The Test coverage: Strong. 70+ new tests with good given/when/then structure. Recommendation: Approve with required changes on B1–B4. The non-blocking items can be addressed in follow-up PRs. Again, really appreciate this contribution — the custom agents feature has been one of the most requested items. Looking forward to landing this! 🎉 |
Blocking fixes: - B1: Return empty restrictions for unknown/custom agents instead of EXPLORATION_AGENT_DENYLIST, allowing custom agents full tool access - B2: Use Object.create(null) consistently across all 5 agent-loading result objects to prevent prototype pollution - B3: Add code comment documenting custom agent bash access trust model - B4: Mock getOpenCodeConfigDir in opencode-config-agents-reader tests to prevent global config dir leakage Non-blocking fixes: - N1: Use resolveAgentDefinitionPaths with project boundary enforcement in opencode-config-agents-reader for path containment - N2: Add session-scoped 30s TTL cache to resolveCallableAgents to avoid redundant SDK IPC calls per tool invocation - N3: Extract shared parseToolsConfig into src/shared/parse-tools-config.ts replacing 4 duplicated local implementations - N4: Add .min(1) to AgentDefinitionPathSchema rejecting empty paths - N5: Add resolve-agent-definition-paths.test.ts covering tilde expansion, relative paths, boundary enforcement, and null containmentDir - N6: Validate agent mode against allowed values instead of bare type assertion in opencode-config-agents-reader
|
[sisyphus-bot] I went ahead and pushed fixes for all the review findings directly to this branch. Here's what was addressed: Blocking fixes:
Non-blocking fixes:
Verification:
The commit is |
…t-based tests
- Fix agent-resolver.ts: add defensive validation on agent name (typeof, trim, filter)
- Fix tools.test.ts: correct mock to return {data: agents} matching SDK contract
- Fix agent-config-handler.ts: include opencode global/project agents in customAgentSummaries
- Add agent-resolver.test.ts: 14 requirement-based tests covering R1-R7 behavioral specs
- Add tools-edge-cases.test.ts: 5 integration tests for rollback, whitespace, dedup, session_id
…t fallback for unknown agents
…d JSON agent loader Wave 1 of agent definitions enhancement (PR code-yeongyu#2299): Schema & Configuration: - Add agent_definitions field to oh-my-opencode config schema - Support list of file paths to .md or .json agent definition files - Add to PARTIAL_STRING_ARRAY_KEYS for Set-union merge semantics - Implement eager path resolution in loadPluginConfig() before merging Path Resolution: - Create resolve-agent-definition-paths.ts helper - User-level paths resolve from ~/.config/opencode/ (no containment) - Project-level paths resolve from project root (with containment check) - Homedir expansion, absolute/relative path handling JSON Agent Loader: - Create parseJsonAgentFile() for .json/.jsonc agent definitions - Validate required fields (name, prompt) - Support tools as string (comma-separated) or array - Map model via mapClaudeModelToOpenCode() - Comprehensive test suite (7 test cases, all passing) Type Extensions: - Extend AgentScope: add 'definition-file' and 'opencode-config' - Add AgentJsonDefinition interface for JSON agent schema All automated checks passing: - lsp_diagnostics clean on all changed files - json-agent-loader.test.ts: 7/7 passing - Full typecheck: zero new errors - QA evidence saved to .sisyphus/evidence/
- Add loadAgentDefinitions() for explicit file path loading (.md/.json/.jsonc) - Add readOpencodeConfigAgents() for independent opencode.json(c) reading - Extract parseMarkdownAgentFile() from loader.ts for reuse - Refactor loader.ts to use extracted parser (-50 LOC) - Add comprehensive test coverage (13 tests for definitions loader, 10 tests for opencode reader) - Support inline agents + agent_definitions paths in opencode.json(c) - Inline agents override definition-file agents (correct precedence) Part of agent definitions enhancement (Wave 2/3)
…ecedence chain - Modified agent-config-handler.ts to load and integrate both new agent sources - Added loadAgentDefinitions() and readOpencodeConfigAgents() calls in loading phase - Integrated both sources into agent precedence chains (both Sisyphus-enabled and disabled paths) - Added detailed logging for new agent sources - Added filtering logic to respect disabled_agents configuration - Extended agent-config-handler.test.ts with 7 new integration tests - All tests passing (18/18 integration, 65/65 loader suite) Wave 3 of agent definitions enhancement complete.
…ckCtx factory Dev added 4 tests (code-yeongyu#2852, model variant, category-derived overrides) that referenced the old mockCtx constant. Our branch replaced it with a createMockCtx() factory. Replace all 4 references.
- Case-insensitive .md extension stripping for agent name extraction - Resolve project agent_definitions paths relative to config dir (.opencode/) - Use getOpenCodeConfigDir() to respect OPENCODE_CONFIG_DIR/XDG_CONFIG_HOME - First-write-wins semantics for both inline and definition-file agents so project-level agents always take precedence over global-level
…perty checks Addresses cubic-dev-ai review: using 'in' on plain objects can skip valid agent names that match inherited properties (toString, constructor, etc.). Switched both occurrences in opencode-config-agents-reader.ts to Object.hasOwn() for safe own-property checks.
…ution Addresses cubic-dev-ai P1 review: Object.hasOwn() alone doesn't prevent a crafted '__proto__' agent name from mutating the result object's prototype chain. Using Object.create(null) eliminates inherited properties entirely, making both the hasOwn checks and property assignments safe.
Blocking fixes: - B1: Return empty restrictions for unknown/custom agents instead of EXPLORATION_AGENT_DENYLIST, allowing custom agents full tool access - B2: Use Object.create(null) consistently across all 5 agent-loading result objects to prevent prototype pollution - B3: Add code comment documenting custom agent bash access trust model - B4: Mock getOpenCodeConfigDir in opencode-config-agents-reader tests to prevent global config dir leakage Non-blocking fixes: - N1: Use resolveAgentDefinitionPaths with project boundary enforcement in opencode-config-agents-reader for path containment - N2: Add session-scoped 30s TTL cache to resolveCallableAgents to avoid redundant SDK IPC calls per tool invocation - N3: Extract shared parseToolsConfig into src/shared/parse-tools-config.ts replacing 4 duplicated local implementations - N4: Add .min(1) to AgentDefinitionPathSchema rejecting empty paths - N5: Add resolve-agent-definition-paths.test.ts covering tilde expansion, relative paths, boundary enforcement, and null containmentDir - N6: Validate agent mode against allowed values instead of bare type assertion in opencode-config-agents-reader
There was a problem hiding this comment.
2 issues found across 15 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/tools/call-omo-agent/agent-resolver.ts">
<violation number="1" location="src/tools/call-omo-agent/agent-resolver.ts:54">
P2: The cache uses a global `"__default__"` key when `sessionId` is missing, so agent lists can bleed across contexts and validate against the wrong dynamic agents for up to 30 seconds.</violation>
</file>
<file name="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts">
<violation number="1" location="src/features/claude-code-agent-loader/opencode-config-agents-reader.ts:95">
P2: Global OpenCode config `agent_definitions` are incorrectly blocked by project-boundary enforcement.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
The opencode-config-agents-reader.test.ts was using mock.module() which permanently replaced the module in bun's module cache, causing state pollution in downstream tests (plugin-detection, write-omo-config, config-loader). Replaced with spyOn() pattern that properly restores in afterEach.
dd92ee0 to
ab11f2e
Compare
|
[sisyphus-bot] Pushed additional fix: replaced Root cause: Result:
Branch is ready for merge. |
…d JSON agent loader Wave 1 of agent definitions enhancement (PR code-yeongyu#2299): Schema & Configuration: - Add agent_definitions field to oh-my-opencode config schema - Support list of file paths to .md or .json agent definition files - Add to PARTIAL_STRING_ARRAY_KEYS for Set-union merge semantics - Implement eager path resolution in loadPluginConfig() before merging Path Resolution: - Create resolve-agent-definition-paths.ts helper - User-level paths resolve from ~/.config/opencode/ (no containment) - Project-level paths resolve from project root (with containment check) - Homedir expansion, absolute/relative path handling JSON Agent Loader: - Create parseJsonAgentFile() for .json/.jsonc agent definitions - Validate required fields (name, prompt) - Support tools as string (comma-separated) or array - Map model via mapClaudeModelToOpenCode() - Comprehensive test suite (7 test cases, all passing) Type Extensions: - Extend AgentScope: add 'definition-file' and 'opencode-config' - Add AgentJsonDefinition interface for JSON agent schema All automated checks passing: - lsp_diagnostics clean on all changed files - json-agent-loader.test.ts: 7/7 passing - Full typecheck: zero new errors - QA evidence saved to .sisyphus/evidence/
Blocking fixes: - B1: Return empty restrictions for unknown/custom agents instead of EXPLORATION_AGENT_DENYLIST, allowing custom agents full tool access - B2: Use Object.create(null) consistently across all 5 agent-loading result objects to prevent prototype pollution - B3: Add code comment documenting custom agent bash access trust model - B4: Mock getOpenCodeConfigDir in opencode-config-agents-reader tests to prevent global config dir leakage Non-blocking fixes: - N1: Use resolveAgentDefinitionPaths with project boundary enforcement in opencode-config-agents-reader for path containment - N2: Add session-scoped 30s TTL cache to resolveCallableAgents to avoid redundant SDK IPC calls per tool invocation - N3: Extract shared parseToolsConfig into src/shared/parse-tools-config.ts replacing 4 duplicated local implementations - N4: Add .min(1) to AgentDefinitionPathSchema rejecting empty paths - N5: Add resolve-agent-definition-paths.test.ts covering tilde expansion, relative paths, boundary enforcement, and null containmentDir - N6: Validate agent mode against allowed values instead of bare type assertion in opencode-config-agents-reader

Summary
Replace the hardcoded
ALLOWED_AGENTSwhitelist validation incall_omo_agentwith dynamic agent resolution viaclient.app.agents(), and extend the agent loader to discover agents from all configuration paths.Closes #1706
Changes
Dynamic Agent Resolution (
call-omo-agent)agent-resolver.ts: NewresolveCallableAgents()queries registered agents at execute-time and merges them withALLOWED_AGENTS(built-in agents are always callable, never dropped)tools.ts: Validatesubagent_typeagainst the dynamic set; fixedsubagent_typeparameter descriptionconstants.ts: Updated description to be path-agnostic (covers all loader paths, not just~/.claude/agents/)tools.test.ts: 18 tests covering dynamic resolution, merge behavior, fallback, and validationAgent Loader Extension (
claude-code-agent-loader)loader.ts: AddedloadOpencodeGlobalAgents()(~/.config/opencode/agents/) andloadOpencodeProjectAgents()(<cwd>/.opencode/agents/)types.ts: ExtendedAgentScopewith"opencode"and"opencode-project"loader.test.ts: 15 tests covering YAML/MD parsing, tool extraction, scope assignment, and env-var pathsAgent Config Handler Wiring (
agent-config-handler.ts)claude_code.agentsconfig flag)opencode-project > opencode-global > user > project > pluginTest Results
bun test src/tools/call-omo-agent/: 18 pass, 0 failbun test src/features/claude-code-agent-loader/: 15 pass, 0 failbun run typecheck: cleanAgent Discovery Paths (after this PR)
~/.claude/agents/userloadUserAgents()<cwd>/.claude/agents/projectloadProjectAgents()~/.config/opencode/agents/opencodeloadOpencodeGlobalAgents()<cwd>/.opencode/agents/opencode-projectloadOpencodeProjectAgents()