The previous Windows implementation used System.Windows.Forms.MessageBox
which displays a blocking modal dialog requiring user interaction.
This replaces it with the native Windows.UI.Notifications.ToastNotificationManager
API (Windows 10+) which shows a non-intrusive toast notification in the corner,
consistent with macOS and Linux behavior.
- Uses native Toast API (no external dependencies like BurntToast)
- Non-blocking: notification auto-dismisses
- Graceful degradation: silently fails on older Windows versions
- Fix escaping for each platform (PowerShell: '' for quotes, AppleScript: backslash)
- 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)
Add pattern matching for 'content...is empty' format to detectErrorType function
in session-recovery hook. This fixes detection of Anthropic API errors like
'The content field in the Message object at messages.65 is empty'.
Previously only caught 'non-empty content' and 'must have non-empty content'
patterns, missing this actual API error format.
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add FallbackState interface to track message removal attempts
- Implement getLastMessagePair() to identify last user+assistant message pair
- Add executeRevertFallback() to remove message pairs when compaction fails
- Configure max 3 revert attempts with min 2 messages requirement
- Trigger fallback after 5 compaction retries exceed
- Reset retry counter on successful message removal for fresh compaction attempt
- Clean fallback state on session deletion
Resolves: When massive context (context bomb) is loaded, compaction fails and session becomes completely broken. Now falls back to emergency message removal after all retry attempts fail, allowing session recovery.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Fixed bug where remindedSessions was only cleared on user messages. Now also
clears on assistant response, enabling the todo continuation reminder to be
re-triggered on the next idle period after the assistant provides a response.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Add a new tool for managing tmux sessions with automatic tracking and cleanup:
- interactive_bash tool: Accepts tmux commands via tmux_command parameter
- Session tracking hook: Tracks omo-* prefixed tmux sessions per OpenCode session
- System reminder: Appends active session list after create/delete operations
- Auto cleanup: Kills all tracked tmux sessions on OpenCode session deletion
- Output truncation: Registered in TRUNCATABLE_TOOLS for long capture-pane outputs
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Tool names in builtinTools are lowercase ('grep', 'glob') but truncator
hooks were checking for capitalized names ('Grep', 'Glob'), causing
truncation to never trigger and resulting in context window overflow.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Message hooks like todo-continuation-enforcer and background-notification
now preserve the agent mode from the previous message when sending follow-up
prompts. This ensures that continuation messages and task completion
notifications use the same agent that was active in the conversation.
- Export findNearestMessageWithFields and MESSAGE_STORAGE from hook-message-injector
- Add getMessageDir helper to locate session message directories
- Pass agent field to session.prompt in todo-continuation-enforcer
- Pass agent field to session.prompt in BackgroundManager.notifyParentSession
Closes#59🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
When OpenCode API doesn't return parts in message response,
read directly from filesystem using readParts(messageID).
This fixes session recovery failures where tool_use IDs couldn't
be extracted because API response had empty parts array.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Replace regex-based command blocking with environment configuration
- Add cross-platform null device support (NUL for Windows, /dev/null for Unix)
- Wrap all bash commands with non-interactive environment variables
- Only block TUI programs that require full PTY
- Update schema, README docs, and all imports/exports
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Instead of blocking commands via regex pattern matching (which caused false
positives like 'startup', 'support'), now wraps all bash commands with:
- CI=true
- DEBIAN_FRONTEND=noninteractive
- GIT_TERMINAL_PROMPT=0
- stdin redirected to /dev/null
TUI programs (text editors, system monitors, etc.) are still blocked as they
require full PTY. Other interactive commands now fail naturally when stdin
is unavailable.
Closes#55 via alternative approach.
- Prevent interactive bash commands from being executed automatically
- Block commands in tool.execute.before hook
- Register in schema and main plugin initialization
- Add findMessagesWithThinkingOnly() to detect orphan thinking messages
- Inject [user interrupted] placeholder for thinking-only messages
- Expand index offset handling from 2 to 3 attempts for better error recovery
- Use constant PLACEHOLDER_TEXT for consistency across recovery functions
- OmO: Primary orchestrator (Claude Opus 4.5)
- OmO-Plan: Inherits ALL settings from OpenCode's plan agent at runtime
- description appended with '(OhMyOpenCode version)'
- Configurable via oh-my-opencode.json agents.OmO-Plan
- build/plan: Demoted to subagent when OmO enabled
- Add plan and OmO-Plan to OverridableAgentNameSchema
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Add .catch() to notify-send command to prevent GDBus.Error logs
when org.freedesktop.Notifications service is unavailable in WSL environments.
Fixes#47🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add stripJsonComments() to handle // comments in opencode.json
- Add findPackageJsonUp() for robust package.json discovery
- Replace import.meta.dirname with fileURLToPath(import.meta.url) for ESM compatibility
- Fix version showing 'unknown' when config contains JSONC comments
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add getLocalDevPath() and getLocalDevVersion() functions
- Improve getCachedVersion() with fallback to bundled package.json
- Display correct version in startup toast for local dev mode
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add configurable build agent hiding (omo_agent.disable_build)
- Add startup-toast hook to show version on OpenCode startup
- Fix auto-update-checker to respect version pinning
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Refactor grep-output-truncator into a general-purpose tool-output-truncator
that applies dynamic truncation to multiple tools based on context window usage.
Truncated tools:
- Grep, safe_grep (existing)
- Glob, safe_glob (new)
- lsp_find_references (new)
- lsp_document_symbols (new)
- lsp_workspace_symbols (new)
- lsp_diagnostics (new)
- ast_grep_search (new)
Uses the new dynamic-truncator utility from shared/ for context-aware
output size limits based on remaining context window tokens.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Change TARGET_TOOLS and AGENT_TOOLS to Set<string> for O(1) lookup
- Normalize tool names to lowercase for case-insensitive comparison
- Remove unnecessary parentSessionID guard that blocked main session triggers
- Fixes issue where Glob/Grep tool calls weren't showing agent usage reminder
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Implements hook that tracks whether explore/librarian agents have been used in a session.
When target tools (Grep, Glob, WebFetch, context7, websearch_exa, grep_app) are called
without prior agent usage, appends reminder message recommending parallel background_task calls.
State persists across tool calls and resets on session compaction, allowing fresh reminders
after context compaction - similar to directory-readme-injector pattern.
Files:
- src/hooks/agent-usage-reminder/: New hook implementation
- types.ts: AgentUsageState interface
- constants.ts: TARGET_TOOLS, AGENT_TOOLS, REMINDER_MESSAGE
- storage.ts: File-based state persistence with compaction handling
- index.ts: Hook implementation with tool.execute.after and event handlers
- src/config/schema.ts: Add 'agent-usage-reminder' to HookNameSchema
- src/hooks/index.ts: Export createAgentUsageReminderHook
- src/index.ts: Instantiate and register hook handlers
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Replace direct parts[idx].text modification with injectHookMessage
- Context now injected via filesystem (like UserPromptSubmitHook)
- Preserves original user message without modification
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Actually inject THINKING_CONFIGS into message (was defined but unused)
- Add maxTokens: 128000 for Anthropic (required for extended thinking)
- Add maxTokens: 64000 for Amazon Bedrock
- Track thinkingConfigInjected state
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
When "ultrawork" or "ulw" keyword is detected in user prompt:
- Injects ULTRAWORK_CONTEXT with agent-agnostic guidance
- Executes AFTER CC hooks (UserPromptSubmit etc.)
- Follows existing hook pattern (think-mode style)
Key features:
- Agent orchestration principles (by capability, not name)
- Parallel execution rules
- TODO tracking enforcement
- Delegation guidance
Closes#31🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Try both targetIndex and targetIndex-1 to handle system message offset
- Remove 'last assistant message' skip logic (API error means it's not final)
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Checks npm registry for latest version on session.created, invalidates
cache and shows toast notification when update is available.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Previously, token calculation accumulated ALL assistant messages' tokens,
causing incorrect usage display (e.g., 524.9%) after compaction.
Now uses only the last message's input tokens, which reflects the actual
current context window usage.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Remove unused chat message notification handler
- Remove formatDuration and formatNotifications helpers
- Simplify to event-only handling
- Remove chat.message hook call from main plugin
Background task notifications now rely on event-based system only.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Previously only checked assistant messages for empty content.
Now checks all messages except the final assistant message,
following Anthropic API rules.
Fixes: "messages.N: all messages must have non-empty content" error
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Implements retry logic with up to 5 attempts when compaction fails.
Uses exponential backoff strategy (2s → 4s → 8s → 16s → 30s).
Shows toast notifications for retry status and final failure.
Prevents infinite loops by clearing state after max attempts.
🤖 GENERATED WITH ASSISTANCE OF OhMyOpenCode
- Merge background_status into background_output with block parameter
- Replace background_result references with background_output throughout codebase
- Update tool descriptions to reflect new unified API
- Remove background-tasks.json (memory-based only)
- Simplify notification messages and tool usage instructions
Automatically disables these Claude Code hooks that duplicate oh-my-opencode functionality:
- inject_rules.py (replaced by rules-injector hook)
- inject_readme.py (replaced by directory-readme-injector hook)
- inject_knowledge.py (replaced by directory-agents-injector hook)
- remind*rules*.py (replaced by rules-injector hook)
Users can override via opencode-cc-plugin.json if needed.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add findMessageByIndexNeedingThinking for precise message targeting
- Detect "expected X found Y" error pattern for thinking block order
- Remove isLastMessage skip - recovery now handles final assistant messages
- Simplify orphan detection: any non-thinking first part is orphan
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Implements README.md injection similar to existing AGENTS.md injector.
Automatically injects README.md contents when reading files, searching
upward from file directory to project root.
Closes#14🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Replace blocking await with non-blocking timer scheduling to handle race
condition between session.idle and session.error events. When ESC abort
occurs, session.error immediately cancels the pending timer, preventing
unwanted continuation prompts.
Changes:
- Add pendingTimers Map to track scheduled continuation checks
- Cancel timer on session.error (especially abort cases)
- Cancel timer on message.updated and session.deleted for cleanup
- Reduce delay to 200ms for faster response
- Maintain existing Set-based flag logic for compatibility
This fixes the issue where ESC abort would not prevent continuation
prompts due to event ordering (idle before error)
- Extract message index from Anthropic error messages (messages.N format)
- Sort messages by time.created instead of id for accurate ordering
- Remove last message skip logic that prevented recovery
- Prioritize recovery targets: index-matched > failedMsg > all empty
- Add error logging for debugging recovery failures
Fixes issue where 'messages.83: all messages must have non-empty content' errors were not being recovered properly due to incorrect message ordering and overly restrictive filtering.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)