commandmate 0.47.2 → 0.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +215 -215
- package/.next/app-path-routes-manifest.json +41 -41
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +9 -9
- 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/release-notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update/route.js +3 -3
- package/.next/server/app/api/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_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 +2 -2
- package/.next/server/app/api/hooks/agent-event/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route.js +2 -2
- package/.next/server/app/api/hooks/claude-done/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js +1 -1
- package/.next/server/app/api/hooks/permission-request/route.js.nft.json +1 -1
- package/.next/server/app/api/hooks/permission-request/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/route.js +1 -1
- package/.next/server/app/api/relays/route.js.nft.json +1 -1
- package/.next/server/app/api/relays/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js +1 -1
- package/.next/server/app/api/repositories/clone/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js +1 -1
- package/.next/server/app/api/repositories/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +1 -1
- package/.next/server/app/api/repositories/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js +1 -1
- package/.next/server/app/api/repositories/scan/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js +1 -1
- package/.next/server/app/api/repositories/sync/route.js.nft.json +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js +1 -1
- package/.next/server/app/api/settings/default-agents/route.js.nft.json +1 -1
- package/.next/server/app/api/settings/default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/settings/default-surface-mode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_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/verification/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/auto-yes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/capture/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/clear-composer/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-reference/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_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]/direct-input/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/direct-input/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/env/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route_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/notes/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/instances/opencode/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/opencode/share/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/prompt-response/strict/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 +3 -3
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/install/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/plan/route_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 -103
- 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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/apply-default-agents/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route.js +1 -1
- package/.next/server/app/api/worktrees/route.js.nft.json +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page.js +1 -1
- package/.next/server/app/sessions/page_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 +12 -12
- 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 +41 -41
- package/.next/server/chunks/1191.js +11 -4
- package/.next/server/chunks/1501.js +1 -1
- package/.next/server/chunks/1601.js +2 -2
- package/.next/server/chunks/1656.js +2 -2
- package/.next/server/chunks/1945.js +3 -3
- package/.next/server/chunks/1990.js +103 -0
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2422.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2534.js +1 -1
- package/.next/server/chunks/255.js +1 -1
- package/.next/server/chunks/3241.js +1 -1
- package/.next/server/chunks/3505.js +2 -2
- package/.next/server/chunks/4248.js +1 -1
- package/.next/server/chunks/4280.js +1 -0
- package/.next/server/chunks/5209.js +1 -1
- package/.next/server/chunks/6119.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6486.js +9 -8
- package/.next/server/chunks/6781.js +1 -1
- package/.next/server/chunks/720.js +103 -0
- package/.next/server/chunks/7604.js +2 -0
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +7 -7
- package/.next/server/chunks/8728.js +3 -3
- package/.next/server/chunks/8791.js +1 -1
- package/.next/server/chunks/8807.js +19 -18
- package/.next/server/chunks/8918.js +2 -104
- package/.next/server/chunks/936.js +1 -1
- package/.next/server/chunks/9390.js +1 -1
- package/.next/server/chunks/9540.js +1 -1
- package/.next/server/chunks/9627.js +3 -3
- package/.next/server/chunks/9731.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/2099-c3e0ab70a1b95dd3.js +1 -0
- package/.next/static/chunks/{2407-a6533805a86d05bd.js → 2407-26139a8a2f1adbe8.js} +1 -1
- package/.next/static/chunks/{2619-04bc32f026a0d946.js → 2619-a305ad4810f1393a.js} +1 -1
- package/.next/static/chunks/{2863-6a07ec82fb52f4dd.js → 2863-f0121af1cbbedb3b.js} +1 -1
- package/.next/static/chunks/{8165-263172c17ae8e8c3.js → 8165-c68b3dc844210e6a.js} +1 -1
- package/.next/static/chunks/8407-35bbfc84793d7004.js +1 -0
- package/.next/static/chunks/9079-406b84d3cc891a87.js +1 -0
- package/.next/static/chunks/app/{layout-538d8d2746ad1588.js → layout-46b4cbf07520d9b6.js} +1 -1
- package/.next/static/chunks/app/sessions/page-fb241bed579c67aa.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-cbc7749a33450cc5.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/terminal/{page-373ea37b16d930c7.js → page-c601f3b3ece6557e.js} +1 -1
- package/.next/trace +13 -13
- package/dist/cli/commands/auto-yes.d.ts +24 -0
- package/dist/cli/commands/auto-yes.d.ts.map +1 -1
- package/dist/cli/commands/auto-yes.js +73 -3
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +10 -1
- package/dist/cli/commands/prompt.d.ts.map +1 -1
- package/dist/cli/commands/prompt.js +5 -3
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +15 -0
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +101 -13
- package/dist/cli/docs/agent-operations.d.ts +2 -2
- package/dist/cli/docs/agent-operations.d.ts.map +1 -1
- package/dist/cli/docs/agent-operations.js +27 -0
- package/dist/cli/types/api-responses.d.ts +116 -2
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +4 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/resource-resolvers.d.ts +0 -18
- package/dist/cli/utils/resource-resolvers.d.ts.map +1 -1
- package/dist/cli/utils/resource-resolvers.js +1 -51
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts +54 -2
- package/dist/lib/polling/auto-yes-suppression-reason.d.ts.map +1 -1
- package/dist/lib/polling/auto-yes-suppression-reason.js +33 -2
- package/dist/lib/prompt-observation/types.d.ts +13 -0
- package/dist/lib/prompt-observation/types.d.ts.map +1 -1
- package/dist/server/locales/en/worktree.json +2 -1
- package/dist/server/locales/ja/worktree.json +2 -1
- package/dist/server/src/lib/auto-yes-poller-answer-target.js +38 -0
- package/dist/server/src/lib/auto-yes-poller-keys.js +35 -0
- package/dist/server/src/lib/auto-yes-poller-session-presence.js +26 -0
- package/dist/server/src/lib/auto-yes-poller-tick.js +233 -0
- package/dist/server/src/lib/auto-yes-poller.js +337 -376
- package/dist/server/src/lib/auto-yes-state.js +50 -2
- package/dist/server/src/lib/cli-tools/submit-verified-sender.js +107 -14
- package/dist/server/src/lib/db/chat-db.js +5 -1
- package/dist/server/src/lib/db/verification-db.js +23 -2
- package/dist/server/src/lib/detection/option-recommendation.js +120 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice-approval-context.js +290 -0
- package/dist/server/src/lib/detection/prompt-detect-multiple-choice.js +396 -350
- package/dist/server/src/lib/detection/prompt-detector.js +92 -21
- package/dist/server/src/lib/detection/prompt-screen-key.js +60 -0
- package/dist/server/src/lib/detection/tools/antigravity/dialog.js +158 -35
- package/dist/server/src/lib/detection/tools/claude/detect.js +111 -10
- package/dist/server/src/lib/detection/tools/command-code/dialog.js +67 -0
- package/dist/server/src/lib/detection/tools/dialog-block.js +16 -0
- package/dist/server/src/lib/detection/waiting-screen-reading.js +98 -0
- package/dist/server/src/lib/hooks/permission-decision-service.js +7 -0
- package/dist/server/src/lib/polling/auto-yes-confirm-page.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger-types.js +3 -0
- package/dist/server/src/lib/polling/auto-yes-confirmation-ledger.js +34 -3
- package/dist/server/src/lib/polling/auto-yes-decision-state.js +195 -0
- package/dist/server/src/lib/polling/auto-yes-dialog-gate.js +139 -10
- package/dist/server/src/lib/polling/auto-yes-enter-fallback.js +14 -0
- package/dist/server/src/lib/polling/auto-yes-manual-answer.js +122 -0
- package/dist/server/src/lib/polling/auto-yes-option-effect.js +157 -0
- package/dist/server/src/lib/polling/auto-yes-policy.js +11 -5
- package/dist/server/src/lib/polling/auto-yes-poller-capture.js +15 -2
- package/dist/server/src/lib/polling/auto-yes-poller-generation.js +42 -1
- package/dist/server/src/lib/polling/auto-yes-poller-receipt-log.js +42 -5
- package/dist/server/src/lib/polling/auto-yes-poller-state.js +147 -49
- package/dist/server/src/lib/polling/auto-yes-poller-steps.js +172 -2
- package/dist/server/src/lib/polling/auto-yes-prompt-suppression.js +2 -2
- package/dist/server/src/lib/polling/auto-yes-question-choice.js +57 -0
- package/dist/server/src/lib/polling/auto-yes-resolver.js +96 -21
- package/dist/server/src/lib/polling/auto-yes-suppression-reason.js +33 -2
- package/dist/server/src/lib/polling/auto-yes-suppression-state.js +25 -1
- package/dist/server/src/lib/polling/prompt-screen-reading.js +232 -0
- package/dist/server/src/lib/polling/response-checker-dialog-gate.js +39 -0
- package/dist/server/src/lib/polling/response-checker.js +133 -43
- package/dist/server/src/lib/prompt-answer-sender.js +104 -10
- package/dist/server/src/lib/push/notification-dedup.js +15 -2
- package/dist/server/src/lib/push/prompt-card-state.js +140 -19
- package/dist/server/src/lib/push/prompt-push-gate.js +158 -12
- package/dist/server/src/lib/push/push-sender.js +23 -3
- package/dist/server/src/lib/push/resolution-push-notifier.js +14 -0
- package/dist/server/src/lib/push/waiting-push-notifier.js +139 -17
- package/dist/server/src/lib/realtime/terminal-broadcast.js +16 -0
- package/dist/server/src/lib/session/agent-event-state.js +25 -5
- package/dist/server/src/lib/session/agent-event-turn.js +140 -46
- package/dist/server/src/lib/session/cli-session.js +21 -2
- package/dist/server/src/lib/session/current-output-builder.js +64 -11
- package/dist/server/src/lib/session/send-attempt-state.js +23 -7
- package/dist/server/src/lib/session/waiting-episode-binding-observation.js +289 -0
- package/dist/server/src/lib/session/waiting-episode-binding-resolve.js +38 -0
- package/dist/server/src/lib/session/waiting-episode-binding.js +276 -0
- package/dist/server/src/lib/session/waiting-episode-state.js +307 -17
- package/dist/server/src/lib/session/waiting-episode-verdict.js +174 -0
- package/dist/server/src/lib/tmux/tmux-capture-cache.js +76 -11
- package/dist/server/src/lib/tmux/tmux.js +54 -9
- package/dist/server/src/lib/verification/gate-runner.js +162 -13
- package/dist/server/src/lib/verification/machine-lock.js +5 -0
- package/dist/server/src/lib/ws-server.js +18 -3
- package/dist/server/src/types/auto-yes-answer-mode.js +38 -0
- package/dist/server/src/types/auto-yes-decision.js +61 -0
- package/dist/server/src/types/auto-yes.js +6 -0
- package/dist/server/src/types/prompt-reading.js +32 -0
- package/dist/types/auto-yes-answer-mode.d.ts +35 -0
- package/dist/types/auto-yes-answer-mode.d.ts.map +1 -0
- package/dist/types/auto-yes-answer-mode.js +38 -0
- package/docs/en/user-guide/webapp-guide.md +33 -4
- package/package.json +1 -1
- package/public/sw.js +76 -4
- package/release-notes/0.48.0.json +57 -0
- package/.next/server/chunks/1559.js +0 -2
- package/.next/server/chunks/2460.js +0 -1
- package/.next/server/chunks/5595.js +0 -1
- package/.next/server/chunks/610.js +0 -1
- package/.next/static/chunks/602-1c1488959215e140.js +0 -1
- package/.next/static/chunks/8407-155f84e5ba05f1d5.js +0 -1
- package/.next/static/chunks/9079-24f9fa549ed298f1.js +0 -1
- package/.next/static/chunks/app/sessions/page-e02f1adb1d1c1ccc.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-46aced20b2b1c010.js +0 -1
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → PTlAswXLq8PAe2vUJ8dVP}/_buildManifest.js +0 -0
- /package/.next/static/{etorRtpxbQqqOzdUeXdw2 → PTlAswXLq8PAe2vUJ8dVP}/_ssgManifest.js +0 -0
|
@@ -16,6 +16,7 @@ exports.buildCompositeKey = buildCompositeKey;
|
|
|
16
16
|
exports.extractWorktreeId = extractWorktreeId;
|
|
17
17
|
exports.extractCliToolId = extractCliToolId;
|
|
18
18
|
exports.extractInstanceId = extractInstanceId;
|
|
19
|
+
exports.autoYesAnswerModeOf = autoYesAnswerModeOf;
|
|
19
20
|
exports.isAutoYesExpired = isAutoYesExpired;
|
|
20
21
|
exports.getAutoYesState = getAutoYesState;
|
|
21
22
|
exports.setAutoYesEnabled = setAutoYesEnabled;
|
|
@@ -36,12 +37,14 @@ exports.getCompositeKeysByWorktree = getCompositeKeysByWorktree;
|
|
|
36
37
|
exports.deleteAutoYesStateByWorktree = deleteAutoYesStateByWorktree;
|
|
37
38
|
exports.getEnabledAutoYesByWorktree = getEnabledAutoYesByWorktree;
|
|
38
39
|
exports.getRestartReleasedAutoYesByWorktree = getRestartReleasedAutoYesByWorktree;
|
|
40
|
+
exports.getEnabledAutoYesAnswerModeByWorktree = getEnabledAutoYesAnswerModeByWorktree;
|
|
39
41
|
exports.migrateAutoYesStateWorktreeIds = migrateAutoYesStateWorktreeIds;
|
|
40
42
|
exports.calculateBackoffInterval = calculateBackoffInterval;
|
|
41
43
|
const auto_yes_config_1 = require("../config/auto-yes-config");
|
|
42
44
|
const path_validator_1 = require("./security/path-validator");
|
|
43
45
|
const types_1 = require("./cli-tools/types");
|
|
44
46
|
const logger_1 = require("../lib/logger");
|
|
47
|
+
const auto_yes_answer_mode_1 = require("../types/auto-yes-answer-mode");
|
|
45
48
|
const global_state_1 = require("./global-state");
|
|
46
49
|
const logger = (0, logger_1.createLogger)('auto-yes-state');
|
|
47
50
|
// =============================================================================
|
|
@@ -124,6 +127,14 @@ function extractInstanceId(compositeKey) {
|
|
|
124
127
|
// parts[2] = alias instanceId; fall back to parts[1] (cliToolId) for primary keys.
|
|
125
128
|
return parts[2] ?? parts[1] ?? null;
|
|
126
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* The answer mode a state stands for (Issue #3863): its own, or
|
|
132
|
+
* `recommended` for a state that predates the field. Not meaningful on a
|
|
133
|
+
* disabled state, whose mode a later enable does not inherit.
|
|
134
|
+
*/
|
|
135
|
+
function autoYesAnswerModeOf(state) {
|
|
136
|
+
return state.answerMode ?? auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE;
|
|
137
|
+
}
|
|
127
138
|
/** In-memory storage for auto-yes states (globalThis for hot reload persistence) */
|
|
128
139
|
const autoYesStates = (0, global_state_1.getOrInitGlobal)('__autoYesStates', () => new Map());
|
|
129
140
|
// =============================================================================
|
|
@@ -196,10 +207,17 @@ function getAutoYesState(worktreeId, cliToolId = 'claude', instanceId) {
|
|
|
196
207
|
* Defaults to DEFAULT_AUTO_YES_DURATION (1 hour) when omitted.
|
|
197
208
|
* @param stopPattern - Optional regex pattern for stop condition (Issue #314).
|
|
198
209
|
* @param instanceId - Optional instance identifier (Issue #896; defaults to primary).
|
|
199
|
-
|
|
200
|
-
|
|
210
|
+
* @param answerMode - Issue #3863: how questions are answered. Omitted, an
|
|
211
|
+
* enable over a LIVE grant keeps that grant's mode, and any other enable —
|
|
212
|
+
* from off, or over a grant that has run out — starts at `recommended`.
|
|
213
|
+
* Whether the grant is live is read through {@link getAutoYesState}, which
|
|
214
|
+
* turns an expired grant into a disabled one first, so an enable at or after
|
|
215
|
+
* the deadline is a new grant, not a continuation. Ignored when disabling.
|
|
216
|
+
*/
|
|
217
|
+
function setAutoYesEnabled(worktreeId, cliToolId, enabled, duration, stopPattern, instanceId, answerMode) {
|
|
201
218
|
const key = buildCompositeKey(worktreeId, cliToolId, instanceId);
|
|
202
219
|
if (enabled) {
|
|
220
|
+
const current = answerMode === undefined ? getAutoYesState(worktreeId, cliToolId, instanceId) : null;
|
|
203
221
|
const now = Date.now();
|
|
204
222
|
const effectiveDuration = duration ?? auto_yes_config_1.DEFAULT_AUTO_YES_DURATION;
|
|
205
223
|
const state = {
|
|
@@ -207,6 +225,7 @@ function setAutoYesEnabled(worktreeId, cliToolId, enabled, duration, stopPattern
|
|
|
207
225
|
enabledAt: now,
|
|
208
226
|
expiresAt: now + effectiveDuration,
|
|
209
227
|
stopPattern,
|
|
228
|
+
answerMode: answerMode ?? (current?.enabled ? autoYesAnswerModeOf(current) : auto_yes_answer_mode_1.DEFAULT_AUTO_YES_ANSWER_MODE),
|
|
210
229
|
};
|
|
211
230
|
autoYesStates.set(key, state);
|
|
212
231
|
notifyChangeAfterShutdown();
|
|
@@ -681,6 +700,35 @@ function getRestartReleasedAutoYesByWorktree() {
|
|
|
681
700
|
}
|
|
682
701
|
return byWorktree;
|
|
683
702
|
}
|
|
703
|
+
/**
|
|
704
|
+
* The answer mode of every armed instance, grouped by worktree and keyed by
|
|
705
|
+
* instance, for the worktree list (Issue #3863).
|
|
706
|
+
*
|
|
707
|
+
* Its own map rather than a field on {@link getEnabledAutoYesByWorktree}'s
|
|
708
|
+
* entries, whose `{ enabled, expiresAt }` shape the list pins (#2512). The same
|
|
709
|
+
* instances that map holds (armed, read through {@link getAutoYesState} so an
|
|
710
|
+
* expiry resolved at read time drops out), each with the mode it runs under.
|
|
711
|
+
*
|
|
712
|
+
* @returns worktreeId -> instanceId -> mode; worktrees with nothing armed are absent
|
|
713
|
+
*/
|
|
714
|
+
function getEnabledAutoYesAnswerModeByWorktree() {
|
|
715
|
+
const byWorktree = new Map();
|
|
716
|
+
// A snapshot of the keys: an expired read below rewrites its own entry.
|
|
717
|
+
for (const key of Array.from(autoYesStates.keys())) {
|
|
718
|
+
const cliToolId = extractCliToolId(key);
|
|
719
|
+
if (!cliToolId)
|
|
720
|
+
continue;
|
|
721
|
+
const worktreeId = extractWorktreeId(key);
|
|
722
|
+
const instanceId = extractInstanceId(key) ?? cliToolId;
|
|
723
|
+
const state = getAutoYesState(worktreeId, cliToolId, instanceId);
|
|
724
|
+
if (!state?.enabled)
|
|
725
|
+
continue;
|
|
726
|
+
const entries = byWorktree.get(worktreeId) ?? {};
|
|
727
|
+
entries[instanceId] = autoYesAnswerModeOf(state);
|
|
728
|
+
byWorktree.set(worktreeId, entries);
|
|
729
|
+
}
|
|
730
|
+
return byWorktree;
|
|
731
|
+
}
|
|
684
732
|
/**
|
|
685
733
|
* Re-key every auto-yes state whose worktree ID is being renamed
|
|
686
734
|
* (Issue #1621 Phase 3).
|
|
@@ -289,7 +289,7 @@ function withoutTrailingBlankRows(lines) {
|
|
|
289
289
|
end--;
|
|
290
290
|
return lines.slice(0, end);
|
|
291
291
|
}
|
|
292
|
-
/** Default bounded read
|
|
292
|
+
/** Default bounded recovery Enters (each read back) before giving up (throwing). */
|
|
293
293
|
const DEFAULT_VERIFY_ATTEMPTS = 4;
|
|
294
294
|
/**
|
|
295
295
|
* First non-blank line of the message, trimmed. This is what a TUI shows on the
|
|
@@ -427,12 +427,61 @@ function comparePasteToken(token, message) {
|
|
|
427
427
|
* and its first line is the input line. Every other frame (a one-row
|
|
428
428
|
* composer, an empty or ghost one, none at all, another tool) is read exactly
|
|
429
429
|
* as before.
|
|
430
|
+
*
|
|
431
|
+
* Issue #3880 (H-2): this is also the reader before Enter
|
|
432
|
+
* ({@link classifyPasteLanded}) and in the error text ({@link describeComposer}).
|
|
433
|
+
* The paste check used to read the twelve-row tail with {@link readComposer}
|
|
434
|
+
* alone, so a codex composer taller than that window (a 20-line paste, or 600
|
|
435
|
+
* bytes wrapped in a narrow pane) put its `›` row above the window — `unseen`,
|
|
436
|
+
* and the body that was in the composer was withdrawn and reported as not
|
|
437
|
+
* landed — and a continuation row starting with `>` (a Markdown quote) was taken
|
|
438
|
+
* for the input line — `mismatch`. The same frame read after Enter was
|
|
439
|
+
* `pending`. One reader on both sides of Enter keeps the two verdicts about the
|
|
440
|
+
* same composer.
|
|
441
|
+
*/
|
|
442
|
+
/**
|
|
443
|
+
* Everything a codex composer holds, for deciding that a pasted body arrived in
|
|
444
|
+
* full (Issue #3880).
|
|
445
|
+
*
|
|
446
|
+
* `extractComposerText` answers for the UI: its text stops at 2,000 characters,
|
|
447
|
+
* at 40 rows and at the composer's first blank row, so a composer that matches
|
|
448
|
+
* it may still be missing the rest of the body — or hold something after it.
|
|
449
|
+
* This reads the raw rows instead, from the `›` row down to the last block of
|
|
450
|
+
* the frame (codex's model / cwd footer), so a body with blank lines, more than
|
|
451
|
+
* 40 rows or more than 2,000 characters is compared whole, and anything typed
|
|
452
|
+
* after the body is part of what is compared.
|
|
430
453
|
*/
|
|
454
|
+
function codexComposerRegion(output) {
|
|
455
|
+
const raw = output.split('\n');
|
|
456
|
+
const box = (0, composer_text_1.findCodexInputBox)(raw);
|
|
457
|
+
if (box === null)
|
|
458
|
+
return null;
|
|
459
|
+
const isBlank = (row) => (0, cli_patterns_1.stripAnsi)(row).trim() === '';
|
|
460
|
+
let end = raw.length - 1;
|
|
461
|
+
while (end >= 0 && isBlank(raw[end]))
|
|
462
|
+
end--;
|
|
463
|
+
let lastBlockStart = end;
|
|
464
|
+
while (lastBlockStart > 0 && !isBlank(raw[lastBlockStart - 1]))
|
|
465
|
+
lastBlockStart--;
|
|
466
|
+
const stop = lastBlockStart > box.lastRow ? lastBlockStart - 1 : end;
|
|
467
|
+
const rows = raw.slice(box.firstRow, stop + 1).map((row) => (0, cli_patterns_1.stripAnsi)(row));
|
|
468
|
+
rows[0] = rows[0].replace(/^\s*\u203A ?/, '');
|
|
469
|
+
return rows.join('\n');
|
|
470
|
+
}
|
|
431
471
|
function readSubmitComposer(output, cliToolId, reader, lines, windowLines) {
|
|
432
472
|
if (cliToolId === 'codex' && reader === 'input-line-marker') {
|
|
433
473
|
const read = (0, composer_text_1.extractComposerText)(output, cliToolId);
|
|
434
|
-
if (read.state === 'content'
|
|
435
|
-
|
|
474
|
+
if (read.state === 'content') {
|
|
475
|
+
const region = codexComposerRegion(output) ?? read.text;
|
|
476
|
+
if (read.text.includes('\n')) {
|
|
477
|
+
return { kind: 'text', text: firstNonBlankLine(read.text), rows: read.text.split('\n'), region };
|
|
478
|
+
}
|
|
479
|
+
// Issue #3880 (N1): a one-row excerpt is read as before for its verdict
|
|
480
|
+
// after Enter, but still carries the whole region — `head` with the rest of
|
|
481
|
+
// the body under a blank row is one excerpt row and must not pass for the
|
|
482
|
+
// whole body before Enter.
|
|
483
|
+
const single = readComposer(reader, lines, windowLines);
|
|
484
|
+
return single.kind === 'text' ? { ...single, region } : single;
|
|
436
485
|
}
|
|
437
486
|
}
|
|
438
487
|
return readComposer(reader, lines, windowLines);
|
|
@@ -530,14 +579,48 @@ function isSubmitted(output, cliToolId, message, composerSpec = (0, composer_spe
|
|
|
530
579
|
* 3. Anything else — the idle placeholder, a ghost suggestion, no composer —
|
|
531
580
|
* shows nothing of the body. `unseen`, which the caller decides about.
|
|
532
581
|
*
|
|
533
|
-
* Reads the
|
|
534
|
-
*
|
|
582
|
+
* Reads the composer the way {@link classifySubmit} does
|
|
583
|
+
* ({@link readSubmitComposer}), so a history echo of an earlier message above the
|
|
584
|
+
* composer is never mistaken for this one, and a frame both functions see holds
|
|
585
|
+
* the same composer for both (Issue #3880). A multi-row codex composer is
|
|
586
|
+
* compared as a whole ({@link codexComposerRegion}), whitespace removed
|
|
587
|
+
* (wrapping and continuation indent proof): only the WHOLE body is `landed`;
|
|
588
|
+
* the body's beginning alone is `pasting` (never enough to press Enter on), the
|
|
589
|
+
* body plus anything else or text from inside it is `mismatch`. The whole body
|
|
590
|
+
* is checked before placeholders, so a body that itself quotes
|
|
591
|
+
* `[Pasted Content 600 chars]` is its own text, not codex's placeholder; a real
|
|
592
|
+
* placeholder is only ever the composer's first row.
|
|
535
593
|
*/
|
|
536
594
|
function classifyPasteLanded(output, cliToolId, message, composerSpec = (0, composer_spec_1.resolveComposerSpec)(cliToolId)) {
|
|
537
595
|
const lines = withoutTrailingBlankRows((0, cli_patterns_1.stripAnsi)(output).split('\n'));
|
|
538
|
-
const composer =
|
|
596
|
+
const composer = readSubmitComposer(output, cliToolId, composerSpec.reader, lines, lines.slice(-VERIFY_WINDOW_LINES));
|
|
539
597
|
if (composer.kind !== 'text')
|
|
540
598
|
return 'unseen';
|
|
599
|
+
if (composer.region !== undefined) {
|
|
600
|
+
const shown = compactText(composer.region);
|
|
601
|
+
const body = compactText(message);
|
|
602
|
+
if (shown === body)
|
|
603
|
+
return 'landed';
|
|
604
|
+
const placeholder = findPasteTokens(composer.text);
|
|
605
|
+
if (placeholder.tokens.length > 0) {
|
|
606
|
+
// A placeholder plus anything else — on its row or under it — is not the body as sent.
|
|
607
|
+
const below = compactText(composer.region.split('\n').slice(1).join('\n'));
|
|
608
|
+
if (placeholder.tokens.length > 1 || placeholder.rest !== '' || below !== '')
|
|
609
|
+
return 'mismatch';
|
|
610
|
+
return comparePasteToken(placeholder.tokens[0], message);
|
|
611
|
+
}
|
|
612
|
+
if (body.startsWith(shown))
|
|
613
|
+
return 'pasting';
|
|
614
|
+
// The body's beginning followed by something else, the body plus more, or a
|
|
615
|
+
// piece from inside it: the composer holds something other than the body.
|
|
616
|
+
if (inputMatchesBody(composer.text, message) || shown.startsWith(body) || body.includes(shown)) {
|
|
617
|
+
return 'mismatch';
|
|
618
|
+
}
|
|
619
|
+
return 'unseen';
|
|
620
|
+
}
|
|
621
|
+
// The whole body on one row is the body, even when it quotes a placeholder.
|
|
622
|
+
if (compactText(composer.text) === compactText(message))
|
|
623
|
+
return 'landed';
|
|
541
624
|
const { tokens, rest } = findPasteTokens(composer.text);
|
|
542
625
|
if (tokens.length === 0) {
|
|
543
626
|
if (inputMatchesBody(composer.text, message))
|
|
@@ -591,9 +674,9 @@ async function pasteBody(sessionName, message) {
|
|
|
591
674
|
}
|
|
592
675
|
}
|
|
593
676
|
/** The composer's first row, for an error message a person has to act on. */
|
|
594
|
-
function describeComposer(output, composerSpec) {
|
|
677
|
+
function describeComposer(output, cliToolId, composerSpec) {
|
|
595
678
|
const lines = withoutTrailingBlankRows((0, cli_patterns_1.stripAnsi)(output).split('\n'));
|
|
596
|
-
const composer =
|
|
679
|
+
const composer = readSubmitComposer(output, cliToolId, composerSpec.reader, lines, lines.slice(-VERIFY_WINDOW_LINES));
|
|
597
680
|
if (composer.kind === 'absent')
|
|
598
681
|
return 'no composer on screen';
|
|
599
682
|
if (composer.kind === 'empty')
|
|
@@ -666,7 +749,7 @@ async function confirmPasteLanded(params) {
|
|
|
666
749
|
}
|
|
667
750
|
const bytes = Buffer.byteLength(message, 'utf8');
|
|
668
751
|
const lineCount = message.split('\n').length;
|
|
669
|
-
const shown = describeComposer(output, composer);
|
|
752
|
+
const shown = describeComposer(output, cliToolId, composer);
|
|
670
753
|
await withdrawUnsentBody(sessionName, cliToolId, composer);
|
|
671
754
|
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
672
755
|
logger.error('paste-not-landed', { sessionName, cliToolId, state, bytes, lines: lineCount, shown });
|
|
@@ -730,7 +813,7 @@ async function confirmTypedBodyLanded(params) {
|
|
|
730
813
|
return;
|
|
731
814
|
}
|
|
732
815
|
const bytes = Buffer.byteLength(message, 'utf8');
|
|
733
|
-
const shown = describeComposer(output, composer);
|
|
816
|
+
const shown = describeComposer(output, cliToolId, composer);
|
|
734
817
|
await withdrawUnsentBody(sessionName, cliToolId, composer);
|
|
735
818
|
(0, tmux_capture_cache_1.invalidateCache)(sessionName);
|
|
736
819
|
logger.error('typed-body-not-landed', { sessionName, cliToolId, bytes, attempts, shown });
|
|
@@ -819,9 +902,10 @@ async function clearComposerBeforeSend(sessionName, cliToolId, composerSpec = (0
|
|
|
819
902
|
*
|
|
820
903
|
* The body and Enter are always separate tmux commands (never batched), so the
|
|
821
904
|
* TUI cannot swallow the Enter inside a bracketed-paste buffer. After the
|
|
822
|
-
* initial submit the pane is read back
|
|
823
|
-
*
|
|
824
|
-
*
|
|
905
|
+
* initial submit the pane is read back; each time it is still pending an extra
|
|
906
|
+
* Enter is sent, up to `verifyAttempts` of them, and every Enter — the last one
|
|
907
|
+
* included (Issue #3880) — is read back before a verdict. If submit can never
|
|
908
|
+
* be confirmed the function THROWS — callers must surface that as a failure, never as
|
|
825
909
|
* success (Issues #1469/#1470/#1471).
|
|
826
910
|
*
|
|
827
911
|
* A body longer than {@link LITERAL_SEND_MAX_BYTES} is pasted instead of typed,
|
|
@@ -884,8 +968,14 @@ async function sendMessageWithSubmitVerification(params) {
|
|
|
884
968
|
}
|
|
885
969
|
// 4. Read-back verification: confirm the message left the input box, resend
|
|
886
970
|
// Enter while it is still pending, and throw if it never submits.
|
|
971
|
+
//
|
|
972
|
+
// Every Enter is followed by a read (Issue #3880, H-1): `attempts` resends
|
|
973
|
+
// take `attempts + 1` reads. The loop used to resend on its last pending read
|
|
974
|
+
// and throw straight after, so a message that only that last Enter submitted
|
|
975
|
+
// was reported "could not be confirmed" — a sent message as exit 99. The
|
|
976
|
+
// last read sends nothing: no Enter goes out that is not read back.
|
|
887
977
|
const attempts = Math.max(1, verifyAttempts);
|
|
888
|
-
for (let attempt = 0; attempt
|
|
978
|
+
for (let attempt = 0; attempt <= attempts; attempt++) {
|
|
889
979
|
await new Promise((resolve) => setTimeout(resolve, verifyDelayMs));
|
|
890
980
|
const output = await (0, tmux_1.capturePane)(sessionName, { startLine: -composer.verifyCaptureLines });
|
|
891
981
|
const state = classifySubmit(output, cliToolId, message, composer);
|
|
@@ -913,6 +1003,9 @@ async function sendMessageWithSubmitVerification(params) {
|
|
|
913
1003
|
logger.error('submit-replaced-by-tui-completion', { sessionName, cliToolId, attempt });
|
|
914
1004
|
throw new Error(`Message was replaced by a TUI autocompletion for session ${sessionName}; the input no longer matches the sent text. Cleared the input line without submitting to avoid executing a different command.`);
|
|
915
1005
|
}
|
|
1006
|
+
// state === 'pending' after the final resend's read-back: give up below.
|
|
1007
|
+
if (attempt === attempts)
|
|
1008
|
+
break;
|
|
916
1009
|
// state === 'pending' — still typed-but-unsent, resend a single Enter and re-check.
|
|
917
1010
|
logger.warn('submit-not-confirmed:resending-enter', {
|
|
918
1011
|
sessionName,
|
|
@@ -715,7 +715,11 @@ function recordAnsweredPrompt(db, params) {
|
|
|
715
715
|
}
|
|
716
716
|
const answeredAt = new Date().toISOString();
|
|
717
717
|
if (target) {
|
|
718
|
-
|
|
718
|
+
// Issue #3881 (review P2-2): the row keeps the reading it was saved with;
|
|
719
|
+
// one saved without a reading (before #3881) takes the answerer's, so a
|
|
720
|
+
// row's classification does not depend on which writer came first.
|
|
721
|
+
const reading = target.parsed.reading === undefined && promptData.reading !== undefined ? { reading: promptData.reading } : {};
|
|
722
|
+
const updated = { ...target.parsed, ...reading, status: 'answered', answer, answeredAt, answeredBy };
|
|
719
723
|
updatePromptData(db, target.id, updated);
|
|
720
724
|
return { message: getMessageById(db, target.id), created: false };
|
|
721
725
|
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.MAX_RUN_HISTORY_DAYS = exports.MAX_RUN_HISTORY_LIMIT = exports.DEFAULT_RUN_HISTORY_LIMIT = exports.VERIFICATION_GATE_SOURCES = exports.VERIFICATION_TRIGGERS = void 0;
|
|
24
|
+
exports.parseGateTiming = parseGateTiming;
|
|
24
25
|
exports.createVerificationRun = createVerificationRun;
|
|
25
26
|
exports.finishVerificationRun = finishVerificationRun;
|
|
26
27
|
exports.createGateResult = createGateResult;
|
|
@@ -54,6 +55,20 @@ exports.VERIFICATION_TRIGGERS = ['manual', 'wait', 'api', 'task'];
|
|
|
54
55
|
* The runtime tuple mirrors the CHECK constraint in migration v56.
|
|
55
56
|
*/
|
|
56
57
|
exports.VERIFICATION_GATE_SOURCES = ['builtin', 'verify.yaml', 'contract'];
|
|
58
|
+
/**
|
|
59
|
+
* How much of a gate's `log_tail` the history listing reads: enough for the
|
|
60
|
+
* `[timing]` line, which is the last line — never the log body.
|
|
61
|
+
*/
|
|
62
|
+
const TIMING_TAIL_CHARS = 200;
|
|
63
|
+
/** The last line of `logEnd`, when it is the runner's `[timing]` line. */
|
|
64
|
+
const TIMING_LINE = /(?:^|\n)\[timing\] queue=(\d+(?:\.\d+)?)s mutex=(\d+(?:\.\d+)?)s run=(\d+(?:\.\d+)?)s\s*$/;
|
|
65
|
+
/** The {@link VerificationGateTiming} of a gate whose `log_tail` ends with `logEnd`, or null. */
|
|
66
|
+
function parseGateTiming(logEnd) {
|
|
67
|
+
const match = TIMING_LINE.exec(logEnd ?? '');
|
|
68
|
+
if (!match)
|
|
69
|
+
return null;
|
|
70
|
+
return { queueSec: Number(match[1]), mutexSec: Number(match[2]), runSec: Number(match[3]) };
|
|
71
|
+
}
|
|
57
72
|
const RUN_COLUMNS = `
|
|
58
73
|
id, worktree_id, instance_id, task_id, trigger, status, base_ref, started_at, finished_at
|
|
59
74
|
`;
|
|
@@ -247,7 +262,8 @@ function clampInt(value, fallback, min, max) {
|
|
|
247
262
|
}
|
|
248
263
|
/**
|
|
249
264
|
* Recent runs across worktrees, newest first, each with its gate verdicts but
|
|
250
|
-
* no log bodies (Issue #1593).
|
|
265
|
+
* no log bodies (Issue #1593). A gate's `[timing]` line is the one piece of its
|
|
266
|
+
* log that is carried, parsed into numbers (`timing`, Issue #3884).
|
|
251
267
|
*
|
|
252
268
|
* `worktreeId` is optional because the advisor that consumes this (#1594) looks
|
|
253
269
|
* at a repository's trend, not one worktree's. Ordering follows the same
|
|
@@ -285,7 +301,8 @@ function listVerificationRunsForPeriod(db, opts = {}) {
|
|
|
285
301
|
const placeholders = runRows.map(() => '?').join(', ');
|
|
286
302
|
const gateRows = db
|
|
287
303
|
.prepare(`
|
|
288
|
-
SELECT run_id, gate_id, status, exit_code, duration_ms, source
|
|
304
|
+
SELECT run_id, gate_id, status, exit_code, duration_ms, source,
|
|
305
|
+
substr(log_tail, -${TIMING_TAIL_CHARS}) AS log_end
|
|
289
306
|
FROM verification_gate_results
|
|
290
307
|
WHERE run_id IN (${placeholders})
|
|
291
308
|
ORDER BY started_at ASC, id ASC
|
|
@@ -300,6 +317,10 @@ function listVerificationRunsForPeriod(db, opts = {}) {
|
|
|
300
317
|
durationMs: row.duration_ms,
|
|
301
318
|
source: row.source ?? null,
|
|
302
319
|
};
|
|
320
|
+
// Only the numbers leave this function: the log stays out of the listing (#3884).
|
|
321
|
+
const timing = parseGateTiming(row.log_end);
|
|
322
|
+
if (timing)
|
|
323
|
+
summary.timing = timing;
|
|
303
324
|
const bucket = byRun.get(row.run_id);
|
|
304
325
|
if (bucket)
|
|
305
326
|
bucket.push(summary);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which option of a question the question itself recommends (Issue #3863).
|
|
4
|
+
*
|
|
5
|
+
* Auto-Yes's `recommended` answer mode answers a question with the option
|
|
6
|
+
* whose TITLE ends in a recommendation marker — `(Recommended)`, `(推奨)` or
|
|
7
|
+
* `(推奨)`. The title, not the label as a whole: on Claude's and Command
|
|
8
|
+
* Code's pickers an option is a title row and, under it, a description, and a
|
|
9
|
+
* description may end in the same words (`… see Recommended Next Actions`),
|
|
10
|
+
* or quote the marker. So the readers that still know where a title ends —
|
|
11
|
+
* the block reader, Command Code's question reader and Claude's
|
|
12
|
+
* AskUserQuestion parser — say per option what its title shows:
|
|
13
|
+
*
|
|
14
|
+
* - `true`: the title ends in a marker;
|
|
15
|
+
* - `false`: it does not;
|
|
16
|
+
* - `'unknown'`: the reader could not tell the title from what follows it
|
|
17
|
+
* (a continuation row that may be the title wrapping or a description).
|
|
18
|
+
*
|
|
19
|
+
* A reader never answers `false` for a title it could not delimit: a marker
|
|
20
|
+
* on the part it could not place would make "no option is recommended" (the
|
|
21
|
+
* default is then answered) a guess.
|
|
22
|
+
*
|
|
23
|
+
* The labels themselves, and every text a contract's deny patterns are
|
|
24
|
+
* matched against, are left as they were read.
|
|
25
|
+
*
|
|
26
|
+
* Leaf module: imports nothing.
|
|
27
|
+
*
|
|
28
|
+
* @module lib/detection/option-recommendation
|
|
29
|
+
*/
|
|
30
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
+
exports.isRecommendedTitle = isRecommendedTitle;
|
|
32
|
+
exports.isRecommendationMarker = isRecommendationMarker;
|
|
33
|
+
exports.upperBoundColumns = upperBoundColumns;
|
|
34
|
+
exports.lowerBoundPaneColumns = lowerBoundPaneColumns;
|
|
35
|
+
exports.cannotBeWrapOf = cannotBeWrapOf;
|
|
36
|
+
/**
|
|
37
|
+
* A marker at the very end of a title, standing on its own: what precedes it
|
|
38
|
+
* is the start of the title, white space, or anything but an ASCII letter or
|
|
39
|
+
* digit (`dispatch (Recommended)`, `する(推奨)`), never a word it is glued
|
|
40
|
+
* to (`Not(Recommended)`). Case as the tools write it. Anchored, no nested
|
|
41
|
+
* quantifiers (ReDoS-safe).
|
|
42
|
+
*/
|
|
43
|
+
const RECOMMENDATION_MARKER_PATTERN = /(?:^|[^A-Za-z0-9])(?:\(Recommended\)|(推奨)|\(推奨\))$/;
|
|
44
|
+
/**
|
|
45
|
+
* Whether a title — the option's whole title, wrapped rows joined — ends in a
|
|
46
|
+
* recommendation marker.
|
|
47
|
+
*
|
|
48
|
+
* @param title - The option's title, without its number or cursor
|
|
49
|
+
*/
|
|
50
|
+
function isRecommendedTitle(title) {
|
|
51
|
+
return RECOMMENDATION_MARKER_PATTERN.test(title.trim());
|
|
52
|
+
}
|
|
53
|
+
/** The markers, as a row holding nothing else spells them. */
|
|
54
|
+
const RECOMMENDATION_MARKERS = new Set(['(Recommended)', '(推奨)', '(推奨)']);
|
|
55
|
+
/**
|
|
56
|
+
* Whether a row holds a marker and nothing else — the tail of a title that
|
|
57
|
+
* wrapped right before its marker (`❯ 1. 整えた状態で続行` / `(Recommended)`).
|
|
58
|
+
*/
|
|
59
|
+
function isRecommendationMarker(row) {
|
|
60
|
+
return RECOMMENDATION_MARKERS.has(row.trim());
|
|
61
|
+
}
|
|
62
|
+
/** One code point that occupies no terminal column. */
|
|
63
|
+
const COMBINING_MARK = /^\p{M}$/u;
|
|
64
|
+
/**
|
|
65
|
+
* An UPPER bound on the columns a row occupies: printable ASCII is one
|
|
66
|
+
* column, a combining mark none, and anything else is counted as two (East
|
|
67
|
+
* Asian wide characters are two; no other code point is wider). Used with a
|
|
68
|
+
* LOWER bound on the pane width, so "it would have fit" is never claimed for
|
|
69
|
+
* a row that might not have.
|
|
70
|
+
*/
|
|
71
|
+
function upperBoundColumns(text) {
|
|
72
|
+
let columns = 0;
|
|
73
|
+
for (const char of text) {
|
|
74
|
+
const code = char.codePointAt(0) ?? 0;
|
|
75
|
+
if (code >= 0x20 && code < 0x7f)
|
|
76
|
+
columns += 1;
|
|
77
|
+
else if (!COMBINING_MARK.test(char))
|
|
78
|
+
columns += 2;
|
|
79
|
+
}
|
|
80
|
+
return columns;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* A LOWER bound on the pane width: the widest row of the frame, counting one
|
|
84
|
+
* column per code point (combining marks none). A row the pane drew is never
|
|
85
|
+
* wider than the pane.
|
|
86
|
+
*/
|
|
87
|
+
function lowerBoundPaneColumns(rows) {
|
|
88
|
+
let widest = 0;
|
|
89
|
+
for (const row of rows) {
|
|
90
|
+
let columns = 0;
|
|
91
|
+
for (const char of row.trimEnd()) {
|
|
92
|
+
if (!COMBINING_MARK.test(char))
|
|
93
|
+
columns += 1;
|
|
94
|
+
}
|
|
95
|
+
if (columns > widest)
|
|
96
|
+
widest = columns;
|
|
97
|
+
}
|
|
98
|
+
return widest;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Whether `next` cannot be the wrapped tail of `row` — the pane would have
|
|
102
|
+
* kept `next`'s first word on `row`.
|
|
103
|
+
*
|
|
104
|
+
* Terminals word-wrap a title: a row ends early only when the following word
|
|
105
|
+
* would not fit. So when `row` plus a space plus that word fits inside the
|
|
106
|
+
* pane, `row` did not wrap there and `next` begins something else (the
|
|
107
|
+
* option's description). Judged with an upper bound on what the row and the
|
|
108
|
+
* word occupy and a lower bound on the pane, so a `true` is never a guess; a
|
|
109
|
+
* `false` only says the row MAY have wrapped.
|
|
110
|
+
*
|
|
111
|
+
* @param row - The option's row, as drawn (indent and number included)
|
|
112
|
+
* @param next - The row under it
|
|
113
|
+
* @param paneColumns - {@link lowerBoundPaneColumns} of the frame
|
|
114
|
+
*/
|
|
115
|
+
function cannotBeWrapOf(row, next, paneColumns) {
|
|
116
|
+
const firstWord = next.trim().split(/\s+/, 1)[0] ?? '';
|
|
117
|
+
if (firstWord === '')
|
|
118
|
+
return false;
|
|
119
|
+
return upperBoundColumns(row.trimEnd()) + 1 + upperBoundColumns(firstWord) <= paneColumns;
|
|
120
|
+
}
|