commandmate 0.44.0 → 0.44.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +348 -352
- package/.next/app-path-routes-manifest.json +40 -40
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +9 -9
- package/.next/react-loadable-manifest.json +3 -3
- 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_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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/metrics/vibe/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/ollama/models/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/escalation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/relays/[relayId]/cancel/route.js +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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/remote/pair/route.js +2 -2
- 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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route.js +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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/[skillId]/git-workflow/route_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_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_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_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_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 +9 -9
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +40 -40
- package/.next/server/chunks/1068.js +1 -1
- package/.next/server/chunks/2119.js +1 -1
- package/.next/server/chunks/2404.js +1 -1
- package/.next/server/chunks/2445.js +1 -1
- package/.next/server/chunks/2816.js +1 -1
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6401.js +1 -1
- package/.next/server/chunks/6474.js +3 -3
- package/.next/server/chunks/650.js +1 -1
- package/.next/server/chunks/7685.js +1 -1
- package/.next/server/chunks/7905.js +1 -1
- package/.next/server/chunks/8581.js +2 -2
- package/.next/server/chunks/8728.js +2 -2
- package/.next/server/chunks/9390.js +1 -1
- package/.next/server/chunks/9731.js +3 -3
- package/.next/server/chunks/9882.js +2 -2
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-manifest.json +5 -5
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages-manifest.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{2407-340774f1a24f2b45.js → 2407-f1f258d4a1d92620.js} +1 -1
- package/.next/static/chunks/344-e1cefd00787060e4.js +1 -0
- package/.next/static/chunks/3922.f45dcfc1e7da552a.js +1 -0
- package/.next/static/chunks/591-308072f285c34787.js +1 -0
- package/.next/static/chunks/6654-ac431270fac1a283.js +1 -0
- package/.next/static/chunks/{9619-84aced0846cbe3ac.js → 9619-6c17a271f7f98fbb.js} +1 -1
- package/.next/static/chunks/998-2eb5883186abd0bd.js +1 -0
- package/.next/static/chunks/app/layout-da66300cc20244ed.js +1 -0
- package/.next/static/chunks/app/more/{page-30057cf1e0762ad2.js → page-87c84987b2765213.js} +1 -1
- package/.next/static/chunks/app/{page-8483ba400af011f5.js → page-1b820c421db48c2c.js} +1 -1
- package/.next/static/chunks/app/review/page-95f749caae382f46.js +1 -0
- package/.next/static/chunks/app/sessions/page-049e06335187aa91.js +1 -0
- package/.next/static/chunks/app/worktrees/[id]/page-040c5f0f585e6812.js +1 -0
- package/.next/static/chunks/{webpack-49ade0526854dd4e.js → webpack-021f0741f22dd16a.js} +1 -1
- package/.next/trace +13 -13
- package/README.md +72 -25
- package/dist/cli/commands/remote.d.ts +10 -0
- package/dist/cli/commands/remote.d.ts.map +1 -1
- package/dist/cli/commands/remote.js +17 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +11 -0
- package/dist/cli/docs/setup-guide.d.ts +1 -1
- package/dist/cli/docs/setup-guide.d.ts.map +1 -1
- package/dist/cli/docs/setup-guide.js +2 -0
- package/dist/cli/types/api-responses.d.ts +10 -0
- package/dist/cli/types/api-responses.d.ts.map +1 -1
- package/dist/lib/detection/status-reason.d.ts +17 -0
- package/dist/lib/detection/status-reason.d.ts.map +1 -1
- package/dist/lib/detection/status-reason.js +17 -0
- package/dist/server/locales/en/worktree.json +13 -1
- package/dist/server/locales/ja/worktree.json +13 -1
- package/dist/server/src/config/session-starting-config.js +75 -0
- package/dist/server/src/lib/cli-tools/antigravity.js +2 -1
- package/dist/server/src/lib/cli-tools/base.js +15 -1
- package/dist/server/src/lib/cli-tools/codex.js +3 -2
- package/dist/server/src/lib/cli-tools/command-code.js +3 -2
- package/dist/server/src/lib/cli-tools/copilot.js +2 -1
- package/dist/server/src/lib/cli-tools/gemini.js +2 -1
- package/dist/server/src/lib/cli-tools/liveness-spec.js +27 -9
- package/dist/server/src/lib/cli-tools/opencode-v2.js +2 -1
- package/dist/server/src/lib/cli-tools/opencode.js +2 -1
- package/dist/server/src/lib/cli-tools/vibe-local.js +2 -1
- package/dist/server/src/lib/detection/status-reason.js +17 -0
- package/dist/server/src/lib/detection/tool-liveness.js +3 -1
- package/dist/server/src/lib/realtime/terminal-broadcast.js +5 -0
- package/dist/server/src/lib/session/agent-session-lifecycle.js +11 -0
- package/dist/server/src/lib/session/claude-session.js +7 -1
- package/dist/server/src/lib/session/current-output-builder.js +49 -21
- package/dist/server/src/lib/session/launch-screen.js +57 -0
- package/dist/server/src/lib/session/session-starting-state.js +236 -0
- package/package.json +1 -1
- package/release-notes/0.44.1.json +54 -0
- package/.next/static/chunks/344-6f9fc1f38f01a839.js +0 -1
- package/.next/static/chunks/3922.8e79fc89f593280b.js +0 -1
- package/.next/static/chunks/5449-6cb80bab2bd06b79.js +0 -1
- package/.next/static/chunks/591-0a45801e83f26f24.js +0 -1
- package/.next/static/chunks/6966-bb854d1145783a64.js +0 -1
- package/.next/static/chunks/app/layout-0fc249fb7de75a27.js +0 -1
- package/.next/static/chunks/app/review/page-ff9efae3f86eb840.js +0 -1
- package/.next/static/chunks/app/sessions/page-55297155e7bf01b9.js +0 -1
- package/.next/static/chunks/app/worktrees/[id]/page-d2103e0c25be83c8.js +0 -1
- /package/.next/static/{wu7SUiHTirFcrpo5teyZ3 → 57lOiz8zSEHdw97XIm0af}/_buildManifest.js +0 -0
- /package/.next/static/{wu7SUiHTirFcrpo5teyZ3 → 57lOiz8zSEHdw97XIm0af}/_ssgManifest.js +0 -0
|
@@ -55,6 +55,7 @@ const db_1 = require("../../lib/db");
|
|
|
55
55
|
// when this instance was last handed a prompt.
|
|
56
56
|
const chat_db_1 = require("../../lib/db/chat-db");
|
|
57
57
|
const unclassified_frame_tracker_1 = require("../../lib/detection/unclassified-frame-tracker");
|
|
58
|
+
const session_starting_state_1 = require("../../lib/session/session-starting-state");
|
|
58
59
|
const composer_text_1 = require("../../lib/detection/composer-text");
|
|
59
60
|
const upstream_faults_1 = require("../../lib/detection/upstream-faults");
|
|
60
61
|
const opencode_pane_obstruction_1 = require("../../lib/detection/opencode-pane-obstruction");
|
|
@@ -608,7 +609,8 @@ async function buildCurrentOutput(db, worktreeId, cliToolId, instanceId, resolut
|
|
|
608
609
|
// surface is actually being watched at, which is exactly the property the
|
|
609
610
|
// terminal snapshot already has. Gated on the merged verdict (`'running'`, not
|
|
610
611
|
// the tmux-session-exists `isRunning`) so an idle pane reads no transcript.
|
|
611
|
-
|
|
612
|
+
// Issue #3179: not during a launch — there is no turn to publish yet.
|
|
613
|
+
if (payload.isRunning && payload.sessionStatus === 'running' && payload.startingSince == null) {
|
|
612
614
|
// Issue #2248 made this an `await`, and it buys less than it looks like: the
|
|
613
615
|
// expensive half — the transcript read and the broadcast — is detached
|
|
614
616
|
// inside, so what is waited for is a worktree row and a Map lookup. What it
|
|
@@ -750,6 +752,10 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
750
752
|
(0, status_evidence_1.forgetLastKnownStatus)((0, auto_yes_manager_1.buildCompositeKey)(worktreeId, cliToolId, instanceId));
|
|
751
753
|
return {
|
|
752
754
|
isRunning: false,
|
|
755
|
+
// Issue #3179: `beginAgentSession` runs before the pane is created, so a
|
|
756
|
+
// launch can be in progress with no tmux session yet. Read-only here —
|
|
757
|
+
// there is no frame to judge a dialog on.
|
|
758
|
+
startingSince: (0, session_starting_state_1.getSessionStartingSince)(worktreeId, cliToolId, instanceId),
|
|
753
759
|
sessionName,
|
|
754
760
|
content: '',
|
|
755
761
|
lineCount: 0,
|
|
@@ -828,7 +834,17 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
828
834
|
const compositeKey = (0, auto_yes_manager_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
829
835
|
const lastServerResponseTimestamp = (0, auto_yes_manager_1.getLastServerResponseTimestamp)(compositeKey);
|
|
830
836
|
const lastOutputTimestamp = lastServerResponseTimestamp ? new Date(lastServerResponseTimestamp) : undefined;
|
|
831
|
-
const
|
|
837
|
+
const rawStatusResult = (0, status_detector_1.detectSessionStatus)(output, cliToolId, lastOutputTimestamp);
|
|
838
|
+
// Issue #3179: a launch in progress. The frame is a shell prompt and the
|
|
839
|
+
// launch line, or a dialog the launch is about to answer, and none of the
|
|
840
|
+
// flags below may be read off it: the floor verdict raised the Navigate pad,
|
|
841
|
+
// the trust dialog raised the selection list / prompt sheet. A dialog that
|
|
842
|
+
// outstays the launch's own answer releases the record (a login, an unknown
|
|
843
|
+
// dialog), and from then on this is the ordinary verdict again.
|
|
844
|
+
const startingSince = (0, session_starting_state_1.observeSessionStartingFrame)(worktreeId, cliToolId, instanceId, rawStatusResult.status === 'waiting' || rawStatusResult.hasActivePrompt);
|
|
845
|
+
const statusResult = startingSince === null
|
|
846
|
+
? rawStatusResult
|
|
847
|
+
: (0, session_starting_state_1.startingStatusResult)(rawStatusResult);
|
|
832
848
|
// Issue #1912: every `running` reason that means "the agent is producing
|
|
833
849
|
// output", not just `thinking_indicator`. opencode answers
|
|
834
850
|
// `opencode_processing_indicator` for its `esc interrupt` footer, which is
|
|
@@ -946,7 +962,9 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
946
962
|
// the guard cannot disagree about whether a prompt is open. What they are
|
|
947
963
|
// still allowed to differ on is what to DO about it — see `blocksSend`, which
|
|
948
964
|
// bounds the structured layer's veto over sends and leaves this flag alone.
|
|
949
|
-
|
|
965
|
+
// Issue #3179: not while a launch is in progress. The scraper half is already
|
|
966
|
+
// neutralised above; this also drops a structured wait the launch inherited.
|
|
967
|
+
const isPromptWaiting = startingSince === null && promptResolution.waiting;
|
|
950
968
|
// Issue #1726: the agent's own account of what it asked. It contributes only
|
|
951
969
|
// where some other layer has already established that a dialog is on screen —
|
|
952
970
|
// this record decides no status of its own, because Claude emits nothing at
|
|
@@ -1033,13 +1051,15 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1033
1051
|
// instead of by coincidence.)
|
|
1034
1052
|
patterns: decisionOptions !== null ? promptWaiting.patterns : null,
|
|
1035
1053
|
};
|
|
1036
|
-
const promptData =
|
|
1037
|
-
?
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
:
|
|
1054
|
+
const promptData = startingSince !== null
|
|
1055
|
+
? null
|
|
1056
|
+
: scraperPromptWaiting
|
|
1057
|
+
? correctedPromptData ??
|
|
1058
|
+
scraperPromptData ??
|
|
1059
|
+
(structuredFacts ? (0, structured_prompt_1.buildStructuredPromptData)(worktreeId, structuredFacts) : null)
|
|
1060
|
+
: structuredFacts
|
|
1061
|
+
? (0, structured_prompt_1.buildStructuredPromptData)(worktreeId, structuredFacts)
|
|
1062
|
+
: null;
|
|
1043
1063
|
// Issue #2870: whether `/prompt-response` would answer the prompt published
|
|
1044
1064
|
// above, read by the SAME function it re-verifies with. In #2868 `promptData`
|
|
1045
1065
|
// came off the generic parser alone, the route refused it, and the UI's Send
|
|
@@ -1111,7 +1131,9 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1111
1131
|
// and the 60 seconds — start afresh if the frame is still unreadable once the
|
|
1112
1132
|
// decision is gone (answered, expired, or the source dropped).
|
|
1113
1133
|
const answerableOverAgentApi = (0, structured_prompt_1.hasApiAnswerableDecision)(eventSource.capabilities.eventIdentity, structuredEvents.pendingDecisions ?? []);
|
|
1114
|
-
|
|
1134
|
+
// Issue #3179: a launch in progress is not a detection failure — its frame is
|
|
1135
|
+
// the shell and the launch line — so no row, and the run starts afresh after.
|
|
1136
|
+
const unclassifiedVerdict = (0, unclassified_frame_tracker_1.observeUnclassifiedFrame)(compositeKey, merged.isUnclassifiedActive && !answerableOverAgentApi && startingSince === null);
|
|
1115
1137
|
if (unclassifiedVerdict.shouldRecord) {
|
|
1116
1138
|
recordUnclassifiedFrame(db, {
|
|
1117
1139
|
worktreeId,
|
|
@@ -1197,29 +1219,34 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1197
1219
|
// `sessionStatus` it sat next to one poll earlier. Observed before it is read
|
|
1198
1220
|
// so a positive poll reports itself, which is what keeps the field from
|
|
1199
1221
|
// looking stale on a healthy session.
|
|
1222
|
+
// Issue #3179: the structured layer cannot override a launch in progress
|
|
1223
|
+
// either — a `waiting` it inherited would put the answer sheet back.
|
|
1224
|
+
const published = startingSince === null
|
|
1225
|
+
? merged
|
|
1226
|
+
: { ...merged, status: 'running', reason: status_detector_1.STATUS_REASON.STARTING, thinking: false };
|
|
1200
1227
|
(0, status_evidence_1.observeStatusEvidence)(compositeKey, {
|
|
1201
|
-
status:
|
|
1202
|
-
reason:
|
|
1203
|
-
evidence:
|
|
1228
|
+
status: published.status,
|
|
1229
|
+
reason: published.reason,
|
|
1230
|
+
evidence: published.evidence,
|
|
1204
1231
|
});
|
|
1205
1232
|
const lastKnown = (0, status_evidence_1.getLastKnownStatus)(compositeKey);
|
|
1206
1233
|
return {
|
|
1207
1234
|
isRunning: true,
|
|
1208
1235
|
sessionName,
|
|
1209
1236
|
cliToolId,
|
|
1210
|
-
sessionStatus:
|
|
1211
|
-
sessionStatusReason:
|
|
1237
|
+
sessionStatus: published.status,
|
|
1238
|
+
sessionStatusReason: published.reason,
|
|
1212
1239
|
content: newContent,
|
|
1213
1240
|
fullOutput: output,
|
|
1214
1241
|
realtimeSnippet,
|
|
1215
1242
|
lineCount: totalLines,
|
|
1216
1243
|
lastCapturedLine,
|
|
1217
1244
|
isComplete: isPromptWaiting,
|
|
1218
|
-
isGenerating:
|
|
1219
|
-
thinking:
|
|
1245
|
+
isGenerating: published.thinking,
|
|
1246
|
+
thinking: published.thinking,
|
|
1220
1247
|
// Issue #2607: named after the tool actually running. A fixed "Claude" was
|
|
1221
1248
|
// published for every agent, and `capture --json` readers took it at its word.
|
|
1222
|
-
thinkingMessage:
|
|
1249
|
+
thinkingMessage: published.thinking ? `${(0, types_2.getCliToolDisplayName)(cliToolId)} is thinking...` : null,
|
|
1223
1250
|
isPromptWaiting,
|
|
1224
1251
|
promptData,
|
|
1225
1252
|
...(promptAnswerable !== undefined ? { promptAnswerable } : {}),
|
|
@@ -1235,11 +1262,12 @@ async function buildPayload(db, worktreeId, cliToolId, instanceId) {
|
|
|
1235
1262
|
isSelectionListActive,
|
|
1236
1263
|
isPagerActive,
|
|
1237
1264
|
isDismissablePanelActive,
|
|
1238
|
-
isUnclassifiedActive: merged.isUnclassifiedActive,
|
|
1265
|
+
isUnclassifiedActive: startingSince === null && merged.isUnclassifiedActive,
|
|
1266
|
+
startingSince,
|
|
1239
1267
|
// Issue #1926: the same fact `isUnclassifiedActive` carries, named the way
|
|
1240
1268
|
// §4 D1 names it. Published from the merged verdict so the two cannot
|
|
1241
1269
|
// disagree on the wire.
|
|
1242
|
-
statusEvidence:
|
|
1270
|
+
statusEvidence: published.evidence,
|
|
1243
1271
|
lastKnownStatus: lastKnown?.status ?? null,
|
|
1244
1272
|
lastKnownStatusAt: lastKnown?.at ?? null,
|
|
1245
1273
|
lastServerResponseTimestamp,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Keep the launch line off the pane (Issue #3180).
|
|
4
|
+
*
|
|
5
|
+
* Every `startSession` types its launch line into the pane's login shell —
|
|
6
|
+
* `CM_HOOK_URL='…' CM_PERMISSION_HOOK_URL='…' CM_PORT='3000' 'agy'` — and the
|
|
7
|
+
* shell echoes it. A tool that repaints the whole screen hides the echo once it
|
|
8
|
+
* draws; agy and codex draw inline, so the line, with its internal URL, port
|
|
9
|
+
* and worktree ID, stayed in the scrollback for the life of the session.
|
|
10
|
+
*
|
|
11
|
+
* `clear` runs in the same shell, before the agent, so the echo is wiped before
|
|
12
|
+
* the agent paints. The shell stays the agent's parent exactly as before, which
|
|
13
|
+
* is what keeps exit detection (`judgeToolLiveness`, `relaunchIfToolExited`)
|
|
14
|
+
* unchanged: when the agent quits, the pane falls back to the same shell prompt.
|
|
15
|
+
*
|
|
16
|
+
* `clear` alone only empties the visible screen. tmux 3.4+ defaults to
|
|
17
|
+
* `scroll-on-clear on`, which moves what `clear` wiped INTO the scrollback, and
|
|
18
|
+
* CommandMate's capture reads the scrollback: in the 2026-10-04 UAT (tmux 3.5a)
|
|
19
|
+
* codex, antigravity, Command Code and gemini still had the launch line twice in
|
|
20
|
+
* `tmux capture-pane -p -J -S -` (two `CM_HOOK_URL` hits), and it surfaced in the
|
|
21
|
+
* UI terminal and in codex's trust-dialog sheet. So `printf '\033[3J'` follows
|
|
22
|
+
* `clear`: ESC [3J (Erase Saved Lines) drops the scrollback, the echo included.
|
|
23
|
+
* `tmux clear-history` would also work but depends on the pane having a tmux
|
|
24
|
+
* binary and `TMUX` set, so it is not used. `printf` is a builtin in zsh, bash,
|
|
25
|
+
* dash and fish, and each reads `\033` in the format as octal ESC; the single
|
|
26
|
+
* quotes keep the backslash for printf in all of them.
|
|
27
|
+
*
|
|
28
|
+
* Joined with `;`, not `&&`, and with `clear`'s stderr dropped: a pane whose
|
|
29
|
+
* `clear` is missing or fails (unknown `TERM`, no ncurses), or whose `printf`
|
|
30
|
+
* fails, must still start the agent — a launch line left on screen is a
|
|
31
|
+
* cosmetic leak, a session that never starts is not — and must not print the
|
|
32
|
+
* failure in the line's place.
|
|
33
|
+
*
|
|
34
|
+
* Applied at the `sendKeys` call site, AFTER any flags a tool appends
|
|
35
|
+
* (`--model`, `-s <id>`, Command Code's launch flags): `buildAgentLaunchCommandLine`
|
|
36
|
+
* stays `NAME='value' … command`, and an appended flag lands on the agent, not
|
|
37
|
+
* on `clear`.
|
|
38
|
+
*
|
|
39
|
+
* Deliberately not in a module the session suites mock wholesale
|
|
40
|
+
* (`agent-session-lifecycle`, `tmux`), so those suites see the real prefix.
|
|
41
|
+
*
|
|
42
|
+
* @module lib/session/launch-screen
|
|
43
|
+
*/
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.LAUNCH_SCREEN_CLEAR_PREFIX = void 0;
|
|
46
|
+
exports.withLaunchScreenCleared = withLaunchScreenCleared;
|
|
47
|
+
/** The prefix every launch line is typed with. */
|
|
48
|
+
exports.LAUNCH_SCREEN_CLEAR_PREFIX = "clear 2>/dev/null; printf '\\033[3J'; ";
|
|
49
|
+
/**
|
|
50
|
+
* The line to type into the pane: clear the screen and the scrollback, then launch.
|
|
51
|
+
*
|
|
52
|
+
* @param launchCommand - The rendered launch line, flags included
|
|
53
|
+
* @returns `clear 2>/dev/null; printf '\033[3J'; <launchCommand>`
|
|
54
|
+
*/
|
|
55
|
+
function withLaunchScreenCleared(launchCommand) {
|
|
56
|
+
return `${exports.LAUNCH_SCREEN_CLEAR_PREFIX}${launchCommand}`;
|
|
57
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which agent sessions are still starting (Issue #3179).
|
|
4
|
+
*
|
|
5
|
+
* `isRunning` is tmux's `has-session`, and every tool's `launchSession` creates
|
|
6
|
+
* the tmux session BEFORE it types the launch command — so from that moment the
|
|
7
|
+
* screen saw a "running" session whose pane held nothing but a shell prompt and
|
|
8
|
+
* the launch line. That frame matches no tool's rule, falls to the detector's
|
|
9
|
+
* floor (`running` / `default`) and raised `isUnclassifiedActive`, which drew the
|
|
10
|
+
* Navigate pad; the trust dialog the launch answers by itself was drawn as a
|
|
11
|
+
* selection list or a prompt; and the composer's stop button lit up red.
|
|
12
|
+
*
|
|
13
|
+
* This module is the missing fact: "a launch of this (worktree, tool, instance)
|
|
14
|
+
* is in progress, and began at T". It is written by `beginAgentSession` (every
|
|
15
|
+
* tool's creation path goes through it) and cleared by `BaseCLITool.startSession`
|
|
16
|
+
* in a `finally`, success and failure alike — which also covers the
|
|
17
|
+
* `relaunchIfToolExited` path, because that reuses `startSession`.
|
|
18
|
+
*
|
|
19
|
+
* ## Whose record it is (Issue #3195)
|
|
20
|
+
*
|
|
21
|
+
* The key is (worktree, tool, instance), and a key outlives a launch: kill a
|
|
22
|
+
* launch mid-way and start the instance again, and the killed `startSession`
|
|
23
|
+
* is still in its readiness wait (agy: up to 30 s) while the new one writes
|
|
24
|
+
* the same key. When the old one finished, its `finally` deleted the new
|
|
25
|
+
* launch's record and the new "starting" display ended early.
|
|
26
|
+
*
|
|
27
|
+
* So every launch carries a token. `startSession` issues one
|
|
28
|
+
* ({@link issueSessionStartingToken}) and runs `launchSession` inside
|
|
29
|
+
* {@link runWithSessionStartingToken}; `markSessionStarting`, reached from
|
|
30
|
+
* `beginAgentSession` anywhere below that call, picks it up from the
|
|
31
|
+
* `AsyncLocalStorage`, and the `finally` clears with it — a record written
|
|
32
|
+
* under another token is left alone. A second mark under the same token (codex's
|
|
33
|
+
* `relaunchIntoSamePane`) rewrites the same launch's record, so the `finally`
|
|
34
|
+
* still clears it. A mark never replaces a record of a LATER launch (tokens
|
|
35
|
+
* only grow), so a killed launch that re-marks on its way out cannot take the
|
|
36
|
+
* key back from its successor. `clearSessionStarting` without a token — the
|
|
37
|
+
* kill-session route — drops the record whoever wrote it.
|
|
38
|
+
*
|
|
39
|
+
* ## The escape hatches
|
|
40
|
+
*
|
|
41
|
+
* A starting display that never ends would hide a stuck launch, which is worse
|
|
42
|
+
* than the defect it fixes. So the record stops answering when:
|
|
43
|
+
*
|
|
44
|
+
* - the launch returned or threw (`clearSessionStarting`);
|
|
45
|
+
* - it is older than the tool's readiness wait plus a grace period
|
|
46
|
+
* (`getSessionStartingMaxMs`) — several tools only log when that wait runs
|
|
47
|
+
* out and carry on, so time is the only signal there is;
|
|
48
|
+
* - a dialog has stayed on screen for longer than the launch takes to answer
|
|
49
|
+
* the ones it knows about (`SESSION_STARTING_PROMPT_GRACE_MS`) — a login or
|
|
50
|
+
* an unknown dialog, which a human has to see. Once released this way the
|
|
51
|
+
* record stays released for the rest of the launch, so the display does not
|
|
52
|
+
* flicker back when the dialog is answered.
|
|
53
|
+
*
|
|
54
|
+
* A server restart drops the map, and the screen shows the raw pane — harmless.
|
|
55
|
+
*
|
|
56
|
+
* In memory and on `globalThis` for the reason every shared map in this
|
|
57
|
+
* subsystem is (#1736): the writer (`POST /send`) and the readers
|
|
58
|
+
* (`/current-output`, the WebSocket streamer, `GET /api/worktrees`) are
|
|
59
|
+
* different route bundles under `next dev`.
|
|
60
|
+
*
|
|
61
|
+
* @module lib/session/session-starting-state
|
|
62
|
+
*/
|
|
63
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
+
exports.issueSessionStartingToken = issueSessionStartingToken;
|
|
65
|
+
exports.runWithSessionStartingToken = runWithSessionStartingToken;
|
|
66
|
+
exports.markSessionStarting = markSessionStarting;
|
|
67
|
+
exports.clearSessionStarting = clearSessionStarting;
|
|
68
|
+
exports.getSessionStartingSince = getSessionStartingSince;
|
|
69
|
+
exports.observeSessionStartingFrame = observeSessionStartingFrame;
|
|
70
|
+
exports.startingStatusResult = startingStatusResult;
|
|
71
|
+
exports.resetSessionStartingState = resetSessionStartingState;
|
|
72
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
73
|
+
const auto_yes_state_1 = require("../../lib/auto-yes-state");
|
|
74
|
+
const status_reason_1 = require("../../lib/detection/status-reason");
|
|
75
|
+
const session_starting_config_1 = require("../../config/session-starting-config");
|
|
76
|
+
const records = globalThis.__sessionStartingRecords ??
|
|
77
|
+
(globalThis.__sessionStartingRecords = new Map());
|
|
78
|
+
/** On `globalThis` like the map, so tokens keep growing across route bundles. */
|
|
79
|
+
const tokenSeq = globalThis.__sessionStartingTokenSeq ??
|
|
80
|
+
(globalThis.__sessionStartingTokenSeq = { last: 0 });
|
|
81
|
+
const tokenScope = globalThis.__sessionStartingTokenScope ??
|
|
82
|
+
(globalThis.__sessionStartingTokenScope = new node_async_hooks_1.AsyncLocalStorage());
|
|
83
|
+
/**
|
|
84
|
+
* A token for a launch about to begin (Issue #3195). Strictly greater than
|
|
85
|
+
* every token issued before it.
|
|
86
|
+
*/
|
|
87
|
+
function issueSessionStartingToken() {
|
|
88
|
+
tokenSeq.last += 1;
|
|
89
|
+
return tokenSeq.last;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Run a launch under its token, so a `markSessionStarting` anywhere below it
|
|
93
|
+
* records the launch as this token's (Issue #3195).
|
|
94
|
+
*
|
|
95
|
+
* @param token - From {@link issueSessionStartingToken}
|
|
96
|
+
* @param fn - The launch
|
|
97
|
+
*/
|
|
98
|
+
function runWithSessionStartingToken(token, fn) {
|
|
99
|
+
return tokenScope.run(token, fn);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Record that a launch of this instance began.
|
|
103
|
+
*
|
|
104
|
+
* Under the launch's token: the one {@link runWithSessionStartingToken} is
|
|
105
|
+
* running, or a fresh one outside any. A record of a later launch is kept —
|
|
106
|
+
* this call is then a launch that was already superseded (Issue #3195).
|
|
107
|
+
*
|
|
108
|
+
* @param worktreeId - Worktree ID
|
|
109
|
+
* @param cliToolId - Tool being launched
|
|
110
|
+
* @param instanceId - Instance (defaults to the primary)
|
|
111
|
+
* @param at - Epoch ms; defaults to now
|
|
112
|
+
* @returns The token the record was written under, or null when it was not written
|
|
113
|
+
*/
|
|
114
|
+
function markSessionStarting(worktreeId, cliToolId, instanceId, at = Date.now()) {
|
|
115
|
+
const token = tokenScope.getStore() ?? issueSessionStartingToken();
|
|
116
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
117
|
+
const existing = records.get(key);
|
|
118
|
+
if (existing !== undefined && existing.token > token)
|
|
119
|
+
return null;
|
|
120
|
+
records.set(key, {
|
|
121
|
+
cliToolId,
|
|
122
|
+
token,
|
|
123
|
+
since: at,
|
|
124
|
+
promptSeenAt: null,
|
|
125
|
+
released: false,
|
|
126
|
+
});
|
|
127
|
+
return token;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Forget the launch of this instance. Idempotent, and never throws: it runs in
|
|
131
|
+
* `startSession`'s `finally`, where an exception would replace the launch's own
|
|
132
|
+
* error — an id `buildCompositeKey` refuses could never have been recorded.
|
|
133
|
+
*
|
|
134
|
+
* With a token, only that launch's record is dropped — a launch that was
|
|
135
|
+
* killed and replaced must not end its successor's display (Issue #3195).
|
|
136
|
+
* Without one (kill-session), the record is dropped whoever wrote it.
|
|
137
|
+
*
|
|
138
|
+
* @param worktreeId - Worktree ID
|
|
139
|
+
* @param cliToolId - Tool that was launched
|
|
140
|
+
* @param instanceId - Instance (defaults to the primary)
|
|
141
|
+
* @param token - The launch's token; omit to drop any launch's record
|
|
142
|
+
*/
|
|
143
|
+
function clearSessionStarting(worktreeId, cliToolId, instanceId, token) {
|
|
144
|
+
try {
|
|
145
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
146
|
+
if (token !== undefined && records.get(key)?.token !== token)
|
|
147
|
+
return;
|
|
148
|
+
records.delete(key);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
// Nothing was recorded under an id that does not compose into a key.
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** The record's start time while it still answers, else null (dropping an expired one). */
|
|
155
|
+
function activeSince(key, record, now) {
|
|
156
|
+
if (record === undefined || record.released)
|
|
157
|
+
return null;
|
|
158
|
+
if (now - record.since > (0, session_starting_config_1.getSessionStartingMaxMs)(record.cliToolId)) {
|
|
159
|
+
records.delete(key);
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return record.since;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* When this instance's launch began, or null when it is not starting (no
|
|
166
|
+
* launch, already finished, past its time bound, or released by a dialog).
|
|
167
|
+
*
|
|
168
|
+
* Read-only apart from dropping an expired record.
|
|
169
|
+
*
|
|
170
|
+
* @param worktreeId - Worktree ID
|
|
171
|
+
* @param cliToolId - Tool
|
|
172
|
+
* @param instanceId - Instance (defaults to the primary)
|
|
173
|
+
* @param now - Epoch ms; defaults to now
|
|
174
|
+
*/
|
|
175
|
+
function getSessionStartingSince(worktreeId, cliToolId, instanceId, now = Date.now()) {
|
|
176
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
177
|
+
return activeSince(key, records.get(key), now);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* {@link getSessionStartingSince}, fed what the current frame shows.
|
|
181
|
+
*
|
|
182
|
+
* A dialog on screen (a prompt, a selection list, any `waiting` verdict) starts
|
|
183
|
+
* a dwell; one that outlives {@link SESSION_STARTING_PROMPT_GRACE_MS} is a
|
|
184
|
+
* dialog the launch is not going to answer, and the record is released so the
|
|
185
|
+
* screen shows it. A frame with no dialog resets the dwell.
|
|
186
|
+
*
|
|
187
|
+
* @param worktreeId - Worktree ID
|
|
188
|
+
* @param cliToolId - Tool
|
|
189
|
+
* @param instanceId - Instance (defaults to the primary)
|
|
190
|
+
* @param dialogVisible - Whether the frame shows a dialog
|
|
191
|
+
* @param now - Epoch ms; defaults to now
|
|
192
|
+
* @returns The launch's start time while it is still shown as starting, else null
|
|
193
|
+
*/
|
|
194
|
+
function observeSessionStartingFrame(worktreeId, cliToolId, instanceId, dialogVisible, now = Date.now()) {
|
|
195
|
+
const key = (0, auto_yes_state_1.buildCompositeKey)(worktreeId, cliToolId, instanceId);
|
|
196
|
+
const record = records.get(key);
|
|
197
|
+
const since = activeSince(key, record, now);
|
|
198
|
+
if (since === null || record === undefined)
|
|
199
|
+
return null;
|
|
200
|
+
if (!dialogVisible) {
|
|
201
|
+
record.promptSeenAt = null;
|
|
202
|
+
return since;
|
|
203
|
+
}
|
|
204
|
+
record.promptSeenAt ??= now;
|
|
205
|
+
if (now - record.promptSeenAt >= session_starting_config_1.SESSION_STARTING_PROMPT_GRACE_MS) {
|
|
206
|
+
record.released = true;
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
return since;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The verdict published for a frame under a launch in progress (Issue #3179).
|
|
213
|
+
*
|
|
214
|
+
* `running` with the `starting` reason: the session exists and is busy, and no
|
|
215
|
+
* dialog, selection list or unclassified overlay is on it for anybody to drive.
|
|
216
|
+
* `positive` because the launch record is an observation this server made, not
|
|
217
|
+
* a pattern that failed to match. The raw verdict is not consulted beyond its
|
|
218
|
+
* `confidence`; reading anything else off it is what this replaces.
|
|
219
|
+
*
|
|
220
|
+
* @param raw - What the detector said about the frame
|
|
221
|
+
* @returns The neutral verdict for the same frame
|
|
222
|
+
*/
|
|
223
|
+
function startingStatusResult(raw) {
|
|
224
|
+
return {
|
|
225
|
+
...raw,
|
|
226
|
+
status: 'running',
|
|
227
|
+
reason: status_reason_1.STATUS_REASON.STARTING,
|
|
228
|
+
hasActivePrompt: false,
|
|
229
|
+
promptDetection: { ...raw.promptDetection, isPrompt: false, promptData: undefined },
|
|
230
|
+
evidence: 'positive',
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/** Drop every record. For tests. */
|
|
234
|
+
function resetSessionStartingState() {
|
|
235
|
+
records.clear();
|
|
236
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "commandmate",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.1",
|
|
4
4
|
"description": "No long blocks of time? Run an AI team from your phone. Git worktree sessions, task contracts and verification gates for Claude Code, Codex, Gemini CLI, Copilot, OpenCode, Antigravity and Command Code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agents",
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.44.1",
|
|
3
|
+
"date": "2026-10-04",
|
|
4
|
+
"highlight": {
|
|
5
|
+
"ja": "エージェントの起動中は、途中の画面の代わりに「起動中…」と経過時間を表示するようになりました。",
|
|
6
|
+
"en": "While an agent is starting, the screen now shows that it is starting and how long it has taken, instead of a half-drawn session."
|
|
7
|
+
},
|
|
8
|
+
"added": [
|
|
9
|
+
{
|
|
10
|
+
"ja": "エージェントの起動中は「起動中…」の案内を出し、5 秒を超えると経過時間も表示するようになりました。",
|
|
11
|
+
"en": "While an agent starts, a starting notice is shown, with the elapsed time after five seconds."
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"improved": [
|
|
15
|
+
{
|
|
16
|
+
"ja": "エージェントを起動するときに打ち込むコマンドの行が、ターミナルに残らなくなりました。",
|
|
17
|
+
"en": "The command line typed to launch an agent no longer stays in the terminal."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"ja": "remote コマンドで、ペアリングの期限の時刻と残り時間が QR コードの下に表示されるようになりました。",
|
|
21
|
+
"en": "The remote command now shows when the pairing expires and how much time is left, under the QR code."
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"fixed": [
|
|
25
|
+
{
|
|
26
|
+
"ja": "インスタンスを止めると、そのインスタンスの Auto Yes も切れるようにしました。",
|
|
27
|
+
"en": "Stopping an instance now also turns off its Auto Yes."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"ja": "シェルのプロンプトが長い環境で、Claude を終了した後に次の送信が失敗する問題を直しました。",
|
|
31
|
+
"en": "Fixed the next message failing after exiting Claude when the shell prompt is long."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"ja": "エージェントの起動に 30 秒以上かかったとき、画面が送信失敗と表示する問題を直しました。",
|
|
35
|
+
"en": "Fixed the screen reporting a failed send when an agent took more than 30 seconds to start."
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"ja": "起動中に止めてすぐ起動し直すと、起動中の案内が早く消える問題を直しました。",
|
|
39
|
+
"en": "Fixed the starting notice disappearing early when an agent was stopped and started again right away."
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"ja": "OpenCode V2 の承認で、選択肢が出ているのに「選択肢を読み取れませんでした」と表示される問題を直しました。",
|
|
43
|
+
"en": "Fixed OpenCode V2 approvals saying the options could not be read while the options were shown."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"ja": "ログイン画面を開いている間に、エラーになる通信をくり返していた問題を直しました。",
|
|
47
|
+
"en": "Fixed the login page repeatedly making requests that failed."
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"ja": "期限切れのペアリングを、remote status が使用済みと表示する問題を直しました。",
|
|
51
|
+
"en": "Fixed remote status showing an expired pairing as used."
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[344],{56936:(e,t,n)=>{n.d(t,{BV:()=>y,Ct:()=>i,Hi:()=>o,K3:()=>a,PS:()=>u,SR:()=>r,T2:()=>l,Z3:()=>p,nk:()=>d});let o=0,a=8e3,r=2,i=2e4,s=[408,425,429,500,502,503,504],c=["GET","HEAD","OPTIONS"],l=3e4;function d(e){let t=(null!=e?e:"GET").toUpperCase();return c.includes(t)}function u(e){return s.includes(e)}function p(e){return d(e)?1e4:3e4}function y(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Math.random(),n=Number.isFinite(e)&&e>0?Math.floor(e):0,o=Math.min(500*2**n,4e3);return Math.max(0,Math.round(o+.25*o*(2*t-1)))}},80344:(e,t,n)=>{n.d(t,{$T:()=>g,E:()=>y,GQ:()=>T,O0:()=>s,Rx:()=>w,gC:()=>f,hD:()=>r,hS:()=>b,xd:()=>c,y:()=>h});var o=n(56936),a=n(52407);class r extends Error{constructor(e,t,n,o){super(e),this.status=t,this.data=n,this.name="ApiError",this.kind=null!=o?o:t>0?"http":"network"}}async function i(e,t,n){if(!(e.headers.get("content-type")||"").includes("application/json"))return t;try{return await e.json()}catch(e){return t}}function s(e){var t;return e.redirected&&(null!=(t=e.url)?t:"").includes("/login")?new r("Authentication required",401):null}function c(e){return e.headers?(e.headers.get("content-type")||"").includes("application/json")?null:new r("Unexpected response format",e.status):null}let l=null;function d(e){let t=Date.now();null!==l&&l.reachable===e&&t-l.at<o.T2||(l={reachable:e,at:t},(0,a.nG)(e))}async function u(e,t,n){var o;let a=null!=(o=t.signal)?o:void 0;if(null==a?void 0:a.aborted)throw new r("Request aborted",0,void 0,"aborted");if(n<=0||"function"!=typeof AbortController)return fetch(e,t);let i=new AbortController,s=!1,c=setTimeout(()=>{s=!0,i.abort()},n),l=()=>i.abort();null==a||a.addEventListener("abort",l);try{return await fetch(e,{...t,signal:i.signal})}catch(e){if(null==a?void 0:a.aborted)throw new r("Request aborted",0,e,"aborted");if(s)throw new r("Request timed out after ".concat(n,"ms"),0,e,"timeout");throw e}finally{clearTimeout(c),null==a||a.removeEventListener("abort",l)}}function p(e){return new Promise(t=>setTimeout(t,e))}async function y(e,t){var n;let{timeoutMs:a,retries:i,...s}=null!=t?t:{},c=(null!=(n=s.method)?n:"GET").toUpperCase(),l=(0,o.nk)(c)?Math.max(0,null!=i?i:o.SR):0,y=void 0===a?(0,o.Z3)(c):null!=a?a:o.Hi,m=Date.now(),h=e=>e<l&&Date.now()-m<o.Ct;for(let t=0;;t++){if("undefined"!=typeof navigator&&!1===navigator.onLine)throw new r("No network connection",0,void 0,"offline");try{let n=await u(e,s,y);if(d(!0),(0,o.PS)(n.status)&&h(t)){await p((0,o.BV)(t));continue}return n}catch(n){let e=function(e){if(e instanceof r)return e;let t=e instanceof Error?e.name:"";return"AbortError"===t||"TimeoutError"===t?new r("Request aborted",0,e,"aborted"):new r(e instanceof Error?e.message:"Unknown error",0,e,"network")}(n);if("aborted"===e.kind||(d(!1),!h(t)))throw e;await p((0,o.BV)(t))}}}async function m(e,t){try{let n=new Headers(null==t?void 0:t.headers);n.set("Content-Type","application/json");let o=await y(e,{...t,headers:n}),a=s(o);if(a)throw a;if(!o.ok){let e=await i(o,{},"error-body");throw new r(e.error||"HTTP error ".concat(o.status),o.status,e)}let l=c(o);if(l)throw l;return o.json()}catch(e){if(e instanceof r)throw e;throw new r(e instanceof Error?e.message:"Unknown error",0,e)}}let h={getAll:async()=>m("/api/worktrees"),getById:async e=>m("/api/worktrees/".concat(e)),updateDescription:async(e,t)=>m("/api/worktrees/".concat(e),{method:"PATCH",body:JSON.stringify({description:t})}),updateLink:async(e,t)=>m("/api/worktrees/".concat(e),{method:"PATCH",body:JSON.stringify({link:t})}),toggleFavorite:async(e,t)=>m("/api/worktrees/".concat(e),{method:"PATCH",body:JSON.stringify({favorite:t})}),updateStatus:async(e,t)=>m("/api/worktrees/".concat(e),{method:"PATCH",body:JSON.stringify({status:t})}),updateCliTool:async(e,t)=>m("/api/worktrees/".concat(e),{method:"PATCH",body:JSON.stringify({cliToolId:t})}),markAsViewed:async e=>m("/api/worktrees/".concat(e,"/viewed"),{method:"PATCH"}),async getMessages(e,t,n,o){let a=new URLSearchParams;return t&&a.append("cliTool",t),n&&a.append("includeArchived","true"),"number"==typeof o&&Number.isFinite(o)&&a.append("limit",String(o)),m("/api/worktrees/".concat(e,"/messages").concat(a.toString()?"?".concat(a.toString()):""))},async sendMessage(e,t,n){var o;let a={content:t};return(null==n?void 0:n.cliToolId)&&(a.cliToolId=n.cliToolId),(null==n?void 0:n.instanceId)&&(a.instanceId=n.instanceId),(null==n?void 0:n.imagePath)&&(a.imagePath=n.imagePath),null===(o=await m("/api/worktrees/".concat(e,"/send"),{method:"POST",body:JSON.stringify(a)}))||"object"!=typeof o||o.timestamp instanceof Date?o:{...o,timestamp:new Date(o.timestamp)}},async uploadImageFile(e,t){let n=Date.now(),o="".concat(n,"-").concat(t.name),a=".commandmate/attachments",r=new FormData;r.append("file",new File([t],o,{type:t.type}));let s=await fetch("/api/worktrees/".concat(e,"/upload/").concat(a),{method:"POST",body:r});if(!s.ok){var c;let e=await i(s,{},"error-body");throw Error((null==e||null==(c=e.error)?void 0:c.message)||"Upload failed (HTTP ".concat(s.status,")"))}return{path:(await i(s,{},"response-body")).path||"".concat(a,"/").concat(o)}},getLogs:async e=>m("/api/worktrees/".concat(e,"/logs")),async getLogFile(e,t,n){let o=(null==n?void 0:n.sanitize)?"?sanitize=true":"";return m("/api/worktrees/".concat(e,"/logs/").concat(t).concat(o))},async killSession(e,t,n){let o=new URLSearchParams;t&&o.set("cliTool",t),n&&o.set("instance",n);let a=o.toString();return m("/api/worktrees/".concat(e,"/kill-session").concat(a?"?".concat(a):""),{method:"POST"})}},w={scan:async e=>m("/api/repositories/scan",{method:"POST",body:JSON.stringify({repositoryPath:e})}),sync:async()=>m("/api/repositories/sync",{method:"POST"}),delete:async e=>m("/api/repositories",{method:"DELETE",body:JSON.stringify({repositoryPath:e})}),async clone(e,t){var n;return m("/api/repositories/clone",{method:"POST",body:JSON.stringify({cloneUrl:e,fork:null!=(n=null==t?void 0:t.fork)&&n})})},getCloneStatus:async e=>m("/api/repositories/clone/".concat(e)),getExcluded:async()=>m("/api/repositories/excluded"),restore:async e=>m("/api/repositories/restore",{method:"PUT",body:JSON.stringify({repositoryPath:e})}),list:async()=>m("/api/repositories"),updateDisplayName:async(e,t)=>m("/api/repositories/".concat(encodeURIComponent(e)),{method:"PUT",body:JSON.stringify({displayName:t})}),updateVisibility:async(e,t)=>m("/api/repositories/".concat(encodeURIComponent(e)),{method:"PUT",body:JSON.stringify({visible:t})}),updateEnabled:async(e,t)=>m("/api/repositories/".concat(encodeURIComponent(e)),{method:"PUT",body:JSON.stringify({enabled:t})}),validatePath:async e=>m("/api/repositories/validate-path",{method:"POST",body:JSON.stringify({repositoryPath:e})})},f={async browse(e){let t=e?"?path=".concat(encodeURIComponent(e)):"";return m("/api/fs/browse".concat(t))},addRecentPath:async e=>m("/api/fs/recent-paths",{method:"POST",body:JSON.stringify({path:e})})},g={getAll:async e=>(await m("/api/worktrees/".concat(e,"/memos"))).memos,create:async(e,t)=>(await m("/api/worktrees/".concat(e,"/memos"),{method:"POST",body:JSON.stringify(t||{})})).memo,update:async(e,t,n)=>(await m("/api/worktrees/".concat(e,"/memos/").concat(t),{method:"PUT",body:JSON.stringify(n)})).memo,delete:async(e,t)=>m("/api/worktrees/".concat(e,"/memos/").concat(t),{method:"DELETE"}),async reorder(e,t){await m("/api/worktrees/".concat(e,"/memos"),{method:"PATCH",body:JSON.stringify({memoIds:t})})}};function b(e){return e instanceof r||e instanceof Error?e.message:"An unknown error occurred"}let T={checkForUpdate:async()=>m("/api/app/update-check",{method:"GET"}),startUpdate:async()=>m("/api/app/update",{method:"POST"}),async ping(){try{return(await fetch("/api/auth/status",{cache:"no-store"})).ok}catch(e){return!1}},async getReleaseNotes(e,t){let n=new URLSearchParams({from:e,to:t});return m("/api/app/release-notes?".concat(n.toString()),{method:"GET"})}}}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[3922],{33922:(e,t,r)=>{r.r(t),r.d(t,{MarkdownEditor:()=>ee});var n=r(95155),l=r(12115),o=r(47650),a=r(18955),s=r(80003),i=r(52056),d=r(64269),c=r(60322),u=r(94442),f=r(36402),m=r(3005),h=r(72115),x=r(89715),v=r(71847);let p=(0,v.A)("columns-2",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M12 3v18",key:"108xh3"}]]);var g=r(57828);let w=(0,v.A)("list-indent-increase",[["path",{d:"M21 5H11",key:"us1j55"}],["path",{d:"M21 12H11",key:"wd7e0v"}],["path",{d:"M21 19H11",key:"saa85w"}],["path",{d:"m3 8 4 4-4 4",key:"1a3j6y"}]]),b=(0,v.A)("list-indent-decrease",[["path",{d:"M21 5H11",key:"us1j55"}],["path",{d:"M21 12H11",key:"wd7e0v"}],["path",{d:"M21 19H11",key:"saa85w"}],["path",{d:"m7 8-4 4 4 4",key:"o5hrat"}]]);var k=r(76482),y=r(5917),j=r(75426),E=r(97624),N=r(37354),C=r(46046),S=r(65229),M=r(48407);let F=(0,l.memo)(function(e){let{filePath:t,isDirty:r,viewMode:l,onViewModeChange:o,showMobileTabs:s,copied:i,onCopy:d,isMaximized:c,onToggleFullscreen:u,isAutoSaveEnabled:f,onAutoSaveToggle:m,isAutoSaving:h,isSaving:v,onSave:F,onClose:R,hideViewModeToggle:A,hideMaximizeButton:P,onIndent:T,onOutdent:V,tabMovesFocus:z,onToggleTabMovesFocus:I}=e,D=(0,a.c)("worktree"),O=e=>e.preventDefault();return(0,n.jsxs)("div",{className:"flex items-center justify-between px-4 py-2 border-b border-border bg-muted",children:[(0,n.jsxs)("div",{className:"flex items-center gap-2 min-w-0 flex-shrink",children:[(0,n.jsx)(x.A,{className:"h-4 w-4 text-muted-foreground flex-shrink-0"}),(0,n.jsx)("span",{className:"text-sm font-medium text-foreground truncate",children:t}),r&&(0,n.jsx)("span",{"data-testid":"dirty-indicator",className:"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-warning-subtle text-warning-foreground flex-shrink-0",children:D("editor.unsaved")})]}),(0,n.jsxs)("div",{className:"flex items-center gap-2 flex-shrink-0",children:[!s&&!A&&(0,n.jsxs)("div",{className:"flex items-center gap-1 bg-muted rounded-lg p-1",children:[(0,n.jsx)("button",{"data-testid":"view-mode-split","aria-pressed":"split"===l,onClick:()=>o("split"),className:"p-1.5 rounded ".concat("split"===l?"bg-white dark:bg-input shadow-sm text-accent-600 dark:text-accent-400":"text-muted-foreground hover:text-foreground"),title:D("editor.splitView"),children:(0,n.jsx)(p,{className:"h-4 w-4"})}),(0,n.jsx)("button",{"data-testid":"view-mode-editor","aria-pressed":"editor"===l,onClick:()=>o("editor"),className:"p-1.5 rounded ".concat("editor"===l?"bg-white dark:bg-input shadow-sm text-accent-600 dark:text-accent-400":"text-muted-foreground hover:text-foreground"),title:D("editor.editorOnly"),children:(0,n.jsx)(x.A,{className:"h-4 w-4"})}),(0,n.jsx)("button",{"data-testid":"view-mode-preview","aria-pressed":"preview"===l,onClick:()=>o("preview"),className:"p-1.5 rounded ".concat("preview"===l?"bg-white dark:bg-input shadow-sm text-accent-600 dark:text-accent-400":"text-muted-foreground hover:text-foreground"),title:D("editor.previewOnly"),children:(0,n.jsx)(g.A,{className:"h-4 w-4"})})]}),(0,n.jsx)(M.$n,{variant:"ghost","data-testid":"editor-indent-button",onMouseDown:O,onClick:T,className:"flex min-h-[44px] min-w-[44px] items-center justify-center p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted rounded",title:D("editor.indent"),"aria-label":D("editor.indent"),children:(0,n.jsx)(w,{className:"h-4 w-4"})}),(0,n.jsx)(M.$n,{variant:"ghost","data-testid":"editor-outdent-button",onMouseDown:O,onClick:V,className:"flex min-h-[44px] min-w-[44px] items-center justify-center p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted rounded",title:D("editor.outdent"),"aria-label":D("editor.outdent"),children:(0,n.jsx)(b,{className:"h-4 w-4"})}),(0,n.jsx)(M.$n,{variant:"ghost","data-testid":"editor-tab-focus-toggle",onMouseDown:O,onClick:I,"aria-pressed":z,className:"flex min-h-[44px] min-w-[44px] items-center justify-center p-1.5 hover:bg-muted rounded ".concat(z?"text-accent-600 dark:text-accent-400":"text-muted-foreground hover:text-foreground"),title:D(z?"editor.tabMovesFocusOn":"editor.tabMovesFocusOff"),"aria-label":D(z?"editor.tabMovesFocusOn":"editor.tabMovesFocusOff"),children:(0,n.jsx)(k.A,{className:"h-4 w-4"})}),(0,n.jsx)(M.$n,{variant:"ghost","data-testid":"copy-content-button",onClick:d,className:"p-1.5 hover:bg-muted rounded ".concat(i?"text-success":"text-muted-foreground hover:text-foreground"),title:D("actions.copyContent"),children:i?(0,n.jsx)(y.A,{className:"h-4 w-4"}):(0,n.jsx)(j.A,{className:"h-4 w-4"})}),!P&&(0,n.jsx)(M.$n,{variant:"ghost","data-testid":"maximize-button",onClick:u,className:"p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted rounded",title:D(c?"editor.exitFullscreen":"editor.enterFullscreen"),"aria-pressed":c,children:c?(0,n.jsx)(E.A,{className:"h-4 w-4"}):(0,n.jsx)(N.A,{className:"h-4 w-4"})}),(0,n.jsxs)("div",{className:"flex items-center gap-1.5",children:[(0,n.jsx)("span",{className:"text-xs text-muted-foreground",children:D("editor.auto")}),(0,n.jsx)("button",{"data-testid":"auto-save-toggle",role:"switch","aria-checked":f,onClick:()=>m(!f),className:"relative inline-flex h-5 w-9 items-center rounded-full transition-colors ".concat(f?"bg-accent-600":"bg-input"),children:(0,n.jsx)("span",{className:"inline-block h-3.5 w-3.5 transform rounded-full bg-white transition-transform ".concat(f?"translate-x-4":"translate-x-0.5")})})]}),f?(0,n.jsx)("span",{"data-testid":"auto-save-indicator",className:"text-sm text-muted-foreground",children:h?D("actions.saving"):r?"":D("actions.saved")}):(0,n.jsxs)(M.$n,{variant:"ghost","data-testid":"save-button",onClick:F,disabled:!r||v,className:"flex items-center gap-1.5 px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ".concat(r&&!v?"bg-accent-600 text-white hover:bg-accent-700":"bg-muted text-muted-foreground cursor-not-allowed"),children:[(0,n.jsx)(C.A,{className:"h-4 w-4"}),D(v?"actions.saving":"actions.save")]}),R&&(0,n.jsx)(M.$n,{variant:"ghost","data-testid":"close-button",onClick:R,className:"p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted rounded",title:D("actions.close"),children:(0,n.jsx)(S.A,{className:"h-4 w-4"})})]})]})});var R=r(24027),A=r(55924),P=r(79962),T=r(38218);let V=l.useLayoutEffect;function z(){if("undefined"==typeof document)return null;let e=document;return e.fullscreenElement||e.webkitFullscreenElement||e.mozFullScreenElement||e.msFullscreenElement||null}var I=r(2317),D=r(60850),O=r(8269),L=r(51434),K=r(4138),$=r(59854);function H(e,t){return e.lastIndexOf("\n",t-1)+1}function W(e,t,r){let n=r>t&&r>0&&"\n"===e[r-1]?r-1:r;return{start:H(e,t),end:function(e,t){let r=e.indexOf("\n",t);return -1===r?e.length:r}(e,n)}}function _(e,t,r,n,l,o){return{replaceStart:t,replaceEnd:r,replacement:n,selectionStart:l,selectionEnd:o,value:e.slice(0,t)+n+e.slice(r)}}function q(e,t,r,n){if(!(r>t&&e.slice(t,r).includes("\n"))){let l=t-H(e,t),o=n.length-l%n.length,a=" ".repeat(o),s=t+a.length;return _(e,t,r,a,s,s)}let{start:l,end:o}=W(e,t,r),a=e.slice(l,o).split("\n").map(e=>""===e||"\r"===e?e:n+e).join("\n");return _(e,l,o,a,l,l+a.length)}function B(e,t,r,n){let{start:l,end:o}=W(e,t,r),a=e.slice(l,o),s=a.split("\n").map(e=>(function(e,t){if(e.startsWith(" "))return e.slice(1);let r=0;for(;r<t.length&&" "===e[r];)r+=1;return e.slice(r)})(e,n)).join("\n");if(s===a)return t===r?null:_(e,l,o,s,t,r);if(t===r){let r=Math.min(a.length-s.length,Math.max(0,t-l)),n=t-r;return _(e,l,o,s,n,n)}return _(e,l,o,s,l,l+s.length)}let G={split:{showEditor:!0,showPreview:!0,editorWidth:"w-1/2",previewWidth:"w-1/2"},editor:{showEditor:!0,showPreview:!1,editorWidth:"w-full",previewWidth:"w-0"},preview:{showEditor:!1,showPreview:!0,editorWidth:"w-0",previewWidth:"w-full"}},U="commandmate:md-editor-view-mode",J={WARNING_THRESHOLD:512e3};function Y(e){return"number"==typeof e&&e>=.1&&e<=.9}function X(e){return"boolean"==typeof e}function Z(e){return"split"===e||"editor"===e||"preview"===e}let Q=(0,l.memo)(function(e){let{previewContent:t,onOpenFile:r,filePath:o,worktreeId:a,tocVisible:i,onToggleTocVisible:d,tocTitle:c,tocShowLabel:u,tocHideLabel:f}=e,m=(0,l.useRef)(null),h=(0,l.useRef)(null),[x,v]=(0,l.useState)(null),[p,g]=(0,l.useState)(!1);(0,l.useEffect)(()=>{v(h.current)},[]),(0,l.useEffect)(()=>{let e=m.current;if(!e||"undefined"==typeof ResizeObserver)return;let t=new ResizeObserver(e=>{var t,r;g((null!=(r=null==(t=e[0])?void 0:t.contentRect.width)?r:0)>=480)});return t.observe(e),()=>t.disconnect()},[]);let w=(0,l.useMemo)(()=>(0,P.K)(t),[t]),b=w.length>=2&&p,k=b&&i;return(0,n.jsxs)("div",{ref:m,className:"relative flex flex-1 overflow-hidden",children:[(0,n.jsx)("div",{ref:h,"data-testid":"markdown-preview",className:"flex-1 min-w-0 p-4 overflow-y-auto prose prose-sm dark:prose-invert max-w-none prose-headings:scroll-mt-2",children:(0,n.jsx)(R.G8,{content:t,onOpenFile:r,currentFilePath:o,worktreeId:a})}),k&&(0,n.jsx)("aside",{"data-testid":"markdown-preview-toc",className:"w-48 flex-shrink-0 overflow-y-auto border-l border-border py-4",children:(0,n.jsx)("div",{className:"sticky top-0",children:(0,n.jsx)(A.K,{entries:w,title:c,headerOffset:0,root:x})})}),b&&(0,n.jsx)("button",{"data-testid":"markdown-preview-toc-toggle",onClick:d,"aria-pressed":i,"aria-label":i?f:u,title:i?f:u,className:"absolute top-2 right-2 z-10 flex items-center justify-center rounded-md border border-border bg-surface/90 p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted shadow-sm",children:(0,n.jsx)(s.A,{className:"h-4 w-4"})})]})}),ee=(0,l.memo)(function(e){let{worktreeId:t,filePath:r,fileType:s,onClose:x,onSave:v,initialViewMode:p,onMaximizedChange:g,onDirtyChange:w,onOpenFile:b,initialContent:k,embedded:y=!1,onContentChange:j}=e,E="text"===(null!=s?s:r.toLowerCase().endsWith(".md")?"markdown":"text"),N=(0,a.c)("worktree"),C=(0,f.SC)(),S=void 0!==k,M=null!=k?k:"",[A,H]=(0,l.useState)(M),[W,_]=(0,l.useState)(M),[ee,et]=(0,l.useState)(M),[er,en]=(0,l.useState)(()=>E||y?"editor":function(e){if(e&&Z(e))return e;{let e=localStorage.getItem(U);if(e&&Z(e))return e}return"split"}(p)),[el,eo]=(0,l.useState)(!S),[ea,es]=(0,l.useState)(!1),[ei,ed]=(0,l.useState)(null),[ec,eu]=(0,l.useState)(()=>S&&new Blob([M]).size>J.WARNING_THRESHOLD),{copied:ef,markCopied:em}=(0,K.q)(),[eh,ex]=(0,l.useState)("editor"),[ev,ep]=(0,l.useState)(null),{showToast:eg}=(0,u.dj)(),ew=(0,l.useRef)(null),eb=(0,l.useRef)(null),ek=(0,l.useRef)(null),ey=(0,l.useRef)(null),ej=(0,l.useRef)(null),eE=(0,l.useRef)(null),eN=(0,T.a)(),eC=function(){let[e,t]=(0,l.useState)(!1);return V(()=>{let e=window.matchMedia("(orientation: portrait)");t(e.matches);let r=e=>{t(e.matches)};return e.addEventListener("change",r),()=>e.removeEventListener("change",r)},[]),e}();(0,l.useEffect)(()=>{eN&&ex("preview")},[eN]);let{isKeyboardVisible:eS,keyboardHeight:eM}=(0,L.C)(),{value:eF,setValue:eR}=(0,I.V)({key:"commandmate:md-editor-maximized",defaultValue:!1,validate:X}),{isFullscreen:eA,isFallbackMode:eP,enterFullscreen:eT,exitFullscreen:eV,toggleFullscreen:ez}=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{elementRef:t,onEnter:r,onExit:n,onError:o}=e,[a,s]=(0,l.useState)(!1),[i,d]=(0,l.useState)(!1),[c,u]=(0,l.useState)(null),f=(0,l.useCallback)(()=>{let e=null!=z();s(e),!e&&i&&d(!1)},[i]),m=(0,l.useCallback)(async()=>{if(u(null),"undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1||0)){s(!0),d(!0),null==r||r();return}if(function(){if("undefined"==typeof document)return!1;let e=document;return!!(e.fullscreenEnabled||e.webkitFullscreenEnabled||e.mozFullScreenEnabled||e.msFullscreenEnabled)}()&&(null==t?void 0:t.current))try{var e;await ((e=t.current).requestFullscreen?Promise.resolve(e.requestFullscreen()):e.webkitRequestFullscreen?Promise.resolve(e.webkitRequestFullscreen()):e.mozRequestFullScreen?Promise.resolve(e.mozRequestFullScreen()):e.msRequestFullscreen?Promise.resolve(e.msRequestFullscreen()):Promise.reject(Error("Fullscreen API not supported"))),s(!0),d(!1),null==r||r()}catch(t){let e=t instanceof Error?t.message:"Failed to enter fullscreen";u(e),null==o||o(t instanceof Error?t:Error(e)),s(!0),d(!0),null==r||r()}else s(!0),d(!0),null==r||r()},[t,r,o]),h=(0,l.useCallback)(async()=>{if(u(null),i){s(!1),d(!1),null==n||n();return}if(z())try{await function(){if("undefined"==typeof document)return Promise.resolve();let e=document;return e.exitFullscreen?Promise.resolve(e.exitFullscreen()):e.webkitExitFullscreen?Promise.resolve(e.webkitExitFullscreen()):e.mozCancelFullScreen?Promise.resolve(e.mozCancelFullScreen()):e.msExitFullscreen?Promise.resolve(e.msExitFullscreen()):Promise.resolve()}(),s(!1),null==n||n()}catch(t){let e=t instanceof Error?t.message:"Failed to exit fullscreen";u(e),null==o||o(t instanceof Error?t:Error(e)),s(!1),d(!1),null==n||n()}else s(!1),d(!1),null==n||n()},[i,n,o]),x=(0,l.useCallback)(async()=>{a?await h():await m()},[a,m,h]);return(0,l.useEffect)(()=>(function(e){if("undefined"==typeof document)return()=>{};let t=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange"];for(let r of t)document.addEventListener(r,e);return()=>{for(let r of t)document.removeEventListener(r,e)}})(f),[f]),{isFullscreen:a,isFallbackMode:i,enterFullscreen:m,exitFullscreen:h,toggleFullscreen:x,error:c}}({elementRef:ey,onEnter:()=>eR(!0),onExit:()=>eR(!1)}),{value:eI,setValue:eD}=(0,I.V)({key:"commandmate:md-editor-split-ratio",defaultValue:.5,validate:Y}),{value:eO,setValue:eL}=(0,I.V)({key:"commandmate:md-editor-auto-save",defaultValue:!1,validate:X}),{value:eK,setValue:e$}=(0,I.V)({key:"commandmate:md-editor-tab-moves-focus",defaultValue:!1,validate:X}),{value:eH,setValue:eW}=(0,I.V)({key:P.Y,defaultValue:!0,validate:X}),e_=(0,l.useCallback)(()=>{eW(e=>!e)},[eW]),{ref:eq}=(0,O.hU)({onSwipeDown:()=>{eA&&eV()},threshold:150,enabled:eA&&eN}),eB=A!==W,eG=E?G.editor:G[er];(0,l.useEffect)(()=>{null==w||w(eB)},[eB,w]);let eU=!E&&eN&&eC&&"split"===er,eJ=(0,l.useMemo)(()=>(0,d.sg)(e=>{et(e)},300),[]),eY=(0,l.useCallback)(async()=>{eo(!0),ed(null);try{let n=await fetch("/api/worktrees/".concat(t,"/files/").concat(r)),l=await n.json();if(!n.ok||!l.success){var e;throw Error((null==(e=l.error)?void 0:e.message)||N("editor.loadError"))}let o=l.content||"";H(o),_(o),et(o),new Blob([o]).size>J.WARNING_THRESHOLD&&eu(!0)}catch(e){ed(e instanceof Error?e.message:N("editor.loadError"))}finally{eo(!1)}},[t,r]),eX=(0,l.useCallback)(async e=>{let n=await fetch("/api/worktrees/".concat(t,"/files/").concat(r),{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({content:e})});if(401===n.status||n.redirected)throw Error(N("editor.sessionExpired"));let l=await n.json();if(!n.ok||!l.success){var o;throw Error((null==(o=l.error)?void 0:o.message)||N("editor.saveError"))}_(e)},[t,r,N]),{isSaving:eZ,error:eQ,saveNow:e0}=(0,D.U)({value:A,saveFn:eX,debounceMs:3e3,disabled:!eO}),e1=(0,l.useCallback)(e=>{eL(e),e&&eB&&eX(A)},[eL,eB,eX,A]),e4=(0,l.useCallback)(async()=>{if(eB&&!ea){es(!0);try{await eX(A),eg(N("editor.saveSuccess"),"success"),v&&v(r,A)}catch(e){eg(e instanceof Error?e.message:N("editor.saveError"),"error")}finally{es(!1)}}},[eX,A,eB,ea,v,r,eg,N]),e2=A.split("\n").length,e5=(0,l.useCallback)(()=>{ew.current&&eb.current&&(eb.current.scrollTop=ew.current.scrollTop)},[]),e3=(0,l.useCallback)(e=>{let t=e.target.value;H(t),eJ(t),null==j||j(t)},[eJ,j]),e8=(0,l.useCallback)(e=>{en(e),localStorage.setItem(U,e)},[]),e7=(0,l.useCallback)(async()=>{if(eO){if((eB||eZ)&&(await e0(),eQ)&&!await C({description:N("editor.saveFailedCloseConfirm"),variant:"danger"}))return}else if(eB&&!await C({description:N("editor.unsavedCloseConfirm"),variant:"danger"}))return;null==x||x()},[eO,eB,eZ,e0,eQ,x,C,N]),e9=(0,l.useCallback)(async()=>{try{await (0,c.l)(A),em()}catch(e){}},[A,em]),e6=(0,l.useCallback)(e=>{if(!ej.current)return;let t=ej.current.offsetWidth;if(0===t)return;let r=e/t;eD(e=>Math.max(.1,Math.min(.9,e+r)))},[eD]),te=(0,l.useCallback)(()=>{eD(.5)},[eD]),tt=(0,l.useCallback)(e=>{if(e.target!==ew.current||e.currentTarget===e.target){if((e.ctrlKey||e.metaKey)&&"s"===e.key){e.preventDefault(),eO?(async()=>{await e0(),null==v||v(r,A)})():e4();return}if((e.ctrlKey||e.metaKey)&&e.shiftKey&&"F"===e.key){e.preventDefault(),ez();return}if("Escape"===e.key&&eA){e.preventDefault(),eV();return}}},[e4,eO,e0,v,r,A,ez,eV,eA]),tr=(0,l.useCallback)(e=>{let t=ew.current;if(!t)return;if(e.value===t.value)return void t.setSelectionRange(e.selectionStart,e.selectionEnd);t.focus(),t.setSelectionRange(e.replaceStart,e.replaceEnd);let r=!1;try{r="function"==typeof document.execCommand&&document.execCommand("insertText",!1,e.replacement)}catch(e){r=!1}if(r)return void t.setSelectionRange(e.selectionStart,e.selectionEnd);eE.current={start:e.selectionStart,end:e.selectionEnd},H(e.value),eJ(e.value),null==j||j(e.value)},[eJ,j]),tn=(0,l.useCallback)(()=>{let e=ew.current;e&&tr(q(e.value,e.selectionStart,e.selectionEnd," "))},[tr]),tl=(0,l.useCallback)(()=>{let e=ew.current;if(!e)return;let t=B(e.value,e.selectionStart,e.selectionEnd," ");t&&tr(t)},[tr]),to=(0,l.useCallback)(()=>{e$(e=>!e)},[e$]),ta=(0,l.useCallback)(e=>{if(e.ctrlKey&&!e.metaKey&&!e.altKey&&("m"===e.key||"M"===e.key)){e.preventDefault(),to();return}if("Tab"===e.key&&!eK&&!e.ctrlKey&&!e.metaKey&&!e.altKey){let t=e.currentTarget,r=e.shiftKey?B(t.value,t.selectionStart,t.selectionEnd," "):q(t.value,t.selectionStart,t.selectionEnd," ");r&&(e.preventDefault(),tr(r));return}tt(e)},[eK,to,tr,tt]);(0,l.useEffect)(()=>{let e=eE.current;if(!e)return;eE.current=null;let t=ew.current;t&&(t.focus(),t.setSelectionRange(e.start,e.end))},[A]);let ts=(0,l.useCallback)(e=>(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)("div",{ref:eb,className:"flex-shrink-0 py-4 pl-2 pr-2 text-right select-none text-muted-foreground font-mono text-sm bg-muted dark:bg-muted/50 border-r border-border overflow-hidden","aria-hidden":"true",children:Array.from({length:e2},(e,t)=>(0,n.jsx)("div",{className:"leading-[1.5rem]",children:t+1},t+1))}),(0,n.jsx)("textarea",{ref:ew,"data-testid":"markdown-editor-textarea",value:A,onChange:e3,onKeyDown:ta,onScroll:e5,className:"flex-1 py-4 pr-4 pl-3 font-mono text-sm resize-none bg-surface text-foreground focus:outline-none leading-[1.5rem]".concat(e?" focus:ring-2 focus:ring-ring focus:ring-inset":""),placeholder:E?N("editor.placeholder"):N("editor.placeholderMarkdown"),spellCheck:!1})]}),[e2,A,e3,ta,e5,E,N]);(0,l.useEffect)(()=>{let e=e=>{"Escape"===e.key&&eA&&(e.preventDefault(),eV())};return eA&&document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}},[eA,eV]),(0,l.useEffect)(()=>{y||eF&&!eA&&eT()},[]),(0,l.useEffect)(()=>{if("undefined"==typeof document)return;let e=document.getElementById("markdown-editor-portal");return e||((e=document.createElement("div")).id="markdown-editor-portal",document.body.appendChild(e)),ep(e),()=>{let e=document.getElementById("markdown-editor-portal");e&&0===e.childNodes.length&&e.remove()}},[]),(0,l.useEffect)(()=>{null==g||g(eA)},[eA,g]),(0,l.useEffect)(()=>{S||eY()},[eY,S]),(0,l.useEffect)(()=>{let e=eO?eB||eZ:eB,t=t=>{e&&(t.preventDefault(),t.returnValue="")};return e?(ek.current=t,window.addEventListener("beforeunload",t)):ek.current&&(window.removeEventListener("beforeunload",ek.current),ek.current=null),()=>{ek.current&&window.removeEventListener("beforeunload",ek.current)}},[eB,eZ,eO]),(0,l.useEffect)(()=>{eQ&&eO&&(eL(!1),eg(N("editor.autoSaveFailed"),"error"))},[eQ,eO,eL,eg,N]);let ti=(0,l.useMemo)(()=>{let e="flex flex-col bg-surface";return eA&&eP?"".concat(e," fixed inset-0"):"".concat(e," h-full")},[eA,eP]),td=(0,l.useMemo)(()=>{if(eA)return{zIndex:$.M.MAXIMIZED_EDITOR}},[eA]),tc=(0,l.useMemo)(()=>{if("split"===er&&!eU)return{width:"".concat(100*eI,"%"),flexShrink:0}},[er,eI,eU]),tu=(0,l.useMemo)(()=>{if("split"===er&&!eU)return{width:"".concat((1-eI)*100,"%"),flexShrink:0}},[er,eI,eU]),tf=(0,l.useMemo)(()=>{if(eS&&eM>0)return{paddingBottom:eM}},[eS,eM]);if(el)return(0,n.jsx)("div",{"data-testid":"markdown-editor",className:"flex items-center justify-center h-full bg-surface",children:(0,n.jsxs)("div",{className:"text-center",children:[(0,n.jsx)(m.y,{size:"xl",variant:"accent",className:"inline-block"}),(0,n.jsx)("p",{className:"mt-4 text-muted-foreground",children:N("editor.loading")})]})});if(ei)return(0,n.jsx)("div",{"data-testid":"markdown-editor-error",className:"flex items-center justify-center h-full bg-surface",children:(0,n.jsxs)("div",{className:"text-center",children:[(0,n.jsx)(i.A,{className:"h-12 w-12 text-danger mx-auto mb-4"}),(0,n.jsx)("p",{className:"text-danger-foreground",children:ei}),x&&(0,n.jsx)("button",{onClick:x,className:"mt-4 px-4 py-2 bg-muted hover:bg-muted/80 rounded-lg text-foreground",children:N("actions.close")})]})});let tm=(0,n.jsxs)("div",{ref:e=>{ey.current=e,eq.current=e},"data-testid":"markdown-editor",className:ti,style:td,onKeyDown:tt,role:eA&&eP?"dialog":void 0,"aria-modal":eA&&eP?"true":void 0,children:[(0,n.jsx)(F,{filePath:r,isDirty:eB,viewMode:er,onViewModeChange:e8,showMobileTabs:eU,copied:ef,onCopy:e9,isMaximized:eA,onToggleFullscreen:ez,isAutoSaveEnabled:eO,onAutoSaveToggle:e1,isAutoSaving:eZ,isSaving:ea,onSave:e4,onClose:x?e7:void 0,hideViewModeToggle:E||y,hideMaximizeButton:y,onIndent:tn,onOutdent:tl,tabMovesFocus:eK,onToggleTabMovesFocus:to}),eA&&(0,n.jsx)(R.OJ,{isMobile:eN}),ec&&(0,n.jsx)(R.Uc,{onDismiss:()=>eu(!1)}),eU&&(0,n.jsx)(R.RF,{mobileTab:eh,onTabChange:ex}),(0,n.jsxs)("div",{ref:ej,className:"flex flex-1 overflow-hidden",style:tf,children:[eU?"editor"===eh&&(0,n.jsx)("div",{"data-testid":"markdown-editor-container",className:"flex overflow-hidden w-full flex-1",children:ts(!1)}):(0,n.jsx)("div",{"data-testid":"markdown-editor-container",className:"flex overflow-hidden transition-all duration-200 ".concat(eG.showEditor?"":"hidden"),style:"split"===er?tc:{width:eG.showEditor?"100%":"0%"},children:ts(!0)}),"split"===er&&eG.showEditor&&eG.showPreview&&!eU&&(0,n.jsx)(h.f,{onResize:e6,onDoubleClick:te,orientation:"horizontal",ariaValueNow:Math.round(100*eI),minRatio:.1}),eU?"preview"===eh&&(0,n.jsx)("div",{"data-testid":"markdown-preview-container",className:"flex flex-col overflow-hidden w-full",children:(0,n.jsx)(Q,{previewContent:ee,onOpenFile:b,filePath:r,worktreeId:t,tocVisible:eH,onToggleTocVisible:e_,tocTitle:N("toc.title"),tocShowLabel:N("toc.show"),tocHideLabel:N("toc.hide")})}):(0,n.jsx)("div",{"data-testid":"markdown-preview-container",className:"flex flex-col overflow-hidden transition-all duration-200 ".concat(eG.showPreview?"":"hidden"),style:"split"===er?tu:{width:eG.showPreview?"100%":"0%"},children:(0,n.jsx)(Q,{previewContent:ee,onOpenFile:b,filePath:r,worktreeId:t,tocVisible:eH,onToggleTocVisible:e_,tocTitle:N("toc.title"),tocShowLabel:N("toc.show"),tocHideLabel:N("toc.hide")})})]})]});return eA&&eP&&ev?(0,o.createPortal)(tm,ev):tm})},55924:(e,t,r)=>{r.d(t,{K:()=>o});var n=r(95155),l=r(12115);function o(e){let{entries:t,title:r,headerOffset:o=64,root:a=null,className:s=""}=e,[i,d]=(0,l.useState)(null);return((0,l.useRef)(null).current=i,(0,l.useEffect)(()=>{if("undefined"==typeof IntersectionObserver||0===t.length)return;let e=new IntersectionObserver(e=>{let t=function(e){let t=e.filter(e=>e.isIntersecting).sort((e,t)=>e.boundingClientRect.top-t.boundingClientRect.top);return t.length>0?t[0].target.id:null}(e);t&&d(t)},{root:a,rootMargin:"-".concat(o,"px 0px -70% 0px"),threshold:0}),r=[];for(let n of t){let t=document.getElementById(n.id);t&&(e.observe(t),r.push(t))}return()=>{e.disconnect(),r.length=0}},[t,o,a]),0===t.length)?null:(0,n.jsxs)("nav",{"aria-label":r,className:s,children:[(0,n.jsx)("p",{className:"px-3 pb-2 text-xs font-semibold uppercase tracking-wide text-muted-foreground",children:r}),(0,n.jsx)("ul",{className:"space-y-0.5 text-sm",children:t.map((e,t)=>{let r=e.id===i;return(0,n.jsx)("li",{children:(0,n.jsx)("a",{href:"#".concat(e.id),onClick:t=>((e,t)=>{e.preventDefault();let r="undefined"!=typeof document?document.getElementById(t):null;r&&r.scrollIntoView({behavior:"smooth",block:"start"}),d(t)})(t,e.id),"aria-current":r?"location":void 0,"data-depth":e.depth,style:{paddingLeft:"".concat((e.depth-1)*12+12,"px")},className:["block truncate rounded py-1 pr-2 transition-colors",r?"bg-accent-50 font-medium text-accent-700":"text-muted-foreground hover:bg-muted hover:text-foreground"].join(" "),title:e.text,children:e.text})},"".concat(e.id,"-").concat(t))})})]})}},79962:(e,t,r)=>{r.d(t,{K:()=>s,Y:()=>l});var n=r(21286);let l="commandmate:md-toc-visible",o=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?[ \t]*$/,a=/^( {0,3})(`{3,}|~{3,})(.*)$/;function s(e){if(!e)return[];let t=new n.A,r=[],l=null,s=0;for(let n of e.split("\n")){var i;let e=a.exec(n);if(l){if(e){let t=e[2];t[0]===l&&t.length>=s&&""===e[3].trim()&&(l=null,s=0)}continue}if(e){let t=e[2],r=t[0];if("`"===r&&e[3].includes("`"));else{l=r,s=t.length;continue}}let d=o.exec(n);if(!d)continue;let c=d[1].length,u=function(e){let t=e;return(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace(/!\[[^\]]*\]\([^)]*\)/g,"")).replace(/!\[[^\]]*\]\[[^\]]*\]/g,"")).replace(/\[([^\]]*)\]\([^)]*\)/g,"$1")).replace(/\[([^\]]*)\]\[[^\]]*\]/g,"$1")).replace(/\[([^\]]*)\]/g,"$1")).replace(/(`+)([\s\S]*?)\1/g,"$2")).replace(/(\*\*|__)(.*?)\1/g,"$2")).replace(/(\*|_)(.*?)\1/g,"$2")).replace(/~~(.*?)~~/g,"$1")).replace(/\\([\\`*_{}[\]()#+\-.!~])/g,"$1")).trim()}((null!=(i=d[2])?i:"").replace(/([ \t]|^)#+[ \t]*$/,"")),f=t.slug(u);r.push({depth:c,text:u,id:f})}return r}},80003:(e,t,r)=>{r.d(t,{A:()=>n});let n=(0,r(71847).A)("list",[["path",{d:"M3 5h.01",key:"18ugdj"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M3 19h.01",key:"noohij"}],["path",{d:"M8 5h13",key:"1pao27"}],["path",{d:"M8 12h13",key:"1za7za"}],["path",{d:"M8 19h13",key:"m83p4d"}]])}}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5449],{54014:(e,t,n)=>{n.d(t,{Ab:()=>i,NL:()=>h,O6:()=>v,XH:()=>l,f_:()=>f,hR:()=>u,lu:()=>g,n6:()=>a,oo:()=>d,pQ:()=>o,sw:()=>s,vz:()=>p});let l=["claude","codex","gemini","vibe-local","opencode","copilot","antigravity","command-code","opencode-v2"],i=10,o=50,r=/^[a-zA-Z0-9_-]+$/;function a(e){return"string"==typeof e&&e.length>0&&e.length<=64&&r.test(e)}let c={claude:"Claude",codex:"Codex",gemini:"Gemini","vibe-local":"Vibe Local",opencode:"OpenCode",copilot:"Copilot",antigravity:"Antigravity","command-code":"Command Code","opencode-v2":"OpenCode V2"};function u(e){return l.includes(e)}function d(e){var t;return null!=(t=c[e])?t:e}function f(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"Assistant";return e&&u(e)?d(e):t}function s(e){let t=e.alias;return"string"==typeof t&&t.trim().length>0?t:d(e.cliTool)}function v(e,t,n){let l=e.find(e=>e.id===t);return l?s(l):d(n)}function g(e){return e.map((e,t)=>({id:e,cliTool:e,alias:d(e),order:t}))}let p=128,h=2097152},55449:(e,t,n)=>{n.d(t,{IK:()=>c,qD:()=>f,sA:()=>a,zk:()=>i});var l=n(63001);let i="/api/settings/default-agents",o=l.fJ,r=new Set;function a(){return o}function c(e){if(!Array.isArray(e))return!1;let t=(0,l.Lt)(e);if(!t.valid)return!1;let n=t.value;if(n.length===o.length&&n.every((e,t)=>e===o[t]))return!1;for(let e of(o=n,r))e();return!0}let u=null,d=!1;async function f(){return d?o:u||("function"!=typeof fetch?o:u=(async()=>{try{let e=await fetch(i);if(e.ok){let t=await e.json();c(null==t?void 0:t.defaultSelectedAgents),d=!0}}catch(e){}finally{u=null}return o})())}},63001:(e,t,n)=>{n.d(t,{Lt:()=>a,Wj:()=>o,eu:()=>i,fJ:()=>r});var l=n(54014);let i=2,o=6,r=["claude","codex","antigravity"];function a(e){return e.length<i||e.length>o?{valid:!1,error:"Must be ".concat(i,"-").concat(o," elements")}:e.every(e=>"string"==typeof e&&l.XH.includes(e))?new Set(e).size!==e.length?{valid:!1,error:"Duplicate tool IDs not allowed"}:{valid:!0,value:e}:{valid:!1,error:"Invalid CLI tool ID"}}}}]);
|