commandmate 0.42.2 → 0.44.0
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/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +176 -176
- package/.next/app-path-routes-manifest.json +34 -34
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +15 -15
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route.js.nft.json +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +2 -2
- package/.next/server/app/api/app/update/route.js.nft.json +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route.js.nft.json +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route.js.nft.json +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route.js.nft.json +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +103 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route.js.nft.json +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.js.nft.json +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route.js.nft.json +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route.js +1 -1
- package/.next/server/app/api/skills/installations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route.js +2 -2
- package/.next/server/app/api/skills/operations/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route.js +1 -1
- package/.next/server/app/api/skills/reindex/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route.js +1 -1
- package/.next/server/app/api/slash-commands/route.js.nft.json +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route.js.nft.json +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.js.nft.json +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route.js.nft.json +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js +7 -7
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -103
- package/.next/server/app/api/worktrees/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +3 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -103
- package/.next/server/app/api/worktrees/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +103 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +103 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js +1 -1
- package/.next/server/app/skills/[skillId]/page.js.nft.json +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- package/.next/server/app/worktrees/[id]/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page.js.nft.json +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +34 -34
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1501.js +3 -3
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/22.js +1 -1
- package/.next/server/chunks/2283.js +15 -0
- package/.next/server/chunks/2328.js +1 -1
- package/.next/server/chunks/2404.js +4 -3
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/252.js +1 -1
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3730.js +1 -1
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/4207.js +3 -3
- package/.next/server/chunks/4802.js +1 -1
- package/.next/server/chunks/488.js +1 -0
- package/.next/server/chunks/5064.js +1 -1
- package/.next/server/chunks/5326.js +1 -1
- package/.next/server/chunks/5456.js +1 -1
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/5775.js +1 -1
- package/.next/server/chunks/611.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6285.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6474.js +14 -0
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/6661.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/6793.js +1 -1
- package/.next/server/chunks/6927.js +1 -0
- package/.next/server/chunks/7491.js +3 -0
- package/.next/server/chunks/7506.js +1 -1
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8543.js +1 -1
- package/.next/server/chunks/8581.js +2 -2
- package/.next/server/chunks/8728.js +2 -2
- package/.next/server/chunks/8782.js +1 -0
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8800.js +4 -3
- package/.next/server/chunks/8918.js +108 -6
- package/.next/server/chunks/9130.js +3 -3
- package/.next/server/chunks/{8052.js → 9353.js} +4 -2
- package/.next/server/chunks/9390.js +3 -0
- package/.next/server/chunks/9627.js +3 -3
- package/.next/server/chunks/967.js +1 -0
- package/.next/server/chunks/9731.js +3 -3
- package/.next/server/chunks/9882.js +3 -3
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/src/middleware.js +2 -2
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/chunks/2053-85a974ddfe7498fe.js +1 -0
- package/.next/static/chunks/{2407-6b9e12c099fa598c.js → 2407-340774f1a24f2b45.js} +1 -1
- package/.next/static/chunks/5449-6cb80bab2bd06b79.js +1 -0
- package/.next/static/chunks/5521-c358c31f60e5e689.js +1 -0
- package/.next/static/chunks/591-0a45801e83f26f24.js +1 -0
- package/.next/static/chunks/8165-3853772f6ae1299b.js +1 -0
- package/.next/static/chunks/{8566-a6a7c70558927410.js → 8566-aeda747542072ace.js} +1 -1
- package/.next/static/chunks/8811-29eaa24237f48558.js +1 -0
- package/.next/static/chunks/{9619-22adf5367c4b7080.js → 9619-84aced0846cbe3ac.js} +1 -1
- package/.next/static/chunks/app/{layout-5b95e1236dcd9ef6.js → layout-0fc249fb7de75a27.js} +1 -1
- package/.next/static/chunks/app/review/page-ff9efae3f86eb840.js +1 -0
- package/.next/static/chunks/app/sessions/page-55297155e7bf01b9.js +1 -0
- package/.next/static/chunks/app/skills/[skillId]/page-9ee7a381636e60cb.js +1 -0
- package/.next/static/chunks/app/skills/page-182e16168b2fc098.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-d2103e0c25be83c8.js +1 -0
- package/.next/static/css/38070d879efa1371.css +1 -0
- package/.next/trace +13 -13
- package/README.md +58 -620
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +23 -149
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +11 -1
- package/dist/cli/commands/docs.d.ts.map +1 -1
- package/dist/cli/commands/docs.js +5 -0
- package/dist/cli/commands/remote.d.ts +24 -1
- package/dist/cli/commands/remote.d.ts.map +1 -1
- package/dist/cli/commands/remote.js +155 -6
- package/dist/cli/commands/reply.d.ts +40 -0
- package/dist/cli/commands/reply.d.ts.map +1 -0
- package/dist/cli/commands/reply.js +133 -0
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +255 -112
- package/dist/cli/commands/stop.d.ts.map +1 -1
- package/dist/cli/commands/stop.js +53 -1
- package/dist/cli/commands/sync.js +3 -3
- package/dist/cli/commands/wait.d.ts +5 -0
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +10 -1
- package/dist/cli/docs/agent-operations.d.ts +2 -2
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +13 -0
- package/dist/cli/docs/setup-guide.d.ts +14 -0
- package/dist/cli/docs/setup-guide.d.ts.map +1 -0
- package/dist/cli/docs/setup-guide.js +366 -0
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +4 -0
- package/dist/cli/types/api-responses.d.ts +11 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +2 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/daemon.d.ts +42 -2
- package/dist/cli/utils/daemon.d.ts.map +1 -1
- package/dist/cli/utils/daemon.js +222 -40
- package/dist/cli/utils/docs-reader.d.ts +6 -0
- package/dist/cli/utils/docs-reader.d.ts.map +1 -1
- package/dist/cli/utils/docs-reader.js +14 -13
- package/dist/cli/utils/npm-runner.d.ts +12 -0
- package/dist/cli/utils/npm-runner.d.ts.map +1 -1
- package/dist/cli/utils/npm-runner.js +36 -0
- package/dist/cli/utils/process-inspect.d.ts +55 -0
- package/dist/cli/utils/process-inspect.d.ts.map +1 -0
- package/dist/cli/utils/process-inspect.js +214 -0
- package/dist/cli/utils/remote-pairing.d.ts +68 -0
- package/dist/cli/utils/remote-pairing.d.ts.map +1 -0
- package/dist/cli/utils/remote-pairing.js +117 -0
- package/dist/cli/utils/reply-ledger.d.ts +95 -0
- package/dist/cli/utils/reply-ledger.d.ts.map +1 -0
- package/dist/cli/utils/reply-ledger.js +187 -0
- package/dist/cli/utils/server-identity.d.ts +50 -0
- package/dist/cli/utils/server-identity.d.ts.map +1 -0
- package/dist/cli/utils/server-identity.js +118 -0
- package/dist/cli/utils/server-ready.d.ts +13 -0
- package/dist/cli/utils/server-ready.d.ts.map +1 -1
- package/dist/cli/utils/server-ready.js +16 -0
- package/dist/lib/cli-tools/copilot-executable.d.ts +9 -0
- package/dist/lib/cli-tools/copilot-executable.d.ts.map +1 -1
- package/dist/lib/cli-tools/copilot-executable.js +21 -5
- package/dist/lib/cli-tools/opencode-executable.d.ts +103 -0
- package/dist/lib/cli-tools/opencode-executable.d.ts.map +1 -0
- package/dist/lib/cli-tools/opencode-executable.js +179 -0
- package/dist/lib/cli-tools/types.d.ts +1 -1
- package/dist/lib/cli-tools/types.d.ts.map +1 -1
- package/dist/lib/cli-tools/types.js +5 -1
- package/dist/lib/detection/tools/verified-against.d.ts +15 -0
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +17 -1
- package/dist/lib/detection/version-probes.d.ts.map +1 -1
- package/dist/lib/detection/version-probes.js +14 -1
- package/dist/lib/security/pairing-code.d.ts +2 -1
- package/dist/lib/security/pairing-code.d.ts.map +1 -1
- package/dist/lib/session/tmux-session-surface.d.ts.map +1 -1
- package/dist/lib/session/tmux-session-surface.js +1 -1
- package/dist/server/locales/en/worktree.json +72 -20
- package/dist/server/locales/ja/worktree.json +72 -20
- package/dist/server/server.js +23 -0
- package/dist/server/src/config/cli-tool-timing-config.js +19 -1
- package/dist/server/src/config/detection-evidence-config.js +3 -0
- package/dist/server/src/config/image-extensions.js +1 -0
- package/dist/server/src/config/schedule-config.js +55 -1
- package/dist/server/src/lib/auto-yes-poller.js +69 -4
- package/dist/server/src/lib/cli-tools/agent-mode-spec.js +54 -2
- package/dist/server/src/lib/cli-tools/base.js +6 -2
- package/dist/server/src/lib/cli-tools/command-code-plan-review.js +175 -0
- package/dist/server/src/lib/cli-tools/command-code.js +81 -2
- package/dist/server/src/lib/cli-tools/composer-spec.js +10 -0
- package/dist/server/src/lib/cli-tools/copilot-executable.js +21 -5
- package/dist/server/src/lib/cli-tools/graceful-exit.js +15 -1
- package/dist/server/src/lib/cli-tools/index.js +3 -1
- package/dist/server/src/lib/cli-tools/install-hints.js +9 -3
- package/dist/server/src/lib/cli-tools/liveness-spec.js +19 -0
- package/dist/server/src/lib/cli-tools/manager.js +2 -0
- package/dist/server/src/lib/cli-tools/opencode-executable.js +179 -0
- package/dist/server/src/lib/cli-tools/opencode-v2.js +369 -0
- package/dist/server/src/lib/cli-tools/opencode.js +29 -5
- package/dist/server/src/lib/cli-tools/types.js +5 -1
- package/dist/server/src/lib/cmate-cli-tool-parser.js +65 -7
- package/dist/server/src/lib/cmate-parser.js +12 -0
- package/dist/server/src/lib/cmate-validator.js +13 -1
- package/dist/server/src/lib/detection/cli-patterns.js +172 -3
- package/dist/server/src/lib/detection/model-info-extractor.js +79 -7
- package/dist/server/src/lib/detection/status-detector.js +10 -1
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +2 -1
- package/dist/server/src/lib/detection/tools/codex/detect.js +26 -0
- package/dist/server/src/lib/detection/tools/command-code/plan-review-state.js +75 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/detect.js +253 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/dialog-title.js +48 -0
- package/dist/server/src/lib/detection/tools/registry.js +2 -0
- package/dist/server/src/lib/detection/tools/run-detection.js +9 -0
- package/dist/server/src/lib/detection/tools/verified-against.js +17 -1
- package/dist/server/src/lib/detection/upstream-faults.js +8 -0
- package/dist/server/src/lib/detection/version-probes.js +14 -1
- package/dist/server/src/lib/hooks/agent-session-telemetry.js +36 -1
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +33 -1
- package/dist/server/src/lib/hooks/sources/opencode/log-diagnosis.js +105 -0
- package/dist/server/src/lib/hooks/sources/opencode/source.js +7 -1
- package/dist/server/src/lib/hooks/sources/opencode-v2/client.js +422 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/decision-labels.js +24 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/history.js +421 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/ingest.js +271 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/mappers.js +165 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/payloads.js +351 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/ports.js +230 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/reattach.js +149 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/runtime.js +180 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/secrets.js +182 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/source.js +295 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/subscription.js +455 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/tool-id.js +18 -0
- package/dist/server/src/lib/hooks/sources/opencode-v2/usage.js +214 -0
- package/dist/server/src/lib/hooks/sources/registry.js +2 -0
- package/dist/server/src/lib/hooks/structured-decision-response.js +14 -5
- package/dist/server/src/lib/job-executor.js +2 -1
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +15 -1
- package/dist/server/src/lib/polling/structured-history-gate.js +19 -5
- package/dist/server/src/lib/relay/relay-delivery.js +4 -1
- package/dist/server/src/lib/session/agent-event-state.js +24 -0
- package/dist/server/src/lib/session/claude-executor.js +186 -12
- package/dist/server/src/lib/session/claude-session.js +131 -15
- package/dist/server/src/lib/session/current-output-builder.js +27 -3
- package/dist/server/src/lib/session/send-user-message.js +4 -0
- package/dist/server/src/lib/session/session-start-error.js +20 -0
- package/dist/server/src/lib/session/structured-prompt.js +54 -0
- package/dist/server/src/lib/session/tmux-session-surface.js +1 -1
- package/dist/server/src/lib/skills/agent-state-paths.js +39 -0
- package/dist/server/src/lib/skills/compatibility-matrix.js +65 -0
- package/dist/server/src/lib/skills/receipt-owned-paths.js +118 -0
- package/dist/server/src/lib/tmux/tmux.js +73 -2
- package/dist/server/src/lib/verification/env-clean-gate.js +281 -10
- package/dist/server/src/lib/verification/gate-runner.js +29 -2
- package/dist/server/src/lib/verification/scope-gate.js +58 -4
- package/dist/server/src/types/cli-tool-contracts.js +10 -2
- package/dist/types/cli-tool-contracts.d.ts +16 -5
- package/dist/types/cli-tool-contracts.d.ts.map +1 -1
- package/dist/types/cli-tool-contracts.js +10 -2
- package/docs/en/architecture.md +722 -0
- package/docs/en/user-guide/agents-guide.md +306 -0
- package/docs/en/user-guide/cli-setup-guide.md +676 -0
- package/docs/en/user-guide/cmate-schedules-guide.md +388 -0
- package/docs/en/user-guide/commands-guide.md +467 -0
- package/docs/en/user-guide/quick-start.md +231 -0
- package/docs/en/user-guide/webapp-guide.md +1020 -0
- package/docs/en/user-guide/workflow-examples.md +463 -0
- package/package.json +19 -7
- package/release-notes/0.43.0.json +130 -0
- package/release-notes/0.44.0.json +82 -0
- package/scripts/hooks/cmate-agent-event.sh +14 -0
- package/scripts/opencode-v2/launch.sh +226 -0
- package/.next/server/chunks/1990.js +0 -103
- package/.next/server/chunks/3707.js +0 -15
- package/.next/server/chunks/4443.js +0 -3
- package/.next/server/chunks/5164.js +0 -1
- package/.next/server/chunks/5742.js +0 -1
- package/.next/server/chunks/7004.js +0 -1
- package/.next/server/chunks/8673.js +0 -14
- package/.next/static/chunks/2039-117a361f795ddc4b.js +0 -1
- package/.next/static/chunks/2053-611dd27d42721b79.js +0 -1
- package/.next/static/chunks/3778-56f41fc2cecb8c43.js +0 -1
- package/.next/static/chunks/5449-550bd273dccc3ae4.js +0 -1
- package/.next/static/chunks/7705-2a2936551b0cf9a3.js +0 -1
- package/.next/static/chunks/8165-934ee7ff3b4ddfd4.js +0 -1
- package/.next/static/chunks/app/review/page-30616daa1dc595c2.js +0 -1
- package/.next/static/chunks/app/sessions/page-1a8ba152bbcb9efb.js +0 -1
- package/.next/static/chunks/app/skills/[skillId]/page-ab7e432b69fccb3b.js +0 -1
- package/.next/static/chunks/app/skills/page-56b4fa11223e0cbd.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-59f5337e031518c6.js +0 -1
- package/.next/static/css/b3f433d52b8ed5c8.css +0 -1
- /package/.next/static/{MXZXkcFAnpELZnxxHB4iJ → wu7SUiHTirFcrpo5teyZ3}/_buildManifest.js +0 -0
- /package/.next/static/{MXZXkcFAnpELZnxxHB4iJ → wu7SUiHTirFcrpo5teyZ3}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which `opencode` is OpenCode 1.x and which is OpenCode V2 (Issue #2939).
|
|
4
|
+
*
|
|
5
|
+
* ## Why the name is not enough
|
|
6
|
+
*
|
|
7
|
+
* OpenCode V2's npm package `@opencode/cli` (2.0.18) registers **both**
|
|
8
|
+
* `opencode` and `opencode2` in its `bin`. So on a machine that has it,
|
|
9
|
+
* `opencode` may be OpenCode 1.x (its own installer, `~/.opencode/bin`) or
|
|
10
|
+
* OpenCode V2 (`/opt/homebrew/bin/opencode`), decided by nothing but the order
|
|
11
|
+
* of `PATH`. Asking `which opencode` then answers "OpenCode is installed" for a
|
|
12
|
+
* V2 binary, and the v1 launch line (`opencode --port N --hostname …`) reaches
|
|
13
|
+
* a program that has neither flag.
|
|
14
|
+
*
|
|
15
|
+
* The answer here is the version each candidate prints about itself:
|
|
16
|
+
*
|
|
17
|
+
* - OpenCode 1.x prints a bare `1.18.33`;
|
|
18
|
+
* - OpenCode V2 prints `opencode v2.0.18`.
|
|
19
|
+
*
|
|
20
|
+
* Every `opencode` / `opencode2` on `PATH` is a candidate, not just the first,
|
|
21
|
+
* so a V2 `opencode` earlier on `PATH` no longer hides a 1.x one behind it.
|
|
22
|
+
*
|
|
23
|
+
* ## Probe and launch are one measurement
|
|
24
|
+
*
|
|
25
|
+
* The path that answered is the path the launch line runs — the rule
|
|
26
|
+
* `./copilot-executable` set for copilot (#1907). The server resolves names on
|
|
27
|
+
* its own `PATH`, the pane on its login shell's; typing a bare `opencode` would
|
|
28
|
+
* let the two disagree.
|
|
29
|
+
*
|
|
30
|
+
* ## Cost
|
|
31
|
+
*
|
|
32
|
+
* `opencode --version` takes ~0.4 s and both tools probe `opencode`, so one
|
|
33
|
+
* probe per path is shared for {@link OPENCODE_EXECUTABLE_CACHE_TTL_MS}, and a
|
|
34
|
+
* concurrent caller gets the probe already in flight.
|
|
35
|
+
*
|
|
36
|
+
* @module lib/cli-tools/opencode-executable
|
|
37
|
+
*/
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.OPENCODE_EXECUTABLE_CACHE_TTL_MS = exports.OPENCODE_VERSION_PROBE_TIMEOUT_MS = exports.OPENCODE_V2_BINARY_NAME = exports.OPENCODE_V1_BINARY_NAME = void 0;
|
|
40
|
+
exports.parseOpencodeVersionOutput = parseOpencodeVersionOutput;
|
|
41
|
+
exports.clearOpencodeExecutableCache = clearOpencodeExecutableCache;
|
|
42
|
+
exports.probeOpencodeExecutable = probeOpencodeExecutable;
|
|
43
|
+
exports.resolveOpencodeV1Executable = resolveOpencodeV1Executable;
|
|
44
|
+
exports.resolveOpencodeV2Executable = resolveOpencodeV2Executable;
|
|
45
|
+
exports.describeOpencodeV1Unavailable = describeOpencodeV1Unavailable;
|
|
46
|
+
const child_process_1 = require("child_process");
|
|
47
|
+
const copilot_executable_1 = require("./copilot-executable");
|
|
48
|
+
const env_sanitizer_1 = require("../security/env-sanitizer");
|
|
49
|
+
/** OpenCode 1.x's executable name (tool id `opencode`). */
|
|
50
|
+
exports.OPENCODE_V1_BINARY_NAME = 'opencode';
|
|
51
|
+
/** OpenCode V2's own executable name (tool id `opencode-v2`). */
|
|
52
|
+
exports.OPENCODE_V2_BINARY_NAME = 'opencode2';
|
|
53
|
+
/** Budget for one `--version`. */
|
|
54
|
+
exports.OPENCODE_VERSION_PROBE_TIMEOUT_MS = 5000;
|
|
55
|
+
/** `--version` prints one short line; anything bigger is not an answer. */
|
|
56
|
+
const OPENCODE_VERSION_PROBE_MAX_BUFFER = 64 * 1024;
|
|
57
|
+
/** How long one probe result is reused (same TTL as the installed-agents cache). */
|
|
58
|
+
exports.OPENCODE_EXECUTABLE_CACHE_TTL_MS = 30_000;
|
|
59
|
+
/** Candidates probed per name. A PATH with more copies than this is not a setup to guess about. */
|
|
60
|
+
const MAX_CANDIDATES_PER_NAME = 4;
|
|
61
|
+
/** `opencode v2.0.18` — OpenCode V2's form. */
|
|
62
|
+
const PREFIXED_VERSION_LINE = /^opencode v(\d+)\.(\d+)\.(\d+)((?:[-+][0-9A-Za-z.-]+)?)$/;
|
|
63
|
+
/** `1.18.33` — OpenCode 1.x's form: the version and nothing else. */
|
|
64
|
+
const BARE_VERSION_LINE = /^v?(\d+)\.(\d+)\.(\d+)((?:[-+][0-9A-Za-z.-]+)?)$/;
|
|
65
|
+
/**
|
|
66
|
+
* Classify `opencode --version` / `opencode2 --version` output.
|
|
67
|
+
*
|
|
68
|
+
* A line has to be a version in one of the two forms and nothing else, so a
|
|
69
|
+
* different program that happens to print a number is not taken for either.
|
|
70
|
+
* The major version decides: 1 is OpenCode 1.x, 2 or later is OpenCode V2.
|
|
71
|
+
* `0.x` (the pre-1.0 `opencode`) and anything unreadable are null.
|
|
72
|
+
*
|
|
73
|
+
* @returns The generation and version, or null when the output is not OpenCode's
|
|
74
|
+
*/
|
|
75
|
+
function parseOpencodeVersionOutput(output) {
|
|
76
|
+
for (const rawLine of output.split(/\r?\n/)) {
|
|
77
|
+
const line = rawLine.trim();
|
|
78
|
+
if (!line)
|
|
79
|
+
continue;
|
|
80
|
+
const match = PREFIXED_VERSION_LINE.exec(line) ?? BARE_VERSION_LINE.exec(line);
|
|
81
|
+
if (!match)
|
|
82
|
+
continue;
|
|
83
|
+
const major = Number(match[1]);
|
|
84
|
+
const version = `${match[1]}.${match[2]}.${match[3]}${match[4] ?? ''}`;
|
|
85
|
+
if (major === 1)
|
|
86
|
+
return { generation: 'v1', version };
|
|
87
|
+
if (major >= 2)
|
|
88
|
+
return { generation: 'v2', version };
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const probeCache = new Map();
|
|
94
|
+
/** Forget every cached probe (tests, and a caller that knows the install changed). */
|
|
95
|
+
function clearOpencodeExecutableCache() {
|
|
96
|
+
probeCache.clear();
|
|
97
|
+
}
|
|
98
|
+
function runVersionProbe(executable) {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
try {
|
|
101
|
+
(0, child_process_1.execFile)(executable, ['--version'], {
|
|
102
|
+
timeout: exports.OPENCODE_VERSION_PROBE_TIMEOUT_MS,
|
|
103
|
+
maxBuffer: OPENCODE_VERSION_PROBE_MAX_BUFFER,
|
|
104
|
+
env: (0, env_sanitizer_1.sanitizeEnvForChildProcess)(),
|
|
105
|
+
}, (error, stdout, stderr) => {
|
|
106
|
+
if (error) {
|
|
107
|
+
resolve(null);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
resolve(parseOpencodeVersionOutput(`${stdout ?? ''}\n${stderr ?? ''}`));
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
resolve(null);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
/** `<path> --version`, classified; cached per path. Never rejects. */
|
|
119
|
+
function probeOpencodeExecutable(path) {
|
|
120
|
+
const now = Date.now();
|
|
121
|
+
const cached = probeCache.get(path);
|
|
122
|
+
if (cached && cached.expiresAt > now)
|
|
123
|
+
return cached.info;
|
|
124
|
+
const info = runVersionProbe(path);
|
|
125
|
+
probeCache.set(path, { expiresAt: now + exports.OPENCODE_EXECUTABLE_CACHE_TTL_MS, info });
|
|
126
|
+
return info;
|
|
127
|
+
}
|
|
128
|
+
/** Probe `names` in order and return the first candidate of `generation`. */
|
|
129
|
+
async function resolveGeneration(names, generation) {
|
|
130
|
+
const probed = [];
|
|
131
|
+
for (const name of names) {
|
|
132
|
+
for (const path of (0, copilot_executable_1.findExecutablesOnPath)(name, MAX_CANDIDATES_PER_NAME)) {
|
|
133
|
+
if (probed.some((p) => p.path === path))
|
|
134
|
+
continue;
|
|
135
|
+
const info = await probeOpencodeExecutable(path);
|
|
136
|
+
probed.push({ path, info });
|
|
137
|
+
if (info?.generation === generation) {
|
|
138
|
+
return { executable: { path, version: info.version, generation }, probed };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { executable: null, probed };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* OpenCode 1.x: the first `opencode` on `PATH` that prints a 1.x version.
|
|
146
|
+
* An `opencode` that answers `opencode v2.x` is skipped, never launched.
|
|
147
|
+
*/
|
|
148
|
+
function resolveOpencodeV1Executable() {
|
|
149
|
+
return resolveGeneration([exports.OPENCODE_V1_BINARY_NAME], 'v1');
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* OpenCode V2: `opencode2` first, then an `opencode` that prints
|
|
153
|
+
* `opencode v2.x` — for an operator who has V2 only under the `opencode` name.
|
|
154
|
+
*/
|
|
155
|
+
function resolveOpencodeV2Executable() {
|
|
156
|
+
return resolveGeneration([exports.OPENCODE_V2_BINARY_NAME, exports.OPENCODE_V1_BINARY_NAME], 'v2');
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Why OpenCode 1.x counts as not installed, when there is more to say than
|
|
160
|
+
* "no `opencode` on PATH".
|
|
161
|
+
*
|
|
162
|
+
* @returns A sentence naming the `opencode` that is there and what it is, or
|
|
163
|
+
* null when nothing called `opencode` was found at all
|
|
164
|
+
*/
|
|
165
|
+
function describeOpencodeV1Unavailable(resolution) {
|
|
166
|
+
if (resolution.executable)
|
|
167
|
+
return null;
|
|
168
|
+
const v2 = resolution.probed.find((p) => p.info?.generation === 'v2');
|
|
169
|
+
if (v2?.info) {
|
|
170
|
+
return (`\`opencode\` at ${v2.path} is OpenCode V2 ${v2.info.version}, not OpenCode 1.x ` +
|
|
171
|
+
'(npm `@opencode/cli` registers both `opencode` and `opencode2`). ' +
|
|
172
|
+
'Use the OpenCode V2 agent, or put an OpenCode 1.x `opencode` on PATH.');
|
|
173
|
+
}
|
|
174
|
+
const other = resolution.probed[0];
|
|
175
|
+
if (other) {
|
|
176
|
+
return `\`opencode\` at ${other.path} did not report an OpenCode 1.x version (\`opencode --version\`).`;
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenCode V2 (`opencode2`) CLI tool (Issue #2934, Epic #2370 Phase 1).
|
|
4
|
+
*
|
|
5
|
+
* A separate tool from `opencode` (v1), not a version branch of it: OpenCode
|
|
6
|
+
* 2.0's server, event vocabulary and screen all differ, and v1 keeps every
|
|
7
|
+
* behaviour it had (Epic #2370, decision 1).
|
|
8
|
+
*
|
|
9
|
+
* ## The pane
|
|
10
|
+
*
|
|
11
|
+
* One tmux pane holds both processes OpenCode V2 needs. The launch line runs
|
|
12
|
+
* `scripts/opencode-v2/launch.sh`, which starts `opencode2 serve` on the
|
|
13
|
+
* instance's own port with the instance's own password, waits for
|
|
14
|
+
* `GET /openapi.json`, runs `opencode2 --server <url> <worktree>` in the
|
|
15
|
+
* foreground, and — through a trap on EXIT / HUP / INT / TERM — stops the server
|
|
16
|
+
* whichever way the TUI goes. So `/exit`, a crashed TUI and `tmux kill-session`
|
|
17
|
+
* all release the port (the #1905 failure, prevented by construction), and a
|
|
18
|
+
* CommandMate restart leaves both running because neither is CommandMate's
|
|
19
|
+
* child.
|
|
20
|
+
*
|
|
21
|
+
* ## What is structured and what is read off the screen
|
|
22
|
+
*
|
|
23
|
+
* - state (running / ready / waiting) comes from the server's SSE stream
|
|
24
|
+
* (`@/lib/hooks/sources/opencode-v2`), subscribed once the TUI is up;
|
|
25
|
+
* - sending goes through the TUI's composer via tmux, as for v1's fallback
|
|
26
|
+
* path (D6). `session.prompt` is not used: it addresses a session by id, and
|
|
27
|
+
* the TUI may be showing a different one;
|
|
28
|
+
* - the screen scraper still reads the pane, as every tool's fallback.
|
|
29
|
+
*
|
|
30
|
+
* Phase 2 adds approvals / questions / History, Phase 3 richer screen reading
|
|
31
|
+
* and quick keys ({@link OpenCodeV2Tool.navigationKeys}, Issue #2966).
|
|
32
|
+
*
|
|
33
|
+
* @module lib/cli-tools/opencode-v2
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.OpenCodeV2Tool = exports.OPENCODE_V2_NAVIGATION_KEY_VALUES = exports.OPENCODE_V2_RESUME_RETRY_MS = exports.OPENCODE_V2_READY_MAX_ATTEMPTS = exports.OPENCODE_V2_READY_POLL_INTERVAL_MS = void 0;
|
|
37
|
+
exports.parseOpencodeV2Version = parseOpencodeV2Version;
|
|
38
|
+
exports.toOpencodeV2ComposerText = toOpencodeV2ComposerText;
|
|
39
|
+
const child_process_1 = require("child_process");
|
|
40
|
+
const util_1 = require("util");
|
|
41
|
+
const base_1 = require("./base");
|
|
42
|
+
const terminal_keys_1 = require("../../types/terminal-keys");
|
|
43
|
+
const tmux_1 = require("../tmux/tmux");
|
|
44
|
+
const cli_patterns_1 = require("../detection/cli-patterns");
|
|
45
|
+
const submit_verified_sender_1 = require("./submit-verified-sender");
|
|
46
|
+
const tmux_capture_cache_1 = require("../tmux/tmux-capture-cache");
|
|
47
|
+
const tmux_pane_config_1 = require("../../config/tmux-pane-config");
|
|
48
|
+
const logger_1 = require("../../lib/logger");
|
|
49
|
+
const errors_1 = require("../../lib/errors");
|
|
50
|
+
const agent_session_lifecycle_1 = require("../../lib/session/agent-session-lifecycle");
|
|
51
|
+
const runtime_1 = require("../../lib/hooks/sources/opencode-v2/runtime");
|
|
52
|
+
const client_1 = require("../../lib/hooks/sources/opencode-v2/client");
|
|
53
|
+
const ports_1 = require("../../lib/hooks/sources/opencode-v2/ports");
|
|
54
|
+
const subscription_1 = require("../../lib/hooks/sources/opencode-v2/subscription");
|
|
55
|
+
const tool_id_1 = require("../../lib/hooks/sources/opencode-v2/tool-id");
|
|
56
|
+
const graceful_exit_1 = require("./graceful-exit");
|
|
57
|
+
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
58
|
+
const install_hints_1 = require("./install-hints");
|
|
59
|
+
const opencode_executable_1 = require("./opencode-executable");
|
|
60
|
+
const logger = (0, logger_1.createLogger)('cli-tools/opencode-v2');
|
|
61
|
+
const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
|
|
62
|
+
/** Interval between composer polls (launch and send). */
|
|
63
|
+
exports.OPENCODE_V2_READY_POLL_INTERVAL_MS = 500;
|
|
64
|
+
/** Composer polls after the launch line before giving up (30 s at 500 ms). */
|
|
65
|
+
exports.OPENCODE_V2_READY_MAX_ATTEMPTS = 60;
|
|
66
|
+
/** Rows captured when looking for the composer. The pane is 200 rows tall. */
|
|
67
|
+
const OPENCODE_V2_READY_CAPTURE_LINES = tmux_pane_config_1.OPENCODE_PANE_HEIGHT;
|
|
68
|
+
/**
|
|
69
|
+
* How long a failed lazy resume is not retried (ms). `isRunning` is polled, and
|
|
70
|
+
* a server that is really gone must not be probed on every poll.
|
|
71
|
+
*/
|
|
72
|
+
exports.OPENCODE_V2_RESUME_RETRY_MS = 30_000;
|
|
73
|
+
/**
|
|
74
|
+
* The version `opencode2 --version` reports, or null when the output is not
|
|
75
|
+
* OpenCode V2's. Issue #2939: the same rule OpenCode 1.x is told apart by
|
|
76
|
+
* (`./opencode-executable`), so `1.18.33` is not V2 and `opencode v2.0.18` is.
|
|
77
|
+
*/
|
|
78
|
+
function parseOpencodeV2Version(output) {
|
|
79
|
+
const info = (0, opencode_executable_1.parseOpencodeVersionOutput)(output);
|
|
80
|
+
return info?.generation === 'v2' ? info.version : null;
|
|
81
|
+
}
|
|
82
|
+
/** A bare `/<name>`: a slash command with no argument and no whitespace at all. */
|
|
83
|
+
const BARE_SLASH_COMMAND = /^\/\S+$/;
|
|
84
|
+
/**
|
|
85
|
+
* The text to type for `message` (Issue #2950).
|
|
86
|
+
*
|
|
87
|
+
* The TUI opens its command dropdown on any composer text starting with `/`,
|
|
88
|
+
* and while it is open Enter picks a row instead of submitting — so a bare
|
|
89
|
+
* `/probe-agentsskills` sits in the composer ("No matching commands") and runs
|
|
90
|
+
* nothing, while `/probe-agentsskills ` (one trailing space) closes the
|
|
91
|
+
* dropdown and runs. The palette already inserts `` `${trigger} ` `` (see
|
|
92
|
+
* `loadOpencodeSkills` in `@/lib/slash-commands`, "The trailing space is
|
|
93
|
+
* load-bearing"), but the send route trims the body, so the space never
|
|
94
|
+
* arrives. It is put back here, and only for a bare `/<name>`: a command with
|
|
95
|
+
* an argument already has a space after the name, and ordinary text does not
|
|
96
|
+
* open the dropdown.
|
|
97
|
+
*/
|
|
98
|
+
function toOpencodeV2ComposerText(message) {
|
|
99
|
+
return BARE_SLASH_COMMAND.test(message) ? `${message} ` : message;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The leader-chord letters OpenCode V2 2.0.18 answers on its home screen, as
|
|
103
|
+
* sent by `OpencodeQuickKeys`' v2 strip (Issue #2966): `a` agents, `l`
|
|
104
|
+
* sessions, `m` models. `n` (new session) is also sent, but is already in
|
|
105
|
+
* {@link NAVIGATION_KEY_VALUES} (#2254), so it is not listed twice.
|
|
106
|
+
*
|
|
107
|
+
* Deliberately narrower than v1's `OPENCODE_CHORD_ONLY_VALUES`. Measured on
|
|
108
|
+
* 2.0.18 (private tmux socket, 80 columns, isolated `HOME` / XDG dirs):
|
|
109
|
+
* `ctrl+x t` is not `theme_list` any more — on the home screen the leader lets
|
|
110
|
+
* the `t` through into the composer, and inside a session it opens a terminal
|
|
111
|
+
* pane. `g` / `u` / `r` / `c` work only inside a session and type their letter
|
|
112
|
+
* into the composer otherwise; the strip does not offer them for v2 (see
|
|
113
|
+
* `OpencodeQuickKeys`), so they are not declared either.
|
|
114
|
+
*/
|
|
115
|
+
const OPENCODE_V2_CHORD_ONLY_VALUES = ['a', 'l', 'm'];
|
|
116
|
+
/**
|
|
117
|
+
* Everything an OpenCode V2 pane may be sent through `/special-keys`: the base
|
|
118
|
+
* pad plus the `ctrl+x` leader, `ctrl+p` / `ctrl+t`, and the three chord
|
|
119
|
+
* letters above (Issue #2966).
|
|
120
|
+
*/
|
|
121
|
+
exports.OPENCODE_V2_NAVIGATION_KEY_VALUES = [
|
|
122
|
+
...terminal_keys_1.NAVIGATION_KEY_VALUES,
|
|
123
|
+
terminal_keys_1.OPENCODE_LEADER_KEY,
|
|
124
|
+
...terminal_keys_1.OPENCODE_DIRECT_KEY_VALUES,
|
|
125
|
+
...OPENCODE_V2_CHORD_ONLY_VALUES,
|
|
126
|
+
];
|
|
127
|
+
class OpenCodeV2Tool extends base_1.BaseCLITool {
|
|
128
|
+
id = tool_id_1.OPENCODE_V2_CLI_TOOL_ID;
|
|
129
|
+
name = 'OpenCode V2';
|
|
130
|
+
command = tool_id_1.OPENCODE_V2_COMMAND;
|
|
131
|
+
/** Last lazy-resume attempt per session name, for {@link OPENCODE_V2_RESUME_RETRY_MS}. */
|
|
132
|
+
resumeAttemptedAt = new Map();
|
|
133
|
+
/**
|
|
134
|
+
* Declare the keys OpenCode V2's quick keys send (Issue #2966).
|
|
135
|
+
*
|
|
136
|
+
* Without this override the route validates against the base pad and answers
|
|
137
|
+
* 400 for `C-p` / `C-t` / `C-x`, so the palette, the variant cycle and every
|
|
138
|
+
* leader chord on the strip would be unsendable. The leader is `ctrl+x`, the
|
|
139
|
+
* same default as v1 — 2.0.18's own palette prints `ctrl+x m`, `ctrl+x a`,
|
|
140
|
+
* `ctrl+x l`, `ctrl+x n`.
|
|
141
|
+
*
|
|
142
|
+
* @returns This tool's {@link NavigationKeySpec}
|
|
143
|
+
*/
|
|
144
|
+
navigationKeys() {
|
|
145
|
+
return {
|
|
146
|
+
keys: exports.OPENCODE_V2_NAVIGATION_KEY_VALUES,
|
|
147
|
+
leaderKey: terminal_keys_1.OPENCODE_LEADER_KEY,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Installed means an executable that identifies itself as OpenCode V2
|
|
152
|
+
* (`opencode v<semver>`, D1): `opencode2`, or — Issue #2939 — an `opencode`
|
|
153
|
+
* that answers as V2, for an operator who has V2 under that name only.
|
|
154
|
+
*/
|
|
155
|
+
async isInstalled() {
|
|
156
|
+
return (await (0, opencode_executable_1.resolveOpencodeV2Executable)()).executable !== null;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Whether the instance's tmux session exists.
|
|
160
|
+
*
|
|
161
|
+
* A live session this process holds no subscription for — a pane that
|
|
162
|
+
* outlived a CommandMate restart — gets its event stream back here, fire and
|
|
163
|
+
* forget and at most every {@link OPENCODE_V2_RESUME_RETRY_MS}, so status
|
|
164
|
+
* comes from the server again as soon as anything polls the pane.
|
|
165
|
+
*/
|
|
166
|
+
async isRunning(worktreeId, instanceId) {
|
|
167
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
168
|
+
const running = await (0, tmux_1.hasSession)(sessionName);
|
|
169
|
+
if (running)
|
|
170
|
+
this.resumeInBackground(worktreeId, sessionName, instanceId);
|
|
171
|
+
return running;
|
|
172
|
+
}
|
|
173
|
+
resumeInBackground(worktreeId, sessionName, instanceId) {
|
|
174
|
+
const target = (0, runtime_1.opencodeV2Target)(worktreeId, instanceId);
|
|
175
|
+
if ((0, subscription_1.isOpencodeV2Subscribed)(target))
|
|
176
|
+
return;
|
|
177
|
+
const now = Date.now();
|
|
178
|
+
const last = this.resumeAttemptedAt.get(sessionName);
|
|
179
|
+
if (last !== undefined && now - last < exports.OPENCODE_V2_RESUME_RETRY_MS)
|
|
180
|
+
return;
|
|
181
|
+
this.resumeAttemptedAt.set(sessionName, now);
|
|
182
|
+
void (async () => {
|
|
183
|
+
try {
|
|
184
|
+
const worktreePath = await (0, tmux_1.getSessionWorkingDirectory)(sessionName);
|
|
185
|
+
if (worktreePath === null)
|
|
186
|
+
return;
|
|
187
|
+
await (0, runtime_1.resumeOpencodeV2EventStream)(target, worktreePath);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
logger.debug('opencode-v2-lazy-resume-failed', { error: (0, errors_1.getErrorMessage)(error) });
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
193
|
+
}
|
|
194
|
+
async launchSession(worktreeId, worktreePath, instanceId) {
|
|
195
|
+
// Issue #2939: the file that answered as V2 is the file the line runs.
|
|
196
|
+
const executable = (await (0, opencode_executable_1.resolveOpencodeV2Executable)()).executable;
|
|
197
|
+
if (!executable) {
|
|
198
|
+
throw (0, install_hints_1.missingToolError)(this);
|
|
199
|
+
}
|
|
200
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
201
|
+
const target = (0, runtime_1.opencodeV2Target)(worktreeId, instanceId);
|
|
202
|
+
const geometry = { windowWidth: (0, tmux_pane_config_1.resolveOpencodePaneWidth)(), windowHeight: tmux_pane_config_1.OPENCODE_PANE_HEIGHT };
|
|
203
|
+
const exists = await (0, tmux_1.hasSession)(sessionName);
|
|
204
|
+
if (exists) {
|
|
205
|
+
await this.reconcileExistingSession(sessionName, worktreePath, geometry);
|
|
206
|
+
if (await this.isToolLive(sessionName, { confirm: true })) {
|
|
207
|
+
await (0, runtime_1.resumeOpencodeV2EventStream)(target, worktreePath);
|
|
208
|
+
logger.info('opencode-v2-session-exists');
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
logger.warn('opencode-v2-session-relaunch', { sessionName });
|
|
212
|
+
// The pane is back at its shell, so whatever it held is gone with it.
|
|
213
|
+
await (0, runtime_1.releaseOpencodeV2Server)(target);
|
|
214
|
+
}
|
|
215
|
+
(0, agent_session_lifecycle_1.beginAgentSession)(target);
|
|
216
|
+
try {
|
|
217
|
+
if (!exists) {
|
|
218
|
+
await (0, tmux_1.createSession)({ sessionName, workingDirectory: worktreePath });
|
|
219
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
await execFileAsync('tmux', [
|
|
223
|
+
'resize-window', '-t', (0, tmux_1.exactTarget)(sessionName),
|
|
224
|
+
'-x', String(geometry.windowWidth), '-y', String(geometry.windowHeight),
|
|
225
|
+
]);
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Non-fatal, as for v1: the TUI still starts at whatever size it gets.
|
|
229
|
+
}
|
|
230
|
+
// Port and password first: the launch line is built from both.
|
|
231
|
+
const port = await (0, runtime_1.reserveOpencodeV2Server)(target, worktreePath);
|
|
232
|
+
if (port === null) {
|
|
233
|
+
logger.warn('opencode-v2-launch-without-server', { worktreeId, instanceId });
|
|
234
|
+
}
|
|
235
|
+
await (0, tmux_1.sendKeys)(sessionName, (0, agent_session_lifecycle_1.buildAgentLaunchCommandLine)({ target, executablePath: executable.path, worktreePath }), true);
|
|
236
|
+
await this.waitForReady(sessionName);
|
|
237
|
+
await (0, runtime_1.attachOpencodeV2EventStream)(target);
|
|
238
|
+
logger.info('started-opencode-v2-session');
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
throw new Error(`Failed to start OpenCode V2 session: ${(0, errors_1.getErrorMessage)(error)}`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/** Poll until the composer is on screen (or give up quietly). */
|
|
245
|
+
async waitForReady(sessionName) {
|
|
246
|
+
for (let attempt = 0; attempt < exports.OPENCODE_V2_READY_MAX_ATTEMPTS; attempt++) {
|
|
247
|
+
try {
|
|
248
|
+
const output = (0, cli_patterns_1.stripAnsi)(await (0, tmux_1.capturePane)(sessionName, OPENCODE_V2_READY_CAPTURE_LINES));
|
|
249
|
+
if ((0, cli_patterns_1.isOpencodeV2ComposerVisible)(output)) {
|
|
250
|
+
logger.info('opencode-v2-composer-detected', { attempt });
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// The pane may not be readable yet; keep polling.
|
|
256
|
+
}
|
|
257
|
+
await new Promise((resolve) => setTimeout(resolve, exports.OPENCODE_V2_READY_POLL_INTERVAL_MS));
|
|
258
|
+
}
|
|
259
|
+
logger.info('opencode-v2-ready-detection-timeout');
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Wait for the composer before typing into it (D6).
|
|
264
|
+
*
|
|
265
|
+
* Issue #2971: a dialog open over the composer (model / variant picker,
|
|
266
|
+
* Commands, Sessions, agents) leaves the footer on screen, so the composer
|
|
267
|
+
* check alone passes and the text went into the dialog's filter. The send is
|
|
268
|
+
* refused instead, on the first frame that shows one: the dialog is someone's
|
|
269
|
+
* choice in progress, so it is neither dismissed (Escape would throw that
|
|
270
|
+
* choice away) nor waited out (nothing closes it but a person).
|
|
271
|
+
*
|
|
272
|
+
* @throws When a dialog is open, or when the composer does not appear within
|
|
273
|
+
* {@link OPENCODE_V2_COMPOSER_WAIT_MS}
|
|
274
|
+
*/
|
|
275
|
+
async waitForComposer(sessionName) {
|
|
276
|
+
const deadline = Date.now() + cli_tool_timing_config_1.OPENCODE_V2_COMPOSER_WAIT_MS;
|
|
277
|
+
for (;;) {
|
|
278
|
+
let dialog = null;
|
|
279
|
+
try {
|
|
280
|
+
const output = (0, cli_patterns_1.stripAnsi)(await (0, tmux_1.capturePane)(sessionName, OPENCODE_V2_READY_CAPTURE_LINES));
|
|
281
|
+
dialog = (0, cli_patterns_1.findOpencodeV2DialogTitle)(output);
|
|
282
|
+
if (dialog === null && (0, cli_patterns_1.isOpencodeV2ComposerVisible)(output))
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
// Treated as "not yet".
|
|
287
|
+
}
|
|
288
|
+
if (dialog !== null) {
|
|
289
|
+
throw new Error(`OpenCode V2 composer not available: the "${dialog}" dialog is open. ` +
|
|
290
|
+
'Close it (esc) or finish the choice, then send again');
|
|
291
|
+
}
|
|
292
|
+
if (Date.now() >= deadline)
|
|
293
|
+
break;
|
|
294
|
+
await new Promise((resolve) => setTimeout(resolve, exports.OPENCODE_V2_READY_POLL_INTERVAL_MS));
|
|
295
|
+
}
|
|
296
|
+
throw new Error('OpenCode V2 composer not ready: timed out waiting for it before sending');
|
|
297
|
+
}
|
|
298
|
+
async sendMessage(worktreeId, message, instanceId) {
|
|
299
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
300
|
+
if (!(await (0, tmux_1.hasSession)(sessionName))) {
|
|
301
|
+
throw new Error(`OpenCode V2 session ${sessionName} does not exist. Start the session first.`);
|
|
302
|
+
}
|
|
303
|
+
await this.relaunchIfToolExited(worktreeId, instanceId);
|
|
304
|
+
try {
|
|
305
|
+
await this.waitForComposer(sessionName);
|
|
306
|
+
await (0, submit_verified_sender_1.sendMessageWithSubmitVerification)({
|
|
307
|
+
sessionName,
|
|
308
|
+
message: toOpencodeV2ComposerText(message),
|
|
309
|
+
cliToolId: tool_id_1.OPENCODE_V2_CLI_TOOL_ID,
|
|
310
|
+
composer: this.describeComposer(),
|
|
311
|
+
});
|
|
312
|
+
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
313
|
+
logger.info('sent-message-to-opencode-v2-session');
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
throw new Error(`Failed to send message to OpenCode V2: ${(0, errors_1.getErrorMessage)(error)}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Stop the TUI and, through the wrapper's trap, its server.
|
|
321
|
+
*
|
|
322
|
+
* `/exit` and a separate Enter first (the declared graceful sequence), then
|
|
323
|
+
* the postcondition: the session gone AND the port no longer answering. If
|
|
324
|
+
* either fails the session is killed — the SIGHUP reaches the wrapper, whose
|
|
325
|
+
* trap stops the server. Everything the instance held (subscription, port,
|
|
326
|
+
* password file) is released at the end.
|
|
327
|
+
*/
|
|
328
|
+
async killSession(worktreeId, instanceId) {
|
|
329
|
+
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
330
|
+
const target = (0, runtime_1.opencodeV2Target)(worktreeId, instanceId);
|
|
331
|
+
const port = (0, ports_1.getAssignedOpencodeV2Port)(target);
|
|
332
|
+
try {
|
|
333
|
+
if (await (0, tmux_1.hasSession)(sessionName)) {
|
|
334
|
+
await (0, tmux_1.sendKeys)(sessionName, graceful_exit_1.OPENCODE_V2_EXIT_COMMAND_TEXT, false);
|
|
335
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_TEXT_INPUT_WAIT_MS));
|
|
336
|
+
await (0, tmux_1.sendSpecialKeys)(sessionName, ['Enter']);
|
|
337
|
+
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.OPENCODE_V2_EXIT_WAIT_MS));
|
|
338
|
+
const verdict = await (0, graceful_exit_1.verifyGracefulExit)({
|
|
339
|
+
sessionAlive: () => (0, tmux_1.hasSession)(sessionName),
|
|
340
|
+
portAnswering: port === null
|
|
341
|
+
? null
|
|
342
|
+
: async () => (await (0, client_1.probeOpencodeV2Server)(port, '')).kind !== 'unreachable',
|
|
343
|
+
});
|
|
344
|
+
if (!verdict.ok) {
|
|
345
|
+
logger.info('opencode-v2-graceful-exit-postcondition-unmet', {
|
|
346
|
+
sessionName,
|
|
347
|
+
reason: verdict.reason,
|
|
348
|
+
...(port !== null ? { port } : {}),
|
|
349
|
+
});
|
|
350
|
+
await (0, tmux_1.killSession)(sessionName);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
await (0, tmux_1.killSession)(sessionName);
|
|
355
|
+
}
|
|
356
|
+
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
357
|
+
this.resumeAttemptedAt.delete(sessionName);
|
|
358
|
+
logger.info('stopped-opencode-v2-session');
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
logger.error('session:stop-failed', { error: (0, errors_1.getErrorMessage)(error) });
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
364
|
+
finally {
|
|
365
|
+
await (0, runtime_1.releaseOpencodeV2Server)(target);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
exports.OpenCodeV2Tool = OpenCodeV2Tool;
|
|
@@ -73,6 +73,8 @@ const opencode_session_store_1 = require("../../lib/session/opencode-session-sto
|
|
|
73
73
|
const graceful_exit_1 = require("./graceful-exit");
|
|
74
74
|
const cli_tool_timing_config_1 = require("../../config/cli-tool-timing-config");
|
|
75
75
|
const install_hints_1 = require("./install-hints");
|
|
76
|
+
const opencode_executable_1 = require("./opencode-executable");
|
|
77
|
+
const log_diagnosis_1 = require("../../lib/hooks/sources/opencode/log-diagnosis");
|
|
76
78
|
const logger = (0, logger_1.createLogger)('cli-tools/opencode');
|
|
77
79
|
const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
|
|
78
80
|
/**
|
|
@@ -227,6 +229,14 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
227
229
|
leaderKey: terminal_keys_1.OPENCODE_LEADER_KEY,
|
|
228
230
|
};
|
|
229
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Installed means an `opencode` on PATH that reports a 1.x version (Issue
|
|
234
|
+
* #2939). `which opencode` is not enough: npm `@opencode/cli` registers
|
|
235
|
+
* `opencode` for OpenCode V2 too. See `./opencode-executable`.
|
|
236
|
+
*/
|
|
237
|
+
async isInstalled() {
|
|
238
|
+
return (await (0, opencode_executable_1.resolveOpencodeV1Executable)()).executable !== null;
|
|
239
|
+
}
|
|
230
240
|
/**
|
|
231
241
|
* Check if OpenCode session is running for a worktree
|
|
232
242
|
*/
|
|
@@ -242,9 +252,12 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
242
252
|
* @param worktreePath - Worktree path
|
|
243
253
|
*/
|
|
244
254
|
async launchSession(worktreeId, worktreePath, instanceId) {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
255
|
+
// Issue #2939: one resolution decides both whether to start and what to
|
|
256
|
+
// run, so the launch line names the very file that answered as 1.x.
|
|
257
|
+
const resolution = await (0, opencode_executable_1.resolveOpencodeV1Executable)();
|
|
258
|
+
const executable = resolution.executable;
|
|
259
|
+
if (!executable) {
|
|
260
|
+
throw (0, install_hints_1.missingToolError)(this, (0, opencode_executable_1.describeOpencodeV1Unavailable)(resolution));
|
|
248
261
|
}
|
|
249
262
|
const sessionName = this.getSessionName(worktreeId, instanceId);
|
|
250
263
|
const target = (0, runtime_1.opencodeTarget)(worktreeId, instanceId);
|
|
@@ -355,7 +368,7 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
355
368
|
// variable, because CommandMate holds the connection (#1846).
|
|
356
369
|
const plannedCommand = (0, agent_session_lifecycle_1.buildAgentLaunchCommandLine)({
|
|
357
370
|
target,
|
|
358
|
-
executablePath:
|
|
371
|
+
executablePath: executable.path,
|
|
359
372
|
worktreePath,
|
|
360
373
|
});
|
|
361
374
|
// Issue #2038: continue the conversation this instance was in before it
|
|
@@ -379,6 +392,7 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
379
392
|
sessionId: resumeSessionId,
|
|
380
393
|
});
|
|
381
394
|
}
|
|
395
|
+
const launchedAt = Date.now();
|
|
382
396
|
await (0, tmux_1.sendKeys)(sessionName, launchCommand, true);
|
|
383
397
|
// Issue #1908: poll for opencode's own composer instead of sleeping 15 s.
|
|
384
398
|
await this.waitForReady(sessionName);
|
|
@@ -393,7 +407,17 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
393
407
|
// with the server already listening, which the fixed 15 s wait did not
|
|
394
408
|
// guarantee: the 22.8 s run had nothing to probe at 15 s and would have
|
|
395
409
|
// lost structured events for the whole session.
|
|
396
|
-
await (0, runtime_1.attachOpencodeEventStream)(target);
|
|
410
|
+
const attached = await (0, runtime_1.attachOpencodeEventStream)(target);
|
|
411
|
+
// Issue #2939 (D2): a server that never answered may be OpenCode 1.x
|
|
412
|
+
// dying on the database OpenCode V2 migrated. opencode's own log says so;
|
|
413
|
+
// when it does, that is the start error. Otherwise nothing changes.
|
|
414
|
+
if (!attached && (0, ports_1.getAssignedOpencodePort)(target) !== null) {
|
|
415
|
+
const conflict = await (0, log_diagnosis_1.findOpencodeSharedDataConflict)(launchedAt);
|
|
416
|
+
if (conflict !== null) {
|
|
417
|
+
logger.warn('opencode-shared-data-conflict', { worktreeId, finding: conflict });
|
|
418
|
+
throw new Error((0, log_diagnosis_1.buildOpencodeSharedDataConflictMessage)(conflict));
|
|
419
|
+
}
|
|
420
|
+
}
|
|
397
421
|
logger.info('started-opencode-session:sessionname');
|
|
398
422
|
}
|
|
399
423
|
catch (error) {
|
|
@@ -24,7 +24,7 @@ exports.isImageCapableCLITool = isImageCapableCLITool;
|
|
|
24
24
|
* T2.1: Single source of truth for CLI tool IDs
|
|
25
25
|
* CLIToolType is derived from this constant (DRY principle)
|
|
26
26
|
*/
|
|
27
|
-
exports.CLI_TOOL_IDS = ['claude', 'codex', 'gemini', 'vibe-local', 'opencode', 'copilot', 'antigravity', 'command-code'];
|
|
27
|
+
exports.CLI_TOOL_IDS = ['claude', 'codex', 'gemini', 'vibe-local', 'opencode', 'copilot', 'antigravity', 'command-code', 'opencode-v2'];
|
|
28
28
|
/**
|
|
29
29
|
* CLI tools that render inside the terminal's alternate screen (Issue #1268).
|
|
30
30
|
*
|
|
@@ -48,6 +48,9 @@ const ALTERNATE_SCREEN_CLI_TOOLS = new Set([
|
|
|
48
48
|
// INLINE -- measured on 1.40.1, `#{alternate_on}` is 0 and the pane keeps its
|
|
49
49
|
// scrollback -- so its captured line count really is a monotonic cursor, the
|
|
50
50
|
// way codex's and agy's are.
|
|
51
|
+
// Issue #2934: OpenCode V2's TUI is the same full-screen toolkit as v1's
|
|
52
|
+
// (`#{alternate_on}` 1 on 2.0.18, measured 2026-09-28).
|
|
53
|
+
'opencode-v2',
|
|
51
54
|
]);
|
|
52
55
|
/**
|
|
53
56
|
* Whether a CLI tool renders in the terminal's alternate screen, making the
|
|
@@ -195,6 +198,7 @@ exports.CLI_TOOL_DISPLAY_NAMES = {
|
|
|
195
198
|
copilot: 'Copilot',
|
|
196
199
|
antigravity: 'Antigravity',
|
|
197
200
|
'command-code': 'Command Code',
|
|
201
|
+
'opencode-v2': 'OpenCode V2',
|
|
198
202
|
};
|
|
199
203
|
/**
|
|
200
204
|
* Check if a string is a valid CLIToolType
|