The boulder continuation in event-handler.ts skipped injection whenever
the last agent was 'sisyphus' and the boulder state had agent='atlas'
set explicitly. The allowSisyphusWhenDefaultAtlas guard required
boulderAgentWasNotExplicitlySet=true, but start-work-hook.ts always
calls createBoulderState(..., 'atlas') which sets the agent explicitly.
This created a chicken-and-egg deadlock: boulder continuation needs
atlas to be the last agent, but the continuation itself is what switches
to atlas. With /start-work, the first iteration was always blocked.
Fix: drop the boulderAgentWasNotExplicitlySet constraint so Sisyphus is
always allowed when the boulder targets atlas (whether explicit or default).
Also reduce todo-continuation-enforcer CONTINUATION_COOLDOWN_MS from
30s to 5s to match atlas hook cooldown and recover interruptions faster.
Hephaestus requires GPT models, which can be provided by github-copilot.
The requiresProvider list was missing github-copilot, causing hephaestus
to not be created when github-copilot was the only GPT provider connected.
This also fixes a flaky CI test that documented this expected behavior.
Hephaestus requires GPT models, which can be provided by github-copilot.
The requiresProvider list was missing github-copilot, causing hephaestus
to not be created when github-copilot was the only GPT provider connected.
This also fixes a flaky CI test that documented this expected behavior.
Hephaestus requires GPT models, which can be provided by github-copilot.
The requiresProvider list was missing github-copilot, causing hephaestus
to not be created when github-copilot was the only GPT provider connected.
This also fixes a flaky CI test that documented this expected behavior.
gpt-5.3-codex is not available on GitHub Copilot. The fallback chains
incorrectly listed github-copilot as a valid provider for this model,
causing the doctor to report 'configured model github-copilot/gpt-5.3-codex
is not valid' for Hephaestus agent.
Affected agents: hephaestus (requiresProvider + fallbackChain)
Affected categories: ultrabrain, deep, unspecified-low
Copilot users can still use Hephaestus via openai or opencode providers.
Fixes#2047
Avoid Date.now call-order flakiness by pinning the mocked current time and setting the message start time explicitly in the test setup.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Use sender-module indirection and an optional main-session filter guard to keep notification assertions deterministic across concurrent test execution.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Fix operator precedence bug in hasActiveWork boolean expression
- Reuse getMainSessionStatus result from watchdog to avoid duplicate API calls
- Add flag to only check secondary timeout once to avoid unnecessary API traffic
Implements fixes from issue #1880 and #1934 to prevent exit code 130 timeout in CI environments:
- Add lastEventTimestamp to EventState for tracking when events were last received
- Add event watchdog: if no events for 30s, verify session status via direct API call
- Add secondary timeout: after 60s without meaningful work events, check for active children/todos and assume work is in progress
This prevents the poll loop from waiting for full 600s timeout when:
1. Event stream drops silently (common in CI with network instability)
2. Main session delegates to children without producing meaningful work on main session
- Replace regex /^([A-Za-z_]+)#.../ with indexOf-based prefix check to catch
line-ref#VK and line.ref#VK style inputs that were previously giving generic errors
- Extract parseLineRefWithHint helper to eliminate duplicated try-catch in
validateLineRef and validateLineRefs
- Restore idempotency guard in appendWriteHashlineOutput using new output format
- Add tests for LINE42 extraction, line-ref hint, line.ref hint, and guard behavior
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace full hashlined file content in write tool response with a simple
'File written successfully. N lines written.' summary to reduce context
bloat.
- Detect non-numeric prefixes (e.g., "LINE#HK", "POS#VK") and explain
that the prefix must be an actual line number, not literal text
- Add suggestLineForHash() that reverse-looks up a hash in file lines
to suggest the correct reference (e.g., Did you mean "1#HK"?)
- Unify error message format from "LINE#ID" to "{line_number}#{hash_id}"
matching the tool description convention
- Add 3 tests covering non-numeric prefix detection and hash suggestion
applySetLine, applyReplaceLines, applyInsertAfter, applyInsertBefore
were re-exported from both edit-operations.ts and index.ts but have no
external consumers — they are only used internally within the module.
Only applyHashlineEdits (the public API) remains exported.
Remove the old LINE:HEX (e.g. "42:ab") reference format support. All
refs now use LINE#ID format exclusively (e.g. "42#VK"). Also fixes
HASHLINE_OUTPUT_PATTERN to use | separator (was missed in PR #2079).
This function is no longer called from edit-operations.ts after the
op/pos/end/lines schema refactor in PR #2079. Remove the function
definition and its 3 dedicated test cases.
restoreIndentForPairedReplacement() and restoreLeadingIndent() unconditionally
restored original indentation when replacement had none, preventing intentional
indentation changes (e.g. removing a tab from '\t1절' to '1절'). Skip indent
restoration when trimmed content is identical, indicating a whitespace-only edit.
Change LINE#HASH:content format to LINE#HASH|content across the entire
codebase. The pipe separator is more visually distinct and avoids
conflicts with TypeScript colons in code content.
15 files updated: implementation, prompts, tests, and READMEs.
OpenCode updated its read tool output format — the <content> tag now shares
a line with the first content line (<content>1: content) with no newline.
The hook's exact indexOf('<content>') detection returned -1, causing all
read output to pass through unmodified (no hash anchors). This silently
disabled the entire hashline-edit workflow.
Fixes:
- Sub-bug 1: Use findIndex + startsWith instead of exact indexOf match
- Sub-bug 2: Extract inline content after <content> prefix as first line
- Sub-bug 3: Normalize open-tag line to bare tag in output (no duplicate)
Also adds backward compat for legacy <file> + 00001| pipe format.
Unify internal hashline edit handling around replace/append/prepend to remove legacy operation shapes. This keeps normalization, ordering, deduplication, execution, and tests aligned with the new op/pos/end/lines contract.
Move blocking/polling logic before full_session branch so that
block=true waits for task completion regardless of output format.
🤖 Generated with assistance of oh-my-opencode
Unify hashline_edit input with replace/append/prepend + pos/end/lines semantics so callers use a single stable shape. Add normalization coverage and refresh tool guidance/tests to reduce schema confusion and stale legacy payload usage.