Skip to content

fix: add OpenCode slash command discovery and execution support#568

Open
chr1syy wants to merge 5 commits intoRunMaestro:0.16.0-RCfrom
chr1syy:fix-opencode-slash-commands
Open

fix: add OpenCode slash command discovery and execution support#568
chr1syy wants to merge 5 commits intoRunMaestro:0.16.0-RCfrom
chr1syy:fix-opencode-slash-commands

Conversation

@chr1syy
Copy link
Collaborator

@chr1syy chr1syy commented Mar 13, 2026

Summary

  • Enables OpenCode slash command discovery by reading commands from disk (.opencode/commands/*.md, ~/.config/opencode/commands/*.md, and opencode.json config)
  • Sets supportsSlashCommands: true for OpenCode agent so commands appear in autocomplete
  • Makes getSlashCommandDescription() agent-aware to provide correct descriptions per agent

Closes #552

Changes

File Change
src/main/agents/capabilities.ts Flip supportsSlashCommands to true for opencode
src/main/ipc/handlers/agents.ts Add discoverOpenCodeSlashCommands() — disk-based discovery from 3 sources (built-in, project-local, global + config)
src/renderer/constants/app.ts Add OPENCODE_BUILTIN_COMMANDS descriptions, make getSlashCommandDescription() agent-aware
src/renderer/hooks/agent/useAgentListeners.ts Pass toolType to getSlashCommandDescription()
src/renderer/hooks/wizard/useWizardHandlers.ts Pass toolType to getSlashCommandDescription()

How it works

Unlike Claude Code (which discovers commands via system/init JSON event), OpenCode stores commands on disk:

  1. Built-in: init, review, undo, redo, share, help, models
  2. Project-local: .opencode/commands/<name>.md files
  3. Global: ~/.config/opencode/commands/<name>.md files
  4. Config: opencode.jsoncommand property

The discovery function reads all three sources and returns a unified command list, matching Claude Code's end-to-end pipeline (discover → autocomplete → execute).

Test plan

  • Create an OpenCode session in Maestro and verify slash commands appear in autocomplete
  • Add a custom .opencode/commands/test.md file and verify it's discovered
  • Verify Claude Code slash commands still work unchanged
  • Verify Codex sessions (no slash commands) are unaffected

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • OpenCode agent now supports built-in slash commands: init, review, undo, redo, share, help, models.
    • Discovery of custom OpenCode slash commands from project/global configs and opencode.json enabled.
  • Improvements

    • Command descriptions are resolved per agent/tool for more accurate help and UI display.
    • Discovery runs for both Claude Code and OpenCode where applicable.
  • Tests

    • Expanded tests covering OpenCode discovery paths, error handling, and edge cases.

OpenCode slash commands (both built-in and custom) were silently ignored
because the capability flag was false and discovery was hard-gated to
Claude Code only. This adds disk-based discovery for OpenCode commands
from .opencode/commands/*.md, ~/.config/opencode/commands/*.md, and
opencode.json config files, and makes getSlashCommandDescription()
agent-aware to provide correct descriptions for each agent's commands.

Closes RunMaestro#552

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@greptile-apps
Copy link

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR adds OpenCode slash command discovery and execution support by enabling disk-based command discovery from three on-disk sources (.opencode/commands/*.md, global ~/.config/opencode/commands/*.md, and opencode.json config) plus OpenCode's seven built-ins. It also makes getSlashCommandDescription() agent-aware so descriptions are sourced from the correct agent's command map.

Key changes:

  • capabilities.ts: Flips supportsSlashCommands: true for OpenCode
  • agents.ts: Adds discoverOpenCodeSlashCommands() using fs.promises (async, non-blocking) with correct XDG_CONFIG_HOME support and Array.isArray guard for config parsing
  • app.ts: Adds OPENCODE_BUILTIN_COMMANDS, adds agentId parameter to getSlashCommandDescription() with a correct guard preventing cross-agent description leakage
  • useWizardHandlers.ts / useAgentListeners.ts: Passes toolType through to the description function; gates fetchCustomCommands() to Claude Code only

Issue found:

  • In addCommandsFromConfig, JSON.parse() will throw a SyntaxError for malformed opencode.json. A SyntaxError has no .code property, so the catch block re-throws it. This propagates through Promise.all and causes discoverOpenCodeSlashCommands to reject entirely — returning no commands at all, not even the seven built-ins. A user with a single typo in their config loses all autocomplete. The fix is to wrap JSON.parse in its own try/catch and log a warning instead of propagating the parse error. A corresponding test for this path is also missing in agents.test.ts.

Confidence Score: 3/5

  • Safe to merge after fixing the JSON parse error handling in addCommandsFromConfig; the bug silently breaks all command discovery for users with a malformed config file.
  • The overall approach is solid — async I/O, XDG support, array guard, and agent-aware descriptions are all done correctly. The one concrete bug is that JSON.parse errors are not isolated: a SyntaxError from a malformed opencode.json has no .code property, bypasses the ENOENT guard, gets re-thrown through Promise.all, and leaves the user with zero slash commands instead of the expected built-in set. This is a user-visible regression for an easily-triggered input condition and warrants a fix before merging.
  • src/main/ipc/handlers/agents.ts — specifically the addCommandsFromConfig helper's catch block

Important Files Changed

Filename Overview
src/main/ipc/handlers/agents.ts Adds discoverOpenCodeSlashCommands() with async disk-based discovery from 4 sources using fs.promises. Logic issue: JSON.parse throws a SyntaxError (no .code) for malformed config, which is re-thrown via Promise.all, killing all discovery including built-ins.
src/main/agents/capabilities.ts Single-line capability flip: supportsSlashCommands set to true for OpenCode. Correct and intentional.
src/renderer/constants/app.ts Adds OPENCODE_BUILTIN_COMMANDS, refactors getSlashCommandDescription to be agent-aware with a correct guard on the backwards-compat cross-agent loop. Looks clean.
src/renderer/hooks/agent/useAgentListeners.ts Moves commands map inside setSessions to access s.toolType for per-agent descriptions. Correct refactor; no behavioral change for the replace-on-slashCommands-event path.
src/renderer/hooks/wizard/useWizardHandlers.ts Gates fetchCustomCommands() to claude-code only; gates the outer effect to `claude-code
src/tests/main/ipc/handlers/agents.test.ts Good coverage for ENOENT, array-valued config, built-in commands, and project .md discovery. Missing test case for malformed JSON in opencode.json (SyntaxError path is untested).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Session activated\nclaude-code or opencode] --> B{toolType?}
    B -->|claude-code| C[fetchCustomCommands\nclaudeCommands/*.md via IPC]
    B -->|claude-code| D[discoverAgentCommands\nspawn claude --print /help]
    B -->|opencode| E[discoverAgentCommands\ndiscoverOpenCodeSlashCommands]
    C --> M[merge into agentCommands]
    D --> M
    E --> F[Built-ins\ninit,review,undo,redo,share,help,models]
    E --> G[.opencode/commands/*.md\nproject-local]
    E --> H[XDG_CONFIG_HOME/opencode/commands/*.md\nglobal]
    E --> I[opencode.json command property\nproject + global]
    F & G & H & I --> J[Promise.all\ncollect into Set]
    J --> K{JSON.parse error?}
    K -->|SyntaxError — no .code\ncurrent: rethrow ALL commands lost| L[❌ Discovery fails\nno commands returned]
    K -->|Valid JSON or ENOENT| M
    M --> N[agentCommands stored in session\nautocomplete populated]
    O[Claude Code init event\nonSlashCommands] -->|replaces agentCommands| N
Loading

Last reviewed commit: c271453

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3f07b830-c0f8-43c1-a4bd-6710a74658ba

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds OpenCode slash-command support: flips opencode capability to support slash commands, implements discovery of built-in and project/global-configured OpenCode commands, integrates discovery into IPC, and makes renderer command descriptions agent-aware.

Changes

Cohort / File(s) Summary
Tests
src/__tests__/main/ipc/handlers/agents.test.ts
Expanded tests for agents:discoverSlashCommands to cover OpenCode discovery paths, opencode.json parsing, project/global .opencode/commands/*.md, ENOENT and error paths, and unsupported-agent behavior.
Agent Capabilities
src/main/agents/capabilities.ts
Changed opencode.supportsSlashCommands from false to true.
IPC Handler / Discovery
src/main/ipc/handlers/agents.ts
Added discoverOpenCodeSlashCommands(cwd) and OPENCODE discovery logic (built-ins, project .opencode commands, global config, opencode.json); integrated into agents:discoverSlashCommands for agentId === 'opencode'.
Renderer constants
src/renderer/constants/app.ts
Added OPENCODE_BUILTIN_COMMANDS, AGENT_BUILTIN_COMMANDS mapping; changed getSlashCommandDescription(cmd, agentId?) signature and fallback resolution to be agent-aware.
Renderer hooks
src/renderer/hooks/agent/useAgentListeners.ts, src/renderer/hooks/wizard/useWizardHandlers.ts
Updated callers to pass session/tool toolType/agentId to getSlashCommandDescription; discovery now runs for claude-code and opencode, and custom command fetch gating adjusted.

Sequence Diagram

sequenceDiagram
    participant Renderer as Renderer (UI)
    participant IPC as IPC Handler (agents:discoverSlashCommands)
    participant FS as Filesystem (project/global .opencode + opencode.json)
    participant Session as Session (agentCommands)

    Renderer->>IPC: Request slash commands for agentId "opencode"
    IPC->>IPC: Route to OpenCode discovery
    IPC->>FS: Read built-in command list
    FS-->>IPC: Built-in commands
    IPC->>FS: Read project .opencode/commands/*.md
    FS-->>IPC: Project command files (names)
    IPC->>FS: Read project opencode.json
    FS-->>IPC: Project opencode.json (commands)
    IPC->>FS: Read global config (~/.opencode/... or base)
    FS-->>IPC: Global command files / global opencode.json
    IPC->>IPC: Consolidate unique command names
    IPC-->>Renderer: Return merged command array
    Renderer->>Session: Populate agentCommands with descriptions (agent-aware)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: add OpenCode slash command discovery and execution support' accurately summarizes the main change: enabling OpenCode slash commands.
Linked Issues check ✅ Passed The PR implements all primary coding objectives from issue #552: OpenCode command discovery from disk/config, capability flag enabled, agent-aware descriptions, and execution path.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing OpenCode slash command discovery and execution. No unrelated or extraneous modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

chr1syy and others added 2 commits March 13, 2026 11:35
The test expected OpenCode to return null from discoverSlashCommands,
but it now correctly returns built-in commands. Updated to test Codex
(which genuinely has no slash commands) and added a dedicated test for
OpenCode built-in command discovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
typeof [] === 'object' is true in JS, so an array value for the
"command" property in opencode.json would produce bogus /0, /1 slash
command entries. Add !Array.isArray() guard to both project-level and
global config parsing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chr1syy
Copy link
Collaborator Author

chr1syy commented Mar 13, 2026

@coderabbitai review
@greptileai re-review

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

@chr1syy Sure, I'll review the changes in this PR!


🧠 Learnings used
Learnt from: CR
Repo: RunMaestro/Maestro PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T18:31:11.110Z
Learning: Applies to src/main/**/*.ts : When spawning agents, ensure the correct agent type is used (don't hardcode `claude-code`), custom agent configuration (customPath, customArgs, customEnvVars) is passed through, and the agent's `binaryName` is used for remote execution (not local paths).
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/hooks/wizard/useWizardHandlers.ts (1)

178-268: ⚠️ Potential issue | 🟠 Major

OpenCode sessions still never run slash-command discovery here.

Line 183 returns unless the active session is Claude Code, so this effect never calls agents.discoverSlashCommands('opencode', ...). With supportsSlashCommands now enabled, OpenCode sessions will still keep an empty agentCommands list and won't show the new autocomplete entries.

🛠️ Suggested wiring fix
-		if (currentSession.toolType !== 'claude-code') return;
+		if (
+			currentSession.toolType !== 'claude-code' &&
+			currentSession.toolType !== 'opencode'
+		) {
+			return;
+		}
 		if (currentSession.agentCommands && currentSession.agentCommands.length > 0) return;
@@
-		fetchCustomCommands();
+		if (currentSession.toolType === 'claude-code') {
+			fetchCustomCommands();
+		}
 		discoverAgentCommands();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/hooks/wizard/useWizardHandlers.ts` around lines 178 - 268, The
effect currently bails out unless currentSession.toolType === 'claude-code',
preventing agents.discoverSlashCommands from running for 'opencode' sessions;
update the early-return so it allows any tool that supports slash commands
(e.g., replace the strict 'claude-code' check with a call to the
supportsSlashCommands predicate or include 'opencode') so discoverAgentCommands
(which calls maestro.agents.discoverSlashCommands) runs for those sessions and
populates s.agentCommands; adjust the condition around currentSession.toolType
in useEffect in useWizardHandlers.ts accordingly.
🧹 Nitpick comments (1)
src/__tests__/main/ipc/handlers/agents.test.ts (1)

1094-1108: This only covers the built-in happy path for OpenCode.

The new risk is in .opencode/commands/*.md and opencode.json parsing, but this assertion only proves the built-in set is seeded. A regression in the disk/config discovery logic—or in the Array.isArray guard on command—would still leave this suite green.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/main/ipc/handlers/agents.test.ts` around lines 1094 - 1108, The
test currently only verifies built-in OpenCode commands; add assertions and
setup to exercise the on-disk/config discovery paths so regressions in parsing
.opencode/commands/*.md and opencode.json (and the Array.isArray guard on
`command`) are caught: mock the filesystem reads (or the helper that loads
.opencode files) to return a mix of valid and invalid command definitions and a
sample opencode.json, call the same handler retrieved via
handlers.get('agents:discoverSlashCommands') after mocking
mockAgentDetector.getAgent to return the opencode agent, and assert the final
result includes commands discovered from disk/config and that non-array/invalid
`command` entries are ignored (or handled) as expected. Ensure you reference and
exercise the command-parsing code path used by agents:discoverSlashCommands so
the disk/config logic is validated in the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/ipc/handlers/agents.ts`:
- Around line 50-116: The catch blocks around reading project/global command
directories and project/global opencode.json currently swallow all errors;
change each catch to only suppress "file not found" (error.code === 'ENOENT')
while rethrowing other errors (including permission errors and JSON
parse/SyntaxError) so they propagate to IPC error handling/Sentry. Locate the
four try/catch blocks that reference projectCommandsDir, globalCommandsDir,
projectConfigPath, and globalConfigPath (they update the commands Set and use
logger and LOG_CONTEXT) and replace the generic catch handlers with logic: if
error?.code === 'ENOENT' then logger.debug(...) as before, else throw error.

In `@src/renderer/constants/app.ts`:
- Around line 120-129: The loop that searches AGENT_BUILTIN_COMMANDS for cmdName
should only run when agentId is not provided; currently if an agentId is passed
but lacks cmdName you still fall back to another agent's command. Modify the
logic around AGENT_BUILTIN_COMMANDS, agentId, and cmdName so that after checking
AGENT_BUILTIN_COMMANDS[agentId]?.[cmdName] you only iterate
Object.values(AGENT_BUILTIN_COMMANDS) when agentId is falsy (i.e., guard the
fallback with if (!agentId) or return undefined when an agentId was supplied and
its map does not contain cmdName).

---

Outside diff comments:
In `@src/renderer/hooks/wizard/useWizardHandlers.ts`:
- Around line 178-268: The effect currently bails out unless
currentSession.toolType === 'claude-code', preventing
agents.discoverSlashCommands from running for 'opencode' sessions; update the
early-return so it allows any tool that supports slash commands (e.g., replace
the strict 'claude-code' check with a call to the supportsSlashCommands
predicate or include 'opencode') so discoverAgentCommands (which calls
maestro.agents.discoverSlashCommands) runs for those sessions and populates
s.agentCommands; adjust the condition around currentSession.toolType in
useEffect in useWizardHandlers.ts accordingly.

---

Nitpick comments:
In `@src/__tests__/main/ipc/handlers/agents.test.ts`:
- Around line 1094-1108: The test currently only verifies built-in OpenCode
commands; add assertions and setup to exercise the on-disk/config discovery
paths so regressions in parsing .opencode/commands/*.md and opencode.json (and
the Array.isArray guard on `command`) are caught: mock the filesystem reads (or
the helper that loads .opencode files) to return a mix of valid and invalid
command definitions and a sample opencode.json, call the same handler retrieved
via handlers.get('agents:discoverSlashCommands') after mocking
mockAgentDetector.getAgent to return the opencode agent, and assert the final
result includes commands discovered from disk/config and that non-array/invalid
`command` entries are ignored (or handled) as expected. Ensure you reference and
exercise the command-parsing code path used by agents:discoverSlashCommands so
the disk/config logic is validated in the test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2ed8ee64-8158-4c7f-b0db-2165b17458dc

📥 Commits

Reviewing files that changed from the base of the PR and between 9e25141 and f52b59c.

📒 Files selected for processing (6)
  • src/__tests__/main/ipc/handlers/agents.test.ts
  • src/main/agents/capabilities.ts
  • src/main/ipc/handlers/agents.ts
  • src/renderer/constants/app.ts
  • src/renderer/hooks/agent/useAgentListeners.ts
  • src/renderer/hooks/wizard/useWizardHandlers.ts

- Convert discoverOpenCodeSlashCommands to async using fs.promises
- Respect XDG_CONFIG_HOME for global OpenCode config paths
- Only suppress ENOENT errors; rethrow permission/parse errors to Sentry
- Fix cross-agent description leak in getSlashCommandDescription
- Wire OpenCode sessions into slash command discovery in useWizardHandlers
- Add tests for disk/config discovery, array guard, and error propagation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@chr1syy
Copy link
Collaborator Author

chr1syy commented Mar 13, 2026

@coderabbitai re-review please
@greptileai re-review please

@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

@chr1syy Sure! I'll kick off a full re-review of the PR right away.


🧠 Learnings used
Learnt from: CR
Repo: RunMaestro/Maestro PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-03-11T18:31:11.110Z
Learning: Applies to src/main/**/*.ts : When spawning agents, ensure the correct agent type is used (don't hardcode `claude-code`), custom agent configuration (customPath, customArgs, customEnvVars) is passed through, and the agent's `binaryName` is used for remote execution (not local paths).
✅ Actions performed

Full review triggered.

Comment on lines +70 to +85
const addCommandsFromConfig = async (configPath: string) => {
try {
const content = await fs.promises.readFile(configPath, 'utf-8');
const config = JSON.parse(content);
if (config.command && typeof config.command === 'object' && !Array.isArray(config.command)) {
for (const name of Object.keys(config.command)) {
commands.add(name);
}
}
} catch (error: any) {
if (error?.code === 'ENOENT') {
logger.debug(`OpenCode config not found: ${configPath}`, LOG_CONTEXT);
} else {
throw error;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSON parse errors silently kill all command discovery

JSON.parse(content) throws a SyntaxError for malformed JSON. A SyntaxError has no .code property, so error?.code === 'ENOENT' evaluates to false and the error is re-thrown. Since both addCommandsFromConfig calls run inside Promise.all, a single malformed opencode.json (e.g. a stray trailing comma or an unquoted key) causes the entire discoverOpenCodeSlashCommands to reject — wiping out the built-in commands that were already collected into commands.

The practical impact: a user with any typo in their opencode.json will see zero slash-command autocomplete instead of the seven built-in commands they should always get.

	const addCommandsFromConfig = async (configPath: string) => {
		try {
			const content = await fs.promises.readFile(configPath, 'utf-8');
			let config: any;
			try {
				config = JSON.parse(content);
			} catch {
				logger.warn(`OpenCode config has invalid JSON, skipping: ${configPath}`, LOG_CONTEXT);
				return;
			}
			if (config.command && typeof config.command === 'object' && !Array.isArray(config.command)) {
				for (const name of Object.keys(config.command)) {
					commands.add(name);
				}
			}
		} catch (error: any) {
			if (error?.code === 'ENOENT') {
				logger.debug(`OpenCode config not found: ${configPath}`, LOG_CONTEXT);
			} else {
				throw error;
			}
		}
	};

The same pattern applies to both the project-level and global opencode.json paths read on lines 92–93.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/ipc/handlers/agents.ts (1)

32-33: Potential for silent drift with renderer-side command list.

OPENCODE_BUILTIN_COMMANDS is defined here as a string array, while src/renderer/constants/app.ts (line 94-102) defines OPENCODE_BUILTIN_COMMANDS as a Record<string, string> with descriptions. If commands are added or removed in one location but not the other, the lists will silently diverge.

Consider extracting the canonical command list to a shared location (e.g., src/shared/constants.ts) and deriving both usages from it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/ipc/handlers/agents.ts` around lines 32 - 33,
OPENCODE_BUILTIN_COMMANDS is duplicated in different shapes which can silently
diverge; extract a single canonical source (e.g., a shared constants module
exporting a canonicalCommands array) and derive both usages from it: export the
canonicalCommands (string[]) and then derive OPENCODE_BUILTIN_COMMANDS
(string[]) and the renderer's OPENCODE_BUILTIN_COMMANDS record (mapping to
descriptions) by importing and transforming the canonical list; update the
references in the handler that uses OPENCODE_BUILTIN_COMMANDS and the renderer
constant to import from the shared module and remove the local hardcoded list.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/main/ipc/handlers/agents.ts`:
- Around line 32-33: OPENCODE_BUILTIN_COMMANDS is duplicated in different shapes
which can silently diverge; extract a single canonical source (e.g., a shared
constants module exporting a canonicalCommands array) and derive both usages
from it: export the canonicalCommands (string[]) and then derive
OPENCODE_BUILTIN_COMMANDS (string[]) and the renderer's
OPENCODE_BUILTIN_COMMANDS record (mapping to descriptions) by importing and
transforming the canonical list; update the references in the handler that uses
OPENCODE_BUILTIN_COMMANDS and the renderer constant to import from the shared
module and remove the local hardcoded list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3cfac1ae-2b88-4a40-9301-f648799f32a3

📥 Commits

Reviewing files that changed from the base of the PR and between 9e25141 and c271453.

📒 Files selected for processing (6)
  • src/__tests__/main/ipc/handlers/agents.test.ts
  • src/main/agents/capabilities.ts
  • src/main/ipc/handlers/agents.ts
  • src/renderer/constants/app.ts
  • src/renderer/hooks/agent/useAgentListeners.ts
  • src/renderer/hooks/wizard/useWizardHandlers.ts

…very

SyntaxError from JSON.parse has no .code property, so it bypassed the
ENOENT check and rejected the entire Promise.all — wiping out built-in
commands. Split the try/catch so file-not-found and parse errors are
handled independently.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant