commandmate 0.44.1 → 0.44.3
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 +169 -169
- package/.next/app-path-routes-manifest.json +35 -35
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- 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/agents/update/route.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +2 -2
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route.js +1 -1
- package/.next/server/app/api/daily-summary/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js +1 -1
- package/.next/server/app/api/daily-summary/status/route.js.nft.json +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route.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.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js +2 -2
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.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.js +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_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.js +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +3 -3
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_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_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_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_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.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.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.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.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.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.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.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.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.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.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.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/unstage/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/working-diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route.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.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.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js +1 -2
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -2
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/resolve-target/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route.js +1 -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 +2 -2
- 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 +2 -2
- package/.next/server/app/api/worktrees/[id]/schedules/active/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/active/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route.js +3 -3
- package/.next/server/app/api/worktrees/[id]/schedules/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/search/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/send/route.js +1 -1
- 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 +3 -3
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page.js.nft.json +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_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 +11 -11
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +35 -35
- package/.next/server/chunks/1191.js +2 -2
- package/.next/server/chunks/1210.js +1 -1
- package/.next/server/chunks/1559.js +2 -0
- package/.next/server/chunks/1789.js +1 -0
- 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/2460.js +1 -0
- package/.next/server/chunks/2710.js +1 -1
- package/.next/server/chunks/2908.js +1 -0
- package/.next/server/chunks/2980.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3480.js +1 -1
- package/.next/server/chunks/3718.js +1 -1
- package/.next/server/chunks/4207.js +2 -2
- package/.next/server/chunks/450.js +1 -1
- package/.next/server/chunks/4672.js +5 -0
- package/.next/server/chunks/{9353.js → 4718.js} +2 -2
- package/.next/server/chunks/4837.js +14 -0
- package/.next/server/chunks/5048.js +1 -1
- package/.next/server/chunks/5209.js +1 -0
- package/.next/server/chunks/5595.js +1 -0
- package/.next/server/chunks/5625.js +25 -0
- package/.next/server/chunks/5845.js +1 -0
- package/.next/server/chunks/611.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/6793.js +3 -3
- package/.next/server/chunks/7491.js +2 -2
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/850.js +1 -0
- package/.next/server/chunks/8543.js +1 -1
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8800.js +1 -1
- package/.next/server/chunks/8918.js +7 -7
- package/.next/server/chunks/9130.js +1 -5
- package/.next/server/chunks/9390.js +2 -3
- package/.next/server/chunks/9584.js +1 -1
- package/.next/server/chunks/9627.js +6 -6
- package/.next/server/chunks/9731.js +3 -3
- 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/static/chunks/{1642-fb2e176aaadbd137.js → 1642-767aed8e7c61ef7f.js} +1 -1
- package/.next/static/chunks/{2407-f1f258d4a1d92620.js → 2407-06d35bb1aa02de80.js} +1 -1
- package/.next/static/chunks/{2619-04bc32f026a0d946.js → 2619-a305ad4810f1393a.js} +1 -1
- package/.next/static/chunks/4727-5d695d71e3fdf97b.js +1 -0
- package/.next/static/chunks/{8165-3853772f6ae1299b.js → 8165-3525fb42f1b4976e.js} +1 -1
- package/.next/static/chunks/app/{layout-da66300cc20244ed.js → layout-0d1750b833f5cc3e.js} +1 -1
- package/.next/static/chunks/app/sessions/page-2af68c63211c751f.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-e36898c3a80e7302.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/{page-373ea37b16d930c7.js → page-c601f3b3ece6557e.js} +1 -1
- package/.next/static/css/057f64a65726c439.css +1 -0
- package/.next/trace +13 -13
- package/dist/cli/commands/ask.d.ts.map +1 -1
- package/dist/cli/commands/ask.js +120 -119
- package/dist/cli/commands/attach.d.ts +94 -0
- package/dist/cli/commands/attach.d.ts.map +1 -1
- package/dist/cli/commands/attach.js +145 -7
- package/dist/cli/commands/auto-yes.js +1 -1
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +10 -13
- package/dist/cli/commands/command-target.d.ts +23 -0
- package/dist/cli/commands/command-target.d.ts.map +1 -0
- package/dist/cli/commands/command-target.js +25 -0
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +41 -2
- package/dist/cli/commands/message-dispatch.d.ts +36 -0
- package/dist/cli/commands/message-dispatch.d.ts.map +1 -0
- package/dist/cli/commands/message-dispatch.js +63 -0
- package/dist/cli/commands/reply.d.ts.map +1 -1
- package/dist/cli/commands/reply.js +2 -5
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +3 -6
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +149 -146
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +608 -416
- package/dist/cli/types/api-responses.d.ts +174 -27
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/api-responses.js +4 -2
- package/dist/cli/utils/api-client.d.ts +25 -5
- package/dist/cli/utils/api-client.d.ts.map +1 -1
- package/dist/cli/utils/api-client.js +87 -55
- package/dist/cli/utils/server-url.d.ts +1 -0
- package/dist/cli/utils/server-url.d.ts.map +1 -1
- package/dist/cli/utils/server-url.js +7 -0
- package/dist/config/uat-isolation.d.ts +140 -0
- package/dist/config/uat-isolation.d.ts.map +1 -0
- package/dist/config/uat-isolation.js +246 -0
- package/dist/lib/global-state.d.ts +12 -0
- package/dist/lib/global-state.d.ts.map +1 -0
- package/dist/lib/global-state.js +16 -0
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts +33 -0
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -0
- package/dist/lib/polling/auto-yes-suppression-reason.js +2 -0
- package/dist/lib/session/prompt-view.d.ts +228 -0
- package/dist/lib/session/prompt-view.d.ts.map +1 -0
- package/dist/lib/session/prompt-view.js +290 -0
- package/dist/lib/session/status-evidence-type.d.ts +16 -0
- package/dist/lib/session/status-evidence-type.d.ts.map +1 -0
- package/dist/lib/session/status-evidence-type.js +2 -0
- package/dist/lib/tmux/legacy-session-alias.d.ts.map +1 -1
- package/dist/lib/tmux/legacy-session-alias.js +2 -1
- package/dist/server/locales/en/worktree.json +3 -1
- package/dist/server/locales/ja/worktree.json +3 -1
- package/dist/server/server.js +5 -3
- package/dist/server/src/cli/types/api-responses.js +4 -2
- package/dist/server/src/config/cli-tool-timing-config.js +1 -6
- package/dist/server/src/config/uat-isolation.js +246 -0
- package/dist/server/src/lib/assistant-response-saver.js +62 -3
- package/dist/server/src/lib/auto-yes-lifecycle.js +139 -0
- package/dist/server/src/lib/auto-yes-poller.js +465 -160
- package/dist/server/src/lib/auto-yes-state.js +2 -2
- package/dist/server/src/lib/cli-tools/antigravity.js +39 -80
- package/dist/server/src/lib/cli-tools/base.js +151 -0
- package/dist/server/src/lib/cli-tools/codex.js +44 -80
- package/dist/server/src/lib/cli-tools/command-code.js +24 -56
- package/dist/server/src/lib/cli-tools/copilot.js +25 -67
- package/dist/server/src/lib/cli-tools/direct-input.js +8 -0
- package/dist/server/src/lib/cli-tools/gemini.js +23 -73
- package/dist/server/src/lib/cli-tools/opencode-pane-width.js +53 -0
- package/dist/server/src/lib/cli-tools/opencode-v2.js +9 -7
- package/dist/server/src/lib/cli-tools/opencode.js +21 -85
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +127 -4
- package/dist/server/src/lib/cli-tools/vibe-local.js +21 -66
- package/dist/server/src/lib/detection/cli-patterns.js +374 -3047
- package/dist/server/src/lib/detection/idle-evidence-observation.js +2 -2
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +7 -32
- package/dist/server/src/lib/detection/prompt-detector.js +2 -35
- package/dist/server/src/lib/detection/selection-shape-patterns.js +69 -0
- package/dist/server/src/lib/detection/selection-shape.js +32 -520
- package/dist/server/src/lib/detection/shared/pasted-text.js +41 -0
- package/dist/server/src/lib/detection/shared/shell-pane-command.js +16 -0
- package/dist/server/src/lib/detection/shared/strip-box-drawing.js +25 -0
- package/dist/server/src/lib/detection/status-detector.js +1 -1
- package/dist/server/src/lib/detection/tools/antigravity/detect.js +12 -60
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +2 -15
- package/dist/server/src/lib/detection/tools/antigravity/live-region.js +39 -0
- package/dist/server/src/lib/detection/tools/antigravity/patterns.js +286 -0
- package/dist/server/src/lib/detection/tools/claude/detect.js +11 -17
- package/dist/server/src/lib/detection/tools/claude/live-region.js +26 -0
- package/dist/server/src/lib/detection/tools/claude/patterns.js +264 -4
- package/dist/server/src/lib/detection/tools/claude/prompt.js +2 -10
- package/dist/server/src/lib/detection/tools/codex/cli-patterns.js +1 -1
- package/dist/server/src/lib/detection/tools/codex/detect.js +71 -130
- package/dist/server/src/lib/detection/tools/codex/live-region.js +104 -0
- package/dist/server/src/lib/detection/tools/codex/patterns.js +855 -0
- package/dist/server/src/lib/detection/tools/codex/prompt.js +2 -10
- package/dist/server/src/lib/detection/tools/command-code/detect.js +19 -50
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +2 -18
- package/dist/server/src/lib/detection/tools/command-code/live-region.js +36 -0
- package/dist/server/src/lib/detection/tools/command-code/patterns.js +234 -0
- package/dist/server/src/lib/detection/tools/command-code/selection-shape.js +461 -0
- package/dist/server/src/lib/detection/tools/context-above.js +20 -0
- package/dist/server/src/lib/detection/tools/copilot/detect.js +13 -35
- package/dist/server/src/lib/detection/tools/copilot/live-region.js +52 -0
- package/dist/server/src/lib/detection/tools/copilot/patterns.js +640 -0
- package/dist/server/src/lib/detection/tools/copilot/prompt.js +2 -10
- package/dist/server/src/lib/detection/tools/frame.js +36 -2
- package/dist/server/src/lib/detection/tools/gemini/patterns.js +29 -0
- package/dist/server/src/lib/detection/tools/live-region-specs.js +31 -0
- package/dist/server/src/lib/detection/tools/live-region.js +204 -0
- package/dist/server/src/lib/detection/tools/opencode/detect.js +11 -49
- package/dist/server/src/lib/detection/tools/opencode/live-region.js +24 -0
- package/dist/server/src/lib/detection/tools/opencode/patterns.js +508 -0
- package/dist/server/src/lib/detection/tools/opencode-gutter-live-region.js +72 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/detect.js +10 -42
- package/dist/server/src/lib/detection/tools/opencode-v2/live-region.js +24 -0
- package/dist/server/src/lib/detection/tools/opencode-v2/patterns.js +63 -0
- package/dist/server/src/lib/detection/tools/run-detection.js +31 -50
- package/dist/server/src/lib/detection/tools/verdicts.js +59 -0
- package/dist/server/src/lib/detection/tools/vibe-local/patterns.js +20 -0
- package/dist/server/src/lib/detection/truncate-raw-content.js +38 -0
- package/dist/server/src/lib/detection/turn-abandoned.js +66 -0
- package/dist/server/src/lib/detection/unclassified-frame-tracker.js +2 -2
- package/dist/server/src/lib/global-state.js +16 -0
- package/dist/server/src/lib/hooks/agent-session-telemetry.js +4 -6
- package/dist/server/src/lib/hooks/permission-decision-state.js +2 -2
- package/dist/server/src/lib/hooks/sources/antigravity/history.js +11 -76
- package/dist/server/src/lib/hooks/sources/antigravity/hooks-config.js +63 -1
- package/dist/server/src/lib/hooks/sources/antigravity/source.js +16 -0
- package/dist/server/src/lib/hooks/sources/antigravity/transcript.js +3 -12
- package/dist/server/src/lib/hooks/sources/claude/history.js +17 -156
- package/dist/server/src/lib/hooks/sources/claude/queued-notice.js +53 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +33 -3
- package/dist/server/src/lib/hooks/sources/claude/transcript.js +3 -13
- package/dist/server/src/lib/hooks/sources/codex/history.js +11 -74
- package/dist/server/src/lib/hooks/sources/codex/hooks-config.js +147 -11
- package/dist/server/src/lib/hooks/sources/codex/relay-install.js +64 -21
- package/dist/server/src/lib/hooks/sources/codex/transcript.js +5 -15
- package/dist/server/src/lib/hooks/sources/command-code/history.js +20 -121
- package/dist/server/src/lib/hooks/sources/command-code/transcript.js +3 -13
- package/dist/server/src/lib/hooks/sources/copilot/hook-settings.js +161 -31
- package/dist/server/src/lib/hooks/sources/define-source.js +40 -55
- package/dist/server/src/lib/hooks/sources/event-mapper.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/diff.js +3 -4
- package/dist/server/src/lib/hooks/sources/opencode/history.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/launch-settings.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/payloads.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/ports.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode/subscription.js +4 -3
- package/dist/server/src/lib/hooks/sources/opencode/transcript.js +3 -16
- package/dist/server/src/lib/hooks/sources/opencode-v2/history.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode-v2/mappers.js +5 -4
- package/dist/server/src/lib/hooks/sources/opencode-v2/ports.js +2 -1
- package/dist/server/src/lib/hooks/sources/opencode-v2/subscription.js +3 -7
- package/dist/server/src/lib/hooks/sources/opencode-v2/usage.js +2 -1
- package/dist/server/src/lib/hooks/sources/pending-decisions.js +2 -1
- package/dist/server/src/lib/hooks/sources/registry.js +3 -2
- package/dist/server/src/lib/hooks/sources/transcript-history.js +262 -0
- package/dist/server/src/lib/hooks/sources/turn-body.js +31 -0
- package/dist/server/src/lib/hooks/tool-input-normalization-state.js +2 -2
- package/dist/server/src/lib/polling/antigravity-permission-receipts.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +16 -4
- package/dist/server/src/lib/polling/auto-yes-enter-fallback-state.js +142 -0
- package/dist/server/src/lib/polling/auto-yes-enter-fallback.js +187 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +9 -3
- package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +2 -0
- package/dist/server/src/lib/polling/auto-yes-suppression-state.js +2 -2
- package/dist/server/src/lib/polling/pending-scraped-response.js +190 -0
- package/dist/server/src/lib/polling/prompt-dedup-state.js +2 -2
- package/dist/server/src/lib/polling/prompt-dedup.js +2 -2
- package/dist/server/src/lib/polling/response-checker-dialog-gate.js +95 -0
- package/dist/server/src/lib/polling/response-checker-extraction-result.js +50 -0
- package/dist/server/src/lib/polling/response-checker-extraction-steps.js +670 -0
- package/dist/server/src/lib/polling/response-checker.js +666 -1162
- package/dist/server/src/lib/polling/response-dedup.js +3 -4
- package/dist/server/src/lib/polling/response-poller-constants.js +17 -0
- package/dist/server/src/lib/polling/response-poller-core.js +54 -20
- package/dist/server/src/lib/polling/startup-screen.js +142 -0
- package/dist/server/src/lib/polling/structured-history-gate.js +3 -2
- package/dist/server/src/lib/prompt-answer-semantic.js +178 -0
- package/dist/server/src/lib/prompt-answer-sender.js +6 -5
- package/dist/server/src/lib/push/failure-episode-state.js +2 -2
- package/dist/server/src/lib/push/notification-dedup.js +3 -4
- package/dist/server/src/lib/push/prompt-card-state.js +2 -2
- package/dist/server/src/lib/push/waiting-push-notifier.js +3 -4
- package/dist/server/src/lib/realtime/publisher-registry.js +3 -2
- package/dist/server/src/lib/realtime/terminal-broadcast.js +38 -2
- package/dist/server/src/lib/realtime/terminal-session-ownership.js +45 -0
- package/dist/server/src/lib/relay/relay-delivery.js +6 -2
- package/dist/server/src/lib/relay/relay-readiness.js +38 -1
- package/dist/server/src/lib/relay/relay-triggers.js +9 -0
- package/dist/server/src/lib/resource-cleanup.js +6 -4
- package/dist/server/src/lib/response-cleaner.js +24 -1
- package/dist/server/src/lib/response-extractor.js +16 -0
- package/dist/server/src/lib/schedule-manager.js +8 -10
- package/dist/server/src/lib/session/agent-event-ask-user-question.js +168 -0
- package/dist/server/src/lib/session/agent-event-awaiting-instruction.js +104 -0
- package/dist/server/src/lib/session/agent-event-dedup.js +539 -0
- package/dist/server/src/lib/session/agent-event-model.js +562 -0
- package/dist/server/src/lib/session/agent-event-record.js +10 -0
- package/dist/server/src/lib/session/agent-event-state.js +106 -1854
- package/dist/server/src/lib/session/agent-event-structured-state.js +109 -0
- package/dist/server/src/lib/session/agent-event-turn.js +811 -0
- package/dist/server/src/lib/session/agent-session-lifecycle.js +11 -2
- package/dist/server/src/lib/session/chat-turn-progress.js +322 -0
- package/dist/server/src/lib/session/claude-executor.js +45 -5
- package/dist/server/src/lib/session/claude-session.js +21 -65
- package/dist/server/src/lib/session/cli-session.js +17 -0
- package/dist/server/src/lib/session/current-output-builder.js +454 -1103
- package/dist/server/src/lib/session/current-output-history-writers.js +255 -0
- package/dist/server/src/lib/session/current-output-types.js +9 -0
- package/dist/server/src/lib/session/detection-divergence.js +55 -0
- package/dist/server/src/lib/session/global-session-constants.js +2 -13
- package/dist/server/src/lib/session/hook-turn-hold.js +102 -0
- package/dist/server/src/lib/session/layer-disagreement.js +2 -2
- package/dist/server/src/lib/session/opencode-session-store.js +2 -1
- package/dist/server/src/lib/session/prompt-view.js +290 -0
- package/dist/server/src/lib/session/prompt-waiting-composition.js +35 -0
- package/dist/server/src/lib/session/provisional-turn.js +3 -1
- package/dist/server/src/lib/session/send-user-message.js +1 -1
- package/dist/server/src/lib/session/session-starting-state.js +4 -6
- package/dist/server/src/lib/session/status-evidence-type.js +2 -0
- package/dist/server/src/lib/session/status-evidence.js +2 -2
- package/dist/server/src/lib/session/structured-status-merge.js +335 -0
- package/dist/server/src/lib/session/waiting-episode-state.js +3 -4
- package/dist/server/src/lib/session/waiting-kind.js +3 -0
- package/dist/server/src/lib/session-cleanup.js +6 -8
- package/dist/server/src/lib/skills/install-plan.js +2 -1
- package/dist/server/src/lib/skills/snapshot-store.js +2 -2
- package/dist/server/src/lib/skills/uninstall-plan.js +2 -2
- package/dist/server/src/lib/timer-manager.js +6 -8
- package/dist/server/src/lib/tmux/geometry-delegation.js +3 -4
- package/dist/server/src/lib/tmux/legacy-session-alias.js +2 -1
- package/dist/server/src/lib/tmux/session-hooks.js +2 -1
- package/dist/server/src/lib/tmux/session-status-options.js +3 -3
- package/dist/server/src/lib/tmux/tmux-capture-cache.js +3 -2
- package/dist/server/src/lib/tmux/tmux.js +33 -59
- package/dist/server/src/lib/tui-accumulator.js +2 -2
- package/dist/server/src/lib/version-checker.js +6 -6
- package/dist/server/src/lib/ws-server.js +47 -11
- package/docs/en/user-guide/webapp-guide.md +27 -3
- package/package.json +1 -1
- package/release-notes/0.44.2.json +33 -0
- package/release-notes/0.44.3.json +82 -0
- package/scripts/hooks/cmate-agent-event.sh +18 -0
- package/.next/server/chunks/1068.js +0 -1
- package/.next/server/chunks/434.js +0 -1
- package/.next/server/chunks/5775.js +0 -1
- package/.next/server/chunks/6474.js +0 -14
- package/.next/server/chunks/650.js +0 -1
- package/.next/server/chunks/6661.js +0 -1
- package/.next/server/chunks/8583.js +0 -1
- package/.next/server/chunks/964.js +0 -1
- package/.next/server/chunks/967.js +0 -1
- package/.next/server/chunks/9882.js +0 -25
- package/.next/static/chunks/591-308072f285c34787.js +0 -1
- package/.next/static/chunks/app/sessions/page-049e06335187aa91.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-040c5f0f585e6812.js +0 -1
- package/.next/static/css/38070d879efa1371.css +0 -1
- package/dist/server/src/lib/cli-tools/index.js +0 -41
- package/dist/server/src/lib/polling/global-session-poller.js +0 -140
- /package/.next/static/{57lOiz8zSEHdw97XIm0af → tWwHQzmvc-rv9KKUtDWfQ}/_buildManifest.js +0 -0
- /package/.next/static/{57lOiz8zSEHdw97XIm0af → tWwHQzmvc-rv9KKUtDWfQ}/_ssgManifest.js +0 -0
|
@@ -9,16 +9,18 @@
|
|
|
9
9
|
* - ApiClient: HTTP get/post with base URL and auth headers
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.ApiError = exports.ApiClient = exports.MAX_STOP_PATTERN_LENGTH = void 0;
|
|
12
|
+
exports.ApiError = exports.ApiClient = exports.FOREIGN_SESSION_ERROR_CODE = exports.MAX_STOP_PATTERN_LENGTH = void 0;
|
|
13
13
|
exports.isValidWorktreeId = isValidWorktreeId;
|
|
14
14
|
exports.isValidInstanceId = isValidInstanceId;
|
|
15
15
|
exports.resolveAuthToken = resolveAuthToken;
|
|
16
|
+
exports.foreignSessionMessage = foreignSessionMessage;
|
|
16
17
|
exports.handleApiError = handleApiError;
|
|
17
18
|
exports.assertResponseShape = assertResponseShape;
|
|
18
19
|
exports.fetchDaemonVersion = fetchDaemonVersion;
|
|
19
20
|
exports.warnIfVersionSkew = warnIfVersionSkew;
|
|
20
21
|
const types_1 = require("../types");
|
|
21
22
|
const package_info_1 = require("./package-info");
|
|
23
|
+
const uat_isolation_1 = require("../../config/uat-isolation");
|
|
22
24
|
const server_url_1 = require("./server-url");
|
|
23
25
|
/** Maximum stop-pattern length [SEC4-06] */
|
|
24
26
|
exports.MAX_STOP_PATTERN_LENGTH = 500;
|
|
@@ -91,6 +93,30 @@ function serverErrorDetail(payload) {
|
|
|
91
93
|
function withServerUrl(message, context) {
|
|
92
94
|
return context?.serverUrl ? `${message} (server: ${context.serverUrl})` : message;
|
|
93
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* The `code` the server sends with the 409 for a tmux session another
|
|
98
|
+
* CommandMate server created (Issue #2865). Spelled out rather than imported:
|
|
99
|
+
* the server's constant lives next to the tmux gateway, which the CLI must not
|
|
100
|
+
* load. `tests/unit/cli/utils/api-client-foreign-session-3334.test.ts` pins the
|
|
101
|
+
* two to the same string.
|
|
102
|
+
*/
|
|
103
|
+
exports.FOREIGN_SESSION_ERROR_CODE = 'session_owned_by_other_server';
|
|
104
|
+
/**
|
|
105
|
+
* Issue #3334: what the operator reads for that 409. It has to say three
|
|
106
|
+
* things the status alone does not: the session is another CommandMate
|
|
107
|
+
* server's, this command therefore did nothing to it, and where to go instead.
|
|
108
|
+
*/
|
|
109
|
+
function foreignSessionMessage(payload) {
|
|
110
|
+
const name = typeof payload?.sessionName === 'string' && payload.sessionName !== ''
|
|
111
|
+
? `"${payload.sessionName}" `
|
|
112
|
+
: '';
|
|
113
|
+
const where = typeof payload?.sessionPath === 'string' && payload.sessionPath !== ''
|
|
114
|
+
? ` (it was started in ${payload.sessionPath})`
|
|
115
|
+
: '';
|
|
116
|
+
return (`The tmux session ${name}belongs to another CommandMate server${where}, ` +
|
|
117
|
+
'so nothing was sent to it, read from it or stopped. ' +
|
|
118
|
+
'Use the CommandMate server that started it, or stop that session there first.');
|
|
119
|
+
}
|
|
94
120
|
/**
|
|
95
121
|
* Classify API errors into user-friendly messages and exit codes.
|
|
96
122
|
* [IA3-09] Covers: ECONNREFUSED, 400, 401/403, 404, 429, 500, timeout
|
|
@@ -98,8 +124,9 @@ function withServerUrl(message, context) {
|
|
|
98
124
|
* @param error - Error object or unknown
|
|
99
125
|
* @param status - HTTP status code if available
|
|
100
126
|
* @param payload - Parsed error body, when the response carried one (Issue #1637).
|
|
101
|
-
* Used for 5xx
|
|
102
|
-
* pinned by tests as the CLI's
|
|
127
|
+
* Used for 5xx, and for the foreign-session 409 (Issue #3334): the other 4xx
|
|
128
|
+
* messages below are already specific, and are pinned by tests as the CLI's
|
|
129
|
+
* own wording.
|
|
103
130
|
* @param context - Which server answered, when the caller knows (Issue #2404).
|
|
104
131
|
* Read by the 404 branch only; the other messages do not send anyone looking
|
|
105
132
|
* in the wrong place.
|
|
@@ -139,6 +166,23 @@ function handleApiError(error, status, payload, context) {
|
|
|
139
166
|
message: withServerUrl('Resource not found. Check the worktree ID.', context),
|
|
140
167
|
exitCode: types_1.ExitCode.UNEXPECTED_ERROR,
|
|
141
168
|
};
|
|
169
|
+
case 409:
|
|
170
|
+
// Issue #3334: the one 409 every session route shares (#2865 / #3290).
|
|
171
|
+
// Without this it read "Unexpected HTTP status: 409", which does not say
|
|
172
|
+
// that nothing was done, nor why. Same exit code as that default branch,
|
|
173
|
+
// so a script branching on it sees no change. Every other 409 keeps the
|
|
174
|
+
// default wording below — the commands that own one (send's
|
|
175
|
+
// PROMPT_WAITING, verify's running run) already explain it themselves.
|
|
176
|
+
if (payload?.code === exports.FOREIGN_SESSION_ERROR_CODE) {
|
|
177
|
+
return {
|
|
178
|
+
message: foreignSessionMessage(payload),
|
|
179
|
+
exitCode: types_1.ExitCode.UNEXPECTED_ERROR,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
message: `Unexpected HTTP status: ${status}`,
|
|
184
|
+
exitCode: types_1.ExitCode.UNEXPECTED_ERROR,
|
|
185
|
+
};
|
|
142
186
|
case 429:
|
|
143
187
|
return {
|
|
144
188
|
message: 'Rate limited. Please retry after a moment.',
|
|
@@ -219,6 +263,11 @@ class ApiClient {
|
|
|
219
263
|
// *under* process.env — see its doc comment for why that order is the reverse of the one
|
|
220
264
|
// `status` uses. resolveServerEndpoint() then applies the same CM_BIND / CM_HTTPS_CERT +
|
|
221
265
|
// CM_HTTPS_KEY rules as `status`, which the old hardcoded `http://localhost:` ignored.
|
|
266
|
+
// Issue #3360: in UAT isolation the default port 3000 is the user's production server,
|
|
267
|
+
// so a client that was not told where to go must not go anywhere.
|
|
268
|
+
if (!options?.baseUrl && (0, uat_isolation_1.isUatIsolationEnabled)() && !process.env.CM_PORT) {
|
|
269
|
+
throw new ApiError(`${uat_isolation_1.UAT_ISOLATION_ENV_VAR}=${process.env[uat_isolation_1.UAT_ISOLATION_ENV_VAR]} requires CM_PORT: refusing to fall back to the default port 3000.`, types_1.ExitCode.CONFIG_ERROR);
|
|
270
|
+
}
|
|
222
271
|
this.baseUrl = options?.baseUrl || (0, server_url_1.resolveServerEndpoint)((0, server_url_1.loadClientEnv)()).url;
|
|
223
272
|
this.token = resolveAuthToken(options);
|
|
224
273
|
// [SEC4-02] Warn about HTTP to non-localhost
|
|
@@ -229,9 +278,11 @@ class ApiClient {
|
|
|
229
278
|
/**
|
|
230
279
|
* The base URL this client actually dials (Issue #2404).
|
|
231
280
|
*
|
|
232
|
-
* Resolved once in the constructor
|
|
233
|
-
*
|
|
234
|
-
*
|
|
281
|
+
* Resolved once in the constructor: the `baseUrl` option when a caller passes
|
|
282
|
+
* one (there is no CLI flag for it), else `CM_PORT` / `CM_BIND` through the
|
|
283
|
+
* precedence in `loadClientEnv()` (exported > `~/.commandmate/.env` > 3000;
|
|
284
|
+
* under `CM_UAT_ISOLATION=1` exported only, never 3000), which is why it is
|
|
285
|
+
* read from here rather than re-derived by each
|
|
235
286
|
* caller: a second derivation is a second answer, and "which server did this
|
|
236
287
|
* command talk to" only helps if it is the one the request went to.
|
|
237
288
|
*/
|
|
@@ -300,31 +351,7 @@ class ApiClient {
|
|
|
300
351
|
* [DR1-05] Generic type parameter specified at call site
|
|
301
352
|
*/
|
|
302
353
|
async post(path, body) {
|
|
303
|
-
|
|
304
|
-
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
305
|
-
method: 'POST',
|
|
306
|
-
headers: this.getHeaders(),
|
|
307
|
-
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
308
|
-
});
|
|
309
|
-
if (!response.ok) {
|
|
310
|
-
// Issue #1637: read the body first — handleApiError needs it to surface
|
|
311
|
-
// the server's reason for a 5xx instead of "check the logs".
|
|
312
|
-
const payload = await readErrorPayload(response);
|
|
313
|
-
const errResult = handleApiError(null, response.status, payload, { serverUrl: this.baseUrl });
|
|
314
|
-
throw new ApiError(errResult.message, errResult.exitCode, response.status, payload);
|
|
315
|
-
}
|
|
316
|
-
// Handle 204 No Content
|
|
317
|
-
const text = await response.text();
|
|
318
|
-
if (!text)
|
|
319
|
-
return undefined;
|
|
320
|
-
return JSON.parse(text);
|
|
321
|
-
}
|
|
322
|
-
catch (error) {
|
|
323
|
-
if (error instanceof ApiError)
|
|
324
|
-
throw error;
|
|
325
|
-
const errResult = handleApiError(error);
|
|
326
|
-
throw new ApiError(errResult.message, errResult.exitCode);
|
|
327
|
-
}
|
|
354
|
+
return sendWithBody(this.baseUrl, 'POST', this.getHeaders(), path, body);
|
|
328
355
|
}
|
|
329
356
|
/**
|
|
330
357
|
* HTTP PATCH request (Issue #1000: agent-instance roster mutations via
|
|
@@ -332,33 +359,38 @@ class ApiClient {
|
|
|
332
359
|
* [DR1-05] Generic type parameter specified at call site
|
|
333
360
|
*/
|
|
334
361
|
async patch(path, body) {
|
|
335
|
-
|
|
336
|
-
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
337
|
-
method: 'PATCH',
|
|
338
|
-
headers: this.getHeaders(),
|
|
339
|
-
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
340
|
-
});
|
|
341
|
-
if (!response.ok) {
|
|
342
|
-
// Issue #1637: read the body first — handleApiError needs it to surface
|
|
343
|
-
// the server's reason for a 5xx instead of "check the logs".
|
|
344
|
-
const payload = await readErrorPayload(response);
|
|
345
|
-
const errResult = handleApiError(null, response.status, payload, { serverUrl: this.baseUrl });
|
|
346
|
-
throw new ApiError(errResult.message, errResult.exitCode, response.status, payload);
|
|
347
|
-
}
|
|
348
|
-
const text = await response.text();
|
|
349
|
-
if (!text)
|
|
350
|
-
return undefined;
|
|
351
|
-
return JSON.parse(text);
|
|
352
|
-
}
|
|
353
|
-
catch (error) {
|
|
354
|
-
if (error instanceof ApiError)
|
|
355
|
-
throw error;
|
|
356
|
-
const errResult = handleApiError(error);
|
|
357
|
-
throw new ApiError(errResult.message, errResult.exitCode);
|
|
358
|
-
}
|
|
362
|
+
return sendWithBody(this.baseUrl, 'PATCH', this.getHeaders(), path, body);
|
|
359
363
|
}
|
|
360
364
|
}
|
|
361
365
|
exports.ApiClient = ApiClient;
|
|
366
|
+
/** POST / PATCH share everything but the method; an empty body (204) is `undefined`. */
|
|
367
|
+
async function sendWithBody(baseUrl, method, headers, path, body) {
|
|
368
|
+
try {
|
|
369
|
+
const response = await fetch(`${baseUrl}${path}`, {
|
|
370
|
+
method,
|
|
371
|
+
headers,
|
|
372
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
373
|
+
});
|
|
374
|
+
if (!response.ok) {
|
|
375
|
+
// Issue #1637: read the body first — handleApiError needs it to surface
|
|
376
|
+
// the server's reason for a 5xx instead of "check the logs".
|
|
377
|
+
const payload = await readErrorPayload(response);
|
|
378
|
+
const errResult = handleApiError(null, response.status, payload, { serverUrl: baseUrl });
|
|
379
|
+
throw new ApiError(errResult.message, errResult.exitCode, response.status, payload);
|
|
380
|
+
}
|
|
381
|
+
// Handle 204 No Content
|
|
382
|
+
const text = await response.text();
|
|
383
|
+
if (!text)
|
|
384
|
+
return undefined;
|
|
385
|
+
return JSON.parse(text);
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
if (error instanceof ApiError)
|
|
389
|
+
throw error;
|
|
390
|
+
const errResult = handleApiError(error);
|
|
391
|
+
throw new ApiError(errResult.message, errResult.exitCode);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
362
394
|
/**
|
|
363
395
|
* Read the typed error body of a failed response.
|
|
364
396
|
*
|
|
@@ -80,6 +80,7 @@ export declare function loadEnvFileValues(envPath?: string): Record<string, stri
|
|
|
80
80
|
* reported the .env port.
|
|
81
81
|
*
|
|
82
82
|
* Resolution order: `process.env` > `~/.commandmate/.env` > resolveServerEndpoint() defaults.
|
|
83
|
+
* Under `CM_UAT_ISOLATION=1` the file layer is skipped (Issue #3360).
|
|
83
84
|
*
|
|
84
85
|
* Neither of the two consults the file *alone*; {@link loadEnvFileValues} is the loader for
|
|
85
86
|
* the question where the shell must not appear as a layer at all.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-url.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/server-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"server-url.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/server-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAErE,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3B,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,SAAS,GAAG,cAAc,CAQpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,UAAU,CAWpE;AAaD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS1E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,aAAa,IAAI,SAAS,CAazC"}
|
|
@@ -14,6 +14,7 @@ exports.loadEffectiveEnv = loadEffectiveEnv;
|
|
|
14
14
|
exports.loadEnvFileValues = loadEnvFileValues;
|
|
15
15
|
exports.loadClientEnv = loadClientEnv;
|
|
16
16
|
const dotenv_1 = require("dotenv");
|
|
17
|
+
const uat_isolation_1 = require("../../config/uat-isolation");
|
|
17
18
|
const env_setup_1 = require("./env-setup");
|
|
18
19
|
/**
|
|
19
20
|
* Resolve the endpoint a server started with `env` is reachable at.
|
|
@@ -104,11 +105,17 @@ function loadEnvFileValues(envPath) {
|
|
|
104
105
|
* reported the .env port.
|
|
105
106
|
*
|
|
106
107
|
* Resolution order: `process.env` > `~/.commandmate/.env` > resolveServerEndpoint() defaults.
|
|
108
|
+
* Under `CM_UAT_ISOLATION=1` the file layer is skipped (Issue #3360).
|
|
107
109
|
*
|
|
108
110
|
* Neither of the two consults the file *alone*; {@link loadEnvFileValues} is the loader for
|
|
109
111
|
* the question where the shell must not appear as a layer at all.
|
|
110
112
|
*/
|
|
111
113
|
function loadClientEnv() {
|
|
114
|
+
// Issue #3360: a UAT / daily-check client (`CM_UAT_ISOLATION=1`) reads no .env at all —
|
|
115
|
+
// not ~/.commandmate/.env (global install), not ./.env (local) — so the target is only
|
|
116
|
+
// ever what the caller exported. ApiClient refuses to fall back to 3000 in this mode.
|
|
117
|
+
if ((0, uat_isolation_1.isUatIsolationEnabled)())
|
|
118
|
+
return { ...process.env };
|
|
112
119
|
// parseEnvFile() is a read-only lookup: left to its defaults dotenv would populate
|
|
113
120
|
// process.env with every key the file defines, turning file values into "exported" ones
|
|
114
121
|
// for the rest of the process — the precedence this function exists to avoid.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `CM_UAT_ISOLATION=1` — the mode a UAT / daily-check server and its CLI run in
|
|
3
|
+
* (Issue #3360).
|
|
4
|
+
*
|
|
5
|
+
* A UAT server is isolated from production by its own port, DB, tmux socket and
|
|
6
|
+
* state directories (`.commandmate/uat.yaml`). Three paths were left that those
|
|
7
|
+
* do not cover, because they are keyed by the user's login rather than by
|
|
8
|
+
* anything the UAT can move:
|
|
9
|
+
*
|
|
10
|
+
* 1. **codex's shared files.** `$CODEX_HOME/hooks.json`, the relay under
|
|
11
|
+
* `$CODEX_HOME/commandmate/` and the hook trust in `config.toml` live beside
|
|
12
|
+
* codex's login (`auth.json`), so moving `CODEX_HOME` logs codex out. In this
|
|
13
|
+
* mode the server writes none of them: it reuses the shared file only when it
|
|
14
|
+
* is already byte-identical to what this build would write (the per-session
|
|
15
|
+
* URL travels in the environment, so the hooks then reach THIS server), and
|
|
16
|
+
* otherwise refuses the launch ({@link UatIsolationLaunchRefusedError}) —
|
|
17
|
+
* a bare codex would still read the shared file and run production's hooks.
|
|
18
|
+
* antigravity's `~/.gemini/config/hooks.json` and copilot's
|
|
19
|
+
* `~/.copilot/settings.json` (Issue #3391) are handled the same way. It
|
|
20
|
+
* also never answers the hook review with *trust*, which is codex writing
|
|
21
|
+
* `config.toml`.
|
|
22
|
+
* 2. **claude's user-level hooks.** `--settings` is added to
|
|
23
|
+
* `~/.claude/settings.json`, not substituted for it, so the user's own hooks
|
|
24
|
+
* (which post to production) would run in a UAT session too. Moving
|
|
25
|
+
* `CLAUDE_CONFIG_DIR` logs claude out (measured, `-p` and interactive). In
|
|
26
|
+
* this mode claude is launched with `--setting-sources project,local`, which
|
|
27
|
+
* drops the user source and keeps `--settings` (measured on 2.1.289) — the
|
|
28
|
+
* interactive launch and `claude -p` (Schedules, daily summary) alike.
|
|
29
|
+
* 3. **the CLI's `.env`.** A client in this mode reads no `.env` file at all and
|
|
30
|
+
* refuses to fall back to port 3000: it dials only the `CM_PORT` the caller
|
|
31
|
+
* exported.
|
|
32
|
+
*
|
|
33
|
+
* Unset (or any value other than `1` / `own-home`) changes nothing anywhere.
|
|
34
|
+
*
|
|
35
|
+
* ## `CM_UAT_ISOLATION=own-home` (Issue #3312)
|
|
36
|
+
*
|
|
37
|
+
* For a run under a dedicated OS user (the daily product-path check), whose
|
|
38
|
+
* HOME holds nobody else's CLI config. Everything above still holds — the
|
|
39
|
+
* launch is refused rather than started bare when hook setup fails, the
|
|
40
|
+
* receiver URL travels in the launch environment, headless `codex exec` /
|
|
41
|
+
* `agy -p` are refused, claude reads no user-level settings, the CLI reads no
|
|
42
|
+
* `.env` and never falls back to 3000 — with one difference: the shared hook
|
|
43
|
+
* files (codex's `hooks.json`, relay and trust, antigravity's and copilot's
|
|
44
|
+
* hook files, the claude settings under `CM_AGENT_HOOKS_DIR`) are WRITTEN by
|
|
45
|
+
* this build, instead of being reused read-only. Only after
|
|
46
|
+
* {@link assertUatOwnHomeWriteTargets} has checked, before each launch, that
|
|
47
|
+
* this process runs as `CM_UAT_DEDICATED_USER`, that HOME is that user's, and
|
|
48
|
+
* that every file it is about to write resolves (symlinks followed) to a place
|
|
49
|
+
* inside that HOME owned by that user. {@link sharedHookWritePolicy} is the one
|
|
50
|
+
* rule each tool's launch path calls.
|
|
51
|
+
*
|
|
52
|
+
* `docs/user-guide/uat-isolation.md` has the measurement table and the skip
|
|
53
|
+
* conditions for what cannot be isolated.
|
|
54
|
+
*
|
|
55
|
+
* @module config/uat-isolation
|
|
56
|
+
*/
|
|
57
|
+
/** The switch. Only the exact values `1` and `own-home` turn it on. */
|
|
58
|
+
export declare const UAT_ISOLATION_ENV_VAR = "CM_UAT_ISOLATION";
|
|
59
|
+
/** The value of {@link UAT_ISOLATION_ENV_VAR} for a run under a dedicated OS user (Issue #3312). */
|
|
60
|
+
export declare const UAT_ISOLATION_OWN_HOME = "own-home";
|
|
61
|
+
/** The login name `own-home` must run as (Issue #3312). Compared with `os.userInfo().username`. */
|
|
62
|
+
export declare const UAT_DEDICATED_USER_ENV_VAR = "CM_UAT_DEDICATED_USER";
|
|
63
|
+
/**
|
|
64
|
+
* - `off`: not isolated.
|
|
65
|
+
* - `shared-read-only` (`1`): the shared hook files are reused only when they
|
|
66
|
+
* already match this build, never written.
|
|
67
|
+
* - `own-home`: the shared hook files are written, inside the dedicated user's
|
|
68
|
+
* own HOME only (Issue #3312).
|
|
69
|
+
*/
|
|
70
|
+
export type UatIsolationMode = 'off' | 'shared-read-only' | 'own-home';
|
|
71
|
+
/**
|
|
72
|
+
* `--setting-sources` for a claude session in this mode: the user source
|
|
73
|
+
* (`$CLAUDE_CONFIG_DIR/settings.json`, hooks and plugins included) is dropped;
|
|
74
|
+
* the repository's own `project` / `local` settings and `--settings` stay.
|
|
75
|
+
*/
|
|
76
|
+
export declare const CLAUDE_UAT_SETTING_SOURCES = "project,local";
|
|
77
|
+
type Env = Readonly<Record<string, string | undefined>>;
|
|
78
|
+
/** Which isolation mode this process runs in. */
|
|
79
|
+
export declare function getUatIsolationMode(env?: Env): UatIsolationMode;
|
|
80
|
+
/**
|
|
81
|
+
* Whether this process runs in UAT isolation mode — `1` or `own-home`. Every
|
|
82
|
+
* protection except "never write the shared hook files" keys off this.
|
|
83
|
+
*/
|
|
84
|
+
export declare function isUatIsolationEnabled(env?: Env): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Thrown by a launch that would otherwise start an agent which reads a shared
|
|
87
|
+
* hook config this server did not (and in this mode may not) write.
|
|
88
|
+
*
|
|
89
|
+
* Starting the agent "without hooks" is not an option for codex, antigravity
|
|
90
|
+
* or copilot: the shared file is read regardless of what this server passes,
|
|
91
|
+
* so the production server's hooks — already trusted — would run in the UAT
|
|
92
|
+
* session and post to production. So the launch is refused, and the message says what
|
|
93
|
+
* makes it start.
|
|
94
|
+
*/
|
|
95
|
+
export declare class UatIsolationLaunchRefusedError extends Error {
|
|
96
|
+
constructor(tool: string, reason: string, fix: string);
|
|
97
|
+
}
|
|
98
|
+
/** The fix for a shared hook config that does not match this build. */
|
|
99
|
+
export declare const UAT_SAME_BUILD_FIX = "Run the UAT with the same CommandMate build as the production server, so the shared file already matches what this build writes.";
|
|
100
|
+
/** The fix for an `own-home` launch whose user, HOME or write targets did not check out. */
|
|
101
|
+
export declare const UAT_OWN_HOME_FIX: string;
|
|
102
|
+
/** Who this process is. `os.userInfo()` reads the account database, not `$HOME`. */
|
|
103
|
+
export interface ProcessIdentity {
|
|
104
|
+
username: string;
|
|
105
|
+
uid: number;
|
|
106
|
+
homedir: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Why an `own-home` launch may not write `writeTargets`, or null when it may
|
|
110
|
+
* (Issue #3312). Checks, in this order: `CM_UAT_DEDICATED_USER` is set and is
|
|
111
|
+
* the user this process runs as; `HOME` resolves to that user's home directory
|
|
112
|
+
* (from the account database) and is owned by them; each target resolves —
|
|
113
|
+
* every symlink on the way followed — to a path inside that home, and the entry
|
|
114
|
+
* that decides the write (the target, or its nearest existing ancestor) is
|
|
115
|
+
* owned by that user.
|
|
116
|
+
*/
|
|
117
|
+
export declare function checkUatOwnHomeWriteTargets(writeTargets: readonly string[], env?: Env, identity?: ProcessIdentity): string | null;
|
|
118
|
+
/**
|
|
119
|
+
* Under `own-home`, refuse the launch of `tool` unless
|
|
120
|
+
* {@link checkUatOwnHomeWriteTargets} passes for `writeTargets`. A no-op in
|
|
121
|
+
* every other mode.
|
|
122
|
+
*
|
|
123
|
+
* @throws {UatIsolationLaunchRefusedError}
|
|
124
|
+
*/
|
|
125
|
+
export declare function assertUatOwnHomeWriteTargets(tool: string, writeTargets: readonly string[], env?: Env): void;
|
|
126
|
+
/**
|
|
127
|
+
* The one rule for a hook file shared with the user's other CommandMate
|
|
128
|
+
* servers (codex, antigravity and copilot call it; Issue #3312):
|
|
129
|
+
*
|
|
130
|
+
* - not isolated: `write`
|
|
131
|
+
* - `CM_UAT_ISOLATION=1`: `read-only` — reuse it only when it already matches
|
|
132
|
+
* - `CM_UAT_ISOLATION=own-home`: `write`, once
|
|
133
|
+
* {@link assertUatOwnHomeWriteTargets} has passed for every path the write
|
|
134
|
+
* touches; otherwise the launch is refused
|
|
135
|
+
*
|
|
136
|
+
* @throws {UatIsolationLaunchRefusedError} Under `own-home` only
|
|
137
|
+
*/
|
|
138
|
+
export declare function sharedHookWritePolicy(tool: string, writeTargets: readonly string[], env?: Env): 'write' | 'read-only';
|
|
139
|
+
export {};
|
|
140
|
+
//# sourceMappingURL=uat-isolation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uat-isolation.d.ts","sourceRoot":"","sources":["../../src/config/uat-isolation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAMH,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,oGAAoG;AACpG,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD,mGAAmG;AACnG,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAElE;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,kBAAkB,GAAG,UAAU,CAAC;AAEvE;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,kBAAkB,CAAC;AAE1D,KAAK,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AAExD,iDAAiD;AACjD,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,GAAiB,GAAG,gBAAgB,CAK5E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,GAAE,GAAiB,GAAG,OAAO,CAErE;AAED;;;;;;;;;GASG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CAYtD;AAED,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,qIACqG,CAAC;AAErI,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,QAEqF,CAAC;AAEnH,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAyCD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,GAAG,GAAE,GAAiB,EACtB,QAAQ,GAAE,eAAmC,GAC5C,MAAM,GAAG,IAAI,CAgCf;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,GAAG,GAAE,GAAiB,GACrB,IAAI,CAIN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,GAAG,GAAE,GAAiB,GACrB,OAAO,GAAG,WAAW,CAKvB"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `CM_UAT_ISOLATION=1` — the mode a UAT / daily-check server and its CLI run in
|
|
4
|
+
* (Issue #3360).
|
|
5
|
+
*
|
|
6
|
+
* A UAT server is isolated from production by its own port, DB, tmux socket and
|
|
7
|
+
* state directories (`.commandmate/uat.yaml`). Three paths were left that those
|
|
8
|
+
* do not cover, because they are keyed by the user's login rather than by
|
|
9
|
+
* anything the UAT can move:
|
|
10
|
+
*
|
|
11
|
+
* 1. **codex's shared files.** `$CODEX_HOME/hooks.json`, the relay under
|
|
12
|
+
* `$CODEX_HOME/commandmate/` and the hook trust in `config.toml` live beside
|
|
13
|
+
* codex's login (`auth.json`), so moving `CODEX_HOME` logs codex out. In this
|
|
14
|
+
* mode the server writes none of them: it reuses the shared file only when it
|
|
15
|
+
* is already byte-identical to what this build would write (the per-session
|
|
16
|
+
* URL travels in the environment, so the hooks then reach THIS server), and
|
|
17
|
+
* otherwise refuses the launch ({@link UatIsolationLaunchRefusedError}) —
|
|
18
|
+
* a bare codex would still read the shared file and run production's hooks.
|
|
19
|
+
* antigravity's `~/.gemini/config/hooks.json` and copilot's
|
|
20
|
+
* `~/.copilot/settings.json` (Issue #3391) are handled the same way. It
|
|
21
|
+
* also never answers the hook review with *trust*, which is codex writing
|
|
22
|
+
* `config.toml`.
|
|
23
|
+
* 2. **claude's user-level hooks.** `--settings` is added to
|
|
24
|
+
* `~/.claude/settings.json`, not substituted for it, so the user's own hooks
|
|
25
|
+
* (which post to production) would run in a UAT session too. Moving
|
|
26
|
+
* `CLAUDE_CONFIG_DIR` logs claude out (measured, `-p` and interactive). In
|
|
27
|
+
* this mode claude is launched with `--setting-sources project,local`, which
|
|
28
|
+
* drops the user source and keeps `--settings` (measured on 2.1.289) — the
|
|
29
|
+
* interactive launch and `claude -p` (Schedules, daily summary) alike.
|
|
30
|
+
* 3. **the CLI's `.env`.** A client in this mode reads no `.env` file at all and
|
|
31
|
+
* refuses to fall back to port 3000: it dials only the `CM_PORT` the caller
|
|
32
|
+
* exported.
|
|
33
|
+
*
|
|
34
|
+
* Unset (or any value other than `1` / `own-home`) changes nothing anywhere.
|
|
35
|
+
*
|
|
36
|
+
* ## `CM_UAT_ISOLATION=own-home` (Issue #3312)
|
|
37
|
+
*
|
|
38
|
+
* For a run under a dedicated OS user (the daily product-path check), whose
|
|
39
|
+
* HOME holds nobody else's CLI config. Everything above still holds — the
|
|
40
|
+
* launch is refused rather than started bare when hook setup fails, the
|
|
41
|
+
* receiver URL travels in the launch environment, headless `codex exec` /
|
|
42
|
+
* `agy -p` are refused, claude reads no user-level settings, the CLI reads no
|
|
43
|
+
* `.env` and never falls back to 3000 — with one difference: the shared hook
|
|
44
|
+
* files (codex's `hooks.json`, relay and trust, antigravity's and copilot's
|
|
45
|
+
* hook files, the claude settings under `CM_AGENT_HOOKS_DIR`) are WRITTEN by
|
|
46
|
+
* this build, instead of being reused read-only. Only after
|
|
47
|
+
* {@link assertUatOwnHomeWriteTargets} has checked, before each launch, that
|
|
48
|
+
* this process runs as `CM_UAT_DEDICATED_USER`, that HOME is that user's, and
|
|
49
|
+
* that every file it is about to write resolves (symlinks followed) to a place
|
|
50
|
+
* inside that HOME owned by that user. {@link sharedHookWritePolicy} is the one
|
|
51
|
+
* rule each tool's launch path calls.
|
|
52
|
+
*
|
|
53
|
+
* `docs/user-guide/uat-isolation.md` has the measurement table and the skip
|
|
54
|
+
* conditions for what cannot be isolated.
|
|
55
|
+
*
|
|
56
|
+
* @module config/uat-isolation
|
|
57
|
+
*/
|
|
58
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
59
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
60
|
+
};
|
|
61
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
|
+
exports.UAT_OWN_HOME_FIX = exports.UAT_SAME_BUILD_FIX = exports.UatIsolationLaunchRefusedError = exports.CLAUDE_UAT_SETTING_SOURCES = exports.UAT_DEDICATED_USER_ENV_VAR = exports.UAT_ISOLATION_OWN_HOME = exports.UAT_ISOLATION_ENV_VAR = void 0;
|
|
63
|
+
exports.getUatIsolationMode = getUatIsolationMode;
|
|
64
|
+
exports.isUatIsolationEnabled = isUatIsolationEnabled;
|
|
65
|
+
exports.checkUatOwnHomeWriteTargets = checkUatOwnHomeWriteTargets;
|
|
66
|
+
exports.assertUatOwnHomeWriteTargets = assertUatOwnHomeWriteTargets;
|
|
67
|
+
exports.sharedHookWritePolicy = sharedHookWritePolicy;
|
|
68
|
+
const fs_1 = __importDefault(require("fs"));
|
|
69
|
+
const os_1 = __importDefault(require("os"));
|
|
70
|
+
const path_1 = __importDefault(require("path"));
|
|
71
|
+
/** The switch. Only the exact values `1` and `own-home` turn it on. */
|
|
72
|
+
exports.UAT_ISOLATION_ENV_VAR = 'CM_UAT_ISOLATION';
|
|
73
|
+
/** The value of {@link UAT_ISOLATION_ENV_VAR} for a run under a dedicated OS user (Issue #3312). */
|
|
74
|
+
exports.UAT_ISOLATION_OWN_HOME = 'own-home';
|
|
75
|
+
/** The login name `own-home` must run as (Issue #3312). Compared with `os.userInfo().username`. */
|
|
76
|
+
exports.UAT_DEDICATED_USER_ENV_VAR = 'CM_UAT_DEDICATED_USER';
|
|
77
|
+
/**
|
|
78
|
+
* `--setting-sources` for a claude session in this mode: the user source
|
|
79
|
+
* (`$CLAUDE_CONFIG_DIR/settings.json`, hooks and plugins included) is dropped;
|
|
80
|
+
* the repository's own `project` / `local` settings and `--settings` stay.
|
|
81
|
+
*/
|
|
82
|
+
exports.CLAUDE_UAT_SETTING_SOURCES = 'project,local';
|
|
83
|
+
/** Which isolation mode this process runs in. */
|
|
84
|
+
function getUatIsolationMode(env = process.env) {
|
|
85
|
+
const value = env[exports.UAT_ISOLATION_ENV_VAR];
|
|
86
|
+
if (value === '1')
|
|
87
|
+
return 'shared-read-only';
|
|
88
|
+
if (value === exports.UAT_ISOLATION_OWN_HOME)
|
|
89
|
+
return 'own-home';
|
|
90
|
+
return 'off';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Whether this process runs in UAT isolation mode — `1` or `own-home`. Every
|
|
94
|
+
* protection except "never write the shared hook files" keys off this.
|
|
95
|
+
*/
|
|
96
|
+
function isUatIsolationEnabled(env = process.env) {
|
|
97
|
+
return getUatIsolationMode(env) !== 'off';
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Thrown by a launch that would otherwise start an agent which reads a shared
|
|
101
|
+
* hook config this server did not (and in this mode may not) write.
|
|
102
|
+
*
|
|
103
|
+
* Starting the agent "without hooks" is not an option for codex, antigravity
|
|
104
|
+
* or copilot: the shared file is read regardless of what this server passes,
|
|
105
|
+
* so the production server's hooks — already trusted — would run in the UAT
|
|
106
|
+
* session and post to production. So the launch is refused, and the message says what
|
|
107
|
+
* makes it start.
|
|
108
|
+
*/
|
|
109
|
+
class UatIsolationLaunchRefusedError extends Error {
|
|
110
|
+
constructor(tool, reason, fix) {
|
|
111
|
+
super(getUatIsolationMode() === 'own-home'
|
|
112
|
+
? `${exports.UAT_ISOLATION_ENV_VAR}=${exports.UAT_ISOLATION_OWN_HOME}: refusing to start ${tool}: ${reason}. ` +
|
|
113
|
+
`This server writes the hook config only inside the dedicated user's own HOME, and ${tool} ` +
|
|
114
|
+
`would otherwise start with hooks this server did not prepare. ${fix}`
|
|
115
|
+
: `${exports.UAT_ISOLATION_ENV_VAR}=1: refusing to start ${tool}: ${reason}. ` +
|
|
116
|
+
`This server does not write the shared hook config in UAT isolation, and ${tool} ` +
|
|
117
|
+
`would read it anyway and run the production hooks. ${fix}`);
|
|
118
|
+
this.name = 'UatIsolationLaunchRefusedError';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.UatIsolationLaunchRefusedError = UatIsolationLaunchRefusedError;
|
|
122
|
+
/** The fix for a shared hook config that does not match this build. */
|
|
123
|
+
exports.UAT_SAME_BUILD_FIX = 'Run the UAT with the same CommandMate build as the production server, so the shared file already matches what this build writes.';
|
|
124
|
+
/** The fix for an `own-home` launch whose user, HOME or write targets did not check out. */
|
|
125
|
+
exports.UAT_OWN_HOME_FIX = `Run ${exports.UAT_ISOLATION_ENV_VAR}=${exports.UAT_ISOLATION_OWN_HOME} as the user named by ${exports.UAT_DEDICATED_USER_ENV_VAR}, ` +
|
|
126
|
+
'with HOME set to that user\'s home and every hook config path (CODEX_HOME, CM_AGENT_HOOKS_DIR, ...) inside it.';
|
|
127
|
+
function currentIdentity() {
|
|
128
|
+
const info = os_1.default.userInfo();
|
|
129
|
+
return { username: info.username, uid: info.uid, homedir: info.homedir };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Where a write to `target` would land, symlinks followed, and whose entry
|
|
133
|
+
* decides who may write there: the target itself when it exists, else its
|
|
134
|
+
* nearest existing ancestor (a file not yet created is judged by the directory
|
|
135
|
+
* it would be created in). A dangling symlink is refused: writing through it
|
|
136
|
+
* would create a file wherever it points.
|
|
137
|
+
*/
|
|
138
|
+
function resolveWriteTarget(target) {
|
|
139
|
+
const absolute = path_1.default.resolve(target);
|
|
140
|
+
let existing = absolute;
|
|
141
|
+
const rest = [];
|
|
142
|
+
for (;;) {
|
|
143
|
+
let entryExists = false;
|
|
144
|
+
try {
|
|
145
|
+
fs_1.default.lstatSync(existing);
|
|
146
|
+
entryExists = true;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
entryExists = false;
|
|
150
|
+
}
|
|
151
|
+
if (entryExists)
|
|
152
|
+
break;
|
|
153
|
+
const parent = path_1.default.dirname(existing);
|
|
154
|
+
if (parent === existing)
|
|
155
|
+
return `${target} has no existing ancestor`;
|
|
156
|
+
rest.unshift(path_1.default.basename(existing));
|
|
157
|
+
existing = parent;
|
|
158
|
+
}
|
|
159
|
+
let real;
|
|
160
|
+
try {
|
|
161
|
+
real = fs_1.default.realpathSync(existing);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return `${existing} is a symlink that points nowhere`;
|
|
165
|
+
}
|
|
166
|
+
return { real: path_1.default.join(real, ...rest), owner: fs_1.default.statSync(real).uid };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Why an `own-home` launch may not write `writeTargets`, or null when it may
|
|
170
|
+
* (Issue #3312). Checks, in this order: `CM_UAT_DEDICATED_USER` is set and is
|
|
171
|
+
* the user this process runs as; `HOME` resolves to that user's home directory
|
|
172
|
+
* (from the account database) and is owned by them; each target resolves —
|
|
173
|
+
* every symlink on the way followed — to a path inside that home, and the entry
|
|
174
|
+
* that decides the write (the target, or its nearest existing ancestor) is
|
|
175
|
+
* owned by that user.
|
|
176
|
+
*/
|
|
177
|
+
function checkUatOwnHomeWriteTargets(writeTargets, env = process.env, identity = currentIdentity()) {
|
|
178
|
+
const dedicated = env[exports.UAT_DEDICATED_USER_ENV_VAR];
|
|
179
|
+
if (!dedicated)
|
|
180
|
+
return `${exports.UAT_DEDICATED_USER_ENV_VAR} is not set`;
|
|
181
|
+
if (identity.username !== dedicated) {
|
|
182
|
+
return `this process runs as ${identity.username}, not as the dedicated user ${dedicated}`;
|
|
183
|
+
}
|
|
184
|
+
const home = env.HOME;
|
|
185
|
+
if (!home || !path_1.default.isAbsolute(home))
|
|
186
|
+
return 'HOME is not set to an absolute path';
|
|
187
|
+
let homeReal;
|
|
188
|
+
let accountHomeReal;
|
|
189
|
+
try {
|
|
190
|
+
homeReal = fs_1.default.realpathSync(home);
|
|
191
|
+
accountHomeReal = fs_1.default.realpathSync(identity.homedir);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return `HOME (${home}) or ${dedicated}'s home directory (${identity.homedir}) does not exist`;
|
|
195
|
+
}
|
|
196
|
+
if (homeReal !== accountHomeReal) {
|
|
197
|
+
return `HOME (${home}) is not ${dedicated}'s home directory (${identity.homedir})`;
|
|
198
|
+
}
|
|
199
|
+
if (fs_1.default.statSync(homeReal).uid !== identity.uid)
|
|
200
|
+
return `HOME (${home}) is not owned by ${dedicated}`;
|
|
201
|
+
for (const target of writeTargets) {
|
|
202
|
+
const resolved = resolveWriteTarget(target);
|
|
203
|
+
if (typeof resolved === 'string')
|
|
204
|
+
return resolved;
|
|
205
|
+
if (resolved.real !== homeReal && !resolved.real.startsWith(`${homeReal}${path_1.default.sep}`)) {
|
|
206
|
+
return `${target} resolves to ${resolved.real}, outside ${dedicated}'s HOME (${homeReal})`;
|
|
207
|
+
}
|
|
208
|
+
if (resolved.owner !== identity.uid) {
|
|
209
|
+
return `${target} (${resolved.real}) is not owned by ${dedicated}`;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Under `own-home`, refuse the launch of `tool` unless
|
|
216
|
+
* {@link checkUatOwnHomeWriteTargets} passes for `writeTargets`. A no-op in
|
|
217
|
+
* every other mode.
|
|
218
|
+
*
|
|
219
|
+
* @throws {UatIsolationLaunchRefusedError}
|
|
220
|
+
*/
|
|
221
|
+
function assertUatOwnHomeWriteTargets(tool, writeTargets, env = process.env) {
|
|
222
|
+
if (getUatIsolationMode(env) !== 'own-home')
|
|
223
|
+
return;
|
|
224
|
+
const problem = checkUatOwnHomeWriteTargets(writeTargets, env);
|
|
225
|
+
if (problem)
|
|
226
|
+
throw new UatIsolationLaunchRefusedError(tool, problem, exports.UAT_OWN_HOME_FIX);
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* The one rule for a hook file shared with the user's other CommandMate
|
|
230
|
+
* servers (codex, antigravity and copilot call it; Issue #3312):
|
|
231
|
+
*
|
|
232
|
+
* - not isolated: `write`
|
|
233
|
+
* - `CM_UAT_ISOLATION=1`: `read-only` — reuse it only when it already matches
|
|
234
|
+
* - `CM_UAT_ISOLATION=own-home`: `write`, once
|
|
235
|
+
* {@link assertUatOwnHomeWriteTargets} has passed for every path the write
|
|
236
|
+
* touches; otherwise the launch is refused
|
|
237
|
+
*
|
|
238
|
+
* @throws {UatIsolationLaunchRefusedError} Under `own-home` only
|
|
239
|
+
*/
|
|
240
|
+
function sharedHookWritePolicy(tool, writeTargets, env = process.env) {
|
|
241
|
+
const mode = getUatIsolationMode(env);
|
|
242
|
+
if (mode === 'shared-read-only')
|
|
243
|
+
return 'read-only';
|
|
244
|
+
assertUatOwnHomeWriteTargets(tool, writeTargets, env);
|
|
245
|
+
return 'write';
|
|
246
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide state helper for the `globalThis.__*` cache pattern.
|
|
3
|
+
*
|
|
4
|
+
* Returns the value already stored on `globalThis[key]`, or runs `init` once and
|
|
5
|
+
* stores its result. `init` runs only when the slot is `null`/`undefined`, at the
|
|
6
|
+
* moment this function is called (so callers keep their own init timing).
|
|
7
|
+
*
|
|
8
|
+
* `key` and the initial value are typed from each file's `declare global`
|
|
9
|
+
* declaration. This module imports nothing so any layer (server, CLI) can use it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getOrInitGlobal<K extends keyof typeof globalThis>(key: K, init: () => NonNullable<(typeof globalThis)[K]>): NonNullable<(typeof globalThis)[K]>;
|
|
12
|
+
//# sourceMappingURL=global-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-state.d.ts","sourceRoot":"","sources":["../../src/lib/global-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,OAAO,UAAU,EAC/D,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,MAAM,WAAW,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAC9C,WAAW,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAErC"}
|