@wolfx/oh-my-openagent 4.1.1 → 4.2.0-patch.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +2 -1
- package/README.ko.md +2 -1
- package/README.md +2 -1
- package/README.ru.md +2 -1
- package/README.zh-cn.md +2 -1
- package/dist/agents/atlas/default-prompt-sections.d.ts +3 -3
- package/dist/agents/atlas/gemini-prompt-sections.d.ts +2 -2
- package/dist/agents/atlas/gpt-prompt-sections.d.ts +2 -2
- package/dist/agents/atlas/kimi-prompt-sections.d.ts +3 -3
- package/dist/agents/atlas/opus-4-7-prompt-sections.d.ts +3 -3
- package/dist/agents/momus.d.ts +1 -1
- package/dist/agents/prometheus/behavioral-summary.d.ts +1 -1
- package/dist/agents/prometheus/high-accuracy-mode.d.ts +1 -1
- package/dist/agents/prometheus/identity-constraints.d.ts +1 -1
- package/dist/agents/prometheus/plan-generation.d.ts +1 -1
- package/dist/agents/prometheus/plan-template.d.ts +1 -1
- package/dist/config/schema/team-mode.d.ts +1 -1
- package/dist/features/background-agent/error-classifier.d.ts +1 -0
- package/dist/features/background-agent/fallback-retry-handler.d.ts +15 -0
- package/dist/features/background-agent/manager.d.ts +11 -8
- package/dist/features/background-agent/parent-wake-notifier.d.ts +74 -0
- package/dist/features/background-agent/process-cleanup.d.ts +2 -0
- package/dist/features/background-agent/session-route.d.ts +12 -0
- package/dist/features/background-agent/spawner.d.ts +2 -2
- package/dist/features/background-agent/task-registry.d.ts +6 -0
- package/dist/features/background-agent/types.d.ts +2 -0
- package/dist/features/boulder-state/constants.d.ts +4 -4
- package/dist/features/boulder-state/storage.d.ts +1 -1
- package/dist/features/builtin-commands/templates/init-deep.d.ts +1 -1
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/context-injector/injector.d.ts +1 -1
- package/dist/features/opencode-skill-loader/git-master-template-injection.d.ts +18 -0
- package/dist/features/run-continuation-state/constants.d.ts +1 -1
- package/dist/features/team-mode/team-layout-tmux/resolve-caller-tmux-session.d.ts +3 -1
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +3 -3
- package/dist/features/team-mode/tools/messaging.d.ts +1 -0
- package/dist/features/team-mode/types.d.ts +2 -2
- package/dist/features/tmux-subagent/attachable-session-status.d.ts +1 -1
- package/dist/features/tmux-subagent/manager.d.ts +6 -0
- package/dist/features/tmux-subagent/pane-state-parser.d.ts +2 -0
- package/dist/features/tmux-subagent/polling-manager.d.ts +6 -2
- package/dist/features/tmux-subagent/types.d.ts +4 -0
- package/dist/hooks/atlas/boulder-continuation-injector.d.ts +1 -0
- package/dist/hooks/atlas/omo-path.d.ts +6 -0
- package/dist/hooks/atlas/tool-execute-after.d.ts +3 -0
- package/dist/hooks/atlas/tool-progress.d.ts +14 -0
- package/dist/hooks/atlas/types.d.ts +7 -0
- package/dist/hooks/auto-slash-command/detector.d.ts +2 -0
- package/dist/hooks/auto-update-checker/cache.d.ts +8 -1
- package/dist/hooks/auto-update-checker/checker/cached-version.d.ts +8 -1
- package/dist/hooks/background-notification/hook.d.ts +0 -6
- package/dist/hooks/compaction-context-injector/types.d.ts +1 -0
- package/dist/hooks/interactive-bash-session/state-manager.d.ts +1 -1
- package/dist/hooks/json-error-recovery/hook.d.ts +1 -1
- package/dist/hooks/keyword-detector/detector.d.ts +1 -0
- package/dist/hooks/keyword-detector/ultrawork/default.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/gemini.d.ts +1 -1
- package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/constants.d.ts +1 -1
- package/dist/hooks/prometheus-md-only/path-policy.d.ts +3 -3
- package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +11 -0
- package/dist/hooks/ralph-loop/constants.d.ts +1 -1
- package/dist/hooks/ralph-loop/continuation-prompt-injector.d.ts +4 -0
- package/dist/hooks/ralph-loop/iteration-continuation.d.ts +5 -0
- package/dist/hooks/ralph-loop/loop-state-controller.d.ts +3 -3
- package/dist/hooks/ralph-loop/pending-verification-handler.d.ts +2 -1
- package/dist/hooks/ralph-loop/ralph-loop-event-handler.d.ts +2 -2
- package/dist/hooks/ralph-loop/storage.d.ts +2 -2
- package/dist/hooks/ralph-loop/types.d.ts +4 -0
- package/dist/hooks/ralph-loop/verification-failure-handler.d.ts +2 -2
- package/dist/hooks/rules-injector/injector.d.ts +9 -2
- package/dist/hooks/rules-injector/matcher.d.ts +5 -0
- package/dist/hooks/rules-injector/project-root-finder.d.ts +4 -0
- package/dist/hooks/rules-injector/rule-scan-cache.d.ts +9 -2
- package/dist/hooks/runtime-fallback/constants.d.ts +10 -0
- package/dist/hooks/runtime-fallback/first-prompt-watchdog.d.ts +25 -0
- package/dist/hooks/runtime-fallback/hook.d.ts +14 -1
- package/dist/hooks/runtime-fallback/last-user-retry-parts.d.ts +10 -2
- package/dist/hooks/runtime-fallback/types.d.ts +10 -0
- package/dist/hooks/session-recovery/detect-error-type.d.ts +1 -1
- package/dist/hooks/session-recovery/hook.d.ts +1 -0
- package/dist/hooks/session-recovery/interrupted-idle-message-fetch-timeout.d.ts +7 -0
- package/dist/hooks/session-recovery/recover-tool-result-missing.d.ts +6 -1
- package/dist/hooks/session-recovery/types.d.ts +12 -0
- package/dist/hooks/shared/prompt-async-gate.d.ts +1 -0
- package/dist/hooks/shared/session-idle-settle.d.ts +1 -11
- package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
- package/dist/hooks/team-mode-status-injector/hook.d.ts +2 -1
- package/dist/hooks/todo-continuation-enforcer/pending-question-detection.d.ts +2 -0
- package/dist/hooks/todo-continuation-enforcer/session-state.d.ts +3 -4
- package/dist/hooks/todo-continuation-enforcer/types.d.ts +2 -3
- package/dist/hooks/tool-pair-validator/hook.d.ts +7 -2
- package/dist/hooks/unstable-agent-babysitter/task-message-analyzer.d.ts +1 -0
- package/dist/hooks/write-existing-file-guard/tool-execute-before-handler.d.ts +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +41902 -70602
- package/dist/mcp/index.d.ts +3 -1
- package/dist/mcp/lsp.d.ts +13 -0
- package/dist/mcp/types.d.ts +1 -0
- package/dist/plugin/build-team-idle-wake-hint-client.d.ts +12 -0
- package/dist/plugin/chat-message.d.ts +1 -1
- package/dist/plugin/tool-registry.d.ts +1 -2
- package/dist/plugin-dispose.d.ts +0 -3
- package/dist/shared/agent-sort-shim.d.ts +1 -0
- package/dist/shared/delegated-child-session-bootstrap.d.ts +25 -0
- package/dist/shared/dynamic-truncator.d.ts +2 -0
- package/dist/shared/host-skill-config.d.ts +2 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/internal-initiator-marker.d.ts +25 -0
- package/dist/shared/legacy-workspace-migration.d.ts +5 -0
- package/dist/shared/logger.d.ts +12 -0
- package/dist/shared/model-error-classifier.d.ts +2 -0
- package/dist/shared/model-resolution-pipeline.d.ts +4 -0
- package/dist/shared/opencode-http-api.d.ts +9 -0
- package/dist/shared/prompt-async-gate.d.ts +82 -0
- package/dist/shared/replace-tool-args.d.ts +13 -0
- package/dist/shared/session-idle-settle.d.ts +11 -0
- package/dist/shared/tmux/tmux-utils/pane-activate.d.ts +1 -0
- package/dist/shared/tmux/tmux-utils/pane-close.d.ts +10 -0
- package/dist/shared/tmux/tmux-utils/pane-command.d.ts +2 -0
- package/dist/shared/tmux/tmux-utils/pane-replace.d.ts +11 -1
- package/dist/shared/tmux/tmux-utils/pane-spawn.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils/server-health.d.ts +12 -1
- package/dist/shared/tmux/tmux-utils/session-spawn.d.ts +2 -2
- package/dist/shared/tmux/tmux-utils/window-spawn.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils.d.ts +2 -0
- package/dist/testing/create-plugin-module.d.ts +41 -0
- package/dist/tools/background-task/constants.d.ts +1 -1
- package/dist/tools/background-task/with-sdk-call-timeout.d.ts +7 -0
- package/dist/tools/call-omo-agent/session-creator.d.ts +2 -1
- package/dist/tools/call-omo-agent/sync-executor.d.ts +2 -2
- package/dist/tools/delegate-task/subagent-discovery.d.ts +2 -0
- package/dist/tools/delegate-task/sync-prompt-sender.d.ts +2 -1
- package/dist/tools/delegate-task/sync-session-creator.d.ts +2 -0
- package/dist/tools/delegate-task/sync-task.d.ts +1 -1
- package/dist/tools/index.d.ts +0 -3
- package/dist/tools/interactive-bash/tools.d.ts +5 -0
- package/package.json +17 -8
- package/dist/hooks/atlas/sisyphus-path.d.ts +0 -6
- package/dist/tools/lsp/client.d.ts +0 -3
- package/dist/tools/lsp/config.d.ts +0 -3
- package/dist/tools/lsp/constants.d.ts +0 -6
- package/dist/tools/lsp/diagnostics-tool.d.ts +0 -2
- package/dist/tools/lsp/directory-diagnostics.d.ts +0 -1
- package/dist/tools/lsp/find-references-tool.d.ts +0 -2
- package/dist/tools/lsp/goto-definition-tool.d.ts +0 -2
- package/dist/tools/lsp/index.d.ts +0 -8
- package/dist/tools/lsp/infer-extension.d.ts +0 -1
- package/dist/tools/lsp/language-config.d.ts +0 -1
- package/dist/tools/lsp/language-mappings.d.ts +0 -3
- package/dist/tools/lsp/lsp-client-connection.d.ts +0 -4
- package/dist/tools/lsp/lsp-client-transport.d.ts +0 -22
- package/dist/tools/lsp/lsp-client-wrapper.d.ts +0 -9
- package/dist/tools/lsp/lsp-client.d.ts +0 -17
- package/dist/tools/lsp/lsp-formatters.d.ts +0 -13
- package/dist/tools/lsp/lsp-manager-process-cleanup.d.ts +0 -15
- package/dist/tools/lsp/lsp-manager-temp-directory-cleanup.d.ts +0 -8
- package/dist/tools/lsp/lsp-process.d.ts +0 -29
- package/dist/tools/lsp/lsp-server.d.ts +0 -24
- package/dist/tools/lsp/rename-tools.d.ts +0 -3
- package/dist/tools/lsp/server-config-loader.d.ts +0 -25
- package/dist/tools/lsp/server-definitions.d.ts +0 -3
- package/dist/tools/lsp/server-installation.d.ts +0 -1
- package/dist/tools/lsp/server-path-bases.d.ts +0 -1
- package/dist/tools/lsp/server-resolution.d.ts +0 -15
- package/dist/tools/lsp/symbols-tool.d.ts +0 -2
- package/dist/tools/lsp/tools.d.ts +0 -5
- package/dist/tools/lsp/types.d.ts +0 -123
- package/dist/tools/lsp/workspace-edit.d.ts +0 -8
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* The markdown template structure for work plans generated by Prometheus.
|
|
5
5
|
* Includes TL;DR, context, objectives, verification strategy, TODOs, and success criteria.
|
|
6
6
|
*/
|
|
7
|
-
export declare const PROMETHEUS_PLAN_TEMPLATE = "## Plan Structure\n\nGenerate plan to: `.sisyphus/plans/{name}.md`\n\n```markdown\n# {Plan Title}\n\n## TL;DR\n\n> **Quick Summary**: [1-2 sentences capturing the core objective and approach]\n> \n> **Deliverables**: [Bullet list of concrete outputs]\n> - [Output 1]\n> - [Output 2]\n> \n> **Estimated Effort**: [Quick | Short | Medium | Large | XL]\n> **Parallel Execution**: [YES - N waves | NO - sequential]\n> **Critical Path**: [Task X \u2192 Task Y \u2192 Task Z]\n\n---\n\n## Context\n\n### Original Request\n[User's initial description]\n\n### Interview Summary\n**Key Discussions**:\n- [Point 1]: [User's decision/preference]\n- [Point 2]: [Agreed approach]\n\n**Research Findings**:\n- [Finding 1]: [Implication]\n- [Finding 2]: [Recommendation]\n\n### Metis Review\n**Identified Gaps** (addressed):\n- [Gap 1]: [How resolved]\n- [Gap 2]: [How resolved]\n\n---\n\n## Work Objectives\n\n### Core Objective\n[1-2 sentences: what we're achieving]\n\n### Concrete Deliverables\n- [Exact file/endpoint/feature]\n\n### Definition of Done\n- [ ] [Verifiable condition with command]\n\n### Must Have\n- [Non-negotiable requirement]\n\n### Must NOT Have (Guardrails)\n- [Explicit exclusion from Metis review]\n- [AI slop pattern to avoid]\n- [Scope boundary]\n\n---\n\n## Verification Strategy (MANDATORY)\n\n> **ZERO HUMAN INTERVENTION** - ALL verification is agent-executed. No exceptions.\n> Acceptance criteria requiring \"user manually tests/confirms\" are FORBIDDEN.\n\n### Test Decision\n- **Infrastructure exists**: [YES/NO]\n- **Automated tests**: [TDD / Tests-after / None]\n- **Framework**: [bun test / vitest / jest / pytest / none]\n- **If TDD**: Each task follows RED (failing test) \u2192 GREEN (minimal impl) \u2192 REFACTOR\n\n### QA Policy\nEvery task MUST include agent-executed QA scenarios (see TODO template below).\nEvidence saved to `.sisyphus/evidence/task-{N}-{scenario-slug}.{ext}`.\n\n- **Frontend/UI**: Use Playwright (playwright skill) - Navigate, interact, assert DOM, screenshot\n- **TUI/CLI**: Use interactive_bash (tmux) - Run command, send keystrokes, validate output\n- **API/Backend**: Use Bash (curl) - Send requests, assert status + response fields\n- **Library/Module**: Use Bash (bun/node REPL) - Import, call functions, compare output\n\n---\n\n## Execution Strategy\n\n### Parallel Execution Waves\n\n> Maximize throughput by grouping independent tasks into parallel waves.\n> Each wave completes before the next begins.\n> Target: 5-8 tasks per wave. Fewer than 3 per wave (except final) = under-splitting.\n\n```\nWave 1 (Start Immediately - foundation + scaffolding):\n\u251C\u2500\u2500 Task 1: Project scaffolding + config [quick]\n\u251C\u2500\u2500 Task 2: Design system tokens [quick]\n\u251C\u2500\u2500 Task 3: Type definitions [quick]\n\u251C\u2500\u2500 Task 4: Schema definitions [quick]\n\u251C\u2500\u2500 Task 5: Storage interface + in-memory impl [quick]\n\u251C\u2500\u2500 Task 6: Auth middleware [quick]\n\u2514\u2500\u2500 Task 7: Client module [quick]\n\nWave 2 (After Wave 1 - core modules, MAX PARALLEL):\n\u251C\u2500\u2500 Task 8: Core business logic (depends: 3, 5, 7) [deep]\n\u251C\u2500\u2500 Task 9: API endpoints (depends: 4, 5) [unspecified-high]\n\u251C\u2500\u2500 Task 10: Secondary storage impl (depends: 5) [unspecified-high]\n\u251C\u2500\u2500 Task 11: Retry/fallback logic (depends: 8) [deep]\n\u251C\u2500\u2500 Task 12: UI layout + navigation (depends: 2) [visual-engineering]\n\u251C\u2500\u2500 Task 13: API client + hooks (depends: 4) [quick]\n\u2514\u2500\u2500 Task 14: Telemetry middleware (depends: 5, 10) [unspecified-high]\n\nWave 3 (After Wave 2 - integration + UI):\n\u251C\u2500\u2500 Task 15: Main route combining modules (depends: 6, 11, 14) [deep]\n\u251C\u2500\u2500 Task 16: UI data visualization (depends: 12, 13) [visual-engineering]\n\u251C\u2500\u2500 Task 17: Deployment config A (depends: 15) [quick]\n\u251C\u2500\u2500 Task 18: Deployment config B (depends: 15) [quick]\n\u251C\u2500\u2500 Task 19: Deployment config C (depends: 15) [quick]\n\u2514\u2500\u2500 Task 20: UI request log + build (depends: 16) [visual-engineering]\n\nWave FINAL (After ALL tasks \u2014 4 parallel reviews, then user okay):\n\u251C\u2500\u2500 Task F1: Plan compliance audit (oracle)\n\u251C\u2500\u2500 Task F2: Code quality review (unspecified-high)\n\u251C\u2500\u2500 Task F3: Real manual QA (unspecified-high)\n\u2514\u2500\u2500 Task F4: Scope fidelity check (deep)\n-> Present results -> Get explicit user okay\n\nCritical Path: Task 1 \u2192 Task 5 \u2192 Task 8 \u2192 Task 11 \u2192 Task 15 \u2192 Task 21 \u2192 F1-F4 \u2192 user okay\nParallel Speedup: ~70% faster than sequential\nMax Concurrent: 7 (Waves 1 & 2)\n```\n\n### Dependency Matrix (abbreviated - show ALL tasks in your generated plan)\n\n- **1-7**: - - 8-14, 1\n- **8**: 3, 5, 7 - 11, 15, 2\n- **11**: 8 - 15, 2\n- **14**: 5, 10 - 15, 2\n- **15**: 6, 11, 14 - 17-19, 21, 3\n- **21**: 15 - 23, 24, 4\n\n> This is abbreviated for reference. YOUR generated plan must include the FULL matrix for ALL tasks.\n\n### Agent Dispatch Summary\n\n- **1**: **7** - T1-T4 \u2192 `quick`, T5 \u2192 `quick`, T6 \u2192 `quick`, T7 \u2192 `quick`\n- **2**: **7** - T8 \u2192 `deep`, T9 \u2192 `unspecified-high`, T10 \u2192 `unspecified-high`, T11 \u2192 `deep`, T12 \u2192 `visual-engineering`, T13 \u2192 `quick`, T14 \u2192 `unspecified-high`\n- **3**: **6** - T15 \u2192 `deep`, T16 \u2192 `visual-engineering`, T17-T19 \u2192 `quick`, T20 \u2192 `visual-engineering`\n- **4**: **4** - T21 \u2192 `deep`, T22 \u2192 `unspecified-high`, T23 \u2192 `deep`, T24 \u2192 `git`\n- **FINAL**: **4** - F1 \u2192 `oracle`, F2 \u2192 `unspecified-high`, F3 \u2192 `unspecified-high`, F4 \u2192 `deep`\n\n---\n\n## TODOs\n\n> Implementation + Test = ONE Task. Never separate.\n> EVERY task MUST have: Recommended Agent Profile + Parallelization info + QA Scenarios.\n> **A task WITHOUT QA Scenarios is INCOMPLETE. No exceptions.**\n\n- [ ] 1. [Task Title]\n\n **What to do**:\n - [Clear implementation steps]\n - [Test cases to cover]\n\n **Must NOT do**:\n - [Specific exclusions from guardrails]\n\n **Recommended Agent Profile**:\n > Select category + skills based on task domain. Justify each choice.\n - **Category**: `[visual-engineering | ultrabrain | artistry | quick | unspecified-low | unspecified-high | writing]`\n - Reason: [Why this category fits the task domain]\n - **Skills**: [`skill-1`, `skill-2`]\n - `skill-1`: [Why needed - domain overlap explanation]\n - `skill-2`: [Why needed - domain overlap explanation]\n - **Skills Evaluated but Omitted**:\n - `omitted-skill`: [Why domain doesn't overlap]\n\n **Parallelization**:\n - **Can Run In Parallel**: YES | NO\n - **Parallel Group**: Wave N (with Tasks X, Y) | Sequential\n - **Blocks**: [Tasks that depend on this task completing]\n - **Blocked By**: [Tasks this depends on] | None (can start immediately)\n\n **References** (CRITICAL - Be Exhaustive):\n\n > The executor has NO context from your interview. References are their ONLY guide.\n > Each reference must answer: \"What should I look at and WHY?\"\n\n **Pattern References** (existing code to follow):\n - `src/services/auth.ts:45-78` - Authentication flow pattern (JWT creation, refresh token handling)\n\n **API/Type References** (contracts to implement against):\n - `src/types/user.ts:UserDTO` - Response shape for user endpoints\n\n **Test References** (testing patterns to follow):\n - `src/__tests__/auth.test.ts:describe(\"login\")` - Test structure and mocking patterns\n\n **External References** (libraries and frameworks):\n - Official docs: `https://zod.dev/?id=basic-usage` - Zod validation syntax\n\n **WHY Each Reference Matters** (explain the relevance):\n - Don't just list files - explain what pattern/information the executor should extract\n - Bad: `src/utils.ts` (vague, which utils? why?)\n - Good: `src/utils/validation.ts:sanitizeInput()` - Use this sanitization pattern for user input\n\n **Acceptance Criteria**:\n\n > **AGENT-EXECUTABLE VERIFICATION ONLY** - No human action permitted.\n > Every criterion MUST be verifiable by running a command or using a tool.\n\n **If TDD (tests enabled):**\n - [ ] Test file created: src/auth/login.test.ts\n - [ ] bun test src/auth/login.test.ts \u2192 PASS (3 tests, 0 failures)\n\n **QA Scenarios (MANDATORY - task is INCOMPLETE without these):**\n\n > **This is NOT optional. A task without QA scenarios WILL BE REJECTED.**\n >\n > Write scenario tests that verify the ACTUAL BEHAVIOR of what you built.\n > Minimum: 1 happy path + 1 failure/edge case per task.\n > Each scenario = exact tool + exact steps + exact assertions + evidence path.\n >\n > **The executing agent MUST run these scenarios after implementation.**\n > **The orchestrator WILL verify evidence files exist before marking task complete.**\n\n \\`\\`\\`\n Scenario: [Happy path - what SHOULD work]\n Tool: [Playwright / interactive_bash / Bash (curl)]\n Preconditions: [Exact setup state]\n Steps:\n 1. [Exact action - specific command/selector/endpoint, no vagueness]\n 2. [Next action - with expected intermediate state]\n 3. [Assertion - exact expected value, not \"verify it works\"]\n Expected Result: [Concrete, observable, binary pass/fail]\n Failure Indicators: [What specifically would mean this failed]\n Evidence: .sisyphus/evidence/task-{N}-{scenario-slug}.{ext}\n\n Scenario: [Failure/edge case - what SHOULD fail gracefully]\n Tool: [same format]\n Preconditions: [Invalid input / missing dependency / error state]\n Steps:\n 1. [Trigger the error condition]\n 2. [Assert error is handled correctly]\n Expected Result: [Graceful failure with correct error message/code]\n Evidence: .sisyphus/evidence/task-{N}-{scenario-slug}-error.{ext}\n \\`\\`\\`\n\n > **Specificity requirements - every scenario MUST use:**\n > - **Selectors**: Specific CSS selectors (`.login-button`, not \"the login button\")\n > - **Data**: Concrete test data (`\"test@example.com\"`, not `\"[email]\"`)\n > - **Assertions**: Exact values (`text contains \"Welcome back\"`, not \"verify it works\")\n > - **Timing**: Wait conditions where relevant (`timeout: 10s`)\n > - **Negative**: At least ONE failure/error scenario per task\n >\n > **Anti-patterns (your scenario is INVALID if it looks like this):**\n > - \u274C \"Verify it works correctly\" - HOW? What does \"correctly\" mean?\n > - \u274C \"Check the API returns data\" - WHAT data? What fields? What values?\n > - \u274C \"Test the component renders\" - WHERE? What selector? What content?\n > - \u274C Any scenario without an evidence path\n\n **Evidence to Capture:**\n - [ ] Each evidence file named: task-{N}-{scenario-slug}.{ext}\n - [ ] Screenshots for UI, terminal output for CLI, response bodies for API\n\n **Commit**: YES | NO (groups with N)\n - Message: `type(scope): desc`\n - Files: `path/to/file`\n - Pre-commit: `test command`\n\n---\n\n## Final Verification Wave (MANDATORY \u2014 after ALL implementation tasks)\n\n> 4 review agents run in PARALLEL. ALL must APPROVE. Present consolidated results to user and get explicit \"okay\" before completing.\n>\n> **Do NOT auto-proceed after verification. Wait for user's explicit approval before marking work complete.**\n> **Never mark F1-F4 as checked before getting user's okay.** Rejection or user feedback -> fix -> re-run -> present again -> wait for okay.\n\n- [ ] F1. **Plan Compliance Audit** \u2014 `oracle`\n Read the plan end-to-end. For each \"Must Have\": verify implementation exists (read file, curl endpoint, run command). For each \"Must NOT Have\": search codebase for forbidden patterns \u2014 reject with file:line if found. Check evidence files exist in .sisyphus/evidence/. Compare deliverables against plan.\n Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`\n\n- [ ] F2. **Code Quality Review** \u2014 `unspecified-high`\n Run `tsc --noEmit` + linter + `bun test`. Review all changed files for: `as any`/`@ts-ignore`, empty catches, console.log in prod, commented-out code, unused imports. Check AI slop: excessive comments, over-abstraction, generic names (data/result/item/temp).\n Output: `Build [PASS/FAIL] | Lint [PASS/FAIL] | Tests [N pass/N fail] | Files [N clean/N issues] | VERDICT`\n\n- [ ] F3. **Real Manual QA** \u2014 `unspecified-high` (+ `playwright` skill if UI)\n Start from clean state. Execute EVERY QA scenario from EVERY task \u2014 follow exact steps, capture evidence. Test cross-task integration (features working together, not isolation). Test edge cases: empty state, invalid input, rapid actions. Save to `.sisyphus/evidence/final-qa/`.\n Output: `Scenarios [N/N pass] | Integration [N/N] | Edge Cases [N tested] | VERDICT`\n\n- [ ] F4. **Scope Fidelity Check** \u2014 `deep`\n For each task: read \"What to do\", read actual diff (git log/diff). Verify 1:1 \u2014 everything in spec was built (no missing), nothing beyond spec was built (no creep). Check \"Must NOT do\" compliance. Detect cross-task contamination: Task N touching Task M's files. Flag unaccounted changes.\n Output: `Tasks [N/N compliant] | Contamination [CLEAN/N issues] | Unaccounted [CLEAN/N files] | VERDICT`\n\n---\n\n## Commit Strategy\n\n- **1**: `type(scope): desc` - file.ts, npm test\n\n---\n\n## Success Criteria\n\n### Verification Commands\n```bash\ncommand # Expected: output\n```\n\n### Final Checklist\n- [ ] All \"Must Have\" present\n- [ ] All \"Must NOT Have\" absent\n- [ ] All tests pass\n```\n\n---\n";
|
|
7
|
+
export declare const PROMETHEUS_PLAN_TEMPLATE = "## Plan Structure\n\nGenerate plan to: `.omo/plans/{name}.md`\n\n```markdown\n# {Plan Title}\n\n## TL;DR\n\n> **Quick Summary**: [1-2 sentences capturing the core objective and approach]\n> \n> **Deliverables**: [Bullet list of concrete outputs]\n> - [Output 1]\n> - [Output 2]\n> \n> **Estimated Effort**: [Quick | Short | Medium | Large | XL]\n> **Parallel Execution**: [YES - N waves | NO - sequential]\n> **Critical Path**: [Task X \u2192 Task Y \u2192 Task Z]\n\n---\n\n## Context\n\n### Original Request\n[User's initial description]\n\n### Interview Summary\n**Key Discussions**:\n- [Point 1]: [User's decision/preference]\n- [Point 2]: [Agreed approach]\n\n**Research Findings**:\n- [Finding 1]: [Implication]\n- [Finding 2]: [Recommendation]\n\n### Metis Review\n**Identified Gaps** (addressed):\n- [Gap 1]: [How resolved]\n- [Gap 2]: [How resolved]\n\n---\n\n## Work Objectives\n\n### Core Objective\n[1-2 sentences: what we're achieving]\n\n### Concrete Deliverables\n- [Exact file/endpoint/feature]\n\n### Definition of Done\n- [ ] [Verifiable condition with command]\n\n### Must Have\n- [Non-negotiable requirement]\n\n### Must NOT Have (Guardrails)\n- [Explicit exclusion from Metis review]\n- [AI slop pattern to avoid]\n- [Scope boundary]\n\n---\n\n## Verification Strategy (MANDATORY)\n\n> **ZERO HUMAN INTERVENTION** - ALL verification is agent-executed. No exceptions.\n> Acceptance criteria requiring \"user manually tests/confirms\" are FORBIDDEN.\n\n### Test Decision\n- **Infrastructure exists**: [YES/NO]\n- **Automated tests**: [TDD / Tests-after / None]\n- **Framework**: [bun test / vitest / jest / pytest / none]\n- **If TDD**: Each task follows RED (failing test) \u2192 GREEN (minimal impl) \u2192 REFACTOR\n\n### QA Policy\nEvery task MUST include agent-executed QA scenarios (see TODO template below).\nEvidence saved to `.omo/evidence/task-{N}-{scenario-slug}.{ext}`.\n\n- **Frontend/UI**: Use Playwright (playwright skill) - Navigate, interact, assert DOM, screenshot\n- **TUI/CLI**: Use interactive_bash (tmux) - Run command, send keystrokes, validate output\n- **API/Backend**: Use Bash (curl) - Send requests, assert status + response fields\n- **Library/Module**: Use Bash (bun/node REPL) - Import, call functions, compare output\n\n---\n\n## Execution Strategy\n\n### Parallel Execution Waves\n\n> Maximize throughput by grouping independent tasks into parallel waves.\n> Each wave completes before the next begins.\n> Target: 5-8 tasks per wave. Fewer than 3 per wave (except final) = under-splitting.\n\n```\nWave 1 (Start Immediately - foundation + scaffolding):\n\u251C\u2500\u2500 Task 1: Project scaffolding + config [quick]\n\u251C\u2500\u2500 Task 2: Design system tokens [quick]\n\u251C\u2500\u2500 Task 3: Type definitions [quick]\n\u251C\u2500\u2500 Task 4: Schema definitions [quick]\n\u251C\u2500\u2500 Task 5: Storage interface + in-memory impl [quick]\n\u251C\u2500\u2500 Task 6: Auth middleware [quick]\n\u2514\u2500\u2500 Task 7: Client module [quick]\n\nWave 2 (After Wave 1 - core modules, MAX PARALLEL):\n\u251C\u2500\u2500 Task 8: Core business logic (depends: 3, 5, 7) [deep]\n\u251C\u2500\u2500 Task 9: API endpoints (depends: 4, 5) [unspecified-high]\n\u251C\u2500\u2500 Task 10: Secondary storage impl (depends: 5) [unspecified-high]\n\u251C\u2500\u2500 Task 11: Retry/fallback logic (depends: 8) [deep]\n\u251C\u2500\u2500 Task 12: UI layout + navigation (depends: 2) [visual-engineering]\n\u251C\u2500\u2500 Task 13: API client + hooks (depends: 4) [quick]\n\u2514\u2500\u2500 Task 14: Telemetry middleware (depends: 5, 10) [unspecified-high]\n\nWave 3 (After Wave 2 - integration + UI):\n\u251C\u2500\u2500 Task 15: Main route combining modules (depends: 6, 11, 14) [deep]\n\u251C\u2500\u2500 Task 16: UI data visualization (depends: 12, 13) [visual-engineering]\n\u251C\u2500\u2500 Task 17: Deployment config A (depends: 15) [quick]\n\u251C\u2500\u2500 Task 18: Deployment config B (depends: 15) [quick]\n\u251C\u2500\u2500 Task 19: Deployment config C (depends: 15) [quick]\n\u2514\u2500\u2500 Task 20: UI request log + build (depends: 16) [visual-engineering]\n\nWave FINAL (After ALL tasks \u2014 4 parallel reviews, then user okay):\n\u251C\u2500\u2500 Task F1: Plan compliance audit (oracle)\n\u251C\u2500\u2500 Task F2: Code quality review (unspecified-high)\n\u251C\u2500\u2500 Task F3: Real manual QA (unspecified-high)\n\u2514\u2500\u2500 Task F4: Scope fidelity check (deep)\n-> Present results -> Get explicit user okay\n\nCritical Path: Task 1 \u2192 Task 5 \u2192 Task 8 \u2192 Task 11 \u2192 Task 15 \u2192 Task 21 \u2192 F1-F4 \u2192 user okay\nParallel Speedup: ~70% faster than sequential\nMax Concurrent: 7 (Waves 1 & 2)\n```\n\n### Dependency Matrix (abbreviated - show ALL tasks in your generated plan)\n\n- **1-7**: - - 8-14, 1\n- **8**: 3, 5, 7 - 11, 15, 2\n- **11**: 8 - 15, 2\n- **14**: 5, 10 - 15, 2\n- **15**: 6, 11, 14 - 17-19, 21, 3\n- **21**: 15 - 23, 24, 4\n\n> This is abbreviated for reference. YOUR generated plan must include the FULL matrix for ALL tasks.\n\n### Agent Dispatch Summary\n\n- **1**: **7** - T1-T4 \u2192 `quick`, T5 \u2192 `quick`, T6 \u2192 `quick`, T7 \u2192 `quick`\n- **2**: **7** - T8 \u2192 `deep`, T9 \u2192 `unspecified-high`, T10 \u2192 `unspecified-high`, T11 \u2192 `deep`, T12 \u2192 `visual-engineering`, T13 \u2192 `quick`, T14 \u2192 `unspecified-high`\n- **3**: **6** - T15 \u2192 `deep`, T16 \u2192 `visual-engineering`, T17-T19 \u2192 `quick`, T20 \u2192 `visual-engineering`\n- **4**: **4** - T21 \u2192 `deep`, T22 \u2192 `unspecified-high`, T23 \u2192 `deep`, T24 \u2192 `git`\n- **FINAL**: **4** - F1 \u2192 `oracle`, F2 \u2192 `unspecified-high`, F3 \u2192 `unspecified-high`, F4 \u2192 `deep`\n\n---\n\n## TODOs\n\n> Implementation + Test = ONE Task. Never separate.\n> EVERY task MUST have: Recommended Agent Profile + Parallelization info + QA Scenarios.\n> **A task WITHOUT QA Scenarios is INCOMPLETE. No exceptions.**\n\n- [ ] 1. [Task Title]\n\n **What to do**:\n - [Clear implementation steps]\n - [Test cases to cover]\n\n **Must NOT do**:\n - [Specific exclusions from guardrails]\n\n **Recommended Agent Profile**:\n > Select category + skills based on task domain. Justify each choice.\n - **Category**: `[visual-engineering | ultrabrain | artistry | quick | unspecified-low | unspecified-high | writing]`\n - Reason: [Why this category fits the task domain]\n - **Skills**: [`skill-1`, `skill-2`]\n - `skill-1`: [Why needed - domain overlap explanation]\n - `skill-2`: [Why needed - domain overlap explanation]\n - **Skills Evaluated but Omitted**:\n - `omitted-skill`: [Why domain doesn't overlap]\n\n **Parallelization**:\n - **Can Run In Parallel**: YES | NO\n - **Parallel Group**: Wave N (with Tasks X, Y) | Sequential\n - **Blocks**: [Tasks that depend on this task completing]\n - **Blocked By**: [Tasks this depends on] | None (can start immediately)\n\n **References** (CRITICAL - Be Exhaustive):\n\n > The executor has NO context from your interview. References are their ONLY guide.\n > Each reference must answer: \"What should I look at and WHY?\"\n\n **Pattern References** (existing code to follow):\n - `src/services/auth.ts:45-78` - Authentication flow pattern (JWT creation, refresh token handling)\n\n **API/Type References** (contracts to implement against):\n - `src/types/user.ts:UserDTO` - Response shape for user endpoints\n\n **Test References** (testing patterns to follow):\n - `src/__tests__/auth.test.ts:describe(\"login\")` - Test structure and mocking patterns\n\n **External References** (libraries and frameworks):\n - Official docs: `https://zod.dev/?id=basic-usage` - Zod validation syntax\n\n **WHY Each Reference Matters** (explain the relevance):\n - Don't just list files - explain what pattern/information the executor should extract\n - Bad: `src/utils.ts` (vague, which utils? why?)\n - Good: `src/utils/validation.ts:sanitizeInput()` - Use this sanitization pattern for user input\n\n **Acceptance Criteria**:\n\n > **AGENT-EXECUTABLE VERIFICATION ONLY** - No human action permitted.\n > Every criterion MUST be verifiable by running a command or using a tool.\n\n **If TDD (tests enabled):**\n - [ ] Test file created: src/auth/login.test.ts\n - [ ] bun test src/auth/login.test.ts \u2192 PASS (3 tests, 0 failures)\n\n **QA Scenarios (MANDATORY - task is INCOMPLETE without these):**\n\n > **This is NOT optional. A task without QA scenarios WILL BE REJECTED.**\n >\n > Write scenario tests that verify the ACTUAL BEHAVIOR of what you built.\n > Minimum: 1 happy path + 1 failure/edge case per task.\n > Each scenario = exact tool + exact steps + exact assertions + evidence path.\n >\n > **The executing agent MUST run these scenarios after implementation.**\n > **The orchestrator WILL verify evidence files exist before marking task complete.**\n\n \\`\\`\\`\n Scenario: [Happy path - what SHOULD work]\n Tool: [Playwright / interactive_bash / Bash (curl)]\n Preconditions: [Exact setup state]\n Steps:\n 1. [Exact action - specific command/selector/endpoint, no vagueness]\n 2. [Next action - with expected intermediate state]\n 3. [Assertion - exact expected value, not \"verify it works\"]\n Expected Result: [Concrete, observable, binary pass/fail]\n Failure Indicators: [What specifically would mean this failed]\n Evidence: .omo/evidence/task-{N}-{scenario-slug}.{ext}\n\n Scenario: [Failure/edge case - what SHOULD fail gracefully]\n Tool: [same format]\n Preconditions: [Invalid input / missing dependency / error state]\n Steps:\n 1. [Trigger the error condition]\n 2. [Assert error is handled correctly]\n Expected Result: [Graceful failure with correct error message/code]\n Evidence: .omo/evidence/task-{N}-{scenario-slug}-error.{ext}\n \\`\\`\\`\n\n > **Specificity requirements - every scenario MUST use:**\n > - **Selectors**: Specific CSS selectors (`.login-button`, not \"the login button\")\n > - **Data**: Concrete test data (`\"test@example.com\"`, not `\"[email]\"`)\n > - **Assertions**: Exact values (`text contains \"Welcome back\"`, not \"verify it works\")\n > - **Timing**: Wait conditions where relevant (`timeout: 10s`)\n > - **Negative**: At least ONE failure/error scenario per task\n >\n > **Anti-patterns (your scenario is INVALID if it looks like this):**\n > - \u274C \"Verify it works correctly\" - HOW? What does \"correctly\" mean?\n > - \u274C \"Check the API returns data\" - WHAT data? What fields? What values?\n > - \u274C \"Test the component renders\" - WHERE? What selector? What content?\n > - \u274C Any scenario without an evidence path\n\n **Evidence to Capture:**\n - [ ] Each evidence file named: task-{N}-{scenario-slug}.{ext}\n - [ ] Screenshots for UI, terminal output for CLI, response bodies for API\n\n **Commit**: YES | NO (groups with N)\n - Message: `type(scope): desc`\n - Files: `path/to/file`\n - Pre-commit: `test command`\n\n---\n\n## Final Verification Wave (MANDATORY \u2014 after ALL implementation tasks)\n\n> 4 review agents run in PARALLEL. ALL must APPROVE. Present consolidated results to user and get explicit \"okay\" before completing.\n>\n> **Do NOT auto-proceed after verification. Wait for user's explicit approval before marking work complete.**\n> **Never mark F1-F4 as checked before getting user's okay.** Rejection or user feedback -> fix -> re-run -> present again -> wait for okay.\n\n- [ ] F1. **Plan Compliance Audit** \u2014 `oracle`\n Read the plan end-to-end. For each \"Must Have\": verify implementation exists (read file, curl endpoint, run command). For each \"Must NOT Have\": search codebase for forbidden patterns \u2014 reject with file:line if found. Check evidence files exist in .omo/evidence/. Compare deliverables against plan.\n Output: `Must Have [N/N] | Must NOT Have [N/N] | Tasks [N/N] | VERDICT: APPROVE/REJECT`\n\n- [ ] F2. **Code Quality Review** \u2014 `unspecified-high`\n Run `tsc --noEmit` + linter + `bun test`. Review all changed files for: `as any`/`@ts-ignore`, empty catches, console.log in prod, commented-out code, unused imports. Check AI slop: excessive comments, over-abstraction, generic names (data/result/item/temp).\n Output: `Build [PASS/FAIL] | Lint [PASS/FAIL] | Tests [N pass/N fail] | Files [N clean/N issues] | VERDICT`\n\n- [ ] F3. **Real Manual QA** \u2014 `unspecified-high` (+ `playwright` skill if UI)\n Start from clean state. Execute EVERY QA scenario from EVERY task \u2014 follow exact steps, capture evidence. Test cross-task integration (features working together, not isolation). Test edge cases: empty state, invalid input, rapid actions. Save to `.omo/evidence/final-qa/`.\n Output: `Scenarios [N/N pass] | Integration [N/N] | Edge Cases [N tested] | VERDICT`\n\n- [ ] F4. **Scope Fidelity Check** \u2014 `deep`\n For each task: read \"What to do\", read actual diff (git log/diff). Verify 1:1 \u2014 everything in spec was built (no missing), nothing beyond spec was built (no creep). Check \"Must NOT do\" compliance. Detect cross-task contamination: Task N touching Task M's files. Flag unaccounted changes.\n Output: `Tasks [N/N compliant] | Contamination [CLEAN/N issues] | Unaccounted [CLEAN/N files] | VERDICT`\n\n---\n\n## Commit Strategy\n\n- **1**: `type(scope): desc` - file.ts, npm test\n\n---\n\n## Success Criteria\n\n### Verification Commands\n```bash\ncommand # Expected: output\n```\n\n### Final Checklist\n- [ ] All \"Must Have\" present\n- [ ] All \"Must NOT Have\" absent\n- [ ] All tests pass\n```\n\n---\n";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
/** Team Mode config - see .
|
|
2
|
+
/** Team Mode config - see .omo/plans/team-mode.md (D-01/D-25). */
|
|
3
3
|
export declare const TeamModeConfigSchema: z.ZodObject<{
|
|
4
4
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
5
5
|
tmux_visualization: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -3,6 +3,7 @@ export declare function isAbortedSessionError(error: unknown): boolean;
|
|
|
3
3
|
export declare function getErrorText(error: unknown): string;
|
|
4
4
|
export declare function extractErrorName(error: unknown): string | undefined;
|
|
5
5
|
export declare function extractErrorMessage(error: unknown): string | undefined;
|
|
6
|
+
export declare function extractErrorStatusCode(error: unknown): number | undefined;
|
|
6
7
|
interface EventPropertiesLike {
|
|
7
8
|
[key: string]: unknown;
|
|
8
9
|
}
|
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import type { BackgroundTask } from "./types";
|
|
2
2
|
import type { ConcurrencyManager } from "./concurrency";
|
|
3
3
|
import type { OpencodeClient, QueueItem } from "./constants";
|
|
4
|
+
import { log, readConnectedProvidersCache, readProviderModelsCache } from "../../shared";
|
|
5
|
+
import { shouldRetryError, getNextFallback, hasMoreFallbacks, selectFallbackProvider } from "../../shared/model-error-classifier";
|
|
6
|
+
import { transformModelForProvider } from "../../shared/provider-model-id-transform";
|
|
7
|
+
export type FallbackRetryHandlerDeps = {
|
|
8
|
+
log: typeof log;
|
|
9
|
+
readProviderModelsCache: typeof readProviderModelsCache;
|
|
10
|
+
readConnectedProvidersCache: typeof readConnectedProvidersCache;
|
|
11
|
+
shouldRetryError: typeof shouldRetryError;
|
|
12
|
+
getNextFallback: typeof getNextFallback;
|
|
13
|
+
hasMoreFallbacks: typeof hasMoreFallbacks;
|
|
14
|
+
selectFallbackProvider: typeof selectFallbackProvider;
|
|
15
|
+
transformModelForProvider: typeof transformModelForProvider;
|
|
16
|
+
};
|
|
4
17
|
export declare function tryFallbackRetry(args: {
|
|
5
18
|
task: BackgroundTask;
|
|
6
19
|
errorInfo: {
|
|
7
20
|
name?: string;
|
|
8
21
|
message?: string;
|
|
22
|
+
statusCode?: number;
|
|
9
23
|
};
|
|
10
24
|
source: string;
|
|
11
25
|
concurrencyManager: ConcurrencyManager;
|
|
@@ -21,4 +35,5 @@ export declare function tryFallbackRetry(args: {
|
|
|
21
35
|
failedError?: string;
|
|
22
36
|
nextModel: string;
|
|
23
37
|
}) => void;
|
|
38
|
+
deps?: Partial<FallbackRetryHandlerDeps>;
|
|
24
39
|
}): Promise<boolean>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
import type { BackgroundTaskConfig, TmuxConfig } from "../../config/schema";
|
|
2
3
|
import type { ModelFallbackControllerAccessor } from "../../hooks/model-fallback";
|
|
3
|
-
import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
|
|
4
|
-
import { TaskHistory } from "./task-history";
|
|
5
4
|
import { log } from "../../shared";
|
|
6
|
-
import type { BackgroundTaskConfig, TmuxConfig } from "../../config/schema";
|
|
7
5
|
import { type SubagentSpawnContext } from "./subagent-spawn-limits";
|
|
6
|
+
import { TaskHistory } from "./task-history";
|
|
7
|
+
import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
|
|
8
8
|
interface EventProperties {
|
|
9
9
|
sessionID?: string;
|
|
10
10
|
info?: {
|
|
@@ -56,8 +56,7 @@ export declare class BackgroundManager {
|
|
|
56
56
|
private completedTaskSummaries;
|
|
57
57
|
private idleDeferralTimers;
|
|
58
58
|
private notificationQueueByParent;
|
|
59
|
-
private
|
|
60
|
-
private pendingParentWakeTimers;
|
|
59
|
+
private readonly parentWakeNotifier;
|
|
61
60
|
private observedOutputSessions;
|
|
62
61
|
private observedIncompleteTodosBySession;
|
|
63
62
|
private rootDescendantCounts;
|
|
@@ -86,6 +85,8 @@ export declare class BackgroundManager {
|
|
|
86
85
|
private removeTask;
|
|
87
86
|
private archiveCompletedTask;
|
|
88
87
|
private updateTaskParent;
|
|
88
|
+
private captureResumeTaskSnapshot;
|
|
89
|
+
private restoreTaskAfterSkippedResume;
|
|
89
90
|
private removeTaskFromParentIndex;
|
|
90
91
|
launch(input: LaunchInput): Promise<BackgroundTask>;
|
|
91
92
|
private processKey;
|
|
@@ -113,17 +114,20 @@ export declare class BackgroundManager {
|
|
|
113
114
|
resume(input: ResumeInput): Promise<BackgroundTask>;
|
|
114
115
|
private checkSessionTodos;
|
|
115
116
|
private markSessionOutputObserved;
|
|
117
|
+
private clearDispatchedParentWake;
|
|
118
|
+
private requeueDispatchedParentWake;
|
|
116
119
|
private clearSessionOutputObserved;
|
|
117
120
|
private clearSessionTodoObservation;
|
|
118
121
|
private hasOutputSignalFromPart;
|
|
119
122
|
handleEvent(event: Event): void;
|
|
123
|
+
private interruptTaskFromAsyncPromptFailure;
|
|
120
124
|
private handleSessionErrorEvent;
|
|
121
125
|
private tryFallbackRetry;
|
|
122
126
|
markForNotification(task: BackgroundTask): void;
|
|
123
127
|
getPendingNotifications(sessionID: string): BackgroundTask[];
|
|
124
128
|
clearNotifications(sessionID: string): void;
|
|
125
129
|
queuePendingNotification(sessionID: string | undefined, notification: string): void;
|
|
126
|
-
injectPendingNotificationsIntoChatMessage(
|
|
130
|
+
injectPendingNotificationsIntoChatMessage(_output: {
|
|
127
131
|
parts: Array<{
|
|
128
132
|
type: string;
|
|
129
133
|
text?: string;
|
|
@@ -172,11 +176,10 @@ export declare class BackgroundManager {
|
|
|
172
176
|
*/
|
|
173
177
|
private tryCompleteTask;
|
|
174
178
|
private notifyParentSession;
|
|
179
|
+
private resolveParentWakePromptContext;
|
|
175
180
|
private isSessionActive;
|
|
176
181
|
private queuePendingParentWake;
|
|
177
182
|
private flushPendingParentWake;
|
|
178
|
-
private schedulePendingParentWakeFlush;
|
|
179
|
-
private clearPendingParentWakeTimer;
|
|
180
183
|
private hasRunningTasks;
|
|
181
184
|
private pruneStaleTasksAndNotifications;
|
|
182
185
|
private checkAndInterruptStaleTasks;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
type OpencodeClient = PluginInput["client"];
|
|
3
|
+
export type ParentWakePromptContext = {
|
|
4
|
+
agent?: string;
|
|
5
|
+
model?: {
|
|
6
|
+
providerID: string;
|
|
7
|
+
modelID: string;
|
|
8
|
+
};
|
|
9
|
+
variant?: string;
|
|
10
|
+
tools?: Record<string, boolean>;
|
|
11
|
+
};
|
|
12
|
+
export type PendingParentWake = {
|
|
13
|
+
promptContext: ParentWakePromptContext;
|
|
14
|
+
notifications: string[];
|
|
15
|
+
shouldReply: boolean;
|
|
16
|
+
dispatchedAt?: number;
|
|
17
|
+
toolCallDeferralStartedAt?: number;
|
|
18
|
+
};
|
|
19
|
+
type ParentWakeNotifierDeps = {
|
|
20
|
+
client: OpencodeClient;
|
|
21
|
+
directory: string;
|
|
22
|
+
enqueueNotificationForParent: (parentSessionID: string | undefined, operation: () => Promise<void>) => Promise<void>;
|
|
23
|
+
};
|
|
24
|
+
type ParentWakeNotifierOptions = {
|
|
25
|
+
pendingRetryMs: number;
|
|
26
|
+
acceptedMessageSkewMs: number;
|
|
27
|
+
toolCallDeferMaxMs: number;
|
|
28
|
+
failureRequeueWindowMs: number;
|
|
29
|
+
/**
|
|
30
|
+
* If the latest message in the parent session is a `user` message added
|
|
31
|
+
* within this window, the parent-wake injection is deferred. Prevents the
|
|
32
|
+
* race where a parent-wake `dispatchInternalPrompt` collides with a fresh
|
|
33
|
+
* user prompt, which on macOS/Electron has triggered native SIGABRT crashes
|
|
34
|
+
* inside OpenCode's `@parcel/watcher` TSFN callback path. See issue #4120.
|
|
35
|
+
*/
|
|
36
|
+
userMessageInProgressWindowMs: number;
|
|
37
|
+
};
|
|
38
|
+
export declare class ParentWakeNotifier {
|
|
39
|
+
private readonly deps;
|
|
40
|
+
private readonly options;
|
|
41
|
+
private pendingParentWakes;
|
|
42
|
+
private pendingParentWakeTimers;
|
|
43
|
+
private dispatchedParentWakes;
|
|
44
|
+
private dispatchedParentWakeTimers;
|
|
45
|
+
constructor(deps: ParentWakeNotifierDeps, options: ParentWakeNotifierOptions);
|
|
46
|
+
getPendingParentWakes(): Map<string, PendingParentWake>;
|
|
47
|
+
getPendingParentWakeTimers(): Map<string, ReturnType<typeof setTimeout>>;
|
|
48
|
+
getDispatchedParentWakes(): Map<string, PendingParentWake>;
|
|
49
|
+
getDispatchedParentWakeTimers(): Map<string, ReturnType<typeof setTimeout>>;
|
|
50
|
+
queuePendingParentWake(sessionID: string, notification: string, promptContext: ParentWakePromptContext, shouldReply: boolean, delayMs?: number): void;
|
|
51
|
+
flushPendingParentWake(sessionID: string): Promise<void>;
|
|
52
|
+
clearDispatchedParentWake(sessionID: string): void;
|
|
53
|
+
requeueDispatchedParentWake(sessionID: string, reason: string): Promise<boolean>;
|
|
54
|
+
schedulePendingParentWakeFlush(sessionID: string, delayMs?: number): void;
|
|
55
|
+
clearPendingParentWakeTimer(sessionID: string): void;
|
|
56
|
+
shutdown(): void;
|
|
57
|
+
private isSessionActive;
|
|
58
|
+
private resolveParentWakePromptContext;
|
|
59
|
+
private cloneParentWake;
|
|
60
|
+
private trackDispatchedParentWake;
|
|
61
|
+
private loadParentWakeSessionMessages;
|
|
62
|
+
private getParentWakeMessageRole;
|
|
63
|
+
private getParentWakeMessageFinish;
|
|
64
|
+
private getParentWakeMessageCreatedAt;
|
|
65
|
+
private parentWakePartIsWaitingOnTool;
|
|
66
|
+
private latestAssistantTurnIsWaitingOnTools;
|
|
67
|
+
private parentWakeMessageHasOutput;
|
|
68
|
+
private parentWakeMessageContainsNotification;
|
|
69
|
+
private isUserMessageInProgress;
|
|
70
|
+
private shouldDeferParentWakeForSessionHistory;
|
|
71
|
+
private hasAcceptedMessageAfterDispatchedParentWake;
|
|
72
|
+
private requeueWake;
|
|
73
|
+
}
|
|
74
|
+
export {};
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export declare function __disableScheduledForcedExitForTesting(): void;
|
|
3
3
|
/** @internal test-only */
|
|
4
4
|
export declare function __enableScheduledForcedExitForTesting(): void;
|
|
5
|
+
/** @internal test-only seam: exposes the error normalizer used by registerErrorEvent. */
|
|
6
|
+
export declare function describeProcessCleanupError(error: unknown): Record<string, unknown>;
|
|
5
7
|
interface CleanupTarget {
|
|
6
8
|
shutdown(): void | Promise<void>;
|
|
7
9
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { PluginInput } from "@opencode-ai/plugin";
|
|
2
|
+
import { promptWithModelSuggestionRetry } from "../../shared";
|
|
3
|
+
type OpencodeClient = PluginInput["client"];
|
|
4
|
+
type PromptAsyncArgs = Parameters<OpencodeClient["session"]["promptAsync"]>[0];
|
|
5
|
+
type PromptRetryClient = Parameters<typeof promptWithModelSuggestionRetry>[0];
|
|
6
|
+
type PromptRetryArgs = Parameters<typeof promptWithModelSuggestionRetry>[1];
|
|
7
|
+
type SessionMessagesArgs = Parameters<OpencodeClient["session"]["messages"]>[0];
|
|
8
|
+
export declare function routeSessionPrompt(args: PromptAsyncArgs, directory: string): PromptAsyncArgs;
|
|
9
|
+
export declare function promptAsyncInDirectory(client: OpencodeClient, args: PromptAsyncArgs, directory: string): Promise<unknown>;
|
|
10
|
+
export declare function promptWithRetryInDirectory(client: PromptRetryClient, args: PromptRetryArgs, directory: string): Promise<void>;
|
|
11
|
+
export declare function messagesInDirectory(client: OpencodeClient, args: SessionMessagesArgs, directory: string): Promise<unknown>;
|
|
12
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
|
|
2
|
-
import type { OpencodeClient, OnSubagentSessionCreated, QueueItem } from "./constants";
|
|
3
1
|
import type { ConcurrencyManager } from "./concurrency";
|
|
2
|
+
import type { OnSubagentSessionCreated, OpencodeClient, QueueItem } from "./constants";
|
|
3
|
+
import type { BackgroundTask, LaunchInput, ResumeInput } from "./types";
|
|
4
4
|
export declare const FALLBACK_AGENT = "general";
|
|
5
5
|
export declare function isAgentNotFoundError(error: unknown): boolean;
|
|
6
6
|
export declare function buildFallbackBody(originalBody: Record<string, unknown>, fallbackAgent: string, options?: {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BackgroundTask } from "./types";
|
|
2
|
+
export declare function rememberBackgroundTask(task: BackgroundTask): void;
|
|
3
|
+
export declare function archiveBackgroundTask(task: BackgroundTask): void;
|
|
4
|
+
export declare function getRegisteredBackgroundTask(taskID: string): BackgroundTask | undefined;
|
|
5
|
+
export declare function forgetBackgroundTask(taskID: string): void;
|
|
6
|
+
export declare function clearBackgroundTaskRegistryForTesting(): void;
|
|
@@ -64,6 +64,8 @@ export interface BackgroundTask {
|
|
|
64
64
|
parentAgent?: string;
|
|
65
65
|
/** Parent session's tool restrictions for notification prompts */
|
|
66
66
|
parentTools?: Record<string, boolean>;
|
|
67
|
+
skillContent?: string;
|
|
68
|
+
sessionPermission?: SessionPermissionRule[];
|
|
67
69
|
/** Marks if the task was launched from an unstable agent/category */
|
|
68
70
|
isUnstableAgent?: boolean;
|
|
69
71
|
/** Category used for this task (e.g., 'quick', 'visual-engineering') */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Boulder State Constants
|
|
3
3
|
*/
|
|
4
|
-
export declare const BOULDER_DIR = ".
|
|
4
|
+
export declare const BOULDER_DIR = ".omo";
|
|
5
5
|
export declare const BOULDER_FILE = "boulder.json";
|
|
6
|
-
export declare const BOULDER_STATE_PATH = ".
|
|
6
|
+
export declare const BOULDER_STATE_PATH = ".omo/boulder.json";
|
|
7
7
|
export declare const NOTEPAD_DIR = "notepads";
|
|
8
|
-
export declare const NOTEPAD_BASE_PATH = ".
|
|
8
|
+
export declare const NOTEPAD_BASE_PATH = ".omo/notepads";
|
|
9
9
|
/** Prometheus plan directory pattern */
|
|
10
|
-
export declare const PROMETHEUS_PLANS_DIR = ".
|
|
10
|
+
export declare const PROMETHEUS_PLANS_DIR = ".omo/plans";
|
|
@@ -21,7 +21,7 @@ export declare function upsertTaskSessionState(directory: string, input: {
|
|
|
21
21
|
}): BoulderState | null;
|
|
22
22
|
/**
|
|
23
23
|
* Find Prometheus plan files for this project.
|
|
24
|
-
* Prometheus stores plans at: {project}/.
|
|
24
|
+
* Prometheus stores plans at: {project}/.omo/plans/{name}.md
|
|
25
25
|
*/
|
|
26
26
|
export declare function findPrometheusPlans(directory: string): string[];
|
|
27
27
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const INIT_DEEP_TEMPLATE = "# /init-deep\n\nGenerate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.\n\n## Usage\n\n```\n/init-deep # Update mode: modify existing + create new where warranted\n/init-deep --create-new # Read existing \u2192 remove all \u2192 regenerate from scratch\n/init-deep --max-depth=2 # Limit directory depth (default: 3)\n```\n\n---\n\n## Workflow (High-Level)\n\n1. **Discovery + Analysis** (concurrent)\n - Fire background explore agents immediately\n - Main session: bash structure + LSP codemap + read existing AGENTS.md\n2. **Score & Decide** - Determine AGENTS.md locations from merged findings\n3. **Generate** - Root first, then subdirs in parallel\n4. **Review** - Deduplicate, trim, validate\n\n<critical>\n**TodoWrite ALL phases. Mark in_progress \u2192 completed in real-time.**\n```\nTodoWrite([\n { id: \"discovery\", content: \"Fire explore agents + LSP codemap + read existing\", status: \"pending\", priority: \"high\" },\n { id: \"scoring\", content: \"Score directories, determine locations\", status: \"pending\", priority: \"high\" },\n { id: \"generate\", content: \"Generate AGENTS.md files (root + subdirs)\", status: \"pending\", priority: \"high\" },\n { id: \"review\", content: \"Deduplicate, validate, trim\", status: \"pending\", priority: \"medium\" }\n])\n```\n</critical>\n\n---\n\n## Phase 1: Discovery + Analysis (Concurrent)\n\n**Mark \"discovery\" as in_progress.**\n\n### Fire Background Explore Agents IMMEDIATELY\n\nDon't wait-these run async while main session works.\n\n```\n// Fire all at once, collect results later\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore project structure\", run_in_background=true, prompt=\"Project structure: PREDICT standard patterns for detected language \u2192 REPORT deviations only\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find entry points\", run_in_background=true, prompt=\"Entry points: FIND main files \u2192 REPORT non-standard organization\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find conventions\", run_in_background=true, prompt=\"Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) \u2192 REPORT project-specific rules\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find anti-patterns\", run_in_background=true, prompt=\"Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments \u2192 LIST forbidden patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore build/CI\", run_in_background=true, prompt=\"Build/CI: FIND .github/workflows, Makefile \u2192 REPORT non-standard patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find test patterns\", run_in_background=true, prompt=\"Test patterns: FIND test configs, test structure \u2192 REPORT unique conventions\")\n```\n\n<dynamic-agents>\n**DYNAMIC AGENT SPAWNING**: After bash analysis, spawn ADDITIONAL explore agents based on project scale:\n\n| Factor | Threshold | Additional Agents |\n|--------|-----------|-------------------|\n| **Total files** | >100 | +1 per 100 files |\n| **Total lines** | >10k | +1 per 10k lines |\n| **Directory depth** | \u22654 | +2 for deep exploration |\n| **Large files (>500 lines)** | >10 files | +1 for complexity hotspots |\n| **Monorepo** | detected | +1 per package/workspace |\n| **Multiple languages** | >1 | +1 per language |\n\n```bash\n# Measure project scale first\ntotal_files=$(find . -type f -not -path '*/node_modules/*' -not -path '*/.git/*' | wc -l)\ntotal_lines=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" -o -name \"*.go\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}')\nlarge_files=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {count++} END {print count+0}')\nmax_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' | awk -F/ '{print NF}' | sort -rn | head -1)\n```\n\nExample spawning:\n```\n// 500 files, 50k lines, depth 6, 15 large files \u2192 spawn 5+5+2+1 = 13 additional agents\ntask(subagent_type=\"explore\", load_skills=[], description=\"Analyze large files\", run_in_background=true, prompt=\"Large file analysis: FIND files >500 lines, REPORT complexity hotspots\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore deep modules\", run_in_background=true, prompt=\"Deep modules at depth 4+: FIND hidden patterns, internal conventions\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find shared utilities\", run_in_background=true, prompt=\"Cross-cutting concerns: FIND shared utilities across directories\")\n// ... more based on calculation\n```\n</dynamic-agents>\n\n### Main Session: Concurrent Analysis\n\n**While background agents run**, main session does:\n\n#### 1. Bash Structural Analysis\n```bash\n# Directory depth + file counts\nfind . -type d -not -path '*/\\.*' -not -path '*/node_modules/*' -not -path '*/venv/*' -not -path '*/dist/*' -not -path '*/build/*' | awk -F/ '{print NF-1}' | sort -n | uniq -c\n\n# Files per directory (top 30)\nfind . -type f -not -path '*/\\.*' -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -30\n\n# Code concentration by extension\nfind . -type f \\( -name \"*.py\" -o -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.js\" -o -name \"*.go\" -o -name \"*.rs\" \\) -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -20\n\n# Existing AGENTS.md / CLAUDE.md\nfind . -type f \\( -name \"AGENTS.md\" -o -name \"CLAUDE.md\" \\) -not -path '*/node_modules/*' 2>/dev/null\n```\n\n#### 2. Read Existing AGENTS.md\n```\nFor each existing file found:\n Read(filePath=file)\n Extract: key insights, conventions, anti-patterns\n Store in EXISTING_AGENTS map\n```\n\nIf `--create-new`: Read all existing first (preserve context) \u2192 then delete all \u2192 regenerate.\n\n#### 3. LSP Codemap (if available)\n```\nLspServers() # Check availability\n\n# Entry points (parallel)\nLspDocumentSymbols(filePath=\"src/index.ts\")\nLspDocumentSymbols(filePath=\"main.py\")\n\n# Key symbols (parallel)\nLspWorkspaceSymbols(filePath=\".\", query=\"class\")\nLspWorkspaceSymbols(filePath=\".\", query=\"interface\")\nLspWorkspaceSymbols(filePath=\".\", query=\"function\")\n\n# Centrality for top exports\nLspFindReferences(filePath=\"...\", line=X, character=Y)\n```\n\n**LSP Fallback**: If unavailable, rely on explore agents + AST-grep.\n\n### Collect Background Results\n\n```\n// After main session analysis done, collect all task results\nfor each task_id: background_output(task_id=\"...\")\n```\n\n**Merge: bash + LSP + existing + explore findings. Mark \"discovery\" as completed.**\n\n---\n\n## Phase 2: Scoring & Location Decision\n\n**Mark \"scoring\" as in_progress.**\n\n### Scoring Matrix\n\n| Factor | Weight | High Threshold | Source |\n|--------|--------|----------------|--------|\n| File count | 3x | >20 | bash |\n| Subdir count | 2x | >5 | bash |\n| Code ratio | 2x | >70% | bash |\n| Unique patterns | 1x | Has own config | explore |\n| Module boundary | 2x | Has index.ts/__init__.py | bash |\n| Symbol density | 2x | >30 symbols | LSP |\n| Export count | 2x | >10 exports | LSP |\n| Reference centrality | 3x | >20 refs | LSP |\n\n### Decision Rules\n\n| Score | Action |\n|-------|--------|\n| **Root (.)** | ALWAYS create |\n| **>15** | Create AGENTS.md |\n| **8-15** | Create if distinct domain |\n| **<8** | Skip (parent covers) |\n\n### Output\n```\nAGENTS_LOCATIONS = [\n { path: \".\", type: \"root\" },\n { path: \"src/hooks\", score: 18, reason: \"high complexity\" },\n { path: \"src/api\", score: 12, reason: \"distinct domain\" }\n]\n```\n\n**Mark \"scoring\" as completed.**\n\n---\n\n## Phase 3: Generate AGENTS.md\n\n**Mark \"generate\" as in_progress.**\n\n<critical>\n**File Writing Rule**: If AGENTS.md already exists at the target path \u2192 use `Edit` tool. If it does NOT exist \u2192 use `Write` tool.\nNEVER use Write to overwrite an existing file. ALWAYS check existence first via `Read` or discovery results.\n</critical>\n\n### Root AGENTS.md (Full Treatment)\n\n```markdown\n# PROJECT KNOWLEDGE BASE\n\n**Generated:** {TIMESTAMP}\n**Commit:** {SHORT_SHA}\n**Branch:** {BRANCH}\n\n## OVERVIEW\n{1-2 sentences: what + core stack}\n\n## STRUCTURE\n\\`\\`\\`\n{root}/\n\u251C\u2500\u2500 {dir}/ # {non-obvious purpose only}\n\u2514\u2500\u2500 {entry}\n\\`\\`\\`\n\n## WHERE TO LOOK\n| Task | Location | Notes |\n|------|----------|-------|\n\n## CODE MAP\n{From LSP - skip if unavailable or project <10 files}\n\n| Symbol | Type | Location | Refs | Role |\n|--------|------|----------|------|------|\n\n## CONVENTIONS\n{ONLY deviations from standard}\n\n## ANTI-PATTERNS (THIS PROJECT)\n{Explicitly forbidden here}\n\n## UNIQUE STYLES\n{Project-specific}\n\n## COMMANDS\n\\`\\`\\`bash\n{dev/test/build}\n\\`\\`\\`\n\n## NOTES\n{Gotchas}\n```\n\n**Quality gates**: 50-150 lines, no generic advice, no obvious info.\n\n### Subdirectory AGENTS.md (Parallel)\n\nLaunch writing tasks for each location:\n\n```\nfor loc in AGENTS_LOCATIONS (except root):\n task(category=\"writing\", load_skills=[], run_in_background=false, description=\"Generate AGENTS.md\", prompt=\\`\n Generate AGENTS.md for: ${loc.path}\n - Reason: ${loc.reason}\n - 30-80 lines max\n - NEVER repeat parent content\n - Sections: OVERVIEW (1 line), STRUCTURE (if >5 subdirs), WHERE TO LOOK, CONVENTIONS (if different), ANTI-PATTERNS\n \\`)\n```\n\n**Wait for all. Mark \"generate\" as completed.**\n\n---\n\n## Phase 4: Review & Deduplicate\n\n**Mark \"review\" as in_progress.**\n\nFor each generated file:\n- Remove generic advice\n- Remove parent duplicates\n- Trim to size limits\n- Verify telegraphic style\n\n**Mark \"review\" as completed.**\n\n---\n\n## Final Report\n\n```\n=== init-deep Complete ===\n\nMode: {update | create-new}\n\nFiles:\n [OK] ./AGENTS.md (root, {N} lines)\n [OK] ./src/hooks/AGENTS.md ({N} lines)\n\nDirs Analyzed: {N}\nAGENTS.md Created: {N}\nAGENTS.md Updated: {N}\n\nHierarchy:\n ./AGENTS.md\n \u2514\u2500\u2500 src/hooks/AGENTS.md\n```\n\n---\n\n## Anti-Patterns\n\n- **Static agent count**: MUST vary agents based on project size/depth\n- **Sequential execution**: MUST parallel (explore + LSP concurrent)\n- **Ignoring existing**: ALWAYS read existing first, even with --create-new\n- **Over-documenting**: Not every dir needs AGENTS.md\n- **Redundancy**: Child never repeats parent\n- **Generic content**: Remove anything that applies to ALL projects\n- **Verbose style**: Telegraphic or die";
|
|
1
|
+
export declare const INIT_DEEP_TEMPLATE = "# /init-deep\n\nGenerate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.\n\n## Usage\n\n```\n/init-deep # Update mode: modify existing + create new where warranted\n/init-deep --create-new # Read existing \u2192 remove all \u2192 regenerate from scratch\n/init-deep --max-depth=2 # Limit directory depth (default: 3)\n```\n\n---\n\n## Workflow (High-Level)\n\n1. **Discovery + Analysis** (concurrent)\n - Fire background explore agents immediately\n - Main session: bash structure + LSP codemap + read existing AGENTS.md\n2. **Score & Decide** - Determine AGENTS.md locations from merged findings\n3. **Generate** - Root first, then subdirs in parallel\n4. **Review** - Deduplicate, trim, validate\n\n<critical>\n**TodoWrite ALL phases. Mark in_progress \u2192 completed in real-time.**\n```\nTodoWrite([\n { id: \"discovery\", content: \"Fire explore agents + LSP codemap + read existing\", status: \"pending\", priority: \"high\" },\n { id: \"scoring\", content: \"Score directories, determine locations\", status: \"pending\", priority: \"high\" },\n { id: \"generate\", content: \"Generate AGENTS.md files (root + subdirs)\", status: \"pending\", priority: \"high\" },\n { id: \"review\", content: \"Deduplicate, validate, trim\", status: \"pending\", priority: \"medium\" }\n])\n```\n</critical>\n\n---\n\n## Phase 1: Discovery + Analysis (Concurrent)\n\n**Mark \"discovery\" as in_progress.**\n\n### Fire Background Explore Agents IMMEDIATELY\n\nDon't wait-these run async while main session works.\n\n```\n// Fire all at once, collect results later\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore project structure\", run_in_background=true, prompt=\"Project structure: PREDICT standard patterns for detected language \u2192 REPORT deviations only\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find entry points\", run_in_background=true, prompt=\"Entry points: FIND main files \u2192 REPORT non-standard organization\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find conventions\", run_in_background=true, prompt=\"Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) \u2192 REPORT project-specific rules\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find anti-patterns\", run_in_background=true, prompt=\"Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments \u2192 LIST forbidden patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore build/CI\", run_in_background=true, prompt=\"Build/CI: FIND .github/workflows, Makefile \u2192 REPORT non-standard patterns\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find test patterns\", run_in_background=true, prompt=\"Test patterns: FIND test configs, test structure \u2192 REPORT unique conventions\")\n```\n\n<dynamic-agents>\n**DYNAMIC AGENT SPAWNING**: After bash analysis, spawn ADDITIONAL explore agents based on project scale:\n\n| Factor | Threshold | Additional Agents |\n|--------|-----------|-------------------|\n| **Total files** | >100 | +1 per 100 files |\n| **Total lines** | >10k | +1 per 10k lines |\n| **Directory depth** | \u22654 | +2 for deep exploration |\n| **Large files (>500 lines)** | >10 files | +1 for complexity hotspots |\n| **Monorepo** | detected | +1 per package/workspace |\n| **Multiple languages** | >1 | +1 per language |\n\n```bash\n# Measure project scale first\ntotal_files=$(find . -type f -not -path '*/node_modules/*' -not -path '*/.git/*' | wc -l)\ntotal_lines=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" -o -name \"*.go\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | tail -1 | awk '{print $1}')\nlarge_files=$(find . -type f \\( -name \"*.ts\" -o -name \"*.py\" \\) -not -path '*/node_modules/*' -exec wc -l {} + 2>/dev/null | awk '$1 > 500 {count++} END {print count+0}')\nmax_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' | awk -F/ '{print NF}' | sort -rn | head -1)\n```\n\nExample spawning:\n```\n// 500 files, 50k lines, depth 6, 15 large files \u2192 spawn 5+5+2+1 = 13 additional agents\ntask(subagent_type=\"explore\", load_skills=[], description=\"Analyze large files\", run_in_background=true, prompt=\"Large file analysis: FIND files >500 lines, REPORT complexity hotspots\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Explore deep modules\", run_in_background=true, prompt=\"Deep modules at depth 4+: FIND hidden patterns, internal conventions\")\ntask(subagent_type=\"explore\", load_skills=[], description=\"Find shared utilities\", run_in_background=true, prompt=\"Cross-cutting concerns: FIND shared utilities across directories\")\n// ... more based on calculation\n```\n</dynamic-agents>\n\n### Main Session: Concurrent Analysis\n\n**While background agents run**, main session does:\n\n#### 1. Bash Structural Analysis\n```bash\n# Directory depth + file counts\nfind . -type d -not -path '*/\\.*' -not -path '*/node_modules/*' -not -path '*/venv/*' -not -path '*/dist/*' -not -path '*/build/*' | awk -F/ '{print NF-1}' | sort -n | uniq -c\n\n# Files per directory (top 30)\nfind . -type f -not -path '*/\\.*' -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -30\n\n# Code concentration by extension\nfind . -type f \\( -name \"*.py\" -o -name \"*.ts\" -o -name \"*.tsx\" -o -name \"*.js\" -o -name \"*.go\" -o -name \"*.rs\" \\) -not -path '*/node_modules/*' | sed 's|/[^/]*$||' | sort | uniq -c | sort -rn | head -20\n\n# Existing AGENTS.md / CLAUDE.md\nfind . -type f \\( -name \"AGENTS.md\" -o -name \"CLAUDE.md\" \\) -not -path '*/node_modules/*' 2>/dev/null\n```\n\n#### 2. Read Existing AGENTS.md\n```\nFor each existing file found:\n Read(filePath=file)\n Extract: key insights, conventions, anti-patterns\n Store in EXISTING_AGENTS map\n```\n\nIf `--create-new`: Read all existing first (preserve context) \u2192 then delete all \u2192 regenerate.\n\n#### 3. LSP Codemap (if available)\n```\nLspServers() # Check availability\n\n# Entry points (parallel)\nLspDocumentSymbols(filePath=\"src/index.ts\")\nLspDocumentSymbols(filePath=\"main.py\")\n\n# Key symbols (parallel)\nLspWorkspaceSymbols(filePath=\".\", query=\"class\")\nLspWorkspaceSymbols(filePath=\".\", query=\"interface\")\nLspWorkspaceSymbols(filePath=\".\", query=\"function\")\n\n# Centrality for top exports\nLspFindReferences(filePath=\"...\", line=X, character=Y)\n```\n\n**LSP Fallback**: If unavailable, rely on explore agents + AST-grep.\n\n### Collect Background Results\n\n```\n// After main session analysis done, collect all task results\nfor each background task ID (`bg_...`): background_output(task_id=\"bg_...\")\n```\n\n**Merge: bash + LSP + existing + explore findings. Mark \"discovery\" as completed.**\n\n---\n\n## Phase 2: Scoring & Location Decision\n\n**Mark \"scoring\" as in_progress.**\n\n### Scoring Matrix\n\n| Factor | Weight | High Threshold | Source |\n|--------|--------|----------------|--------|\n| File count | 3x | >20 | bash |\n| Subdir count | 2x | >5 | bash |\n| Code ratio | 2x | >70% | bash |\n| Unique patterns | 1x | Has own config | explore |\n| Module boundary | 2x | Has index.ts/__init__.py | bash |\n| Symbol density | 2x | >30 symbols | LSP |\n| Export count | 2x | >10 exports | LSP |\n| Reference centrality | 3x | >20 refs | LSP |\n\n### Decision Rules\n\n| Score | Action |\n|-------|--------|\n| **Root (.)** | ALWAYS create |\n| **>15** | Create AGENTS.md |\n| **8-15** | Create if distinct domain |\n| **<8** | Skip (parent covers) |\n\n### Output\n```\nAGENTS_LOCATIONS = [\n { path: \".\", type: \"root\" },\n { path: \"src/hooks\", score: 18, reason: \"high complexity\" },\n { path: \"src/api\", score: 12, reason: \"distinct domain\" }\n]\n```\n\n**Mark \"scoring\" as completed.**\n\n---\n\n## Phase 3: Generate AGENTS.md\n\n**Mark \"generate\" as in_progress.**\n\n<critical>\n**File Writing Rule**: If AGENTS.md already exists at the target path \u2192 use `Edit` tool. If it does NOT exist \u2192 use `Write` tool.\nNEVER use Write to overwrite an existing file. ALWAYS check existence first via `Read` or discovery results.\n</critical>\n\n### Root AGENTS.md (Full Treatment)\n\n```markdown\n# PROJECT KNOWLEDGE BASE\n\n**Generated:** {TIMESTAMP}\n**Commit:** {SHORT_SHA}\n**Branch:** {BRANCH}\n\n## OVERVIEW\n{1-2 sentences: what + core stack}\n\n## STRUCTURE\n\\`\\`\\`\n{root}/\n\u251C\u2500\u2500 {dir}/ # {non-obvious purpose only}\n\u2514\u2500\u2500 {entry}\n\\`\\`\\`\n\n## WHERE TO LOOK\n| Task | Location | Notes |\n|------|----------|-------|\n\n## CODE MAP\n{From LSP - skip if unavailable or project <10 files}\n\n| Symbol | Type | Location | Refs | Role |\n|--------|------|----------|------|------|\n\n## CONVENTIONS\n{ONLY deviations from standard}\n\n## ANTI-PATTERNS (THIS PROJECT)\n{Explicitly forbidden here}\n\n## UNIQUE STYLES\n{Project-specific}\n\n## COMMANDS\n\\`\\`\\`bash\n{dev/test/build}\n\\`\\`\\`\n\n## NOTES\n{Gotchas}\n```\n\n**Quality gates**: 50-150 lines, no generic advice, no obvious info.\n\n### Subdirectory AGENTS.md (Parallel)\n\nLaunch writing tasks for each location:\n\n```\nfor loc in AGENTS_LOCATIONS (except root):\n task(category=\"writing\", load_skills=[], run_in_background=false, description=\"Generate AGENTS.md\", prompt=\\`\n Generate AGENTS.md for: ${loc.path}\n - Reason: ${loc.reason}\n - 30-80 lines max\n - NEVER repeat parent content\n - Sections: OVERVIEW (1 line), STRUCTURE (if >5 subdirs), WHERE TO LOOK, CONVENTIONS (if different), ANTI-PATTERNS\n \\`)\n```\n\n**Wait for all. Mark \"generate\" as completed.**\n\n---\n\n## Phase 4: Review & Deduplicate\n\n**Mark \"review\" as in_progress.**\n\nFor each generated file:\n- Remove generic advice\n- Remove parent duplicates\n- Trim to size limits\n- Verify telegraphic style\n\n**Mark \"review\" as completed.**\n\n---\n\n## Final Report\n\n```\n=== init-deep Complete ===\n\nMode: {update | create-new}\n\nFiles:\n [OK] ./AGENTS.md (root, {N} lines)\n [OK] ./src/hooks/AGENTS.md ({N} lines)\n\nDirs Analyzed: {N}\nAGENTS.md Created: {N}\nAGENTS.md Updated: {N}\n\nHierarchy:\n ./AGENTS.md\n \u2514\u2500\u2500 src/hooks/AGENTS.md\n```\n\n---\n\n## Anti-Patterns\n\n- **Static agent count**: MUST vary agents based on project size/depth\n- **Sequential execution**: MUST parallel (explore + LSP concurrent)\n- **Ignoring existing**: ALWAYS read existing first, even with --create-new\n- **Over-documenting**: Not every dir needs AGENTS.md\n- **Redundancy**: Child never repeats parent\n- **Generic content**: Remove anything that applies to ALL projects\n- **Verbose style**: Telegraphic or die";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const START_WORK_TEMPLATE = "You are starting a Sisyphus work session.\n\n## ARGUMENTS\n\n- `/start-work [plan-name] [--worktree <path>]`\n - `plan-name` (optional): name or partial match of the plan to start\n - `--worktree <path>` (optional): absolute path to an existing git worktree to work in\n - If specified and valid: hook pre-sets worktree_path in boulder.json\n - If specified but invalid: you must run `git worktree add <path> <branch>` first\n - If omitted: work directly in the current project directory (no worktree)\n\n## WHAT TO DO\n\n1. **Find available plans**: Search for Prometheus-generated plan files at `.
|
|
1
|
+
export declare const START_WORK_TEMPLATE = "You are starting a Sisyphus work session.\n\n## ARGUMENTS\n\n- `/start-work [plan-name] [--worktree <path>]`\n - `plan-name` (optional): name or partial match of the plan to start\n - `--worktree <path>` (optional): absolute path to an existing git worktree to work in\n - If specified and valid: hook pre-sets worktree_path in boulder.json\n - If specified but invalid: you must run `git worktree add <path> <branch>` first\n - If omitted: work directly in the current project directory (no worktree)\n\n## WHAT TO DO\n\n1. **Find available plans**: Search for Prometheus-generated plan files at `.omo/plans/`\n\n2. **Check for active boulder state**: Read `.omo/boulder.json` if it exists\n\n3. **Decision logic**:\n - If multiple active works are listed in your context:\n - This means boulder.json has more than one work with status: `active` or `paused`\n - Use the Question tool to ask the user which plan to resume\n - Resume by running `/start-work {plan-name}` for the selected plan\n - If the user says \"start a new plan\", continue with cold-start auto-selection logic\n - If exactly one active work is listed and the user did not name a plan:\n - Auto-resume that single active work\n - If no active plan OR plan is complete:\n - List available plan files\n - If ONE plan: auto-select it\n - If MULTIPLE plans: show list with timestamps, ask user to select\n\n4. **Worktree Setup** (ONLY when `--worktree` was explicitly specified and `worktree_path` not already set in boulder.json):\n 1. `git worktree list --porcelain` - see available worktrees\n 2. Create: `git worktree add <absolute-path> <branch-or-HEAD>`\n 3. Update boulder.json to add `\"worktree_path\": \"<absolute-path>\"`\n 4. All work happens inside that worktree directory\n\n5. **Create/Update boulder.json**:\n ```json\n {\n \"active_plan\": \"/absolute/path/to/plan.md\",\n \"started_at\": \"ISO_TIMESTAMP\",\n \"session_ids\": [\"session_id_1\", \"session_id_2\"],\n \"plan_name\": \"plan-name\",\n \"worktree_path\": \"/absolute/path/to/git/worktree\"\n }\n ```\n\n6. **Read the plan file** and start executing tasks according to atlas workflow\n\n## OUTPUT FORMAT\n\nWhen listing plans for selection:\n```\nAvailable Work Plans\n\nCurrent Time: {ISO timestamp}\nSession ID: {current session id}\n\n1. [plan-name-1.md] - Modified: {date} - Progress: 3/10 tasks\n2. [plan-name-2.md] - Modified: {date} - Progress: 0/5 tasks\n\nWhich plan would you like to work on? (Enter number or plan name)\n```\n\nWhen resuming existing work:\n```\nResuming Work Session\n\nActive Plan: {plan-name}\nProgress: {completed}/{total} tasks\nSessions: {count} (appending current session)\nWorktree: {worktree_path}\n\nReading plan and continuing from last incomplete task...\n```\n\nWhen auto-selecting single plan:\n```\nStarting Work Session\n\nPlan: {plan-name}\nSession ID: {session_id}\nStarted: {timestamp}\nWorktree: {worktree_path}\n\nReading plan and beginning execution...\n```\n\n## CRITICAL\n\n- The session_id is injected by the hook - use it directly\n- Always update boulder.json BEFORE starting work\n- If worktree_path is set in boulder.json, all work happens inside that worktree directory\n- Read the FULL plan file before delegating any tasks\n- Follow atlas delegation protocols (7-section format)\n\n## TASK BREAKDOWN (MANDATORY)\n\nAfter reading the plan file, you MUST decompose every plan task into granular, implementation-level sub-steps and register ALL of them as task/todo items BEFORE starting any work.\n\n**How to break down**:\n- Each plan checkbox item (e.g., `- [ ] Add user authentication`) must be split into concrete, actionable sub-tasks\n- Sub-tasks should be specific enough that each one touches a clear set of files/functions\n- Include: file to modify, what to change, expected behavior, and how to verify\n- Do NOT leave any task vague - \"implement feature X\" is NOT acceptable; \"add validateToken() to src/auth/middleware.ts that checks JWT expiry and returns 401\" IS acceptable\n\n**Example breakdown**:\nPlan task: `- [ ] Add rate limiting to API`\n\u2192 Todo items:\n 1. Create `src/middleware/rate-limiter.ts` with sliding window algorithm (max 100 req/min per IP)\n 2. Add RateLimiter middleware to `src/app.ts` router chain, before auth middleware\n 3. Add rate limit headers (X-RateLimit-Limit, X-RateLimit-Remaining) to response in `rate-limiter.ts`\n 4. Add test: verify 429 response after exceeding limit in `src/middleware/rate-limiter.test.ts`\n 5. Add test: verify headers are present on normal responses\n\nRegister these as task/todo items so progress is tracked and visible throughout the session.\n\n## WORKTREE COMPLETION\n\nWhen working in a worktree (`worktree_path` is set in boulder.json) and ALL plan tasks are complete:\n1. Commit all remaining changes in the worktree\n2. **Sync .omo state back**: Copy `.omo/` from the worktree to the main repo before removal.\n This is CRITICAL when `.omo/` is gitignored - state written during worktree execution would otherwise be lost.\n ```bash\n cp -r <worktree-path>/.omo/* <main-repo>/.omo/ 2>/dev/null || true\n ```\n3. Switch to the main working directory (the original repo, NOT the worktree)\n4. Merge the worktree branch into the current branch: `git merge <worktree-branch>`\n5. If merge succeeds, clean up: `git worktree remove <worktree-path>`\n6. Remove the boulder.json state\n\nThis is the DEFAULT behavior when `--worktree` was used. Skip merge only if the user explicitly instructs otherwise (e.g., asks to create a PR instead).";
|
|
@@ -1,2 +1,20 @@
|
|
|
1
1
|
import { type GitMasterConfig } from "../../config/schema";
|
|
2
|
+
import { type ShellType } from "../../shared/shell-env";
|
|
3
|
+
/**
|
|
4
|
+
* Parse a bash-format env prefix string ("VAR=value VAR2=value2") into a Record.
|
|
5
|
+
* Only handles simple KEY=VALUE pairs (no quoting needed since assertValidGitEnvPrefix
|
|
6
|
+
* already validates the format is shell-safe alphanumeric assignments).
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseBashEnvPrefix(prefix: string): Record<string, string>;
|
|
9
|
+
/**
|
|
10
|
+
* Build the shell-aware command prefix for git commands.
|
|
11
|
+
* Uses the shared shell detection and env prefix builder to emit correct syntax
|
|
12
|
+
* for PowerShell ($env:VAR='value';), cmd (set VAR="value" &&),
|
|
13
|
+
* csh (setenv VAR value;), or unix (VAR=value).
|
|
14
|
+
*
|
|
15
|
+
* For unix shells, we use the inline VAR=value prefix style (not export) to match
|
|
16
|
+
* the original behavior where the env var applies only to the immediately following command.
|
|
17
|
+
* For csh/tcsh, we use setenv syntax since csh does not support inline VAR=value.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildShellAwareGitPrefix(bashPrefix: string, shellType?: ShellType): string;
|
|
2
20
|
export declare function injectGitMasterConfig(template: string, config?: GitMasterConfig): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const CONTINUATION_MARKER_DIR = ".
|
|
1
|
+
export declare const CONTINUATION_MARKER_DIR = ".omo/run-continuation";
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { TmuxCommandResult } from "../../../shared/tmux";
|
|
1
2
|
type ResolvedCallerTmuxSession = {
|
|
2
3
|
sessionId: string;
|
|
3
4
|
paneId: string;
|
|
4
5
|
windowTarget: string;
|
|
5
6
|
};
|
|
6
|
-
|
|
7
|
+
type RunTmuxCommand = (tmuxPath: string, args: string[]) => Promise<TmuxCommandResult>;
|
|
8
|
+
export declare function resolveCallerTmuxSession(tmuxPath: string, callerPaneId?: string | undefined, runCommand?: RunTmuxCommand): Promise<ResolvedCallerTmuxSession | null>;
|
|
7
9
|
export {};
|
|
@@ -13,7 +13,7 @@ export declare const createTeamRunMock: import("bun:test").Mock<(spec: TeamSpec,
|
|
|
13
13
|
teamName: string;
|
|
14
14
|
specSource: "user" | "project";
|
|
15
15
|
createdAt: number;
|
|
16
|
-
status: "
|
|
16
|
+
status: "active" | "failed" | "deleted" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
|
|
17
17
|
members: {
|
|
18
18
|
name: string;
|
|
19
19
|
agentType: "leader" | "general-purpose";
|
|
@@ -108,7 +108,7 @@ export declare const loadTeamSpecMock: import("bun:test").Mock<() => Promise<{
|
|
|
108
108
|
export declare const listActiveTeamsMock: import("bun:test").Mock<() => Promise<{
|
|
109
109
|
teamRunId: string;
|
|
110
110
|
teamName: string;
|
|
111
|
-
status: "
|
|
111
|
+
status: "active" | "failed" | "deleted" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
|
|
112
112
|
memberCount: number;
|
|
113
113
|
scope: "user" | "project";
|
|
114
114
|
}[]>>;
|
|
@@ -118,7 +118,7 @@ export declare const loadRuntimeStateMock: import("bun:test").Mock<(teamRunId: s
|
|
|
118
118
|
teamName: string;
|
|
119
119
|
specSource: "user" | "project";
|
|
120
120
|
createdAt: number;
|
|
121
|
-
status: "
|
|
121
|
+
status: "active" | "failed" | "deleted" | "creating" | "shutdown_requested" | "deleting" | "orphaned";
|
|
122
122
|
members: {
|
|
123
123
|
name: string;
|
|
124
124
|
agentType: "leader" | "general-purpose";
|
|
@@ -255,9 +255,9 @@ export declare const RuntimeStateSchema: z.ZodObject<{
|
|
|
255
255
|
}>;
|
|
256
256
|
createdAt: z.ZodNumber;
|
|
257
257
|
status: z.ZodEnum<{
|
|
258
|
-
deleted: "deleted";
|
|
259
|
-
failed: "failed";
|
|
260
258
|
active: "active";
|
|
259
|
+
failed: "failed";
|
|
260
|
+
deleted: "deleted";
|
|
261
261
|
creating: "creating";
|
|
262
262
|
shutdown_requested: "shutdown_requested";
|
|
263
263
|
deleting: "deleting";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare const ATTACHABLE_SESSION_STATUSES: readonly ["idle", "running"];
|
|
1
|
+
declare const ATTACHABLE_SESSION_STATUSES: readonly ["idle", "running", "busy"];
|
|
2
2
|
export type AttachableSessionStatus = (typeof ATTACHABLE_SESSION_STATUSES)[number];
|
|
3
3
|
export declare function isAttachableSessionStatus(status: string | undefined): status is AttachableSessionStatus;
|
|
4
4
|
export {};
|
|
@@ -2,6 +2,7 @@ import type { PluginInput } from "@opencode-ai/plugin";
|
|
|
2
2
|
import type { TmuxConfig } from "../../config/schema";
|
|
3
3
|
import type { WindowState } from "./types";
|
|
4
4
|
import * as sharedModule from "../../shared";
|
|
5
|
+
import { executeActions, executeAction } from "./action-executor";
|
|
5
6
|
type OpencodeClient = PluginInput["client"];
|
|
6
7
|
interface SessionCreatedEvent {
|
|
7
8
|
type: string;
|
|
@@ -21,6 +22,8 @@ export interface TmuxUtilDeps {
|
|
|
21
22
|
client: OpencodeClient;
|
|
22
23
|
sessionId: string;
|
|
23
24
|
}) => Promise<boolean>;
|
|
25
|
+
executeActions: typeof executeActions;
|
|
26
|
+
executeAction: typeof executeAction;
|
|
24
27
|
log: typeof sharedModule.log;
|
|
25
28
|
}
|
|
26
29
|
export declare class TmuxSessionManager {
|
|
@@ -47,6 +50,7 @@ export declare class TmuxSessionManager {
|
|
|
47
50
|
private isolatedContainerNullStateCount;
|
|
48
51
|
private staleSweepCompleted;
|
|
49
52
|
private staleSweepInProgress;
|
|
53
|
+
private isolatedSessionManagerId;
|
|
50
54
|
constructor(ctx: PluginInput, tmuxConfig: TmuxConfig, deps?: Partial<TmuxUtilDeps>);
|
|
51
55
|
private isEnabled;
|
|
52
56
|
private isIsolated;
|
|
@@ -61,8 +65,10 @@ export declare class TmuxSessionManager {
|
|
|
61
65
|
private cleanupIsolatedContainerAfterSessionDeletion;
|
|
62
66
|
private markSessionClosePending;
|
|
63
67
|
private queryWindowStateSafely;
|
|
68
|
+
private activateTrackedSessionPane;
|
|
64
69
|
private windowStateContainsPane;
|
|
65
70
|
private finalizeForceRemoveCandidate;
|
|
71
|
+
private canAutoActivatePane;
|
|
66
72
|
private closeTrackedSessionPane;
|
|
67
73
|
private finalizeTrackedSessionClose;
|
|
68
74
|
private closeTrackedSession;
|
|
@@ -2,6 +2,8 @@ import type { TmuxPaneInfo } from "./types";
|
|
|
2
2
|
type ParsedPaneState = {
|
|
3
3
|
windowWidth: number;
|
|
4
4
|
windowHeight: number;
|
|
5
|
+
windowActive: boolean;
|
|
6
|
+
sessionAttached: boolean;
|
|
5
7
|
panes: TmuxPaneInfo[];
|
|
6
8
|
};
|
|
7
9
|
export declare function parsePaneStateOutput(stdout: string): ParsedPaneState | null;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import type { OpencodeClient } from "../../tools/delegate-task/types";
|
|
2
|
-
import type { TrackedSession } from "./types";
|
|
2
|
+
import type { TrackedSession, WindowState } from "./types";
|
|
3
3
|
export declare class TmuxPollingManager {
|
|
4
4
|
private client;
|
|
5
5
|
private sessions;
|
|
6
6
|
private closeSessionById;
|
|
7
7
|
private retryPendingCloses?;
|
|
8
|
+
private getWindowState?;
|
|
9
|
+
private activateSessionPane?;
|
|
10
|
+
private canActivatePane;
|
|
8
11
|
private pollInterval?;
|
|
9
12
|
private pollingInFlight;
|
|
10
|
-
constructor(client: OpencodeClient, sessions: Map<string, TrackedSession>, closeSessionById: (sessionId: string) => Promise<void>, retryPendingCloses?: (() => Promise<void>) | undefined);
|
|
13
|
+
constructor(client: OpencodeClient, sessions: Map<string, TrackedSession>, closeSessionById: (sessionId: string) => Promise<void>, retryPendingCloses?: (() => Promise<void>) | undefined, getWindowState?: (() => Promise<WindowState | null>) | undefined, activateSessionPane?: ((tracked: TrackedSession) => Promise<boolean>) | undefined, canActivatePane?: (state: WindowState) => boolean);
|
|
11
14
|
handleEvent(event: {
|
|
12
15
|
type: string;
|
|
13
16
|
properties?: Record<string, unknown>;
|
|
@@ -16,4 +19,5 @@ export declare class TmuxPollingManager {
|
|
|
16
19
|
stopPolling(): void;
|
|
17
20
|
private pollSessions;
|
|
18
21
|
private getEventSessionId;
|
|
22
|
+
private activateFocusedPanes;
|
|
19
23
|
}
|
|
@@ -2,6 +2,8 @@ export interface TrackedSession {
|
|
|
2
2
|
sessionId: string;
|
|
3
3
|
paneId: string;
|
|
4
4
|
description: string;
|
|
5
|
+
attachActivated: boolean;
|
|
6
|
+
attachActivatedAt?: Date;
|
|
5
7
|
createdAt: Date;
|
|
6
8
|
lastSeenAt: Date;
|
|
7
9
|
closePending: boolean;
|
|
@@ -25,6 +27,8 @@ export interface TmuxPaneInfo {
|
|
|
25
27
|
export interface WindowState {
|
|
26
28
|
windowWidth: number;
|
|
27
29
|
windowHeight: number;
|
|
30
|
+
windowActive?: boolean;
|
|
31
|
+
sessionAttached?: boolean;
|
|
28
32
|
mainPane: TmuxPaneInfo | null;
|
|
29
33
|
agentPanes: TmuxPaneInfo[];
|
|
30
34
|
}
|