council_read was a sandboxed readFile wrapper for .sisyphus/ archives.
Now that council_finalize extracts member responses into plain files,
the standard Read tool serves the same purpose. Removes the tool, its
tests, and updates Athena's prompt to reference Read directly.
Adopt the opencode-handoff pattern: switch_agent now creates a new session
and sends the context via promptAsync immediately in the tool's execute
function, then navigates the TUI to the new session.
Removes ~1700 LOC of complexity: persistent state management, event-based
hook monitoring, retry logic, session idle waiting, apply verification,
and terminal detection — all replaced by 3 SDK calls.
Deleted: src/features/agent-switch/ (14 files), src/hooks/agent-switch/ (4 files)
Updated: Athena prompt to announce handoff before calling switch_agent
Add DIAGNOSE, CREATE, PERSPECTIVES, FREEFORM intents to Athena's council
classification system. Refine existing AUDIT (add DIAGNOSE boundary),
EVALUATE (improve criteria guidance), and EXPLAIN (remove catch-all status).
Fix bug where prepare_council_prompt defaulted to AUDIT when no intent was
specified — this caused analytical frameworks to be injected into creative
requests (e.g. poetry). Now defaults to no addendum.
Derive validIntents from Object.keys(COUNCIL_INTENT_ADDENDUMS) to prevent
drift between the addendums record and the validation array.
task-output-writer wrote to process.cwd()/.sisyphus/task-outputs/ while
council_finalize read from ctx.directory/.sisyphus/task-outputs/. When
these differ, all output files appear missing.
Fix by passing directory to writeTaskOutput from BackgroundManager, and
adding basePath to council_read. Also removes process.chdir() from tests
that was masking the bug.
Ripgrep's --glob flag silently returns no results when the pattern
contains a directory prefix (e.g. 'apps/backend/**/*.ts'). Models
naturally write patterns this way when exploring unfamiliar codebases.
Extract the static directory segments from the pattern, append them to
the search path, and pass only the glob portion to ripgrep.
- Add council-continuation-enforcer to nudge council members until they
output COUNCIL_MEMBER_RESPONSE, replacing the hacky post-compaction hack
- Add background_wait + background_cancel to council member tool allowlist
so members can properly manage their explore agents before responding
- Update COUNCIL_DELEGATION_ADDENDUM prompt to instruct members to cancel
pending tasks and wait for explore results before final response
- Fix council_finalize path resolution to use project directory
- Remove post-compaction-continuation.ts and recentlyCompactedSessions hack
- Add council-response-checker for detecting response tag in session messages
When models pass relative paths (e.g. 'apps/ios/CleanSlate') to glob/grep
tools, they were passed directly to ripgrep which resolved them against
process.cwd(). In OpenCode Desktop, process.cwd() is '/' causing all
relative path lookups to fail with 'No such file or directory'.
Fix: use path.resolve(ctx.directory, args.path) to resolve relative paths
against the project directory instead of relying on process.cwd().
When models pass relative paths (e.g. 'apps/ios/CleanSlate') to glob/grep
tools, they were passed directly to ripgrep which resolved them against
process.cwd(). In OpenCode Desktop, process.cwd() is '/' causing all
relative path lookups to fail with 'No such file or directory'.
Fix: use path.resolve(ctx.directory, args.path) to resolve relative paths
against the project directory instead of relying on process.cwd().
- Add _isCompleting guard and writeTaskOutput call before status flip
- Propagate writeOutputToFile from LaunchInput to BackgroundTask
- Delete council-result-format.ts and tests (no longer needed)
- 38/38 tests passing
- council_finalize: batch extract, archive, and return council results
- council_read: secure file reader for archived council responses
- background_wait: stripped to metadata-only, returns completed_tasks array
- Removed all council-specific logic from background_wait
- 28/28 tests passing across all changed files
- Remove applyModelThinkingConfig and all callers (OpenCode handles thinking natively)
- Add try/catch error handling to prepare_council_prompt filesystem operations
- Add mode input validation to prepare_council_prompt tool
- Add 2 missing placeholder test cases (RETRY_FAILED_IF_OTHERS_FINISHED, CANCEL_RETRYING_ON_QUORUM)
- Remove redundant 'Do NOT use TodoWrite' prompt section from council member agent
- Remove COUNCIL_MEMBER_PROMPT from temp file content since it's already
provided as the council member's system prompt via agent config, saving
~350+ tokens per council member per invocation
- Add startup cleanup for stale athena-council-*.md files older than 30
minutes in .sisyphus/tmp/ to handle cases where process exits before
setTimeout cleanup fires
- Remove redundant intermediate permission object spread in createAthenaAgent
- Fix test style: it() -> test(), add #given/#then prefixes per conventions
Both modes now inject explicit instructions: solo warns against subagent usage, delegation provides concrete call_omo_agent examples. Delegation is now the recommended default to reduce context window pressure on council members.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Add background_output to council-member allowlist (fixes delegation deadlock)
- Replace empty catch with error logging in prepare-council-prompt
- Remove unnecessary type assertion in agent.ts
- Remove dead hasAgentToolRestrictions function
- Fix incorrect test assertions (undefined vs false semantics)
- Add barrel export for athena module
- Add guard function test coverage (5 tests)
- Add parity test for triple-sync restrictions (9 tests)
- Add session.compacted handler in BackgroundManager to prevent premature
task completion after compaction (defer first post-compaction idle)
- Explicitly block TodoWrite/TodoRead for council members in all sync
points (AgentConfig permission + session tools + prompt instructions)
- Add council member prefix check to todo-continuation-enforcer skip list
to prevent infinite continuation loops on completed council members
- Add optional analysis mode (solo/delegation) question to Athena setup:
solo = thorough but heavier, delegation = fast via explore/librarian
- Allow call_omo_agent in council member allow-list for delegation mode
- Update COUNCIL_MEMBER_PROMPT with TodoWrite prohibition and delegation
addendum for when delegation mode is selected
- Update prepare_council_prompt tool with mode parameter
Council members now use an allow-list (read, grep, glob, lsp_*, ast_grep_search)
instead of a deny-list. Prompt file moved from /tmp/ to .sisyphus/tmp/ so no
external_directory permission is needed. COUNCIL_MEMBER_PROMPT is included in
the temp file for self-contained council member instructions.
Athena saves the analysis prompt to a temp file once, then launches each
council member with a short "Read <path> for your instructions" prompt.
This eliminates repeated prompt text across N task calls while preserving
individual clickable task panes in the TUI.
- Make directory required in SkillLoadOptions, getAllSkills, and async
skill template resolvers to prevent unsafe process.cwd() fallback
- Remove dead skill export and process.cwd() fallback in skill tool
- Replace kimi-for-coding/k2p5 with kimi-for-coding/kimi-k2.5 in
council-members-generator
- Check context.abort in background-wait and background-output polling loops
- Remove legacy kimi-for-coding/k2p5 from athena fallback chain
- Pass ctx.directory from tool-registry to createSkillTool instead of process.cwd()
Remove the entire custom tool implementation (constants, launcher, session-waiter, tool-helpers, tools, types, and all tests). Council members are now launched via the standard task tool.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Athena now uses background_wait (race-style) to collect council results with incremental progress instead of sequential background_output calls or rapid polling. Updated both the system prompt and tool description to guide Athena to the correct waiting pattern.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
New tool that takes multiple task IDs and blocks until ANY one completes (Promise.race pattern). Returns the completed task's result plus a progress summary with remaining IDs. Enables Athena to show incremental council progress without polling.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- Extract helper functions from tools.ts into dedicated tool-helpers.ts
- Replace getToolContextProperty workaround with typed AthenaCouncilToolContext
- Remove dead code path in formatCouncilLaunchFailure
- Add logging for council member launch and session resolution
- Update tool description to reflect notification-based workflow
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Improve not-configured error message with config file path. Wrap metadataFn in try/catch for best-effort metadata. Replace unsafe as-casts with getToolContextProperty helper. Show Name (model) format in errors. Return error directly for empty member selection.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Return CouncilSessionWaitResult with timedOut/aborted flags instead of raw array, so callers know when results are partial. Add 5 tests covering normal flow, abort, partial results, and edge cases.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Remove session-guard.ts (runtime gating uses hasPendingCouncilMembers instead), its test file, and dead snake_case type interfaces from types.ts that don't match the camelCase code.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The athena_council tool now waits for all council members to complete and
returns their collected results as markdown, eliminating the need for
Athena to repeatedly call background_output per member (which created
excessive UI noise).
- Add result-collector.ts that polls task status and fetches session content
- Update tool to accept BackgroundOutputClient and return formatted markdown
- Update Athena prompt to remove background_output polling steps
- Rewrite tests for new blocking behavior and markdown output format