commandmate 0.42.1 → 0.43.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 +144 -144
- package/.next/app-path-routes-manifest.json +23 -23
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- 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_client-reference-manifest.js +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_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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +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_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_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_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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +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_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_client-reference-manifest.js +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_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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_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_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 +104 -2
- 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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_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 +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 +1 -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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js +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_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_client-reference-manifest.js +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_client-reference-manifest.js +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_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_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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +23 -23
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1501.js +4 -4
- package/.next/server/chunks/1990.js +1 -1
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/22.js +1 -1
- 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/434.js +1 -1
- package/.next/server/chunks/5064.js +1 -1
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/5742.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/6491.js +103 -0
- 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/7491.js +3 -0
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +2 -2
- package/.next/server/chunks/8583.js +1 -1
- package/.next/server/chunks/8673.js +6 -6
- package/.next/server/chunks/8728.js +2 -2
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8800.js +4 -3
- package/.next/server/chunks/8918.js +5 -5
- 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 +4 -4
- package/.next/server/chunks/964.js +1 -1
- 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/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{1642-fb2e176aaadbd137.js → 1642-767aed8e7c61ef7f.js} +1 -1
- package/.next/static/chunks/{2407-21fbf12d753b8d4d.js → 2407-940df9b11fadafc6.js} +1 -1
- package/.next/static/chunks/{2619-04bc32f026a0d946.js → 2619-a305ad4810f1393a.js} +1 -1
- package/.next/static/chunks/5449-6cb80bab2bd06b79.js +1 -0
- package/.next/static/chunks/7705-1f58d4c03d991fcf.js +1 -0
- package/.next/static/chunks/8165-3525fb42f1b4976e.js +1 -0
- package/.next/static/chunks/app/{layout-8ff4c7c08ef1f621.js → layout-057c850cd0df978e.js} +1 -1
- package/.next/static/chunks/app/review/page-ff9efae3f86eb840.js +1 -0
- package/.next/static/chunks/app/skills/[skillId]/page-74aac15286504ef4.js +1 -0
- package/.next/static/chunks/app/skills/page-182e16168b2fc098.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-eab0bf7564d3f9e2.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/{page-373ea37b16d930c7.js → page-c601f3b3ece6557e.js} +1 -1
- package/.next/trace +13 -13
- package/README.md +3 -3
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +23 -149
- 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/verify.d.ts.map +1 -1
- package/dist/cli/commands/verify.js +9 -0
- 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/program.d.ts.map +1 -1
- package/dist/cli/program.js +4 -0
- package/dist/cli/types/index.d.ts +2 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- 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/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/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 +44 -14
- package/dist/server/locales/ja/worktree.json +44 -14
- 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/schedule-config.js +55 -1
- package/dist/server/src/lib/auto-yes-poller.js +47 -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.js +55 -1
- 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/db/worktree-db.js +1 -1
- package/dist/server/src/lib/detection/cli-patterns.js +78 -2
- 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/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/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 +184 -10
- 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/structured-prompt.js +54 -0
- package/dist/server/src/lib/session/tmux-session-surface.js +1 -1
- package/dist/server/src/lib/skills/compatibility-matrix.js +65 -0
- package/dist/server/src/lib/tmux/tmux.js +48 -2
- package/dist/server/src/lib/verification/env-clean-gate.js +228 -9
- package/dist/server/src/lib/verification/env-snapshot.js +65 -1
- 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/package.json +2 -1
- package/release-notes/0.42.2.json +20 -0
- package/release-notes/0.43.0.json +130 -0
- package/scripts/hooks/cmate-agent-event.sh +14 -0
- package/scripts/opencode-v2/launch.sh +226 -0
- package/.next/server/chunks/4443.js +0 -3
- package/.next/server/chunks/5164.js +0 -1
- package/.next/server/chunks/650.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/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-3c946bd2875391fd.js +0 -1
- /package/.next/static/{3M_S0B7dhEDdVE2XSJz1Y → BVkBYdceLRvMROqQIqeBx}/_buildManifest.js +0 -0
- /package/.next/static/{3M_S0B7dhEDdVE2XSJz1Y → BVkBYdceLRvMROqQIqeBx}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CommandMate startup sweep for OpenCode V2 instances (Issue #2934).
|
|
4
|
+
*
|
|
5
|
+
* The role v1's `../opencode/reattach` plays, plus the password files:
|
|
6
|
+
*
|
|
7
|
+
* - an instance whose tmux session is still alive gets its subscription back,
|
|
8
|
+
* from the persisted port and the password file on disk (D5, last row);
|
|
9
|
+
* - an instance whose session is gone has its password file deleted and its
|
|
10
|
+
* port assignment dropped (D3). Nothing can use them any more — the server
|
|
11
|
+
* they belonged to died with the pane, because `launch.sh` stops it on every
|
|
12
|
+
* way out.
|
|
13
|
+
*
|
|
14
|
+
* Candidates are the union of the password files and the persisted ports, so
|
|
15
|
+
* a password left behind by a crash is swept even when its port entry is not.
|
|
16
|
+
*
|
|
17
|
+
* Fail-open and never rejects.
|
|
18
|
+
*
|
|
19
|
+
* @module lib/hooks/sources/opencode-v2/reattach
|
|
20
|
+
*/
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
33
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
34
|
+
}) : function(o, v) {
|
|
35
|
+
o["default"] = v;
|
|
36
|
+
});
|
|
37
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
38
|
+
var ownKeys = function(o) {
|
|
39
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
40
|
+
var ar = [];
|
|
41
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
42
|
+
return ar;
|
|
43
|
+
};
|
|
44
|
+
return ownKeys(o);
|
|
45
|
+
};
|
|
46
|
+
return function (mod) {
|
|
47
|
+
if (mod && mod.__esModule) return mod;
|
|
48
|
+
var result = {};
|
|
49
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
50
|
+
__setModuleDefault(result, mod);
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
})();
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.opencodeV2TargetOfKey = opencodeV2TargetOfKey;
|
|
56
|
+
exports.reattachOpencodeV2EventStreams = reattachOpencodeV2EventStreams;
|
|
57
|
+
const auto_yes_state_1 = require("../../../../lib/auto-yes-state");
|
|
58
|
+
const logger_1 = require("../../../../lib/logger");
|
|
59
|
+
const ports_1 = require("./ports");
|
|
60
|
+
const runtime_1 = require("./runtime");
|
|
61
|
+
const secrets_1 = require("./secrets");
|
|
62
|
+
const tool_id_1 = require("./tool-id");
|
|
63
|
+
const logger = (0, logger_1.createLogger)('lib/hooks/sources/opencode-v2/reattach');
|
|
64
|
+
/** The instance a composite key names, when it is an OpenCode V2 key. */
|
|
65
|
+
function opencodeV2TargetOfKey(key) {
|
|
66
|
+
if ((0, auto_yes_state_1.extractCliToolId)(key) !== tool_id_1.OPENCODE_V2_CLI_TOOL_ID)
|
|
67
|
+
return null;
|
|
68
|
+
const worktreeId = (0, auto_yes_state_1.extractWorktreeId)(key);
|
|
69
|
+
const instanceId = (0, auto_yes_state_1.extractInstanceId)(key);
|
|
70
|
+
if (worktreeId.length === 0 || instanceId === null || instanceId.length === 0)
|
|
71
|
+
return null;
|
|
72
|
+
return { worktreeId, cliToolId: tool_id_1.OPENCODE_V2_CLI_TOOL_ID, instanceId };
|
|
73
|
+
}
|
|
74
|
+
async function defaultDeps() {
|
|
75
|
+
const { CLIToolManager } = await Promise.resolve().then(() => __importStar(require('../../../../lib/cli-tools/manager')));
|
|
76
|
+
const tool = CLIToolManager.getInstance().getTool(tool_id_1.OPENCODE_V2_CLI_TOOL_ID);
|
|
77
|
+
let resolveWorktreePath = () => null;
|
|
78
|
+
try {
|
|
79
|
+
const [{ getDbInstance }, { getWorktreeById }] = await Promise.all([
|
|
80
|
+
Promise.resolve().then(() => __importStar(require('../../../../lib/db/db-instance'))),
|
|
81
|
+
Promise.resolve().then(() => __importStar(require('../../../../lib/db'))),
|
|
82
|
+
]);
|
|
83
|
+
const db = getDbInstance();
|
|
84
|
+
resolveWorktreePath = (worktreeId) => getWorktreeById(db, worktreeId)?.path ?? null;
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
logger.warn('opencode-v2-reattach-worktree-lookup-unavailable', {
|
|
88
|
+
error: error instanceof Error ? error.message : String(error),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
isPaneRunning: (target) => tool.isRunning(target.worktreeId, target.instanceId),
|
|
93
|
+
resolveWorktreePath,
|
|
94
|
+
resume: runtime_1.resumeOpencodeV2EventStream,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Re-subscribe live instances and sweep dead ones.
|
|
99
|
+
*
|
|
100
|
+
* @param deps - Collaborators; production passes none
|
|
101
|
+
*/
|
|
102
|
+
async function reattachOpencodeV2EventStreams(deps) {
|
|
103
|
+
const report = { known: 0, candidates: 0, reattached: 0, swept: 0 };
|
|
104
|
+
try {
|
|
105
|
+
const keys = new Set([
|
|
106
|
+
...(0, secrets_1.listOpencodeV2PasswordKeys)(),
|
|
107
|
+
...Object.keys((0, ports_1.readPersistedOpencodeV2Ports)()),
|
|
108
|
+
]);
|
|
109
|
+
const entries = [];
|
|
110
|
+
for (const key of keys) {
|
|
111
|
+
const target = opencodeV2TargetOfKey(key);
|
|
112
|
+
if (target !== null)
|
|
113
|
+
entries.push({ key, target });
|
|
114
|
+
}
|
|
115
|
+
report.known = entries.length;
|
|
116
|
+
if (entries.length === 0)
|
|
117
|
+
return report;
|
|
118
|
+
const resolved = deps ?? (await defaultDeps());
|
|
119
|
+
await Promise.all(entries.map(async ({ key, target }) => {
|
|
120
|
+
let running = false;
|
|
121
|
+
try {
|
|
122
|
+
running = await resolved.isPaneRunning(target);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
running = false;
|
|
126
|
+
}
|
|
127
|
+
if (!running) {
|
|
128
|
+
(0, secrets_1.removeOpencodeV2PasswordByKey)(key);
|
|
129
|
+
(0, ports_1.forgetOpencodeV2PortByKey)(key);
|
|
130
|
+
report.swept += 1;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
report.candidates += 1;
|
|
134
|
+
const worktreePath = resolved.resolveWorktreePath(target.worktreeId);
|
|
135
|
+
if (worktreePath === null)
|
|
136
|
+
return;
|
|
137
|
+
if (await resolved.resume(target, worktreePath))
|
|
138
|
+
report.reattached += 1;
|
|
139
|
+
}));
|
|
140
|
+
logger.info('opencode-v2-reattach-complete', { ...report });
|
|
141
|
+
return report;
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
logger.warn('opencode-v2-reattach-failed', {
|
|
145
|
+
error: error instanceof Error ? error.message : String(error),
|
|
146
|
+
});
|
|
147
|
+
return report;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The calls `cli-tools/opencode-v2.ts` makes around a pane's life
|
|
4
|
+
* (Issue #2934).
|
|
5
|
+
*
|
|
6
|
+
* - {@link reserveOpencodeV2Server} before the launch line is built: a port
|
|
7
|
+
* and a fresh password file, which `prepareOpencodeV2Launch` turns into the
|
|
8
|
+
* wrapper's arguments;
|
|
9
|
+
* - {@link attachOpencodeV2EventStream} once the TUI is up;
|
|
10
|
+
* - {@link resumeOpencodeV2EventStream} for a pane that outlived a CommandMate
|
|
11
|
+
* restart;
|
|
12
|
+
* - {@link releaseOpencodeV2Server} when the pane is killed: subscription,
|
|
13
|
+
* port assignment and password file, all three.
|
|
14
|
+
*
|
|
15
|
+
* Every one of them is fail-open. A pane that runs without structured events is
|
|
16
|
+
* still driven by the screen scraper.
|
|
17
|
+
*
|
|
18
|
+
* @module lib/hooks/sources/opencode-v2/runtime
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.OPENCODE_V2_ATTACH_PROBE_DELAYS_MS = void 0;
|
|
22
|
+
exports.opencodeV2Target = opencodeV2Target;
|
|
23
|
+
exports.reserveOpencodeV2Server = reserveOpencodeV2Server;
|
|
24
|
+
exports.isOpencodeV2ServerOurs = isOpencodeV2ServerOurs;
|
|
25
|
+
exports.attachOpencodeV2EventStream = attachOpencodeV2EventStream;
|
|
26
|
+
exports.resumeOpencodeV2EventStream = resumeOpencodeV2EventStream;
|
|
27
|
+
exports.releaseOpencodeV2Server = releaseOpencodeV2Server;
|
|
28
|
+
const logger_1 = require("../../../../lib/logger");
|
|
29
|
+
const client_1 = require("./client");
|
|
30
|
+
const ingest_1 = require("./ingest");
|
|
31
|
+
const ports_1 = require("./ports");
|
|
32
|
+
const secrets_1 = require("./secrets");
|
|
33
|
+
const source_1 = require("./source");
|
|
34
|
+
const subscription_1 = require("./subscription");
|
|
35
|
+
const tool_id_1 = require("./tool-id");
|
|
36
|
+
const logger = (0, logger_1.createLogger)('lib/hooks/sources/opencode-v2/runtime');
|
|
37
|
+
/** Waits before each health probe of a freshly started server. */
|
|
38
|
+
exports.OPENCODE_V2_ATTACH_PROBE_DELAYS_MS = [0, 500, 1_000, 2_000];
|
|
39
|
+
/** The instance reference every OpenCode V2 call keys off. */
|
|
40
|
+
function opencodeV2Target(worktreeId, instanceId) {
|
|
41
|
+
return { worktreeId, cliToolId: tool_id_1.OPENCODE_V2_CLI_TOOL_ID, instanceId };
|
|
42
|
+
}
|
|
43
|
+
function errorMessage(error) {
|
|
44
|
+
return error instanceof Error ? error.message : String(error);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Reserve a port and write a fresh password file for one launch.
|
|
48
|
+
*
|
|
49
|
+
* @returns The port, or null when either could not be had — the launch line
|
|
50
|
+
* then degrades to `--standalone` (see `prepareOpencodeV2Launch`)
|
|
51
|
+
*/
|
|
52
|
+
async function reserveOpencodeV2Server(target, worktreePath) {
|
|
53
|
+
try {
|
|
54
|
+
const port = await (0, ports_1.allocateOpencodeV2Port)(target, worktreePath);
|
|
55
|
+
if (port === null)
|
|
56
|
+
return null;
|
|
57
|
+
(0, secrets_1.writeOpencodeV2Password)(target);
|
|
58
|
+
return port;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger.warn('opencode-v2-server-reserve-failed', {
|
|
62
|
+
worktreeId: target.worktreeId,
|
|
63
|
+
instanceId: target.instanceId ?? target.cliToolId,
|
|
64
|
+
error: errorMessage(error),
|
|
65
|
+
});
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Whether the server on `port` accepts the instance's current password. */
|
|
70
|
+
async function isOpencodeV2ServerOurs(target, port) {
|
|
71
|
+
const password = (0, secrets_1.readOpencodeV2Password)(target);
|
|
72
|
+
if (password === null)
|
|
73
|
+
return false;
|
|
74
|
+
return (await (0, client_1.probeOpencodeV2Server)(port, password)).kind === 'healthy';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Subscribe to the instance's server.
|
|
78
|
+
*
|
|
79
|
+
* @returns Whether a subscription is open afterwards
|
|
80
|
+
*/
|
|
81
|
+
async function attachOpencodeV2EventStream(target) {
|
|
82
|
+
try {
|
|
83
|
+
const port = (0, ports_1.getAssignedOpencodeV2Port)(target);
|
|
84
|
+
if (port === null)
|
|
85
|
+
return false;
|
|
86
|
+
if ((0, subscription_1.isOpencodeV2Subscribed)(target))
|
|
87
|
+
return true;
|
|
88
|
+
let healthy = false;
|
|
89
|
+
for (const waitMs of exports.OPENCODE_V2_ATTACH_PROBE_DELAYS_MS) {
|
|
90
|
+
if (waitMs > 0)
|
|
91
|
+
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
92
|
+
if (await isOpencodeV2ServerOurs(target, port)) {
|
|
93
|
+
healthy = true;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (!healthy) {
|
|
98
|
+
logger.info('opencode-v2-server-not-reachable', {
|
|
99
|
+
worktreeId: target.worktreeId,
|
|
100
|
+
instanceId: target.instanceId ?? target.cliToolId,
|
|
101
|
+
port,
|
|
102
|
+
});
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
await source_1.opencodeV2AgentEventSource.subscribe(target, (event) => {
|
|
106
|
+
void (0, ingest_1.ingestOpencodeV2Event)(target, event);
|
|
107
|
+
});
|
|
108
|
+
logger.info('opencode-v2-event-stream-attached', {
|
|
109
|
+
worktreeId: target.worktreeId,
|
|
110
|
+
instanceId: target.instanceId ?? target.cliToolId,
|
|
111
|
+
port,
|
|
112
|
+
});
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
logger.warn('opencode-v2-event-stream-attach-failed', {
|
|
117
|
+
worktreeId: target.worktreeId,
|
|
118
|
+
instanceId: target.instanceId ?? target.cliToolId,
|
|
119
|
+
error: errorMessage(error),
|
|
120
|
+
});
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Re-subscribe to a server that outlived a CommandMate restart, from the
|
|
126
|
+
* persisted port and the password file on disk.
|
|
127
|
+
*
|
|
128
|
+
* @returns Whether a subscription is open afterwards
|
|
129
|
+
*/
|
|
130
|
+
async function resumeOpencodeV2EventStream(target, worktreePath) {
|
|
131
|
+
try {
|
|
132
|
+
if ((0, subscription_1.isOpencodeV2Subscribed)(target))
|
|
133
|
+
return true;
|
|
134
|
+
const port = await (0, ports_1.recoverOpencodeV2Port)(target, worktreePath, (candidate) => isOpencodeV2ServerOurs(target, candidate));
|
|
135
|
+
if (port === null)
|
|
136
|
+
return false;
|
|
137
|
+
return await attachOpencodeV2EventStream(target);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
logger.warn('opencode-v2-event-stream-resume-failed', {
|
|
141
|
+
worktreeId: target.worktreeId,
|
|
142
|
+
instanceId: target.instanceId ?? target.cliToolId,
|
|
143
|
+
error: errorMessage(error),
|
|
144
|
+
});
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Let go of everything the instance held: the subscription, the port
|
|
150
|
+
* assignment and the password file.
|
|
151
|
+
*/
|
|
152
|
+
async function releaseOpencodeV2Server(target) {
|
|
153
|
+
try {
|
|
154
|
+
await (0, subscription_1.closeOpencodeV2Subscription)(target);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
logger.warn('opencode-v2-subscription-close-failed', {
|
|
158
|
+
worktreeId: target.worktreeId,
|
|
159
|
+
error: errorMessage(error),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
(0, ports_1.forgetOpencodeV2Port)(target);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
logger.warn('opencode-v2-port-forget-failed', {
|
|
167
|
+
worktreeId: target.worktreeId,
|
|
168
|
+
error: errorMessage(error),
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
(0, secrets_1.removeOpencodeV2Password)(target);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
logger.warn('opencode-v2-password-remove-failed', {
|
|
176
|
+
worktreeId: target.worktreeId,
|
|
177
|
+
error: errorMessage(error),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The per-instance server password of OpenCode V2 (Issue #2934, decision D3).
|
|
4
|
+
*
|
|
5
|
+
* `opencode2 serve` authenticates every request by default (Basic, user
|
|
6
|
+
* `opencode`). Started without `OPENCODE_SERVER_PASSWORD` it invents a password
|
|
7
|
+
* and PRINTS it on stdout, which in a tmux pane means onto the screen
|
|
8
|
+
* CommandMate renders; started with the variable, it uses that value and prints
|
|
9
|
+
* nothing (measured on 2.0.18, #2370 Phase 0 (a)). So CommandMate generates a
|
|
10
|
+
* fresh value per launch and hands it over through a file:
|
|
11
|
+
*
|
|
12
|
+
* - `~/.commandmate/opencode-v2/<composite key>.pw`, the file 0600 and the
|
|
13
|
+
* directory 0700, so only the same OS user can read it;
|
|
14
|
+
* - `scripts/opencode-v2/launch.sh` reads it and exports it to the serve and
|
|
15
|
+
* TUI processes as `OPENCODE_SERVER_PASSWORD` and nowhere else;
|
|
16
|
+
* - the SSE subscription (`./client`) reads it for its `Authorization` header.
|
|
17
|
+
*
|
|
18
|
+
* What is deliberately NOT a carrier: `AgentLaunchPlan.env` and `command` (the
|
|
19
|
+
* line typed into the pane, readable by `ps` and echoed on the terminal — pinned
|
|
20
|
+
* by `tests/unit/lib/agent-launch-plan-secrets-1933.test.ts`), the tmux screen,
|
|
21
|
+
* and every log line this module and its callers write (they name the PATH at
|
|
22
|
+
* most, never the value).
|
|
23
|
+
*
|
|
24
|
+
* Accepted, and written down so nobody has to rediscover it: the serve and TUI
|
|
25
|
+
* processes hold the password in their environment, and so does every shell
|
|
26
|
+
* tool the agent runs, because those inherit the TUI's environment. The server
|
|
27
|
+
* listens on 127.0.0.1 only, so what the password guards never leaves the
|
|
28
|
+
* machine, and anyone who can read another process's environment is already the
|
|
29
|
+
* same OS user.
|
|
30
|
+
*
|
|
31
|
+
* The file is deleted by `killSession` and, at CommandMate startup, for every
|
|
32
|
+
* instance whose tmux session is gone (`./reattach`).
|
|
33
|
+
*
|
|
34
|
+
* @module lib/hooks/sources/opencode-v2/secrets
|
|
35
|
+
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.OPENCODE_V2_PASSWORD_SUFFIX = exports.OPENCODE_V2_PASSWORD_BYTES = exports.OPENCODE_V2_DIR_ENV = void 0;
|
|
38
|
+
exports.getOpencodeV2StateDir = getOpencodeV2StateDir;
|
|
39
|
+
exports.ensureOpencodeV2StateDir = ensureOpencodeV2StateDir;
|
|
40
|
+
exports.opencodeV2KeyOf = opencodeV2KeyOf;
|
|
41
|
+
exports.opencodeV2FileStem = opencodeV2FileStem;
|
|
42
|
+
exports.opencodeV2KeyOfFileStem = opencodeV2KeyOfFileStem;
|
|
43
|
+
exports.getOpencodeV2PasswordFilePath = getOpencodeV2PasswordFilePath;
|
|
44
|
+
exports.generateOpencodeV2Password = generateOpencodeV2Password;
|
|
45
|
+
exports.writeOpencodeV2Password = writeOpencodeV2Password;
|
|
46
|
+
exports.readOpencodeV2Password = readOpencodeV2Password;
|
|
47
|
+
exports.readOpencodeV2PasswordByKey = readOpencodeV2PasswordByKey;
|
|
48
|
+
exports.removeOpencodeV2Password = removeOpencodeV2Password;
|
|
49
|
+
exports.removeOpencodeV2PasswordByKey = removeOpencodeV2PasswordByKey;
|
|
50
|
+
exports.listOpencodeV2PasswordKeys = listOpencodeV2PasswordKeys;
|
|
51
|
+
const crypto_1 = require("crypto");
|
|
52
|
+
const fs_1 = require("fs");
|
|
53
|
+
const os_1 = require("os");
|
|
54
|
+
const path_1 = require("path");
|
|
55
|
+
const safe_directory_1 = require("../../../../config/safe-directory");
|
|
56
|
+
const auto_yes_state_1 = require("../../../../lib/auto-yes-state");
|
|
57
|
+
/** Environment variable that relocates the whole OpenCode V2 state directory. */
|
|
58
|
+
exports.OPENCODE_V2_DIR_ENV = 'CM_OPENCODE_V2_DIR';
|
|
59
|
+
/** Bytes of entropy per password. D3 asks for at least 32. */
|
|
60
|
+
exports.OPENCODE_V2_PASSWORD_BYTES = 32;
|
|
61
|
+
/** Suffix of a password file. */
|
|
62
|
+
exports.OPENCODE_V2_PASSWORD_SUFFIX = '.pw';
|
|
63
|
+
/**
|
|
64
|
+
* Where OpenCode V2's per-instance state (passwords, port assignments) lives.
|
|
65
|
+
*
|
|
66
|
+
* `~/.commandmate/opencode-v2`, or `$CM_OPENCODE_V2_DIR`. Resolved on every call
|
|
67
|
+
* so a test that points `HOME` or the variable somewhere else is honoured.
|
|
68
|
+
*/
|
|
69
|
+
function getOpencodeV2StateDir() {
|
|
70
|
+
const fallback = (0, path_1.join)((0, os_1.homedir)(), '.commandmate', 'opencode-v2');
|
|
71
|
+
return (0, safe_directory_1.resolveSafeDirectory)(process.env[exports.OPENCODE_V2_DIR_ENV], fallback, exports.OPENCODE_V2_DIR_ENV);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Create the state directory with owner-only access.
|
|
75
|
+
*
|
|
76
|
+
* `mkdirSync`'s `mode` is filtered by the umask and ignored for a directory that
|
|
77
|
+
* already exists, so the permission is set explicitly afterwards.
|
|
78
|
+
*/
|
|
79
|
+
function ensureOpencodeV2StateDir() {
|
|
80
|
+
const dir = getOpencodeV2StateDir();
|
|
81
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
|
|
82
|
+
(0, fs_1.chmodSync)(dir, 0o700);
|
|
83
|
+
return dir;
|
|
84
|
+
}
|
|
85
|
+
/** The composite key of an instance, as the rest of CommandMate spells it. */
|
|
86
|
+
function opencodeV2KeyOf(target) {
|
|
87
|
+
return (0, auto_yes_state_1.buildCompositeKey)(target.worktreeId, target.cliToolId, target.instanceId);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The file name a composite key is stored under.
|
|
91
|
+
*
|
|
92
|
+
* The key's `:` separators are kept (they are legal in a POSIX file name and the
|
|
93
|
+
* file then reads as the key it belongs to); anything that could leave the
|
|
94
|
+
* directory — a `/`, a `..` — is percent-encoded.
|
|
95
|
+
*/
|
|
96
|
+
function opencodeV2FileStem(key) {
|
|
97
|
+
return encodeURIComponent(key).replace(/%3A/gi, ':').replace(/\./g, '%2E');
|
|
98
|
+
}
|
|
99
|
+
/** The inverse of {@link opencodeV2FileStem}, or null for a name it never wrote. */
|
|
100
|
+
function opencodeV2KeyOfFileStem(stem) {
|
|
101
|
+
try {
|
|
102
|
+
return decodeURIComponent(stem);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Absolute path of an instance's password file. */
|
|
109
|
+
function getOpencodeV2PasswordFilePath(target) {
|
|
110
|
+
return (0, path_1.join)(getOpencodeV2StateDir(), `${opencodeV2FileStem(opencodeV2KeyOf(target))}${exports.OPENCODE_V2_PASSWORD_SUFFIX}`);
|
|
111
|
+
}
|
|
112
|
+
/** A new password: {@link OPENCODE_V2_PASSWORD_BYTES} random bytes, URL-safe base64. */
|
|
113
|
+
function generateOpencodeV2Password() {
|
|
114
|
+
return (0, crypto_1.randomBytes)(exports.OPENCODE_V2_PASSWORD_BYTES).toString('base64url');
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Generate a fresh password for one launch and write it to the instance's file.
|
|
118
|
+
*
|
|
119
|
+
* Always a new value: a relaunch must not reuse the previous server's password,
|
|
120
|
+
* and an old file left behind by a crash is overwritten rather than trusted.
|
|
121
|
+
*
|
|
122
|
+
* @returns The file's path. The value itself is not returned on purpose — the
|
|
123
|
+
* launch path has no business holding it.
|
|
124
|
+
*/
|
|
125
|
+
function writeOpencodeV2Password(target) {
|
|
126
|
+
ensureOpencodeV2StateDir();
|
|
127
|
+
const path = getOpencodeV2PasswordFilePath(target);
|
|
128
|
+
// Removed first so `mode` applies: `writeFileSync` only honours it when it
|
|
129
|
+
// creates the file.
|
|
130
|
+
(0, fs_1.rmSync)(path, { force: true });
|
|
131
|
+
(0, fs_1.writeFileSync)(path, `${generateOpencodeV2Password()}\n`, { mode: 0o600, flag: 'wx' });
|
|
132
|
+
(0, fs_1.chmodSync)(path, 0o600);
|
|
133
|
+
return path;
|
|
134
|
+
}
|
|
135
|
+
/** The instance's password, or null when it has no (readable, non-empty) file. */
|
|
136
|
+
function readOpencodeV2Password(target) {
|
|
137
|
+
return readPasswordFile(getOpencodeV2PasswordFilePath(target));
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* {@link readOpencodeV2Password} by composite key — the form the persisted port
|
|
141
|
+
* assignments are keyed by (Issue #2944: the slash palette knows a worktree,
|
|
142
|
+
* not an instance, so it walks `ports.json` and needs each entry's password).
|
|
143
|
+
*/
|
|
144
|
+
function readOpencodeV2PasswordByKey(key) {
|
|
145
|
+
return readPasswordFile((0, path_1.join)(getOpencodeV2StateDir(), `${opencodeV2FileStem(key)}${exports.OPENCODE_V2_PASSWORD_SUFFIX}`));
|
|
146
|
+
}
|
|
147
|
+
function readPasswordFile(path) {
|
|
148
|
+
try {
|
|
149
|
+
const value = (0, fs_1.readFileSync)(path, 'utf8').split('\n')[0];
|
|
150
|
+
return value !== undefined && value.length > 0 ? value : null;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/** Delete the instance's password file. A missing file is not an error. */
|
|
157
|
+
function removeOpencodeV2Password(target) {
|
|
158
|
+
(0, fs_1.rmSync)(getOpencodeV2PasswordFilePath(target), { force: true });
|
|
159
|
+
}
|
|
160
|
+
/** Delete a password file by its composite key (the startup sweep's form). */
|
|
161
|
+
function removeOpencodeV2PasswordByKey(key) {
|
|
162
|
+
(0, fs_1.rmSync)((0, path_1.join)(getOpencodeV2StateDir(), `${opencodeV2FileStem(key)}${exports.OPENCODE_V2_PASSWORD_SUFFIX}`), { force: true });
|
|
163
|
+
}
|
|
164
|
+
/** The composite keys that currently have a password file. */
|
|
165
|
+
function listOpencodeV2PasswordKeys() {
|
|
166
|
+
let names;
|
|
167
|
+
try {
|
|
168
|
+
names = (0, fs_1.readdirSync)(getOpencodeV2StateDir());
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return [];
|
|
172
|
+
}
|
|
173
|
+
const keys = [];
|
|
174
|
+
for (const name of names) {
|
|
175
|
+
if (!name.endsWith(exports.OPENCODE_V2_PASSWORD_SUFFIX))
|
|
176
|
+
continue;
|
|
177
|
+
const key = opencodeV2KeyOfFileStem(name.slice(0, -exports.OPENCODE_V2_PASSWORD_SUFFIX.length));
|
|
178
|
+
if (key !== null && key.length > 0)
|
|
179
|
+
keys.push(key);
|
|
180
|
+
}
|
|
181
|
+
return keys;
|
|
182
|
+
}
|