- Detect namespaced commands (containing ':') from Claude marketplace plugins
- Provide clear error message explaining marketplace plugins are not supported
- Point users to .claude/commands/ as alternative for custom commands
- Fixes issue where /daplug:run-prompt gave ambiguous 'command not found'
Closes#1682
* fix: generate skill/slashcommand tool descriptions synchronously when pre-provided
When skills are passed via options (pre-resolved), build the tool description
synchronously instead of fire-and-forget async. This eliminates the race
condition where the description getter returns the bare prefix before the
async cache-warming microtask completes.
Fixes#1039
* chore: changes by sisyphus-dev-ai
---------
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
This ensures that commands defined in src/features/builtin-commands/commands.ts
(like /start-work, /refactor, /init-deep) are visible to the slashcommand tool
and the agent. Previously, only markdown-based commands were discovered.
Multiple files were hardcoding ~/.config/opencode paths instead of using
getOpenCodeConfigDir() which respects the OPENCODE_CONFIG_DIR env var.
This broke profile isolation features like OCX ghost mode, where users
set OPENCODE_CONFIG_DIR to a custom path but oh-my-opencode.json and
other configs weren't being read from that location.
Changes:
- plugin-config.ts: Use getOpenCodeConfigDir() directly
- cli/doctor/checks: Use getOpenCodeConfigDir() for auth and config checks
- tools/lsp/config.ts: Use getOpenCodeConfigDir() for LSP config paths
- command loaders: Use getOpenCodeConfigDir() for global command dirs
- hooks: Use getOpenCodeConfigDir() for hook config paths
- config-path.ts: Mark getUserConfigDir() as deprecated
- tests: Ensure OPENCODE_CONFIG_DIR is properly isolated in tests
* fix: background task completion detection and silent notifications
- Fix TS2742 by adding explicit ToolDefinition type annotations
- Add stability detection (3 consecutive stable polls after 10s minimum)
- Remove early continue when sessionStatus is undefined
- Add silent notification system via tool.execute.after hook injection
- Change task retention from 200ms to 5 minutes for background_output retrieval
- Fix formatTaskResult to sort messages by time descending
Fixes hanging background tasks that never complete due to missing sessionStatus.
* fix: improve background task completion detection and message extraction
- Add stability-based completion detection (10s min + 3 stable polls)
- Fix message extraction to recognize 'reasoning' parts from thinking models
- Switch from promptAsync() to prompt() for proper agent initialization
- Remove model parameter from prompt body (use agent's configured model)
- Add fire-and-forget prompt pattern for sisyphus_task sync mode
- Add silent notification via tool.execute.after hook injection
- Fix indentation issues in manager.ts and index.ts
Incorporates fixes from:
- PR #592: Stability detection mechanism
- PR #610: Model parameter passing (partially)
- PR #628: Completion detection improvements
Known limitation: Thinking models (e.g. claude-*-thinking-*) cause
JSON Parse errors in child sessions. Use non-thinking models for
background agents until OpenCode core resolves this.
* fix: add tool_result handling and pendingByParent tracking for resume/external tasks
Addresses code review feedback from PR #638:
P1: Add tool_result type to validateSessionHasOutput() to prevent
false negatives for tool-only background tasks that would otherwise
timeout after 30 minutes despite having valid results.
P2: Add pendingByParent tracking to resume() and registerExternalTask()
to prevent premature 'ALL COMPLETE' notifications when mixing
launched and resumed tasks.
* fix: address code review feedback - log messages, model passthrough, sorting, race condition
- Fix misleading log messages: 'promptAsync' -> 'prompt (fire-and-forget)'
- Restore model passthrough in launch() for Sisyphus category configs
- Fix call-omo-agent sorting: use time.created number instead of String(time)
- Fix race condition: check promptError inside polling loop, not just after 100ms
- Fix#542: slashcommand tool returns empty content for skills
- Add lazyContentLoader to CommandInfo type
- Load skill content in formatLoadedCommand when content is empty
- Filter non-ultrawork keywords in subagent sessions
- Extract createSlashcommandTool factory with SlashcommandToolOptions
- Export discoverCommandsSync for external use
- Move description building to lazy evaluation with caching
- Support pre-warming cache with provided commands and skills
- Simplify tool initialization in plugin with new factory approach
This allows the slashcommand tool to be instantiated with custom options
while maintaining backward compatibility through lazy loading.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Remove all sync functions from command loader (async now default)
- Remove sync load functions from skill loader (async now default)
- Add resolveSymlinkAsync to file-utils.ts
- Update all callers to use async versions:
- config-handler.ts
- index.ts
- tools/slashcommand/tools.ts
- tools/skill/tools.ts
- hooks/auto-slash-command/executor.ts
- loader.test.ts
- All 607 tests pass, build succeeds
Generated with assistance of 🤖 [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* feat(commands): add handoffs support for speckit compatibility
- Upgrade frontmatter parser to use js-yaml for complex YAML support
- Add HandoffDefinition interface for speckit-style workflow transitions
- Update CommandFrontmatter and CommandDefinition to include handoffs
- Add comprehensive tests for backward compatibility and complex YAML
- Fix type parameters in auto-slash-command and slashcommand tools
Closes#407
* fix(frontmatter): use JSON_SCHEMA for security and add extra fields tolerance tests
- Use JSON_SCHEMA in yaml.load() to prevent code execution via YAML tags
- Add tests to verify extra fields in frontmatter don't cause failures
- Address Greptile security review comment
---------
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
* feat(skill): add builtin skill types and schemas with priority-based merging support
- Add BuiltinSkill interface for programmatic skill definitions
- Create builtin-skills module with createBuiltinSkills factory function
- Add SkillScope expansion to include 'builtin' and 'config' scopes
- Create SkillsConfig and SkillDefinition Zod schemas for config validation
- Add merger.ts utility with mergeSkills function for priority-based skill merging
- Update skill and command types to support optional paths for builtin/config skills
- Priority order: builtin < config < user < opencode < project < opencode-project
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* feat(skill): integrate programmatic skill discovery and merged skill support
- Add discovery functions for Claude and OpenCode skill directories
- Add discoverUserClaudeSkills, discoverProjectClaudeSkills functions
- Add discoverOpencodeGlobalSkills, discoverOpencodeProjectSkills functions
- Update createSkillTool to support pre-merged skills via options
- Add extractSkillBody utility to handle both file and programmatic skills
- Integrate mergeSkills in plugin initialization to apply priority-based merging
- Support optional path/resolvedPath for builtin and config-sourced skills
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* chore(slashcommand): support optional path for builtin and config command scopes
- Update CommandInfo type to make path and content optional properties
- Prepare command tool for builtin and config sourced commands
- Maintain backward compatibility with file-based command loading
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* docs(tools): improve tool descriptions for interactive-bash and slashcommand
- Added use case clarification to interactive-bash tool description (server processes, long-running tasks, background jobs, interactive CLI tools)
- Simplified slashcommand description to emphasize 'loading' skills concept and removed verbose documentation
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* refactor(skill-loader): simplify redundant condition in skill merging logic
Remove redundant 'else if (loaded)' condition that was always true since we're already inside the 'if (loaded)' block. Simplify to 'else' for clarity.
Addresses code review feedback on PR #340 for the skill infrastructure feature.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
* feat: add opencode-skill-loader with 4-source priority system
- Create new opencode-skill-loader feature module independent from Claude Code
- Support 4 source paths with priority: opencode-project > project > opencode > user
- .opencode/skill/ (opencode-project)
- .claude/skills/ (project)
- ~/.config/opencode/skill/ (opencode)
- ~/.claude/skills/ (user)
- Support both SKILL.md and {SKILLNAME}.md file patterns
- Maintain path awareness for file references (@path syntax)
* feat: integrate opencode-skill-loader into main plugin
- Import and use new skill loader functions
- Load skills from all 4 sources and merge into config.command
- Also merge pluginComponents.skills (previously loaded but never used)
* feat: add skill discovery to slashcommand tool
- Import and use discoverAllSkills from opencode-skill-loader
- Display skills alongside commands in tool description and execution
- Update formatCommandList to handle combined commands and skills
* refactor: remove old claude-code-skill-loader
- Delete src/features/claude-code-skill-loader/ directory (was never integrated into main plugin)
- Update plugin loader import to use new opencode-skill-loader types
* docs: update AGENTS.md for new skill loader
- Update structure to show opencode-skill-loader instead of claude-code-skill-loader
- Update Skills priority order to include all 4 sources
---------
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Fixes#255
- Add getClaudeConfigDir() utility function that respects CLAUDE_CONFIG_DIR env var
- Update all hardcoded ~/.claude paths to use the new utility
- Add comprehensive tests for getClaudeConfigDir()
- Maintain backward compatibility with default ~/.claude when env var is not set
Files updated:
- src/shared/claude-config-dir.ts (new utility)
- src/shared/claude-config-dir.test.ts (tests)
- src/hooks/claude-code-hooks/config.ts
- src/hooks/claude-code-hooks/todo.ts
- src/hooks/claude-code-hooks/transcript.ts
- src/features/claude-code-command-loader/loader.ts
- src/features/claude-code-agent-loader/loader.ts
- src/features/claude-code-skill-loader/loader.ts
- src/features/claude-code-mcp-loader/loader.ts
- src/tools/session-manager/constants.ts
- src/tools/slashcommand/tools.ts
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
- Claude Code commands (user, project scope): sanitize model to undefined
- OpenCode commands (opencode, opencode-project scope): preserve model as-is
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Provides 'slashcommand' tool that executes commands loaded by command-loader.
Handles shell injection and file reference resolution.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)