aibroker 0.9.1 → 0.11.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/README.md +21 -1
- package/dist/adapters/iterm/sessions.d.ts.map +1 -1
- package/dist/adapters/iterm/sessions.js +3 -0
- package/dist/adapters/iterm/sessions.js.map +1 -1
- package/dist/daemon/ask.d.ts.map +1 -1
- package/dist/daemon/ask.js +7 -1
- package/dist/daemon/ask.js.map +1 -1
- package/dist/daemon/audit-cli.d.ts +2 -0
- package/dist/daemon/audit-cli.d.ts.map +1 -0
- package/dist/daemon/audit-cli.js +90 -0
- package/dist/daemon/audit-cli.js.map +1 -0
- package/dist/daemon/audit.d.ts +82 -0
- package/dist/daemon/audit.d.ts.map +1 -0
- package/dist/daemon/audit.js +143 -0
- package/dist/daemon/audit.js.map +1 -0
- package/dist/daemon/cli.js +7 -1
- package/dist/daemon/cli.js.map +1 -1
- package/dist/daemon/core-handlers.d.ts.map +1 -1
- package/dist/daemon/core-handlers.js +104 -9
- package/dist/daemon/core-handlers.js.map +1 -1
- package/dist/daemon/terminal-screen.d.ts +4 -49
- package/dist/daemon/terminal-screen.d.ts.map +1 -1
- package/dist/daemon/terminal-screen.js +4 -89
- package/dist/daemon/terminal-screen.js.map +1 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/transport/screen.d.ts +45 -0
- package/dist/transport/screen.d.ts.map +1 -0
- package/dist/transport/screen.js +83 -0
- package/dist/transport/screen.js.map +1 -0
- package/dist/transport/sync-facade.d.ts +12 -4
- package/dist/transport/sync-facade.d.ts.map +1 -1
- package/dist/transport/sync-facade.js +61 -4
- package/dist/transport/sync-facade.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -29,7 +29,23 @@ export { WatcherClient } from "./ipc/client.js";
|
|
|
29
29
|
export { IpcServer } from "./ipc/server.js";
|
|
30
30
|
export { validateAdapterHealth, validateSessionList, validateHubStatus, validateTtsResult, validateTranscription, } from "./ipc/validate.js";
|
|
31
31
|
// ── Adapters > iTerm2 ──
|
|
32
|
-
export { runAppleScript, stripItermPrefix, withSessionAppleScript, sendKeystrokeToSession, sendEscapeSequenceToSession,
|
|
32
|
+
export { runAppleScript, stripItermPrefix, withSessionAppleScript, sendKeystrokeToSession, sendEscapeSequenceToSession, findClaudeSession, isClaudeRunningInSession, isItermRunning, isItermSessionAlive, isScreenLocked, writeToTty, snapshotAllSessions, } from "./adapters/iterm/core.js";
|
|
33
|
+
/**
|
|
34
|
+
* Session writes come from the GUARDED facade, not the raw iTerm primitives.
|
|
35
|
+
*
|
|
36
|
+
* These used to be re-exported straight from adapters/iterm/core.js, which
|
|
37
|
+
* writes to a tty with no idea what is reading it. When a session's Claude has
|
|
38
|
+
* exited, its tab is still there at a shell prompt — and a shell executes what
|
|
39
|
+
* it is sent. That is not hypothetical: an ordinary status message containing a
|
|
40
|
+
* fenced code block had its example command run, creating a real task.
|
|
41
|
+
*
|
|
42
|
+
* The guarded versions refuse to write unless the target is showing a live
|
|
43
|
+
* Claude prompt. Same signature, plus an optional `{ allowShell: true }` for
|
|
44
|
+
* callers that genuinely mean to address a shell (launching a session).
|
|
45
|
+
* Anything relying on the old unguarded behaviour to write into a shell must
|
|
46
|
+
* now say so explicitly.
|
|
47
|
+
*/
|
|
48
|
+
export { typeIntoSession, pasteTextIntoSession, isClaudeSession, invalidateReadyCache, } from "./transport/sync-facade.js";
|
|
33
49
|
export { setItermSessionVar, setItermTabName, setItermBadge, getItermSessionVar, findItermSessionForTermId, listClaudeSessions, getSessionList, createClaudeSession, createTerminalTab, restartSession, killSession, } from "./adapters/iterm/sessions.js";
|
|
34
50
|
export { recordFromMic, transcribeLocalAudio, WHISPER_BIN as DICTATION_WHISPER_BIN, WHISPER_MODEL as DICTATION_WHISPER_MODEL, } from "./adapters/iterm/dictation.js";
|
|
35
51
|
// ── Adapters > Kokoro TTS ──
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,cAAc;AACd,cAAc,kBAAkB,CAAC;AAEjC,aAAa;AACb,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACtG,OAAO,EACL,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,SAAS,EACT,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzF,YAAY;AACZ,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAQ3B,0BAA0B;AAC1B,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,2BAA2B,EAC3B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transport/screen.ts — pure predicates over a captured terminal frame.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately dependency-free so the transport layer itself can use them
|
|
5
|
+
* without importing anything that imports the transport back.
|
|
6
|
+
*/
|
|
7
|
+
/** The line Claude's input box is drawn on. */
|
|
8
|
+
export declare const INPUT_LINE: RegExp;
|
|
9
|
+
/** A horizontal rule; the input box is bounded by two of them. */
|
|
10
|
+
export declare const CLAUDE_UI: RegExp;
|
|
11
|
+
/** A shell prompt: a line ending in a common prompt terminator. */
|
|
12
|
+
export declare const SHELL_PROMPT: RegExp;
|
|
13
|
+
/** Collapse whitespace so wrapped and padded terminal text compares sanely. */
|
|
14
|
+
export declare function flatten(s: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* True when Claude's input box is LIVE at the bottom of the screen.
|
|
17
|
+
*
|
|
18
|
+
* "Contains a box somewhere" is not enough, and the difference is a safety
|
|
19
|
+
* issue. When Claude exits — crashes, is suspended, or is ended cleanly — its
|
|
20
|
+
* whole UI stays in the terminal's scrollback while a shell prompt appears
|
|
21
|
+
* underneath. A frame-wide search still finds the rules and the `❯`, declares
|
|
22
|
+
* the session ready, and the caller types into a live shell, where zsh
|
|
23
|
+
* EXECUTES the text.
|
|
24
|
+
*
|
|
25
|
+
* A live box is therefore required to be at the bottom: the closing rule near
|
|
26
|
+
* the end of the visible frame, with nothing shell-prompt-shaped after it.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isClaudeReady(frame: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* The lines inside Claude's input box.
|
|
31
|
+
*
|
|
32
|
+
* Identified structurally — the region between the last two horizontal rules —
|
|
33
|
+
* because the `❯` marker also matches every echoed message in the transcript.
|
|
34
|
+
*/
|
|
35
|
+
export declare function inputBoxLines(frame: string): string[];
|
|
36
|
+
/** Index of the line opening the bottom input box, or -1. */
|
|
37
|
+
export declare function inputBoxStart(frame: string): number;
|
|
38
|
+
/**
|
|
39
|
+
* Has `needle` left the input box and landed in the transcript?
|
|
40
|
+
*
|
|
41
|
+
* Presence on screen is not enough: unsubmitted text in the box is also
|
|
42
|
+
* present. Submission is the moment it appears while the box no longer holds it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function hasBeenSubmitted(frame: string, needle: string): boolean;
|
|
45
|
+
//# sourceMappingURL=screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../../src/transport/screen.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+CAA+C;AAC/C,eAAO,MAAM,UAAU,QAAU,CAAC;AAClC,kEAAkE;AAClE,eAAO,MAAM,SAAS,QAAW,CAAC;AAClC,mEAAmE;AACnE,eAAO,MAAM,YAAY,QAAgB,CAAC;AAE1C,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAA0C;AAEpF;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAkBpD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CASrD;AAED,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGvE"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transport/screen.ts — pure predicates over a captured terminal frame.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately dependency-free so the transport layer itself can use them
|
|
5
|
+
* without importing anything that imports the transport back.
|
|
6
|
+
*/
|
|
7
|
+
/** The line Claude's input box is drawn on. */
|
|
8
|
+
export const INPUT_LINE = /^\s*❯/;
|
|
9
|
+
/** A horizontal rule; the input box is bounded by two of them. */
|
|
10
|
+
export const CLAUDE_UI = /─{20,}/;
|
|
11
|
+
/** A shell prompt: a line ending in a common prompt terminator. */
|
|
12
|
+
export const SHELL_PROMPT = /[➜$%#»]\s*$/;
|
|
13
|
+
/** Collapse whitespace so wrapped and padded terminal text compares sanely. */
|
|
14
|
+
export function flatten(s) { return s.replace(/\s+/g, " ").trim(); }
|
|
15
|
+
/**
|
|
16
|
+
* True when Claude's input box is LIVE at the bottom of the screen.
|
|
17
|
+
*
|
|
18
|
+
* "Contains a box somewhere" is not enough, and the difference is a safety
|
|
19
|
+
* issue. When Claude exits — crashes, is suspended, or is ended cleanly — its
|
|
20
|
+
* whole UI stays in the terminal's scrollback while a shell prompt appears
|
|
21
|
+
* underneath. A frame-wide search still finds the rules and the `❯`, declares
|
|
22
|
+
* the session ready, and the caller types into a live shell, where zsh
|
|
23
|
+
* EXECUTES the text.
|
|
24
|
+
*
|
|
25
|
+
* A live box is therefore required to be at the bottom: the closing rule near
|
|
26
|
+
* the end of the visible frame, with nothing shell-prompt-shaped after it.
|
|
27
|
+
*/
|
|
28
|
+
export function isClaudeReady(frame) {
|
|
29
|
+
const lines = frame.split("\n").filter((l) => l.trim().length > 0);
|
|
30
|
+
if (lines.length === 0)
|
|
31
|
+
return false;
|
|
32
|
+
let lastRule = -1;
|
|
33
|
+
lines.forEach((l, i) => { if (CLAUDE_UI.test(l))
|
|
34
|
+
lastRule = i; });
|
|
35
|
+
if (lastRule < 0)
|
|
36
|
+
return false;
|
|
37
|
+
// Claude renders only its status lines below the box; a shell fills the rest
|
|
38
|
+
// of the screen, pushing the box further and further up.
|
|
39
|
+
if (lines.length - 1 - lastRule > 8)
|
|
40
|
+
return false;
|
|
41
|
+
// Belt and braces: an explicit prompt below the box means the shell has it.
|
|
42
|
+
for (let i = lastRule + 1; i < lines.length; i++) {
|
|
43
|
+
if (SHELL_PROMPT.test(lines[i]))
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
return lines.some((l) => INPUT_LINE.test(l));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The lines inside Claude's input box.
|
|
50
|
+
*
|
|
51
|
+
* Identified structurally — the region between the last two horizontal rules —
|
|
52
|
+
* because the `❯` marker also matches every echoed message in the transcript.
|
|
53
|
+
*/
|
|
54
|
+
export function inputBoxLines(frame) {
|
|
55
|
+
const lines = frame.split("\n");
|
|
56
|
+
const rules = [];
|
|
57
|
+
lines.forEach((l, i) => { if (CLAUDE_UI.test(l))
|
|
58
|
+
rules.push(i); });
|
|
59
|
+
if (rules.length >= 2) {
|
|
60
|
+
const [open, close] = [rules[rules.length - 2], rules[rules.length - 1]];
|
|
61
|
+
return lines.slice(open + 1, close);
|
|
62
|
+
}
|
|
63
|
+
return lines.filter((l) => INPUT_LINE.test(l)); // no box drawn — best effort
|
|
64
|
+
}
|
|
65
|
+
/** Index of the line opening the bottom input box, or -1. */
|
|
66
|
+
export function inputBoxStart(frame) {
|
|
67
|
+
const lines = frame.split("\n");
|
|
68
|
+
const rules = [];
|
|
69
|
+
lines.forEach((l, i) => { if (CLAUDE_UI.test(l))
|
|
70
|
+
rules.push(i); });
|
|
71
|
+
return rules.length >= 2 ? rules[rules.length - 2] : -1;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Has `needle` left the input box and landed in the transcript?
|
|
75
|
+
*
|
|
76
|
+
* Presence on screen is not enough: unsubmitted text in the box is also
|
|
77
|
+
* present. Submission is the moment it appears while the box no longer holds it.
|
|
78
|
+
*/
|
|
79
|
+
export function hasBeenSubmitted(frame, needle) {
|
|
80
|
+
const stillTyped = inputBoxLines(frame).some((l) => flatten(l).includes(needle.slice(0, 24)));
|
|
81
|
+
return !stillTyped && flatten(frame).includes(needle);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=screen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screen.js","sourceRoot":"","sources":["../../src/transport/screen.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,10 +31,18 @@ import type { SessionSnapshot } from "../adapters/iterm/core.js";
|
|
|
31
31
|
export declare function snapshotAllSessions(): SessionSnapshot[];
|
|
32
32
|
/** Translate a caller's $TMUX_PANE into the durable @aibroker_id identity. */
|
|
33
33
|
export declare function aibrokerIdForPane(paneId: string): string | null;
|
|
34
|
-
/** Inject text + Enter into a session. */
|
|
35
|
-
export declare function typeIntoSession(id: string, text: string
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
/** Inject text + Enter into a session. Refuses a shell unless `allowShell`. */
|
|
35
|
+
export declare function typeIntoSession(id: string, text: string, opts?: {
|
|
36
|
+
allowShell?: boolean;
|
|
37
|
+
}): boolean;
|
|
38
|
+
/** Inject text WITHOUT Enter (chunked / partial sends). Same guard. */
|
|
39
|
+
export declare function pasteTextIntoSession(id: string, text: string, opts?: {
|
|
40
|
+
allowShell?: boolean;
|
|
41
|
+
}): boolean;
|
|
42
|
+
/** Drop a cached readiness verdict (call right after launching into a tab). */
|
|
43
|
+
export declare function invalidateReadyCache(id?: string): void;
|
|
44
|
+
/** True when the session is currently showing a live Claude prompt. */
|
|
45
|
+
export declare function isClaudeSession(id: string): boolean;
|
|
38
46
|
/**
|
|
39
47
|
* Read what a session is currently showing. Used by checkpoint's ack detection,
|
|
40
48
|
* which watches for the screen to change (message landed) and then settle
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-facade.d.ts","sourceRoot":"","sources":["../../src/transport/sync-facade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-facade.d.ts","sourceRoot":"","sources":["../../src/transport/sync-facade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAmCjE,qFAAqF;AACrF,wBAAgB,mBAAmB,IAAI,eAAe,EAAE,CAgBvD;AAeD,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG/D;AAgDD,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAItG;AAED,uEAAuE;AACvE,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAI3G;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAEtD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGxE;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAG5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKtE"}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
import * as iterm from "../adapters/iterm/core.js";
|
|
30
30
|
import { ItermTransport } from "./iterm.js";
|
|
31
31
|
import { TmuxTransport } from "./tmux.js";
|
|
32
|
+
import { isClaudeReady } from "./screen.js";
|
|
32
33
|
import { log } from "../core/log.js";
|
|
33
34
|
const override = (process.env.AIBROKER_TRANSPORT ?? "").trim().toLowerCase();
|
|
34
35
|
const tmuxTransport = new TmuxTransport();
|
|
@@ -92,18 +93,74 @@ export function aibrokerIdForPane(paneId) {
|
|
|
92
93
|
return null;
|
|
93
94
|
return tmuxTransport.aibrokerIdForPane(paneId);
|
|
94
95
|
}
|
|
95
|
-
/**
|
|
96
|
-
|
|
96
|
+
/**
|
|
97
|
+
* ── Shell-injection guard ───────────────────────────────────────────────────
|
|
98
|
+
*
|
|
99
|
+
* A session whose Claude has exited — crashed, suspended, or ended cleanly via
|
|
100
|
+
* `pai end` — leaves its tab alive at a shell prompt, keeps its persistent PAI
|
|
101
|
+
* name, and therefore still matches by project. Writing to it no longer reaches
|
|
102
|
+
* Claude: it reaches zsh, and zsh EXECUTES what it is sent.
|
|
103
|
+
*
|
|
104
|
+
* Reproduced twice for real. A probe question ran as a command; separately, an
|
|
105
|
+
* ordinary status message containing a fenced code block had its example
|
|
106
|
+
* command executed, creating a live Todoist task. The payload does not need to
|
|
107
|
+
* be adversarial — routine technical writing is full of backticks, which zsh
|
|
108
|
+
* expands as command substitution.
|
|
109
|
+
*
|
|
110
|
+
* The guard belongs here rather than in each caller: send_to_session, inbound
|
|
111
|
+
* WhatsApp/Telegram delivery, the session backend and PAILot chunk writes all
|
|
112
|
+
* carry arbitrary text into a session, and enumerating them is exactly how one
|
|
113
|
+
* gets missed. Callers that legitimately address a shell — launching a session
|
|
114
|
+
* types `cd … && claude …` into a fresh tab — pass `allowShell`.
|
|
115
|
+
*/
|
|
116
|
+
const READY_TTL_MS = 2_000;
|
|
117
|
+
const readyCache = new Map();
|
|
118
|
+
/** Is this session showing a live Claude prompt? Cached briefly for chunked writes. */
|
|
119
|
+
function claudeHasTty(id) {
|
|
120
|
+
const hit = readyCache.get(id);
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
if (hit && now - hit.at < READY_TTL_MS)
|
|
123
|
+
return hit.ready;
|
|
124
|
+
const frame = captureSession(id, 80);
|
|
125
|
+
// Unreadable is NOT treated as safe: refusing a legitimate send is recoverable,
|
|
126
|
+
// executing a message in a shell is not.
|
|
127
|
+
const ready = frame !== null && isClaudeReady(frame);
|
|
128
|
+
readyCache.set(id, { at: now, ready });
|
|
129
|
+
return ready;
|
|
130
|
+
}
|
|
131
|
+
function refuse(id, text) {
|
|
132
|
+
log(`REFUSED write to ${id}: no live Claude prompt — its terminal is at a shell, ` +
|
|
133
|
+
`which would execute the text rather than read it. ` +
|
|
134
|
+
`First 60 chars: ${JSON.stringify(text.slice(0, 60))}`);
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
/** Inject text + Enter into a session. Refuses a shell unless `allowShell`. */
|
|
138
|
+
export function typeIntoSession(id, text, opts = {}) {
|
|
139
|
+
if (!opts.allowShell && !claudeHasTty(id))
|
|
140
|
+
return refuse(id, text);
|
|
97
141
|
if (routeToTmux(id))
|
|
98
142
|
return tmuxTransport.sendText(id, text, { enter: true });
|
|
99
143
|
return iterm.typeIntoSession(id, text);
|
|
100
144
|
}
|
|
101
|
-
/** Inject text WITHOUT Enter (chunked / partial sends). */
|
|
102
|
-
export function pasteTextIntoSession(id, text) {
|
|
145
|
+
/** Inject text WITHOUT Enter (chunked / partial sends). Same guard. */
|
|
146
|
+
export function pasteTextIntoSession(id, text, opts = {}) {
|
|
147
|
+
if (!opts.allowShell && !claudeHasTty(id))
|
|
148
|
+
return refuse(id, text);
|
|
103
149
|
if (routeToTmux(id))
|
|
104
150
|
return tmuxTransport.sendText(id, text, { enter: false });
|
|
105
151
|
return iterm.pasteTextIntoSession(id, text);
|
|
106
152
|
}
|
|
153
|
+
/** Drop a cached readiness verdict (call right after launching into a tab). */
|
|
154
|
+
export function invalidateReadyCache(id) {
|
|
155
|
+
if (id)
|
|
156
|
+
readyCache.delete(id);
|
|
157
|
+
else
|
|
158
|
+
readyCache.clear();
|
|
159
|
+
}
|
|
160
|
+
/** True when the session is currently showing a live Claude prompt. */
|
|
161
|
+
export function isClaudeSession(id) {
|
|
162
|
+
return claudeHasTty(id);
|
|
163
|
+
}
|
|
107
164
|
/**
|
|
108
165
|
* Read what a session is currently showing. Used by checkpoint's ack detection,
|
|
109
166
|
* which watches for the screen to change (message landed) and then settle
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-facade.js","sourceRoot":"","sources":["../../src/transport/sync-facade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,KAAK,MAAM,2BAA2B,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAErC,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAE7E,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;AAC1C,MAAM,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;AAE5C,8EAA8E;AAC9E,iFAAiF;AACjF,gFAAgF;AAChF,8EAA8E;AAC9E,8BAA8B;AAC9B,MAAM,UAAU,GAAG,QAAQ,KAAK,MAAM,CAAC;AACvC,MAAM,SAAS,GAAG,QAAQ,KAAK,OAAO,CAAC;AAEvC,SAAS,cAAc,CAAC,CAAiB;IACvC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,WAAW,EAAE,SAAS;QACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;QAChB,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;QACjB,6EAA6E;QAC7E,OAAO,EAAE,IAAI;QACb,+EAA+E;QAC/E,UAAU,EAAE,CAAC,CAAC,UAAU;KACzB,CAAC;AACJ,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB;IACjC,0EAA0E;IAC1E,4EAA4E;IAC5E,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,IAAI,aAAa,GAAsB,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAErF,IAAI,UAAU,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACtC,wEAAwE;QACxE,0EAA0E;QAC1E,uEAAuE;QACvE,qEAAqE;QACrE,MAAM,UAAU,GAAG,aAAa,CAAC,kBAAkB,EAAE,CAAC;QACtD,IAAI,UAAU,CAAC,IAAI;YAAE,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrG,CAAC;IAED,OAAO,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,EAAU;IAC7B,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC,CAAC,uCAAuC;IACrE,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;AAC3C,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,aAAa,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"sync-facade.js","sourceRoot":"","sources":["../../src/transport/sync-facade.ts"],"names":[],"mappings":"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"}
|