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
|
@@ -10,6 +10,7 @@ exports.reconcileSessionGeometry = reconcileSessionGeometry;
|
|
|
10
10
|
exports.isTmuxAvailable = isTmuxAvailable;
|
|
11
11
|
exports.hasSession = hasSession;
|
|
12
12
|
exports.getSessionWorkingDirectory = getSessionWorkingDirectory;
|
|
13
|
+
exports.getPaneCurrentCommand = getPaneCurrentCommand;
|
|
13
14
|
exports.listSessions = listSessions;
|
|
14
15
|
exports.createSession = createSession;
|
|
15
16
|
exports.sendKeys = sendKeys;
|
|
@@ -216,6 +217,27 @@ async function getSessionWorkingDirectory(sessionName) {
|
|
|
216
217
|
return null;
|
|
217
218
|
}
|
|
218
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* The foreground command of a session's pane (`#{pane_current_command}`), or
|
|
222
|
+
* null when tmux cannot say (Issue #3089).
|
|
223
|
+
*
|
|
224
|
+
* Read by Claude's start wait to tell "the agent quit back to the shell" from
|
|
225
|
+
* "the agent is still drawing": once the agent has exited, the pane's
|
|
226
|
+
* foreground process is the login shell again (`bash`, `zsh`, `-zsh`, ...).
|
|
227
|
+
*
|
|
228
|
+
* @param sessionName - Target session name
|
|
229
|
+
* @returns The command name, or null when the session or tmux is unavailable
|
|
230
|
+
*/
|
|
231
|
+
async function getPaneCurrentCommand(sessionName) {
|
|
232
|
+
try {
|
|
233
|
+
const { stdout } = await execFileAsync('tmux', ['display-message', '-p', '-t', exactTarget(sessionName), '#{pane_current_command}'], { timeout: DEFAULT_TIMEOUT });
|
|
234
|
+
const command = stdout.trim();
|
|
235
|
+
return command === '' ? null : command;
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
219
241
|
/**
|
|
220
242
|
* List all tmux sessions
|
|
221
243
|
*
|
|
@@ -254,6 +276,33 @@ async function listSessions() {
|
|
|
254
276
|
return [];
|
|
255
277
|
}
|
|
256
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Issue #2958: what window 0 of a new session runs until `createSession`
|
|
281
|
+
* replaces it with the login shell. Two words so tmux execs it directly (a
|
|
282
|
+
* single word would be run through `default-shell -c`); it never exits on its
|
|
283
|
+
* own and dies with the SIGHUP the replacement sends.
|
|
284
|
+
*/
|
|
285
|
+
const PLACEHOLDER_PANE_COMMAND = ['sleep', '2147483647'];
|
|
286
|
+
/**
|
|
287
|
+
* Fallback for a failed window rebuild: swap the placeholder in window 0 for
|
|
288
|
+
* the login shell tmux would have started (`default-shell`, as a login shell).
|
|
289
|
+
*
|
|
290
|
+
* A bare `respawn-pane` would re-run the pane's creation command — the
|
|
291
|
+
* placeholder — so the shell is named explicitly.
|
|
292
|
+
*/
|
|
293
|
+
async function respawnLoginShell(sessionName, workingDirectory) {
|
|
294
|
+
let shell = '';
|
|
295
|
+
try {
|
|
296
|
+
const { stdout } = await execFileAsync('tmux', ['show-options', '-gv', 'default-shell'], { timeout: DEFAULT_TIMEOUT });
|
|
297
|
+
shell = stdout.trim();
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// Fall through to the environment's shell.
|
|
301
|
+
}
|
|
302
|
+
if (!shell)
|
|
303
|
+
shell = process.env.SHELL || '/bin/sh';
|
|
304
|
+
await execFileAsync('tmux', ['respawn-pane', '-k', '-t', `${exactTarget(sessionName)}0`, '-c', workingDirectory, shell, '-l'], { timeout: DEFAULT_TIMEOUT });
|
|
305
|
+
}
|
|
257
306
|
/**
|
|
258
307
|
* Create a new tmux session
|
|
259
308
|
*
|
|
@@ -300,7 +349,23 @@ async function createSession(sessionNameOrOptions, cwd) {
|
|
|
300
349
|
try {
|
|
301
350
|
// Create session with explicit window size to avoid 80x24 default
|
|
302
351
|
// This is critical for TUI tools (Copilot, OpenCode) that use alternate screen
|
|
303
|
-
|
|
352
|
+
//
|
|
353
|
+
// Issue #2958: window 0 runs a PLACEHOLDER, not the login shell, because it
|
|
354
|
+
// is thrown away by the `new-window -k` below a few milliseconds later. A
|
|
355
|
+
// shell killed that early is still inside its rc files, and pyenv's
|
|
356
|
+
// `pyenv init -` (`command pyenv rehash`) can die holding its lock file
|
|
357
|
+
// (`$PYENV_ROOT/shims/.pyenv-shim`). The NEXT shell then spins in
|
|
358
|
+
// `pyenv rehash` for its 60s lock timeout before running the launch command,
|
|
359
|
+
// so the agent missed the 60s initialization wait (exit 99). Measured on tmux
|
|
360
|
+
// 3.5a / pyenv 2.6.0: 7 of 40 shell-first creations left the lock behind and
|
|
361
|
+
// the replacement pane ran its first command after 61s; 0 of 40 with the
|
|
362
|
+
// placeholder. Two argv words make tmux exec it directly, so no shell (and
|
|
363
|
+
// no rc file) is started for window 0 at all.
|
|
364
|
+
await execFileAsync('tmux', [
|
|
365
|
+
'new-session', '-d', '-s', sessionName, '-c', workingDirectory,
|
|
366
|
+
'-x', String(windowWidth), '-y', String(windowHeight),
|
|
367
|
+
...PLACEHOLDER_PANE_COMMAND,
|
|
368
|
+
], { timeout: DEFAULT_TIMEOUT });
|
|
304
369
|
// Issue #1624: `history-limit` must be set BEFORE the pane that uses it exists.
|
|
305
370
|
//
|
|
306
371
|
// It is a session option, but a pane sizes its scrollback buffer ONCE, from
|
|
@@ -324,7 +389,9 @@ async function createSession(sessionNameOrOptions, cwd) {
|
|
|
324
389
|
// cwd instead). Omitting it silently launches every agent in the wrong repo.
|
|
325
390
|
//
|
|
326
391
|
// Best-effort, matching the geometry step below: if this fails the session is
|
|
327
|
-
// still usable, just with tmux's default 2000-line scrollback.
|
|
392
|
+
// still usable, just with tmux's default 2000-line scrollback. Window 0 is
|
|
393
|
+
// only a placeholder (Issue #2958), so the fallback must still put the login
|
|
394
|
+
// shell into it — see respawnLoginShell().
|
|
328
395
|
try {
|
|
329
396
|
await execFileAsync('tmux', ['new-window', '-k', '-t', `${exactTarget(sessionName)}0`, '-c', workingDirectory], { timeout: DEFAULT_TIMEOUT });
|
|
330
397
|
}
|
|
@@ -334,6 +401,7 @@ async function createSession(sessionNameOrOptions, cwd) {
|
|
|
334
401
|
historyLimit,
|
|
335
402
|
error: error instanceof Error ? error.message : String(error),
|
|
336
403
|
});
|
|
404
|
+
await respawnLoginShell(sessionName, workingDirectory);
|
|
337
405
|
}
|
|
338
406
|
// Issue #1163: Pin the pane to a fixed height so alternate-screen TUIs
|
|
339
407
|
// (Claude/Codex/etc.) keep enough visible rows for capture-pane.
|
|
@@ -515,6 +583,9 @@ const ALLOWED_SPECIAL_KEYS = new Set([
|
|
|
515
583
|
// (`COMMAND_CODE_NAVIGATION_KEY_VALUES`), so the route answers 400 for every
|
|
516
584
|
// other tool — the same arrangement as `s` above.
|
|
517
585
|
'C-a',
|
|
586
|
+
// Issue #3138: Command Code's plan review is submitted with ctrl+r; sent via
|
|
587
|
+
// sendSpecialKeys() like the other keys instead of a one-off sendKeys() call.
|
|
588
|
+
'C-r',
|
|
518
589
|
]);
|
|
519
590
|
/**
|
|
520
591
|
* Type guard for "sendSpecialKeys() will actually deliver this key" (Issue #2032).
|
|
@@ -17,9 +17,13 @@
|
|
|
17
17
|
* counted, and it is the single failure this gate must not reproduce.
|
|
18
18
|
* 2. **Additions and removals are judged asymmetrically.** Everything that
|
|
19
19
|
* existed at task start must still exist, whoever it belonged to — that is
|
|
20
|
-
* the pkill (#1739) and `kill-server` (#1624) case — with
|
|
21
|
-
*
|
|
22
|
-
*
|
|
20
|
+
* the pkill (#1739) and `kill-server` (#1624) case — with three exceptions,
|
|
21
|
+
* each recorded in the baseline rather than guessed at verification: a
|
|
22
|
+
* tmux session of *another CommandMate server* (#2627) or of *this* server's
|
|
23
|
+
* worktree in *another repository* (#3043), which their owners close
|
|
24
|
+
* whenever they like, and a `.commandmate-demo-vitest-<pid>` directory
|
|
25
|
+
* whose pid was already dead (#3043), which the demo-video tests clean up
|
|
26
|
+
* by design. New things are a
|
|
23
27
|
* violation *unless they are attributable to another worker*, because
|
|
24
28
|
* parallel delegations legitimately start their own sessions and servers
|
|
25
29
|
* inside each other's measurement windows — or unless they are the one
|
|
@@ -31,10 +35,12 @@
|
|
|
31
35
|
* @module lib/verification/env-clean-gate
|
|
32
36
|
*/
|
|
33
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.ENV_CLEAN_GUIDANCE = exports.MAX_REPORTED_ENV_CHANGES = exports.REQUIRE_ENV_CLEAN_SOURCE_CONTRACT = exports.REQUIRE_ENV_CLEAN_SOURCE_CONFIG = void 0;
|
|
38
|
+
exports.ENV_CLEAN_GUIDANCE = exports.MAX_REPORTED_ENV_CHANGES = exports.isLivePid = exports.readLivePidCwd = exports.REQUIRE_ENV_CLEAN_SOURCE_CONTRACT = exports.REQUIRE_ENV_CLEAN_SOURCE_CONFIG = void 0;
|
|
35
39
|
exports.resolveRequireEnvClean = resolveRequireEnvClean;
|
|
36
40
|
exports.attributeSessionName = attributeSessionName;
|
|
37
41
|
exports.attributeAnchor = attributeAnchor;
|
|
42
|
+
exports.demoVitestPid = demoVitestPid;
|
|
43
|
+
exports.attributeHomeEntry = attributeHomeEntry;
|
|
38
44
|
exports.resolveTaskSessionName = resolveTaskSessionName;
|
|
39
45
|
exports.recordTaskSession = recordTaskSession;
|
|
40
46
|
exports.readTaskSession = readTaskSession;
|
|
@@ -42,11 +48,19 @@ exports.currentSessionServer = currentSessionServer;
|
|
|
42
48
|
exports.isOtherServerSession = isOtherServerSession;
|
|
43
49
|
exports.recordOtherServerSessions = recordOtherServerSessions;
|
|
44
50
|
exports.readOtherServerSessions = readOtherServerSessions;
|
|
51
|
+
exports.recordOtherRepositorySessions = recordOtherRepositorySessions;
|
|
52
|
+
exports.readOtherRepositorySessions = readOtherRepositorySessions;
|
|
53
|
+
exports.recordDeadDemoVitestEntries = recordDeadDemoVitestEntries;
|
|
54
|
+
exports.readDeadDemoVitestEntries = readDeadDemoVitestEntries;
|
|
45
55
|
exports.diffEnvSnapshots = diffEnvSnapshots;
|
|
46
56
|
exports.formatEnvCleanReport = formatEnvCleanReport;
|
|
47
57
|
exports.envCleanNoBaseline = envCleanNoBaseline;
|
|
48
58
|
exports.evaluateEnvClean = evaluateEnvClean;
|
|
59
|
+
const child_process_1 = require("child_process");
|
|
60
|
+
const fs_1 = require("fs");
|
|
49
61
|
const path_1 = require("path");
|
|
62
|
+
const db_instance_1 = require("../../lib/db/db-instance");
|
|
63
|
+
const worktree_db_1 = require("../../lib/db/worktree-db");
|
|
50
64
|
const session_name_1 = require("../../lib/cli-tools/session-name");
|
|
51
65
|
const types_1 = require("../../lib/cli-tools/types");
|
|
52
66
|
const env_snapshot_1 = require("./env-snapshot");
|
|
@@ -138,16 +152,102 @@ function attributeAnchor(anchor, worktreePath) {
|
|
|
138
152
|
return 'other';
|
|
139
153
|
return 'unattributed';
|
|
140
154
|
}
|
|
141
|
-
|
|
155
|
+
/** Bounded like the snapshot probes: a hung `lsof` must not hold a run open. */
|
|
156
|
+
const PID_CWD_TIMEOUT_MS = 5_000;
|
|
157
|
+
/**
|
|
158
|
+
* Read a process's cwd from the machine: `/proc/<pid>/cwd` on Linux, `lsof` on
|
|
159
|
+
* macOS (which has no procfs). A dead pid, a process owned by someone this user
|
|
160
|
+
* cannot inspect, or a missing `lsof` all answer null — which leaves the entry
|
|
161
|
+
* unattributed, the strict verdict.
|
|
162
|
+
*/
|
|
163
|
+
const readLivePidCwd = (pid) => {
|
|
164
|
+
try {
|
|
165
|
+
process.kill(pid, 0);
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// EPERM means the process exists but belongs to another user.
|
|
169
|
+
if (error.code !== 'EPERM')
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
if (process.platform === 'linux') {
|
|
173
|
+
try {
|
|
174
|
+
return (0, fs_1.readlinkSync)(`/proc/${pid}/cwd`);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
try {
|
|
181
|
+
const out = (0, child_process_1.execFileSync)('lsof', ['-a', '-d', 'cwd', '-p', String(pid), '-F', 'n'], {
|
|
182
|
+
encoding: 'utf8',
|
|
183
|
+
timeout: PID_CWD_TIMEOUT_MS,
|
|
184
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
185
|
+
});
|
|
186
|
+
const line = out.split('\n').find((field) => field.startsWith('n'));
|
|
187
|
+
return line ? line.slice(1) : null;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
exports.readLivePidCwd = readLivePidCwd;
|
|
194
|
+
/**
|
|
195
|
+
* `tests/unit/skills/demo-video/env-scripts.test.ts` creates
|
|
196
|
+
* `~/.commandmate-demo-vitest-<pid>` for the length of its run — in the real
|
|
197
|
+
* `$HOME`, because `env-up.sh` refuses `/tmp` and `/var` (#2954). The name
|
|
198
|
+
* carries the pid of the test process that made it, which is the one `$HOME`
|
|
199
|
+
* entry whose owner can be established.
|
|
200
|
+
*/
|
|
201
|
+
const DEMO_VITEST_HOME_ENTRY = /^\.commandmate-demo-vitest-([1-9]\d*)$/;
|
|
202
|
+
const isLivePid = (pid) => {
|
|
203
|
+
try {
|
|
204
|
+
process.kill(pid, 0);
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
return error.code === 'EPERM';
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
exports.isLivePid = isLivePid;
|
|
212
|
+
/** The pid a `.commandmate-demo-vitest-<pid>` name carries; null for any other name. */
|
|
213
|
+
function demoVitestPid(name) {
|
|
214
|
+
const match = DEMO_VITEST_HOME_ENTRY.exec(name);
|
|
215
|
+
if (!match)
|
|
216
|
+
return null;
|
|
217
|
+
const pid = Number(match[1]);
|
|
218
|
+
return Number.isSafeInteger(pid) ? pid : null;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Attribute a `$HOME` entry (#2954).
|
|
222
|
+
*
|
|
223
|
+
* Only `.commandmate-demo-vitest-<pid>` can be attributed, and only while its
|
|
224
|
+
* pid is alive: the test process's cwd is then judged exactly as a listener's
|
|
225
|
+
* is ({@link attributeAnchor}), so a parallel worktree's test run is `other`.
|
|
226
|
+
* A dead pid, an unreadable cwd, or a cwd inside this worktree leave it
|
|
227
|
+
* unattributed — a directory this worker's own tests failed to remove is still
|
|
228
|
+
* caught.
|
|
229
|
+
*/
|
|
230
|
+
function attributeHomeEntry(name, worktreePath, resolvePidCwd = exports.readLivePidCwd) {
|
|
231
|
+
const pid = demoVitestPid(name);
|
|
232
|
+
if (pid === null)
|
|
233
|
+
return 'unattributed';
|
|
234
|
+
const owner = attributeAnchor(resolvePidCwd(pid), worktreePath);
|
|
235
|
+
// `self` is not an excuse for an addition, and a file has no self to report.
|
|
236
|
+
return owner === 'other' ? 'other' : 'unattributed';
|
|
237
|
+
}
|
|
238
|
+
function attributeEntry(probeId, entry, context, resolvePidCwd) {
|
|
142
239
|
switch (probeId) {
|
|
143
240
|
case 'tmux-sessions':
|
|
144
241
|
return attributeSessionName(entry.key, context.worktreeId);
|
|
145
242
|
case 'listeners':
|
|
146
243
|
return attributeAnchor(entry.anchor, context.worktreePath);
|
|
244
|
+
case 'home-entries':
|
|
245
|
+
return attributeHomeEntry(entry.key, context.worktreePath, resolvePidCwd);
|
|
147
246
|
default:
|
|
148
247
|
// A file has no owner. `$HOME` and `~/.commandmate` are shared, so an
|
|
149
248
|
// entry appearing there is a violation for whoever is being judged — the
|
|
150
|
-
// rule the Issue's incident list is made of.
|
|
249
|
+
// rule the Issue's incident list is made of. The one `$HOME` exception is
|
|
250
|
+
// above (#2954).
|
|
151
251
|
return 'unattributed';
|
|
152
252
|
}
|
|
153
253
|
}
|
|
@@ -172,11 +272,13 @@ function resolveTaskSessionName(task) {
|
|
|
172
272
|
}
|
|
173
273
|
}
|
|
174
274
|
/** A freshly captured baseline, stamped with its task's own agent session. */
|
|
175
|
-
function recordTaskSession(snapshot, task, server = currentSessionServer()) {
|
|
275
|
+
function recordTaskSession(snapshot, task, server = currentSessionServer(), isPidAlive = exports.isLivePid) {
|
|
176
276
|
return {
|
|
177
277
|
...snapshot,
|
|
178
278
|
taskSession: resolveTaskSessionName(task),
|
|
179
279
|
otherServerSessions: recordOtherServerSessions(snapshot, server),
|
|
280
|
+
otherRepositorySessions: recordOtherRepositorySessions(snapshot, task.worktreeId, server),
|
|
281
|
+
deadDemoVitestEntries: recordDeadDemoVitestEntries(snapshot, isPidAlive),
|
|
180
282
|
};
|
|
181
283
|
}
|
|
182
284
|
/**
|
|
@@ -212,6 +314,14 @@ function currentSessionServer() {
|
|
|
212
314
|
return undefined;
|
|
213
315
|
}
|
|
214
316
|
},
|
|
317
|
+
repositoryOf: (worktreeId) => {
|
|
318
|
+
try {
|
|
319
|
+
return (0, worktree_db_1.getWorktreeById)((0, db_instance_1.getDbInstance)(), worktreeId)?.repositoryPath || null;
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
},
|
|
215
325
|
};
|
|
216
326
|
}
|
|
217
327
|
/**
|
|
@@ -290,6 +400,131 @@ function readOtherServerSessions(baseline) {
|
|
|
290
400
|
return new Set();
|
|
291
401
|
return new Set(recorded.filter((name) => typeof name === 'string'));
|
|
292
402
|
}
|
|
403
|
+
// =============================================================================
|
|
404
|
+
// This server's sessions of another repository (Issue #3043)
|
|
405
|
+
// =============================================================================
|
|
406
|
+
/**
|
|
407
|
+
* The repository a session of this server belongs to, or null when that
|
|
408
|
+
* cannot be pinned to exactly one.
|
|
409
|
+
*
|
|
410
|
+
* The worktree id and the instance suffix are not separable by name alone
|
|
411
|
+
* (`parseSessionName`), so every hyphen-boundary prefix of the tail is looked
|
|
412
|
+
* up; a prefix that is not a registered worktree answers null and is skipped.
|
|
413
|
+
* More than one repository among the answers is ambiguous and answers null —
|
|
414
|
+
* the strict direction, because null excuses nothing.
|
|
415
|
+
*/
|
|
416
|
+
function sessionRepository(tail, server) {
|
|
417
|
+
const repositoryOf = server.repositoryOf;
|
|
418
|
+
if (!repositoryOf)
|
|
419
|
+
return null;
|
|
420
|
+
const repositories = new Set();
|
|
421
|
+
let end = tail.indexOf('-');
|
|
422
|
+
for (;;) {
|
|
423
|
+
const candidate = end === -1 ? tail : tail.slice(0, end);
|
|
424
|
+
const repository = repositoryOf(candidate);
|
|
425
|
+
if (repository)
|
|
426
|
+
repositories.add(repository);
|
|
427
|
+
if (end === -1)
|
|
428
|
+
break;
|
|
429
|
+
end = tail.indexOf('-', end + 1);
|
|
430
|
+
}
|
|
431
|
+
return repositories.size === 1 ? [...repositories][0] : null;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* The baseline's `mcbd-*` sessions of *this* server whose worktree belongs to a
|
|
435
|
+
* repository other than the task's, at task creation.
|
|
436
|
+
*
|
|
437
|
+
* Why this is the second line removals are excused on — the design note for
|
|
438
|
+
* #3043, which extends the one for #2627 rather than contradicting it:
|
|
439
|
+
*
|
|
440
|
+
* - #1624, the case the removal rule exists for, was a worker killing a
|
|
441
|
+
* *sibling worktree of the same repository*. Those sessions stay guarded
|
|
442
|
+
* exactly as before: a same-repository removal is never excused, however
|
|
443
|
+
* plainly `other` its name is.
|
|
444
|
+
* - A worktree of another repository is driven by another orchestrate on the
|
|
445
|
+
* same server, which closes its workers' sessions when they finish (the
|
|
446
|
+
* 2026-09-29 and 2026-09-30 runs, `commandagent-issue-546/554` against
|
|
447
|
+
* `commandmate-issue-3023`). A delegation has no business in another
|
|
448
|
+
* repository, and the one it is judged for cannot tell that close from a
|
|
449
|
+
* kill any better than it could for another server's.
|
|
450
|
+
* - It uses the database the #2627 note rejected, but not for what that note
|
|
451
|
+
* rejected it for: there the other server's worktrees lived in a different
|
|
452
|
+
* database under colliding ids. Here the session carries *this* server's
|
|
453
|
+
* namespace, so *this* server's worktree table is the authority on it.
|
|
454
|
+
* - Recorded at task creation, like {@link recordOtherServerSessions}: the
|
|
455
|
+
* other orchestrate may remove its worktree — and with it the row — before
|
|
456
|
+
* this task is verified, and an unknown worktree excuses nothing.
|
|
457
|
+
*
|
|
458
|
+
* Still rejected: excusing every `other` removal (drops #1624), counting,
|
|
459
|
+
* timing and the worker's command log, for the reasons in the #2627 note; and
|
|
460
|
+
* a "needs review" verdict of its own, because the orchestrator's review of the
|
|
461
|
+
* same-repository case is exactly the one #1624 needs a hard failure for.
|
|
462
|
+
*
|
|
463
|
+
* @returns the names, or null when `server` has no namespace or cannot place
|
|
464
|
+
* the task's own worktree
|
|
465
|
+
*/
|
|
466
|
+
function recordOtherRepositorySessions(snapshot, taskWorktreeId, server) {
|
|
467
|
+
if (server.namespace === null || !server.repositoryOf)
|
|
468
|
+
return null;
|
|
469
|
+
const ownRepository = server.repositoryOf(taskWorktreeId);
|
|
470
|
+
if (!ownRepository)
|
|
471
|
+
return null;
|
|
472
|
+
const sessions = snapshot.probes['tmux-sessions'];
|
|
473
|
+
if (!sessions || sessions.status !== 'ok')
|
|
474
|
+
return [];
|
|
475
|
+
return sessions.entries
|
|
476
|
+
.map((entry) => entry.key)
|
|
477
|
+
.filter((name) => {
|
|
478
|
+
if (attributeSessionName(name, taskWorktreeId) !== 'other')
|
|
479
|
+
return false;
|
|
480
|
+
if (isOtherServerSession(name, server))
|
|
481
|
+
return false;
|
|
482
|
+
const parsed = (0, session_name_1.parseSessionName)(name);
|
|
483
|
+
if (!parsed)
|
|
484
|
+
return false;
|
|
485
|
+
const repository = sessionRepository(parsed.rest, server);
|
|
486
|
+
return repository !== null && repository !== ownRepository;
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
/** The recorded other-repository sessions of a baseline; empty when none was recorded. */
|
|
490
|
+
function readOtherRepositorySessions(baseline) {
|
|
491
|
+
const recorded = baseline.otherRepositorySessions;
|
|
492
|
+
if (!Array.isArray(recorded))
|
|
493
|
+
return new Set();
|
|
494
|
+
return new Set(recorded.filter((name) => typeof name === 'string'));
|
|
495
|
+
}
|
|
496
|
+
// =============================================================================
|
|
497
|
+
// Stale demo-vitest directories (Issue #3043)
|
|
498
|
+
// =============================================================================
|
|
499
|
+
/**
|
|
500
|
+
* The baseline's `.commandmate-demo-vitest-<pid>` entries whose pid was already
|
|
501
|
+
* dead at task creation.
|
|
502
|
+
*
|
|
503
|
+
* Recorded then, because only then is it knowable: a removed directory's pid is
|
|
504
|
+
* always dead by verification, so the gate could not otherwise tell a leftover
|
|
505
|
+
* swept up by `env-scripts.test.ts` (#3025, run by any parallel worktree's unit
|
|
506
|
+
* gate) from a directory a live test run was still using. The latter — a pid
|
|
507
|
+
* alive at task start — stays a violation: a worker may have deleted a parallel
|
|
508
|
+
* test's working directory.
|
|
509
|
+
*/
|
|
510
|
+
function recordDeadDemoVitestEntries(snapshot, isPidAlive = exports.isLivePid) {
|
|
511
|
+
const home = snapshot.probes['home-entries'];
|
|
512
|
+
if (!home || home.status !== 'ok')
|
|
513
|
+
return [];
|
|
514
|
+
return home.entries
|
|
515
|
+
.map((entry) => entry.key)
|
|
516
|
+
.filter((name) => {
|
|
517
|
+
const pid = demoVitestPid(name);
|
|
518
|
+
return pid !== null && !isPidAlive(pid);
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
/** The recorded dead-pid demo-vitest entries of a baseline; empty when none was recorded. */
|
|
522
|
+
function readDeadDemoVitestEntries(baseline) {
|
|
523
|
+
const recorded = baseline.deadDemoVitestEntries;
|
|
524
|
+
if (!Array.isArray(recorded))
|
|
525
|
+
return new Set();
|
|
526
|
+
return new Set(recorded.filter((name) => typeof name === 'string' && demoVitestPid(name) !== null));
|
|
527
|
+
}
|
|
293
528
|
function toChange(entry, owner) {
|
|
294
529
|
return { key: entry.key, detail: entry.detail, owner };
|
|
295
530
|
}
|
|
@@ -304,7 +539,10 @@ function toChange(entry, owner) {
|
|
|
304
539
|
function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
305
540
|
const taskSession = readTaskSession(baseline);
|
|
306
541
|
const otherServerSessions = readOtherServerSessions(baseline);
|
|
542
|
+
const otherRepositorySessions = readOtherRepositorySessions(baseline);
|
|
543
|
+
const deadDemoVitestEntries = readDeadDemoVitestEntries(baseline);
|
|
307
544
|
const ignoredHomeEntries = new Set(options.ignoreHomeEntries ?? []);
|
|
545
|
+
const resolvePidCwd = options.resolvePidCwd ?? exports.readLivePidCwd;
|
|
308
546
|
const probes = env_snapshot_1.ENV_PROBE_IDS.map((probeId) => {
|
|
309
547
|
const before = baseline.probes[probeId];
|
|
310
548
|
const after = final.probes[probeId];
|
|
@@ -318,6 +556,8 @@ function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
|
318
556
|
taskSessionAdded: [],
|
|
319
557
|
removed: [],
|
|
320
558
|
removedByOtherServer: [],
|
|
559
|
+
removedByOtherRepository: [],
|
|
560
|
+
removedStaleDemoVitest: [],
|
|
321
561
|
ignoredByConfig: [],
|
|
322
562
|
};
|
|
323
563
|
}
|
|
@@ -331,6 +571,8 @@ function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
|
331
571
|
taskSessionAdded: [],
|
|
332
572
|
removed: [],
|
|
333
573
|
removedByOtherServer: [],
|
|
574
|
+
removedByOtherRepository: [],
|
|
575
|
+
removedStaleDemoVitest: [],
|
|
334
576
|
ignoredByConfig: [],
|
|
335
577
|
};
|
|
336
578
|
}
|
|
@@ -346,7 +588,7 @@ function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
|
346
588
|
for (const entry of after.entries) {
|
|
347
589
|
if (beforeKeys.has(entry.key))
|
|
348
590
|
continue;
|
|
349
|
-
const owner = attributeEntry(probeId, entry, context);
|
|
591
|
+
const owner = attributeEntry(probeId, entry, context, resolvePidCwd);
|
|
350
592
|
if (isIgnoredByConfig(entry)) {
|
|
351
593
|
ignoredByConfig.push(toChange(entry, owner));
|
|
352
594
|
continue;
|
|
@@ -367,10 +609,12 @@ function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
|
367
609
|
after.entries.some((entry) => beforeKeys.has(entry.key) || (taskSession !== null && entry.key === taskSession));
|
|
368
610
|
const removed = [];
|
|
369
611
|
const removedByOtherServer = [];
|
|
612
|
+
const removedByOtherRepository = [];
|
|
613
|
+
const removedStaleDemoVitest = [];
|
|
370
614
|
for (const entry of before.entries) {
|
|
371
615
|
if (afterKeys.has(entry.key))
|
|
372
616
|
continue;
|
|
373
|
-
const change = toChange(entry, attributeEntry(probeId, entry, context));
|
|
617
|
+
const change = toChange(entry, attributeEntry(probeId, entry, context, resolvePidCwd));
|
|
374
618
|
if (isIgnoredByConfig(entry)) {
|
|
375
619
|
ignoredByConfig.push(change);
|
|
376
620
|
}
|
|
@@ -379,6 +623,14 @@ function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
|
379
623
|
otherServerSessions.has(entry.key)) {
|
|
380
624
|
removedByOtherServer.push(change);
|
|
381
625
|
}
|
|
626
|
+
else if (tmuxServerSurvived &&
|
|
627
|
+
change.owner === 'other' &&
|
|
628
|
+
otherRepositorySessions.has(entry.key)) {
|
|
629
|
+
removedByOtherRepository.push(change);
|
|
630
|
+
}
|
|
631
|
+
else if (probeId === 'home-entries' && deadDemoVitestEntries.has(entry.key)) {
|
|
632
|
+
removedStaleDemoVitest.push(change);
|
|
633
|
+
}
|
|
382
634
|
else {
|
|
383
635
|
removed.push(change);
|
|
384
636
|
}
|
|
@@ -392,6 +644,8 @@ function diffEnvSnapshots(baseline, final, context, options = {}) {
|
|
|
392
644
|
taskSessionAdded,
|
|
393
645
|
removed,
|
|
394
646
|
removedByOtherServer,
|
|
647
|
+
removedByOtherRepository,
|
|
648
|
+
removedStaleDemoVitest,
|
|
395
649
|
ignoredByConfig,
|
|
396
650
|
};
|
|
397
651
|
});
|
|
@@ -453,6 +707,14 @@ function formatTaskSessionChanges(changes) {
|
|
|
453
707
|
function formatRemovedByOtherServer(changes) {
|
|
454
708
|
return changes.map((change) => ` · - ${change.key} (ignored: another CommandMate server's session, recorded at task start)`);
|
|
455
709
|
}
|
|
710
|
+
/** Removals excused as this server's sessions of another repository (#3043), one line each. */
|
|
711
|
+
function formatRemovedByOtherRepository(changes) {
|
|
712
|
+
return changes.map((change) => ` · - ${change.key} (ignored: a worktree of another repository on this server, recorded at task start)`);
|
|
713
|
+
}
|
|
714
|
+
/** Removals excused as leftover demo-vitest directories (#3043), one line each. */
|
|
715
|
+
function formatRemovedStaleDemoVitest(changes) {
|
|
716
|
+
return changes.map((change) => ` · - ${change.key} (ignored: its pid was already dead at task start — a leftover swept by the demo-video tests)`);
|
|
717
|
+
}
|
|
456
718
|
function formatIgnoredByConfig(changes) {
|
|
457
719
|
if (changes.length === 0)
|
|
458
720
|
return [];
|
|
@@ -486,6 +748,8 @@ function formatEnvCleanReport(diff) {
|
|
|
486
748
|
lines.push(` ${probe.probeId} clean (${label})${excused}`);
|
|
487
749
|
lines.push(...formatTaskSessionChanges(probe.taskSessionAdded));
|
|
488
750
|
lines.push(...formatRemovedByOtherServer(probe.removedByOtherServer));
|
|
751
|
+
lines.push(...formatRemovedByOtherRepository(probe.removedByOtherRepository));
|
|
752
|
+
lines.push(...formatRemovedStaleDemoVitest(probe.removedStaleDemoVitest));
|
|
489
753
|
lines.push(...formatIgnoredByConfig(probe.ignoredByConfig));
|
|
490
754
|
continue;
|
|
491
755
|
}
|
|
@@ -494,6 +758,8 @@ function formatEnvCleanReport(diff) {
|
|
|
494
758
|
lines.push(...formatChanges('-', probe.removed));
|
|
495
759
|
lines.push(...formatTaskSessionChanges(probe.taskSessionAdded));
|
|
496
760
|
lines.push(...formatRemovedByOtherServer(probe.removedByOtherServer));
|
|
761
|
+
lines.push(...formatRemovedByOtherRepository(probe.removedByOtherRepository));
|
|
762
|
+
lines.push(...formatRemovedStaleDemoVitest(probe.removedStaleDemoVitest));
|
|
497
763
|
lines.push(...formatIgnoredByConfig(probe.ignoredByConfig));
|
|
498
764
|
for (const excused of probe.ignoredAdded) {
|
|
499
765
|
lines.push(` · ${excused.key} (ignored: belongs to another worktree)`);
|
|
@@ -518,7 +784,11 @@ function envCleanNoBaseline(taskId, sources) {
|
|
|
518
784
|
return (`${verify_config_1.ENV_CLEAN_GATE_ID}: UNKNOWN — no baseline snapshot exists for ${who}, so nothing can be ` +
|
|
519
785
|
'compared. This is NOT "the environment is unchanged": no measurement was taken. ' +
|
|
520
786
|
'A baseline is recorded when the task is created (`send --contract`) and only while the ' +
|
|
521
|
-
`gate is switched on (currently: ${how}). Switch it on, then re-send the task.`
|
|
787
|
+
`gate is switched on (currently: ${how}). Switch it on, then re-send the task.` +
|
|
788
|
+
(taskId
|
|
789
|
+
? ''
|
|
790
|
+
: ' To re-verify this worktree\'s contract task (this run is not attached to a task), run ' +
|
|
791
|
+
'`commandmate verify <worktree> --task <id>`.'));
|
|
522
792
|
}
|
|
523
793
|
/**
|
|
524
794
|
* Judge the machine against the task's baseline.
|
|
@@ -552,6 +822,7 @@ async function evaluateEnvClean(input) {
|
|
|
552
822
|
}
|
|
553
823
|
const diff = diffEnvSnapshots(input.baseline, final, input, {
|
|
554
824
|
ignoreHomeEntries: input.ignoreHomeEntries,
|
|
825
|
+
resolvePidCwd: input.resolvePidCwd,
|
|
555
826
|
});
|
|
556
827
|
const header = `${verify_config_1.ENV_CLEAN_GATE_ID}: baseline=${new Date(input.baseline.capturedAt).toISOString()} ` +
|
|
557
828
|
`status=${diff.status} task-session=${describeTaskSession(diff.taskSession)}`;
|
|
@@ -50,6 +50,8 @@ const worktree_index_1 = require("./worktree-index");
|
|
|
50
50
|
// exit-code table the pane prints, so the producer and the reader are one string.
|
|
51
51
|
const run_verdict_vocabulary_1 = require("./run-verdict-vocabulary");
|
|
52
52
|
const scope_gate_1 = require("./scope-gate");
|
|
53
|
+
const receipt_owned_paths_1 = require("../../lib/skills/receipt-owned-paths");
|
|
54
|
+
const agent_state_paths_1 = require("../../lib/skills/agent-state-paths");
|
|
53
55
|
const verify_config_1 = require("./verify-config");
|
|
54
56
|
Object.defineProperty(exports, "ENV_CLEAN_GATE_ID", { enumerable: true, get: function () { return verify_config_1.ENV_CLEAN_GATE_ID; } });
|
|
55
57
|
Object.defineProperty(exports, "SCOPE_GATE_ID", { enumerable: true, get: function () { return verify_config_1.SCOPE_GATE_ID; } });
|
|
@@ -816,10 +818,35 @@ async function evaluateWorkEvidence(worktreePath, baseRef, requireCommit, agentE
|
|
|
816
818
|
if (porcelain.code !== 0) {
|
|
817
819
|
return done('error', "work-evidence: 'git status --porcelain' failed.", null);
|
|
818
820
|
}
|
|
819
|
-
|
|
821
|
+
// Untracked files a recorded Skill install placed, untouched since, are
|
|
822
|
+
// CommandMate's and not the agent's (#3092): installing a Skill alone must
|
|
823
|
+
// still read as `not_started`. Anything the receipt does not vouch for —
|
|
824
|
+
// including a Skill file whose bytes changed — is counted as before.
|
|
825
|
+
const skillOwned = (0, receipt_owned_paths_1.collectSkillReceiptOwnedPaths)(worktreePath);
|
|
826
|
+
let skillInstalledCount = 0;
|
|
827
|
+
const agentStateExcluded = new Set();
|
|
828
|
+
const uncommittedCount = (0, scope_gate_1.parsePorcelainStatusEntries)(porcelain.stdout).filter((entry) => {
|
|
829
|
+
if (!entry.paths.some((path) => !(0, scope_gate_1.isContractPath)(path)))
|
|
830
|
+
return false;
|
|
831
|
+
if ((0, scope_gate_1.isSkillInstalledUntrackedEntry)(entry, skillOwned)) {
|
|
832
|
+
skillInstalledCount += 1;
|
|
833
|
+
return false;
|
|
834
|
+
}
|
|
835
|
+
if ((0, agent_state_paths_1.isAgentStateUntrackedEntry)(entry)) {
|
|
836
|
+
entry.paths.forEach((path) => agentStateExcluded.add(path));
|
|
837
|
+
return false;
|
|
838
|
+
}
|
|
839
|
+
return true;
|
|
840
|
+
}).length;
|
|
820
841
|
const summary = `work-evidence: baseRef=${baseRef} commits=${commitCount} uncommitted=${uncommittedCount}` +
|
|
821
842
|
(requireCommit.required ? ' requireCommit=true' : '') +
|
|
822
|
-
' (contract files excluded)'
|
|
843
|
+
' (contract files excluded)' +
|
|
844
|
+
(skillInstalledCount > 0
|
|
845
|
+
? ` (${skillInstalledCount} CommandMate-installed Skill file(s) excluded)`
|
|
846
|
+
: '') +
|
|
847
|
+
(agentStateExcluded.size > 0
|
|
848
|
+
? ` (agent-managed state file(s) excluded: ${[...agentStateExcluded].sort().join(', ')})`
|
|
849
|
+
: '');
|
|
823
850
|
if (!Number.isFinite(commitCount) || (commitCount === 0 && uncommittedCount === 0)) {
|
|
824
851
|
// Issue #2043, and the ONLY place this gate's verdict differs from what it
|
|
825
852
|
// was: git found nothing, so ask the agent. `null` — every tool but
|