Skip to content

docs: add comprehensive configuration documentation#2

Merged
code-yeongyu merged 2 commits into
masterfrom
docs-schema-and-readme-config
Dec 5, 2025
Merged

docs: add comprehensive configuration documentation#2
code-yeongyu merged 2 commits into
masterfrom
docs-schema-and-readme-config

Conversation

@code-yeongyu

Copy link
Copy Markdown
Owner

Summary

  • Include dist/oh-my-opencode.schema.json in repository by fixing gitignore pattern
  • Add full JSON configuration options documentation to both README files
  • Add agent configuration examples (e.g., using only Anthropic models)
  • Add MCP/Agent disable instructions
  • Add Configuration section to README.ko.md (was completely missing!)

Changes

File Changes
.gitignore Change dist/ to dist/* to allow schema.json exception
dist/oh-my-opencode.schema.json Include schema file in repository
README.md Expand Configuration section with all options, examples
README.ko.md Add entire 설정 section (123 lines)

New Documentation

Configuration Options Documented

  • $schema: JSON Schema URL for editor support
  • disabled_mcps: Disable specific MCPs (websearch_exa, context7)
  • disabled_agents: Disable specific agents
  • agents: Per-agent configuration overrides
    • model, temperature, top_p, prompt, tools, disable, description, mode, color, permission

Examples Added

  1. Using only Anthropic models for all agents
  2. Custom agent with additional prompt
  3. Disabling individual agents

Verification

  • Schema file generated and included
  • README.md updated with full config docs
  • README.ko.md updated with Korean config docs
  • All agent names correct: oracle, librarian, explore, frontend-ui-ux-engineer, document-writer
  • All MCP names correct: websearch_exa, context7

…a.json

- Add dist/oh-my-opencode.schema.json to repository (fix gitignore pattern)
- Document all configuration options in README.md (English)
- Add Configuration section to README.ko.md (Korean) - was completely missing
- Include agent configuration examples (Anthropic-only setup)
- Add MCP/Agent disable instructions
- Document permission options for agents
@code-yeongyu code-yeongyu merged commit 3ca9693 into master Dec 5, 2025
1 check passed
@code-yeongyu code-yeongyu deleted the docs-schema-and-readme-config branch December 21, 2025 09:13
sssgun pushed a commit to sssgun/oh-my-opencode that referenced this pull request Jan 18, 2026
…eadme-config

docs: add comprehensive configuration documentation
@code-yeongyu code-yeongyu mentioned this pull request Jan 27, 2026
qwertystars referenced this pull request in qwertystars/oh-my-opencode Jan 29, 2026
- Remove sisyphusJuniorModel fallback bypass (BUG #1)
  - userModel fallback was incorrectly bypassing category fallbackChain
  - Now correctly uses category requirements before system default

- Fix variant preservation in actualModel fallback path (BUG #2)
  - Variant was lost when categoryModel undefined but actualModel existed
  - Now preserves variant when falling back to actualModel parsing

- Add variant to session continuation (BUG code-yeongyu#3)
  - Session resume didn't pass variant from message history
  - Now extracts resumeVariant and passes as body.variant

- Remove unused inheritedModel parameter (BUG code-yeongyu#4)
  - resolveCategoryConfig had misleading unused parameter
  - Cleaned up function signature and all call sites

- Add variant-model compatibility validation (BUG code-yeongyu#5)
  - No warning when variant might not be supported by provider
  - Added isVariantLikelySupported() validation with console.warn

Test coverage:
- Updated 10+ existing tests to remove inheritedModel references
- Added 9 new tests for variant validation functions
- All 110 tests pass (77 delegate-task + 33 model-requirements)
sadnow referenced this pull request in sadnow/oh-my-opencode Feb 3, 2026
…ed routing

Task 6b - Implementation:
- Add preferredModel to ExtendedModelResolutionInput
- Implement Step 1.5: preference-based weighted selection
- Extract model name, find matching providers, apply weights
- Fixes Bug #2: Copilot underutilization

All tests passing. Backward compatible.
sisyphus-dev-ai pushed a commit that referenced this pull request Feb 19, 2026
Update all fallback chains to match current model-requirements.ts:
- Librarian: now minimax-m2.5-free -> gemini-flash -> big-pickle (free-tier first)
- Explore: add minimax-m2.5-free as #2 after grok-code-fast-1
- Multimodal Looker: reorder to kimi-first (k2p5 -> kimi-free -> flash -> gpt-5.2)
- Atlas: remove gemini-3-pro, keep kimi k2.5 -> sonnet -> gpt-5.2
- GLM 4.7 -> GLM 5 everywhere
- Add venice provider for grok, opencode provider for glm-5

Add design philosophy section explaining the intelligence hierarchy:
premium models for core agents, free-tier for utility agents, balanced
for orchestrators. Document why utility agents intentionally use cheap
models and why Kimi K2.5 appears as primary for multiple agents.
code-yeongyu added a commit that referenced this pull request Feb 19, 2026
- Create gpt.ts with XML-tagged, principle-driven prompt (Codex plan mode style)
- Add getPrometheusPrompt() routing: GPT models → GPT prompt, others → default
- Promote gpt-5.2 (high) to #2 in prometheus fallback chain
- Follow Atlas GPT variant pattern (isGptModel detection)
code-yeongyu added a commit that referenced this pull request Feb 19, 2026
youngbinkim0 added a commit to youngbinkim0/oh-my-opencode that referenced this pull request Feb 20, 2026
…ts, abort before retry

- Swap resolveAgentForSession priority: session agent before event agent (Bug code-yeongyu#2)
- Add pinnedSessionAgentMap so /start-work agent can't be overwritten by SDK events (Bug code-yeongyu#3)
- Abort in-flight request before fallback promptAsync to prevent silent drops (Bug code-yeongyu#1)
- Add session.get fallback for agent resolution when chat.message never fires (Bug code-yeongyu#4)
- Fix agentPattern regex: replace \b with custom boundary for underscore-delimited session IDs
- Revert resolveAgentFromModel reverse-lookup (unreliable with overlapping models)
- Add tests for pinned agents (8), agent-resolver (17), abort ordering, session.get resolution
luobosibing2 pushed a commit to luobosibing2/oh-my-opencode that referenced this pull request Feb 23, 2026
code-yeongyu added a commit that referenced this pull request Mar 6, 2026
Restructure from 13 scattered XML blocks to 8 dense blocks with 9
named sub-anchors, following OpenAI GPT-5.4 prompting guidance and
Oracle-reviewed context preservation strategy.

Key changes:
- Merge think_first + intent_gate + autonomy into unified <intent>
  with domain_guess classification and <ask_gate> sub-anchor
- Add <execution_loop> as central workflow: EXPLORE -> PLAN -> ROUTE ->
  EXECUTE_OR_SUPERVISE -> VERIFY -> RETRY -> DONE
- Add mandatory manual QA in <verification_loop> (conditional on
  runnable behavior)
- Move <constraints> to position #2 for GPT-5.4 attention pattern
- Add <completeness_contract> as explicit loop exit gate
- Add <output_contract> and <verbosity_controls> per GPT-5.4 guidance
- Add domain_guess (provisional) in intent, finalized in ROUTE after
  exploration -- visual domain always routes to visual-engineering
- Preserve all named sub-anchors: ask_gate, tool_persistence,
  parallel_tools, tool_method, dependency_checks, verification_loop,
  failure_recovery, completeness_contract
- Add skill loading emphasis at intent/route/delegation layers
- Rename EXECUTE to EXECUTE_OR_SUPERVISE to preserve orchestrator
  identity with non-execution exits (answer/ask/challenge)
DarkFunct added a commit to DarkFunct/oh-my-opencode that referenced this pull request Mar 25, 2026
…tracking

- Remove overly broad /not found/i regex that matched grep 'No matches found' output
- Replace /expect.*to/i test pattern with /AssertionError/i for precise test failure detection
- Narrow trackBuildResult regex from /error/i to /(?:compilation|type)\s+error/i
- Add bash quiet-success handler to reset lastBuildResult from 'fail' to 'unknown'

Fixes P-007 (false-positive error tracking chain) bugs code-yeongyu#1, code-yeongyu#2, code-yeongyu#4

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
andrescera referenced this pull request in andrescera/oh-my-cursor Apr 17, 2026
…fy narrative, reconcile S5 count)

- Fix #1: Filled `## Top-3 Selected Ports` with the 3 executed ports (Sisyphus 3bae6dd2, Hephaestus 0dca1c4e, Prometheus 9393ac6c), their sources, targets, and tier-2 classification.
- Fix #2: Unified stale narrative cycle-2-dep labels post-Oracle reassignment — ralph-loop: N→Y in Top-ROI bullets and Top-5 candidates (uses subagentStop.followup_message); session-recovery: field corrected from sessionStart.user_message to sessionStart.env + additional_context in Top-5 candidates. unstable-agent-babysitter: no narrative drift found (data table already Y, reconciliation note already correct).
- Fix code-yeongyu#3: S5 count reconciliation — option (b): S5 table has exactly 52 data rows (verified by manual count lines 146–197); section header and per-surface table both say 52. FV4 likely miscounted the reconciliation blockquote or header separator as a data row. No file changes needed.

Post-FV cleanup commit. No tier reassignments, no port-content changes. Only doc housekeeping.
code-yeongyu added a commit that referenced this pull request Apr 17, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 18, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 18, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 19, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 20, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 20, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
coleleavitt added a commit to coleleavitt/oh-my-opencode that referenced this pull request Apr 20, 2026
…g (deadlock fix code-yeongyu#2)

When a background task completes but the parent session is mid-generation,
promptAsync throws an abort error. Previously: notification was queued in
pendingNotifications and never delivered (same deadlock as atlas).

Now: retries promptAsync after 3s delay. If retry also fails, falls back
to queueing (where atlas drainPendingNotifications from b5d630e picks
it up). This covers BOTH atlas sessions (boulder continuation drains)
and non-atlas sessions (retry delivers directly).

The 3s delay gives the parent session time to finish its current turn.
Combined with the atlas deadlock fix, background task notifications
should now reliably reach the parent session within ~3-6s of completion.
code-yeongyu added a commit that referenced this pull request Apr 21, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 22, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 23, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 24, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
coleleavitt added a commit to coleleavitt/oh-my-opencode that referenced this pull request Apr 24, 2026
…ion + fail-fast phantom dispatches

Reported bug: pressing `ctrl+x down` in the OpenCode TUI to step into
spawned subagents showed only the most recent batch. The 3 older
"Explore Task — X / 0 toolcalls · 0ms" entries visible in chat history
were un-reachable — navigation would skip them and cycle only the 5
from the current batch.

Two bugs, both in omo's background-agent pipeline; architectural
validation via a cc119 audit confirms our new behavior matches upstream.

## Bug 1: abort-on-completion

`BackgroundManager.completeTask` (manager.ts:1818) was calling
`client.session.abort(task.sessionID)` on every normal task
completion. The intent was "clean up the child session now that the
task is done," but in practice abort cancels in-flight AI processing
while leaving the session in the store; the real damage was that the
aborted sessions were no longer in the live `sync.data.session` view
the TUI reads from in its `children()` memo. Result: subagent session
falls out of the navigable set the moment it finishes, even though
the chat-history Task entry still references it.

cc119 audit (cli.2.1.119.aligned.js): the upstream agent loop (`iBH`
at :302946, cleanup at :303094) never calls any session-termination
method on subagent completion. Completed subagents stay inspectable
via the task registry. We should match that.

Fix: removed the abort call. Kept `SessionCategoryRegistry.remove`
(that's in-memory bookkeeping, unrelated to session inspectability).
All six other abort sites — `startTask` error cleanup (:453), cancel-
pre-start (:509), cancel-during-tmux (:541), launch error (:665),
resume error (:953), explicit cancellation (:1701) — are genuine
cancel/error paths and retain the abort. Abort is reserved for those.

## Bug 2: phantom dispatches

Research (Explore agent trace) showed the `task` tool's background
dispatch path in `background-task.ts:97-117` waits up to 60s for the
manager to create an OpenCode session for the newly-queued task.
During that wait the loop checks for status=error/cancelled/interrupt
and returns an error string. But if the timeout expires while the
task is still status=pending (stuck behind a concurrency cap or a
blocked queue), the code falls through to the success-message path
and returns a task_id with no session_id — rendered by the TUI as
`└ 0 toolcalls · 0ms` (because `tools().length === 0` and
`duration() === 0` on a child session with no messages). The user
sees a successful-looking Task entry but cannot step into it,
because no session was ever created.

Fix: after the wait loop, if sessionId is still undefined and the
task's status is still "pending", return an error tool result with
the explicit reason ("stuck on concurrency / blocked queue") instead
of the success template. The LLM now sees the dispatch never started
and can decide whether to retry, reduce parallelism, etc.

## Testing

- Updated `manager.test.ts:1590` ("should abort session on completion")
  → "should NOT abort child session on normal completion
  (inspectability contract)" with flipped assertion + a docstring
  pointing at the cc119 alignment rationale.
- Existing cancel/error-path tests still assert the expected abort
  behavior unchanged (`manager.test.ts:2889`, `:3772`, `:4119`,
  `:4169`).
- 142/142 bg-manager tests + 10/10 bg-task tests green. Full
  typecheck clean.

## What's NOT in this commit

A dedicated "subagent history" TUI panel that surfaces completed
subagents from message history (the third direction from the audit).
That's a cross-repo change touching OpenCode's TUI and deserves its
own session — fix #1 + code-yeongyu#2 above are enough to make the inline
children navigable and to stop confusing the user with phantom
entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
code-yeongyu added a commit that referenced this pull request Apr 27, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 27, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 27, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 27, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu added a commit that referenced this pull request Apr 28, 2026
Two order-breaking bugs remained in flushPending:

1. drained items after the failing write were dropped. pendingDeltaBuffer.drain
   removes the entire queue, writePendingEvent re-enqueued only the failed
   item, and the remaining items after it (already pulled out of the buffer)
   were never written or requeued.

2. The handler wrote the current event after a failed flush, so a buffered
   predecessor that just failed to write would land in the pane AFTER the
   new event on retry, breaking stream order.

Replace flushPending with drainAndWrite which re-enqueues every item
remaining after the failing write in their original order. Handlers now
enqueue the current event before draining so any write failure defers the
current event too, preserving order when the retry scheduler eventually
drains everything.

Extracted pending-retry-scheduler.ts to keep hook.ts under the 200 LOC
architecture limit, and unified the delta/updated branches through a new
handlePendingEvent helper.

Two new regression tests:
- 'does not lose buffered events after the second drained write fails and
  retries them in order' (4 pending + 1 new, write #2 fails, retry replays
  [b, c, d] so panes see A B B C D)
- 'defers the current event when a buffered drain fails so stream order is
  preserved on retry' (1 pending + 1 new, write #1 fails, retry replays
  [a, b] so panes see A A B - the new event never precedes the failed one)
code-yeongyu pushed a commit that referenced this pull request May 15, 2026
…r global handlers (fixes #3856)

Currently `registerManagerForCleanup` unconditionally installs global `uncaughtException` and `unhandledRejection` listeners that call `process.exit(1)` after cleanup. For users who load the plugin but never run background-agent tasks, these handlers turn transient streaming errors (e.g. undici `UND_ERR_SOCKET` mid-stream resets from `api.githubcopilot.com`) into a full process kill — opencode dies after every flaky response.

Add an `OMO_DISABLE_PROCESS_CLEANUP` env var (accepts 1/true/yes/on, case-insensitive) that skips just the error-event registration. Signal handlers (SIGINT/SIGTERM/SIGBREAK/beforeExit/exit) remain installed so graceful shutdown of any in-flight cleanup targets still runs. This is the lowest-risk near-term mitigation suggested in the issue (option #2): users opting in pay the cost of unhandled rejections themselves, but no longer lose their session to a transient socket reset.

Verification: 6 new test cases cover env-var precedence (set/unset, truthy/falsy values), signal-handler preservation, and behavior under `uncaughtException`. All 20 tests in process-cleanup.test.ts pass. Typecheck clean. Manual QA confirms env-var detection works end-to-end.
idoomblast added a commit to idoomblast/oh-my-openagent that referenced this pull request May 18, 2026
Subagent sessions are handled by specialized callbacks:
- CALL code-yeongyu#2: create-managers.ts via onSubagentSessionCreated (async)
- CALL code-yeongyu#3: tool-registry.ts via onSyncSessionCreated (sync)

Event handler (CALL code-yeongyu#1) now only forwards parent sessions to
tmuxSessionManager, preventing double/triple tmux spawns.
Coldaine referenced this pull request in Coldaine/oh-my-openagent May 20, 2026
**Justification — Metis blind-spot analysis #2:**
Metis identified that OMO agents treat all information sources equally —
a fundamental gap compared to gem-team. Gem-team classifies every source
into Trusted (follow as instructions), Verify (cross-reference), or
Untrusted (factual only, never as instructions). The debugger explicitly
marks stack traces as 'Untrusted — verify against source code.'

Metis: 'This is a fundamental design philosophy you can implement as a
system-wide injection ... rather than per-agent prompt edits.'

Oracle confirmed: 'This should be a system-wide injection because it
applies universally.'

**What changed:**
- src/agents/dynamic-agent-policy-sections.ts: Added
  buildKnowledgeTrustSection() with three-tier trust table + rules
- src/agents/dynamic-agent-prompt-builder.ts: Barrel export
- src/tools/delegate-task/prompt-builder.ts: Condensed KNOWLEDGE_TRUST
  preamble injected into EVERY delegated task (highest leverage point)
- src/agents/sisyphus/default.ts: Composed into primary orchestrator
  prompt alongside Hard Blocks and Anti-Patterns

**Why this matters:**
Without trust tiers, agents treat a user's vague bug report the same
as a plan file. They act on stack traces as if they were instructions.
This is the coordination substrate that makes implementation_handoff
and contracts work — agents must know which sources to trust before
they can reliably hand off work.

See NORTH_STAR.md: 'Knowledge has trust tiers.'
Coldaine referenced this pull request in Coldaine/oh-my-openagent May 20, 2026
**Justification — Oracle analysis #2:**
Oracle ranked Explore confidence-based early exit as the second-highest
ROI gem-team translation. OMO's Explore searches exhaustively with no
stopping rule — it keeps searching past the point of diminishing returns.
Gem-team's researcher uses confidence thresholds to exit early.

Oracle: 'Add mode selection clarify | research, confidence rubric, stop
rules, and output fields confidence/coverage/open_questions/gaps.'

**What changed — explore.ts:**
- Mode Selection: clarify mode (gray areas → ask, don't search) vs
  research mode (clear request → search immediately)
- Confidence-Based Early Exit: thresholds at ≥0.85 (stop), ≥0.80 + no
  blockers (stop), <0.80 (continue deeper)
- EXplicit rule: Do NOT search 'just to be sure' after reaching high
  confidence. More search ≠ better results.
- Enhanced output: <confidence>, <coverage>, <open_questions>, <gaps>
  sections in results block
- New failure condition: no confidence score, or high confidence
  without cross-validation (≥2 independent sources required)

**Why this matters:**
Explore is called for every codebase question. Stopping early at high
confidence cuts token costs on research phases by ~30-50% without
quality loss. Combined with the knowledge trust hierarchy, explore
results are now explicitly VERIFY-tier — the consumer knows to
cross-reference before building a plan on them.

**Gem-team source:**
- gem-researcher clarify mode (gem-researcher.agent.md:46-60)
- confidence-based early exit (gem-researcher.agent.md:80-84)
- confidence calculation (gem-researcher.agent.md:117-154)
herjarsa pushed a commit to herjarsa/oh-my-openagent that referenced this pull request May 23, 2026
- Create @oh-my-opencode/semantic-memory package with SQLite storage
- Implement simple embedding generation using term frequency hashing
- Add cosine similarity search for semantic memory retrieval
- Create memory-context-injector hook for automatic memory storage
- Add 'omo memory' CLI with search, recent, store, delete, stats, clear commands
- Support memory types: context, decision, error, pattern, insight
- Include comprehensive test suite (13 tests)

Closes code-yeongyu#2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant