commandmate 0.27.0 → 0.28.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/.env.example +28 -0
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +286 -256
- package/.next/app-path-routes-manifest.json +36 -32
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +12 -12
- package/.next/required-server-files.json +1 -1
- package/.next/routes-manifest.json +32 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +1 -1
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +32 -1
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +34 -3
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/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 +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 +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 +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 +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 +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 +1 -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 +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 +7 -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/repositories/[id]/route.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/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/[id]/todos/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 +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 +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/sidebar/group-order/route.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.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 +1 -1
- 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.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.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 +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 +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 +2 -2
- 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 +2 -2
- 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/todos/route.js +1 -1
- package/.next/server/app/api/todos/route.js.nft.json +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.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 +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-tool/route.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 +2 -2
- 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 +2 -2
- 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]/env/route.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 +2 -2
- 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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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/opencode/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -0
- 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 +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 +2 -2
- 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 +4 -4
- 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 +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 +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 +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 +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -0
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -0
- 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 +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 -1
- 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 +5 -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 +1 -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 +6 -2
- 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 +7 -3
- 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 +1 -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]/start-polling/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/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.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 +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.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 -3
- 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 +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 +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 +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 +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 +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/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]/route.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 +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 +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/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/chat/page_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.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 +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.js +1 -1
- package/.next/server/app/review/page.js.nft.json +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.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 +15 -10
- 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 +2 -2
- 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 +36 -32
- package/.next/server/chunks/1058.js +1 -0
- package/.next/server/chunks/1068.js +1 -3
- package/.next/server/chunks/1191.js +13 -0
- package/.next/server/chunks/1296.js +1 -1
- package/.next/server/chunks/1601.js +2 -2
- package/.next/server/chunks/1714.js +7 -0
- package/.next/server/chunks/1886.js +5 -0
- package/.next/server/chunks/1944.js +1 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/221.js +19 -0
- package/.next/server/chunks/222.js +1 -0
- package/.next/server/chunks/2328.js +1 -1
- package/.next/server/chunks/2366.js +1 -0
- package/.next/server/chunks/2404.js +2 -2
- package/.next/server/chunks/243.js +1 -0
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2759.js +1 -1
- package/.next/server/chunks/3346.js +1 -1
- package/.next/server/chunks/3480.js +17 -1
- package/.next/server/chunks/3558.js +1 -0
- package/.next/server/chunks/4299.js +1 -0
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/5017.js +1 -1
- package/.next/server/chunks/5089.js +1 -1
- package/.next/server/chunks/5354.js +1 -1
- package/.next/server/chunks/5571.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6274.js +11 -10
- package/.next/server/chunks/6285.js +1 -1
- package/.next/server/chunks/6337.js +1 -0
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/663.js +78 -0
- package/.next/server/chunks/7472.js +1 -1
- package/.next/server/chunks/7824.js +1 -0
- package/.next/server/chunks/7905.js +1 -0
- package/.next/server/chunks/880.js +1 -1
- package/.next/server/chunks/8807.js +84 -18
- package/.next/server/chunks/9130.js +5 -0
- package/.next/server/chunks/9328.js +1 -1
- package/.next/server/chunks/9358.js +1 -1
- package/.next/server/chunks/9508.js +1 -1
- package/.next/server/chunks/9584.js +1 -0
- package/.next/server/chunks/9627.js +274 -0
- package/.next/server/chunks/9798.js +2 -0
- package/.next/server/chunks/9938.js +1 -1
- 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/1188-8567ee5ecfef02ee.js +1 -0
- package/.next/static/chunks/3361-aa1b6e7c1d7eeeb4.js +1 -0
- package/.next/static/chunks/3968-8d8ca15657748bfb.js +1 -0
- package/.next/static/chunks/6381-d921ab728eda1191.js +1 -0
- package/.next/static/chunks/app/api/app/update/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/skills/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/templates/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/todos/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/more/page-03867ab635d197c7.js +1 -0
- package/.next/static/chunks/app/proxy/[...path]/route-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/review/page-9a6d18ddcccbb63c.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-9247d6b9d647f750.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-27b7cb2e77099eec.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-00ad5d9a62a71cab.js +1 -0
- package/.next/static/css/98722bc4152cedcc.css +1 -0
- package/.next/trace +13 -13
- package/.next/types/app/api/worktrees/[id]/instances/opencode/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/opencode/diff/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/opencode/session/route.ts +347 -0
- package/.next/types/app/api/worktrees/[id]/opencode/share/route.ts +347 -0
- package/.next/types/routes.d.ts +5 -1
- package/.next/types/validator.ts +36 -0
- package/README.md +9 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +66 -0
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +46 -1
- package/dist/cli/commands/interrupt.d.ts +25 -0
- package/dist/cli/commands/interrupt.d.ts.map +1 -0
- package/dist/cli/commands/interrupt.js +146 -0
- package/dist/cli/commands/report.d.ts.map +1 -1
- package/dist/cli/commands/report.js +11 -4
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +146 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +104 -0
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +39 -1
- package/dist/cli/config/agent-target-options.d.ts +12 -0
- package/dist/cli/config/agent-target-options.d.ts.map +1 -1
- package/dist/cli/config/agent-target-options.js +15 -1
- package/dist/cli/docs/agent-operations.d.ts +1 -1
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +34 -0
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +6 -0
- package/dist/cli/types/api-responses.d.ts +375 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +63 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/types/index.js +31 -1
- package/dist/cli/utils/daemon.d.ts.map +1 -1
- package/dist/cli/utils/daemon.js +3 -0
- package/dist/cli/utils/env-setup.d.ts +24 -0
- package/dist/cli/utils/env-setup.d.ts.map +1 -1
- package/dist/cli/utils/env-setup.js +70 -0
- package/dist/cli/utils/vapid-keygen.d.ts +74 -0
- package/dist/cli/utils/vapid-keygen.d.ts.map +1 -0
- package/dist/cli/utils/vapid-keygen.js +111 -0
- package/dist/lib/cli-tools/types.d.ts +11 -1
- package/dist/lib/cli-tools/types.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.d.ts +14 -3
- package/dist/lib/detection/tools/verified-against.d.ts.map +1 -1
- package/dist/lib/detection/tools/verified-against.js +14 -3
- package/dist/lib/push/vapid.d.ts +178 -0
- package/dist/lib/push/vapid.d.ts.map +1 -0
- package/dist/lib/push/vapid.js +293 -0
- package/dist/lib/server/localhost-self-check.d.ts +203 -0
- package/dist/lib/server/localhost-self-check.d.ts.map +1 -0
- package/dist/lib/server/localhost-self-check.js +333 -0
- package/dist/server/locales/en/notifications.json +23 -1
- package/dist/server/locales/ja/notifications.json +23 -1
- package/dist/server/server.js +103 -0
- package/dist/server/src/config/image-extensions.js +244 -0
- package/dist/server/src/config/opencode-constants.js +69 -0
- package/dist/server/src/config/tmux-pane-config.js +100 -1
- package/dist/server/src/lib/cli-tools/base.js +33 -48
- package/dist/server/src/lib/cli-tools/opencode-config.js +12 -0
- package/dist/server/src/lib/cli-tools/opencode.js +435 -7
- package/dist/server/src/lib/cli-tools/start-availability.js +160 -0
- package/dist/server/src/lib/cmate-cli-tool-parser.js +328 -7
- package/dist/server/src/lib/cmate-parser.js +12 -0
- package/dist/server/src/lib/db/agent-instances-db.js +129 -0
- package/dist/server/src/lib/db/agent-session-cost-db.js +204 -0
- package/dist/server/src/lib/db/agent-session-cost-sampler.js +194 -0
- package/dist/server/src/lib/db/chat-db.js +33 -0
- package/dist/server/src/lib/db/db-instance.js +11 -0
- package/dist/server/src/lib/db/db.js +8 -3
- package/dist/server/src/lib/db/migrations/index.js +6 -0
- package/dist/server/src/lib/db/migrations/runner.js +1 -1
- package/dist/server/src/lib/db/migrations/v57-push-subscription-defaults-notice.js +54 -0
- package/dist/server/src/lib/db/migrations/v58-agent-session-costs.js +100 -0
- package/dist/server/src/lib/db/migrations/v59-opencode-instance-settings.js +71 -0
- package/dist/server/src/lib/db/push-subscriptions-db.js +56 -5
- package/dist/server/src/lib/detection/cli-patterns.js +17 -6
- package/dist/server/src/lib/detection/excerpt.js +48 -0
- package/dist/server/src/lib/detection/model-info-extractor.js +26 -3
- package/dist/server/src/lib/detection/opencode-modal-overlay.js +400 -0
- package/dist/server/src/lib/detection/opencode-pane-obstruction.js +181 -0
- package/dist/server/src/lib/detection/status-detector.js +7 -0
- package/dist/server/src/lib/detection/status-reason.js +20 -0
- package/dist/server/src/lib/detection/terminal-columns.js +94 -0
- package/dist/server/src/lib/detection/tools/opencode/detect.js +43 -0
- package/dist/server/src/lib/detection/tools/opencode/prompt.js +20 -0
- package/dist/server/src/lib/detection/tools/verified-against.js +14 -3
- package/dist/server/src/lib/detection/upstream-faults.js +7 -22
- package/dist/server/src/lib/hooks/agent-session-telemetry.js +324 -0
- package/dist/server/src/lib/hooks/pending-decision-kind.js +72 -0
- package/dist/server/src/lib/hooks/sources/define-source.js +88 -0
- package/dist/server/src/lib/hooks/sources/opencode/client.js +907 -2
- package/dist/server/src/lib/hooks/sources/opencode/diff.js +336 -0
- package/dist/server/src/lib/hooks/sources/opencode/history.js +480 -0
- package/dist/server/src/lib/hooks/sources/opencode/ingest.js +76 -7
- package/dist/server/src/lib/hooks/sources/opencode/launch-settings.js +222 -0
- package/dist/server/src/lib/hooks/sources/opencode/mappers.js +31 -0
- package/dist/server/src/lib/hooks/sources/opencode/payloads.js +45 -0
- package/dist/server/src/lib/hooks/sources/opencode/ports.js +16 -0
- package/dist/server/src/lib/hooks/sources/opencode/push.js +307 -0
- package/dist/server/src/lib/hooks/sources/opencode/reattach.js +284 -0
- package/dist/server/src/lib/hooks/sources/opencode/runtime.js +165 -2
- package/dist/server/src/lib/hooks/sources/opencode/source.js +46 -2
- package/dist/server/src/lib/hooks/sources/opencode/subscription.js +407 -4
- package/dist/server/src/lib/hooks/sources/opencode/transcript.js +383 -0
- package/dist/server/src/lib/hooks/structured-decision-response.js +460 -0
- package/dist/server/src/lib/job-executor.js +43 -20
- package/dist/server/src/lib/polling/response-checker.js +43 -16
- package/dist/server/src/lib/polling/structured-history-gate.js +75 -0
- package/dist/server/src/lib/prompt-answer-sender.js +153 -2
- package/dist/server/src/lib/push/delivery-health.js +237 -0
- package/dist/server/src/lib/push/failure-push-notifier.js +109 -7
- package/dist/server/src/lib/push/index.js +25 -1
- package/dist/server/src/lib/push/prompt-card-state.js +254 -14
- package/dist/server/src/lib/push/push-sender.js +63 -12
- package/dist/server/src/lib/push/resolution-push-notifier.js +15 -3
- package/dist/server/src/lib/push/vapid.js +264 -5
- package/dist/server/src/lib/push/waiting-push-notifier.js +7 -0
- package/dist/server/src/lib/server/localhost-self-check.js +333 -0
- package/dist/server/src/lib/session/agent-event-state.js +169 -4
- package/dist/server/src/lib/session/claude-executor.js +152 -15
- package/dist/server/src/lib/session/current-output-builder.js +182 -15
- package/dist/server/src/lib/session/opencode-session-api.js +214 -0
- package/dist/server/src/lib/session/opencode-session-recall.js +168 -0
- package/dist/server/src/lib/session/opencode-session-store.js +274 -0
- package/dist/server/src/lib/session/provisional-turn.js +54 -1
- package/dist/server/src/lib/session/send-user-message.js +6 -5
- package/dist/server/src/lib/session/structured-prompt.js +53 -2
- package/dist/server/src/lib/skills/compatibility-matrix.js +50 -1
- package/dist/server/src/lib/tmux/tmux.js +74 -4
- package/dist/server/src/lib/verification/gate-runner.js +71 -8
- package/dist/server/src/types/agent-session.js +63 -0
- package/dist/server/src/types/agent-transcript.js +80 -0
- package/dist/server/src/types/opencode-export.js +228 -0
- package/dist/server/src/types/opencode-instance-settings.js +140 -0
- package/dist/server/src/types/opencode-share.js +111 -0
- package/dist/server/src/types/terminal-keys.js +69 -1
- package/dist/types/cli-tool-contracts.d.ts +48 -0
- package/dist/types/cli-tool-contracts.d.ts.map +1 -1
- package/dist/types/terminal-keys.d.ts +89 -0
- package/dist/types/terminal-keys.d.ts.map +1 -0
- package/dist/types/terminal-keys.js +105 -0
- package/package.json +1 -1
- package/.next/server/chunks/1029.js +0 -1
- package/.next/server/chunks/1239.js +0 -1
- package/.next/server/chunks/1538.js +0 -7
- package/.next/server/chunks/2546.js +0 -1
- package/.next/server/chunks/2689.js +0 -13
- package/.next/server/chunks/3292.js +0 -1
- package/.next/server/chunks/3417.js +0 -1
- package/.next/server/chunks/3736.js +0 -1
- package/.next/server/chunks/4423.js +0 -1
- package/.next/server/chunks/4444.js +0 -32
- package/.next/server/chunks/4565.js +0 -3
- package/.next/server/chunks/467.js +0 -1
- package/.next/server/chunks/4905.js +0 -5
- package/.next/server/chunks/552.js +0 -19
- package/.next/server/chunks/5998.js +0 -74
- package/.next/server/chunks/6919.js +0 -1
- package/.next/server/chunks/7970.js +0 -229
- package/.next/server/chunks/8536.js +0 -1
- package/.next/server/chunks/9284.js +0 -1
- package/.next/static/chunks/3361-5d6e93fba8a92bc1.js +0 -1
- package/.next/static/chunks/6381-b7250e8ca7a44c6c.js +0 -1
- package/.next/static/chunks/8521-c43994fb58501d13.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/skills/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/templates/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/todos/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/more/page-3266dfa945972649.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/review/page-8f63aff862fee421.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-6add0d88e2828c23.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-e4f28966b4fc0ce1.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/terminal/page-a75fe180a7233b2b.js +0 -1
- package/.next/static/css/928e5a8830fbf997.css +0 -1
- /package/.next/static/{t0BoV4H46ZgKmTjSi7GIz → 0GHE2JGlFzqvSBZAcBFSt}/_buildManifest.js +0 -0
- /package/.next/static/{t0BoV4H46ZgKmTjSi7GIz → 0GHE2JGlFzqvSBZAcBFSt}/_ssgManifest.js +0 -0
|
@@ -1,27 +1,286 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* VAPID configuration for Web Push
|
|
3
|
+
* VAPID configuration for Web Push, and the one startup check that reports on it
|
|
4
|
+
* (Issue #1125; the check and the subject rules are Issues #2123 / #2124).
|
|
4
5
|
*
|
|
5
6
|
* Keys are supplied via environment variables and read lazily so tests can vary
|
|
6
7
|
* them and so an unconfigured deployment simply disables push (never crashes).
|
|
7
8
|
* The private key and subject are secrets — never log the returned config.
|
|
9
|
+
*
|
|
10
|
+
* ## Why the default subject is an https: URL (Issue #2124)
|
|
11
|
+
*
|
|
12
|
+
* The VAPID `sub` claim is the sender's contact, and **Apple validates it**. The
|
|
13
|
+
* original default, `mailto:commandmate@localhost`, names a domain that cannot
|
|
14
|
+
* exist, so APNs answered 403 and iOS/iPadOS received nothing while Android kept
|
|
15
|
+
* working — FCM is permissive about `sub`, so testing on Android alone cannot
|
|
16
|
+
* see it. Measured by the orchestrator during the Epic #2002 device UAT
|
|
17
|
+
* (2026-08-27, develop e8d09989), fanning ONE waiting notification to two
|
|
18
|
+
* devices:
|
|
19
|
+
*
|
|
20
|
+
* Android 10 / Chrome 151 -> FCM default subject: delivered
|
|
21
|
+
* iPad / iPadOS 18.7 -> APNs default subject: 403, push-send-failed
|
|
22
|
+
* https://github.com/Kewton/CommandMate: delivered
|
|
23
|
+
*
|
|
24
|
+
* This file's author did NOT reproduce that on hardware; the APNs/FCM behaviour
|
|
25
|
+
* above is quoted from that UAT and is not re-measured here. What IS pinned by
|
|
26
|
+
* the unit suite is the pure part: which subjects this module accepts and which
|
|
27
|
+
* it flags, and that the default is one of the accepted ones.
|
|
28
|
+
*
|
|
29
|
+
* RFC 8292 §2.1 allows both `mailto:` and `https:` for `sub`, so a project URL
|
|
30
|
+
* is a conforming default that needs no per-install mailbox.
|
|
31
|
+
*
|
|
32
|
+
* ## Why an invalid subject is reported and NOT replaced
|
|
33
|
+
*
|
|
34
|
+
* {@link inspectVapidConfig} flags a bad `CM_VAPID_SUBJECT`; {@link getVapidConfig}
|
|
35
|
+
* still returns it verbatim. Silently substituting the default would make the
|
|
36
|
+
* warning describe a value the server does not actually send, and would make
|
|
37
|
+
* `commandmate status` disagree with the wire. The operator set it; they are told
|
|
38
|
+
* it will be rejected, and startup is never blocked (fail-open, exactly as
|
|
39
|
+
* `lib/server/localhost-self-check` is).
|
|
40
|
+
*
|
|
41
|
+
* ## No `@/` imports here, ever
|
|
42
|
+
*
|
|
43
|
+
* `src/cli/commands/status.ts` imports this module so the CLI and the server run
|
|
44
|
+
* the SAME check, and `tsconfig.cli.json` resets `paths` to `{}` — an alias
|
|
45
|
+
* import here would break `npm run build:cli`. Same constraint as
|
|
46
|
+
* `lib/server/localhost-self-check.ts` and `lib/detection/version-probes.ts`.
|
|
47
|
+
* This module must also stay dependency-free for that reason.
|
|
48
|
+
*
|
|
49
|
+
* @module lib/push/vapid
|
|
8
50
|
*/
|
|
9
51
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
exports.VAPID_ENV_KEYS = exports.VAPID_DEFAULT_SUBJECT = void 0;
|
|
53
|
+
exports.extractVapidSubjectHost = extractVapidSubjectHost;
|
|
54
|
+
exports.classifyVapidSubject = classifyVapidSubject;
|
|
55
|
+
exports.inspectVapidConfig = inspectVapidConfig;
|
|
56
|
+
exports.formatVapidReportLines = formatVapidReportLines;
|
|
57
|
+
exports.runVapidSelfCheck = runVapidSelfCheck;
|
|
10
58
|
exports.getVapidConfig = getVapidConfig;
|
|
11
59
|
exports.isPushConfigured = isPushConfigured;
|
|
12
60
|
exports.getVapidPublicKey = getVapidPublicKey;
|
|
13
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Default `sub` claim when `CM_VAPID_SUBJECT` is unset.
|
|
63
|
+
*
|
|
64
|
+
* A real, resolvable https: URL — see the module header for the APNs measurement
|
|
65
|
+
* that made `mailto:commandmate@localhost` the wrong answer (Issue #2124).
|
|
66
|
+
*/
|
|
67
|
+
exports.VAPID_DEFAULT_SUBJECT = 'https://github.com/Kewton/CommandMate';
|
|
68
|
+
/** The three environment variables that configure Web Push. */
|
|
69
|
+
exports.VAPID_ENV_KEYS = {
|
|
70
|
+
publicKey: 'CM_VAPID_PUBLIC_KEY',
|
|
71
|
+
privateKey: 'CM_VAPID_PRIVATE_KEY',
|
|
72
|
+
subject: 'CM_VAPID_SUBJECT',
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Host suffixes that never resolve on the public internet, so a push service can
|
|
76
|
+
* never verify a `sub` that names one.
|
|
77
|
+
*
|
|
78
|
+
* `.example` is here as a *TLD*; `example.com` is an ordinary resolvable domain
|
|
79
|
+
* and is deliberately NOT rejected (it is the conventional placeholder in every
|
|
80
|
+
* VAPID tutorial and in this repository's own tests).
|
|
81
|
+
*/
|
|
82
|
+
const NON_ROUTABLE_TLDS = [
|
|
83
|
+
'local',
|
|
84
|
+
'localhost',
|
|
85
|
+
'localdomain',
|
|
86
|
+
'internal',
|
|
87
|
+
'intranet',
|
|
88
|
+
'home',
|
|
89
|
+
'lan',
|
|
90
|
+
'test',
|
|
91
|
+
'invalid',
|
|
92
|
+
'example',
|
|
93
|
+
];
|
|
94
|
+
/** Loopback / unspecified literals, which are never a contact anyone can reach. */
|
|
95
|
+
function isLoopbackLiteral(host) {
|
|
96
|
+
if (host === '::1' || host === '0.0.0.0' || host === '::')
|
|
97
|
+
return true;
|
|
98
|
+
return /^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(host);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The host a subject names, lowercased, or `null` when it names none.
|
|
102
|
+
*
|
|
103
|
+
* `mailto:` takes everything after the LAST `@` (a local part may legally contain
|
|
104
|
+
* one when quoted) up to the first `?` (RFC 6068 header separator). `https:` is
|
|
105
|
+
* parsed by `URL`, whose `hostname` already strips the brackets off an IPv6
|
|
106
|
+
* literal.
|
|
107
|
+
*/
|
|
108
|
+
function extractVapidSubjectHost(subject) {
|
|
109
|
+
const trimmed = subject.trim();
|
|
110
|
+
if (/^mailto:/i.test(trimmed)) {
|
|
111
|
+
const address = trimmed.slice('mailto:'.length).split('?')[0];
|
|
112
|
+
const at = address.lastIndexOf('@');
|
|
113
|
+
if (at < 0)
|
|
114
|
+
return null;
|
|
115
|
+
const host = address.slice(at + 1).trim().toLowerCase();
|
|
116
|
+
return host.length > 0 ? host : null;
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const url = new URL(trimmed);
|
|
120
|
+
return url.hostname.length > 0 ? url.hostname.toLowerCase() : null;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Decide whether a `sub` claim is one a push service can be expected to accept.
|
|
128
|
+
*
|
|
129
|
+
* Deliberately conservative: it rejects only hosts that provably cannot resolve.
|
|
130
|
+
* A reachable-but-wrong contact (`mailto:nobody@example.com`) is the operator's
|
|
131
|
+
* business, and a check that guessed at it would warn on healthy installs.
|
|
132
|
+
*
|
|
133
|
+
* @param subject - Raw `CM_VAPID_SUBJECT`, or the default.
|
|
134
|
+
* @returns The problem, or `null` when the subject is usable.
|
|
135
|
+
*/
|
|
136
|
+
function classifyVapidSubject(subject) {
|
|
137
|
+
const trimmed = subject.trim();
|
|
138
|
+
if (!/^(mailto:|https:\/\/)/i.test(trimmed))
|
|
139
|
+
return 'unsupported-scheme';
|
|
140
|
+
const host = extractVapidSubjectHost(trimmed);
|
|
141
|
+
if (host === null)
|
|
142
|
+
return 'missing-host';
|
|
143
|
+
if (isLoopbackLiteral(host))
|
|
144
|
+
return 'non-routable-host';
|
|
145
|
+
// A bare name (`localhost`, `mac-mini`) has no public resolution path.
|
|
146
|
+
if (!host.includes('.'))
|
|
147
|
+
return 'non-routable-host';
|
|
148
|
+
const tld = host.slice(host.lastIndexOf('.') + 1);
|
|
149
|
+
if (NON_ROUTABLE_TLDS.includes(tld))
|
|
150
|
+
return 'non-routable-host';
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Read the three variables and say, in one verdict, everything both Issues need
|
|
155
|
+
* reported: whether push is on at all (#2123) and whether the subject will be
|
|
156
|
+
* accepted (#2124).
|
|
157
|
+
*
|
|
158
|
+
* ONE check, two facts — deliberately not two checks. The startup log, the
|
|
159
|
+
* `commandmate status` output and the unit suite all consume this one function,
|
|
160
|
+
* so the two surfaces cannot drift apart.
|
|
161
|
+
*
|
|
162
|
+
* Pure: no I/O, no logging, never throws.
|
|
163
|
+
*
|
|
164
|
+
* @param env - Environment to read (default: `process.env`). `commandmate status`
|
|
165
|
+
* passes the env the *daemon* runs with, which is not this process's own.
|
|
166
|
+
*/
|
|
167
|
+
function inspectVapidConfig(env = process.env) {
|
|
168
|
+
const publicKey = env[exports.VAPID_ENV_KEYS.publicKey]?.trim() ?? '';
|
|
169
|
+
const privateKey = env[exports.VAPID_ENV_KEYS.privateKey]?.trim() ?? '';
|
|
170
|
+
const rawSubject = env[exports.VAPID_ENV_KEYS.subject]?.trim() ?? '';
|
|
171
|
+
const presentKeys = [];
|
|
172
|
+
const missingKeys = [];
|
|
173
|
+
(publicKey ? presentKeys : missingKeys).push(exports.VAPID_ENV_KEYS.publicKey);
|
|
174
|
+
(privateKey ? presentKeys : missingKeys).push(exports.VAPID_ENV_KEYS.privateKey);
|
|
175
|
+
const subject = rawSubject || exports.VAPID_DEFAULT_SUBJECT;
|
|
176
|
+
const subjectSource = rawSubject ? 'env' : 'default';
|
|
177
|
+
const subjectIssue = classifyVapidSubject(subject);
|
|
178
|
+
if (rawSubject)
|
|
179
|
+
presentKeys.push(exports.VAPID_ENV_KEYS.subject);
|
|
180
|
+
const configured = publicKey !== '' && privateKey !== '';
|
|
181
|
+
const status = configured
|
|
182
|
+
? subjectIssue === null
|
|
183
|
+
? 'ok'
|
|
184
|
+
: 'invalid-subject'
|
|
185
|
+
: publicKey || privateKey
|
|
186
|
+
? 'partial'
|
|
187
|
+
: 'unconfigured';
|
|
188
|
+
return {
|
|
189
|
+
status,
|
|
190
|
+
configured,
|
|
191
|
+
subject,
|
|
192
|
+
subjectSource,
|
|
193
|
+
subjectIssue,
|
|
194
|
+
presentKeys,
|
|
195
|
+
missingKeys,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/** Human-readable reason for a {@link VapidSubjectIssue}. */
|
|
199
|
+
function describeSubjectIssue(issue) {
|
|
200
|
+
switch (issue) {
|
|
201
|
+
case 'unsupported-scheme':
|
|
202
|
+
return 'it is neither a "mailto:" address nor an "https://" URL (RFC 8292 allows only those two)';
|
|
203
|
+
case 'missing-host':
|
|
204
|
+
return 'it names no host at all';
|
|
205
|
+
case 'non-routable-host':
|
|
206
|
+
return 'its host cannot be resolved from the public internet (localhost, a bare name, or a reserved TLD)';
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* The startup / `status` report, as lines — shared by both surfaces so they can
|
|
211
|
+
* never drift apart, exactly as `formatLocalhostConflictWarning` is (#2113).
|
|
212
|
+
*
|
|
213
|
+
* **Returns an empty array when the configuration is healthy.** That silence is
|
|
214
|
+
* the negative control both Issues ask for: a correctly configured server prints
|
|
215
|
+
* nothing about push, so the presence of a line is itself the signal.
|
|
216
|
+
*
|
|
217
|
+
* Never includes a key or a private value. `subject` is printed because it is the
|
|
218
|
+
* value the operator has to fix, and it is a contact address rather than a
|
|
219
|
+
* credential — the module header's "never log the config" rule is about the keys.
|
|
220
|
+
*/
|
|
221
|
+
function formatVapidReportLines(inspection) {
|
|
222
|
+
switch (inspection.status) {
|
|
223
|
+
case 'ok':
|
|
224
|
+
return [];
|
|
225
|
+
case 'unconfigured':
|
|
226
|
+
return [
|
|
227
|
+
'Push notifications are disabled: no VAPID keys are configured.',
|
|
228
|
+
` Set ${exports.VAPID_ENV_KEYS.publicKey} and ${exports.VAPID_ENV_KEYS.privateKey} to enable them.`,
|
|
229
|
+
' "commandmate init" generates a key pair for you.',
|
|
230
|
+
' Setup: docs/user-guide/webapp-guide.md ("Phone notifications")',
|
|
231
|
+
];
|
|
232
|
+
case 'partial':
|
|
233
|
+
return [
|
|
234
|
+
`Push notifications are disabled: ${inspection.missingKeys.join(' and ')} ${inspection.missingKeys.length > 1 ? 'are' : 'is'} not set.`,
|
|
235
|
+
` Both ${exports.VAPID_ENV_KEYS.publicKey} and ${exports.VAPID_ENV_KEYS.privateKey} are required;` +
|
|
236
|
+
' a key pair only works as a pair.',
|
|
237
|
+
' "commandmate init" generates a key pair for you.',
|
|
238
|
+
' Setup: docs/user-guide/webapp-guide.md ("Phone notifications")',
|
|
239
|
+
];
|
|
240
|
+
case 'invalid-subject':
|
|
241
|
+
return [
|
|
242
|
+
`${exports.VAPID_ENV_KEYS.subject}="${inspection.subject}" will be rejected by Apple (APNs):` +
|
|
243
|
+
` ${describeSubjectIssue(inspection.subjectIssue)}.`,
|
|
244
|
+
' iPhone/iPad receive nothing while Android keeps working, because FCM does not check it.',
|
|
245
|
+
` Use a reachable contact, e.g. ${exports.VAPID_DEFAULT_SUBJECT} or mailto:you@your-domain.example.org.`,
|
|
246
|
+
` Unset ${exports.VAPID_ENV_KEYS.subject} to fall back to ${exports.VAPID_DEFAULT_SUBJECT}.`,
|
|
247
|
+
];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Run the startup self-check and print its verdict, or nothing when healthy.
|
|
252
|
+
*
|
|
253
|
+
* Fail-open by construction, the same contract `runLocalhostSelfCheck` carries:
|
|
254
|
+
* it never throws, it never blocks `listen`, and a healthy install is silent.
|
|
255
|
+
*
|
|
256
|
+
* @returns The inspection, or `null` when the check itself could not be carried
|
|
257
|
+
* out (which is reported as nothing at all).
|
|
258
|
+
*/
|
|
259
|
+
function runVapidSelfCheck(options = {}) {
|
|
260
|
+
const { env = process.env, warn = (message) => console.warn(message) } = options;
|
|
261
|
+
try {
|
|
262
|
+
const inspection = inspectVapidConfig(env);
|
|
263
|
+
for (const line of formatVapidReportLines(inspection)) {
|
|
264
|
+
warn(line);
|
|
265
|
+
}
|
|
266
|
+
return inspection;
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// A diagnostic must never be the reason a server fails to start.
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
14
273
|
/**
|
|
15
274
|
* Returns the VAPID config, or null when push is not configured (both public
|
|
16
275
|
* and private keys must be present). Read from env on every call.
|
|
17
276
|
*/
|
|
18
277
|
function getVapidConfig() {
|
|
19
|
-
const publicKey = process.env.
|
|
20
|
-
const privateKey = process.env.
|
|
278
|
+
const publicKey = process.env[exports.VAPID_ENV_KEYS.publicKey]?.trim();
|
|
279
|
+
const privateKey = process.env[exports.VAPID_ENV_KEYS.privateKey]?.trim();
|
|
21
280
|
if (!publicKey || !privateKey) {
|
|
22
281
|
return null;
|
|
23
282
|
}
|
|
24
|
-
const subject = process.env.
|
|
283
|
+
const subject = process.env[exports.VAPID_ENV_KEYS.subject]?.trim() || exports.VAPID_DEFAULT_SUBJECT;
|
|
25
284
|
return { publicKey, privateKey, subject };
|
|
26
285
|
}
|
|
27
286
|
/** True when both VAPID keys are configured. */
|
|
@@ -152,6 +152,13 @@ function handleWaitingTransition(transition) {
|
|
|
152
152
|
// way #1790 already does for the opening one. Fire-and-forget: the notifier
|
|
153
153
|
// never rejects, and the `void` keeps the synchronous listener contract
|
|
154
154
|
// `emit` relies on.
|
|
155
|
+
//
|
|
156
|
+
// Issue #2057: what reaches here is bounded by `waiting-episode-state`,
|
|
157
|
+
// which is in memory. A `waiting: false` poll on an instance this process
|
|
158
|
+
// never saw waiting emits nothing at all, so a wait that ended while the
|
|
159
|
+
// server was down produces no closing edge and no resolution — durable card
|
|
160
|
+
// marks do not change that, and it is the limitation §6.2 of the design
|
|
161
|
+
// note records rather than one this module can close.
|
|
155
162
|
void (0, resolution_push_notifier_1.notifyPromptResolved)({
|
|
156
163
|
worktreeId: transition.worktreeId,
|
|
157
164
|
agentName: transition.instanceId ?? transition.cliToolId,
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Startup self-check: does the URL we tell users to open actually reach US?
|
|
4
|
+
* Issue #2113
|
|
5
|
+
*
|
|
6
|
+
* CommandMate binds IPv4 `127.0.0.1` by default (server.ts, `CM_BIND`), but every
|
|
7
|
+
* setup guide sends the user to `http://localhost:<port>`. On macOS `localhost`
|
|
8
|
+
* resolves `::1` (IPv6) BEFORE `127.0.0.1`, and a `0.0.0.0`/`::` bind of ours never
|
|
9
|
+
* covers `::1` either — so an unrelated process holding `::1:<port>` silently owns
|
|
10
|
+
* the address the docs advertise. The browser then talks to that process while
|
|
11
|
+
* CommandMate keeps reporting a healthy `> Ready on http://127.0.0.1:<port>`.
|
|
12
|
+
*
|
|
13
|
+
* Measured 2026-08-27 on develop 54e122a9: `127.0.0.1:3000` answered in 14ms while
|
|
14
|
+
* `localhost:3000` and `[::1]:3000` both timed out after 10s against a stray Next.js
|
|
15
|
+
* dev server. Because the squatter was also Next.js, the browser pulled chunks from
|
|
16
|
+
* the WRONG app and rendered CommandMate's own `error.chunkReload.title`
|
|
17
|
+
* ("Updating to the latest version") — an error screen that looks like ours while
|
|
18
|
+
* not being served by us at all.
|
|
19
|
+
*
|
|
20
|
+
* HOW IDENTITY IS DECIDED (the part that has to be exact):
|
|
21
|
+
*
|
|
22
|
+
* The probe sends a GET to `<protocol>://localhost:<port>/api/auth/status` carrying a
|
|
23
|
+
* one-shot random nonce in `x-cm-self-check`, and our own HTTP server carries a
|
|
24
|
+
* temporary `prependListener('request')` that watches for that nonce. The verdict comes
|
|
25
|
+
* from OUR OWN OBSERVATION of the request, never from trusting the response body:
|
|
26
|
+
*
|
|
27
|
+
* observed the nonce -> 'self' (the advertised URL reaches us)
|
|
28
|
+
* got an HTTP response, no nonce-> 'foreign' (something else answered) <- WARN
|
|
29
|
+
* connection error / timeout -> 'unreachable' (nothing there; browsers fall
|
|
30
|
+
* through to 127.0.0.1) <- silent
|
|
31
|
+
*
|
|
32
|
+
* `/api/auth/status` is deliberately an EXISTING endpoint (it is in
|
|
33
|
+
* AUTH_EXCLUDED_PATHS, touches no DB and mutates nothing), so no diagnostic route had
|
|
34
|
+
* to be added. Nothing in the verdict depends on what it returns, which is why the
|
|
35
|
+
* check still works with auth on, with an IP ACL that would 403 us, and against an
|
|
36
|
+
* HTTPS server with a self-signed certificate.
|
|
37
|
+
*
|
|
38
|
+
* FAIL-OPEN IS THE CONTRACT. Nothing here throws, nothing here blocks `listen`, and
|
|
39
|
+
* only the 'foreign' verdict produces output. 'unreachable' is deliberately silent:
|
|
40
|
+
* an empty `::1` is the NORMAL case on a machine where nothing squats the port, and
|
|
41
|
+
* Node's Happy Eyeballs (and every browser) then falls through to `127.0.0.1`.
|
|
42
|
+
*
|
|
43
|
+
* @module lib/server/localhost-self-check
|
|
44
|
+
*/
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.SELF_CHECK_FILE_PREFIX = exports.SELF_CHECK_DIR_NAME = exports.SELF_CHECK_TIMEOUT_MS = exports.SELF_CHECK_HOSTNAME = exports.SELF_CHECK_PATH = exports.SELF_CHECK_HEADER = void 0;
|
|
47
|
+
exports.probeLocalhostIdentity = probeLocalhostIdentity;
|
|
48
|
+
exports.formatBoundUrl = formatBoundUrl;
|
|
49
|
+
exports.formatLocalhostConflictWarning = formatLocalhostConflictWarning;
|
|
50
|
+
exports.getSelfCheckDir = getSelfCheckDir;
|
|
51
|
+
exports.getSelfCheckStatePath = getSelfCheckStatePath;
|
|
52
|
+
exports.writeLocalhostConflict = writeLocalhostConflict;
|
|
53
|
+
exports.readLocalhostConflict = readLocalhostConflict;
|
|
54
|
+
exports.clearLocalhostConflict = clearLocalhostConflict;
|
|
55
|
+
exports.runLocalhostSelfCheck = runLocalhostSelfCheck;
|
|
56
|
+
const http_1 = require("http");
|
|
57
|
+
const https_1 = require("https");
|
|
58
|
+
const crypto_1 = require("crypto");
|
|
59
|
+
const fs_1 = require("fs");
|
|
60
|
+
const path_1 = require("path");
|
|
61
|
+
// Relative, NOT `@/cli/utils/...`: this module is pulled into the CLI program by
|
|
62
|
+
// src/cli/commands/status.ts, and tsconfig.cli.json resets `paths` to {} — an alias
|
|
63
|
+
// import here would break `npm run build:cli`. Same reason as version-probes.ts.
|
|
64
|
+
const install_context_1 = require("../../cli/utils/install-context");
|
|
65
|
+
/** Header the probe request carries its nonce in */
|
|
66
|
+
exports.SELF_CHECK_HEADER = 'x-cm-self-check';
|
|
67
|
+
/**
|
|
68
|
+
* Endpoint the probe targets. Existing route, in AUTH_EXCLUDED_PATHS
|
|
69
|
+
* (src/config/auth-config.ts), no DB access, no side effects.
|
|
70
|
+
*/
|
|
71
|
+
exports.SELF_CHECK_PATH = '/api/auth/status';
|
|
72
|
+
/** Hostname the docs advertise, and therefore the one under test */
|
|
73
|
+
exports.SELF_CHECK_HOSTNAME = 'localhost';
|
|
74
|
+
/** How long to wait for either the nonce observation or a response */
|
|
75
|
+
exports.SELF_CHECK_TIMEOUT_MS = 3000;
|
|
76
|
+
/**
|
|
77
|
+
* Directory (under the config dir) the conflict records live in.
|
|
78
|
+
*
|
|
79
|
+
* `logs/` and not a dedicated `self-check/`: in a local install `getConfigDir()` is the
|
|
80
|
+
* repository checkout itself, and `.gitignore` already ignores `logs/` there (it does
|
|
81
|
+
* the same for `data/`, `skills/`, `temp/` — "service-owned runtime state lands at the
|
|
82
|
+
* repo root"). A new top-level directory would show up as an untracked change in the
|
|
83
|
+
* user's own repository, which for a worktree manager means dirtying a repo it also
|
|
84
|
+
* displays. The record is diagnostic output keyed by port, so `logs/` fits it anyway.
|
|
85
|
+
*/
|
|
86
|
+
exports.SELF_CHECK_DIR_NAME = 'logs';
|
|
87
|
+
/** Filename prefix of a conflict record inside {@link SELF_CHECK_DIR_NAME} */
|
|
88
|
+
exports.SELF_CHECK_FILE_PREFIX = 'self-check-';
|
|
89
|
+
/**
|
|
90
|
+
* Ask "if a user opens the URL we advertise, do they reach this process?".
|
|
91
|
+
*
|
|
92
|
+
* Resolves as soon as the answer is known — the nonce observation fires on our
|
|
93
|
+
* server's `request` event, i.e. when headers arrive, so a 'self' verdict does not
|
|
94
|
+
* wait for Next.js to render or compile the route.
|
|
95
|
+
*
|
|
96
|
+
* Never rejects.
|
|
97
|
+
*/
|
|
98
|
+
async function probeLocalhostIdentity(options) {
|
|
99
|
+
const { server, port, protocol = 'http', host = exports.SELF_CHECK_HOSTNAME, path = exports.SELF_CHECK_PATH, timeoutMs = exports.SELF_CHECK_TIMEOUT_MS, } = options;
|
|
100
|
+
const nonce = options.nonce ?? (0, crypto_1.randomBytes)(16).toString('hex');
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
let settled = false;
|
|
103
|
+
let observed = false;
|
|
104
|
+
let timer = null;
|
|
105
|
+
// Prepended so we read the header before server.ts's own request handler can
|
|
106
|
+
// rewrite anything on it.
|
|
107
|
+
const listener = (req) => {
|
|
108
|
+
const seen = req?.headers?.[exports.SELF_CHECK_HEADER];
|
|
109
|
+
const value = Array.isArray(seen) ? seen[0] : seen;
|
|
110
|
+
if (value === nonce) {
|
|
111
|
+
observed = true;
|
|
112
|
+
settle('self');
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const settle = (verdict) => {
|
|
116
|
+
if (settled)
|
|
117
|
+
return;
|
|
118
|
+
settled = true;
|
|
119
|
+
if (timer !== null)
|
|
120
|
+
clearTimeout(timer);
|
|
121
|
+
try {
|
|
122
|
+
server.removeListener('request', listener);
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// A server that cannot detach a listener is still not a reason to fail startup.
|
|
126
|
+
}
|
|
127
|
+
resolve(verdict);
|
|
128
|
+
};
|
|
129
|
+
try {
|
|
130
|
+
server.prependListener('request', listener);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// Without the observer there is no way to tell 'self' from 'foreign'; declaring
|
|
134
|
+
// 'foreign' here would warn on a perfectly healthy machine.
|
|
135
|
+
resolve('unreachable');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
timer = setTimeout(() => settle(observed ? 'self' : 'unreachable'), timeoutMs);
|
|
139
|
+
let req;
|
|
140
|
+
try {
|
|
141
|
+
const send = protocol === 'https' ? https_1.request : http_1.request;
|
|
142
|
+
req = send({
|
|
143
|
+
host,
|
|
144
|
+
port,
|
|
145
|
+
path,
|
|
146
|
+
method: 'GET',
|
|
147
|
+
headers: {
|
|
148
|
+
[exports.SELF_CHECK_HEADER]: nonce,
|
|
149
|
+
'user-agent': 'commandmate-self-check',
|
|
150
|
+
},
|
|
151
|
+
// A self-signed certificate is the documented local HTTPS setup
|
|
152
|
+
// (`mkcert localhost`, see `commandmate start --cert`), so verifying here
|
|
153
|
+
// would turn every such install's check into a silent 'unreachable'.
|
|
154
|
+
// Skipping verification is safe HERE and only here: the verdict comes from
|
|
155
|
+
// our own in-process observation rather than from trusting the peer, the
|
|
156
|
+
// request carries no credentials, and its only payload is a random nonce
|
|
157
|
+
// that means nothing to anyone else. NODE_TLS_REJECT_UNAUTHORIZED is never
|
|
158
|
+
// touched — this is scoped to this one request.
|
|
159
|
+
...(protocol === 'https' ? { rejectUnauthorized: false } : {}),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
settle(observed ? 'self' : 'unreachable');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
req.setTimeout(timeoutMs, () => {
|
|
167
|
+
req.destroy();
|
|
168
|
+
});
|
|
169
|
+
req.on('response', (res) => {
|
|
170
|
+
// Drain so the socket can close; the body is never inspected.
|
|
171
|
+
res.resume();
|
|
172
|
+
settle(observed ? 'self' : 'foreign');
|
|
173
|
+
});
|
|
174
|
+
req.on('error', () => {
|
|
175
|
+
settle(observed ? 'self' : 'unreachable');
|
|
176
|
+
});
|
|
177
|
+
try {
|
|
178
|
+
req.end();
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
settle(observed ? 'self' : 'unreachable');
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Bracket a bare IPv6 literal so the result is a URL a user can paste. `localhost` and
|
|
187
|
+
* dotted-quad hosts pass through untouched.
|
|
188
|
+
*/
|
|
189
|
+
function formatHostForUrl(host) {
|
|
190
|
+
return host.includes(':') && !host.startsWith('[') ? `[${host}]` : host;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Build the dialable URL for a bind address, matching resolveServerEndpoint()'s rule
|
|
194
|
+
* that a wildcard bind is reported as 127.0.0.1.
|
|
195
|
+
*/
|
|
196
|
+
function formatBoundUrl(protocol, bind, port) {
|
|
197
|
+
const host = bind === '0.0.0.0' ? '127.0.0.1' : bind;
|
|
198
|
+
return `${protocol}://${formatHostForUrl(host)}:${port}`;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* The warning, as lines, shared by the startup log and `commandmate status` so the two
|
|
202
|
+
* can never drift apart.
|
|
203
|
+
*/
|
|
204
|
+
function formatLocalhostConflictWarning(record) {
|
|
205
|
+
return [
|
|
206
|
+
`Another process is answering on ${record.probedUrl} — it is NOT this CommandMate server.`,
|
|
207
|
+
` CommandMate is listening on ${record.boundUrl} (CM_BIND=${record.bind}).`,
|
|
208
|
+
` "localhost" can resolve to ::1 (IPv6) first, and ${record.bind} does not cover ::1,`,
|
|
209
|
+
' so a browser opening the localhost URL reaches the other process instead.',
|
|
210
|
+
` Open ${record.boundUrl} instead, or free the port:`,
|
|
211
|
+
` lsof -nP -iTCP:${record.port} -sTCP:LISTEN`,
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
/** Directory holding the per-port conflict records */
|
|
215
|
+
function getSelfCheckDir() {
|
|
216
|
+
return (0, path_1.join)((0, install_context_1.getConfigDir)(), exports.SELF_CHECK_DIR_NAME);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Path of the record for one port (`<configDir>/logs/self-check-<port>.json`).
|
|
220
|
+
*
|
|
221
|
+
* @throws Error when the port is not a plausible TCP port — the value becomes a
|
|
222
|
+
* filename, so it is validated rather than interpolated blindly.
|
|
223
|
+
*/
|
|
224
|
+
function getSelfCheckStatePath(port) {
|
|
225
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
226
|
+
throw new Error(`Invalid port for self-check state path: ${String(port)}`);
|
|
227
|
+
}
|
|
228
|
+
return (0, path_1.join)(getSelfCheckDir(), `${exports.SELF_CHECK_FILE_PREFIX}${port}.json`);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Persist a conflict for `commandmate status` to read.
|
|
232
|
+
*
|
|
233
|
+
* @returns true when the record was written
|
|
234
|
+
*/
|
|
235
|
+
function writeLocalhostConflict(record) {
|
|
236
|
+
try {
|
|
237
|
+
const dir = getSelfCheckDir();
|
|
238
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
239
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true, mode: 0o700 });
|
|
240
|
+
}
|
|
241
|
+
(0, fs_1.writeFileSync)(getSelfCheckStatePath(record.port), `${JSON.stringify(record)}\n`, {
|
|
242
|
+
mode: 0o600,
|
|
243
|
+
});
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Read the conflict recorded for a port.
|
|
252
|
+
*
|
|
253
|
+
* Never throws: `status` must keep working on an unreadable, truncated or
|
|
254
|
+
* hand-edited record, and on a machine where the config dir cannot be resolved at all.
|
|
255
|
+
*
|
|
256
|
+
* @returns The record, or null when there is none (or it is unusable)
|
|
257
|
+
*/
|
|
258
|
+
function readLocalhostConflict(port) {
|
|
259
|
+
try {
|
|
260
|
+
const statePath = getSelfCheckStatePath(port);
|
|
261
|
+
if (!(0, fs_1.existsSync)(statePath)) {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
const parsed = JSON.parse((0, fs_1.readFileSync)(statePath, 'utf-8'));
|
|
265
|
+
return isConflictRecord(parsed) && parsed.port === port ? parsed : null;
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Drop the record for a port. Called on every clean self-check and on shutdown, so a
|
|
273
|
+
* fixed environment stops warning on the next start rather than needing a manual sweep.
|
|
274
|
+
*/
|
|
275
|
+
function clearLocalhostConflict(port) {
|
|
276
|
+
try {
|
|
277
|
+
const statePath = getSelfCheckStatePath(port);
|
|
278
|
+
if ((0, fs_1.existsSync)(statePath)) {
|
|
279
|
+
(0, fs_1.unlinkSync)(statePath);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// Best effort: a stale record is guarded by the PID comparison in `status`.
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/** Structural check for a record read back off disk */
|
|
287
|
+
function isConflictRecord(value) {
|
|
288
|
+
if (typeof value !== 'object' || value === null)
|
|
289
|
+
return false;
|
|
290
|
+
const r = value;
|
|
291
|
+
return (typeof r.port === 'number' &&
|
|
292
|
+
typeof r.pid === 'number' &&
|
|
293
|
+
typeof r.bind === 'string' &&
|
|
294
|
+
typeof r.boundUrl === 'string' &&
|
|
295
|
+
typeof r.probedUrl === 'string' &&
|
|
296
|
+
typeof r.detectedAt === 'string');
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Run the startup self-check and route its verdict to the log and the status file.
|
|
300
|
+
*
|
|
301
|
+
* Fail-open by construction: every path is wrapped, the function never rejects, and the
|
|
302
|
+
* caller in server.ts does not await it. A `null` return means the check could not be
|
|
303
|
+
* carried out at all — which is reported as nothing, exactly like 'unreachable'.
|
|
304
|
+
*
|
|
305
|
+
* @returns The verdict, or null when the check itself failed
|
|
306
|
+
*/
|
|
307
|
+
async function runLocalhostSelfCheck(options) {
|
|
308
|
+
const { server, port, bind, protocol = 'http', host = exports.SELF_CHECK_HOSTNAME, timeoutMs = exports.SELF_CHECK_TIMEOUT_MS, pid = process.pid, now = () => new Date(), warn = (message) => console.warn(message), probe = probeLocalhostIdentity, } = options;
|
|
309
|
+
try {
|
|
310
|
+
const verdict = await probe({ server, port, protocol, host, timeoutMs });
|
|
311
|
+
if (verdict !== 'foreign') {
|
|
312
|
+
clearLocalhostConflict(port);
|
|
313
|
+
return verdict;
|
|
314
|
+
}
|
|
315
|
+
const record = {
|
|
316
|
+
port,
|
|
317
|
+
pid,
|
|
318
|
+
bind,
|
|
319
|
+
boundUrl: formatBoundUrl(protocol, bind, port),
|
|
320
|
+
probedUrl: `${protocol}://${formatHostForUrl(host)}:${port}`,
|
|
321
|
+
detectedAt: now().toISOString(),
|
|
322
|
+
};
|
|
323
|
+
writeLocalhostConflict(record);
|
|
324
|
+
for (const line of formatLocalhostConflictWarning(record)) {
|
|
325
|
+
warn(line);
|
|
326
|
+
}
|
|
327
|
+
return verdict;
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// A diagnostic must never be the reason a server is considered unhealthy.
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|