commandmate 0.28.0 → 0.29.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +404 -397
- package/.next/app-path-routes-manifest.json +26 -25
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +12 -12
- package/.next/react-loadable-manifest.json +0 -6
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route.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.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.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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route.js +2 -0
- package/.next/server/app/api/remote/pair/route.js.nft.json +1 -0
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/files/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/create/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branch/delete/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/branches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/checkout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/commit/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/fetch/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/log/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/pull/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/staged/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/[index]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/apply/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/pop/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/push/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/stash/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +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.js +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +9 -9
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +26 -25
- package/.next/server/chunks/1162.js +1 -1
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2759.js +1 -1
- package/.next/server/chunks/3440.js +1 -1
- package/.next/server/chunks/3543.js +1 -1
- package/.next/server/chunks/3945.js +1 -1
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/880.js +6 -6
- package/.next/server/chunks/9123.js +2 -2
- package/.next/server/chunks/9938.js +1 -1
- package/.next/server/functions-config-manifest.json +3 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/src/middleware.js +1 -1
- package/.next/server/src/middleware.js.map +1 -1
- package/.next/static/Dvfs4ZThl5vBhJGP-ZQuJ/_buildManifest.js +1 -0
- package/.next/static/chunks/5229-580b581fce5aeb52.js +1 -0
- package/.next/static/chunks/6381-9a929249196a0e77.js +1 -0
- package/.next/static/chunks/app/api/app/update/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/app/update-check/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/conversation/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/current-output/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/messages/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/session/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/start/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/terminal/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/assistant/tools/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/auth/login/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/auth/logout/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/auth/status/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/capabilities/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/daily-summary/status/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/external-apps/[id]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/external-apps/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/fs/browse/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/fs/recent-paths/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/hooks/agent-event/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/hooks/claude-done/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/hooks/permission-request/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/metrics/vibe/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/ollama/models/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/push/escalation/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/push/subscriptions/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/push/vapid/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/remote/pair/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/clone/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/excluded/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/restore/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/scan/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/sync/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/repositories/validate-path/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/sidebar/group-order/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/skills/[id]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/skills/installations/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/skills/operations/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/skills/reindex/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/skills/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/slash-commands/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/tasks/[taskId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/templates/[id]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/templates/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/todos/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/verification/runs/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/api/worktrees/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/login/page-03659dded846ef1d.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/proxy/[...path]/route-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/layout-e3626364434d521b.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-817378dd7c580774.js +1 -0
- package/.next/static/chunks/webpack-7e79064bfce988d7.js +1 -0
- package/.next/static/css/6266bde3bce465a2.css +1 -0
- package/.next/trace +13 -13
- package/.next/types/app/api/remote/pair/route.ts +347 -0
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/README.md +15 -3
- package/dist/cli/commands/remote.d.ts +248 -0
- package/dist/cli/commands/remote.d.ts.map +1 -0
- package/dist/cli/commands/remote.js +849 -0
- package/dist/cli/config/security-messages.d.ts +25 -0
- package/dist/cli/config/security-messages.d.ts.map +1 -1
- package/dist/cli/config/security-messages.js +43 -1
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +6 -0
- package/dist/cli/types/index.d.ts +20 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/qr-terminal.d.ts +54 -0
- package/dist/cli/utils/qr-terminal.d.ts.map +1 -0
- package/dist/cli/utils/qr-terminal.js +181 -0
- package/dist/cli/utils/remote-state.d.ts +123 -0
- package/dist/cli/utils/remote-state.d.ts.map +1 -0
- package/dist/cli/utils/remote-state.js +193 -0
- package/dist/config/auth-config.d.ts +1 -1
- package/dist/config/auth-config.d.ts.map +1 -1
- package/dist/config/auth-config.js +5 -0
- package/dist/lib/remote/cloudflare.d.ts +285 -0
- package/dist/lib/remote/cloudflare.d.ts.map +1 -0
- package/dist/lib/remote/cloudflare.js +619 -0
- package/dist/lib/remote/index.d.ts +17 -0
- package/dist/lib/remote/index.d.ts.map +1 -0
- package/dist/lib/remote/index.js +64 -0
- package/dist/lib/remote/provider-registry.d.ts +29 -0
- package/dist/lib/remote/provider-registry.d.ts.map +1 -0
- package/dist/lib/remote/provider-registry.js +73 -0
- package/dist/lib/remote/tailscale.d.ts +268 -0
- package/dist/lib/remote/tailscale.d.ts.map +1 -0
- package/dist/lib/remote/tailscale.js +546 -0
- package/dist/lib/remote/types.d.ts +127 -0
- package/dist/lib/remote/types.d.ts.map +1 -0
- package/dist/lib/remote/types.js +53 -0
- package/dist/lib/security/pairing-code.d.ts +182 -0
- package/dist/lib/security/pairing-code.d.ts.map +1 -0
- package/dist/lib/security/pairing-code.js +265 -0
- package/dist/server/src/config/auth-config.js +5 -0
- package/package.json +2 -1
- package/.next/static/0GHE2JGlFzqvSBZAcBFSt/_buildManifest.js +0 -1
- package/.next/static/chunks/5229-1f5f19740a8d6c11.js +0 -1
- package/.next/static/chunks/6271.295ced91b6335f18.js +0 -1
- package/.next/static/chunks/6381-d921ab728eda1191.js +0 -1
- package/.next/static/chunks/app/api/app/update/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/app/update-check/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/conversation/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/current-output/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/messages/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/session/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/start/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/terminal/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/assistant/tools/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/auth/login/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/auth/logout/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/auth/status/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/capabilities/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/daily-summary/status/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/health/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/external-apps/[id]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/external-apps/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/fs/browse/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/fs/recent-paths/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/hooks/agent-event/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/hooks/claude-done/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/hooks/permission-request/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/metrics/vibe/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/ollama/models/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/push/escalation/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/push/subscriptions/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/push/vapid/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/[todoId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/[id]/todos/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/[jobId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/clone/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/excluded/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/restore/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/scan/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/sync/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/repositories/validate-path/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/sidebar/group-order/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/skills/[id]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/skills/installations/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/skills/operations/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/skills/reindex/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/skills/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/slash-commands/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/cancel/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/tasks/[taskId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/templates/[id]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/templates/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/todos/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/[runId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/verification/runs/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/auto-yes/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/capture/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/clear-composer/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cli-tool/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/cmate/schedules/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/current-output/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/env/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/[logId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/execution-logs/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/files/[...path]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/create/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branch/delete/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/branches/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/checkout/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/commit/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/diff/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/fetch/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/log/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/pull/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/push/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/reset/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/revert/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/show/[commitHash]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stage/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/staged/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/[index]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/apply/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/pop/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/push/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/stash/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/status/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/unstage/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/git/working-diff/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/instances/opencode/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/interrupt/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/kill-session/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/[filename]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/logs/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/marp-render/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/[memoId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/memos/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/messages/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/diff/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/session/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/opencode/share/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/prompt-response/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/resolve-target/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/respond/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/[scheduleId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/active/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/schedules/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/search/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/send/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/install/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/plan/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/[skillId]/update-plan/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/skills/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/slash-commands/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/special-keys/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/start-polling/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tasks/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/terminal/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/history/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/timers/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/[todoId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/todos/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/[...path]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/tree/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/upload/[...path]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/[runId]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/verify/runs/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/[id]/viewed/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/api/worktrees/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/login/page-adc51f0f7cbb7ac6.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/proxy/[...path]/route-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/layout-9247d6b9d647f750.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-27b7cb2e77099eec.js +0 -1
- package/.next/static/chunks/webpack-6a9668cf54a26eba.js +0 -1
- package/.next/static/css/98722bc4152cedcc.css +0 -1
- /package/.next/static/{0GHE2JGlFzqvSBZAcBFSt → Dvfs4ZThl5vBhJGP-ZQuJ}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider abstraction for `commandmate remote` (Issue #1937, R1).
|
|
4
|
+
*
|
|
5
|
+
* The shapes here are §6.1 of `docs/design/remote-qr-pairing-1937.md` verbatim.
|
|
6
|
+
* Two of them carry a structural guarantee rather than a convention, and both
|
|
7
|
+
* exist because a Provider can destroy configuration the user created and that
|
|
8
|
+
* CommandMate has no way to restore (§6.3):
|
|
9
|
+
*
|
|
10
|
+
* 1. `RemoteProvider` has no `reset()` / `cleanupAll()`. `stop()` takes a
|
|
11
|
+
* `RemoteHandle` and nothing else, so "read the Provider's whole config and
|
|
12
|
+
* tear it down" is not expressible in this type. A pinning test asserts the
|
|
13
|
+
* member list stays exactly `id` / `detect` / `start` / `stop`.
|
|
14
|
+
* 2. `start()` must return `preexisting`. `stop()` reverts only what is in
|
|
15
|
+
* `owned` and NOT in `preexisting`; anything in both is skipped and reported
|
|
16
|
+
* in `StopOutcome.skipped` so a human can see what was left alone.
|
|
17
|
+
*
|
|
18
|
+
* Choosing between Providers is deliberately NOT here. "Tailscale first, and do
|
|
19
|
+
* not silently fall back to a public tunnel" is a rule about selection, not a
|
|
20
|
+
* property of either Provider, so it lives in the orchestrator that will own
|
|
21
|
+
* `src/cli/commands/remote.ts` (R9). See `provider-registry.ts`.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.isPreexistingSnapshot = isPreexistingSnapshot;
|
|
25
|
+
exports.planStop = planStop;
|
|
26
|
+
/** Narrows `RemoteHandle.preexisting` to the shape the shared skip rule reads. */
|
|
27
|
+
function isPreexistingSnapshot(value) {
|
|
28
|
+
if (typeof value !== 'object' || value === null)
|
|
29
|
+
return false;
|
|
30
|
+
const keys = value.keys;
|
|
31
|
+
return Array.isArray(keys) && keys.every((key) => typeof key === 'string');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Splits a handle's owned revert entries into "safe to undo" and "leave alone".
|
|
35
|
+
*
|
|
36
|
+
* This is the single implementation of §6.3-2. Every Provider's `stop()` routes
|
|
37
|
+
* through it so the rule cannot drift between Providers, and so the rule can be
|
|
38
|
+
* tested once instead of once per Provider.
|
|
39
|
+
*/
|
|
40
|
+
function planStop(handle) {
|
|
41
|
+
const owned = handle.owned.revert ?? {};
|
|
42
|
+
const protectedKeys = new Set(isPreexistingSnapshot(handle.preexisting) ? handle.preexisting.keys : []);
|
|
43
|
+
const revert = {};
|
|
44
|
+
const skipped = [];
|
|
45
|
+
for (const key of Object.keys(owned)) {
|
|
46
|
+
if (protectedKeys.has(key)) {
|
|
47
|
+
skipped.push(key);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
revert[key] = owned[key];
|
|
51
|
+
}
|
|
52
|
+
return { revert, skipped: skipped.sort() };
|
|
53
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pairing code lifecycle for `commandmate remote` (Issue #1937, R5)
|
|
3
|
+
*
|
|
4
|
+
* Design: docs/design/remote-qr-pairing-1937.md §7
|
|
5
|
+
*
|
|
6
|
+
* CONSTRAINTS:
|
|
7
|
+
* - NODE RUNTIME ONLY. This module touches `fs` and `crypto`; the Edge Runtime
|
|
8
|
+
* (`src/middleware.ts`) must never import it. Pairing is an excluded path, so
|
|
9
|
+
* middleware never needs to.
|
|
10
|
+
* - No Next.js imports, so `src/cli/**` can pull it in for `commandmate remote`
|
|
11
|
+
* under `tsconfig.cli.json` (which declares `"paths": {}` — relative imports
|
|
12
|
+
* only, never `@/...`).
|
|
13
|
+
*
|
|
14
|
+
* WHY A FILE AND NOT AN ENVIRONMENT VARIABLE (§7.2)
|
|
15
|
+
* -------------------------------------------------
|
|
16
|
+
* The cookie has to carry the *plaintext* long-lived token, so the server must
|
|
17
|
+
* know it. The obvious route — put it in the server's startup env — is rejected:
|
|
18
|
+
* `src/lib/tmux/**` passes no `env:` to the panes it spawns, so a pane inherits
|
|
19
|
+
* the server's environment wholesale, and `sanitizeEnvForChildProcess()` is
|
|
20
|
+
* called in only two places that an agent pane does not go through. An env var
|
|
21
|
+
* would therefore be readable by the very Claude / Codex / OpenCode processes
|
|
22
|
+
* CommandMate is driving.
|
|
23
|
+
*
|
|
24
|
+
* So the secret lands in one 0600 handoff file and only its *path* travels in
|
|
25
|
+
* `CM_REMOTE_PAIRING_FILE` (a path is not a secret). Two further consequences:
|
|
26
|
+
*
|
|
27
|
+
* - The consumed flag is THE ABSENCE OF THE FILE. A module-level variable
|
|
28
|
+
* cannot work here: `server.ts` and the Next route handler bundle are
|
|
29
|
+
* separate module instances, so state written by one is invisible to the
|
|
30
|
+
* other.
|
|
31
|
+
* - Deleting the file destroys the plaintext token at the moment of pairing,
|
|
32
|
+
* shrinking its window on disk to "remote start → first pairing".
|
|
33
|
+
*/
|
|
34
|
+
/** Env var carrying the handoff file PATH (never the secret itself). */
|
|
35
|
+
export declare const PAIRING_FILE_ENV_KEY = "CM_REMOTE_PAIRING_FILE";
|
|
36
|
+
/** File name inside the config directory (`~/.commandmate` for global installs). */
|
|
37
|
+
export declare const PAIRING_FILE_NAME = "remote-pairing.json";
|
|
38
|
+
/** Owner read/write only. Asserted by tests, not merely intended. */
|
|
39
|
+
export declare const PAIRING_FILE_MODE = 384;
|
|
40
|
+
/**
|
|
41
|
+
* Crockford Base32 (https://www.crockford.com/base32.html).
|
|
42
|
+
* `I`, `L`, `O` and `U` are absent so a transcribed code cannot be ambiguous.
|
|
43
|
+
*/
|
|
44
|
+
export declare const CROCKFORD_BASE32_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
45
|
+
/** Bits of entropy carried by a pairing code. */
|
|
46
|
+
export declare const PAIRING_CODE_BITS = 128;
|
|
47
|
+
/** ceil(128 / 5) — the encoded length of PAIRING_CODE_BITS. */
|
|
48
|
+
export declare const PAIRING_CODE_LENGTH = 26;
|
|
49
|
+
/** Default time-to-live for one pairing code (§7.4). */
|
|
50
|
+
export declare const DEFAULT_PAIRING_TTL_MS: number;
|
|
51
|
+
/**
|
|
52
|
+
* Input length cap for `POST /api/remote/pair`, copied from `/api/auth/login`'s
|
|
53
|
+
* 256-char cap so an oversized body cannot be used to burn CPU on hashing.
|
|
54
|
+
*/
|
|
55
|
+
export declare const MAX_PAIRING_CODE_LENGTH = 256;
|
|
56
|
+
/** On-disk shape of the handoff file. */
|
|
57
|
+
export interface PairingHandoff {
|
|
58
|
+
/** SHA-256 hex of the canonical pairing code. The code itself is never stored. */
|
|
59
|
+
pairingHash: string;
|
|
60
|
+
/** Epoch ms after which the code is dead. */
|
|
61
|
+
expiresAt: number;
|
|
62
|
+
/** Plaintext long-lived token that becomes the auth cookie value. */
|
|
63
|
+
sessionToken: string;
|
|
64
|
+
}
|
|
65
|
+
/** What `createPairingHandoff()` hands back to the caller (the `remote` command). */
|
|
66
|
+
export interface CreatedPairing {
|
|
67
|
+
/**
|
|
68
|
+
* Plaintext pairing code. NEVER persisted — the caller renders it as a QR
|
|
69
|
+
* code and drops it. Re-displaying it means running `remote` again.
|
|
70
|
+
*/
|
|
71
|
+
code: string;
|
|
72
|
+
/** Plaintext long-lived token (also written to the handoff file). */
|
|
73
|
+
sessionToken: string;
|
|
74
|
+
expiresAt: number;
|
|
75
|
+
filePath: string;
|
|
76
|
+
}
|
|
77
|
+
export interface CreatePairingHandoffOptions {
|
|
78
|
+
/** Defaults to `<configDir>/remote-pairing.json`. */
|
|
79
|
+
filePath?: string;
|
|
80
|
+
/** Defaults to {@link DEFAULT_PAIRING_TTL_MS}. */
|
|
81
|
+
ttlMs?: number;
|
|
82
|
+
/** Defaults to a fresh `generateToken()`. */
|
|
83
|
+
sessionToken?: string;
|
|
84
|
+
/** Injectable clock for tests. */
|
|
85
|
+
now?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Encode bytes as Crockford Base32, MSB first, no padding character.
|
|
89
|
+
*
|
|
90
|
+
* 16 bytes (128 bits) produce 26 characters: 25 characters consume 125 bits and
|
|
91
|
+
* the remaining 3 bits are left-shifted into the 26th.
|
|
92
|
+
*
|
|
93
|
+
* @param bytes - Raw bytes to encode
|
|
94
|
+
* @returns Crockford Base32 string
|
|
95
|
+
*/
|
|
96
|
+
export declare function encodeCrockfordBase32(bytes: Buffer): string;
|
|
97
|
+
/**
|
|
98
|
+
* Canonicalize a transcribed pairing code.
|
|
99
|
+
*
|
|
100
|
+
* This is the whole reason Crockford Base32 was picked over RFC 4648 Base32:
|
|
101
|
+
* `i`/`l` are accepted as `1`, `o` as `0`, case is irrelevant, and grouping
|
|
102
|
+
* spaces or hyphens a human inserted are dropped. `generatePairingCode()`
|
|
103
|
+
* already emits the canonical form, so `normalize(generate()) === generate()`
|
|
104
|
+
* and the QR path is unaffected.
|
|
105
|
+
*
|
|
106
|
+
* @param code - Raw user/QR supplied code
|
|
107
|
+
* @returns Canonical uppercase form used for hashing
|
|
108
|
+
*/
|
|
109
|
+
export declare function normalizePairingCode(code: string): string;
|
|
110
|
+
/**
|
|
111
|
+
* Generate a pairing code carrying {@link PAIRING_CODE_BITS} bits of entropy.
|
|
112
|
+
*
|
|
113
|
+
* Reuses `generateToken()` (32 random bytes as hex) rather than calling
|
|
114
|
+
* `randomBytes` again, and keeps the leading 128 bits: at a 10-minute TTL,
|
|
115
|
+
* single use and a rate limit, 128 bits is already extravagant, and a 26-char
|
|
116
|
+
* code keeps the QR small enough to scan from a laptop screen.
|
|
117
|
+
*
|
|
118
|
+
* @returns 26-character Crockford Base32 code
|
|
119
|
+
*/
|
|
120
|
+
export declare function generatePairingCode(): string;
|
|
121
|
+
/**
|
|
122
|
+
* Absolute path of the default handoff file.
|
|
123
|
+
*
|
|
124
|
+
* @returns `<configDir>/remote-pairing.json`
|
|
125
|
+
*/
|
|
126
|
+
export declare function getDefaultPairingFilePath(): string;
|
|
127
|
+
/**
|
|
128
|
+
* Read the handoff file path out of the environment.
|
|
129
|
+
*
|
|
130
|
+
* @returns The path, or null when `remote` is not running (route answers 404)
|
|
131
|
+
*/
|
|
132
|
+
export declare function getPairingFilePathFromEnv(): string | null;
|
|
133
|
+
/**
|
|
134
|
+
* Write the handoff file with mode 0600.
|
|
135
|
+
*
|
|
136
|
+
* An existing file is unlinked first: `writeFileSync`'s `mode` is only honoured
|
|
137
|
+
* when the file is created, so writing over a stale world-readable file would
|
|
138
|
+
* silently keep the old permissions. `chmodSync` afterwards closes the umask
|
|
139
|
+
* gap for good measure.
|
|
140
|
+
*
|
|
141
|
+
* @param filePath - Absolute path of the handoff file
|
|
142
|
+
* @param handoff - Hash, expiry and plaintext session token
|
|
143
|
+
*/
|
|
144
|
+
export declare function writePairingHandoff(filePath: string, handoff: PairingHandoff): void;
|
|
145
|
+
/**
|
|
146
|
+
* Mint a pairing code plus its handoff file in one step.
|
|
147
|
+
*
|
|
148
|
+
* @param options - Overrides for path, TTL, session token and clock
|
|
149
|
+
* @returns The plaintext code and token, which the caller must not persist
|
|
150
|
+
*/
|
|
151
|
+
export declare function createPairingHandoff(options?: CreatePairingHandoffOptions): CreatedPairing;
|
|
152
|
+
/**
|
|
153
|
+
* Read and validate the handoff file.
|
|
154
|
+
*
|
|
155
|
+
* Missing and malformed are deliberately the same answer: the caller turns both
|
|
156
|
+
* into 410 Gone, and "already consumed" arrives here as ENOENT.
|
|
157
|
+
*
|
|
158
|
+
* @param filePath - Absolute path of the handoff file
|
|
159
|
+
* @returns The handoff, or null when it is absent or unusable
|
|
160
|
+
*/
|
|
161
|
+
export declare function readPairingHandoff(filePath: string): PairingHandoff | null;
|
|
162
|
+
/**
|
|
163
|
+
* Delete the handoff file. Idempotent — a missing file is success.
|
|
164
|
+
*
|
|
165
|
+
* @param filePath - Absolute path of the handoff file
|
|
166
|
+
*/
|
|
167
|
+
export declare function consumePairingHandoff(filePath: string): void;
|
|
168
|
+
/**
|
|
169
|
+
* @param handoff - Handoff read from disk
|
|
170
|
+
* @param now - Epoch ms, injectable for tests
|
|
171
|
+
* @returns true when the pairing window has closed
|
|
172
|
+
*/
|
|
173
|
+
export declare function isPairingExpired(handoff: PairingHandoff, now?: number): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Timing-safe comparison of a supplied code against the stored hash (S001).
|
|
176
|
+
*
|
|
177
|
+
* @param code - Code as supplied by the client
|
|
178
|
+
* @param pairingHash - SHA-256 hex from the handoff file
|
|
179
|
+
* @returns true when the code matches
|
|
180
|
+
*/
|
|
181
|
+
export declare function verifyPairingCode(code: string, pairingHash: string): boolean;
|
|
182
|
+
//# sourceMappingURL=pairing-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairing-code.d.ts","sourceRoot":"","sources":["../../../src/lib/security/pairing-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAUH,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,2BAA2B,CAAC;AAE7D,oFAAoF;AACpF,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,MAAQ,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,yBAAyB,qCAAqC,CAAC;AAE5E,iDAAiD;AACjD,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,wDAAwD;AACxD,eAAO,MAAM,sBAAsB,QAAiB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,kFAAkF;IAClF,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qFAAqF;AACrF,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,2BAA2B;IAC1C,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmB3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAGzD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CASnF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAAgC,GAAG,cAAc,CAU9F;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CA0B1E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAE3F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAgB5E"}
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pairing code lifecycle for `commandmate remote` (Issue #1937, R5)
|
|
4
|
+
*
|
|
5
|
+
* Design: docs/design/remote-qr-pairing-1937.md §7
|
|
6
|
+
*
|
|
7
|
+
* CONSTRAINTS:
|
|
8
|
+
* - NODE RUNTIME ONLY. This module touches `fs` and `crypto`; the Edge Runtime
|
|
9
|
+
* (`src/middleware.ts`) must never import it. Pairing is an excluded path, so
|
|
10
|
+
* middleware never needs to.
|
|
11
|
+
* - No Next.js imports, so `src/cli/**` can pull it in for `commandmate remote`
|
|
12
|
+
* under `tsconfig.cli.json` (which declares `"paths": {}` — relative imports
|
|
13
|
+
* only, never `@/...`).
|
|
14
|
+
*
|
|
15
|
+
* WHY A FILE AND NOT AN ENVIRONMENT VARIABLE (§7.2)
|
|
16
|
+
* -------------------------------------------------
|
|
17
|
+
* The cookie has to carry the *plaintext* long-lived token, so the server must
|
|
18
|
+
* know it. The obvious route — put it in the server's startup env — is rejected:
|
|
19
|
+
* `src/lib/tmux/**` passes no `env:` to the panes it spawns, so a pane inherits
|
|
20
|
+
* the server's environment wholesale, and `sanitizeEnvForChildProcess()` is
|
|
21
|
+
* called in only two places that an agent pane does not go through. An env var
|
|
22
|
+
* would therefore be readable by the very Claude / Codex / OpenCode processes
|
|
23
|
+
* CommandMate is driving.
|
|
24
|
+
*
|
|
25
|
+
* So the secret lands in one 0600 handoff file and only its *path* travels in
|
|
26
|
+
* `CM_REMOTE_PAIRING_FILE` (a path is not a secret). Two further consequences:
|
|
27
|
+
*
|
|
28
|
+
* - The consumed flag is THE ABSENCE OF THE FILE. A module-level variable
|
|
29
|
+
* cannot work here: `server.ts` and the Next route handler bundle are
|
|
30
|
+
* separate module instances, so state written by one is invisible to the
|
|
31
|
+
* other.
|
|
32
|
+
* - Deleting the file destroys the plaintext token at the moment of pairing,
|
|
33
|
+
* shrinking its window on disk to "remote start → first pairing".
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MAX_PAIRING_CODE_LENGTH = exports.DEFAULT_PAIRING_TTL_MS = exports.PAIRING_CODE_LENGTH = exports.PAIRING_CODE_BITS = exports.CROCKFORD_BASE32_ALPHABET = exports.PAIRING_FILE_MODE = exports.PAIRING_FILE_NAME = exports.PAIRING_FILE_ENV_KEY = void 0;
|
|
37
|
+
exports.encodeCrockfordBase32 = encodeCrockfordBase32;
|
|
38
|
+
exports.normalizePairingCode = normalizePairingCode;
|
|
39
|
+
exports.generatePairingCode = generatePairingCode;
|
|
40
|
+
exports.getDefaultPairingFilePath = getDefaultPairingFilePath;
|
|
41
|
+
exports.getPairingFilePathFromEnv = getPairingFilePathFromEnv;
|
|
42
|
+
exports.writePairingHandoff = writePairingHandoff;
|
|
43
|
+
exports.createPairingHandoff = createPairingHandoff;
|
|
44
|
+
exports.readPairingHandoff = readPairingHandoff;
|
|
45
|
+
exports.consumePairingHandoff = consumePairingHandoff;
|
|
46
|
+
exports.isPairingExpired = isPairingExpired;
|
|
47
|
+
exports.verifyPairingCode = verifyPairingCode;
|
|
48
|
+
const crypto_1 = require("crypto");
|
|
49
|
+
const fs_1 = require("fs");
|
|
50
|
+
const path_1 = require("path");
|
|
51
|
+
const auth_config_1 = require("../../config/auth-config");
|
|
52
|
+
const install_context_1 = require("../../cli/utils/install-context");
|
|
53
|
+
const auth_1 = require("./auth");
|
|
54
|
+
/** Env var carrying the handoff file PATH (never the secret itself). */
|
|
55
|
+
exports.PAIRING_FILE_ENV_KEY = 'CM_REMOTE_PAIRING_FILE';
|
|
56
|
+
/** File name inside the config directory (`~/.commandmate` for global installs). */
|
|
57
|
+
exports.PAIRING_FILE_NAME = 'remote-pairing.json';
|
|
58
|
+
/** Owner read/write only. Asserted by tests, not merely intended. */
|
|
59
|
+
exports.PAIRING_FILE_MODE = 0o600;
|
|
60
|
+
/**
|
|
61
|
+
* Crockford Base32 (https://www.crockford.com/base32.html).
|
|
62
|
+
* `I`, `L`, `O` and `U` are absent so a transcribed code cannot be ambiguous.
|
|
63
|
+
*/
|
|
64
|
+
exports.CROCKFORD_BASE32_ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
|
|
65
|
+
/** Bits of entropy carried by a pairing code. */
|
|
66
|
+
exports.PAIRING_CODE_BITS = 128;
|
|
67
|
+
/** ceil(128 / 5) — the encoded length of PAIRING_CODE_BITS. */
|
|
68
|
+
exports.PAIRING_CODE_LENGTH = 26;
|
|
69
|
+
/** Default time-to-live for one pairing code (§7.4). */
|
|
70
|
+
exports.DEFAULT_PAIRING_TTL_MS = 10 * 60 * 1000;
|
|
71
|
+
/**
|
|
72
|
+
* Input length cap for `POST /api/remote/pair`, copied from `/api/auth/login`'s
|
|
73
|
+
* 256-char cap so an oversized body cannot be used to burn CPU on hashing.
|
|
74
|
+
*/
|
|
75
|
+
exports.MAX_PAIRING_CODE_LENGTH = 256;
|
|
76
|
+
/**
|
|
77
|
+
* Encode bytes as Crockford Base32, MSB first, no padding character.
|
|
78
|
+
*
|
|
79
|
+
* 16 bytes (128 bits) produce 26 characters: 25 characters consume 125 bits and
|
|
80
|
+
* the remaining 3 bits are left-shifted into the 26th.
|
|
81
|
+
*
|
|
82
|
+
* @param bytes - Raw bytes to encode
|
|
83
|
+
* @returns Crockford Base32 string
|
|
84
|
+
*/
|
|
85
|
+
function encodeCrockfordBase32(bytes) {
|
|
86
|
+
let out = '';
|
|
87
|
+
let buffer = 0;
|
|
88
|
+
let bits = 0;
|
|
89
|
+
for (const byte of bytes) {
|
|
90
|
+
buffer = (buffer << 8) | byte;
|
|
91
|
+
bits += 8;
|
|
92
|
+
while (bits >= 5) {
|
|
93
|
+
out += exports.CROCKFORD_BASE32_ALPHABET[(buffer >>> (bits - 5)) & 0b11111];
|
|
94
|
+
bits -= 5;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (bits > 0) {
|
|
98
|
+
out += exports.CROCKFORD_BASE32_ALPHABET[(buffer << (5 - bits)) & 0b11111];
|
|
99
|
+
}
|
|
100
|
+
return out;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Canonicalize a transcribed pairing code.
|
|
104
|
+
*
|
|
105
|
+
* This is the whole reason Crockford Base32 was picked over RFC 4648 Base32:
|
|
106
|
+
* `i`/`l` are accepted as `1`, `o` as `0`, case is irrelevant, and grouping
|
|
107
|
+
* spaces or hyphens a human inserted are dropped. `generatePairingCode()`
|
|
108
|
+
* already emits the canonical form, so `normalize(generate()) === generate()`
|
|
109
|
+
* and the QR path is unaffected.
|
|
110
|
+
*
|
|
111
|
+
* @param code - Raw user/QR supplied code
|
|
112
|
+
* @returns Canonical uppercase form used for hashing
|
|
113
|
+
*/
|
|
114
|
+
function normalizePairingCode(code) {
|
|
115
|
+
return code
|
|
116
|
+
.replace(/[\s-]/g, '')
|
|
117
|
+
.toUpperCase()
|
|
118
|
+
.replace(/[ILO]/g, (character) => (character === 'O' ? '0' : '1'));
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Generate a pairing code carrying {@link PAIRING_CODE_BITS} bits of entropy.
|
|
122
|
+
*
|
|
123
|
+
* Reuses `generateToken()` (32 random bytes as hex) rather than calling
|
|
124
|
+
* `randomBytes` again, and keeps the leading 128 bits: at a 10-minute TTL,
|
|
125
|
+
* single use and a rate limit, 128 bits is already extravagant, and a 26-char
|
|
126
|
+
* code keeps the QR small enough to scan from a laptop screen.
|
|
127
|
+
*
|
|
128
|
+
* @returns 26-character Crockford Base32 code
|
|
129
|
+
*/
|
|
130
|
+
function generatePairingCode() {
|
|
131
|
+
const hexDigits = exports.PAIRING_CODE_BITS / 4;
|
|
132
|
+
return encodeCrockfordBase32(Buffer.from((0, auth_1.generateToken)().slice(0, hexDigits), 'hex'));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Absolute path of the default handoff file.
|
|
136
|
+
*
|
|
137
|
+
* @returns `<configDir>/remote-pairing.json`
|
|
138
|
+
*/
|
|
139
|
+
function getDefaultPairingFilePath() {
|
|
140
|
+
return (0, path_1.join)((0, install_context_1.getConfigDir)(), exports.PAIRING_FILE_NAME);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Read the handoff file path out of the environment.
|
|
144
|
+
*
|
|
145
|
+
* @returns The path, or null when `remote` is not running (route answers 404)
|
|
146
|
+
*/
|
|
147
|
+
function getPairingFilePathFromEnv() {
|
|
148
|
+
const value = process.env[exports.PAIRING_FILE_ENV_KEY];
|
|
149
|
+
return value && value.trim().length > 0 ? value : null;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Write the handoff file with mode 0600.
|
|
153
|
+
*
|
|
154
|
+
* An existing file is unlinked first: `writeFileSync`'s `mode` is only honoured
|
|
155
|
+
* when the file is created, so writing over a stale world-readable file would
|
|
156
|
+
* silently keep the old permissions. `chmodSync` afterwards closes the umask
|
|
157
|
+
* gap for good measure.
|
|
158
|
+
*
|
|
159
|
+
* @param filePath - Absolute path of the handoff file
|
|
160
|
+
* @param handoff - Hash, expiry and plaintext session token
|
|
161
|
+
*/
|
|
162
|
+
function writePairingHandoff(filePath, handoff) {
|
|
163
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(filePath), { recursive: true, mode: 0o700 });
|
|
164
|
+
try {
|
|
165
|
+
(0, fs_1.unlinkSync)(filePath);
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Not there yet - the normal case.
|
|
169
|
+
}
|
|
170
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(handoff), { encoding: 'utf8', mode: exports.PAIRING_FILE_MODE });
|
|
171
|
+
(0, fs_1.chmodSync)(filePath, exports.PAIRING_FILE_MODE);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Mint a pairing code plus its handoff file in one step.
|
|
175
|
+
*
|
|
176
|
+
* @param options - Overrides for path, TTL, session token and clock
|
|
177
|
+
* @returns The plaintext code and token, which the caller must not persist
|
|
178
|
+
*/
|
|
179
|
+
function createPairingHandoff(options = {}) {
|
|
180
|
+
const filePath = options.filePath ?? (0, path_1.join)((0, install_context_1.ensureConfigDir)(), exports.PAIRING_FILE_NAME);
|
|
181
|
+
const now = options.now ?? Date.now();
|
|
182
|
+
const code = generatePairingCode();
|
|
183
|
+
const sessionToken = options.sessionToken ?? (0, auth_1.generateToken)();
|
|
184
|
+
const expiresAt = now + (options.ttlMs ?? exports.DEFAULT_PAIRING_TTL_MS);
|
|
185
|
+
writePairingHandoff(filePath, { pairingHash: (0, auth_1.hashToken)(code), expiresAt, sessionToken });
|
|
186
|
+
return { code, sessionToken, expiresAt, filePath };
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Read and validate the handoff file.
|
|
190
|
+
*
|
|
191
|
+
* Missing and malformed are deliberately the same answer: the caller turns both
|
|
192
|
+
* into 410 Gone, and "already consumed" arrives here as ENOENT.
|
|
193
|
+
*
|
|
194
|
+
* @param filePath - Absolute path of the handoff file
|
|
195
|
+
* @returns The handoff, or null when it is absent or unusable
|
|
196
|
+
*/
|
|
197
|
+
function readPairingHandoff(filePath) {
|
|
198
|
+
let raw;
|
|
199
|
+
try {
|
|
200
|
+
raw = (0, fs_1.readFileSync)(filePath, 'utf8');
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
let parsed;
|
|
206
|
+
try {
|
|
207
|
+
parsed = JSON.parse(raw);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const { pairingHash, expiresAt, sessionToken } = parsed;
|
|
216
|
+
if (typeof pairingHash !== 'string' || !(0, auth_config_1.isValidTokenHash)(pairingHash))
|
|
217
|
+
return null;
|
|
218
|
+
if (typeof expiresAt !== 'number' || !Number.isFinite(expiresAt))
|
|
219
|
+
return null;
|
|
220
|
+
if (typeof sessionToken !== 'string' || sessionToken.length === 0)
|
|
221
|
+
return null;
|
|
222
|
+
return { pairingHash, expiresAt, sessionToken };
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Delete the handoff file. Idempotent — a missing file is success.
|
|
226
|
+
*
|
|
227
|
+
* @param filePath - Absolute path of the handoff file
|
|
228
|
+
*/
|
|
229
|
+
function consumePairingHandoff(filePath) {
|
|
230
|
+
try {
|
|
231
|
+
(0, fs_1.unlinkSync)(filePath);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
// Already gone: the state we wanted.
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* @param handoff - Handoff read from disk
|
|
239
|
+
* @param now - Epoch ms, injectable for tests
|
|
240
|
+
* @returns true when the pairing window has closed
|
|
241
|
+
*/
|
|
242
|
+
function isPairingExpired(handoff, now = Date.now()) {
|
|
243
|
+
return now > handoff.expiresAt;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Timing-safe comparison of a supplied code against the stored hash (S001).
|
|
247
|
+
*
|
|
248
|
+
* @param code - Code as supplied by the client
|
|
249
|
+
* @param pairingHash - SHA-256 hex from the handoff file
|
|
250
|
+
* @returns true when the code matches
|
|
251
|
+
*/
|
|
252
|
+
function verifyPairingCode(code, pairingHash) {
|
|
253
|
+
if (typeof code !== 'string' || code.length === 0 || code.length > exports.MAX_PAIRING_CODE_LENGTH) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
if (!(0, auth_config_1.isValidTokenHash)(pairingHash)) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
const candidate = Buffer.from((0, auth_1.hashToken)(normalizePairingCode(code)), 'hex');
|
|
260
|
+
const expected = Buffer.from(pairingHash, 'hex');
|
|
261
|
+
if (candidate.length !== expected.length) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
return (0, crypto_1.timingSafeEqual)(candidate, expected);
|
|
265
|
+
}
|
|
@@ -35,6 +35,11 @@ exports.AUTH_EXCLUDED_PATHS = [
|
|
|
35
35
|
'/api/auth/login',
|
|
36
36
|
'/api/auth/logout',
|
|
37
37
|
'/api/auth/status',
|
|
38
|
+
// Issue #1937 (R5): one-shot pairing-code exchange for `commandmate remote`.
|
|
39
|
+
// The pairing SCREEN is '/login' above, driven by a '#code=' fragment, so
|
|
40
|
+
// this is the only entry the remote feature adds. Handler:
|
|
41
|
+
// src/app/api/remote/pair/route.ts (it authenticates the code itself).
|
|
42
|
+
'/api/remote/pair',
|
|
38
43
|
// Issue #1124 (PWA): non-sensitive resources that must stay reachable before
|
|
39
44
|
// auth so the app is installable and the offline fallback can be precached.
|
|
40
45
|
// All carry no user data (app metadata / public SW code / static fallback).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commandmate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.1",
|
|
4
4
|
"description": "A local control plane for agent CLIs — orchestration and visibility for Claude Code, Codex, Gemini CLI, and more across Git worktrees",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -92,6 +92,7 @@
|
|
|
92
92
|
"next-intl": "^4.8.2",
|
|
93
93
|
"next-themes": "^0.4.6",
|
|
94
94
|
"postcss": "^8.5.6",
|
|
95
|
+
"qr.js": "0.0.0",
|
|
95
96
|
"react": "^19.2.7",
|
|
96
97
|
"react-dom": "^19.2.7",
|
|
97
98
|
"react-markdown": "^10.1.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:59,errorRate:1e-4,numBits:1132,numHashes:14,bitArray:[1,0,0,1,e,r,e,e,e,r,r,e,r,e,r,r,r,e,e,e,r,e,e,e,r,e,r,r,r,e,r,r,r,e,e,r,e,r,e,r,r,e,r,e,e,e,e,e,e,r,e,r,e,r,r,r,e,e,r,r,e,e,e,r,e,e,r,r,r,r,r,e,e,r,r,r,e,r,r,e,e,e,r,r,r,e,e,e,r,r,r,r,r,e,e,e,r,r,e,r,r,r,e,e,r,e,r,e,r,r,r,r,r,r,e,e,r,r,e,r,e,r,e,e,e,e,r,r,r,r,e,e,e,r,r,r,e,e,e,e,e,e,r,e,e,e,r,e,e,r,e,e,e,r,e,e,e,e,r,e,e,e,e,r,r,e,e,r,r,e,r,r,e,r,e,r,e,e,r,r,r,r,e,e,r,e,r,e,e,e,e,e,r,e,e,r,r,r,e,e,r,e,e,r,e,r,e,e,e,r,r,e,r,e,r,e,e,r,e,e,e,r,e,r,r,r,r,e,e,e,r,e,r,e,r,r,e,e,r,r,e,e,e,r,e,e,r,e,e,r,e,e,e,e,e,r,e,e,e,e,r,e,e,e,r,r,e,e,r,e,r,e,r,e,e,r,e,e,r,e,r,r,r,e,e,r,r,r,e,e,e,e,e,e,r,r,r,e,r,e,e,r,r,r,r,e,r,e,e,r,e,e,e,r,r,e,e,r,e,r,r,e,r,e,e,e,r,r,e,e,e,r,e,e,r,e,e,r,r,e,e,r,e,e,r,r,e,e,e,r,r,e,r,e,e,r,r,r,e,e,e,r,e,r,r,e,r,e,e,e,r,r,r,e,r,e,e,e,r,e,r,e,r,r,e,r,e,e,r,r,e,r,r,r,r,r,r,e,r,e,e,r,r,r,e,r,e,e,e,r,e,e,r,r,r,r,e,e,r,e,e,r,r,e,r,e,e,r,e,e,r,r,r,e,r,e,e,e,e,e,e,e,r,e,r,e,e,e,e,e,r,e,e,r,e,e,r,r,r,e,e,r,r,e,e,r,e,e,r,r,r,r,r,e,e,e,r,e,e,e,e,r,r,r,r,e,r,r,e,r,e,r,e,e,r,r,r,r,e,r,r,e,e,e,e,r,r,e,e,r,e,e,r,e,e,r,r,e,r,e,r,e,e,e,r,r,e,e,e,r,e,e,r,r,r,r,e,r,r,e,r,e,e,e,r,r,e,e,e,e,e,r,e,e,r,e,r,e,r,r,r,r,e,e,r,e,r,r,r,r,r,r,r,r,e,e,e,e,r,e,r,r,e,r,r,r,e,r,e,r,e,e,e,e,r,r,r,e,r,e,r,e,e,r,r,e,e,e,e,e,e,r,r,e,e,r,r,e,e,r,e,e,e,r,e,r,e,e,e,e,e,e,r,r,e,e,e,e,e,r,r,e,r,r,r,r,e,r,e,r,e,e,r,e,e,r,e,r,r,e,r,e,e,e,e,e,r,e,e,r,r,e,e,e,e,e,e,e,e,r,r,r,r,r,e,r,r,e,e,e,r,e,e,r,r,e,r,e,e,r,e,r,e,r,e,e,r,r,r,e,e,e,r,e,r,r,r,r,r,e,e,e,r,e,e,r,r,e,r,e,e,e,r,e,r,e,r,e,e,e,e,r,e,r,e,r,e,r,e,r,e,r,e,r,e,e,e,e,e,e,r,e,r,r,r,r,r,e,e,r,r,e,r,e,r,r,r,e,e,e,e,r,r,e,e,r,r,e,r,r,e,r,e,e,r,r,r,e,r,e,r,r,r,e,r,e,r,e,r,e,e,e,e,r,r,e,e,e,e,r,r,r,r,e,e,e,e,r,r,e,r,e,e,r,e,r,e,e,e,e,e,e,r,r,e,e,r,r,e,e,r,e,e,r,r,r,e,r,r,r,r,e,r,r,e,r,e,e,e,r,r,r,e,r,e,e,r,e,r,r,r,r,e,r,e,e,r,r,e,r,e,r,r,r,e,r,e,r,e,r,e,r,r,r,r,r,r,r,r,e,r,r,r,e,r,r,e,r,r,r,r,e,e,r,r,r,e,e,r,e,e,e,e,r,r,r,e,e,e,r,r,e,r,r,r,r,r,r,r,r,e,e,r,e,e,r,r,e,r,e,e,r,r,e,r,e,r,r,e,e,e,e,r,e,r,r,r,r,r,e,e,r,r,e,r,r,r,r,r,e,r,e,r,e,r,r,r,e,r,e,r,r,e,e,e,r,e,r,e,r,e,e,r,e,r,r,r,e,e,r,r,r,e,r,e,r,e,r,e,e,r,r,r,r,e,r,r,r,e,r,e,r,r,e,e,r,e,e,e,e,r,r,e,r,e,e,r,r,e,e,e,e,r,r,e,e,r,e,e,e,e,e,r,r,r,r,e,e,e,r,e,e,r,e,e,r,e,e,r,r,r,r,r,r,r,r,r,e,e,e,r,r,e,e,e,e,r,e,e,e,r,r,r,e,e,e,r,e,e,r,e,r,r,r,r,e,e,r,r,e,e,r]},__routerFilterDynamic:{numItems:11,errorRate:1e-4,numBits:211,numHashes:14,bitArray:[r,e,e,e,r,e,r,r,r,r,e,r,r,e,r,e,r,e,e,e,r,r,e,e,e,r,e,e,e,r,r,e,r,e,e,r,r,r,e,r,e,e,e,r,r,e,r,e,e,r,r,e,e,e,r,e,r,e,r,r,e,r,e,e,r,e,e,r,e,e,e,e,r,e,e,r,r,r,e,e,e,e,e,r,r,r,e,r,e,e,e,r,e,r,e,r,e,e,r,r,e,e,r,e,r,e,r,e,e,e,e,r,r,e,e,r,e,e,e,e,r,e,e,r,r,e,e,r,e,r,e,e,r,e,e,e,e,r,r,e,r,r,r,e,r,r,r,r,r,e,e,e,r,e,r,e,r,e,e,e,e,e,r,r,r,e,e,r,r,e,e,r,r,e,r,r,e,e,r,r,r,e,e,r,e,r,r,r,e,r,e,r,e,e,e,r,e,r,r,r,e,r,e,e,e,r,e,e,r,r,e]},"/_error":["static/chunks/pages/_error-c970d8b55ace1b48.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|