commandmate 0.31.2 → 0.31.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 +161 -161
- package/.next/app-path-routes-manifest.json +33 -33
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +15 -15
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/agents/versions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js +1 -1
- package/.next/server/app/api/assistant/messages/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route.js +1 -1
- package/.next/server/app/api/assistant/session/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route.js +2 -2
- package/.next/server/app/api/assistant/start/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route.js +2 -2
- package/.next/server/app/api/assistant/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/capabilities/route.js +1 -1
- package/.next/server/app/api/capabilities/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/route_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.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_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 +2 -2
- package/.next/server/app/api/push/escalation/route.js.nft.json +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +2 -2
- package/.next/server/app/api/push/vapid/route.js.nft.json +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[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.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.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_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.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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_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]/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.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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/diff/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_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.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_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.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.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/uninstall-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/update-plan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/config/route_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]/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/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_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 +11 -11
- 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 +33 -33
- package/.next/server/chunks/1058.js +1 -1
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/1191.js +1 -1
- package/.next/server/chunks/1886.js +1 -1
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/261.js +1 -1
- package/.next/server/chunks/2739.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3484.js +1 -0
- package/.next/server/chunks/358.js +1 -0
- package/.next/server/chunks/4325.js +1 -1
- package/.next/server/chunks/4393.js +1 -1
- package/.next/server/chunks/4443.js +1 -1
- package/.next/server/chunks/5017.js +1 -1
- package/.next/server/chunks/5120.js +1 -1
- package/.next/server/chunks/5164.js +1 -1
- package/.next/server/chunks/552.js +2 -2
- package/.next/server/chunks/595.js +8 -0
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/8800.js +1 -1
- package/.next/server/chunks/8918.js +3 -3
- package/.next/server/chunks/9123.js +1 -1
- package/.next/server/chunks/9130.js +2 -2
- package/.next/server/chunks/9627.js +3 -3
- package/.next/server/chunks/9696.js +2 -2
- package/.next/server/chunks/9798.js +2 -2
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{1783-11c9b4d8a52ebd91.js → 2813-de885de8a4b11910.js} +1 -1
- package/.next/static/chunks/4718-07ec4e10186928db.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-91b639c90795baa9.js +1 -0
- package/.next/static/css/acc4b9c3feb04287.css +1 -0
- package/.next/trace +13 -13
- package/dist/lib/detection/tools/verified-against.d.ts +24 -24
- package/dist/lib/detection/tools/verified-against.js +24 -24
- package/dist/server/locales/en/worktree.json +1402 -0
- package/dist/server/locales/ja/worktree.json +1402 -0
- package/dist/server/src/lib/db/chat-db.js +44 -1
- package/dist/server/src/lib/detection/cli-patterns.js +157 -23
- package/dist/server/src/lib/detection/model-info-extractor.js +185 -4
- package/dist/server/src/lib/detection/tools/antigravity/detect.js +105 -25
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +233 -0
- package/dist/server/src/lib/detection/tools/verified-against.js +24 -24
- package/dist/server/src/lib/hooks/hook-settings-generator.js +16 -0
- package/dist/server/src/lib/hooks/sources/claude/model-switch.js +169 -0
- package/dist/server/src/lib/hooks/sources/claude/source.js +14 -1
- package/dist/server/src/lib/polling/response-checker.js +17 -1
- package/dist/server/src/lib/push/index.js +13 -1
- package/dist/server/src/lib/push/model-change-push-notifier.js +174 -0
- package/dist/server/src/lib/push/push-sender.js +48 -20
- package/dist/server/src/lib/realtime/model-change-broadcast.js +171 -0
- package/dist/server/src/lib/realtime/types.js +19 -1
- package/dist/server/src/lib/realtime/waiting-broadcast.js +13 -0
- package/dist/server/src/lib/session/agent-event-state.js +344 -12
- package/package.json +1 -1
- package/.next/server/chunks/6894.js +0 -8
- package/.next/server/chunks/7187.js +0 -1
- package/.next/server/chunks/7472.js +0 -1
- package/.next/static/chunks/4718-0d4d93c4c75f336e.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-7a0915e32a2af4d3.js +0 -1
- package/.next/static/css/5c13ea243dfdcb66.css +0 -1
- /package/.next/static/{GiOqe8rfQGQ0NvzB5qr3q → 0hTIackGXw6v7diXJS6yN}/_buildManifest.js +0 -0
- /package/.next/static/{GiOqe8rfQGQ0NvzB5qr3q → 0hTIackGXw6v7diXJS6yN}/_ssgManifest.js +0 -0
|
@@ -39,7 +39,10 @@
|
|
|
39
39
|
* @module lib/session/agent-event-state
|
|
40
40
|
*/
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.LIFECYCLE_AGENT_EVENT_TYPES = exports.STRUCTURED_PROMPT_PROVISIONAL_MAX_AGE_MS = exports.STRUCTURED_STATE_MAX_AGE_MS = exports.AGENT_EVENT_DEDUP_WINDOW_MS = void 0;
|
|
42
|
+
exports.LIFECYCLE_AGENT_EVENT_TYPES = exports.STRUCTURED_PROMPT_PROVISIONAL_MAX_AGE_MS = exports.STRUCTURED_STATE_MAX_AGE_MS = exports.AGENT_EVENT_DEDUP_WINDOW_MS = exports.AGENT_MODEL_EFFORT_SUFFIX_PATTERN = void 0;
|
|
43
|
+
exports.isSameAgentModelName = isSameAgentModelName;
|
|
44
|
+
exports.onAgentModelChange = onAgentModelChange;
|
|
45
|
+
exports.getAgentModelBaseline = getAgentModelBaseline;
|
|
43
46
|
exports.getAgentEventDropCounts = getAgentEventDropCounts;
|
|
44
47
|
exports.getPendingDecisions = getPendingDecisions;
|
|
45
48
|
exports.getAgentTurn = getAgentTurn;
|
|
@@ -156,8 +159,9 @@ const awaitingInstruction = globalThis.__agentEventAwaitingInstruction ??
|
|
|
156
159
|
*
|
|
157
160
|
* A *separate* map, not a field read off {@link lastAgentEvent}, and that is the
|
|
158
161
|
* whole point of it. `lastAgentEvent` is replaced wholesale on every delivery,
|
|
159
|
-
* and Claude puts the model on `SessionStart` and on
|
|
160
|
-
*
|
|
162
|
+
* and Claude puts the model on `SessionStart` and on a `PostModelSwitch`
|
|
163
|
+
* (Issue #2363) and on nothing else — so the very next `UserPromptSubmit` would
|
|
164
|
+
* overwrite the only record that ever knew it, and
|
|
161
165
|
* the UI would show the model for the fraction of a second between session start
|
|
162
166
|
* and the first prompt. Keeping the last *non-null* sighting separately is what
|
|
163
167
|
* makes "which model is this session on" answerable at all for that tool.
|
|
@@ -168,6 +172,22 @@ const awaitingInstruction = globalThis.__agentEventAwaitingInstruction ??
|
|
|
168
172
|
*/
|
|
169
173
|
const lastAgentModel = globalThis.__agentEventLastModel ??
|
|
170
174
|
(globalThis.__agentEventLastModel = new Map());
|
|
175
|
+
/**
|
|
176
|
+
* compositeKey -> epoch ms of the report that last wrote {@link lastAgentModel}
|
|
177
|
+
* (Issue #2361).
|
|
178
|
+
*
|
|
179
|
+
* Kept so the frame can be judged NEWER than the hook. When #2361 was measured
|
|
180
|
+
* on 2.1.263, Claude named its model on `SessionStart` and on nothing
|
|
181
|
+
* CommandMate registered — `/model` fired none of the seven events, and the
|
|
182
|
+
* `SessionStart` a `/clear` emits carries no `model` key — so after a switch
|
|
183
|
+
* the hook latch was a true statement about a process that had since changed
|
|
184
|
+
* its mind, and the screen was the only channel that heard it. Issue #2363
|
|
185
|
+
* registers `PostModelSwitch`, which re-stamps this on every switch; the stamp
|
|
186
|
+
* now matters for the sessions where that hook does not arrive. See
|
|
187
|
+
* {@link resolveAgentModel}.
|
|
188
|
+
*/
|
|
189
|
+
const lastAgentModelAt = globalThis.__agentEventLastModelAt ??
|
|
190
|
+
(globalThis.__agentEventLastModelAt = new Map());
|
|
171
191
|
/**
|
|
172
192
|
* compositeKey -> what the terminal frame last showed for this instance (#1784).
|
|
173
193
|
*
|
|
@@ -216,6 +236,186 @@ const capturedModelInfo = globalThis.__agentCapturedModelInfo ??
|
|
|
216
236
|
*/
|
|
217
237
|
const reportedEffort = globalThis.__agentEventLastEffort ??
|
|
218
238
|
(globalThis.__agentEventLastEffort = new Map());
|
|
239
|
+
/**
|
|
240
|
+
* compositeKey -> the model this instance was last observed on (Issue #2357).
|
|
241
|
+
*
|
|
242
|
+
* A *fourth* map beside the three latches rather than a comparison against
|
|
243
|
+
* them, because the latches are what they are for a reason: each remembers the
|
|
244
|
+
* last non-null value its channel produced, and none of them can say "and the
|
|
245
|
+
* value before that". This map holds exactly that — the previous answer of
|
|
246
|
+
* {@link getResolvedAgentModelInfo} — so a write to either latch can be judged
|
|
247
|
+
* as "same model", "first sighting" or "changed" without re-deriving history
|
|
248
|
+
* from maps that never kept it.
|
|
249
|
+
*
|
|
250
|
+
* Cleared wherever the latches are cleared (generation, discard, test seam) and
|
|
251
|
+
* on `session_start`, so the first model a new agent process reports is
|
|
252
|
+
* recorded as its starting model and announced to nobody.
|
|
253
|
+
*/
|
|
254
|
+
const modelBaseline = globalThis.__agentModelBaseline ??
|
|
255
|
+
(globalThis.__agentModelBaseline = new Map());
|
|
256
|
+
/**
|
|
257
|
+
* Listeners for the model edge, on `globalThis` for the reason the maps above
|
|
258
|
+
* are: under `next dev` each route bundle evaluates this module once, and the
|
|
259
|
+
* hook route (which writes the hook latch) and the status poll (which writes
|
|
260
|
+
* the frame latch) are different bundles. A module-scoped set would let each
|
|
261
|
+
* bundle notify only the listeners registered in the same bundle — which is
|
|
262
|
+
* none, for the one that receives the hook.
|
|
263
|
+
*/
|
|
264
|
+
const modelChangeListeners = globalThis.__agentModelChangeListeners ??
|
|
265
|
+
(globalThis.__agentModelChangeListeners = new Set());
|
|
266
|
+
/**
|
|
267
|
+
* A trailing reasoning-effort token in a model id (`gemini-3.7-flash-high`).
|
|
268
|
+
*
|
|
269
|
+
* The same five words `model-info-extractor` recognises, matched only at the
|
|
270
|
+
* very end and only after a separator, so `gpt-5-mini` keeps its `mini` and a
|
|
271
|
+
* model that merely ends in these letters is untouched. agy encodes the effort
|
|
272
|
+
* in the id it reports on every event (`deriveEffortFromModelId`), and a user
|
|
273
|
+
* moving the same model from `high` to `low` has not changed model.
|
|
274
|
+
*/
|
|
275
|
+
exports.AGENT_MODEL_EFFORT_SUFFIX_PATTERN = /[-_ ](?:minimal|low|medium|high|xhigh)$/i;
|
|
276
|
+
/**
|
|
277
|
+
* Tokens a display label carries that the id does not, dropped before comparing.
|
|
278
|
+
*
|
|
279
|
+
* Measured pairs only: claude's banner reads `Opus 5 (1M context)` for the id
|
|
280
|
+
* `claude-opus-5[1m]` — the `1m` is part of the model, the word is not.
|
|
281
|
+
*/
|
|
282
|
+
const MODEL_LABEL_NOISE_PATTERN = /\bcontext\b/gi;
|
|
283
|
+
/** Lowercase alphanumerics, effort suffix and label-only words removed. */
|
|
284
|
+
function modelNameKey(value) {
|
|
285
|
+
return value
|
|
286
|
+
.replace(exports.AGENT_MODEL_EFFORT_SUFFIX_PATTERN, '')
|
|
287
|
+
.replace(MODEL_LABEL_NOISE_PATTERN, '')
|
|
288
|
+
.toLowerCase()
|
|
289
|
+
.replace(/[^a-z0-9]/g, '');
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Do two model names name the same model? (Issue #2357)
|
|
293
|
+
*
|
|
294
|
+
* Within one channel the answer is exact on alphanumerics — `GPT-5 mini` and
|
|
295
|
+
* `gpt-5-mini` are one model rendered two ways (copilot's bar and its notice,
|
|
296
|
+
* both read off the frame), while `gpt-5` and `gpt-5-mini` are two models and
|
|
297
|
+
* the second is precisely the downgrade this Issue exists to announce. The
|
|
298
|
+
* effort suffix is stripped first, because agy's id carries it and an effort
|
|
299
|
+
* change is not a model change.
|
|
300
|
+
*
|
|
301
|
+
* *Across* channels the rule is widened to containment: the hook reports an
|
|
302
|
+
* id, the screen prints a label, and every measured pair is the label's key
|
|
303
|
+
* inside the id's (`gemini37flash` ⊂ `gemini37flashhigh`, `opus51m` ⊂
|
|
304
|
+
* `claudeopus51m`, `claudesonnet46` ⊂ `anthropicclaudesonnet46`). Containment
|
|
305
|
+
* is NOT applied within a channel — it would fold `gpt-5` into `gpt-5-mini` —
|
|
306
|
+
* and a caller has to say which case it is in.
|
|
307
|
+
*
|
|
308
|
+
* Exported for the tests and for anything that has to agree with this module
|
|
309
|
+
* about identity; deliberately local rather than the extractor's `sameModel`,
|
|
310
|
+
* which is a single-channel exact match and is shared with #2358's edit.
|
|
311
|
+
*/
|
|
312
|
+
function isSameAgentModelName(a, b, options = {}) {
|
|
313
|
+
const ka = modelNameKey(a);
|
|
314
|
+
const kb = modelNameKey(b);
|
|
315
|
+
if (ka === kb)
|
|
316
|
+
return true;
|
|
317
|
+
if (!options.crossSource)
|
|
318
|
+
return false;
|
|
319
|
+
if (ka.length === 0 || kb.length === 0)
|
|
320
|
+
return false;
|
|
321
|
+
return ka.includes(kb) || kb.includes(ka);
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Subscribe to the model edge (Issue #2357).
|
|
325
|
+
*
|
|
326
|
+
* The listener receives every transition {@link observeAgentModel} judged to be
|
|
327
|
+
* a change — never a first sighting, never a value going quiet. `#2357`'s
|
|
328
|
+
* realtime broadcaster and push notifier are the two subscribers; neither keeps
|
|
329
|
+
* a "what was it last time?" of its own, which is the point of this being an
|
|
330
|
+
* edge rather than a level.
|
|
331
|
+
*
|
|
332
|
+
* @returns The unsubscribe function
|
|
333
|
+
*/
|
|
334
|
+
function onAgentModelChange(listener) {
|
|
335
|
+
modelChangeListeners.add(listener);
|
|
336
|
+
return () => {
|
|
337
|
+
modelChangeListeners.delete(listener);
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
/** Deliver one change; a listener that throws must not disturb the write that observed it. */
|
|
341
|
+
function emitAgentModelChange(change) {
|
|
342
|
+
for (const listener of modelChangeListeners) {
|
|
343
|
+
try {
|
|
344
|
+
listener(change);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// Advisory. The hook route and the status poll are the callers, and a
|
|
348
|
+
// notification failure is not a reason to fail either.
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* The model this instance was last observed on, or null. Test seam.
|
|
354
|
+
*/
|
|
355
|
+
function getAgentModelBaseline(worktreeId, cliToolId, instanceId) {
|
|
356
|
+
return modelBaseline.get((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId)) ?? null;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Judge the resolved model after a latch wrote, and announce a change
|
|
360
|
+
* (Issue #2357).
|
|
361
|
+
*
|
|
362
|
+
* Called after every write to {@link lastAgentModel} and
|
|
363
|
+
* {@link capturedModelInfo}, with the channel that wrote. What it compares is
|
|
364
|
+
* {@link getResolvedAgentModelInfo}'s *model* — the merged value the UI shows —
|
|
365
|
+
* against the previous merged value this map remembers. The suppression rules,
|
|
366
|
+
* each of which is a measured false positive:
|
|
367
|
+
*
|
|
368
|
+
* - **`null → value`** (first report, server restart): recorded as the
|
|
369
|
+
* starting model, announced to nobody.
|
|
370
|
+
* - **`value → null`**: cannot reach here — the latches never write null, so
|
|
371
|
+
* a frame that stopped showing the banner leaves the merged value where it
|
|
372
|
+
* was. A generation reset clears this map along with the latches, so the
|
|
373
|
+
* next value is a first sighting again.
|
|
374
|
+
* - **same name, either channel**: `GPT-5 mini` after `gpt-5-mini` is not a
|
|
375
|
+
* change. Compared with {@link isSameAgentModelName}; the cross-channel
|
|
376
|
+
* widening applies only when the merged value's source actually moved.
|
|
377
|
+
* - **`session_start`**: {@link recordAgentEvent} drops the baseline first, so
|
|
378
|
+
* the model a relaunched process reports is that process's starting model.
|
|
379
|
+
*
|
|
380
|
+
* Everything else is a change and is emitted exactly once — the baseline is
|
|
381
|
+
* advanced before the listeners run, so a listener that re-enters this module
|
|
382
|
+
* cannot see the same edge twice.
|
|
383
|
+
*/
|
|
384
|
+
function observeAgentModel(worktreeId, cliToolId, instanceId, source, at) {
|
|
385
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
386
|
+
// Where the merged value came from is decided in one place
|
|
387
|
+
// (`resolveAgentModel`, Issue #2361): the hook's, unless the frame overtook
|
|
388
|
+
// it — and that is independent of which channel just wrote.
|
|
389
|
+
const { info, source: resolvedSource } = resolveAgentModel(key, cliToolId);
|
|
390
|
+
const resolved = info.model;
|
|
391
|
+
if (resolved === null || resolvedSource === null)
|
|
392
|
+
return;
|
|
393
|
+
const previous = modelBaseline.get(key);
|
|
394
|
+
const next = { model: resolved, source: resolvedSource };
|
|
395
|
+
if (previous === undefined) {
|
|
396
|
+
modelBaseline.set(key, next);
|
|
397
|
+
trimOldestEntries(modelBaseline, MAX_RECENT_EVENT_KEYS);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
if (isSameAgentModelName(previous.model, resolved, {
|
|
401
|
+
crossSource: previous.source !== resolvedSource,
|
|
402
|
+
})) {
|
|
403
|
+
// Same model, possibly a new spelling or a new channel: follow it so the
|
|
404
|
+
// next comparison is against the current representation.
|
|
405
|
+
modelBaseline.set(key, next);
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
modelBaseline.set(key, next);
|
|
409
|
+
emitAgentModelChange({
|
|
410
|
+
worktreeId,
|
|
411
|
+
cliToolId,
|
|
412
|
+
instanceId: instanceId ?? cliToolId,
|
|
413
|
+
from: previous.model,
|
|
414
|
+
to: resolved,
|
|
415
|
+
source,
|
|
416
|
+
at,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
219
419
|
/**
|
|
220
420
|
* How long two identical events count as one delivery.
|
|
221
421
|
*
|
|
@@ -542,10 +742,20 @@ function recordAgentEvent(worktreeId, cliToolId, instanceId, record, options = {
|
|
|
542
742
|
// then dropped on the floor. copilot reports none today (#1783), which is
|
|
543
743
|
// exactly why this has to be decided here rather than left to be noticed.
|
|
544
744
|
latchAgentModel(key, record);
|
|
745
|
+
observeAgentModel(worktreeId, cliToolId, instanceId, 'hook', record.at);
|
|
545
746
|
return { recorded: false, skipped: 'late-session-start' };
|
|
546
747
|
}
|
|
547
748
|
lastAgentEvent.set(key, record);
|
|
749
|
+
if (record.event === 'session_start') {
|
|
750
|
+
// Issue #2357: a new agent process, whatever model it names first is its
|
|
751
|
+
// STARTING model — recorded below, announced to nobody. Dropped before the
|
|
752
|
+
// latch so the comparison in `observeAgentModel` has nothing to compare
|
|
753
|
+
// against. `/clear` (session_end + session_start on the same process, same
|
|
754
|
+
// model) passes through here unchanged: same name, no edge either way.
|
|
755
|
+
modelBaseline.delete(key);
|
|
756
|
+
}
|
|
548
757
|
latchAgentModel(key, record);
|
|
758
|
+
observeAgentModel(worktreeId, cliToolId, instanceId, 'hook', record.at);
|
|
549
759
|
applyAskUserQuestionTransition(key, record);
|
|
550
760
|
if (record.event === 'session_start') {
|
|
551
761
|
// The agent restarting inside a pane CommandMate never touched — `claude`
|
|
@@ -600,12 +810,17 @@ function fenceTurnForNewGeneration(key, at) {
|
|
|
600
810
|
}
|
|
601
811
|
/**
|
|
602
812
|
* Issue #1783: latch, never clear. An event without a model is the ordinary
|
|
603
|
-
* case (Claude sends one on `SessionStart`
|
|
604
|
-
* is now unknown" would blank the display
|
|
813
|
+
* case (Claude sends one on `SessionStart` and, since #2363, on a model
|
|
814
|
+
* switch), and reading it as "the model is now unknown" would blank the display
|
|
815
|
+
* on the very next event.
|
|
605
816
|
*/
|
|
606
817
|
function latchAgentModel(key, record) {
|
|
607
818
|
if (typeof record.model === 'string' && record.model !== '') {
|
|
608
819
|
lastAgentModel.set(key, record.model.slice(0, agent_event_types_1.MAX_EVENT_DETAIL_LENGTH));
|
|
820
|
+
// Issue #2361: stamped on every model-bearing report, not only on a change
|
|
821
|
+
// of value — a hook that names the same model again is the agent
|
|
822
|
+
// re-affirming it, and a frame has to be newer than THAT to overtake.
|
|
823
|
+
lastAgentModelAt.set(key, record.at);
|
|
609
824
|
}
|
|
610
825
|
}
|
|
611
826
|
/**
|
|
@@ -1110,8 +1325,9 @@ function getLastAgentEvent(worktreeId, cliToolId, instanceId) {
|
|
|
1110
1325
|
*
|
|
1111
1326
|
* "Last **non-null**", which is the only useful reading: three of the four tools
|
|
1112
1327
|
* that publish a model publish it on some events and not others, and Claude
|
|
1113
|
-
* publishes it on
|
|
1114
|
-
* therefore answer null for almost every
|
|
1328
|
+
* publishes it on two (`SessionStart`, and each switch since #2363). Reading
|
|
1329
|
+
* `getLastAgentEvent()?.model` would therefore answer null for almost every
|
|
1330
|
+
* moment of almost every session.
|
|
1115
1331
|
*
|
|
1116
1332
|
* Deliberately **not** bounded by {@link STRUCTURED_STATE_MAX_AGE_MS}, unlike
|
|
1117
1333
|
* every other reader in this module. That bound exists because a *status* that
|
|
@@ -1149,15 +1365,29 @@ function getLastKnownAgentModel(worktreeId, cliToolId, instanceId) {
|
|
|
1149
1365
|
*
|
|
1150
1366
|
* @param info - {@link import('../../lib/detection/model-info-extractor').extractModelInfo}'s answer
|
|
1151
1367
|
*/
|
|
1152
|
-
function recordCapturedModelInfo(worktreeId, cliToolId, instanceId, info) {
|
|
1368
|
+
function recordCapturedModelInfo(worktreeId, cliToolId, instanceId, info, at = Date.now()) {
|
|
1153
1369
|
if (!info.model && !info.effort)
|
|
1154
1370
|
return;
|
|
1155
1371
|
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
1156
1372
|
const previous = capturedModelInfo.get(key);
|
|
1373
|
+
const model = info.model ? info.model.slice(0, agent_event_types_1.MAX_EVENT_DETAIL_LENGTH) : (previous?.model ?? null);
|
|
1157
1374
|
capturedModelInfo.set(key, {
|
|
1158
|
-
model
|
|
1375
|
+
model,
|
|
1159
1376
|
effort: info.effort ?? previous?.effort ?? null,
|
|
1377
|
+
// Issue #2361: the change stamp moves only when the model half takes a
|
|
1378
|
+
// different value. A banner re-read on every poll keeps the stamp where the
|
|
1379
|
+
// first sighting put it, so it never out-dates a hook by mere repetition.
|
|
1380
|
+
modelChangedAt: model === null
|
|
1381
|
+
? null
|
|
1382
|
+
: model === (previous?.model ?? null)
|
|
1383
|
+
? (previous?.modelChangedAt ?? at)
|
|
1384
|
+
: at,
|
|
1160
1385
|
});
|
|
1386
|
+
// Issue #2357: an effort-only frame leaves the model half where it was, so
|
|
1387
|
+
// there is nothing to judge; a frame that named a model is the screen's
|
|
1388
|
+
// report and is compared against what this instance was last seen on.
|
|
1389
|
+
if (info.model)
|
|
1390
|
+
observeAgentModel(worktreeId, cliToolId, instanceId, 'frame', at);
|
|
1161
1391
|
}
|
|
1162
1392
|
/**
|
|
1163
1393
|
* The last model/effort a terminal capture showed, both halves possibly null.
|
|
@@ -1178,18 +1408,107 @@ function getLastCapturedModelInfo(worktreeId, cliToolId, instanceId) {
|
|
|
1178
1408
|
* (#1783) together with the screen under the precedence documented on
|
|
1179
1409
|
* {@link mergeModelInfo} — hooks win for the model, the screen is the only
|
|
1180
1410
|
* source of effort for codex/claude, and antigravity's effort is derived from
|
|
1181
|
-
* the id it reports rather than from its (renderer-truncated) status bar
|
|
1411
|
+
* the id it reports rather than from its (renderer-truncated) status bar —
|
|
1412
|
+
* with the one exception {@link resolveAgentModel} documents (Issue #2361): a
|
|
1413
|
+
* claude frame that started naming a different model after the hook last
|
|
1414
|
+
* spoke is the newer statement, and wins.
|
|
1182
1415
|
*
|
|
1183
1416
|
* Both halves may be null, and routinely are: no tool publishes an effort over
|
|
1184
1417
|
* hooks, and most tools publish neither. Callers omit the key rather than
|
|
1185
1418
|
* emitting null — see `CliToolSessionStatus`.
|
|
1186
1419
|
*/
|
|
1187
1420
|
function getResolvedAgentModelInfo(worktreeId, cliToolId, instanceId) {
|
|
1188
|
-
return (0,
|
|
1421
|
+
return resolveAgentModel((0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId), cliToolId).info;
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Tools whose hook channel may name the model at session start and never again
|
|
1425
|
+
* (Issue #2361).
|
|
1426
|
+
*
|
|
1427
|
+
* For these, a frame that starts naming a DIFFERENT model after the hook last
|
|
1428
|
+
* spoke may be the only report of a mid-session switch there is, and it
|
|
1429
|
+
* overtakes the hook in {@link resolveAgentModel}. For every other tool the
|
|
1430
|
+
* rule stays #1784's — hooks win — because their hook channel re-reports the
|
|
1431
|
+
* model on later events (codex and antigravity on every one, opencode on every
|
|
1432
|
+
* `message.updated`), so a switch reaches the hook latch by itself and a frame
|
|
1433
|
+
* that disagrees with a hook that is still re-affirming its value is a
|
|
1434
|
+
* misread, not news.
|
|
1435
|
+
*
|
|
1436
|
+
* Measured on claude 2.1.263 for #2361: `SessionStart` alone carried `model`
|
|
1437
|
+
* among the events then registered; `/model`, `/fast` and `/effort` fired none
|
|
1438
|
+
* of them; the `SessionStart` that `/clear` emits carries no `model`.
|
|
1439
|
+
*
|
|
1440
|
+
* Issue #2363 registers `PostModelSwitch`, so on 2.1.263 and later the hook
|
|
1441
|
+
* DOES re-report every `/model` and `/fast` that changes the model, in the
|
|
1442
|
+
* `SessionStart` spelling (`claude-sonnet-5`, `claude-opus-5[1m]`). Claude
|
|
1443
|
+
* stays on this list all the same, as the **fallback** rather than the rule,
|
|
1444
|
+
* and the two cases the rule exists for were weighed against each other:
|
|
1445
|
+
*
|
|
1446
|
+
* - *The hook re-reports.* The switch lands here as a hook write, stamping
|
|
1447
|
+
* {@link lastAgentModelAt}; the pane re-reads the rewritten banner or the
|
|
1448
|
+
* confirmation line moments later and names the same model in its label
|
|
1449
|
+
* spelling, which {@link isSameAgentModelName} (cross-channel) folds into
|
|
1450
|
+
* the hook's exact id. The frame does not overtake, the hook's id is what
|
|
1451
|
+
* is published, and the edge fires once. Nothing in this rule had to change
|
|
1452
|
+
* for that — it was written to defer to a hook that re-affirms.
|
|
1453
|
+
* - *The hook does not arrive.* A claude older than the hook, a session
|
|
1454
|
+
* launched without injection (`CM_AGENT_HOOKS_INJECT=0`, a hand-written
|
|
1455
|
+
* `--settings`), a delivery lost to a wedged server or the 3 s
|
|
1456
|
+
* de-duplication window: the latch is stale, the frame is the only channel
|
|
1457
|
+
* that heard the switch, and this rule is what publishes it. Removing the
|
|
1458
|
+
* tool from this set would take that back to the #2361 symptom — a stale
|
|
1459
|
+
* id shown with no edge — on precisely the sessions that have no other way
|
|
1460
|
+
* of reporting.
|
|
1461
|
+
*
|
|
1462
|
+
* The price of keeping it is the case #2361 already carried: a frame that
|
|
1463
|
+
* starts showing a stale confirmation line AFTER the hook spoke (the banner
|
|
1464
|
+
* scrolls away, an older `Set model to …` row becomes the fallback the
|
|
1465
|
+
* extractor reads) overtakes a hook that was right. That was possible before
|
|
1466
|
+
* #2363 — with a staler hook value underneath — and is no wider now; a switch
|
|
1467
|
+
* whose confirmation line the extractor does read leaves the newer row on the
|
|
1468
|
+
* pane, so the stale row is reachable only after a `/fast` or an automatic
|
|
1469
|
+
* fallback, and only until the next `/model` line or hook.
|
|
1470
|
+
*/
|
|
1471
|
+
const FRAME_OVERTAKES_HOOK_MODEL_TOOLS = new Set(['claude']);
|
|
1472
|
+
/**
|
|
1473
|
+
* The merged model/effort for one instance, and which channel the model half
|
|
1474
|
+
* came from (Issue #2361).
|
|
1475
|
+
*
|
|
1476
|
+
* {@link mergeModelInfo}'s precedence — hooks win the model — with one
|
|
1477
|
+
* exception layered on top for {@link FRAME_OVERTAKES_HOOK_MODEL_TOOLS}: when
|
|
1478
|
+
* the frame's model half CHANGED after the hook last named a model
|
|
1479
|
+
* ({@link CapturedModelRecord.modelChangedAt} > {@link lastAgentModelAt}) and
|
|
1480
|
+
* the two do not name the same model ({@link isSameAgentModelName}, cross
|
|
1481
|
+
* channel), the frame's value is the newer statement and is published in the
|
|
1482
|
+
* hook's place. Every other case is unchanged:
|
|
1483
|
+
*
|
|
1484
|
+
* - the frame names the same model as the hook (the startup banner after
|
|
1485
|
+
* `SessionStart`, or `/model` back to the model the hook named): the hook's
|
|
1486
|
+
* exact id is published, as before;
|
|
1487
|
+
* - the frame's value predates the hook (a switch line still on screen when a
|
|
1488
|
+
* relaunched process reports its starting model): the hook wins;
|
|
1489
|
+
* - no hook has spoken: the frame is the only source, as before.
|
|
1490
|
+
*
|
|
1491
|
+
* `source` is null when neither channel has a model.
|
|
1492
|
+
*/
|
|
1493
|
+
function resolveAgentModel(key, cliToolId) {
|
|
1494
|
+
const hooksModel = lastAgentModel.get(key) ?? null;
|
|
1495
|
+
const captured = capturedModelInfo.get(key);
|
|
1496
|
+
const capturedInfo = { model: captured?.model ?? null, effort: captured?.effort ?? null };
|
|
1189
1497
|
// Issue #2048: the third source. Null for every tool but opencode and for
|
|
1190
1498
|
// every opencode session running on a model's default, so every other
|
|
1191
1499
|
// surface's string is byte-identical to pre-#2048.
|
|
1192
|
-
|
|
1500
|
+
const hooksEffort = reportedEffort.get(key) ?? null;
|
|
1501
|
+
const frameChangedAt = captured?.modelChangedAt ?? null;
|
|
1502
|
+
const frameOvertakes = hooksModel !== null &&
|
|
1503
|
+
capturedInfo.model !== null &&
|
|
1504
|
+
frameChangedAt !== null &&
|
|
1505
|
+
FRAME_OVERTAKES_HOOK_MODEL_TOOLS.has(cliToolId) &&
|
|
1506
|
+
frameChangedAt > (lastAgentModelAt.get(key) ?? 0) &&
|
|
1507
|
+
!isSameAgentModelName(hooksModel, capturedInfo.model, { crossSource: true });
|
|
1508
|
+
const info = (0, model_info_extractor_1.mergeModelInfo)(cliToolId, frameOvertakes ? null : hooksModel, capturedInfo, hooksEffort);
|
|
1509
|
+
if (info.model === null)
|
|
1510
|
+
return { info, source: null };
|
|
1511
|
+
return { info, source: hooksModel !== null && !frameOvertakes ? 'hook' : 'frame' };
|
|
1193
1512
|
}
|
|
1194
1513
|
/**
|
|
1195
1514
|
* Latch the effort (opencode's *variant*) the agent named for itself (#2048).
|
|
@@ -1281,6 +1600,7 @@ function beginAgentEventGeneration(worktreeId, cliToolId, instanceId, at = Date.
|
|
|
1281
1600
|
// A `/clear` is deliberately not affected: it reaches `recordAgentEvent` as
|
|
1282
1601
|
// `session_end` + `session_start`, never this function.
|
|
1283
1602
|
lastAgentModel.delete(key);
|
|
1603
|
+
lastAgentModelAt.delete(key);
|
|
1284
1604
|
// Issue #1784: same argument for what the screen showed. The latch exists to
|
|
1285
1605
|
// survive the banner scrolling away *within* one process; carrying it across
|
|
1286
1606
|
// a relaunch would show the old process's effort with no frame left that
|
|
@@ -1289,6 +1609,10 @@ function beginAgentEventGeneration(worktreeId, cliToolId, instanceId, at = Date.
|
|
|
1289
1609
|
// Issue #2048: and the variant the agent named, for exactly #1783's reason —
|
|
1290
1610
|
// the new process may have been launched with a different one, or with none.
|
|
1291
1611
|
reportedEffort.delete(key);
|
|
1612
|
+
// Issue #2357: and the model this instance was last seen on. The next value
|
|
1613
|
+
// is a new process's starting model (`null → value`), not a change from the
|
|
1614
|
+
// process that was replaced.
|
|
1615
|
+
modelBaseline.delete(key);
|
|
1292
1616
|
// Issue #1899: the ids claimed for this key were issued by the process that
|
|
1293
1617
|
// has just been replaced. Unlike the time-window keys, they never expire on
|
|
1294
1618
|
// their own, so a generation is the only thing that retires them.
|
|
@@ -1323,10 +1647,13 @@ function discardAgentEventState(worktreeId, cliToolId, instanceId) {
|
|
|
1323
1647
|
awaitingInstruction.delete(key);
|
|
1324
1648
|
// Issue #1783: the session that was on this model no longer exists.
|
|
1325
1649
|
lastAgentModel.delete(key);
|
|
1650
|
+
lastAgentModelAt.delete(key);
|
|
1326
1651
|
// Issue #1784: nor does the pane its footer was read from.
|
|
1327
1652
|
capturedModelInfo.delete(key);
|
|
1328
1653
|
// Issue #2048: nor the variant that session was running at.
|
|
1329
1654
|
reportedEffort.delete(key);
|
|
1655
|
+
// Issue #2357: nor the model it was last seen on.
|
|
1656
|
+
modelBaseline.delete(key);
|
|
1330
1657
|
// Issue #1899: nor do the frame ids that session issued.
|
|
1331
1658
|
recentEventIdentities.delete(key);
|
|
1332
1659
|
}
|
|
@@ -1914,8 +2241,13 @@ function clearAgentStopEvents() {
|
|
|
1914
2241
|
// repo shares this process — a model latched by one test would otherwise be
|
|
1915
2242
|
// read by another, in file order, and only in CI.
|
|
1916
2243
|
lastAgentModel.clear();
|
|
2244
|
+
lastAgentModelAt.clear();
|
|
1917
2245
|
// Issue #1784: and the same for the scraped half.
|
|
1918
2246
|
capturedModelInfo.clear();
|
|
1919
2247
|
// Issue #2048: and for the variant the agent reported.
|
|
1920
2248
|
reportedEffort.clear();
|
|
2249
|
+
// Issue #2357: and for the model each instance was last seen on. The
|
|
2250
|
+
// listener set is deliberately NOT cleared — a subscription belongs to the
|
|
2251
|
+
// process, not to a session, and a suite that armed one expects it to stay.
|
|
2252
|
+
modelBaseline.clear();
|
|
1921
2253
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
exports.id=6894,exports.ids=[6894],exports.modules={3453:(a,b,c)=>{"use strict";c.d(b,{Rh:()=>r,T1:()=>o,Z2:()=>m,c$:()=>n,nu:()=>q});var d=c(72626),e=c(80438);let f=(0,d.h)("ip-restriction"),g="::ffff:",h=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/,i=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/,j=process.env.CM_ALLOWED_IPS?.trim()||"",k=process.env.CM_TRUST_PROXY?.trim()||"";""!==k&&"true"!==k&&"false"!==k&&(0,e.h)(f,"trust-proxy-unexpected",{value:k});let l="true"===k;function m(a){return a?a.toLowerCase().startsWith(g)?a.substring(g.length):a:""}function n(a,b){if(0===b.length)return!1;let c=function(a){let b=a.match(h);if(!b)return null;let c=[parseInt(b[1],10),parseInt(b[2],10),parseInt(b[3],10),parseInt(b[4],10)];for(let a of c)if(a<0||a>255)return null;return(c[0]<<24|c[1]<<16|c[2]<<8|c[3])>>>0}(m(a));if(null===c)return!1;for(let a of b)if((c&a.mask)>>>0===a.network)return!0;return!1}function o(a){if(l){let b=a.get("x-forwarded-for");if(b){let a=b.split(",")[0].trim();if(a)return a}}return a.get("x-real-ip")||null}let p=j.length>0?function(a){let b=a.trim();if(0===b.length)return[];let c=b.split(",").map(a=>a.trim()).filter(a=>a.length>0);if(c.length>256)throw Error(`CM_ALLOWED_IPS: too many entries (${c.length}). Maximum is 256.`);let d=[];for(let a of c){if(a.length>18)throw Error(`CM_ALLOWED_IPS: entry "${a}" exceeds maximum length of 18 characters.`);let b=a.match(i);if(b){let c=[parseInt(b[1],10),parseInt(b[2],10),parseInt(b[3],10),parseInt(b[4],10)],e=parseInt(b[5],10);for(let b of c)if(b<0||b>255)throw Error(`CM_ALLOWED_IPS: invalid octet in "${a}". Octets must be 0-255.`);if(e<0||e>32)throw Error(`CM_ALLOWED_IPS: invalid prefix length in "${a}". Must be 0-32.`);let f=(c[0]<<24|c[1]<<16|c[2]<<8|c[3])>>>0,g=0===e?0:0xffffffff<<32-e>>>0;d.push({network:(f&g)>>>0,mask:g});continue}let c=a.match(h);if(c){let b=[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10),parseInt(c[4],10)];for(let c of b)if(c<0||c>255)throw Error(`CM_ALLOWED_IPS: invalid octet in "${a}". Octets must be 0-255.`);let e=(b[0]<<24|b[1]<<16|b[2]<<8|b[3])>>>0;d.push({network:e,mask:0xffffffff});continue}throw Error(`CM_ALLOWED_IPS: invalid entry "${a}". Expected IPv4 address or CIDR notation.`)}return d}(j):[];function q(){return p}function r(){return j.length>0}},7015:(a,b,c)=>{"use strict";c.d(b,{Ds:()=>g});var d=c(81719);class e{constructor(a,b=3e4){this.cache=new Map,this.allAppsCache=null,this.lastRefresh=0,this.db=a,this.ttl=b}getTTL(){return this.ttl}isStale(){return Date.now()-this.lastRefresh>this.ttl}async refresh(){let a=(0,d.$i)(this.db);for(let b of(this.cache.clear(),a))this.cache.set(b.pathPrefix,b);this.allAppsCache=a,this.lastRefresh=Date.now()}async getByPathPrefix(a){return this.isStale()&&await this.refresh(),this.cache.get(a)??null}async getAll(){return this.isStale()&&await this.refresh(),this.allAppsCache??[]}invalidate(){this.cache.clear(),this.allAppsCache=null,this.lastRefresh=0}invalidateByIssueNo(a){this.invalidate()}}let f=null;function g(a){if(!f){if(!a)throw Error("Database instance required to initialize cache");f=new e(a)}return f}},26838:(a,b,c)=>{"use strict";c.d(b,{E2:()=>o,Mj:()=>m,Sw:()=>l,lX:()=>p});var d=c(29021),e=c(33873),f=c(54325),g=c(90164);let h=/^v?\d+\.\d+\.\d+$/,i=/^[a-zA-Z0-9.\-\s_v]+$/,j=[".next","required-server-files.json"],k=globalThis.__versionCheckCache??(globalThis.__versionCheckCache={result:null,fetchedAt:0,rateLimitResetAt:null});function l(){return function(){try{let a=(0,d.readFileSync)((0,e.join)(process.cwd(),"package.json"),"utf-8"),b=JSON.parse(a);if("commandmate"===b.name&&"string"==typeof b.version&&b.version.length>0)return b.version;return null}catch{return null}}()??"0.31.2"}function m(){return l()}let n=null;function o(a){let b=n??=function(){{let a=function(){try{let a=(0,d.readFileSync)((0,e.join)(process.cwd(),...j),"utf-8"),b=JSON.parse(a),c=b.config?.env?.NEXT_PUBLIC_APP_VERSION;if("string"==typeof c&&c.length>0)return c;return null}catch{return null}}();if(a)return a}return"0.31.2"}();return(0,f.LE)(b,a)?{serverVersion:b,clientVersion:a}:null}async function p(){try{var a,b,c;if(null!==k.result&&Date.now()-k.fetchedAt<36e5||k.rateLimitResetAt&&(!(Date.now()>=k.rateLimitResetAt)||(k.rateLimitResetAt=null,0)))return k.result;let d=await fetch("https://api.github.com/repos/Kewton/CommandMate/releases/latest",{headers:{Accept:"application/vnd.github+json","User-Agent":`CommandMate/${m()}`},cache:"no-store",signal:AbortSignal.timeout(5e3)});if(403===d.status)return function(a){let b=a.headers.get("X-RateLimit-Reset");b?k.rateLimitResetAt=1e3*parseInt(b,10):k.rateLimitResetAt=Date.now()+36e5}(d),k.result;if(!d.ok)return k.result;let e=await d.json(),f=m(),j=e.tag_name.replace(/^v/,""),l={hasUpdate:function(a,b){if(!h.test(a)||!h.test(b))return!1;let c=a=>a.replace(/^v/,"").split(".").map(Number),[d,e,f]=c(a),[g,i,j]=c(b);return g!==d?g>d:i!==e?i>e:j>f}(f,e.tag_name),currentVersion:f,latestVersion:j,releaseUrl:(a=e.html_url).startsWith(g.Dk)?a:null,releaseName:(b=e.name,c=e.tag_name,i.test(b)&&b.length<=128?b:c),publishedAt:e.published_at};return k.result=l,k.fetchedAt=Date.now(),l}catch{return k.result}}},39727:()=>{},47990:()=>{},54036:(a,b,c)=>{"use strict";c.d(b,{aq:()=>d,gu:()=>f,kr:()=>h});let d="cm_auth_token",e=/^[0-9a-f]{64}$/;function f(a){return!!a&&e.test(a)}let g=2592e6;function h(){let a=process.env.CM_AUTH_EXPIRE,b=Date.now();if(a)try{return b+function(a){let b=a.match(/^(\d+)([hdm])$/);if(!b)throw Error(`Invalid duration format: "${a}". Use Nh, Nd, or Nm (e.g., "24h", "7d", "90m")`);let c=parseInt(b[1],10),d=b[2],e={h:36e5,d:864e5,m:6e4}[d];if(void 0===e)throw Error(`Invalid duration unit: "${d}"`);let f=c*e;if(f<36e5)throw Error(`Duration too short: minimum is 1h (60m). Got: "${a}"`);if(f>g)throw Error(`Duration too long: maximum is 30d (720h). Got: "${a}"`);return f}(a)}catch{return b+864e5}return process.env.CM_AUTH_TOKEN_HASH?b+864e5:null}},79129:(a,b,c)=>{"use strict";c.r(b),c.d(b,{WORKTREE_RENAMED_EVENT_TYPE:()=>ad,__internal:()=>aj,broadcast:()=>aa,broadcastMessage:()=>ac,cleanupRooms:()=>ag,closeWebSocket:()=>ai,handleProxyUpgrade:()=>N,hasRoomSubscribers:()=>ab,migrateWorktreeRooms:()=>ae,setupWebSocket:()=>O});var d=c(81503),e=c(91645),f=c(88081),g=c(3453),h=c(15194),i=c(40964),j=c(88807),k=c(56791);let l={capturePaneCalls:0,activeControlSessions:0,subscriberCount:0,cleanupCount:0,firstOutputLatencyCount:0,firstOutputLatencyTotalMs:0,firstOutputLatencyLastMs:null,firstOutputLatencyMinMs:null,firstOutputLatencyMaxMs:null};var m=c(79892),n=c(72626),o=c(79646);class p{push(a){if(0===a.length)return[];let b=(this.remainder+a).split("\n");this.remainder=b.pop()??"";let c=[];for(let a of b){let b=a.endsWith("\r")?a.slice(0,-1):a,d=this.parseLine(b);d&&c.push(d)}return c}flush(){if(0===this.remainder.length)return[];let a=this.parseLine(this.remainder);return this.remainder="",a?[a]:[]}parseLine(a){return 0===a.length?{type:"output",data:"\n"}:a.startsWith("%output ")?{type:"output",data:`${a.slice(8)}
|
|
2
|
-
`}:"%exit"===a||a.startsWith("%exit ")?{type:"exit",exitCode:null}:a.startsWith("%error ")?{type:"error",error:Error(a.slice(7))}:a.startsWith("%")?null:{type:"output",data:`${a}
|
|
3
|
-
`}}constructor(){this.remainder=""}}let q=(0,n.h)("tmux-control-client");class r{constructor(a={}){this.parser=new p,this.handlers=new Set,this.child=null,this.sessionName=null,this.idleTimer=null,this.started=!1,this.spawnProcess=a.spawnProcess??((a,b,c)=>(0,o.spawn)(a,b,c)),this.tmuxBinary=a.tmuxBinary??"tmux",this.idleTimeoutMs=a.idleTimeoutMs??3e4}start(a){this.started||(this.sessionName=a,this.child=this.spawnProcess(this.tmuxBinary,["-C","attach-session","-t",(0,m.lA)(a)],{stdio:"pipe"}),this.started=!0,this.child.stdout.setEncoding("utf8"),this.child.stdout.on("data",a=>{this.touch();let b="string"==typeof a?a:a.toString("utf8");for(let a of this.parser.push(b))this.emit(a)}),this.child.stderr.setEncoding("utf8"),this.child.stderr.on("data",a=>{let b="string"==typeof a?a:a.toString("utf8");this.emit({type:"error",error:Error(b.trim()||"tmux control stderr")})}),this.child.on("close",a=>{for(let a of this.parser.flush())this.emit(a);this.emit({type:"exit",exitCode:a}),this.stop()}),this.child.on("error",a=>{this.emit({type:"error",error:a}),this.stop()}),this.resetIdleTimer(),q.debug("start",{sessionName:a}))}onEvent(a){return this.handlers.add(a),()=>{this.handlers.delete(a)}}sendInput(a){if(!this.child?.stdin.writable)throw Error("Tmux control client is not writable");this.touch(),this.child.stdin.write(a)}resize(a,b){if(!this.child?.stdin.writable)throw Error("Tmux control client is not writable");this.touch(),this.child.stdin.write(`refresh-client -C ${a}x${b}
|
|
4
|
-
`)}stop(){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.child&&(this.child.removeAllListeners(),this.child.stdout.removeAllListeners(),this.child.stderr.removeAllListeners(),this.child.kill(),this.child=null),this.started=!1}isStarted(){return this.started}setSessionName(a){this.sessionName=a}emit(a){for(let b of this.handlers)b(a)}touch(){this.resetIdleTimer()}resetIdleTimer(){this.idleTimeoutMs<=0||(this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{q.debug("idle-timeout",{sessionName:this.sessionName}),this.stop()},this.idleTimeoutMs))}}let s=(0,n.h)("tmux-control-registry");class t{constructor(a={}){this.entries=new Map,this.handlers=new Map,this.idleTimeoutMs=a.idleTimeoutMs??15e3,this.createClient=a.createClient??(()=>new r(a))}subscribe(a,b,c){let d=this.ensureEntry(a);d.subscribers.add(b),this.cancelIdleCleanup(d),this.updateMetrics();let e=this.handlers.get(a);return e||(e=new Set,this.handlers.set(a,e)),e.add(c),()=>{e?.delete(c),this.unsubscribe(a,b)}}sendInput(a,b){let c=this.entries.get(a);if(!c)throw Error(`No control client registered for ${a}`);c.client.sendInput(b)}resize(a,b,c){let d=this.entries.get(a);if(!d)throw Error(`No control client registered for ${a}`);d.client.resize(b,c)}hasSession(a){return this.entries.has(a)}getSubscriberCount(a){return this.entries.get(a)?.subscribers.size??0}getTotalSubscriberCount(){let a=0;for(let b of this.entries.values())a+=b.subscribers.size;return a}getSessionCount(){return this.entries.size}shutdown(){for(let[a,b]of this.entries)this.teardownEntry(a,b);this.entries.clear(),this.handlers.clear(),this.updateMetrics()}renameSession(a,b){if(a===b)return!1;let c=this.entries.get(a);if(!c)return!1;if(this.entries.has(b))return s.warn("rename:destination-occupied",{oldName:a,newName:b}),!1;this.entries.delete(a),c.sessionName=b,this.entries.set(b,c),c.client.setSessionName(b);let d=this.handlers.get(a);return d&&(this.handlers.delete(a),this.handlers.set(b,d)),s.debug("rename",{oldName:a,newName:b}),!0}ensureEntry(a){let b=this.entries.get(a);if(b)return b;let c=this.createClient(a);c.start(a);let d={client:c,subscribers:new Set,unsubscribeClientEvent:()=>{},idleTimer:null,sessionName:a};return d.unsubscribeClientEvent=c.onEvent(a=>{let b=this.handlers.get(d.sessionName);if(b)for(let c of b)c(a);("exit"===a.type||"error"===a.type)&&this.deleteEntry(d.sessionName)}),this.entries.set(a,d),this.updateMetrics(),d}unsubscribe(a,b){let c=this.entries.get(a);c&&(c.subscribers.delete(b),this.updateMetrics(),0===c.subscribers.size&&this.scheduleIdleCleanup(a,c))}scheduleIdleCleanup(a,b){if(this.idleTimeoutMs<=0)return void this.deleteEntry(a);this.cancelIdleCleanup(b),b.idleTimer=setTimeout(()=>{s.debug("idle-cleanup",{sessionName:b.sessionName}),this.deleteEntry(b.sessionName)},this.idleTimeoutMs)}cancelIdleCleanup(a){a.idleTimer&&(clearTimeout(a.idleTimer),a.idleTimer=null)}deleteEntry(a){let b=this.entries.get(a);b&&(this.teardownEntry(a,b),this.entries.delete(a),this.handlers.delete(a),this.updateMetrics())}teardownEntry(a,b){this.cancelIdleCleanup(b),b.unsubscribeClientEvent(),b.client.stop(),l.cleanupCount+=1}updateMetrics(){l.activeControlSessions=Math.max(0,this.getSessionCount()),l.subscriberCount=Math.max(0,this.getTotalSubscriberCount())}}let u=null,v={streamingOutput:!0,explicitResize:!0,snapshotFallback:!0};class w{constructor(a={}){this.registry=a.registry??(u||(u=new t),u)}async ensureSession(a,b){await (0,m.N)(a)||await (0,m.jw)(a,b)}async sessionExists(a){return(0,m.N)(a)}async sendInput(a,b){if(this.registry.hasSession(a))return void this.registry.sendInput(a,b);await (0,m.V1)(a,b)}async sendSpecialKey(a,b){if("Escape"!==b&&"C-c"!==b&&"C-d"!==b&&"C-m"!==b&&"Enter"!==b)throw Error(`Unsupported special key for ControlModeTmuxTransport: ${b}`);await (0,m.ds)(a,b)}async resize(a,b,c){this.registry.resize(a,b,c)}async captureSnapshot(a,b){return l.capturePaneCalls+=1,(0,m.Xg)(a,b)}async subscribe(a,b){let c=`sub-${Date.now()}-${Math.random().toString(36).slice(2,10)}`,d=this.registry.subscribe(a,c,a=>{"output"===a.type?b.onOutput(a.data):"exit"===a.type?b.onExit?.({exitCode:a.exitCode}):b.onError(a.error)});return{async unsubscribe(){d()}}}getCapabilities(){return v}getSubscriberCount(a){return this.registry.getSubscriberCount(a)}renameSession(a,b){return this.registry.renameSession(a,b)}async killSession(a){return(0,m.fY)(a)}}let x=null;function y(){return x||(x=new w),x}var z=c(7015),A=c(26838),B=c(54325),C=c(57836);function D(){let a=globalThis.__waitingStatusBroadcastUnsubscribe;a&&(a(),globalThis.__waitingStatusBroadcastUnsubscribe=void 0)}let E=(0,n.h)("publisher-registry");function F(){return globalThis.__realtimeRoomPublisher?.publisher??null}let G=(0,n.h)("ws-server"),H=null,I=new Map,J=new Map,K=null,L=new Set(["localhost","127.0.0.1"]);function M(a,b){try{a.write(`HTTP/1.1 ${b}\r
|
|
5
|
-
Content-Length: 0\r
|
|
6
|
-
Connection: close\r
|
|
7
|
-
\r
|
|
8
|
-
`)}catch{}a.destroy()}async function N(a,b,c,d){let e,f=(a.url||"/").split("?")[0].split("/")[2]||"";if(!f)return void M(b,"400 Bad Request");try{let a=d.getDb(),b=d.getCache(a);e=await b.getByPathPrefix(f)}catch(a){G.error("ws-proxy:cache-error",{pathPrefix:f,error:a instanceof Error?a.message:String(a)}),!b.destroyed&&b.writable&&M(b,"502 Bad Gateway");return}if(b.destroyed||!b.writable)return;if(!e)return void M(b,"404 Not Found");if(!e.enabled)return void M(b,"503 Service Unavailable");if(!e.websocketEnabled)return void M(b,"403 Forbidden");if(!L.has(e.targetHost)){G.warn("ws-proxy:ssrf-blocked",{pathPrefix:f}),M(b,"403 Forbidden");return}let g=d.netConnect({host:e.targetHost,port:e.targetPort}),h=!1,i=!1,j=()=>{if(!i){i=!0;try{g.destroy()}catch{}try{b.destroy()}catch{}}};g.on("connect",()=>{h=!0;try{let b=function(a){let b=a.method||"GET",c=a.url||"/",d=a.httpVersion||"1.1",e=[`${b} ${c} HTTP/${d}`];for(let[b,c]of Object.entries(a.headers))if(void 0!==c)if(Array.isArray(c))for(let a of c)e.push(`${b}: ${a}`);else e.push(`${b}: ${c}`);return e.join("\r\n")+"\r\n\r\n"}(a);g.write(b)}catch(a){G.error("ws-proxy:upstream-write-error",{pathPrefix:f,error:a instanceof Error?a.message:String(a)}),j();return}b.pipe(g),g.pipe(b)}),g.on("error",a=>{G.error("ws-proxy:upstream-error",{pathPrefix:f,error:a.message}),h||b.destroyed||!b.writable?j():M(b,"502 Bad Gateway")}),g.on("close",()=>{j()}),b.on("error",a=>{G.error("ws-proxy:client-error",{pathPrefix:f,error:a.message}),j()}),b.on("close",()=>{j()})}function O(a){H=new d.zu({noServer:!0}),K=function(a){let b=(globalThis.__realtimeRoomPublisherGeneration??0)+1;return globalThis.__realtimeRoomPublisherGeneration=b,globalThis.__realtimeRoomPublisher={generation:b,publisher:a},globalThis.__realtimeUnroutedPublish=void 0,{token:b,unregister:()=>(function(a){let b=globalThis.__realtimeRoomPublisher;return!!b&&b.generation===a&&(globalThis.__realtimeRoomPublisher=void 0,!0)})(b)}}(Z),function(a){D();let b=(0,C.wN)(b=>{a(b.worktreeId,{type:"session_status_changed",worktreeId:b.worktreeId,cliTool:b.cliToolId,instance:b.instanceId??b.cliToolId,isWaitingForResponse:b.waiting,waitingKind:b.kind??null,waitingSince:b.since})});globalThis.__waitingStatusBroadcastUnsubscribe=b}(R),a.on("upgrade",(a,b,c)=>{let d=a.url||"/";if(d.startsWith("/_next/")){b.write("HTTP/1.1 426 Upgrade Required\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"),b.destroy();return}if((0,g.Rh)()){let c=(0,g.Z2)(a.socket.remoteAddress||"");if(!(0,g.c$)(c,(0,g.nu)())){let a=c.substring(0,45);G.warn("websocket:denied",{ip:a}),b.write("HTTP/1.1 403 Forbidden\r\n\r\n"),b.destroy();return}}if((0,f.y2)()){let c=a.headers.cookie||"",d=(0,f.JT)(c)[f.aq];if(!d||!(0,f.nr)(d)){b.write("HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"),b.destroy();return}}if(d.startsWith("/proxy/"))return void(async()=>{try{await N(a,b,c,{getDb:()=>(0,j.getDbInstance)(),getCache:a=>(0,z.Ds)(a),netConnect:a=>(0,e.connect)(a)})}catch(a){if(G.error("ws-proxy:unhandled-error",{error:a instanceof Error?a.message:String(a)}),!b.destroyed&&b.writable){try{b.write("HTTP/1.1 500 Internal Server Error\r\nContent-Length: 0\r\nConnection: close\r\n\r\n")}catch{}b.destroy()}}})();H.handleUpgrade(a,b,c,b=>{H.emit("connection",b,a)})}),H.on("error",a=>{G.error("server:error",{error:a.message})}),H.on("connection",a=>{let b={ws:a,worktreeIds:new Set,terminalSubscription:null};I.set(a,b),a.on("message",b=>{try{let c=JSON.parse(b.toString());P(a,c)}catch(a){G.error("message:parse-failed",{error:a instanceof Error?a.message:String(a)})}}),a.on("close",()=>{S(a)}),a.on("error",b=>{"WS_ERR_INVALID_CLOSE_CODE"===b.code||b.message?.includes("Invalid WebSocket frame")||b.message?.includes("write after end")||b.message?.includes("ECONNRESET")||b.message?.includes("EPIPE")||G.error("websocket:error",{error:b.message});try{a.terminate()}catch{}S(a)})})}function P(a,b){switch(b.type){case"subscribe":if(!b.worktreeId)return;var c=a,d=b.worktreeId;let e=I.get(c);e&&(e.worktreeIds.add(d),J.has(d)||J.set(d,new Set),J.get(d).add(c));break;case"unsubscribe":if(!b.worktreeId)return;!function(a,b){let c=I.get(a);if(!c)return;c.worktreeIds.delete(b);let d=J.get(b);d&&(d.delete(a),0===d.size&&J.delete(b))}(a,b.worktreeId);break;case"broadcast":if(!b.worktreeId)return;R(b.worktreeId,b.data);break;case B.ST:Q(a,b);break;case"terminal_subscribe":U(a,b);break;case"terminal_input":V(a,b);break;case"terminal_resize":W(a,b);break;case"terminal_unsubscribe":X(a);break;default:G.warn("message:unknown-type")}}function Q(a,b){let c="string"==typeof b.version?b.version:"";if(!c)return;let e=(0,A.E2)(c);if(e&&a.readyState===d.kb.OPEN)try{a.send(JSON.stringify({type:B.Oo,serverVersion:e.serverVersion,clientVersion:e.clientVersion}))}catch(a){G.error("version:notify-failed",{error:a instanceof Error?a.message:String(a)})}}function R(a,b){let c=J.get(a);if(c&&0!==c.size)try{let e=JSON.stringify({type:"broadcast",worktreeId:a,data:b});c.forEach(a=>{if(a.readyState===d.kb.OPEN)try{a.send(e)}catch(a){G.error("broadcast:send-failed",{error:a instanceof Error?a.message:String(a)})}})}catch(b){G.error("broadcast:failed",{worktreeId:a,error:b instanceof Error?b.message:String(b)});try{let b=JSON.stringify({type:"broadcast",worktreeId:a,data:{error:"Message encoding error"}});c.forEach(a=>{if(a.readyState===d.kb.OPEN)try{a.send(b)}catch{}})}catch(a){G.error("fallback:send-failed",{error:a instanceof Error?a.message:String(a)})}}}function S(a){let b=I.get(a);b&&(b.worktreeIds.forEach(b=>{let c=J.get(b);c&&(c.delete(a),0===c.size&&J.delete(b))}),b.terminalSubscription&&(b.terminalSubscription.unsubscribe(),b.terminalSubscription=null),I.delete(a))}function T(a,b){a.readyState===d.kb.OPEN&&a.send(JSON.stringify(b))}async function U(a,b){let c=I.get(a);if(!c)return void T(a,{type:"terminal_error",error:"Unauthorized WebSocket client"});if("true"!==process.env.TMUX_CONTROL_MODE_ENABLED)return void T(a,{type:"terminal_error",error:"Tmux control mode is disabled"});let{worktreeId:d,cliToolId:e}=b;if(!d||!e||!(0,h.hR)(e))return void T(a,{type:"terminal_error",error:"Invalid terminal subscription parameters"});let f=(0,j.getDbInstance)();if(!(0,k.getWorktreeById)(f,d))return void T(a,{type:"terminal_error",error:"Worktree not found"});c.terminalSubscription&&(await c.terminalSubscription.unsubscribe(),c.terminalSubscription=null);let g=(0,i.m)(e,d),m=y();if(m.getSubscriberCount(g)>=4)return void T(a,{type:"terminal_error",error:"Terminal subscriber limit reached"});let n=!1,o=Date.now(),p=await m.subscribe(g,{onOutput:b=>{if(!n){n=!0;let a=Math.max(0,Math.round(Date.now()-o));l.firstOutputLatencyCount+=1,l.firstOutputLatencyTotalMs+=a,l.firstOutputLatencyLastMs=a,l.firstOutputLatencyMinMs=null===l.firstOutputLatencyMinMs?a:Math.min(l.firstOutputLatencyMinMs,a),l.firstOutputLatencyMaxMs=null===l.firstOutputLatencyMaxMs?a:Math.max(l.firstOutputLatencyMaxMs,a)}T(a,{type:"terminal_output",data:b})},onExit:({exitCode:b})=>{T(a,{type:"terminal_exit",exitCode:b})},onError:b=>{(async()=>{try{let b=await m.captureSnapshot(g,{startLine:-200});b.length>0&&T(a,{type:"terminal_output",data:b,fallback:!0})}catch{}T(a,{type:"terminal_error",error:b.message,fallback:!0})})()}});c.terminalSubscription={worktreeId:d,cliToolId:e,sessionName:g,startedAt:o,unsubscribe:p.unsubscribe},T(a,{type:"terminal_status",connected:!0,worktreeId:d,cliToolId:e})}async function V(a,b){let c=I.get(a),d=c?.terminalSubscription;if(!d)return void T(a,{type:"terminal_error",error:"No active terminal subscription"});let e="string"==typeof b.data?b.data:"";if(0===e.length||e.length>4096)return void T(a,{type:"terminal_error",error:"Invalid terminal input"});try{await y().sendInput(d.sessionName,e)}catch(b){T(a,{type:"terminal_error",error:b instanceof Error?b.message:"Failed to send terminal input"})}}async function W(a,b){let c=I.get(a),d=c?.terminalSubscription;if(d){if("number"!=typeof b.cols||!Number.isInteger(b.cols)||b.cols<20||b.cols>500||"number"!=typeof b.rows||!Number.isInteger(b.rows)||b.rows<5||b.rows>200)return void T(a,{type:"terminal_error",error:"Invalid terminal resize payload"});try{await y().resize(d.sessionName,b.cols,b.rows)}catch(b){T(a,{type:"terminal_error",error:b instanceof Error?b.message:"Failed to resize terminal"})}}}async function X(a){let b=I.get(a);if(b?.terminalSubscription){try{await b.terminalSubscription.unsubscribe()}catch{}b.terminalSubscription=null,T(a,{type:"terminal_status",connected:!1})}}function Y(a){let b=J.get(a);return!!b&&b.size>0}let Z={publish:R,hasSubscribers:Y,cleanupRooms:ah,migrateRooms:af};function $(){let a=F();return a&&a!==Z?a:null}function _(a,b){null===F()&&0===J.size&&function(a,b,c=Date.now()){let d=globalThis.__realtimeUnroutedPublish??={total:0,suppressed:0,lastWarnedAt:null,operations:{}};if(d.total+=1,d.operations[a]=(d.operations[a]??0)+1,null!==d.lastWarnedAt&&c-d.lastWarnedAt<6e4){d.suppressed+=1;return}let e=d.suppressed;d.suppressed=0,d.lastWarnedAt=c,E.warn("realtime:no-room-publisher",{operation:a,worktreeId:b,total:d.total,suppressedSinceLastWarning:e,operations:{...d.operations}})}(a,b)}function aa(a,b){let c=$();if(c)return void c.publish(a,b);_("broadcast",a),R(a,b)}function ab(a){let b=$();return b?b.hasSubscribers(a):(_("hasRoomSubscribers",a),Y(a))}function ac(a,b){b.worktreeId?aa(b.worktreeId,{type:a,...b}):G.warn("broadcast:missing-worktree-id")}let ad="worktree_renamed";function ae(a){let b=$();return b?b.migrateRooms(a):af(a)}function af(a){let b=new Map;for(let{oldId:c,newId:d}of a)c&&d&&c!==d&&b.set(c,d);if(0===b.size)return[];let c=[];for(let[a,d]of b){let b=J.get(a);b&&0!==b.size&&(J.delete(a),c.push({oldId:a,newId:d,sockets:b}))}let d=[];for(let{oldId:a,newId:b,sockets:e}of c){let c=J.get(b)??new Set;for(let d of e){c.add(d);let e=I.get(d);e&&(e.worktreeIds.delete(a),e.worktreeIds.add(b)),T(d,{type:ad,worktreeId:b,previousWorktreeId:a})}J.set(b,c),d.push({oldId:a,newId:b,subscribers:e.size})}for(let a of I.values()){let c=a.terminalSubscription;if(!c)continue;let d=b.get(c.worktreeId);if(d)try{if(!(0,h.hR)(c.cliToolId))continue;c.sessionName=(0,i.m)(c.cliToolId,d),c.worktreeId=d}catch(a){G.warn("terminal:rename-failed",{worktreeId:c.worktreeId,newId:d,error:a instanceof Error?a.message:String(a)})}}return d.length>0&&G.info("rooms:migrated",{count:d.length}),d}function ag(a){let b=$();if(b)return void b.cleanupRooms(a);ah(a)}function ah(a){for(let b of a){let a=J.get(b);a&&(a.forEach(a=>{let c=I.get(a);c&&c.worktreeIds.delete(b)}),J.delete(b))}}function ai(){let a=null!==K&&K.unregister();K=null,(a||null===F())&&D(),H&&(I.forEach(a=>{a.ws.close()}),I.clear(),J.clear(),H.close(),H=null)}let aj={handleMessage:P,handleClientVersion:Q,handleProxyUpgrade:N,handleTerminalSubscribe:U,handleTerminalInput:V,handleTerminalResize:W,handleTerminalUnsubscribe:X,handleDisconnect:S,registerClientForTest(a){I.set(a,{ws:a,worktreeIds:new Set,terminalSubscription:null})},getClientInfoForTest:a=>I.get(a),resetStateForTest(){I.clear(),J.clear()}}},88081:(a,b,c)=>{"use strict";c.d(b,{JT:()=>m,QK:()=>k,aq:()=>f.aq,nr:()=>l,r0:()=>p,sO:()=>h,x:()=>q,y2:()=>n,zr:()=>o});var d=c(55511),e=c.n(d),f=c(54036);let g={maxAttempts:5,lockoutDuration:9e5,cleanupInterval:36e5},h=86400,i=(()=>{let a=process.env.CM_AUTH_TOKEN_HASH||void 0;return a?(0,f.gu)(a)?a:void console.error("[auth] CM_AUTH_TOKEN_HASH is not a valid SHA-256 hash"):void 0})(),j=(0,f.kr)();function k(a){return e().createHash("sha256").update(a).digest("hex")}function l(a){if(!i||!a||"string"!=typeof a||null!==j&&Date.now()>j)return!1;let b=k(a),c=Buffer.from(b,"hex"),d=Buffer.from(i,"hex");return c.length===d.length&&e().timingSafeEqual(c,d)}function m(a){let b={};if(!a)return b;for(let c of a.split(";")){let a=c.indexOf("=");if(-1===a)continue;let d=c.substring(0,a).trim(),e=c.substring(a+1).trim();d&&(b[d]=e)}return b}function n(){return!!i}function o(){if(null===j)return 0;let a=j-Date.now();return a<=0?0:Math.floor(a/1e3)}function p(a){return{httpOnly:!0,sameSite:"strict",secure:!!process.env.CM_HTTPS_CERT,maxAge:a,path:"/"}}function q(){let a=new Map,b=setInterval(()=>{let b=Date.now();for(let[c,d]of a){let e=null===d.lockedUntil||b>d.lockedUntil,f=b-d.lastAttempt>g.lockoutDuration;e&&f&&a.delete(c)}},g.cleanupInterval);return b.unref&&b.unref(),{checkLimit(b){let c=a.get(b);if(!c)return{allowed:!0};if(null!==c.lockedUntil){let a=Date.now();if(a<c.lockedUntil)return{allowed:!1,retryAfter:Math.ceil((c.lockedUntil-a)/1e3)};c.attempts=0,c.lockedUntil=null}return{allowed:!0}},recordFailure(b){let c=Date.now(),d=a.get(b)||{attempts:0,lockedUntil:null,lastAttempt:c};d.attempts++,d.lastAttempt=c,d.attempts>=g.maxAttempts&&(d.lockedUntil=c+g.lockoutDuration),a.set(b,d)},recordSuccess(b){a.delete(b)},destroy(){clearInterval(b),a.clear()}}}},90164:(a,b,c)=>{"use strict";c.d(b,{Dk:()=>e,kD:()=>f});let d="https://github.com/Kewton/CommandMate",e=`${d}/releases/`,f=`${d}/blob/main/docs/security-guide.md`}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=7187,exports.ids=[7187],exports.modules={7187:(a,b,c)=>{c.d(b,{bN:()=>am});var d=c(85164),e=c(37717),f=c(26895);let g=["enforce","observe","legacy"],h={claude:"observe",copilot:"enforce",opencode:"enforce",codex:"legacy",gemini:"legacy",antigravity:"legacy","vibe-local":"legacy","command-code":"legacy"},i=globalThis.__idleEvidenceObservations??(globalThis.__idleEvidenceObservations=new Map),j=new Set(["opencode","codex","claude","copilot"]);function k(a){return{...a,detect:(b,c)=>(function(a,b,c={}){let k=a.beforePrompt?.(b)??null;if(k)return k;let l=(0,d.KO)(a.tool),m=j.has(a.tool)?(0,d._A)(b.clean):(0,d._A)(b.lastLines),n=(0,f.gF)(m,l);if(n.isPrompt)if(!a.isStalePrompt?.(b,n))return{status:"waiting",confidence:"high",reason:e.g.PROMPT_DETECTED,hasActivePrompt:!0,evidence:"positive",promptDetection:n};else n={...n,isPrompt:!1,promptData:void 0};let o=a.afterPrompt?.(b,n)??null;if(o)return{...o,promptDetection:o.promptDetection??n};if((0,d.ut)(a.tool,b.thinkingLines))return{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive",promptDetection:n};let p=a.afterThinking?.(b,n)??null;if(p)return{...p,promptDetection:p.promptDetection??n};if(!a.skipGenericInputPrompt){let{promptPattern:c}=(0,d._X)(a.tool);if(c.test(b.lastLines))return{status:"ready",confidence:"high",reason:e.g.INPUT_PROMPT,hasActivePrompt:!1,evidence:function(a,b){if(void 0===a.readIdleEvidence)return"positive";let c=function(a,b=process.env){let c=b.CM_DETECTION_IDLE_EVIDENCE,d=null,e=null;if("string"==typeof c&&""!==c.trim())for(let b of c.split(",")){let[c,f]=b.split("=");if(void 0===f)continue;let h=c.trim(),i=f.trim();g.includes(i)&&("*"===h?d=i:h===a&&(e=i))}return e??d??h[a]??"legacy"}(a.tool);if("legacy"===c)return"positive";let d=a.readIdleEvidence(b);var e=a.tool;let f=i.get(e)??{mode:c,positive:0,none:0};return f.mode=c,"positive"===d?f.positive+=1:f.none+=1,i.set(e,f),"observe"===c?"positive":d}(a,b),promptDetection:n}}return c.lastOutputTimestamp&&Date.now()-c.lastOutputTimestamp.getTime()>5e3?{status:"running",confidence:"low",reason:e.g.NO_RECENT_OUTPUT,hasActivePrompt:!1,evidence:"none",promptDetection:n}:{status:"running",confidence:"low",reason:a.unreadableReason??e.g.DEFAULT,hasActivePrompt:!1,evidence:"none",promptDetection:n}})(a,b,c),detectDialog:a.detectDialog??(()=>null),hasDialogRules:void 0!==a.detectDialog}}var l=c(1804);let m=k({tool:"antigravity",verifiedAgainst:l.yh,beforePrompt:a=>!d.kT.test(a.lastLines)||(0,d.bH)(a.lastLines)?null:{status:"waiting",confidence:"high",reason:e.g.ANTIGRAVITY_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive"},afterThinking(a){if((0,d.ut)("antigravity",a.lastLines))return{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"};let{promptPattern:b}=(0,d._X)("antigravity");return b.test(a.lastLines)?{status:"ready",confidence:"high",reason:e.g.INPUT_PROMPT,hasActivePrompt:!1,evidence:"positive"}:null}});var n=c(94154),o=c(69119);let p=/^[^\S\n]*[│┃]?[^\S\n]*([❯›●>])?[^\S\n]*(\d{1,2})[.)][^\S\n]+(\S.*?)[^\S\n]*[│┃]?$/;function q(a){let b=p.exec(a);if(!b)return null;let c=Number(b[2]);return!Number.isInteger(c)||c<1?null:{glyph:b[1],number:c,label:b[3].trim()}}function r(a,b,c=8){let d=Math.min(b,a.length)-1,e=0,f=[],g=null;for(;d>=0&&e<=c;){let b=a[d];if(""===b.trim()){d--;continue}if(e++,g=q(b))break;f.unshift(b.trim()),d--}if(!g)return null;let h=d,i=[g],j=g.number-1,k=d-1,l=1,m=[];for(;j>=1&&k>=0&&l<=60;){let b=a[k];if(l++,""===b.trim()){k--;continue}let c=q(b);if(c&&c.number===j){i.unshift({...c,label:[c.label,...m].join(" ").trim()}),m=[],j--,k--;continue}if(c)break;m.unshift(b.trim()),k--}if(0!==j||i.length<2)return null;let n=i.findIndex(a=>void 0!==a.glyph);return{options:i.map(a=>a.label),selectedIndex:n,selectedGlyph:n<0?null:i[n].glyph??null,firstRow:k+1,lastRow:h,footer:f.join("\n")}}let s=/esc\s+to\s+cancel|enter\s+to\s+(?:select|confirm|set\s+as\s+default)/i,t=new Set(["❯",">"]),u=/do you want to\b|allow\b.*\?$/i,v=/ready to submit your answers\?|review your answers/i,w=/set\s+as\s+default/i,x=/^\s*[✻✽✶✢✳⦿◉●·⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]\s+\S+\s+for\s+(?:\d+m\s*)?\d+(?:\.\d+)?s(?:\s|$|\s*·)/,y=/^\s*╭─+\s*Claude Code v/,z=/^\s*[>❯]\s+\S/,A=/·\s*\/effort\s*$/;function B(a){let b=(0,n.p4)(a),c=b?b.openingSeparator:a.length,d=(0,o.oT)(a,0,c),e=c-1;for(;e>=0&&(""===a[e].trim()||d.has(e)||A.test(a[e]));)e--;return e}let C=k({tool:"claude",verifiedAgainst:l.iE,afterPrompt:a=>d.XY.test(a.lastLines)?{status:"waiting",confidence:"high",reason:e.g.CLAUDE_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive"}:null,afterThinking:a=>d.aU.test(a.lastLines)?{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"}:null,readIdleEvidence:function(a){let b=B(a.contentLines);if(b>=0&&x.test(a.contentLines[b]))return"positive";let c=(0,n.p4)(a.contentLines),d=a.contentLines.slice(0,c?c.openingSeparator:void 0),e=d.some(a=>y.test(a)),f=d.some(a=>z.test(a));return e&&!f?"positive":"none"},detectDialog:a=>(function(a,b){var c;if(b.transcriptTail<0)return null;let e=(0,d._A)(a.clean).split("\n"),f=r(e,b.transcriptTail+1);if(!f||null===f.selectedGlyph||!t.has(f.selectedGlyph))return null;let g=f.footer.trim();return""===g||s.test(g)?{kind:(c=function(a,b){let c=[];for(let d=b-1;d>=0&&c.length<4;d--){let b=a[d].trim();""!==b&&c.push(b)}return c.join("\n")}(e,f.firstRow),v.test(c)?"ask_user":w.test(g)?"picker":u.test(c)?"permission":"dialog"),options:f.options,answerMode:"numbered"}:null})(a,{transcriptTail:B(a.contentLines)})}),D=(0,c(72626).h)("codex-dialog-rules"),E={version:"0.153.2"},F=/press\s+\S+\s+to\s+\S|esc\s+(?:to\s+)?(?:cancel|close|dismiss|quit|exit|back|go\s+back)/i,G={bold:!1,dim:!1,coloured:!1};function H(a){let b=a.split("\n");for(let a=b.length-1;a>=0;a--){let c=function(a){if(!a.includes("\x1b"))return null;let b=function(a){let b=[],c=G,d=0;for(;d<a.length;){let e=a[d];if("\x1b"!==e){b.push({ch:e,attrs:c}),d++;continue}let f=a[d+1];if("["===f){let b=d+2;for(;b<a.length&&!/[A-Za-z]/.test(a[b]);)b++;if(b>=a.length)break;"m"===a[b]&&(c=function(a,b){let c=""===a?["0"]:a.split(";"),{bold:d,dim:e,coloured:f}=b;for(let a=0;a<c.length;a++){let b=""===c[a]?0:Number(c[a]);if(!Number.isNaN(b)){if(38===b){let b=""===c[a+1]||void 0===c[a+1]?-1:Number(c[a+1]);5===b?a+=2:2===b?a+=4:a+=1,f=!0;continue}if(48===b||58===b){let b=""===c[a+1]||void 0===c[a+1]?-1:Number(c[a+1]);5===b?a+=2:2===b?a+=4:a+=1;continue}0===b?(d=!1,e=!1,f=!1):1===b?d=!0:2===b?e=!0:22===b?(d=!1,e=!1):39===b?f=!1:(b>=30&&b<=37||b>=90&&b<=97)&&(f=!0)}}return{bold:d,dim:e,coloured:f}}(a.slice(d+2,b),c)),d=b+1;continue}if("]"===f){let b=d+2;for(;b<a.length;){if("\x07"===a[b]){b++;break}if("\x1b"===a[b]&&"\\"===a[b+1]){b+=2;break}b++}d=b;continue}d+=2}return b}(a),c=b.findIndex(a=>""!==a.ch.trim());if(c<0||"›"!==b[c].ch)return null;let d=b[c].attrs;if(d.dim)return"transcript-echo";let e=b.slice(c+1).find(a=>""!==a.ch.trim());return e?.attrs.bold||d.coloured?"option":"composer"}(b[a]);if(null!==c)return{kind:c,row:a}}return null}let I=new Set,J={"hooks-review":"permission","hooks-list":"picker","hooks-detail":"picker",update:"update",trust:"trust"};var K=c(74258),L=c(46423);let M=l.jP,N=/press\s+(?:number|enter)\s+to\s+confirm/i,O=/^\s*[❯›●]?\s*\d{1,2}[.)]\s/;function P(a){for(let b=a.length-1;b>=Math.max(0,a.length-10);b--)if(d.aW.test(a[b]))return b;return -1}function Q(a){let b=P(a),c=b>=0?b-1:a.length-1;for(;c>=0&&""===a[c].trim();)c--;return c+1}function R(a){let b=P(a),c=b>=0?b:a.length,e=-1,f=-1;for(let b=0;b<c;b++){let c=a[b],g=c.trim();""!==g&&((N.test(g)||O.test(g))&&(e=b),(0,d.ut)("codex",c)&&(f=b))}return e>=0&&f>e}function S(a){return H(a)?.kind==="option"}let T=k({tool:"codex",verifiedAgainst:M,beforePrompt(a){let{contentLines:b}=a;if(d.pn.test(a.lastLines))return{status:"waiting",confidence:"high",reason:e.g.CODEX_PAGER,hasActivePrompt:!1,evidence:"positive",promptDetection:(0,f.gF)((0,d._A)(a.clean),(0,d.KO)("codex"))};let c=(0,d.E6)(a.clean);if("hooks-list"===c||"hooks-detail"===c)return{status:"waiting",confidence:"high",reason:e.g.CODEX_HOOKS_REVIEW,hasActivePrompt:!1,evidence:"positive",promptDetection:(0,f.gF)((0,d._A)(a.clean),(0,d.KO)("codex"))};let g=P(b),h=g>=0?g-1:b.length-1;for(;h>=0&&""===b[h].trim();)h--;if(h>=0){let c=b.slice(Math.max(0,h-K.h+1),h+1).join("\n");if(d.Jn.test(c)){let g=(0,f.gF)((0,d._A)(a.clean),(0,d.KO)("codex"));return g.isPrompt&&((g.promptData?.question?.trim()??"").endsWith("?")||d.Dd.test(c))&&!R(b)?{status:"waiting",confidence:"high",reason:e.g.PROMPT_DETECTED,hasActivePrompt:!0,evidence:"positive",promptDetection:g}:{status:"waiting",confidence:"high",reason:e.g.CODEX_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive",promptDetection:g}}}let i=function(a,b,c){let d=H(a),e=r(b,c),f=null!==e&&"›"===e.selectedGlyph,g=d?.kind==="option"?"glyph":f&&d?.kind!=="composer"&&d?.kind!=="transcript-echo"?"numbered-block":null;if(null===g)return null;let h=null!==e?e.footer:function(a,b,c){let d=[];for(let e=b+1;e<c&&d.length<8;e++){let b=a[e].trim();""!==b&&d.push(b)}return d.join("\n")}(b,function(a,b){for(let c=Math.min(b,a.length)-1;c>=0;c--)if(a[c].trimStart().startsWith("›"))return c;return -1}(b,c),c);return{by:g,options:e?.options??[],footer:h,footerRecognised:F.test(h)}}(a.raw,b,Q(b));if(i&&!R(b)){i.footerRecognised||function(a){let b=a.slice(0,200);!I.has(b)&&(I.size>=64||(I.add(b),D.warn("codexDialogFooterUnrecognised",{footer:b,verifiedAgainst:E.version,hint:"codex reworded a dialog footer; widen CODEX_DIALOG_FOOTER_PATTERN after re-capturing the frame"})))}(i.footer);let b=(0,f.gF)((0,d._A)(a.clean),(0,d.KO)("codex"));return b.isPrompt?{status:"waiting",confidence:"high",reason:e.g.PROMPT_DETECTED,hasActivePrompt:!0,evidence:"positive",promptDetection:b}:{status:"waiting",confidence:"high",reason:e.g.CODEX_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive",promptDetection:b}}return null},isStalePrompt:a=>R(a.contentLines),detectDialog:a=>(function(a,b){let c=(0,d._A)(a.clean).split("\n"),e=r(c,b.contentEnd);if(b.lifecycleDialog)return{kind:J[b.lifecycleDialog],options:e?.options??[],answerMode:"numbered"};if(!e||!d.Jn.test(e.footer)||b.stalePrompt)return null;let f=function(a,b){let c=[];for(let d=b-1;d>=0&&c.length<4;d--){let b=a[d].trim();""!==b&&c.push(b)}return c.join("\n")}(c,e.firstRow);return{kind:d.Dd.test(e.footer)||f.split("\n")[0]?.endsWith("?")?"permission":"picker",options:e.options,answerMode:"numbered"}})(a,{contentEnd:Q(a.contentLines),stalePrompt:R(a.contentLines),lifecycleDialog:(0,d.E6)(a.clean)}),afterThinking(a){let{contentLines:b}=a,c=P(b);if(c>=0){let f=c-1;for(;f>=0&&""===b[f].trim();)f--;if(f>=0){let c=b.slice(Math.max(0,f-L.$+1),f+1).join("\n");return(0,d.ut)("codex",c)?{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"}:d.gm.test(b[f].trim())&&!S(a.raw)?{status:"ready",confidence:"high",reason:e.g.INPUT_PROMPT,hasActivePrompt:!1,evidence:"positive"}:{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"}}}else{let c=b.length-1;for(;c>=0&&""===b[c].trim();)c--;if(!(c>=0&&d.gm.test(b[c].trim())&&!S(a.raw))&&(0,d.ut)("codex",a.lastLines))return{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"}}return null}}),U=/\benter\s+to\s+select\b\s*[·•]\s*esc\s+to\s+cancel\b/i,V=k({tool:"command-code",verifiedAgainst:l.ji,afterPrompt:a=>U.test(a.lastLines)?{status:"waiting",confidence:"high",reason:e.g.COMMAND_CODE_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive"}:null,afterThinking(a){if((0,d.ut)("command-code",a.lastLines))return{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"};let{promptPattern:b}=(0,d._X)("command-code");return b.test(a.lastLines)?{status:"ready",confidence:"high",reason:e.g.INPUT_PROMPT,hasActivePrompt:!1,evidence:"positive"}:null}}),W=/do you want to\b/i,X=k({tool:"copilot",verifiedAgainst:l.MJ,beforePrompt(a){if((0,d.gT)(a.contentLines)){let b=(0,d.KO)("copilot"),c=(0,f.gF)((0,d._A)(a.clean),b);return c.isPrompt&&(c.promptData?.options?.length??0)<=3?{status:"waiting",confidence:"high",reason:e.g.PROMPT_DETECTED,hasActivePrompt:!0,evidence:"positive",promptDetection:c}:{status:"waiting",confidence:"high",reason:e.g.COPILOT_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive",promptDetection:c}}if("working"===(0,d.Wn)(a.contentLines)){let b=(0,d.KO)("copilot"),c=(0,f.gF)((0,d._A)(a.clean),b);return{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive",promptDetection:c}}return null},afterThinking:a=>"idle"===(0,d.Wn)(a.contentLines)?{status:"ready",confidence:"high",reason:e.g.INPUT_PROMPT,hasActivePrompt:!1,evidence:"positive"}:null,skipGenericInputPrompt:!0,readIdleEvidence:function(a){return"idle"===(0,d.Wn)(a.contentLines)?"positive":"none"},detectDialog:a=>(function(a,b){if(null!==b.statusBar)return null;let c=(0,d._A)(a.clean).split("\n"),e=r(c,b.contentEnd);if(e&&d.V.test(e.footer)){let a=function(a,b){let c=[];for(let d=b-1;d>=0&&c.length<4;d--){let b=a[d].trim();""!==b&&c.push(b)}return c.join("\n")}(c,e.firstRow);return{kind:d.rX.some(b=>a.includes(b))?"trust":W.test(a)?"permission":"picker",options:e.options,answerMode:"numbered"}}return b.selectionFrame?{kind:"picker",options:[],answerMode:"keys"}:null})(a,{statusBar:(0,d.Wn)(a.contentLines),selectionFrame:(0,d.gT)(a.contentLines),contentEnd:a.contentLines.length}),unreadableReason:e.g.UNKNOWN_FRAME});var Y=c(76777),Z=c(50524);let $=/\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\[[0-9;]*m/g,_=/^(?:\x1b\[|\[)([0-9;]*)m$/,aa=new Set([38,48,58]);function ab(a){let b;$.lastIndex=0;let c=[],d="",e=null,f=0,g=0,h=0;for(;null!==(b=$.exec(a));){let i=a.slice(h,b.index);d+=i,f+=(0,Z.LQ)(i),h=b.index+b[0].length;let j=_.exec(b[0]);if(null===j)continue;let k=function(a,b){let c=(""===b?"0":b).split(";"),d=a;for(let a=0;a<c.length;a++){let b=Number(""===c[a]?"0":c[a]);if(Number.isFinite(b)){if(aa.has(b)){let e="2"===c[a+1]?4:2*("5"===c[a+1]);e>0&&48===b&&(d=c.slice(a,a+1+e).join(";")),a+=e;continue}0===b||49===b?d=null:(b>=40&&b<=47||b>=100&&b<=107)&&(d=c[a])}}return d}(e,j[1]);k!==e&&(f>g&&c.push({bg:e,start:g,end:f}),e=k,g=f)}let i=a.slice(h);d+=i,(f+=(0,Z.LQ)(i))>g&&c.push({bg:e,start:g,end:f});let j=new Set(c.map(a=>a.start));return c.length>0&&j.add(c[c.length-1].end),{text:d,segments:c,edges:j,width:f}}function ac(a,b){for(let c of a.segments)if(c.start<=b&&b<c.end)return c.bg;return null}let ad=/\S[^\S\n]{2,}esc[^\S\n]*$/,ae=/^[│┃╹]/;function af(a,b,c){if(!a.edges.has(b)||!a.edges.has(c))return!1;for(let d of a.segments)if(!(d.end<=b)&&!(d.start>=c)&&null===d.bg)return!1;return!(ac(a,b-1)===ac(a,b)||c<a.width&&ac(a,c)===ac(a,c-1)||ae.test((0,Z.Ml)(a.text,b-1,b)))&&!ae.test((0,Z.Ml)(a.text,b,c))}function ag(a){let b=function(a){let b=a.split("\n").map(ab),c=new Set,d=null;for(let a of b){if(!a.text.includes("esc"))continue;let e=[...a.edges].sort((a,b)=>a-b);for(let f of e)if(!(f<1))for(let g of e){if(g-f<16)continue;let e=`${f}:${g}`;if(c.has(e)||!af(a,f,g))continue;let h=(0,Z.Ml)(a.text,f,g);if(!ad.test(h))continue;c.add(e);let i=b.filter(a=>af(a,f,g));if(i.length<3)continue;let j=i.indexOf(a);j<0||j>=3||(null===d||i.length>d.rows)&&(d={id:"opencode_modal_overlay",headerText:(0,Y.D)(h.trim(),200,"…[truncated]"),left:f,right:g,rows:i.length,headerRow:j,frameRowStart:b.indexOf(i[0]),frameRowEnd:b.indexOf(i[i.length-1])})}}return d}(a);return null===b?null:{id:b.id,headerText:b.headerText,left:b.left,right:b.right,rows:b.rows,headerRow:b.headerRow}}let ah=/\s{2,}/;function ai(a){let b=(0,d._A)(a.clean).split("\n"),c=Math.max(0,b.length-7);for(let a=b.length-1;a>=Math.max(0,b.length-10);a--)if(/ctrl\+[tp]/.test(b[a])){c=Math.max(0,a-2);break}let e=b.slice(0,c),f=e.length-1;for(;f>=0&&""===e[f].trim();)f--;return{candidates:e,lastIndex:f}}let aj=k({tool:"opencode",verifiedAgainst:l.BG,afterThinking(a){if(d.Ty.test(a.lastLines))return{status:"waiting",confidence:"high",reason:e.g.OPENCODE_PERMISSION_PROMPT,hasActivePrompt:!1,evidence:"positive"};if(d.kD.test(a.lastLines))return{status:"running",confidence:"high",reason:e.g.OPENCODE_PROCESSING_INDICATOR,hasActivePrompt:!1,evidence:"positive"};let{candidates:b,lastIndex:c}=ai(a);if(c<0)return null;let f=b.slice(Math.max(0,c-L.$+1),c+1).join("\n");if((0,d.ut)("opencode",f))return{status:"running",confidence:"high",reason:e.g.THINKING_INDICATOR,hasActivePrompt:!1,evidence:"positive"};let g=b.slice(Math.max(0,c-K.h+1),c+1).join("\n");if(d.LO.test(b.join("\n")))return{status:"waiting",confidence:"high",reason:e.g.OPENCODE_SELECTION_LIST,hasActivePrompt:!1,evidence:"positive"};if(null!==ag(a.raw))return{status:"waiting",confidence:"high",reason:e.g.OPENCODE_MODAL_OVERLAY,hasActivePrompt:!1,evidence:"positive"};if(d.$t.test(g))return{status:"ready",confidence:"high",reason:e.g.OPENCODE_RESPONSE_COMPLETE,hasActivePrompt:!1,evidence:"positive"};let h=a.lines.slice(Math.max(0,c-K.h+1),c+1).join("\n");return d.vU.test(h)?{status:"ready",confidence:"high",reason:e.g.INPUT_PROMPT,hasActivePrompt:!1,evidence:"positive"}:null},skipGenericInputPrompt:!0,readIdleEvidence:function(a){let{candidates:b,lastIndex:c}=ai(a);if(c<0)return"none";let e=b.slice(Math.max(0,c-K.h+1),c+1).join("\n");if(d.$t.test(e))return"positive";let f=a.lines.slice(Math.max(0,c-K.h+1),c+1).join("\n");return d.vU.test(f)?"positive":"none"},detectDialog(a){var b;let{candidates:c}=ai(a);return b={contentWindow:c.join("\n")},d.Ty.test(a.lastLines)?{kind:"permission",options:function(a){for(let b of a.lines){let a=d.Ty.exec(b);if(a)return a[0].replace(/^[^\S\n]*[│┃][^\S\n]*/,"").trim().split(ah).map(a=>a.trim()).filter(a=>""!==a)}return[]}(a),answerMode:"keys"}:d.LO.test(b.contentWindow)||null!==ag(a.raw)?{kind:"picker",options:[],answerMode:"keys"}:null},unreadableReason:e.g.UNKNOWN_FRAME});function ak(a){return k({tool:a,verifiedAgainst:l.hB})}let al={claude:C,codex:T,copilot:X,opencode:aj,antigravity:m,"command-code":V,gemini:ak("gemini"),"vibe-local":ak("vibe-local")};function am(a){return al[a]??ak(a)}Object.values(al)},26895:(a,b,c)=>{c.d(b,{gF:()=>n,xn:()=>g});var d=c(72626),e=c(69119),f=c(68652);function g(a,b="yes_no"){let c=a.toLowerCase().trim();if("multiple_choice"===b){if(/^\d+$/.test(c))return c;throw Error("Invalid answer for multiple choice prompt. Expected a number.")}if("yes"===c||"y"===c)return"y";if("no"===c||"n"===c)return"n";throw Error("Invalid answer for yes/no prompt. Expected 'yes', 'no', 'y', or 'n'.")}let h=(0,d.h)("prompt-detector"),i=null;function j(a){let b=a.split("\n"),c=(b.length>200?b.slice(-200):b).join("\n");return c.length>5e3&&(c=c.slice(-5e3)),c}let k=[{regex:/^(.+)\s+\(y\/n\)\s*$/m},{regex:/^(.+)\s+\[y\/N\]\s*$/m,defaultOption:"no"},{regex:/^(.+)\s+\[Y\/n\]\s*$/m,defaultOption:"yes"},{regex:/^(.+)\s+\(yes\/no\)\s*$/m}];function l(a,b,c,d){let{startLine:f,endLine:g}=function(a,b,c){let d=c.index??0,e=a=>a.split("\n").length-1,f=b+e(a.slice(0,d));return{startLine:f,endLine:f+e(c[0])}}(b,c,d);return(0,e.ZH)(a,(0,e.wf)(a,f),g+1)}function m(a,b,c,d,e){return{isPrompt:!0,promptData:{type:"yes_no",question:a,options:["yes","no"],status:"pending",...void 0!==e&&{defaultOption:e},instructionText:c,...void 0!==d&&{approvalTarget:d}},cleanContent:b,rawContent:c}}function n(a,b){let c=(0,f.N)(a),d=c===a&&b?.precomputedLines?b.precomputedLines:c.split("\n"),g=d.slice(-50).join("\n"),n=g===i;n||h.debug("detectPrompt:start",{outputLength:c.length}),i=g;let o=d.slice(-20).join("\n"),p=Math.max(0,d.length-20),q=(0,e.rS)(c,b,j);if(q.isPrompt)return n||h.info("detectPrompt:multipleChoice",{isPrompt:!0,question:q.promptData?.question,optionsCount:q.promptData?.options?.length}),q;let r=o.trim();for(let a of k){let b=o.match(a.regex);if(b){let c=b[1].trim();return m(c,c,r,l(d,o,p,b),a.defaultOption)}}let s=o.match(/^(.*?)Approve\?\s*$/m);if(s){let a=s[1].trim();return m(a?`${a} Approve?`:"Approve?",a||"Approve?",r,l(d,o,p,s))}return n||h.debug("detectPrompt:complete",{isPrompt:!1}),{isPrompt:!1,cleanContent:c.trim()}}},37717:(a,b,c)=>{c.d(b,{g:()=>d});let d={PROMPT_DETECTED:"prompt_detected",THINKING_INDICATOR:"thinking_indicator",OPENCODE_PROCESSING_INDICATOR:"opencode_processing_indicator",OPENCODE_SELECTION_LIST:"opencode_selection_list",OPENCODE_MODAL_OVERLAY:"opencode_modal_overlay",OPENCODE_PERMISSION_PROMPT:"opencode_permission_prompt",CLAUDE_SELECTION_LIST:"claude_selection_list",COMMAND_CODE_SELECTION_LIST:"command_code_selection_list",COPILOT_SELECTION_LIST:"copilot_selection_list",CODEX_SELECTION_LIST:"codex_selection_list",CODEX_PAGER:"codex_pager",CODEX_HOOKS_REVIEW:"codex_hooks_review",ANTIGRAVITY_SELECTION_LIST:"antigravity_selection_list",OPENCODE_RESPONSE_COMPLETE:"opencode_response_complete",INPUT_PROMPT:"input_prompt",NO_RECENT_OUTPUT:"no_recent_output",EXITED:"exited",UNKNOWN_FRAME:"unknown_frame",DEFAULT:"default"}},50524:(a,b,c)=>{c.d(b,{LQ:()=>g,Ml:()=>f,sh:()=>e});let d=/^\p{M}$/u;function e(a,b){if(a.length<=b)return a.length;let c=0,e=0;for(let f of a){let a=+!d.test(f);if(1===a&&c>=b)break;c+=a,e+=f.length}return e}function f(a,b,c){return a.slice(e(a,b),e(a,c))}function g(a){let b=0;for(let c of a)d.test(c)||(b+=1);return b}},68652:(a,b,c)=>{c.d(b,{N:()=>g});let d=/Esc\s+to\s+cancel\s*[·•]\s*Tab\s+to\s+amend/i,e=/Enter\s+to\s+select\b.*\bnavigate\b/i,f=/^\s*[>❯]\s*(?:\d{1,2}[.)])?|esc\s+to\s+interrupt|[✻✽✶✢✳⦿◉●⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]\s+.+…/i;function g(a){if(""===a)return"";let b=a.split("\n"),c=-1;for(let a=b.length-1;a>=0;a--){var g;if(g=b[a],d.test(g)||e.test(g)){c=a;break}}let h=b;return c>=0&&(h=b.slice(c+1).some(a=>f.test(a))?b.slice(c+1):b.slice(0,c+1)),(function(a){let b=[],c=!1;for(let d of a){let a=""===d.trim();a&&c||(b.push(d),c=a)}for(;b.length>0&&""===b[b.length-1].trim();)b.pop();return b})(h).join("\n")}},69119:(a,b,c)=>{c.d(b,{ZH:()=>z,oT:()=>j,rS:()=>A,wf:()=>y});var d=c(68652),e=c(85164);let f=/^\s*[\u276F\u25CF\u203A][^\d]*(\d+)(?:\.(?!\d)|\s{2,})\s*(.+)$/,g=/^\s*[^\d]{0,3}(\d+)(?:\.(?!\d)|\s+)\s*(.+)$/,h=/^\s*\d{1,3}\s+tasks?\s+\(\d+\s+done\b/i,i=/^\s*[◼◻]\s/;function j(a,b,c){let d=new Set;for(let e=Math.max(0,b);e<Math.min(c,a.length);e++)if(h.test(a[e])){d.add(e);for(let b=e+1;b<Math.min(c,a.length);b++){let c=a[b];if(!i.test(c)&&!m.test(c))break;d.add(b)}}return d}let k=/^[-─]+$/,l=/^\s*\[[^\]]*\d+\s+lines?\]/i,m=/^\s*[…]?\s*[+\-↑↓⏵⏷]?\s*\d+\s+(?:pending|more|completed)\b/i,n=/Esc\s+to\s+cancel\s*[·•]\s*Tab\s+to\s+amend/i,o=/Enter\s+to\s+select\b.*\bnavigate\b/i,p=/press\s+(?:enter|number)\s+to\s+confirm/i,q=/press\s+number\s+to\s+confirm/i,r=/(?:select|choose|pick|which|what|how|where|enter|type|specify|confirm|approve|accept|reject|decide|preference|option)/i,s=[/type\s+here/i,/tell\s+(me|claude)/i,/enter\s+/i,/custom/i,/differently/i];function t(a,b){if(0===b.length)return!0;let c=b[0].number;return a<c&&a>=c-2}function u(a){return{isPrompt:!1,cleanContent:a.trim()}}function v(a){return 0!==a.length&&!!(a.includes("?")||a.includes("?")||r.test(a))}function w(a,b){let c=b.endsWith("?")||b.endsWith("?");return!!(!c&&/^\s{2,}[^\d]/.test(a)&&!/^\s*\d+\./.test(a)||!c&&/^\s{4,}/.test(a)&&!/^\s*\d+\.\s/.test(a)||b.length<5&&!c||/^[\/~]/.test(b)||b.length>=2&&/^[a-zA-Z0-9_-]+$/.test(b))}let x=/^[⏺⎿●○•✔✓✖✗✘›»❯└├>]/;function y(a,b){let c=Math.max(0,b-12);for(let d=b-1;d>=c;d--)if(function(a){if(void 0===a)return!1;let b=a.trim();return""!==b&&(x.test(b)||k.test(b))}(a[d]))return d+1;return c}function z(a,b,c){let d=a.slice(b,c).map(a=>a.trimEnd()).join("\n").trim();return d.length>0?d:void 0}function A(a,b,c){if(a=(0,d.N)(a),b?.hasNumberedDialogs===!1)return u(a);let h=b?.requireDefaultIndicator??!0,i=a.split("\n"),r=i.length;for(;r>0&&""===i[r-1].trim();)r--;let x=Math.max(0,r-50),A=!1;for(let a=r-1;a>=x;a--){let b=o.test(i[a]);if(n.test(i[a])||b){r=a,A=b;break}}let B=i.slice(x,r);for(let b of B)if(e.l8.test(b))return u(a);let C=!1,D=!1;for(let a of B){let b=a.trim();if(!C&&p.test(b)){C=!0,q.test(b)&&(D=!0);break}}if(h){let b=!1;for(let a of B){let c=a.trim();if(f.test(c)){b=!0;break}}if(!b&&!C)return u(a)}let E=[],F=-1,G=0,H=j(i,x,r);for(let b=r-1;b>=x;b--){let c=i[b].trim();if(H.has(b)||l.test(c)||m.test(c)){G++;continue}let d=c.match(f);if(d){let a=parseInt(d[1],10);if(a<=20&&t(a,E)){let b=d[2].trim();E.unshift({number:a,label:b,isDefault:!0}),G=0;continue}}let e=c.match(g);if(e){let a=parseInt(e[1],10);if(a>20);else if(t(a,E)){let b=e[2].trim();E.unshift({number:a,label:b,isDefault:!1}),G=0;continue}}if(0===E.length&&(c.startsWith("❯")||c.startsWith("●")||c.startsWith("›")))return u(a);if(E.length>0&&c&&!k.test(c)){let a=i[b];if(/^\s{4,}/.test(a)&&w(a,c)){if(++G>25){F=b;break}continue}if(v(c)){F=b;break}if(w(a,c)){if(++G>(/^\s{4,}/.test(a)?25:5)){F=b;break}continue}F=b;break}}if(!function(a){if(0===a.length||1!==a[0])return!1;let b=0;for(let c=1;c<a.length;c++){let d=a[c]-a[c-1];if(d<1||d>2||(2===d&&b++,b>1))return!1}return!0}(E.map(a=>a.number)))return u(a);let I=E.some(a=>a.isDefault),J=h&&C;if(E.length<2||h&&!I&&!J||!h&&!I&&(-1===F||!v(i[F]?.trim()??"")&&!function(a,b,c,d){let e=Math.max(d,b-3);for(let c=b-1;c>=e;c--){let b=a[c]?.trim()??"";if(!(!b||k.test(b))&&v(b))return!0}return!1}(i,F,0,x)))return u(a);let K=function(a,b){if(b<0)return"Please select an option:";let c=[];for(let d=Math.max(0,b-5);d<=b;d++){let b=a[d].trim();b&&!k.test(b)&&c.push(b)}return c.join(" ")}(i,F),L=function(a,b,c){if(b<0)return;let d=Math.max(0,b-19),e=a.slice(d,c).map(a=>a.trimEnd()).join("\n").trim();return e.length>0?e:void 0}(i,F,r),M=function(a,b,c){if(!(b<0))return z(a,y(a,b),c)}(i,F,r);var N=a,O=C?D?"answer_only":"answer_then_enter":void 0,P=A;let{instructionText:Q,approvalTarget:R}={instructionText:L,approvalTarget:M}??{};return{isPrompt:!0,promptData:{type:"multiple_choice",question:K.trim(),options:E.map(a=>{let b=s.some(b=>b.test(a.label));return{number:a.number,label:a.label,isDefault:a.isDefault,requiresTextInput:b}}),status:"pending",instructionText:Q,...void 0!==R?{approvalTarget:R}:{},...O?{submitMode:O}:{},...P?{isAskUserQuestion:!0}:{}},cleanContent:K.trim(),rawContent:c(N.trim())}}},74258:(a,b,c)=>{c.d(b,{h:()=>g,z:()=>h});var d=c(85164),e=c(68652),f=c(46423);let g=15;function h(a){let b=(0,e.N)((0,d.aJ)(a)),c=b.split("\n"),h=c.length-1;for(;h>=0&&""===c[h].trim();)h--;let i=c.slice(0,h+1);return{raw:a,clean:b,lines:c,contentLines:i,lastLines:i.slice(-g).join("\n"),thinkingLines:i.slice(-f.$).join("\n")}}},76777:(a,b,c)=>{c.d(b,{D:()=>d});function d(a,b,c){let d=new TextEncoder;if(d.encode(a).length<=b)return a;let e=b-d.encode(c).length,f=0,g="";for(let b of a){let a=d.encode(b).length;if(f+a>e)break;f+=a,g+=b}return`${g}${c}`}}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=7472,exports.ids=[7472],exports.modules={30008:(a,b,c)=>{c.d(b,{F1:()=>g,_G:()=>i,j0:()=>f,rB:()=>h,xF:()=>j});var d=c(48083),e=c(67882);let f=3e5,g="CM_STRUCTURED_SEND_GUARD";function h(a){return"notification"===a.source?e.Oh.PERMISSION_PROMPT:e.Oh.PERMISSION_REQUEST}function i({worktreeId:a,cliToolId:b,instanceId:c,scraper:e,ignoreStructured:i=!1,now:j=Date.now()}){var k,l,m;let n=(0,d.P5)(a,b,c,j);null!==n&&("waiting"===e.status?(0,d.zA)(a,b,c,j):n.scraperCorroborated&&((0,d.m5)(a,b,c),n=null));let o=e.hasActivePrompt||null!==n;if(e.hasActivePrompt)return{waiting:o,scraperWaiting:!0,structured:n,blocksSend:!0,blockedBy:"scraper",blockReason:e.reason,structuredSendBlockSuppressed:null};if(null===n)return{waiting:o,scraperWaiting:!1,structured:null,blocksSend:!1,blockedBy:null,blockReason:null,structuredSendBlockSuppressed:null};let p=(k=n,l=i,m=j,l?"caller_opt_out":!function(){let a=process.env[g]?.trim().toLowerCase();return"off"===a||"0"===a||"false"===a}()?m-k.at>=f?"expired":null:"disabled");return{waiting:o,scraperWaiting:!1,structured:n,blocksSend:null===p,blockedBy:null===p?"structured":null,blockReason:null===p?h(n):null,structuredSendBlockSuppressed:p}}function j({worktreeId:a,cliToolId:b,instanceId:c,scraper:e,now:f=Date.now()}){let g=(0,d.P5)(a,b,c,f);return{waiting:e.hasActivePrompt||null!==g,scraperWaiting:e.hasActivePrompt,structured:g}}},40043:(a,b,c)=>{c.d(b,{AD:()=>k,Q4:()=>g,ox:()=>j,xG:()=>l});var d=c(37717),e=c(48083);let f=new Set([d.g.NO_RECENT_OUTPUT,d.g.UNKNOWN_FRAME,d.g.DEFAULT]);function g(a,b){return"running"===a&&f.has(b)}let h=e.sA,i=globalThis.__lastKnownStatusByKey??(globalThis.__lastKnownStatusByKey=new Map);function j(a,b,c=Date.now()){for(let[a,b]of i)c-b.at>=h&&i.delete(a);for(;i.size>512;){let a=i.keys().next();if(a.done)break;i.delete(a.value)}"positive"===b.evidence&&(i.delete(a),i.set(a,{status:b.status,reason:b.reason,at:c}))}function k(a,b=Date.now()){let c=i.get(a);return void 0===c?null:b-c.at>=h?(i.delete(a),null):c}function l(a){i.delete(a)}},95595:(a,b,c)=>{c.d(b,{WC:()=>j,f8:()=>i,gv:()=>d.g,ug:()=>g});var d=c(37717),e=c(74258),f=c(7187);let g=new Set([d.g.OPENCODE_SELECTION_LIST,d.g.OPENCODE_MODAL_OVERLAY,d.g.OPENCODE_PERMISSION_PROMPT,d.g.CLAUDE_SELECTION_LIST,d.g.COMMAND_CODE_SELECTION_LIST,d.g.COPILOT_SELECTION_LIST,d.g.CODEX_SELECTION_LIST,d.g.CODEX_PAGER,d.g.CODEX_HOOKS_REVIEW,d.g.ANTIGRAVITY_SELECTION_LIST]),h=new Set([d.g.THINKING_INDICATOR,d.g.OPENCODE_PROCESSING_INDICATOR]);function i(a){return"running"===a.status&&h.has(a.reason)}function j(a,b,c){let d=(0,e.z)(a),g=(0,f.bN)(b).detect(d,{lastOutputTimestamp:c});return{status:g.status,confidence:g.confidence,reason:g.reason,hasActivePrompt:g.hasActivePrompt,evidence:g.evidence,promptDetection:g.promptDetection??{isPrompt:!1,cleanContent:d.clean}}}}};
|