The `forceZsh` option on Linux/macOS would use a hardcoded zshPath
without checking if zsh actually exists on the system. This caused
hook commands to fail silently with exit code 127 on systems without
zsh installed.
Changes:
- Always verify zsh exists via findZshPath() before using it
- Fall back to bash -lc if zsh not found (preserves login shell PATH)
- Fall through to spawn with shell:true if neither found
The bash fallback ensures user PATH from .profile/.bashrc is available,
which is important for hooks that depend on custom tool locations.
Tested with opencode v1.1.3 - PreToolUse hooks now execute correctly
on systems without zsh.
Co-authored-by: Anas Viber <ananas-viber@users.noreply.github.com>
- 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)
Add hadFrontmatter and parseError flags to FrontmatterResult interface to enable error handling in skill loading.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Rewrite permission-compat.ts with runtime version detection
- createAgentToolRestrictions() returns correct format per version
- v1.1.1+ uses permission format, older uses tools format
- Add migrateToolsToPermission/migratePermissionToTools helpers
- Update test suite for new API
🤖 Generated with assistance of OhMyOpenCode
https://github.com/code-yeongyu/oh-my-opencode
- Update preemptive-compaction hook to use 1M limit when env vars set
- Update dynamic-truncator to use 1M limit for output truncation
- Update context-window-monitor to use 1M limit for usage tracking
Previously hardcoded 200k limits caused compaction at 140k tokens even
with 1M context enabled. Now respects env vars consistently with base
opencode implementation.
Fixes compaction triggering too early with Claude Sonnet 4.5 1M context.
Related to anomalyco/opencode#6660
The installer now dynamically detects and uses the appropriate config
directory based on whether opencode CLI or opencode-desktop (Tauri) is
being used:
- opencode CLI: ~/.config/opencode/ (all platforms)
- opencode-desktop on Linux: ~/.config/ai.opencode.desktop/
- opencode-desktop on macOS: ~/Library/Application Support/ai.opencode.desktop/
- opencode-desktop on Windows: %APPDATA%/ai.opencode.desktop/
Key changes:
- Add new opencode-config-dir.ts module with platform-specific path resolution
- Support dev builds with ai.opencode.desktop.dev identifier
- Backward compatibility: checks legacy ~/.config/opencode/ first
- Refactor config-manager.ts to use dynamic paths via config context
- Update doctor plugin check to use shared path utilities
Fixes#440
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
* 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>
- Regenerated root AGENTS.md with overview, structure, and complexity hotspots
- Regenerated all 7 subdirectory AGENTS.md files: hooks, tools, features, agents, cli, auth, shared
- Used 11 background explore agents for comprehensive feature and architecture analysis
- All files within size limits (root: 112 lines, subdirs: 57-68 lines)
- Includes where-to-look guide, conventions, anti-patterns, and agent model information
🤖 Generated with assistance of oh-my-opencode
- Extract AGENT_NAME_MAP, HOOK_NAME_MAP, and migration functions to src/shared/migration.ts
- Add comprehensive BDD-style test suite in src/shared/migration.test.ts with 15 test cases
- Export migration functions from src/shared/index.ts
- Improves testability and maintainability of config migration logic
Tests cover:
- Agent name migrations (omo → Sisyphus, OmO-Plan → Planner-Sisyphus)
- Hook name migrations (anthropic-auto-compact → anthropic-context-window-limit-recovery)
- Config key migrations (omo_agent → sisyphus_agent)
- Case-insensitive lookups and edge cases
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
DCP was failing to find session messages because it was looking in
~/.config/opencode/sessions instead of ~/.local/share/opencode/storage.
Unified all hooks to use getOpenCodeStorageDir() for cross-platform consistency.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
When getContextWindowUsage returns null (no assistant messages yet, API
failure, or first request in session), the truncator was returning
untruncated output. This caused context overflow crashes on early
requests or when usage lookup failed.
Now applies conservative truncation (50k tokens) as fallback, preventing
prompt-too-long errors that crash sessions.
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>
Include output tokens from last response in getContextWindowUsage calculation.
Output tokens become part of next request's input (conversation history), so
they must be counted to avoid overestimating remainingTokens. This aligns with
preemptive-compaction's calculation which already includes output tokens correctly.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* feat(tools): add session management tools for OpenCode sessions
- Add session_list tool for listing sessions with filtering
- Add session_read tool for reading session messages and history
- Add session_search tool for full-text search across sessions
- Add session_info tool for session metadata inspection
- Add comprehensive tests for storage, utils, and tools
- Update documentation in AGENTS.md
Closes#132
* fix(session-manager): add Windows compatibility for storage paths
- Create shared/data-path.ts utility for cross-platform data directory resolution
- On Windows: uses %LOCALAPPDATA% (e.g., C:\Users\Username\AppData\Local)
- On Unix: uses $XDG_DATA_HOME or ~/.local/share (XDG Base Directory spec)
- Update session-manager/constants.ts to use getOpenCodeStorageDir()
- Update hook-message-injector/constants.ts to use same utility
- Remove dependency on xdg-basedir package in session-manager
- Follows existing pattern from auto-update-checker for consistency
---------
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Implements dual-path config resolution on Windows to ensure backward compatibility
while maintaining cross-platform consistency. Checks ~/.config first (new standard),
falls back to %APPDATA% for existing installations.
Resolves#129🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Created src/shared/config-errors.ts to isolate config error state management
- Removed function re-exports (getConfigLoadErrors, clearConfigLoadErrors) from main index.ts
- Only ConfigLoadError type is re-exported from main module to avoid OpenCode calling it as a plugin
- Updated auto-update-checker hook to import from shared/config-errors instead of main index
- Fixes "TypeError: undefined is not an object" crash when OpenCode iterated through ALL exports and called clearConfigLoadErrors(input) which returned undefined
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Use os.tmpdir() instead of hardcoded /tmp for cross-platform temp files
- Use os.homedir() with USERPROFILE fallback for Windows home directory
- Disable forceZsh on Windows (zsh not available by default)
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- 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)
Extract and generalize dynamic output truncation logic from grep-output-truncator.
Provides context window-aware truncation that adapts based on remaining tokens.
Features:
- truncateToTokenLimit(): Sync truncation with configurable header preservation
- getContextWindowUsage(): Get current context window usage from session
- dynamicTruncate(): Async truncation that queries context window state
- createDynamicTruncator(): Factory for creating truncator instance
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add snake-case.ts: objectToSnakeCase, objectToCamelCase utilities
- Add tool-name.ts: transformToolName with PascalCase conversion
- Add pattern-matcher.ts: findMatchingHooks for hook config matching
- Add hook-disabled.ts: isHookDisabled for hook config validation
- Add temporary stub types at src/hooks/claude-code-hooks/types.ts
- Export all new utilities from src/shared/index.ts
Stub types will be replaced with full implementation in Task 1.
Import paths adjusted from opencode-cc-plugin structure to oh-my-opencode.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)