botmux 2.9.1 → 2.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +140 -76
- package/README.md +134 -75
- package/dist/adapters/backend/pty-backend.d.ts +6 -0
- package/dist/adapters/backend/pty-backend.d.ts.map +1 -1
- package/dist/adapters/backend/pty-backend.js +10 -0
- package/dist/adapters/backend/pty-backend.js.map +1 -1
- package/dist/adapters/backend/session-backend-selector.d.ts +11 -0
- package/dist/adapters/backend/session-backend-selector.d.ts.map +1 -0
- package/dist/adapters/backend/session-backend-selector.js +26 -0
- package/dist/adapters/backend/session-backend-selector.js.map +1 -0
- package/dist/adapters/backend/tmux-backend.d.ts +80 -3
- package/dist/adapters/backend/tmux-backend.d.ts.map +1 -1
- package/dist/adapters/backend/tmux-backend.js +301 -49
- package/dist/adapters/backend/tmux-backend.js.map +1 -1
- package/dist/adapters/backend/tmux-pipe-backend.d.ts +100 -0
- package/dist/adapters/backend/tmux-pipe-backend.d.ts.map +1 -0
- package/dist/adapters/backend/tmux-pipe-backend.js +473 -0
- package/dist/adapters/backend/tmux-pipe-backend.js.map +1 -0
- package/dist/adapters/cli/aiden.d.ts.map +1 -1
- package/dist/adapters/cli/aiden.js +5 -0
- package/dist/adapters/cli/aiden.js.map +1 -1
- package/dist/adapters/cli/claude-code.d.ts +40 -1
- package/dist/adapters/cli/claude-code.d.ts.map +1 -1
- package/dist/adapters/cli/claude-code.js +470 -49
- package/dist/adapters/cli/claude-code.js.map +1 -1
- package/dist/adapters/cli/coco.d.ts.map +1 -1
- package/dist/adapters/cli/coco.js +191 -9
- package/dist/adapters/cli/coco.js.map +1 -1
- package/dist/adapters/cli/codex.d.ts.map +1 -1
- package/dist/adapters/cli/codex.js +94 -17
- package/dist/adapters/cli/codex.js.map +1 -1
- package/dist/adapters/cli/shared-hints.d.ts +2 -2
- package/dist/adapters/cli/shared-hints.d.ts.map +1 -1
- package/dist/adapters/cli/shared-hints.js +7 -5
- package/dist/adapters/cli/shared-hints.js.map +1 -1
- package/dist/adapters/cli/types.d.ts +38 -1
- package/dist/adapters/cli/types.d.ts.map +1 -1
- package/dist/autostart.d.ts +14 -0
- package/dist/autostart.d.ts.map +1 -0
- package/dist/autostart.js +357 -0
- package/dist/autostart.js.map +1 -0
- package/dist/bot-registry.d.ts +29 -3
- package/dist/bot-registry.d.ts.map +1 -1
- package/dist/bot-registry.js +91 -12
- package/dist/bot-registry.js.map +1 -1
- package/dist/cli/arg-utils.d.ts +11 -0
- package/dist/cli/arg-utils.d.ts.map +1 -0
- package/dist/cli/arg-utils.js +25 -0
- package/dist/cli/arg-utils.js.map +1 -0
- package/dist/cli/create-group-resolver.d.ts +32 -0
- package/dist/cli/create-group-resolver.d.ts.map +1 -0
- package/dist/cli/create-group-resolver.js +70 -0
- package/dist/cli/create-group-resolver.js.map +1 -0
- package/dist/cli/quoted-render.d.ts +30 -0
- package/dist/cli/quoted-render.d.ts.map +1 -0
- package/dist/cli/quoted-render.js +29 -0
- package/dist/cli/quoted-render.js.map +1 -0
- package/dist/cli.js +916 -272
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -8
- package/dist/config.js.map +1 -1
- package/dist/core/command-handler.d.ts +43 -0
- package/dist/core/command-handler.d.ts.map +1 -1
- package/dist/core/command-handler.js +167 -64
- package/dist/core/command-handler.js.map +1 -1
- package/dist/core/dashboard-events.d.ts +57 -0
- package/dist/core/dashboard-events.d.ts.map +1 -0
- package/dist/core/dashboard-events.js +23 -0
- package/dist/core/dashboard-events.js.map +1 -0
- package/dist/core/dashboard-ipc-server.d.ts +43 -0
- package/dist/core/dashboard-ipc-server.d.ts.map +1 -0
- package/dist/core/dashboard-ipc-server.js +481 -0
- package/dist/core/dashboard-ipc-server.js.map +1 -0
- package/dist/core/dashboard-locate.d.ts +20 -0
- package/dist/core/dashboard-locate.d.ts.map +1 -0
- package/dist/core/dashboard-locate.js +26 -0
- package/dist/core/dashboard-locate.js.map +1 -0
- package/dist/core/dashboard-rows.d.ts +31 -0
- package/dist/core/dashboard-rows.d.ts.map +1 -0
- package/dist/core/dashboard-rows.js +65 -0
- package/dist/core/dashboard-rows.js.map +1 -0
- package/dist/core/inherit-peer.d.ts +14 -0
- package/dist/core/inherit-peer.d.ts.map +1 -0
- package/dist/core/inherit-peer.js +32 -0
- package/dist/core/inherit-peer.js.map +1 -0
- package/dist/core/scheduler.d.ts +24 -0
- package/dist/core/scheduler.d.ts.map +1 -1
- package/dist/core/scheduler.js +93 -2
- package/dist/core/scheduler.js.map +1 -1
- package/dist/core/session-activity.d.ts +3 -0
- package/dist/core/session-activity.d.ts.map +1 -0
- package/dist/core/session-activity.js +20 -0
- package/dist/core/session-activity.js.map +1 -0
- package/dist/core/session-discovery.d.ts +39 -0
- package/dist/core/session-discovery.d.ts.map +1 -1
- package/dist/core/session-discovery.js +114 -21
- package/dist/core/session-discovery.js.map +1 -1
- package/dist/core/session-manager.d.ts +72 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +396 -106
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/types.d.ts +27 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +14 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/worker-pool.d.ts +72 -3
- package/dist/core/worker-pool.d.ts.map +1 -1
- package/dist/core/worker-pool.js +459 -38
- package/dist/core/worker-pool.js.map +1 -1
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +645 -314
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard/aggregator.d.ts +41 -0
- package/dist/dashboard/aggregator.d.ts.map +1 -0
- package/dist/dashboard/aggregator.js +125 -0
- package/dist/dashboard/aggregator.js.map +1 -0
- package/dist/dashboard/auth.d.ts +23 -0
- package/dist/dashboard/auth.d.ts.map +1 -0
- package/dist/dashboard/auth.js +66 -0
- package/dist/dashboard/auth.js.map +1 -0
- package/dist/dashboard/operator-selector.d.ts +20 -0
- package/dist/dashboard/operator-selector.d.ts.map +1 -0
- package/dist/dashboard/operator-selector.js +39 -0
- package/dist/dashboard/operator-selector.js.map +1 -0
- package/dist/dashboard/registry.d.ts +35 -0
- package/dist/dashboard/registry.d.ts.map +1 -0
- package/dist/dashboard/registry.js +74 -0
- package/dist/dashboard/registry.js.map +1 -0
- package/dist/dashboard/web/app.d.ts +2 -0
- package/dist/dashboard/web/app.d.ts.map +1 -0
- package/dist/dashboard/web/app.js +45 -0
- package/dist/dashboard/web/app.js.map +1 -0
- package/dist/dashboard/web/bot-defaults.d.ts +2 -0
- package/dist/dashboard/web/bot-defaults.d.ts.map +1 -0
- package/dist/dashboard/web/bot-defaults.js +201 -0
- package/dist/dashboard/web/bot-defaults.js.map +1 -0
- package/dist/dashboard/web/groups.d.ts +16 -0
- package/dist/dashboard/web/groups.d.ts.map +1 -0
- package/dist/dashboard/web/groups.js +584 -0
- package/dist/dashboard/web/groups.js.map +1 -0
- package/dist/dashboard/web/schedules.d.ts +2 -0
- package/dist/dashboard/web/schedules.d.ts.map +1 -0
- package/dist/dashboard/web/schedules.js +105 -0
- package/dist/dashboard/web/schedules.js.map +1 -0
- package/dist/dashboard/web/sessions.d.ts +2 -0
- package/dist/dashboard/web/sessions.d.ts.map +1 -0
- package/dist/dashboard/web/sessions.js +374 -0
- package/dist/dashboard/web/sessions.js.map +1 -0
- package/dist/dashboard/web/store.d.ts +23 -0
- package/dist/dashboard/web/store.d.ts.map +1 -0
- package/dist/dashboard/web/store.js +82 -0
- package/dist/dashboard/web/store.js.map +1 -0
- package/dist/dashboard-web/app.js +263 -0
- package/dist/dashboard-web/index.html +23 -0
- package/dist/dashboard-web/style.css +93 -0
- package/dist/dashboard.d.ts +2 -0
- package/dist/dashboard.d.ts.map +1 -0
- package/dist/dashboard.js +639 -0
- package/dist/dashboard.js.map +1 -0
- package/dist/im/lark/card-builder.d.ts +18 -1
- package/dist/im/lark/card-builder.d.ts.map +1 -1
- package/dist/im/lark/card-builder.js +70 -9
- package/dist/im/lark/card-builder.js.map +1 -1
- package/dist/im/lark/card-handler.d.ts.map +1 -1
- package/dist/im/lark/card-handler.js +123 -109
- package/dist/im/lark/card-handler.js.map +1 -1
- package/dist/im/lark/client.d.ts +35 -0
- package/dist/im/lark/client.d.ts.map +1 -1
- package/dist/im/lark/client.js +114 -11
- package/dist/im/lark/client.js.map +1 -1
- package/dist/im/lark/event-dispatcher.d.ts +88 -6
- package/dist/im/lark/event-dispatcher.d.ts.map +1 -1
- package/dist/im/lark/event-dispatcher.js +398 -62
- package/dist/im/lark/event-dispatcher.js.map +1 -1
- package/dist/im/lark/forwarded-renderer.d.ts +23 -0
- package/dist/im/lark/forwarded-renderer.d.ts.map +1 -0
- package/dist/im/lark/forwarded-renderer.js +105 -0
- package/dist/im/lark/forwarded-renderer.js.map +1 -0
- package/dist/im/lark/md-card.d.ts +73 -0
- package/dist/im/lark/md-card.d.ts.map +1 -0
- package/dist/im/lark/md-card.js +332 -0
- package/dist/im/lark/md-card.js.map +1 -0
- package/dist/im/lark/merge-forward.d.ts +32 -0
- package/dist/im/lark/merge-forward.d.ts.map +1 -0
- package/dist/im/lark/merge-forward.js +110 -0
- package/dist/im/lark/merge-forward.js.map +1 -0
- package/dist/im/lark/message-parser.d.ts +9 -3
- package/dist/im/lark/message-parser.d.ts.map +1 -1
- package/dist/im/lark/message-parser.js +48 -13
- package/dist/im/lark/message-parser.js.map +1 -1
- package/dist/im/lark/quote-hint.d.ts +18 -0
- package/dist/im/lark/quote-hint.d.ts.map +1 -0
- package/dist/im/lark/quote-hint.js +23 -0
- package/dist/im/lark/quote-hint.js.map +1 -0
- package/dist/services/bridge-fallback-gate.d.ts +42 -0
- package/dist/services/bridge-fallback-gate.d.ts.map +1 -0
- package/dist/services/bridge-fallback-gate.js +12 -0
- package/dist/services/bridge-fallback-gate.js.map +1 -0
- package/dist/services/bridge-rotation-policy.d.ts +139 -0
- package/dist/services/bridge-rotation-policy.d.ts.map +1 -0
- package/dist/services/bridge-rotation-policy.js +125 -0
- package/dist/services/bridge-rotation-policy.js.map +1 -0
- package/dist/services/bridge-turn-queue.d.ts +154 -0
- package/dist/services/bridge-turn-queue.d.ts.map +1 -0
- package/dist/services/bridge-turn-queue.js +316 -0
- package/dist/services/bridge-turn-queue.js.map +1 -0
- package/dist/services/chat-first-seen-store.d.ts +27 -0
- package/dist/services/chat-first-seen-store.d.ts.map +1 -0
- package/dist/services/chat-first-seen-store.js +114 -0
- package/dist/services/chat-first-seen-store.js.map +1 -0
- package/dist/services/claude-transcript.d.ts +268 -0
- package/dist/services/claude-transcript.d.ts.map +1 -0
- package/dist/services/claude-transcript.js +798 -0
- package/dist/services/claude-transcript.js.map +1 -0
- package/dist/services/coco-transcript.d.ts +35 -0
- package/dist/services/coco-transcript.d.ts.map +1 -0
- package/dist/services/coco-transcript.js +192 -0
- package/dist/services/coco-transcript.js.map +1 -0
- package/dist/services/codex-bridge-queue.d.ts +56 -0
- package/dist/services/codex-bridge-queue.d.ts.map +1 -0
- package/dist/services/codex-bridge-queue.js +150 -0
- package/dist/services/codex-bridge-queue.js.map +1 -0
- package/dist/services/codex-transcript.d.ts +84 -0
- package/dist/services/codex-transcript.d.ts.map +1 -0
- package/dist/services/codex-transcript.js +298 -0
- package/dist/services/codex-transcript.js.map +1 -0
- package/dist/services/group-creator.d.ts +23 -0
- package/dist/services/group-creator.d.ts.map +1 -0
- package/dist/services/group-creator.js +75 -0
- package/dist/services/group-creator.js.map +1 -0
- package/dist/services/groups-store.d.ts +98 -0
- package/dist/services/groups-store.d.ts.map +1 -0
- package/dist/services/groups-store.js +213 -0
- package/dist/services/groups-store.js.map +1 -0
- package/dist/services/oncall-store.d.ts +80 -8
- package/dist/services/oncall-store.d.ts.map +1 -1
- package/dist/services/oncall-store.js +265 -55
- package/dist/services/oncall-store.js.map +1 -1
- package/dist/services/project-scanner.d.ts +1 -2
- package/dist/services/project-scanner.d.ts.map +1 -1
- package/dist/services/project-scanner.js +118 -68
- package/dist/services/project-scanner.js.map +1 -1
- package/dist/services/schedule-store.d.ts +5 -0
- package/dist/services/schedule-store.d.ts.map +1 -1
- package/dist/services/schedule-store.js +77 -1
- package/dist/services/schedule-store.js.map +1 -1
- package/dist/services/session-store.d.ts +22 -0
- package/dist/services/session-store.d.ts.map +1 -1
- package/dist/services/session-store.js +62 -4
- package/dist/services/session-store.js.map +1 -1
- package/dist/setup/bots-store.d.ts +3 -0
- package/dist/setup/bots-store.d.ts.map +1 -0
- package/dist/setup/bots-store.js +24 -0
- package/dist/setup/bots-store.js.map +1 -0
- package/dist/setup/detect-platform.d.ts +14 -0
- package/dist/setup/detect-platform.d.ts.map +1 -0
- package/dist/setup/detect-platform.js +139 -0
- package/dist/setup/detect-platform.js.map +1 -0
- package/dist/setup/ensure-fonts.d.ts +13 -0
- package/dist/setup/ensure-fonts.d.ts.map +1 -0
- package/dist/setup/ensure-fonts.js +225 -0
- package/dist/setup/ensure-fonts.js.map +1 -0
- package/dist/setup/ensure-tmux.d.ts +60 -0
- package/dist/setup/ensure-tmux.d.ts.map +1 -0
- package/dist/setup/ensure-tmux.js +236 -0
- package/dist/setup/ensure-tmux.js.map +1 -0
- package/dist/setup/index.d.ts +9 -0
- package/dist/setup/index.d.ts.map +1 -0
- package/dist/setup/index.js +46 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/lark-scopes.json +301 -0
- package/dist/setup/register-app.d.ts +52 -0
- package/dist/setup/register-app.d.ts.map +1 -0
- package/dist/setup/register-app.js +91 -0
- package/dist/setup/register-app.js.map +1 -0
- package/dist/setup/verify-permissions.d.ts +115 -0
- package/dist/setup/verify-permissions.d.ts.map +1 -0
- package/dist/setup/verify-permissions.js +207 -0
- package/dist/setup/verify-permissions.js.map +1 -0
- package/dist/skills/definitions.d.ts +4 -0
- package/dist/skills/definitions.d.ts.map +1 -1
- package/dist/skills/definitions.js +133 -19
- package/dist/skills/definitions.js.map +1 -1
- package/dist/skills/installer.d.ts +3 -1
- package/dist/skills/installer.d.ts.map +1 -1
- package/dist/skills/installer.js +18 -3
- package/dist/skills/installer.js.map +1 -1
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/bot-routing.d.ts +6 -0
- package/dist/utils/bot-routing.d.ts.map +1 -0
- package/dist/utils/bot-routing.js +50 -0
- package/dist/utils/bot-routing.js.map +1 -0
- package/dist/utils/file-lock.d.ts +2 -0
- package/dist/utils/file-lock.d.ts.map +1 -0
- package/dist/utils/file-lock.js +114 -0
- package/dist/utils/file-lock.js.map +1 -0
- package/dist/utils/font-installer.js +1 -1
- package/dist/utils/font-installer.js.map +1 -1
- package/dist/utils/idle-detector.d.ts +6 -0
- package/dist/utils/idle-detector.d.ts.map +1 -1
- package/dist/utils/idle-detector.js +25 -4
- package/dist/utils/idle-detector.js.map +1 -1
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +60 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/render-dimensions.d.ts +48 -0
- package/dist/utils/render-dimensions.d.ts.map +1 -0
- package/dist/utils/render-dimensions.js +55 -0
- package/dist/utils/render-dimensions.js.map +1 -0
- package/dist/utils/screen-analyzer.d.ts.map +1 -1
- package/dist/utils/screen-analyzer.js +24 -0
- package/dist/utils/screen-analyzer.js.map +1 -1
- package/dist/utils/screenshot-renderer.d.ts.map +1 -1
- package/dist/utils/screenshot-renderer.js +67 -23
- package/dist/utils/screenshot-renderer.js.map +1 -1
- package/dist/utils/terminal-renderer.d.ts +16 -0
- package/dist/utils/terminal-renderer.d.ts.map +1 -1
- package/dist/utils/terminal-renderer.js +40 -23
- package/dist/utils/terminal-renderer.js.map +1 -1
- package/dist/utils/transient-snapshot.d.ts +28 -0
- package/dist/utils/transient-snapshot.d.ts.map +1 -0
- package/dist/utils/transient-snapshot.js +96 -0
- package/dist/utils/transient-snapshot.js.map +1 -0
- package/dist/worker.js +2248 -83
- package/dist/worker.js.map +1 -1
- package/package.json +12 -5
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { SessionBackend, SpawnOpts } from './types.js';
|
|
2
|
+
/** Convert `\n` to `\r\n` while leaving existing `\r\n` alone. Exported for
|
|
3
|
+
* unit tests; used to normalise tmux capture-pane output before sending it
|
|
4
|
+
* to xterm.js (which treats bare LF as "down one row, keep column"). */
|
|
5
|
+
export declare function normaliseCaptureLineEndings(s: string): string;
|
|
6
|
+
export declare class TmuxPipeBackend implements SessionBackend {
|
|
7
|
+
/** Real tmux pane address (e.g. "0:2.0") or botmux session name (bmx-*). */
|
|
8
|
+
private readonly paneTarget;
|
|
9
|
+
private readonly fifoPath;
|
|
10
|
+
private readStream;
|
|
11
|
+
private readonly dataCbs;
|
|
12
|
+
private readonly exitCbs;
|
|
13
|
+
private lifecycleTimer;
|
|
14
|
+
private cols;
|
|
15
|
+
private rows;
|
|
16
|
+
private exited;
|
|
17
|
+
/** Set after pipe-pane subscription is active so kill() knows to cancel it. */
|
|
18
|
+
private pipeAttached;
|
|
19
|
+
private readonly createSession;
|
|
20
|
+
private readonly ownsSession;
|
|
21
|
+
private readonly _isReattach;
|
|
22
|
+
/** Claude Code session JSONL path — set by worker for claude-code sessions so
|
|
23
|
+
* the claude-code adapter can verify paste+Enter submissions via file growth. */
|
|
24
|
+
claudeJsonlPath?: string;
|
|
25
|
+
/** PID of the spawned Claude Code child — used by the claude-code adapter to
|
|
26
|
+
* follow Claude's authoritative session id via ~/.claude/sessions/<pid>.json. */
|
|
27
|
+
cliPid?: number;
|
|
28
|
+
/** Working directory the CLI was spawned in — cross-checked against the pid
|
|
29
|
+
* file's cwd field so a recycled PID can't mislead the resolver. */
|
|
30
|
+
cliCwd?: string;
|
|
31
|
+
/** Whether this backend re-attached to an existing bmx-* tmux session
|
|
32
|
+
* (rather than creating a new detached one). Mirrors TmuxBackend.isReattach
|
|
33
|
+
* so the worker can branch on reattach behaviour without a private-cast. */
|
|
34
|
+
get isReattach(): boolean;
|
|
35
|
+
constructor(paneTarget: string, opts?: {
|
|
36
|
+
createSession?: boolean;
|
|
37
|
+
ownsSession?: boolean;
|
|
38
|
+
isReattach?: boolean;
|
|
39
|
+
});
|
|
40
|
+
/** spawn() sets up the pipe-pane subscription + fifo reader. In managed
|
|
41
|
+
* mode it first creates a detached bmx-* tmux session that runs the CLI. */
|
|
42
|
+
spawn(bin: string, args: string[], opts: SpawnOpts): void;
|
|
43
|
+
write(data: string): void;
|
|
44
|
+
sendText(text: string): void;
|
|
45
|
+
sendSpecialKeys(...keys: string[]): void;
|
|
46
|
+
pasteText(text: string): void;
|
|
47
|
+
private exitCopyModeIfNeeded;
|
|
48
|
+
enterCopyMode(): void;
|
|
49
|
+
sendCopyModeCommand(xCommand: string): void;
|
|
50
|
+
resize(cols: number, rows: number): void;
|
|
51
|
+
onData(cb: (data: string) => void): void;
|
|
52
|
+
onExit(cb: (code: number | null, signal: string | null) => void): void;
|
|
53
|
+
kill(): void;
|
|
54
|
+
destroySession(): void;
|
|
55
|
+
getChildPid(): number | null;
|
|
56
|
+
getAttachInfo(): null;
|
|
57
|
+
private startLifecycleWatcher;
|
|
58
|
+
private stopLifecycleWatcher;
|
|
59
|
+
private handlePaneExit;
|
|
60
|
+
private createDetachedSession;
|
|
61
|
+
private applySessionOptions;
|
|
62
|
+
/** Snapshot the full pane history WITH ANSI escapes (`-S - -E -`).
|
|
63
|
+
*
|
|
64
|
+
* Used by web reattach so a brand-new web client sees the whole prior
|
|
65
|
+
* conversation. For the screenshot / screen_update fast path use
|
|
66
|
+
* `captureViewport()` instead — that one only returns the visible pane
|
|
67
|
+
* and is safe to seed a transient xterm-headless with.
|
|
68
|
+
*
|
|
69
|
+
* IMPORTANT: tmux capture-pane separates rows with bare `\n`, no `\r`.
|
|
70
|
+
* xterm.js (and any VT100-compliant emulator) treats a bare LF as
|
|
71
|
+
* "move down one row, keep column" — every captured line lands further
|
|
72
|
+
* to the right than the previous one. Normalising every `\n` to `\r\n`
|
|
73
|
+
* makes the snapshot render correctly. The live pipe-pane stream itself
|
|
74
|
+
* doesn't need this fix — applications write proper `\r\n`. */
|
|
75
|
+
captureCurrentScreen(): string;
|
|
76
|
+
/** Snapshot ONLY the currently visible pane (no scrollback). Equivalent to
|
|
77
|
+
* `tmux capture-pane` with no `-S`/`-E` flags, which defaults to the
|
|
78
|
+
* viewport. This is the right input for a transient xterm-headless seed:
|
|
79
|
+
* the snapshot row count matches the transient terminal's row count, so
|
|
80
|
+
* no normal-buffer scroll happens and the rendered screenshot lines up
|
|
81
|
+
* with what the user is seeing in the web terminal right now. */
|
|
82
|
+
captureViewport(): string;
|
|
83
|
+
private captureWithBounds;
|
|
84
|
+
/** Current real tmux pane dimensions. Drives transient-renderer sizing so
|
|
85
|
+
* the screenshot canvas matches whatever the web client resized the pane
|
|
86
|
+
* to. Returns null if tmux can't be queried (pane gone, server gone). */
|
|
87
|
+
getPaneSize(): {
|
|
88
|
+
cols: number;
|
|
89
|
+
rows: number;
|
|
90
|
+
} | null;
|
|
91
|
+
/** Cheap probe: is the adopted pane currently in the alternate screen
|
|
92
|
+
* buffer? Used by captureCurrentScreen to decide whether the snapshot
|
|
93
|
+
* needs an alt-buffer-enter prefix for correct rendering. */
|
|
94
|
+
private isPaneInAltBuffer;
|
|
95
|
+
/** True if the underlying pane is still addressable in tmux. Cheap check —
|
|
96
|
+
* used by callers to detect "user closed the pane while we were piping". */
|
|
97
|
+
isPaneAlive(): boolean;
|
|
98
|
+
private fireExit;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=tmux-pipe-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-pipe-backend.d.ts","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-pipe-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TmuxPipeBackend — observe a user-owned tmux pane WITHOUT attaching to its
|
|
3
|
+
* session. Used by /adopt mode to avoid the renderer conflict that arises
|
|
4
|
+
* when a normal `tmux attach-session` client coexists with a tmux -CC
|
|
5
|
+
* (iTerm2 control mode) client on the same server (interleaved ANSI vs
|
|
6
|
+
* control-protocol writes corrupt cursor / status-bar / alt-screen state).
|
|
7
|
+
*
|
|
8
|
+
* Architecture (no PTY, no attach):
|
|
9
|
+
* - mkfifo a unique fifo under /tmp
|
|
10
|
+
* - `tmux pipe-pane -O -t <pane> 'cat > <fifo>'` — tmux replicates every
|
|
11
|
+
* byte the pane writes into the fifo (append-only, '-O' overwrites any
|
|
12
|
+
* existing pipe).
|
|
13
|
+
* - fs.createReadStream(<fifo>) — we read tmux's verbatim ANSI stream.
|
|
14
|
+
* - All writes (sendText / sendSpecialKeys / pasteText / copy-mode keys)
|
|
15
|
+
* go through `tmux send-keys / paste-buffer -t <pane>` — so the pane's
|
|
16
|
+
* real address ("0:2.0") is the addressing target, not a synthetic
|
|
17
|
+
* session name.
|
|
18
|
+
* - `tmux capture-pane -e -p -t <pane> -S -` returns the current screen
|
|
19
|
+
* with ANSI; the worker uses it to seed new web-terminal connections
|
|
20
|
+
* so they don't start from a blank screen.
|
|
21
|
+
*
|
|
22
|
+
* The user's source session is never attached, never zoomed, never
|
|
23
|
+
* grouped — fully zero-touch from tmux's perspective beyond the pipe-pane
|
|
24
|
+
* subscription, which is automatically detached when we kill the backend.
|
|
25
|
+
*/
|
|
26
|
+
import * as fs from 'node:fs';
|
|
27
|
+
import { execSync, execFileSync, spawnSync } from 'node:child_process';
|
|
28
|
+
import { tmpdir } from 'node:os';
|
|
29
|
+
import { join } from 'node:path';
|
|
30
|
+
import { randomBytes } from 'node:crypto';
|
|
31
|
+
import { tmuxEnv } from '../../setup/ensure-tmux.js';
|
|
32
|
+
import { buildBotmuxEnvAssignments, resolveUserShell, SHELL_WRAPPER_SCRIPT, TmuxBackend } from './tmux-backend.js';
|
|
33
|
+
function shellescape(s) {
|
|
34
|
+
// Single-quote-escape, replacing internal ' with '\''
|
|
35
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
36
|
+
}
|
|
37
|
+
/** Convert `\n` to `\r\n` while leaving existing `\r\n` alone. Exported for
|
|
38
|
+
* unit tests; used to normalise tmux capture-pane output before sending it
|
|
39
|
+
* to xterm.js (which treats bare LF as "down one row, keep column"). */
|
|
40
|
+
export function normaliseCaptureLineEndings(s) {
|
|
41
|
+
return s.replace(/\r?\n/g, '\r\n');
|
|
42
|
+
}
|
|
43
|
+
export class TmuxPipeBackend {
|
|
44
|
+
/** Real tmux pane address (e.g. "0:2.0") or botmux session name (bmx-*). */
|
|
45
|
+
paneTarget;
|
|
46
|
+
fifoPath;
|
|
47
|
+
readStream = null;
|
|
48
|
+
dataCbs = [];
|
|
49
|
+
exitCbs = [];
|
|
50
|
+
lifecycleTimer = null;
|
|
51
|
+
cols = 200;
|
|
52
|
+
rows = 50;
|
|
53
|
+
exited = false;
|
|
54
|
+
/** Set after pipe-pane subscription is active so kill() knows to cancel it. */
|
|
55
|
+
pipeAttached = false;
|
|
56
|
+
createSession;
|
|
57
|
+
ownsSession;
|
|
58
|
+
_isReattach;
|
|
59
|
+
/** Claude Code session JSONL path — set by worker for claude-code sessions so
|
|
60
|
+
* the claude-code adapter can verify paste+Enter submissions via file growth. */
|
|
61
|
+
claudeJsonlPath;
|
|
62
|
+
/** PID of the spawned Claude Code child — used by the claude-code adapter to
|
|
63
|
+
* follow Claude's authoritative session id via ~/.claude/sessions/<pid>.json. */
|
|
64
|
+
cliPid;
|
|
65
|
+
/** Working directory the CLI was spawned in — cross-checked against the pid
|
|
66
|
+
* file's cwd field so a recycled PID can't mislead the resolver. */
|
|
67
|
+
cliCwd;
|
|
68
|
+
/** Whether this backend re-attached to an existing bmx-* tmux session
|
|
69
|
+
* (rather than creating a new detached one). Mirrors TmuxBackend.isReattach
|
|
70
|
+
* so the worker can branch on reattach behaviour without a private-cast. */
|
|
71
|
+
get isReattach() {
|
|
72
|
+
return this._isReattach;
|
|
73
|
+
}
|
|
74
|
+
constructor(paneTarget, opts) {
|
|
75
|
+
this.paneTarget = paneTarget;
|
|
76
|
+
this.createSession = opts?.createSession ?? false;
|
|
77
|
+
this.ownsSession = opts?.ownsSession ?? false;
|
|
78
|
+
this._isReattach = opts?.isReattach ?? false;
|
|
79
|
+
// Per-instance fifo so concurrent adopt sessions don't collide.
|
|
80
|
+
this.fifoPath = join(tmpdir(), `botmux-pipe-${randomBytes(8).toString('hex')}.fifo`);
|
|
81
|
+
}
|
|
82
|
+
// ─── SessionBackend implementation ────────────────────────────────────────
|
|
83
|
+
/** spawn() sets up the pipe-pane subscription + fifo reader. In managed
|
|
84
|
+
* mode it first creates a detached bmx-* tmux session that runs the CLI. */
|
|
85
|
+
spawn(bin, args, opts) {
|
|
86
|
+
this.cols = opts.cols;
|
|
87
|
+
this.rows = opts.rows;
|
|
88
|
+
if (this.createSession) {
|
|
89
|
+
this.createDetachedSession(bin, args, opts);
|
|
90
|
+
}
|
|
91
|
+
else if (this.ownsSession && this._isReattach) {
|
|
92
|
+
// Backfill tmux options on an existing bmx-* session — daemon may have
|
|
93
|
+
// been upgraded since the session was originally created, and options
|
|
94
|
+
// like set-clipboard / window-size largest are idempotent to re-apply.
|
|
95
|
+
this.applySessionOptions();
|
|
96
|
+
}
|
|
97
|
+
// Step 1: create the fifo. mkfifo is POSIX; linux/darwin both have it.
|
|
98
|
+
spawnSync('mkfifo', [this.fifoPath], { stdio: 'ignore' });
|
|
99
|
+
// Step 2: open the read end with O_RDWR (no O_NONBLOCK).
|
|
100
|
+
//
|
|
101
|
+
// Why O_RDWR? Avoids the fifo open chicken-and-egg: opening O_RDONLY
|
|
102
|
+
// alone blocks until a writer arrives, opening O_WRONLY alone blocks
|
|
103
|
+
// until a reader arrives. Holding both ends ourselves makes either
|
|
104
|
+
// peer's open() return immediately.
|
|
105
|
+
//
|
|
106
|
+
// Why NOT O_NONBLOCK? libuv's ReadStream issues blocking read() calls
|
|
107
|
+
// from its threadpool — that's how it stays responsive without
|
|
108
|
+
// burning CPU. With O_NONBLOCK the very first read() on an empty
|
|
109
|
+
// fifo returns EAGAIN, which libuv surfaces as an error, and the
|
|
110
|
+
// stream dies before tmux ever gets a chance to write a byte. (This
|
|
111
|
+
// exact bug ate the bridge final_output pipeline on first ship: an
|
|
112
|
+
// strace showed worker only read its IPC fd, never the fifo.)
|
|
113
|
+
const fd = fs.openSync(this.fifoPath, fs.constants.O_RDWR);
|
|
114
|
+
this.readStream = fs.createReadStream('', { fd, autoClose: false, highWaterMark: 64 * 1024 });
|
|
115
|
+
this.readStream.on('data', (chunk) => {
|
|
116
|
+
const data = typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
117
|
+
for (const cb of this.dataCbs) {
|
|
118
|
+
try {
|
|
119
|
+
cb(data);
|
|
120
|
+
}
|
|
121
|
+
catch { /* listener crash shouldn't kill the stream */ }
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
this.readStream.on('error', (err) => {
|
|
125
|
+
// Errors are best-effort logged via the worker's stderr (we can't
|
|
126
|
+
// pull a logger in a backend without circular imports). Don't fire
|
|
127
|
+
// exit — the user's CLI is still alive, we just lost realtime view.
|
|
128
|
+
process.stderr.write(`[tmux-pipe-backend] read error: ${err?.message ?? err}\n`);
|
|
129
|
+
});
|
|
130
|
+
// Step 3: ask tmux to replicate the pane's bytes into our fifo.
|
|
131
|
+
// -O causes tmux to overwrite any prior pipe-pane subscription.
|
|
132
|
+
// The shell command must redirect to the fifo; tmux runs it via /bin/sh.
|
|
133
|
+
try {
|
|
134
|
+
execSync(`tmux pipe-pane -O -t ${shellescape(this.paneTarget)} 'cat > ${shellescape(this.fifoPath)}'`, { stdio: 'ignore', timeout: 5000, env: tmuxEnv() });
|
|
135
|
+
this.pipeAttached = true;
|
|
136
|
+
this.startLifecycleWatcher();
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
this.fireExit(1, null);
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
write(data) {
|
|
144
|
+
// No PTY to write to — interpret as a literal send-keys.
|
|
145
|
+
this.sendText(data);
|
|
146
|
+
}
|
|
147
|
+
sendText(text) {
|
|
148
|
+
if (this.exited)
|
|
149
|
+
return;
|
|
150
|
+
this.exitCopyModeIfNeeded();
|
|
151
|
+
execFileSync('tmux', ['send-keys', '-t', this.paneTarget, '-l', '--', text], {
|
|
152
|
+
stdio: 'ignore',
|
|
153
|
+
timeout: 5000,
|
|
154
|
+
env: tmuxEnv(),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
sendSpecialKeys(...keys) {
|
|
158
|
+
if (this.exited)
|
|
159
|
+
return;
|
|
160
|
+
this.exitCopyModeIfNeeded();
|
|
161
|
+
execFileSync('tmux', ['send-keys', '-t', this.paneTarget, ...keys], {
|
|
162
|
+
stdio: 'ignore',
|
|
163
|
+
timeout: 5000,
|
|
164
|
+
env: tmuxEnv(),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
pasteText(text) {
|
|
168
|
+
if (this.exited)
|
|
169
|
+
return;
|
|
170
|
+
this.exitCopyModeIfNeeded();
|
|
171
|
+
execFileSync('tmux', ['load-buffer', '-'], {
|
|
172
|
+
input: text,
|
|
173
|
+
stdio: ['pipe', 'ignore', 'ignore'],
|
|
174
|
+
timeout: 5000,
|
|
175
|
+
env: tmuxEnv(),
|
|
176
|
+
});
|
|
177
|
+
execFileSync('tmux', ['paste-buffer', '-t', this.paneTarget, '-d'], {
|
|
178
|
+
stdio: 'ignore',
|
|
179
|
+
timeout: 5000,
|
|
180
|
+
env: tmuxEnv(),
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
exitCopyModeIfNeeded() {
|
|
184
|
+
if (this.exited)
|
|
185
|
+
return;
|
|
186
|
+
try {
|
|
187
|
+
const inMode = execFileSync('tmux', ['display-message', '-p', '-t', this.paneTarget, '#{pane_in_mode}'], {
|
|
188
|
+
encoding: 'utf-8',
|
|
189
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
190
|
+
timeout: 1000,
|
|
191
|
+
env: tmuxEnv(),
|
|
192
|
+
}).trim();
|
|
193
|
+
if (inMode === '1') {
|
|
194
|
+
execFileSync('tmux', ['send-keys', '-t', this.paneTarget, '-X', 'cancel'], {
|
|
195
|
+
stdio: 'ignore',
|
|
196
|
+
timeout: 1000,
|
|
197
|
+
env: tmuxEnv(),
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// Pane may be gone or tmux may be restarting; keep the original write path best-effort.
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
enterCopyMode() {
|
|
206
|
+
if (this.exited)
|
|
207
|
+
return;
|
|
208
|
+
execFileSync('tmux', ['copy-mode', '-e', '-t', this.paneTarget], {
|
|
209
|
+
stdio: 'ignore',
|
|
210
|
+
timeout: 5000,
|
|
211
|
+
env: tmuxEnv(),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
sendCopyModeCommand(xCommand) {
|
|
215
|
+
if (this.exited)
|
|
216
|
+
return;
|
|
217
|
+
execFileSync('tmux', ['send-keys', '-t', this.paneTarget, '-X', xCommand], {
|
|
218
|
+
stdio: 'ignore',
|
|
219
|
+
timeout: 5000,
|
|
220
|
+
env: tmuxEnv(),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
resize(cols, rows) {
|
|
224
|
+
this.cols = cols;
|
|
225
|
+
this.rows = rows;
|
|
226
|
+
if (this.ownsSession) {
|
|
227
|
+
execFileSync('tmux', ['resize-window', '-t', this.paneTarget, '-x', String(cols), '-y', String(rows)], {
|
|
228
|
+
stdio: 'ignore',
|
|
229
|
+
timeout: 5000,
|
|
230
|
+
env: tmuxEnv(),
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
onData(cb) {
|
|
235
|
+
this.dataCbs.push(cb);
|
|
236
|
+
}
|
|
237
|
+
onExit(cb) {
|
|
238
|
+
this.exitCbs.push(cb);
|
|
239
|
+
}
|
|
240
|
+
kill() {
|
|
241
|
+
if (this.exited)
|
|
242
|
+
return;
|
|
243
|
+
this.exited = true;
|
|
244
|
+
this.stopLifecycleWatcher();
|
|
245
|
+
// Cancel tmux's pipe subscription. Calling pipe-pane without a command
|
|
246
|
+
// turns it off for the target pane.
|
|
247
|
+
if (this.pipeAttached) {
|
|
248
|
+
try {
|
|
249
|
+
execSync(`tmux pipe-pane -t ${shellescape(this.paneTarget)}`, { stdio: 'ignore', timeout: 3000, env: tmuxEnv() });
|
|
250
|
+
}
|
|
251
|
+
catch { /* pane may already be gone — benign */ }
|
|
252
|
+
this.pipeAttached = false;
|
|
253
|
+
}
|
|
254
|
+
if (this.readStream) {
|
|
255
|
+
try {
|
|
256
|
+
this.readStream.destroy();
|
|
257
|
+
}
|
|
258
|
+
catch { /* already closed */ }
|
|
259
|
+
this.readStream = null;
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
fs.unlinkSync(this.fifoPath);
|
|
263
|
+
}
|
|
264
|
+
catch { /* already gone */ }
|
|
265
|
+
}
|
|
266
|
+
destroySession() {
|
|
267
|
+
this.kill();
|
|
268
|
+
if (this.ownsSession) {
|
|
269
|
+
TmuxBackend.killSession(this.paneTarget);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
getChildPid() {
|
|
273
|
+
try {
|
|
274
|
+
const out = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{pane_pid}'`,
|
|
275
|
+
// Explicit stdio: execSync's default leaks the child's stderr to the
|
|
276
|
+
// parent — when tmux server is unavailable this would spam
|
|
277
|
+
// "error connecting to /tmp/tmux-UID/default" into daemon-error.log
|
|
278
|
+
// every poll. Capture stderr in the result instead.
|
|
279
|
+
// tmuxEnv() also strips $TMUX so we don't target a dead parent server.
|
|
280
|
+
{ encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 3000, env: tmuxEnv() }).trim();
|
|
281
|
+
const pid = parseInt(out, 10);
|
|
282
|
+
return pid > 0 ? pid : null;
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
getAttachInfo() {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
// ─── Pipe-specific helpers ────────────────────────────────────────────────
|
|
292
|
+
startLifecycleWatcher() {
|
|
293
|
+
this.stopLifecycleWatcher();
|
|
294
|
+
this.lifecycleTimer = setInterval(() => {
|
|
295
|
+
if (this.exited)
|
|
296
|
+
return;
|
|
297
|
+
try {
|
|
298
|
+
const paneId = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{pane_id}'`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 2000, env: tmuxEnv() }).trim();
|
|
299
|
+
if (!paneId)
|
|
300
|
+
this.handlePaneExit();
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
this.handlePaneExit();
|
|
304
|
+
}
|
|
305
|
+
}, 1000);
|
|
306
|
+
}
|
|
307
|
+
stopLifecycleWatcher() {
|
|
308
|
+
if (this.lifecycleTimer) {
|
|
309
|
+
clearInterval(this.lifecycleTimer);
|
|
310
|
+
this.lifecycleTimer = null;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
handlePaneExit() {
|
|
314
|
+
if (this.exited)
|
|
315
|
+
return;
|
|
316
|
+
this.exited = true;
|
|
317
|
+
this.stopLifecycleWatcher();
|
|
318
|
+
if (this.readStream) {
|
|
319
|
+
try {
|
|
320
|
+
this.readStream.destroy();
|
|
321
|
+
}
|
|
322
|
+
catch { /* already closed */ }
|
|
323
|
+
this.readStream = null;
|
|
324
|
+
}
|
|
325
|
+
try {
|
|
326
|
+
fs.unlinkSync(this.fifoPath);
|
|
327
|
+
}
|
|
328
|
+
catch { /* already gone */ }
|
|
329
|
+
this.fireExit(1, null);
|
|
330
|
+
}
|
|
331
|
+
createDetachedSession(bin, args, opts) {
|
|
332
|
+
const shellSpec = resolveUserShell();
|
|
333
|
+
const envAssignments = buildBotmuxEnvAssignments(opts.env);
|
|
334
|
+
execFileSync('tmux', [
|
|
335
|
+
'new-session',
|
|
336
|
+
'-d',
|
|
337
|
+
'-s', this.paneTarget,
|
|
338
|
+
'-x', String(opts.cols),
|
|
339
|
+
'-y', String(opts.rows),
|
|
340
|
+
'--',
|
|
341
|
+
shellSpec.shell, ...shellSpec.flags, '-c', SHELL_WRAPPER_SCRIPT, '_',
|
|
342
|
+
opts.cwd,
|
|
343
|
+
...envAssignments,
|
|
344
|
+
bin, ...args,
|
|
345
|
+
], {
|
|
346
|
+
cwd: opts.cwd,
|
|
347
|
+
stdio: 'ignore',
|
|
348
|
+
timeout: 5000,
|
|
349
|
+
env: tmuxEnv(opts.env),
|
|
350
|
+
});
|
|
351
|
+
this.applySessionOptions();
|
|
352
|
+
}
|
|
353
|
+
applySessionOptions() {
|
|
354
|
+
const t = shellescape(this.paneTarget);
|
|
355
|
+
const env = tmuxEnv();
|
|
356
|
+
try {
|
|
357
|
+
execSync(`tmux set-option -t ${t} status off`, { stdio: 'ignore', env });
|
|
358
|
+
execSync(`tmux set-option -t ${t} mouse on`, { stdio: 'ignore', env });
|
|
359
|
+
execSync(`tmux set-option -s set-clipboard on`, { stdio: 'ignore', env });
|
|
360
|
+
execSync(`tmux set-option -t ${t} history-limit 50000`, { stdio: 'ignore', env });
|
|
361
|
+
execSync(`tmux set-option -t ${t} window-size largest`, { stdio: 'ignore', env });
|
|
362
|
+
}
|
|
363
|
+
catch { /* session may not be ready yet — benign */ }
|
|
364
|
+
}
|
|
365
|
+
/** Snapshot the full pane history WITH ANSI escapes (`-S - -E -`).
|
|
366
|
+
*
|
|
367
|
+
* Used by web reattach so a brand-new web client sees the whole prior
|
|
368
|
+
* conversation. For the screenshot / screen_update fast path use
|
|
369
|
+
* `captureViewport()` instead — that one only returns the visible pane
|
|
370
|
+
* and is safe to seed a transient xterm-headless with.
|
|
371
|
+
*
|
|
372
|
+
* IMPORTANT: tmux capture-pane separates rows with bare `\n`, no `\r`.
|
|
373
|
+
* xterm.js (and any VT100-compliant emulator) treats a bare LF as
|
|
374
|
+
* "move down one row, keep column" — every captured line lands further
|
|
375
|
+
* to the right than the previous one. Normalising every `\n` to `\r\n`
|
|
376
|
+
* makes the snapshot render correctly. The live pipe-pane stream itself
|
|
377
|
+
* doesn't need this fix — applications write proper `\r\n`. */
|
|
378
|
+
captureCurrentScreen() {
|
|
379
|
+
return this.captureWithBounds('-S - -E -');
|
|
380
|
+
}
|
|
381
|
+
/** Snapshot ONLY the currently visible pane (no scrollback). Equivalent to
|
|
382
|
+
* `tmux capture-pane` with no `-S`/`-E` flags, which defaults to the
|
|
383
|
+
* viewport. This is the right input for a transient xterm-headless seed:
|
|
384
|
+
* the snapshot row count matches the transient terminal's row count, so
|
|
385
|
+
* no normal-buffer scroll happens and the rendered screenshot lines up
|
|
386
|
+
* with what the user is seeing in the web terminal right now. */
|
|
387
|
+
captureViewport() {
|
|
388
|
+
// No `-S`/`-E` flags = tmux default = current viewport only.
|
|
389
|
+
return this.captureWithBounds('');
|
|
390
|
+
}
|
|
391
|
+
captureWithBounds(bounds) {
|
|
392
|
+
if (this.exited)
|
|
393
|
+
return '';
|
|
394
|
+
try {
|
|
395
|
+
const altOn = this.isPaneInAltBuffer();
|
|
396
|
+
const raw = execSync(`tmux capture-pane -e -p -t ${shellescape(this.paneTarget)}${bounds ? ' ' + bounds : ''}`,
|
|
397
|
+
// Explicit stdio — see getChildPid for why default leaks tmux stderr.
|
|
398
|
+
{ encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 5000, maxBuffer: 16 * 1024 * 1024, env: tmuxEnv() });
|
|
399
|
+
const normalised = normaliseCaptureLineEndings(raw);
|
|
400
|
+
if (altOn) {
|
|
401
|
+
// The pane's CLI (e.g. Claude Code, vim) is in the alternate screen
|
|
402
|
+
// buffer. capture-pane returns the alt-buffer's content but no
|
|
403
|
+
// mode-switch escape sequence — we have to bracket the snapshot
|
|
404
|
+
// with `enter alt screen + home + clear` so xterm.js renders it in
|
|
405
|
+
// the alt buffer instead of leaking it into the main buffer where
|
|
406
|
+
// it would persist after the application exits.
|
|
407
|
+
return `\x1b[?1049h\x1b[H\x1b[2J${normalised}`;
|
|
408
|
+
}
|
|
409
|
+
return normalised;
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
return '';
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
/** Current real tmux pane dimensions. Drives transient-renderer sizing so
|
|
416
|
+
* the screenshot canvas matches whatever the web client resized the pane
|
|
417
|
+
* to. Returns null if tmux can't be queried (pane gone, server gone). */
|
|
418
|
+
getPaneSize() {
|
|
419
|
+
if (this.exited)
|
|
420
|
+
return null;
|
|
421
|
+
try {
|
|
422
|
+
const out = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{pane_width} #{pane_height}'`, { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 2000, env: tmuxEnv() }).trim();
|
|
423
|
+
const [cols, rows] = out.split(/\s+/).map(s => parseInt(s, 10));
|
|
424
|
+
if (Number.isFinite(cols) && Number.isFinite(rows) && cols > 0 && rows > 0) {
|
|
425
|
+
return { cols, rows };
|
|
426
|
+
}
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
catch {
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/** Cheap probe: is the adopted pane currently in the alternate screen
|
|
434
|
+
* buffer? Used by captureCurrentScreen to decide whether the snapshot
|
|
435
|
+
* needs an alt-buffer-enter prefix for correct rendering. */
|
|
436
|
+
isPaneInAltBuffer() {
|
|
437
|
+
try {
|
|
438
|
+
const out = execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} '#{alternate_on}'`,
|
|
439
|
+
// Explicit stdio — see getChildPid for why default leaks tmux stderr.
|
|
440
|
+
{ encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'], timeout: 2000, env: tmuxEnv() }).trim();
|
|
441
|
+
return out === '1';
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
/** True if the underlying pane is still addressable in tmux. Cheap check —
|
|
448
|
+
* used by callers to detect "user closed the pane while we were piping". */
|
|
449
|
+
isPaneAlive() {
|
|
450
|
+
if (this.exited)
|
|
451
|
+
return false;
|
|
452
|
+
try {
|
|
453
|
+
execSync(`tmux display-message -p -t ${shellescape(this.paneTarget)} ''`, {
|
|
454
|
+
stdio: 'ignore',
|
|
455
|
+
timeout: 2000,
|
|
456
|
+
env: tmuxEnv(),
|
|
457
|
+
});
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
catch {
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
fireExit(code, signal) {
|
|
465
|
+
for (const cb of this.exitCbs) {
|
|
466
|
+
try {
|
|
467
|
+
cb(code, signal);
|
|
468
|
+
}
|
|
469
|
+
catch { /* listener crash is benign */ }
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
//# sourceMappingURL=tmux-pipe-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tmux-pipe-backend.js","sourceRoot":"","sources":["../../../src/adapters/backend/tmux-pipe-backend.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiden.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAMxD,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,
|
|
1
|
+
{"version":3,"file":"aiden.d.ts","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,YAAY,CAAC;AAMxD,wBAAgB,kBAAkB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,UAAU,CAsCpE;AAED,eAAO,MAAM,MAAM,2BAAqB,CAAC"}
|
|
@@ -17,6 +17,11 @@ export function createAidenAdapter(pathOverride) {
|
|
|
17
17
|
args.push('--permission-mode', 'agentFull');
|
|
18
18
|
return args;
|
|
19
19
|
},
|
|
20
|
+
buildResumeCommand({ sessionId }) {
|
|
21
|
+
// Aiden uses botmux's sessionId directly — no rotation, no separate
|
|
22
|
+
// CLI-native id, so cliSessionId isn't consulted.
|
|
23
|
+
return `aiden --resume ${sessionId}`;
|
|
24
|
+
},
|
|
20
25
|
async writeInput(pty, content) {
|
|
21
26
|
if (pty.sendText && pty.sendSpecialKeys) {
|
|
22
27
|
pty.sendText(content);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiden.js","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAAqB;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACnC,CAAC;YACD,mDAAmD;YACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACxC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS,EAAG,kBAAkB;QACjD,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"aiden.js","sourceRoot":"","sources":["../../../src/adapters/cli/aiden.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGvD,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAAqB;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC;IACpD,OAAO;QACL,EAAE,EAAE,OAAO;QACX,WAAW,EAAE,GAAG;QAEhB,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;YAC7B,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YACnC,CAAC;YACD,mDAAmD;YACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,kBAAkB,CAAC,EAAE,SAAS,EAAE;YAC9B,oEAAoE;YACpE,kDAAkD;YAClD,OAAO,kBAAkB,SAAS,EAAE,CAAC;QACvC,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,GAAc,EAAE,OAAe;YAC9C,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,EAAE,CAAC;gBACxC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACtB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjB,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACnB,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,iBAAiB,EAAE,SAAS,EAAG,kBAAkB;QACjD,WAAW,EAAE,kBAAkB;QAC/B,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC"}
|