commandmate 0.18.0 → 0.19.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 +131 -131
- package/.next/app-path-routes-manifest.json +23 -23
- 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/app/update/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/app/update-check/route.js +1 -1
- package/.next/server/app/api/app/update-check/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/conversation/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/messages/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/start/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/assistant/tools/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/auth/login/route_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/daily-summary/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/daily-summary/status/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/health/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/external-apps/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/browse/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/fs/recent-paths/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/agent-event/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/hooks/claude-done/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/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/subscriptions/route.js +1 -1
- package/.next/server/app/api/push/subscriptions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/push/vapid/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route.js +1 -1
- package/.next/server/app/api/repositories/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/[jobId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/clone/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/excluded/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/scan/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/sync/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/repositories/validate-path/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sidebar/group-order/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/installations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/operations/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/reindex/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/cancel/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route.js +1 -1
- package/.next/server/app/api/tasks/[taskId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/templates/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/todos/route.js +1 -1
- package/.next/server/app/api/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verification/runs/[runId]/route.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.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_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cli-tool/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/cmate/schedules/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/current-output/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/[logId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/execution-logs/route.js +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.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.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.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.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/reset/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/revert/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/git/show/[commitHash]/route.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.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.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.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.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.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]/interrupt/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/kill-session/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/[filename]/route.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/logs/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/marp-render/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/[memoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/memos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/messages/route.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]/prompt-response/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/respond/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/schedules/[scheduleId]/route.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.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.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_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/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/skills/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/slash-commands/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/special-keys/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/start-polling/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tasks/route.js +2 -2
- package/.next/server/app/api/worktrees/[id]/tasks/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/history/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/timers/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/[todoId]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/todos/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/[...path]/route.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/tree/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/upload/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/[id]/verify/runs/[runId]/route.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.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.js +1 -1
- package/.next/server/app/api/worktrees/[id]/viewed/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/worktrees/route_client-reference-manifest.js +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/more/page_client-reference-manifest.js +1 -1
- package/.next/server/app/offline/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/proxy/[...path]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/repositories/page_client-reference-manifest.js +1 -1
- package/.next/server/app/review/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/[skillId]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/installed/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/files/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/page.js +1 -1
- package/.next/server/app/worktrees/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/worktrees/[id]/terminal/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +23 -23
- package/.next/server/chunks/1117.js +1 -1
- package/.next/server/chunks/3042.js +1 -1
- package/.next/server/chunks/3753.js +19 -23
- package/.next/server/chunks/5959.js +3 -3
- package/.next/server/chunks/6130.js +1 -1
- package/.next/server/chunks/6274.js +5 -4
- package/.next/server/chunks/6283.js +1 -1
- package/.next/server/chunks/8681.js +1 -1
- package/.next/server/chunks/8807.js +492 -487
- package/.next/server/chunks/8856.js +1 -1
- 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/{6488-109e3825c7249e47.js → 6488-2c412c29258637b6.js} +1 -1
- package/.next/static/chunks/app/worktrees/[id]/{page-12b3c5f32fc6094e.js → page-f6e09d25cd3b56f9.js} +1 -1
- package/.next/trace +12 -12
- package/dist/cli/commands/auto-yes.d.ts.map +1 -1
- package/dist/cli/commands/auto-yes.js +9 -2
- package/dist/cli/commands/capture.d.ts +1 -0
- package/dist/cli/commands/capture.d.ts.map +1 -1
- package/dist/cli/commands/capture.js +112 -2
- package/dist/cli/commands/instances.d.ts +24 -0
- package/dist/cli/commands/instances.d.ts.map +1 -1
- package/dist/cli/commands/instances.js +44 -0
- package/dist/cli/commands/respond.d.ts.map +1 -1
- package/dist/cli/commands/respond.js +10 -2
- package/dist/cli/commands/send.d.ts.map +1 -1
- package/dist/cli/commands/send.js +20 -11
- package/dist/cli/commands/wait.d.ts +4 -1
- package/dist/cli/commands/wait.d.ts.map +1 -1
- package/dist/cli/commands/wait.js +80 -6
- package/dist/cli/types/index.d.ts +16 -0
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/utils/pager.d.ts +28 -0
- package/dist/cli/utils/pager.d.ts.map +1 -0
- package/dist/cli/utils/pager.js +57 -0
- package/dist/lib/detection/ansi.d.ts +30 -0
- package/dist/lib/detection/ansi.d.ts.map +1 -0
- package/dist/lib/detection/ansi.js +39 -0
- package/dist/lib/tmux/transcript-squeeze.d.ts +76 -0
- package/dist/lib/tmux/transcript-squeeze.d.ts.map +1 -0
- package/dist/lib/tmux/transcript-squeeze.js +96 -0
- package/dist/server/server.js +18 -0
- package/dist/server/src/config/tmux-pane-config.js +33 -1
- package/dist/server/src/lib/cli-tools/antigravity.js +2 -1
- package/dist/server/src/lib/cli-tools/codex.js +3 -2
- package/dist/server/src/lib/cli-tools/copilot.js +2 -2
- package/dist/server/src/lib/cli-tools/gemini.js +2 -2
- package/dist/server/src/lib/cli-tools/opencode.js +2 -2
- package/dist/server/src/lib/cli-tools/vibe-local.js +2 -2
- package/dist/server/src/lib/db/agent-instances-db.js +53 -0
- package/dist/server/src/lib/db/migrations/index.js +2 -0
- package/dist/server/src/lib/db/migrations/runner.js +1 -1
- package/dist/server/src/lib/db/migrations/v52-orphaned-worktree-children.js +76 -0
- package/dist/server/src/lib/db/migrations/worktree-child-tables.js +119 -0
- package/dist/server/src/lib/db/worktree-db.js +65 -42
- package/dist/server/src/lib/detection/cli-patterns.js +24 -1
- package/dist/server/src/lib/detection/status-detector.js +52 -2
- package/dist/server/src/lib/session/claude-session.js +4 -2
- package/dist/server/src/lib/tmux/read-mode-pager.js +161 -0
- package/dist/server/src/lib/tmux/read-mode.js +327 -0
- package/dist/server/src/lib/tmux/tmux.js +43 -5
- package/package.json +1 -1
- /package/.next/static/{-BSmW0Ae2YsxyCl_ue7_d → -E7I667pJDTBamyG8M_Z-}/_buildManifest.js +0 -0
- /package/.next/static/{-BSmW0Ae2YsxyCl_ue7_d → -E7I667pJDTBamyG8M_Z-}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal pager for CLI output (Issue #1623, 案B).
|
|
3
|
+
*
|
|
4
|
+
* `commandmate capture --pane` prints a whole transcript, which is unreadable if
|
|
5
|
+
* it just scrolls past. When stdout is a terminal the text goes through a pager;
|
|
6
|
+
* when it is a pipe or a file it must stay plain so `| grep` and `> file` behave.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the pager command line.
|
|
10
|
+
*
|
|
11
|
+
* `CM_PAGER` wins so a user can page CommandMate output differently from the
|
|
12
|
+
* rest of their shell; `PAGER` is the conventional fallback. An explicitly empty
|
|
13
|
+
* value means "no pager" and is honoured rather than overridden.
|
|
14
|
+
*
|
|
15
|
+
* @returns argv for the pager, or undefined when paging is disabled
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolvePagerCommand(): string[] | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Print `text`, paging it when stdout is an interactive terminal.
|
|
20
|
+
*
|
|
21
|
+
* Falls back to plain stdout whenever paging is not possible or not wanted:
|
|
22
|
+
* non-TTY stdout, no pager configured, or a pager that could not be spawned (so
|
|
23
|
+
* a missing `less` degrades to readable output instead of an error).
|
|
24
|
+
*
|
|
25
|
+
* @param text - Content to display
|
|
26
|
+
*/
|
|
27
|
+
export declare function printMaybePaged(text: string): void;
|
|
28
|
+
//# sourceMappingURL=pager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pager.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/pager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,GAAG,SAAS,CAI1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAsBlD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Terminal pager for CLI output (Issue #1623, 案B).
|
|
4
|
+
*
|
|
5
|
+
* `commandmate capture --pane` prints a whole transcript, which is unreadable if
|
|
6
|
+
* it just scrolls past. When stdout is a terminal the text goes through a pager;
|
|
7
|
+
* when it is a pipe or a file it must stay plain so `| grep` and `> file` behave.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.resolvePagerCommand = resolvePagerCommand;
|
|
11
|
+
exports.printMaybePaged = printMaybePaged;
|
|
12
|
+
const child_process_1 = require("child_process");
|
|
13
|
+
/** Pager used when neither `CM_PAGER` nor `PAGER` is set. `-R` keeps ANSI colors. */
|
|
14
|
+
const DEFAULT_PAGER = 'less -R';
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the pager command line.
|
|
17
|
+
*
|
|
18
|
+
* `CM_PAGER` wins so a user can page CommandMate output differently from the
|
|
19
|
+
* rest of their shell; `PAGER` is the conventional fallback. An explicitly empty
|
|
20
|
+
* value means "no pager" and is honoured rather than overridden.
|
|
21
|
+
*
|
|
22
|
+
* @returns argv for the pager, or undefined when paging is disabled
|
|
23
|
+
*/
|
|
24
|
+
function resolvePagerCommand() {
|
|
25
|
+
const configured = process.env.CM_PAGER ?? process.env.PAGER ?? DEFAULT_PAGER;
|
|
26
|
+
const argv = configured.trim().split(/\s+/).filter(Boolean);
|
|
27
|
+
return argv.length > 0 ? argv : undefined;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Print `text`, paging it when stdout is an interactive terminal.
|
|
31
|
+
*
|
|
32
|
+
* Falls back to plain stdout whenever paging is not possible or not wanted:
|
|
33
|
+
* non-TTY stdout, no pager configured, or a pager that could not be spawned (so
|
|
34
|
+
* a missing `less` degrades to readable output instead of an error).
|
|
35
|
+
*
|
|
36
|
+
* @param text - Content to display
|
|
37
|
+
*/
|
|
38
|
+
function printMaybePaged(text) {
|
|
39
|
+
if (!process.stdout.isTTY) {
|
|
40
|
+
console.log(text);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const argv = resolvePagerCommand();
|
|
44
|
+
if (!argv) {
|
|
45
|
+
console.log(text);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// The pager reads the keyboard from /dev/tty, exactly as in `cmd | less`, so
|
|
49
|
+
// piping the body in through stdin does not cost it its interactivity.
|
|
50
|
+
const result = (0, child_process_1.spawnSync)(argv[0], argv.slice(1), {
|
|
51
|
+
input: text.endsWith('\n') ? text : `${text}\n`,
|
|
52
|
+
stdio: ['pipe', 'inherit', 'inherit'],
|
|
53
|
+
});
|
|
54
|
+
if (result.error) {
|
|
55
|
+
console.log(text);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency-free ANSI escape-sequence primitives.
|
|
3
|
+
*
|
|
4
|
+
* These live in their own leaf module (no logger/db/server imports) so both
|
|
5
|
+
* server-side detection code (`cli-patterns.ts`, which re-exports them) and
|
|
6
|
+
* client components (the terminal display normalizer, Issue #1172) can share the
|
|
7
|
+
* exact same tested pattern without pulling Node-only modules into the browser
|
|
8
|
+
* bundle.
|
|
9
|
+
*
|
|
10
|
+
* Covers:
|
|
11
|
+
* - SGR sequences: ESC[Nm (colors, bold, underline, etc.)
|
|
12
|
+
* - OSC sequences: ESC]...BEL (window title, hyperlinks, etc.)
|
|
13
|
+
* - CSI sequences: ESC[...letter (cursor movement, erase, etc.)
|
|
14
|
+
*
|
|
15
|
+
* Known limitations (SEC-002): 8-bit CSI (0x9B), DEC private modes (ESC[?25h),
|
|
16
|
+
* character-set switching (ESC(0), and some RGB color forms may not match. In
|
|
17
|
+
* practice tmux capture-pane output rarely contains these.
|
|
18
|
+
*/
|
|
19
|
+
export declare const ANSI_PATTERN: RegExp;
|
|
20
|
+
/** Remove all ANSI escape sequences from a string. */
|
|
21
|
+
export declare function stripAnsi(str: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Extract the ANSI escape sequences from a string, in order, discarding all
|
|
24
|
+
* other characters. Reuses the same tested pattern as {@link stripAnsi} so the
|
|
25
|
+
* two stay in lock-step. Used when collapsing blank layout rows for display
|
|
26
|
+
* (Issue #1172): the visible glyphs are dropped but any color/reset sequences
|
|
27
|
+
* that alter how subsequent rows render must be preserved.
|
|
28
|
+
*/
|
|
29
|
+
export declare function extractAnsiSequences(str: string): string;
|
|
30
|
+
//# sourceMappingURL=ansi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ansi.d.ts","sourceRoot":"","sources":["../../../src/lib/detection/ansi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,YAAY,QAAyD,CAAC;AAEnF,sDAAsD;AACtD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGxD"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dependency-free ANSI escape-sequence primitives.
|
|
4
|
+
*
|
|
5
|
+
* These live in their own leaf module (no logger/db/server imports) so both
|
|
6
|
+
* server-side detection code (`cli-patterns.ts`, which re-exports them) and
|
|
7
|
+
* client components (the terminal display normalizer, Issue #1172) can share the
|
|
8
|
+
* exact same tested pattern without pulling Node-only modules into the browser
|
|
9
|
+
* bundle.
|
|
10
|
+
*
|
|
11
|
+
* Covers:
|
|
12
|
+
* - SGR sequences: ESC[Nm (colors, bold, underline, etc.)
|
|
13
|
+
* - OSC sequences: ESC]...BEL (window title, hyperlinks, etc.)
|
|
14
|
+
* - CSI sequences: ESC[...letter (cursor movement, erase, etc.)
|
|
15
|
+
*
|
|
16
|
+
* Known limitations (SEC-002): 8-bit CSI (0x9B), DEC private modes (ESC[?25h),
|
|
17
|
+
* character-set switching (ESC(0), and some RGB color forms may not match. In
|
|
18
|
+
* practice tmux capture-pane output rarely contains these.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.ANSI_PATTERN = void 0;
|
|
22
|
+
exports.stripAnsi = stripAnsi;
|
|
23
|
+
exports.extractAnsiSequences = extractAnsiSequences;
|
|
24
|
+
exports.ANSI_PATTERN = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\[[0-9;]*m/g;
|
|
25
|
+
/** Remove all ANSI escape sequences from a string. */
|
|
26
|
+
function stripAnsi(str) {
|
|
27
|
+
return str.replace(exports.ANSI_PATTERN, '');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract the ANSI escape sequences from a string, in order, discarding all
|
|
31
|
+
* other characters. Reuses the same tested pattern as {@link stripAnsi} so the
|
|
32
|
+
* two stay in lock-step. Used when collapsing blank layout rows for display
|
|
33
|
+
* (Issue #1172): the visible glyphs are dropped but any color/reset sequences
|
|
34
|
+
* that alter how subsequent rows render must be preserved.
|
|
35
|
+
*/
|
|
36
|
+
function extractAnsiSequences(str) {
|
|
37
|
+
const matches = str.match(exports.ANSI_PATTERN);
|
|
38
|
+
return matches ? matches.join('') : '';
|
|
39
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whitespace squeeze for the on-demand reading mode (Issue #1623).
|
|
3
|
+
*
|
|
4
|
+
* TUI sessions are pinned to a 200x1000 canvas (`src/config/tmux-pane-config.ts`)
|
|
5
|
+
* and the agent draws its transcript near the top and its composer at the very
|
|
6
|
+
* bottom, so a raw `capture-pane` is mostly layout-only blank rows. Measured on a
|
|
7
|
+
* live `mcbd-claude-*` session: 1000 rows, 480 truly empty, 7 more that LOOK empty
|
|
8
|
+
* but carry an SGR sequence (`ESC[49m`) and therefore survive a naive
|
|
9
|
+
* `grep -v '^$'` or `less -s`. Squeezing those runs is what makes `less +G` land
|
|
10
|
+
* on the composer instead of hundreds of rows below the last readable line.
|
|
11
|
+
*
|
|
12
|
+
* ## Relationship to the Web UI normalizer
|
|
13
|
+
*
|
|
14
|
+
* `src/lib/terminal/terminal-display-normalizer.ts` (Issue #1172) solves the same
|
|
15
|
+
* problem for the browser terminal and its rules are the ones reproduced here.
|
|
16
|
+
* This module exists as a separate entry point rather than importing that one
|
|
17
|
+
* because the CLI is compiled by `tsconfig.cli.json`, which sets `"paths": {}` —
|
|
18
|
+
* the normalizer's `@/lib/detection/ansi` import fails there with TS2307 (verified
|
|
19
|
+
* by adding the import and running `tsc --project tsconfig.cli.json`), while the
|
|
20
|
+
* relative import below resolves under every build. The two are held byte-identical
|
|
21
|
+
* by a conformance test over real captures
|
|
22
|
+
* (`tests/unit/lib/tmux/transcript-squeeze.test.ts`), so neither can drift.
|
|
23
|
+
*
|
|
24
|
+
* The transform is DISPLAY-ONLY. Nothing here touches the raw output that status
|
|
25
|
+
* detection, Auto-Yes, the response saver or the DB record consume — those keep
|
|
26
|
+
* full fidelity and full line counts.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* A line is visually blank when nothing printable remains after ANSI removal.
|
|
30
|
+
*
|
|
31
|
+
* `.trim()` is deliberate: ECMAScript's WhiteSpace includes U+00A0, which the
|
|
32
|
+
* Claude composer emits (`ESC[38;5;246m❯ ESC[39m`). That line still holds
|
|
33
|
+
* `❯`, so it is content either way, but a row of pure NBSP correctly reads blank.
|
|
34
|
+
*/
|
|
35
|
+
export declare function isVisuallyBlank(line: string): boolean;
|
|
36
|
+
/** Options for {@link squeezeTranscript}. */
|
|
37
|
+
export interface SqueezeOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Keep only the last N lines OF THE SQUEEZED RESULT (Issue #1623 decision D5).
|
|
40
|
+
*
|
|
41
|
+
* Tailing after the squeeze rather than before it is what makes the number
|
|
42
|
+
* meaningful: `--tail 40` on a 1000-row canvas whose transcript ends at row 254
|
|
43
|
+
* would otherwise return 40 rows of blank padding. Undefined or <= 0 keeps
|
|
44
|
+
* everything.
|
|
45
|
+
*/
|
|
46
|
+
tail?: number;
|
|
47
|
+
}
|
|
48
|
+
/** Outcome of a squeeze, including the counts callers report in `--json`. */
|
|
49
|
+
export interface SqueezeResult {
|
|
50
|
+
/** Squeezed transcript, no trailing newline. */
|
|
51
|
+
text: string;
|
|
52
|
+
/** Line count of the input, before squeezing. */
|
|
53
|
+
rawLines: number;
|
|
54
|
+
/** Line count of {@link text}. */
|
|
55
|
+
lines: number;
|
|
56
|
+
/** True when {@link SqueezeOptions.tail} actually dropped leading lines. */
|
|
57
|
+
tailed: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Collapse layout-only blank rows in a `capture-pane` frame.
|
|
61
|
+
*
|
|
62
|
+
* Rules (identical to `normalizeTerminalOutputForDisplay`, Issue #1172):
|
|
63
|
+
* 1. Blankness is judged on `stripAnsi(line).trim()`.
|
|
64
|
+
* 2. Leading and trailing blank runs are removed entirely.
|
|
65
|
+
* 3. An internal blank run of 1-2 rows is kept verbatim (real paragraph spacing).
|
|
66
|
+
* 4. An internal blank run of 3+ rows collapses to ONE row carrying that run's
|
|
67
|
+
* ANSI sequences in order, so a color/reset that spans the gap still applies
|
|
68
|
+
* to the rows below it.
|
|
69
|
+
* 5. Non-blank lines are never altered — content, order and duplicates survive.
|
|
70
|
+
*
|
|
71
|
+
* @param raw - Raw `capture-pane -pe` output
|
|
72
|
+
* @param options - Tail limit
|
|
73
|
+
* @returns The squeezed text plus before/after line counts
|
|
74
|
+
*/
|
|
75
|
+
export declare function squeezeTranscript(raw: string, options?: SqueezeOptions): SqueezeResult;
|
|
76
|
+
//# sourceMappingURL=transcript-squeeze.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-squeeze.d.ts","sourceRoot":"","sources":["../../../src/lib/tmux/transcript-squeeze.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,aAAa,CAwC1F"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Whitespace squeeze for the on-demand reading mode (Issue #1623).
|
|
4
|
+
*
|
|
5
|
+
* TUI sessions are pinned to a 200x1000 canvas (`src/config/tmux-pane-config.ts`)
|
|
6
|
+
* and the agent draws its transcript near the top and its composer at the very
|
|
7
|
+
* bottom, so a raw `capture-pane` is mostly layout-only blank rows. Measured on a
|
|
8
|
+
* live `mcbd-claude-*` session: 1000 rows, 480 truly empty, 7 more that LOOK empty
|
|
9
|
+
* but carry an SGR sequence (`ESC[49m`) and therefore survive a naive
|
|
10
|
+
* `grep -v '^$'` or `less -s`. Squeezing those runs is what makes `less +G` land
|
|
11
|
+
* on the composer instead of hundreds of rows below the last readable line.
|
|
12
|
+
*
|
|
13
|
+
* ## Relationship to the Web UI normalizer
|
|
14
|
+
*
|
|
15
|
+
* `src/lib/terminal/terminal-display-normalizer.ts` (Issue #1172) solves the same
|
|
16
|
+
* problem for the browser terminal and its rules are the ones reproduced here.
|
|
17
|
+
* This module exists as a separate entry point rather than importing that one
|
|
18
|
+
* because the CLI is compiled by `tsconfig.cli.json`, which sets `"paths": {}` —
|
|
19
|
+
* the normalizer's `@/lib/detection/ansi` import fails there with TS2307 (verified
|
|
20
|
+
* by adding the import and running `tsc --project tsconfig.cli.json`), while the
|
|
21
|
+
* relative import below resolves under every build. The two are held byte-identical
|
|
22
|
+
* by a conformance test over real captures
|
|
23
|
+
* (`tests/unit/lib/tmux/transcript-squeeze.test.ts`), so neither can drift.
|
|
24
|
+
*
|
|
25
|
+
* The transform is DISPLAY-ONLY. Nothing here touches the raw output that status
|
|
26
|
+
* detection, Auto-Yes, the response saver or the DB record consume — those keep
|
|
27
|
+
* full fidelity and full line counts.
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.isVisuallyBlank = isVisuallyBlank;
|
|
31
|
+
exports.squeezeTranscript = squeezeTranscript;
|
|
32
|
+
const ansi_1 = require("../detection/ansi");
|
|
33
|
+
/**
|
|
34
|
+
* A line is visually blank when nothing printable remains after ANSI removal.
|
|
35
|
+
*
|
|
36
|
+
* `.trim()` is deliberate: ECMAScript's WhiteSpace includes U+00A0, which the
|
|
37
|
+
* Claude composer emits (`ESC[38;5;246m❯ ESC[39m`). That line still holds
|
|
38
|
+
* `❯`, so it is content either way, but a row of pure NBSP correctly reads blank.
|
|
39
|
+
*/
|
|
40
|
+
function isVisuallyBlank(line) {
|
|
41
|
+
return (0, ansi_1.stripAnsi)(line).trim() === '';
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Collapse layout-only blank rows in a `capture-pane` frame.
|
|
45
|
+
*
|
|
46
|
+
* Rules (identical to `normalizeTerminalOutputForDisplay`, Issue #1172):
|
|
47
|
+
* 1. Blankness is judged on `stripAnsi(line).trim()`.
|
|
48
|
+
* 2. Leading and trailing blank runs are removed entirely.
|
|
49
|
+
* 3. An internal blank run of 1-2 rows is kept verbatim (real paragraph spacing).
|
|
50
|
+
* 4. An internal blank run of 3+ rows collapses to ONE row carrying that run's
|
|
51
|
+
* ANSI sequences in order, so a color/reset that spans the gap still applies
|
|
52
|
+
* to the rows below it.
|
|
53
|
+
* 5. Non-blank lines are never altered — content, order and duplicates survive.
|
|
54
|
+
*
|
|
55
|
+
* @param raw - Raw `capture-pane -pe` output
|
|
56
|
+
* @param options - Tail limit
|
|
57
|
+
* @returns The squeezed text plus before/after line counts
|
|
58
|
+
*/
|
|
59
|
+
function squeezeTranscript(raw, options = {}) {
|
|
60
|
+
const lines = raw === '' ? [] : raw.split('\n');
|
|
61
|
+
const result = [];
|
|
62
|
+
let seenContent = false;
|
|
63
|
+
let i = 0;
|
|
64
|
+
while (i < lines.length) {
|
|
65
|
+
if (!isVisuallyBlank(lines[i])) {
|
|
66
|
+
result.push(lines[i]);
|
|
67
|
+
seenContent = true;
|
|
68
|
+
i++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
let j = i;
|
|
72
|
+
while (j < lines.length && isVisuallyBlank(lines[j]))
|
|
73
|
+
j++;
|
|
74
|
+
const isLeading = !seenContent;
|
|
75
|
+
const isTrailing = j >= lines.length;
|
|
76
|
+
if (!isLeading && !isTrailing) {
|
|
77
|
+
if (j - i <= 2) {
|
|
78
|
+
for (let k = i; k < j; k++)
|
|
79
|
+
result.push(lines[k]);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
result.push((0, ansi_1.extractAnsiSequences)(lines.slice(i, j).join('')));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
i = j;
|
|
86
|
+
}
|
|
87
|
+
const tail = options.tail;
|
|
88
|
+
const tailed = tail !== undefined && tail > 0 && result.length > tail;
|
|
89
|
+
const kept = tailed ? result.slice(result.length - tail) : result;
|
|
90
|
+
return {
|
|
91
|
+
text: kept.join('\n'),
|
|
92
|
+
rawLines: lines.length,
|
|
93
|
+
lines: kept.length,
|
|
94
|
+
tailed,
|
|
95
|
+
};
|
|
96
|
+
}
|
package/dist/server/server.js
CHANGED
|
@@ -319,6 +319,24 @@ app.prepare().then(() => {
|
|
|
319
319
|
console.log(`> WebSocket server ready`);
|
|
320
320
|
// Initialize worktrees after server starts
|
|
321
321
|
await initializeWorktrees();
|
|
322
|
+
// Issue #1623: reconcile the `prefix+g` reading-mode binding on the user's
|
|
323
|
+
// tmux server. Fail-open in its own try/catch — a convenience key must never
|
|
324
|
+
// be able to stop the server from serving.
|
|
325
|
+
//
|
|
326
|
+
// Dynamic import, NOT a top-level static import, for the same reason as the
|
|
327
|
+
// reconcilers above: adding a module graph to server.ts's eval-time graph
|
|
328
|
+
// perturbs Next's AsyncLocalStorage bootstrap under `tsx server.ts`, and the
|
|
329
|
+
// first request that compiles middleware then dies. Do not hoist this.
|
|
330
|
+
try {
|
|
331
|
+
const { initReadMode } = await Promise.resolve().then(() => __importStar(require('./src/lib/tmux/read-mode')));
|
|
332
|
+
const readMode = await initReadMode();
|
|
333
|
+
if (readMode.installed) {
|
|
334
|
+
console.log(`Reading mode ready: press prefix+${readMode.key} in an attached CommandMate session`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
console.error('Error initializing tmux reading mode:', error);
|
|
339
|
+
}
|
|
322
340
|
// [S3-010] Initialize schedule manager AFTER worktrees are ready
|
|
323
341
|
(0, schedule_manager_1.initScheduleManager)();
|
|
324
342
|
// Issue #534: Initialize timer manager AFTER schedule manager
|
|
@@ -17,8 +17,40 @@
|
|
|
17
17
|
* so `capture-pane` cost / render load stays reasonable.
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.TUI_PANE_WIDTH = exports.TUI_PANE_HEIGHT = void 0;
|
|
20
|
+
exports.TMUX_HISTORY_LIMIT = exports.TUI_PANE_WIDTH = exports.TUI_PANE_HEIGHT = void 0;
|
|
21
21
|
/** Fixed pane height (rows) for TUI sessions. Large enough to retain useful history. */
|
|
22
22
|
exports.TUI_PANE_HEIGHT = 1000;
|
|
23
23
|
/** Fixed pane width (columns) for TUI sessions. Matches the historical default. */
|
|
24
24
|
exports.TUI_PANE_WIDTH = 200;
|
|
25
|
+
/**
|
|
26
|
+
* Scrollback lines retained per pane (`history-limit`), Issue #1624.
|
|
27
|
+
*
|
|
28
|
+
* Only NON-alternate-screen tools (codex / gemini / vibe-local / antigravity)
|
|
29
|
+
* consume this: the alternate-screen tools in `ALTERNATE_SCREEN_CLI_TOOLS`
|
|
30
|
+
* (claude / opencode / copilot) keep `history_size` at 0, so scrollback depth is
|
|
31
|
+
* irrelevant to them. See `usesAlternateScreen` in lib/cli-tools/types.ts.
|
|
32
|
+
*
|
|
33
|
+
* WHY 20000 and not the 50000 this used to request — measured on tmux 3.5a with
|
|
34
|
+
* a 200-column pane full of realistic, heavily-SGR-coloured agent output
|
|
35
|
+
* (274 bytes/line as re-emitted by `capture-pane -e`):
|
|
36
|
+
*
|
|
37
|
+
* 1. `capturePane` runs tmux under `execFile` with `maxBuffer: 10 MB`. A full
|
|
38
|
+
* 50000-line capture extrapolates to ~13 MB of escape-laden text, which
|
|
39
|
+
* OVERFLOWS that buffer and makes `capturePane` THROW rather than return a
|
|
40
|
+
* truncated string — i.e. the deepest part of a 50000-line buffer was never
|
|
41
|
+
* readable by this app in the first place. 20000 lines is ~5.2 MB, leaving
|
|
42
|
+
* roughly 2x headroom.
|
|
43
|
+
* 2. Nothing in the app reads deeper than 10000 lines by default (`capturePane`'s
|
|
44
|
+
* options-path default is `-S -10000`; every other call site asks for 1000 or
|
|
45
|
+
* fewer). 20000 keeps a 2x margin over the deepest default read.
|
|
46
|
+
* 3. Memory is charged per line ACTUALLY emitted, not preallocated from the
|
|
47
|
+
* limit: a fresh session cost ~0.3 MB of tmux-server RSS, growing to ~34 MB
|
|
48
|
+
* only after 45000 lines had scrolled (~0.68 KB/line). At 20000 a saturated
|
|
49
|
+
* pane costs ~14 MB, so 20 concurrent sessions cap out near 270 MB instead of
|
|
50
|
+
* the ~680 MB implied by 50000.
|
|
51
|
+
*
|
|
52
|
+
* This is still a 10x increase over tmux's built-in 2000, which is what sessions
|
|
53
|
+
* were actually getting before #1624 (a `mcbd-codex-*` session was observed at
|
|
54
|
+
* 1977/2000 lines used, i.e. actively losing transcript).
|
|
55
|
+
*/
|
|
56
|
+
exports.TMUX_HISTORY_LIMIT = 20000;
|
|
@@ -119,10 +119,11 @@ class AntigravityTool extends base_1.BaseCLITool {
|
|
|
119
119
|
try {
|
|
120
120
|
// Create tmux session with large history buffer for agy output
|
|
121
121
|
// (agy is inline-rendered and retains scrollback, like Codex)
|
|
122
|
+
// Scrollback depth comes from the shared TMUX_HISTORY_LIMIT default
|
|
123
|
+
// (Issue #1624) — do not re-hardcode it here.
|
|
122
124
|
await (0, tmux_1.createSession)({
|
|
123
125
|
sessionName,
|
|
124
126
|
workingDirectory: worktreePath,
|
|
125
|
-
historyLimit: 50000,
|
|
126
127
|
});
|
|
127
128
|
// Wait a moment for the session to be created
|
|
128
129
|
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
@@ -67,11 +67,12 @@ class CodexTool extends base_1.BaseCLITool {
|
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
try {
|
|
70
|
-
// Create tmux session
|
|
70
|
+
// Create tmux session. Codex is inline-rendered, so its transcript lives in
|
|
71
|
+
// the pane scrollback — depth comes from the shared TMUX_HISTORY_LIMIT
|
|
72
|
+
// default (Issue #1624), do not re-hardcode it here.
|
|
71
73
|
await (0, tmux_1.createSession)({
|
|
72
74
|
sessionName,
|
|
73
75
|
workingDirectory: worktreePath,
|
|
74
|
-
historyLimit: 50000,
|
|
75
76
|
});
|
|
76
77
|
// Wait a moment for the session to be created
|
|
77
78
|
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
@@ -113,11 +113,11 @@ class CopilotTool extends base_1.BaseCLITool {
|
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
115
|
try {
|
|
116
|
-
// Create tmux session
|
|
116
|
+
// Create tmux session. Scrollback depth comes from the shared
|
|
117
|
+
// TMUX_HISTORY_LIMIT default (Issue #1624) — do not re-hardcode it here.
|
|
117
118
|
await (0, tmux_1.createSession)({
|
|
118
119
|
sessionName,
|
|
119
120
|
workingDirectory: worktreePath,
|
|
120
|
-
historyLimit: 50000,
|
|
121
121
|
});
|
|
122
122
|
// Wait a moment for the session to be created
|
|
123
123
|
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
@@ -74,11 +74,11 @@ class GeminiTool extends base_1.BaseCLITool {
|
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
76
|
try {
|
|
77
|
-
// Create tmux session
|
|
77
|
+
// Create tmux session. Scrollback depth comes from the shared
|
|
78
|
+
// TMUX_HISTORY_LIMIT default (Issue #1624) — do not re-hardcode it here.
|
|
78
79
|
await (0, tmux_1.createSession)({
|
|
79
80
|
sessionName,
|
|
80
81
|
workingDirectory: worktreePath,
|
|
81
|
-
historyLimit: 50000,
|
|
82
82
|
});
|
|
83
83
|
// Wait a moment for the session to be created
|
|
84
84
|
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
@@ -89,11 +89,11 @@ class OpenCodeTool extends base_1.BaseCLITool {
|
|
|
89
89
|
try {
|
|
90
90
|
// Generate opencode.json if not present (non-fatal on failure)
|
|
91
91
|
await (0, opencode_config_1.ensureOpencodeConfig)(worktreePath);
|
|
92
|
-
// Create tmux session
|
|
92
|
+
// Create tmux session. Scrollback depth comes from the shared
|
|
93
|
+
// TMUX_HISTORY_LIMIT default (Issue #1624) — do not re-hardcode it here.
|
|
93
94
|
await (0, tmux_1.createSession)({
|
|
94
95
|
sessionName,
|
|
95
96
|
workingDirectory: worktreePath,
|
|
96
|
-
historyLimit: 50000,
|
|
97
97
|
});
|
|
98
98
|
// Wait a moment for the session to be created
|
|
99
99
|
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
@@ -66,11 +66,11 @@ class VibeLocalTool extends base_1.BaseCLITool {
|
|
|
66
66
|
return;
|
|
67
67
|
}
|
|
68
68
|
try {
|
|
69
|
-
// Create tmux session
|
|
69
|
+
// Create tmux session. Scrollback depth comes from the shared
|
|
70
|
+
// TMUX_HISTORY_LIMIT default (Issue #1624) — do not re-hardcode it here.
|
|
70
71
|
await (0, tmux_1.createSession)({
|
|
71
72
|
sessionName,
|
|
72
73
|
workingDirectory: worktreePath,
|
|
73
|
-
historyLimit: 50000,
|
|
74
74
|
});
|
|
75
75
|
// Wait a moment for the session to be created
|
|
76
76
|
await new Promise((resolve) => setTimeout(resolve, cli_tool_timing_config_1.TUI_SESSION_CREATE_WAIT_MS));
|
|
@@ -15,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.InvalidAgentInstanceError = exports.AgentInstanceLimitError = void 0;
|
|
16
16
|
exports.getAgentInstances = getAgentInstances;
|
|
17
17
|
exports.getAgentInstance = getAgentInstance;
|
|
18
|
+
exports.resolveInstanceCliTool = resolveInstanceCliTool;
|
|
18
19
|
exports.countAgentInstances = countAgentInstances;
|
|
19
20
|
exports.setAgentInstances = setAgentInstances;
|
|
20
21
|
exports.addAgentInstance = addAgentInstance;
|
|
@@ -103,6 +104,58 @@ function getAgentInstance(db, worktreeId, instanceId) {
|
|
|
103
104
|
`).get(worktreeId, instanceId);
|
|
104
105
|
return row ? mapAgentInstance(row) : null;
|
|
105
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Resolve which CLI tool backs a targeted agent instance (Issue #1629).
|
|
109
|
+
*
|
|
110
|
+
* The CLI tool id is part of the tmux session name, so getting it wrong starts
|
|
111
|
+
* (or looks for) the wrong agent under a session name that claims otherwise:
|
|
112
|
+
* `--instance codex` used to start Claude in `mcbd-claude-<wt>-codex`.
|
|
113
|
+
*
|
|
114
|
+
* Resolution order:
|
|
115
|
+
* 1. the roster entry for `instanceId` — the roster is what declares that
|
|
116
|
+
* `codex` is a codex instance, so it wins over the worktree default
|
|
117
|
+
* 2. `requestedCliTool`, for an instance the roster does not know about
|
|
118
|
+
* (the ad-hoc `send --instance <new-id>` / `--register` flow)
|
|
119
|
+
* 3. `instanceId` when it is itself a CLI tool id — that is how the primary
|
|
120
|
+
* instance is anchored (Issue #868), and holds without a roster row
|
|
121
|
+
* 4. no signal (`cliToolId: null`) — the caller falls back to its default
|
|
122
|
+
*
|
|
123
|
+
* An explicit `requestedCliTool` that contradicts the roster is reported as a
|
|
124
|
+
* conflict rather than silently overriding it: the roster is user-maintained
|
|
125
|
+
* and a mismatch means one of the two is wrong. Callers surface it as an error.
|
|
126
|
+
*
|
|
127
|
+
* @param db - Database instance
|
|
128
|
+
* @param worktreeId - Worktree ID
|
|
129
|
+
* @param instanceId - Targeted agent instance ID (omitted for the primary instance)
|
|
130
|
+
* @param requestedCliTool - CLI tool explicitly named by the caller, if any
|
|
131
|
+
*/
|
|
132
|
+
function resolveInstanceCliTool(db, worktreeId, instanceId, requestedCliTool) {
|
|
133
|
+
if (!instanceId) {
|
|
134
|
+
return { ok: true, cliToolId: requestedCliTool ?? null };
|
|
135
|
+
}
|
|
136
|
+
const registered = getAgentInstance(db, worktreeId, instanceId);
|
|
137
|
+
if (registered && (0, types_1.isCliToolType)(registered.cliTool)) {
|
|
138
|
+
if (requestedCliTool && requestedCliTool !== registered.cliTool) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
instanceId,
|
|
142
|
+
rosterCliTool: registered.cliTool,
|
|
143
|
+
requestedCliTool,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return { ok: true, cliToolId: registered.cliTool };
|
|
147
|
+
}
|
|
148
|
+
// Not registered: an instance id that names a CLI tool is that tool's primary
|
|
149
|
+
// instance by definition, which outranks the worktree default but not an
|
|
150
|
+
// explicit request.
|
|
151
|
+
if (requestedCliTool) {
|
|
152
|
+
return { ok: true, cliToolId: requestedCliTool };
|
|
153
|
+
}
|
|
154
|
+
if ((0, types_1.isCliToolType)(instanceId)) {
|
|
155
|
+
return { ok: true, cliToolId: instanceId };
|
|
156
|
+
}
|
|
157
|
+
return { ok: true, cliToolId: null };
|
|
158
|
+
}
|
|
106
159
|
/**
|
|
107
160
|
* Count agent instances for a worktree.
|
|
108
161
|
*/
|
|
@@ -35,6 +35,7 @@ const v48_skill_operations_audit_index_1 = require("./v48-skill-operations-audit
|
|
|
35
35
|
const v49_verification_runs_1 = require("./v49-verification-runs");
|
|
36
36
|
const v50_tasks_1 = require("./v50-tasks");
|
|
37
37
|
const v51_task_events_1 = require("./v51-task-events");
|
|
38
|
+
const v52_orphaned_worktree_children_1 = require("./v52-orphaned-worktree-children");
|
|
38
39
|
/**
|
|
39
40
|
* Complete ordered list of all migrations.
|
|
40
41
|
* Used internally by the barrel file (db-migrations.ts); NOT exported from the barrel (DR2-004).
|
|
@@ -73,4 +74,5 @@ exports.migrations = [
|
|
|
73
74
|
...v49_verification_runs_1.v49_migrations,
|
|
74
75
|
...v50_tasks_1.v50_migrations,
|
|
75
76
|
...v51_task_events_1.v51_migrations,
|
|
77
|
+
...v52_orphaned_worktree_children_1.v52_migrations,
|
|
76
78
|
];
|
|
@@ -17,7 +17,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
17
17
|
* Current schema version
|
|
18
18
|
* Increment this when adding new migrations
|
|
19
19
|
*/
|
|
20
|
-
exports.CURRENT_SCHEMA_VERSION =
|
|
20
|
+
exports.CURRENT_SCHEMA_VERSION = 52;
|
|
21
21
|
/**
|
|
22
22
|
* Get current schema version from database
|
|
23
23
|
*/
|