Removes the complex state machine and 10-second throttle (MIN_INJECTION_INTERVAL_MS)
that was causing background task completion to hang. The hook now:
- Uses straightforward error cooldown logic instead of complex injection throttling
- Removes unnecessary state tracking that was delaying continuation injection
- Maintains all safety checks (recovery mode, running tasks, error state)
- Keeps countdown behavior with toast notifications
Fixes#312 - Resolves v2.7.0 issue where background task completion would freeze
the agent due to injection delays.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Replace retry loop with intelligent fallback strategy:
- Try default installer first (better for version discovery)
- On failure, fallback to pinned version 1.0.204
- Handle corrupted downloads with direct fallback install
This addresses the sisyphus-agent workflow failure where OpenCode's installer failed
with 'Failed to fetch version information' error.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
- New src/features/builtin-commands/ module with CommandDefinition loader
- Implements init-deep command for hierarchical AGENTS.md knowledge base generation
- Adds BuiltinCommandName and BuiltinCommandNameSchema to config
- Integrates builtin commands loader into main plugin with proper config merging
- Supports disabling specific builtin commands via disabled_commands config array
🤖 Generated with assistance of https://github.com/code-yeongyu/oh-my-opencode
Add metadata() calls to background_task and call_omo_agent tools so that OpenCode UI displays session navigation hints (ctrl+x + arrow keys) like the original Task tool does. This enhances UX by providing consistent session navigation UI for background and subagent tasks.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Previously, errorBypass mode was cleared on session.idle, causing continuation
to fire again on next idle event. This led to unwanted task resumption after
user abort.
Changes:
- Don't clear errorBypass on session.idle - stay in errorBypass mode
- Clear errorBypass to idle only when user sends a new message
This ensures that once user aborts, the enforcer respects that decision until
the user explicitly sends a message to resume.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Fixes race conditions, enables continuous enforcement, and eliminates false positives/negatives.
- Complete redesign using version-token state machine for race condition prevention
- Replaced 5 separate Sets with single Map<sessionID, SessionState>
- Changed cancelCountdown() to invalidate() that ALWAYS bumps version regardless of mode
- Added background task check BEFORE starting countdown (prevents toast spam when bg tasks running)
- Added lastAttemptedAt throttling (10s minimum between attempts, set BEFORE API call)
- Removed non-interactive preemptive injection (all paths now use countdown)
- Added 3 version checks in executeInjection (start, after todo fetch, before API call)
- Removed remindedSessions flag for continuous enforcement
Fixes:
1. Race condition where session.idle fired before message.updated cleared reminded state
2. Single-shot behavior that prevented multiple reminders
3. Phantom reminders sent even after agent started working
4. Toast spam when background tasks are running
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Previously, when an LSP server was configured but not installed, the error
message said "No LSP server configured" which was misleading. Now the
error message distinguishes between:
1. Server not configured at all
2. Server configured but not installed (with installation hints)
The new error messages include:
- Clear indication of whether server is configured vs installed
- Installation commands for each built-in server
- Supported file extensions
- Configuration examples for custom servers
Fixes#304
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
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)
* fix: disable todo-continuation for plan mode agents
Plan mode agents (e.g., 'plan', 'Planner-Sisyphus') only analyze and plan,
they don't implement. The todo-continuation hook was incorrectly triggering
for these agents because the existing write permission check only looked at
the stored message's tools field, not the agent's permission configuration.
This fix adds an explicit check for plan mode agents by name to skip the
todo continuation prompt injection.
Fixes#293
* chore: changes by sisyphus-dev-ai
* fix: address review comments for plan mode agent check
- Use exact match for plan mode agents instead of substring match to
prevent false positives on agents like 'deployment-planner'
- Add plan mode agent check to preemptive injection path (non-interactive
mode) which was missing from the initial fix
---------
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
- Remove eager SG_CLI_PATH constant; use getSgCliPath() lazily in checkEnvironment()
- Move setInterval to inside createCommentCheckerHooks() with guard flag
These changes eliminate module-level side effects that could trigger segfaults
during plugin initialization on Bun 1.3.5 + macOS 15 due to createRequire()
being called during module evaluation.
Fixes#292
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Refactored state management to use a single source of truth per-session using
a state machine pattern with versioning. Key improvements:
- Replace multiple Sets with unified SessionState map for cleaner logic
- Add version tokens to invalidate pending callbacks on state changes
- Improve countdown timer management with proper cleanup
- Add throttle check to prevent rapid injection spam (10s minimum interval)
- Enhance injection checks: re-verify todos before injection, check bg tasks
- Handle message.part.updated events for streaming activity detection
- Add isMainSession() helper for consistent session filtering
- Clearer event handler logic with inline comments explaining state transitions
- Better logging for debugging state changes and decision points
State modes: idle → countingDown → injecting → idle (with recovery/errorBypass)
Prevents race conditions from async operations and UI state changes during countdown.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
The DCP pruning modules were using a hardcoded path (~/.config/opencode/sessions) that doesn't exist.
Sessions are actually stored at ~/.local/share/opencode/storage/message.
All pruning modules now import MESSAGE_STORAGE from hook-message-injector, which uses the correct path via getOpenCodeStorageDir().
This fixes the issue where DCP would fail with 'message dir not found' when trying to recover from token limit errors.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
- Add customPrompt parameter to runCommentChecker function
- Pass --prompt flag to comment-checker CLI when custom_prompt is configured
- Wire up config from plugin initialization
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add finally block in notifyParentSession() to ensure task cleanup
- Call tasks.delete(taskId) after notification sent or on error
- Prevents memory accumulation when tasks complete or fail
- taskId captured before setTimeout to ensure proper cleanup in async context
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Previously, the validator only checked for tool_use parts, causing 'Expected thinking but found text' errors when messages had text content. Renamed hasToolParts to hasContentParts to include both tool_use and text types.
Also added CommentCheckerConfigSchema support for custom prompt configuration.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Expand the search range when finding empty messages by index to better handle API index vs storage index mismatches. This increases robustness when searching for messages to sanitize with more fallback indices.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Convert session-manager storage layer from synchronous blocking I/O (readdirSync, readFileSync) to non-blocking async I/O (readdir, readFile from fs/promises). This fixes hanging issues in session_search and other tools caused by blocking filesystem operations.
Changes:
- storage.ts: getAllSessions, readSessionMessages, getSessionInfo now async
- utils.ts: Updated utility functions to be async-compatible
- tools.ts: Added await calls for async storage functions
- storage.test.ts, utils.test.ts: Updated tests with async/await patterns
This resolves the session_search tool hang issue and improves overall responsiveness.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
Pre-emptively fix empty messages in sessions before running document compression to prevent summarization failures. This prevents accumulation of empty message placeholders that can interfere with context management.
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
* feat(cli): librarian uses gemini-3-flash when hasGemini (antigravity auth)
Closes#294
* feat(cli): add explore to gemini-3-flash when hasGemini + update docs
* feat(cli): fix explore agent fallback logic to use haiku for max20 Claude users
- Use gemini-3-flash for both librarian and explore when hasGemini
- Use haiku for explore when Claude max20 is available (hasClaude && isMax20)
- Fall back to big-pickle for both when other models unavailable
- Updated all README files to document the fallback precedence
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Refactored DCP (Dynamic Context Pruning) to execute FIRST when token limit errors occur
- Previously, DCP only ran as a fallback after compaction failed
- Now DCP runs first to prune redundant context, then compaction executes immediately
- Simplified config flag: dcp_on_compaction_failure → dcp_for_compaction
- Updated documentation in all 4 README files (EN, KO, JA, ZH-CN)
- Updated schema.ts with new config field name and documentation
- Updated executor.ts with new DCP-first logic flow
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add AntigravityTokenRefreshError custom error class with code, description, and status fields
- Implement parseOAuthErrorPayload() for parsing Google's various OAuth error response formats
- Add retry logic with exponential backoff (3 retries, 1s→2s→4s delay) for transient failures
- Add special handling for invalid_grant error - immediately throws without retry and clears caches
- Add invalidateProjectContextByRefreshToken() for selective cache invalidation
- Update fetch.ts error handling to work with new error class and cache invalidation
🤖 Generated with assistance of OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
The installed_plugins.json file has two versions:
- v1: plugins stored as direct objects
- v2: plugins stored as arrays
Use discriminated union types (InstalledPluginsDatabaseV1/V2) for proper
type narrowing based on version field.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* fix: defer config error toast to session.created for TUI readiness
Removed showToast calls from loadConfigFromPath() function. Error notifications were not visible during plugin initialization because the TUI was not ready yet.
Changes:
- Removed immediate showToast calls from validation error handler
- Removed immediate showToast calls from file load error handler
- Errors are still captured via addConfigLoadError() for later display
- auto-update-checker hook will display errors via showConfigErrorsIfAny() after session.created event
This ensures error messages are displayed when the TUI is fully ready and able to render them properly.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
* fix: await config error toast before showing startup toast
Ensure config errors are awaited and displayed before the startup spinner toast is shown. Changed showConfigErrorsIfAny(ctx).catch(() => {}) to await showConfigErrorsIfAny(ctx) to guarantee proper error handling order.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Make DCP behavior opt-in via new 'dcp_on_compaction_failure' experimental flag (disabled by default).
When enabled, Dynamic Context Pruning only executes after summarization fails, then retries compaction. By default, DCP runs before truncation as before.
Changes:
- Add 'dcp_on_compaction_failure' boolean flag to experimental config (default: false)
- Update executor.ts to check flag before running DCP behavior
- Add corresponding documentation to all 4 README files (EN, KO, JA, ZH-CN)
- Update JSON schema
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Add Aaron Iker (@aaroniker) with GitHub and X links to the sponsors
section in all language README files (EN, KO, JA, ZH-CN).
🤖 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#276 - The look_at tool was constructing invalid file:// URLs on Windows
by using template literals. Now uses Node.js pathToFileURL() which correctly
handles backslashes, spaces, and the triple-slash prefix required on Windows.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
The test mock for ctx.$ was not handling tagged template literals correctly,
causing it to ignore interpolated values. Additionally, utility functions that
check for command availability (osascript, notify-send, etc.) were returning
null in test environments, causing sendNotification to exit early.
Changes:
- Fixed template literal reconstruction in mock $ function
- Added spyOn mocks for all utility path functions
- All session-notification tests now passing (11/11)
Fixes#273
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
- Add process.exit(0) in runner.ts for immediate termination
- Fix Timer type to ReturnType<typeof setInterval> in manager.ts
- Add .unref() to BackgroundManager polling interval
- Add cleanup() method to BackgroundManager
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)