Setting concurrency to 0 means unlimited (Infinity).
Works for defaultConcurrency, providerConcurrency, and modelConcurrency.
🤖 Generated with [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Previously, concurrency was released in finally block AFTER prompt completion.
This caused queued tasks to remain blocked while prompt hangs.
Now release happens BEFORE prompt, allowing next queued task to start immediately
when current task completes, regardless of prompt success/failure.
Also added early release on session creation error for proper cleanup.
- Move clearNotificationsForTask() to finally block to ensure cleanup even on success
- Add TASK_TTL_MS (30 min) constant for stale task detection
- Implement pruneStaleTasksAndNotifications() to remove expired tasks and notifications
- Add comprehensive tests for pruning functionality (fresh tasks, stale tasks, notifications)
- Prevents indefinite Map growth when tasks complete without errors
🤖 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)
- 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)
Fixes#191
This commit ensures that the user's selected model is preserved when
background tasks complete and notify their parent sessions.
Changes:
- Add parentModel field to BackgroundTask and LaunchInput interfaces
- Capture model context when launching background tasks
- Pass model context when notifying parent sessions after task completion
Impact:
- Users with OAuth providers (Google, Anthropic) will now have their
model selection preserved across background task continuations
- Background agents no longer revert to hardcoded defaults
Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
Previously, background_cancel(all=true) only cancelled direct child tasks, leaving grandchildren and deeper nested tasks uncancelled. This caused background agents to continue running even when their parent session was cancelled.
Changes:
- Added getAllDescendantTasks() method to BackgroundTaskManager for recursive task collection
- Updated background_cancel to use getAllDescendantTasks instead of getTasksByParentSession
- Added comprehensive test coverage for nested task cancellation scenarios
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Import subagentSessions from claude-code-session-state in both manager.ts and session-notification.ts
- Add sessionID to subagentSessions Set when creating background task session
- Remove sessionID from subagentSessions when background task session is deleted
- Check if session is in subagentSessions before triggering notification
Fixes#70: Notification hook no longer triggers for subagent idle events
🤖 Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Remove call_omo_agent from blocked tools (only calls explore/librarian, safe)
- Keep task and background_task blocked to prevent recursion
- Add checkSessionTodos() to verify incomplete todos before marking tasks complete
- Update session.idle event handler to respect todo status
- Add polling check in task completion to wait for todo-continuation
🤖 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)
- Disable 'task' and 'call_omo_agent' tools in BackgroundManager
- Disable recursive background operation tools in call_omo_agent sync execution
- Prevents agents from spawning background tasks or calling themselves
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Disable 'task' and 'call_omo_agent' tools in BackgroundManager
- Disable recursive background operation tools in call_omo_agent sync execution
- Prevents agents from spawning background tasks or calling themselves
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
When an invalid or unregistered agent is passed to background_task or
call_omo_agent, OpenCode crashes with "TypeError: undefined is not an
object (evaluating 'agent.name')". This fix:
- Validates agent parameter is not empty before launching
- Catches prompt errors and returns friendly error message
- Notifies parent session when background task fails
- Improves error message to guide user on resolution
Fixes#37🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add prompt field to BackgroundTask to store original prompt
- Add lastMessage/lastMessageAt to TaskProgress for real-time monitoring
- Extract last assistant message during polling
- Update formatTaskStatus() to display prompt (truncated 300 chars) and
last message (truncated 500 chars) with timestamp
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Rename omo-task to call-omo-agent with mandatory run_in_background parameter
- Implement background mode using BackgroundManager (fire-and-forget abort)
- Implement sync mode with existing subagent logic
- Fix background_cancel: use fire-and-forget abort to prevent parent session interruption
- Add call_omo_agent to tool disable list in explore/librarian agents
- Add call_omo_agent to tool disable list in BackgroundManager
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Background task tool이 child session을 생성할 때 background_task, background_output, background_cancel 도구를 자동으로 비활성화합니다. OpenCode Task tool 패턴과 동일하게 무한 재귀 호출을 방지합니다.
- manager.ts: promptAsync 호출 시 tools 설정 추가
- index.ts: 불필요한 agent 레벨 disable 설정 제거 (manager에서 처리)
- notification: tool calls 카운트 제거 (정확하게 트래킹되지 않음)
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- 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
session.prompt() fails due to response Zod validation.
promptAsync is fire-and-forget, no response parsing.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
TUI API sends to active session (could be subagent).
Use getMainSessionID() to explicitly target main session.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
session.prompt() fails with validation errors in background context.
Switch to TUI API which directly manipulates the main session input.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
Previous implementation had too many defensive checks that blocked
normal cases. Simplified to: Toast -> 200ms delay -> session.prompt()
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Replace promptAsync() with session.prompt() for visible TUI updates
- Add main session check to skip subagent sessions
- Add session status idle check before sending prompt
- Add 200ms debounce with re-check to prevent race conditions
- Fallback to pending queue when session is busy
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Use `promptAsync` instead of `prompt` to avoid session state conflicts
- Use `tui.showToast` for immediate visible feedback
- Hack: Trigger `tui.submitPrompt` after message injection to force TUI refresh and trigger AI response
- Update `BackgroundManager` to accept `PluginInput` for directory access
prompt() waits for AI response, ensuring message is actually processed.
Added response logging to debug if message delivery works.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
promptAsync() doesn't show visible message to user.
Use tui.showToast() instead for immediate visible notification.
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
session.get() doesn't return status field - it was always undefined.
Now using session.status() API which returns { type: 'idle' | 'busy' | 'retry' }
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Change prompt() to promptAsync() for parent session notification
- Only mark 404 errors as permanent task failure
- Add defensive progress initialization
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Add notifyParentSession() to send message to parent session via prompt()
- Agent receives completion notification immediately, not waiting for next chat.message
- Includes task ID, description, duration, tool calls in notification
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
- Replace unreliable event-based tracking with 2-second polling
- Use SDK session.get() to detect completion (status === idle)
- Use SDK session.messages() to count tool_use parts for progress
- Auto-start polling on launch, auto-stop when no running tasks
- Resume polling on restore if running tasks exist
Fixes: Child session events not reaching plugin event handler
🤖 GENERATED WITH ASSISTANCE OF [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)