@tekmidian/pai 0.51.1 → 0.52.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/dist/{aibroker-client-Bu72yPKj.mjs → aibroker-client-CNfIBrl5.mjs} +1 -1
- package/dist/{aibroker-client-CDIXmq-e.mjs → aibroker-client-DzkTpVjx.mjs} +13 -5
- package/dist/{aibroker-client-CDIXmq-e.mjs.map → aibroker-client-DzkTpVjx.mjs.map} +1 -1
- package/dist/cli/index.mjs +4 -4
- package/dist/cli/program.mjs +4 -4
- package/dist/daemon/index.mjs +3 -3
- package/dist/{daemon-pX0-MiAH.mjs → daemon-BIbpQeXx.mjs} +3 -3
- package/dist/{daemon-Bhs7kk0a.mjs → daemon-COyx4FGM.mjs} +3 -3
- package/dist/{daemon-Bhs7kk0a.mjs.map → daemon-COyx4FGM.mjs.map} +1 -1
- package/dist/hooks/whisper-rules.mjs +5 -2
- package/dist/hooks/whisper-rules.mjs.map +2 -2
- package/dist/{main-resolver-BmZPCmgj.mjs → main-resolver-Dv-oC46Z.mjs} +37 -18
- package/dist/{main-resolver-BmZPCmgj.mjs.map → main-resolver-Dv-oC46Z.mjs.map} +1 -1
- package/dist/main-resolver-DyeXNI8b.mjs +7 -0
- package/dist/{program-BQaDYGNC.mjs → program-ClTUv9-k.mjs} +8 -8
- package/dist/{program-BQaDYGNC.mjs.map → program-ClTUv9-k.mjs.map} +1 -1
- package/dist/{session-keepalive-BuG3wvik.mjs → session-keepalive-BkLOTZf6.mjs} +9 -6
- package/dist/session-keepalive-BkLOTZf6.mjs.map +1 -0
- package/package.json +1 -1
- package/src/hooks/ts/user-prompt/whisper-rules.test.ts +26 -1
- package/src/hooks/ts/user-prompt/whisper-rules.ts +13 -2
- package/dist/main-resolver-BTastpp4.mjs +0 -7
- package/dist/session-keepalive-BuG3wvik.mjs.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as switchToSession, i as sendToSession, n as fetchLiveSessions, r as revealItermSession, t as callAiBroker } from "./aibroker-client-
|
|
1
|
+
import { a as switchToSession, i as sendToSession, n as fetchLiveSessions, r as revealItermSession, t as callAiBroker } from "./aibroker-client-DzkTpVjx.mjs";
|
|
2
2
|
|
|
3
3
|
export { sendToSession };
|
|
@@ -126,19 +126,27 @@ async function fetchLiveSessions() {
|
|
|
126
126
|
* `enter: true` and appends the Enter itself, so a trailing \n submits twice —
|
|
127
127
|
* once for the text and once for an empty prompt.
|
|
128
128
|
*/
|
|
129
|
-
async function sendToSession(sessionId, text, timeoutMs = SEND_TIMEOUT_MS) {
|
|
129
|
+
async function sendToSession(sessionId, text, timeoutMs = SEND_TIMEOUT_MS, opts) {
|
|
130
130
|
try {
|
|
131
|
-
|
|
131
|
+
const params = {
|
|
132
132
|
target: sessionId,
|
|
133
133
|
message: text
|
|
134
|
-
}
|
|
134
|
+
};
|
|
135
|
+
if (opts?.noReply) params.noReply = true;
|
|
136
|
+
await callAiBroker("send_to_session", params, timeoutMs);
|
|
135
137
|
return { ok: true };
|
|
136
138
|
} catch (e) {
|
|
137
139
|
const error = String(e);
|
|
140
|
+
const timedOut = /timed out/i.test(error);
|
|
141
|
+
if (opts?.noReply && timedOut) return {
|
|
142
|
+
ok: false,
|
|
143
|
+
timedOut: true,
|
|
144
|
+
error
|
|
145
|
+
};
|
|
138
146
|
return {
|
|
139
147
|
ok: false,
|
|
140
148
|
error,
|
|
141
|
-
timedOut
|
|
149
|
+
timedOut
|
|
142
150
|
};
|
|
143
151
|
}
|
|
144
152
|
}
|
|
@@ -212,4 +220,4 @@ end tell`;
|
|
|
212
220
|
|
|
213
221
|
//#endregion
|
|
214
222
|
export { switchToSession as a, sendToSession as i, fetchLiveSessions as n, revealItermSession as r, callAiBroker as t };
|
|
215
|
-
//# sourceMappingURL=aibroker-client-
|
|
223
|
+
//# sourceMappingURL=aibroker-client-DzkTpVjx.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aibroker-client-CDIXmq-e.mjs","names":[],"sources":["../src/cli/lib/aibroker-client.ts"],"sourcesContent":["/**\n * aibroker-client.ts — Lightweight IPC client for AIBroker daemon.\n *\n * Connects to the AIBroker Unix Domain Socket, sends a JSON-RPC request,\n * and reads a single newline-terminated JSON response. No class needed —\n * just a thin async function matching the WatcherClient protocol.\n *\n * Socket path: /tmp/aibroker.sock (default; override via AIBROKER_SOCKET env).\n */\n\nimport { connect } from \"node:net\";\nimport { randomUUID } from \"node:crypto\";\nimport { spawnSync } from \"node:child_process\";\nimport { aibrokerSocketPath } from \"../../runtime-paths.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Lightweight session metadata returned by the AIBroker `sessions` IPC method.\n * Does NOT include scrollback content — use `session_content` for that.\n */\nexport interface AiBrokerSessionMeta {\n index: number;\n sessionId: string;\n /** iTerm2 tab title or profile name */\n name: string;\n /** PAI session name set via /Name; null for bare shells */\n paiName: string | null;\n atPrompt: boolean;\n /** \"claude\" for Claude Code panes, \"shell\" for bare terminals */\n kind: \"claude\" | \"shell\";\n /** Whether this is the currently focused pane */\n active: boolean;\n /** Last user prompt seen in scrollback (only populated by fetchLiveSessionsWithPrompts) */\n lastPrompt?: string;\n}\n\ninterface AiBrokerSessionsResult {\n sessions: AiBrokerSessionMeta[];\n}\n\n// ---------------------------------------------------------------------------\n// Core call\n// ---------------------------------------------------------------------------\n\n// AIBROKER_SOCKET stays first: it is AIBroker's own variable and a user who has\n// set it means it. The fallback goes through runtime-paths so the test guard\n// can redirect it — writing to a live socket from a test is the same hazard as\n// writing to live user state, and this one is not even ours.\nconst DEFAULT_SOCKET = process.env.AIBROKER_SOCKET ?? aibrokerSocketPath();\n\n/**\n * How long to wait for `send_to_session`, which must exceed the server's own\n * ack window or the caller gives up while the callee is still working.\n *\n * AIBroker waits up to SEND_ACK_TIMEOUT_MS (15s) for the submit confirmation —\n * the text leaving the input line — before answering. The generic client\n * timeout is 8s. So every send needing 8-15s to confirm reported\n * \"AIBroker IPC call timed out\" while succeeding, and the handler's eventual\n * `delivered: true` was written into a socket nobody was reading any more.\n *\n * Measured on `pai pause all` across 15 sessions: 9 reported failed, 8 of them\n * verifiably paused. A caller's deadline shorter than the callee's is not a\n * tuning question, it is a guaranteed false negative on every slow success.\n */\nconst SEND_TIMEOUT_MS = 30_000;\n\n/**\n * Call an AIBroker IPC method and return the result.\n *\n * Resolves with the `result` field of a successful response.\n * Rejects if the socket is not available, the call times out, or the\n * daemon returns an error.\n *\n * @param method IPC method name (e.g. \"session_content\", \"send_to_session\")\n * @param params Method parameters object\n * @param timeoutMs Connection + response timeout in milliseconds (default: 8 000)\n */\nexport function callAiBroker(\n method: string,\n params: Record<string, unknown> = {},\n timeoutMs = 8_000\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const socketPath = DEFAULT_SOCKET;\n let done = false;\n let buffer = \"\";\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function finish(err: Error | null, value?: Record<string, unknown>): void {\n if (done) return;\n done = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n try {\n socket.destroy();\n } catch {\n /* ignore */\n }\n if (err) reject(err);\n else resolve(value!);\n }\n\n const socket = connect(socketPath, () => {\n const request = {\n id: randomUUID(),\n sessionId: process.env.TERM_SESSION_ID ?? \"pai-cli\",\n method,\n params,\n };\n const itermId = process.env.ITERM_SESSION_ID;\n if (itermId) Object.assign(request, { itermSessionId: itermId });\n socket.write(JSON.stringify(request) + \"\\n\");\n });\n\n socket.on(\"data\", (chunk: Buffer) => {\n buffer += chunk.toString(\"utf8\");\n const nl = buffer.indexOf(\"\\n\");\n if (nl === -1) return;\n const line = buffer.slice(0, nl);\n\n let response: { ok: boolean; result?: Record<string, unknown>; error?: string };\n try {\n response = JSON.parse(line);\n } catch {\n finish(new Error(`AIBroker IPC parse error: ${line.slice(0, 120)}`));\n return;\n }\n\n if (!response.ok) {\n finish(new Error(response.error ?? \"AIBroker IPC call failed\"));\n } else {\n finish(null, response.result ?? {});\n }\n });\n\n socket.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"ENOENT\" || e.code === \"ECONNREFUSED\") {\n finish(new Error(\"AIBroker not running (socket not found).\"));\n } else {\n finish(e);\n }\n });\n\n socket.on(\"end\", () => {\n if (!done) finish(new Error(\"AIBroker IPC connection closed before response.\"));\n });\n\n timer = setTimeout(\n () => finish(new Error(\"AIBroker IPC call timed out.\")),\n timeoutMs\n );\n });\n}\n\n// ---------------------------------------------------------------------------\n// Typed helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch all live iTerm2 session metadata from AIBroker via the `sessions` method.\n * Returns an empty array if AIBroker is not running.\n *\n * This is metadata-only (no scrollback). It is faster than `session_content`\n * and the correct source for listing/routing purposes.\n */\nexport async function fetchLiveSessions(): Promise<AiBrokerSessionMeta[]> {\n try {\n const result = await callAiBroker(\"sessions\", {});\n const sessions = (result as unknown as AiBrokerSessionsResult).sessions;\n if (!Array.isArray(sessions)) return [];\n return sessions;\n } catch {\n return [];\n }\n}\n\n/**\n * Fetch live sessions WITH the last user prompt extracted from terminal scrollback.\n *\n * Heavier than `fetchLiveSessions` (one IPC call returning full content for\n * every session), but yields a `lastPrompt` field useful for the unified\n * listing.\n */\nexport async function fetchLiveSessionsWithPrompts(): Promise<\n (AiBrokerSessionMeta & { lastPrompt?: string })[]\n> {\n // Get the basic metadata first (always works, fast).\n const metas = await fetchLiveSessions();\n if (metas.length === 0) return [];\n\n // Then enrich with last prompts via session_content (single call, all sessions).\n try {\n const contentResult = (await callAiBroker(\"session_content\", { lines: 60 })) as {\n sessions?: Array<{ sessionId: string; content?: string }>;\n };\n const contentMap = new Map<string, string>();\n for (const s of contentResult.sessions ?? []) {\n if (s.sessionId && typeof s.content === \"string\") {\n contentMap.set(s.sessionId, s.content);\n }\n }\n return metas.map((m) => {\n const content = contentMap.get(m.sessionId);\n const lastPrompt = content ? extractLastUserPrompt(content) : undefined;\n return { ...m, lastPrompt };\n });\n } catch {\n return metas.map((m) => ({ ...m }));\n }\n}\n\n/**\n * Extract the most-recent user prompt from a terminal scrollback string.\n *\n * Claude Code's TUI shows user input lines prefixed with `❯ `. We scan from\n * the bottom up, skipping the active input box (between the two horizontal\n * rule lines) and the statusline footer.\n */\nfunction extractLastUserPrompt(content: string): string | undefined {\n const lines = content.split(\"\\n\");\n // Walk bottom-up looking for the most recent user-typed line.\n // Claude Code marks user prompts with one of these prefixes:\n // ❯ <text> (current/recent prompt in the input box or scrollback)\n // > <text> (older variant)\n // The line MUST have non-empty content after the prompt symbol.\n // Skip the active input box (often empty `❯`) and statusline (👋 PAI CC...).\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i].trim();\n // Match ❯ or > (followed by space) then content\n const m = line.match(/^[❯>]\\s+(.+?)\\s*$/);\n if (!m) continue;\n let text = m[1].trim();\n if (!text) continue;\n // Skip lines that are just box-drawing or known UI noise\n if (/^[─━═]+/.test(text)) continue;\n if (text.startsWith(\"👋\")) continue;\n // Strip ANSI escape sequences that may leak in\n text = text.replace(/\\x1B\\[[0-9;]*[A-Za-z]/g, \"\").trim();\n if (text) return text;\n }\n return undefined;\n}\n\n/**\n * Send text to a specific AIBroker session by its iTerm2 sessionId.\n *\n * The wire keys are `target` and `message`, and neither is negotiable — the\n * handler rejects anything else with \"target is required\" before it looks at\n * the rest. This was written as `{ target: sessionId, message: text }`, which is the shape of\n * THIS function's own parameters rather than the shape of the IPC, so every\n * call failed identically. `pai pause all` was the only caller, so the live\n * path had never once executed: its --dry-run branch returns before sending,\n * and that was the only branch anyone had exercised.\n *\n * The caller must NOT terminate `text` with a newline. The transport sends with\n * `enter: true` and appends the Enter itself, so a trailing \\n submits twice —\n * once for the text and once for an empty prompt.\n */\nexport async function sendToSession(\n sessionId: string,\n text: string,\n timeoutMs = SEND_TIMEOUT_MS\n): Promise<{ ok: boolean; error?: string; timedOut?: boolean }> {\n try {\n await callAiBroker(\"send_to_session\", { target: sessionId, message: text }, timeoutMs);\n return { ok: true };\n } catch (e) {\n const error = String(e);\n // A timeout is NOT a delivery failure, and conflating the two is expensive.\n // The handler deposits into the target's mailbox BEFORE it waits for the\n // submit ack, so a send that times out has still been delivered — only the\n // confirmation is missing. Reported as a plain failure, the natural response\n // is to send again, which is how `pai pause all` produced nested\n // \"carried forward\" blocks in checkpoints that had already been written.\n return { ok: false, error, timedOut: /timed out/i.test(error) };\n }\n}\n\n/**\n * Switch iTerm2 focus to the session identified by `target`.\n *\n * `target` can be a sessionId, paiName, or tab index number (as string).\n * After switching, activates the iTerm2 application itself so the window\n * comes to the foreground.\n *\n * Returns { ok: true } if AIBroker confirmed the switch, or\n * { ok: false, error } if AIBroker is not running or the session was not found.\n */\nexport async function switchToSession(target: string): Promise<{ ok: boolean; error?: string }> {\n try {\n await callAiBroker(\"switch\", { target });\n // Bring iTerm2 itself to the foreground (the IPC only selects the tab)\n const { spawnSync } = await import(\"node:child_process\");\n spawnSync(\"osascript\", [\"-e\", 'tell application \"iTerm\" to activate'], {\n stdio: \"ignore\",\n });\n return { ok: true };\n } catch (e) {\n return { ok: false, error: String(e) };\n }\n}\n\n/**\n * Bring the iTerm2 tab containing a specific session to the front.\n *\n * This is the mechanism AIBroker's screenshot path uses: match the session by\n * its iTerm2 session id (the `sessionId` returned by `fetchLiveSessions`, which\n * is iTerm's own `id of session`), then `select` its window, tab, and session.\n * Unlike the `switch` IPC (which only flips an internal index and never touches\n * iTerm), this actually reveals the tab.\n */\nexport function revealItermSession(itermSessionId: string): { ok: boolean; error?: string } {\n // Strip any \"iterm:\" style prefix, matching AIBroker's stripItermPrefix.\n const id = itermSessionId.replace(/^iterm:/i, \"\").trim();\n const script = `tell application \"iTerm2\"\n activate\n repeat with w in windows\n repeat with t in tabs of w\n repeat with s in sessions of t\n if id of s is \"${id}\" then\n select w\n select t\n select s\n return \"ok\"\n end if\n end repeat\n end repeat\n end repeat\n return \"not-found\"\nend tell`;\n try {\n const r = spawnSync(\"osascript\", [\"-e\", script], { encoding: \"utf8\" });\n if (r.status !== 0) {\n return { ok: false, error: (r.stderr || \"osascript failed\").trim() };\n }\n if ((r.stdout ?? \"\").trim() === \"ok\") return { ok: true };\n return { ok: false, error: \"session not found in any iTerm2 window\" };\n } catch (e) {\n return { ok: false, error: String(e) };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;AAmDA,MAAM,iBAAiB,QAAQ,IAAI,mBAAmB,oBAAoB;;;;;;;;;;;;;;;AAgB1E,MAAM,kBAAkB;;;;;;;;;;;;AAaxB,SAAgB,aACd,QACA,SAAkC,EAAE,EACpC,YAAY,KACsB;AAClC,QAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,aAAa;EACnB,IAAI,OAAO;EACX,IAAI,SAAS;EACb,IAAI,QAA8C;EAElD,SAAS,OAAO,KAAmB,OAAuC;AACxE,OAAI,KAAM;AACV,UAAO;AACP,OAAI,UAAU,MAAM;AAClB,iBAAa,MAAM;AACnB,YAAQ;;AAEV,OAAI;AACF,WAAO,SAAS;WACV;AAGR,OAAI,IAAK,QAAO,IAAI;OACf,SAAQ,MAAO;;EAGtB,MAAM,SAAS,QAAQ,kBAAkB;GACvC,MAAM,UAAU;IACd,IAAI,YAAY;IAChB,WAAW,QAAQ,IAAI,mBAAmB;IAC1C;IACA;IACD;GACD,MAAM,UAAU,QAAQ,IAAI;AAC5B,OAAI,QAAS,QAAO,OAAO,SAAS,EAAE,gBAAgB,SAAS,CAAC;AAChE,UAAO,MAAM,KAAK,UAAU,QAAQ,GAAG,KAAK;IAC5C;AAEF,SAAO,GAAG,SAAS,UAAkB;AACnC,aAAU,MAAM,SAAS,OAAO;GAChC,MAAM,KAAK,OAAO,QAAQ,KAAK;AAC/B,OAAI,OAAO,GAAI;GACf,MAAM,OAAO,OAAO,MAAM,GAAG,GAAG;GAEhC,IAAI;AACJ,OAAI;AACF,eAAW,KAAK,MAAM,KAAK;WACrB;AACN,2BAAO,IAAI,MAAM,6BAA6B,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC;AACpE;;AAGF,OAAI,CAAC,SAAS,GACZ,QAAO,IAAI,MAAM,SAAS,SAAS,2BAA2B,CAAC;OAE/D,QAAO,MAAM,SAAS,UAAU,EAAE,CAAC;IAErC;AAEF,SAAO,GAAG,UAAU,MAA6B;AAC/C,OAAI,EAAE,SAAS,YAAY,EAAE,SAAS,eACpC,wBAAO,IAAI,MAAM,2CAA2C,CAAC;OAE7D,QAAO,EAAE;IAEX;AAEF,SAAO,GAAG,aAAa;AACrB,OAAI,CAAC,KAAM,wBAAO,IAAI,MAAM,kDAAkD,CAAC;IAC/E;AAEF,UAAQ,iBACA,uBAAO,IAAI,MAAM,+BAA+B,CAAC,EACvD,UACD;GACD;;;;;;;;;AAcJ,eAAsB,oBAAoD;AACxE,KAAI;EAEF,MAAM,YADS,MAAM,aAAa,YAAY,EAAE,CAAC,EACc;AAC/D,MAAI,CAAC,MAAM,QAAQ,SAAS,CAAE,QAAO,EAAE;AACvC,SAAO;SACD;AACN,SAAO,EAAE;;;;;;;;;;;;;;;;;;AAsFb,eAAsB,cACpB,WACA,MACA,YAAY,iBACkD;AAC9D,KAAI;AACF,QAAM,aAAa,mBAAmB;GAAE,QAAQ;GAAW,SAAS;GAAM,EAAE,UAAU;AACtF,SAAO,EAAE,IAAI,MAAM;UACZ,GAAG;EACV,MAAM,QAAQ,OAAO,EAAE;AAOvB,SAAO;GAAE,IAAI;GAAO;GAAO,UAAU,aAAa,KAAK,MAAM;GAAE;;;;;;;;;;;;;AAcnE,eAAsB,gBAAgB,QAA0D;AAC9F,KAAI;AACF,QAAM,aAAa,UAAU,EAAE,QAAQ,CAAC;EAExC,MAAM,EAAE,cAAc,MAAM,OAAO;AACnC,YAAU,aAAa,CAAC,MAAM,yCAAuC,EAAE,EACrE,OAAO,UACR,CAAC;AACF,SAAO,EAAE,IAAI,MAAM;UACZ,GAAG;AACV,SAAO;GAAE,IAAI;GAAO,OAAO,OAAO,EAAE;GAAE;;;;;;;;;;;;AAa1C,SAAgB,mBAAmB,gBAAyD;CAG1F,MAAM,SAAS;;;;;yBADJ,eAAe,QAAQ,YAAY,GAAG,CAAC,MAAM,CAM9B;;;;;;;;;;;AAW1B,KAAI;EACF,MAAM,IAAI,UAAU,aAAa,CAAC,MAAM,OAAO,EAAE,EAAE,UAAU,QAAQ,CAAC;AACtE,MAAI,EAAE,WAAW,EACf,QAAO;GAAE,IAAI;GAAO,QAAQ,EAAE,UAAU,oBAAoB,MAAM;GAAE;AAEtE,OAAK,EAAE,UAAU,IAAI,MAAM,KAAK,KAAM,QAAO,EAAE,IAAI,MAAM;AACzD,SAAO;GAAE,IAAI;GAAO,OAAO;GAA0C;UAC9D,GAAG;AACV,SAAO;GAAE,IAAI;GAAO,OAAO,OAAO,EAAE;GAAE"}
|
|
1
|
+
{"version":3,"file":"aibroker-client-DzkTpVjx.mjs","names":[],"sources":["../src/cli/lib/aibroker-client.ts"],"sourcesContent":["/**\n * aibroker-client.ts — Lightweight IPC client for AIBroker daemon.\n *\n * Connects to the AIBroker Unix Domain Socket, sends a JSON-RPC request,\n * and reads a single newline-terminated JSON response. No class needed —\n * just a thin async function matching the WatcherClient protocol.\n *\n * Socket path: /tmp/aibroker.sock (default; override via AIBROKER_SOCKET env).\n */\n\nimport { connect } from \"node:net\";\nimport { randomUUID } from \"node:crypto\";\nimport { spawnSync } from \"node:child_process\";\nimport { aibrokerSocketPath } from \"../../runtime-paths.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Lightweight session metadata returned by the AIBroker `sessions` IPC method.\n * Does NOT include scrollback content — use `session_content` for that.\n */\nexport interface AiBrokerSessionMeta {\n index: number;\n sessionId: string;\n /** iTerm2 tab title or profile name */\n name: string;\n /** PAI session name set via /Name; null for bare shells */\n paiName: string | null;\n atPrompt: boolean;\n /** \"claude\" for Claude Code panes, \"shell\" for bare terminals */\n kind: \"claude\" | \"shell\";\n /** Whether this is the currently focused pane */\n active: boolean;\n /** Last user prompt seen in scrollback (only populated by fetchLiveSessionsWithPrompts) */\n lastPrompt?: string;\n}\n\ninterface AiBrokerSessionsResult {\n sessions: AiBrokerSessionMeta[];\n}\n\n// ---------------------------------------------------------------------------\n// Core call\n// ---------------------------------------------------------------------------\n\n// AIBROKER_SOCKET stays first: it is AIBroker's own variable and a user who has\n// set it means it. The fallback goes through runtime-paths so the test guard\n// can redirect it — writing to a live socket from a test is the same hazard as\n// writing to live user state, and this one is not even ours.\nconst DEFAULT_SOCKET = process.env.AIBROKER_SOCKET ?? aibrokerSocketPath();\n\n/**\n * How long to wait for `send_to_session`, which must exceed the server's own\n * ack window or the caller gives up while the callee is still working.\n *\n * AIBroker waits up to SEND_ACK_TIMEOUT_MS (15s) for the submit confirmation —\n * the text leaving the input line — before answering. The generic client\n * timeout is 8s. So every send needing 8-15s to confirm reported\n * \"AIBroker IPC call timed out\" while succeeding, and the handler's eventual\n * `delivered: true` was written into a socket nobody was reading any more.\n *\n * Measured on `pai pause all` across 15 sessions: 9 reported failed, 8 of them\n * verifiably paused. A caller's deadline shorter than the callee's is not a\n * tuning question, it is a guaranteed false negative on every slow success.\n */\nconst SEND_TIMEOUT_MS = 30_000;\n\n/**\n * Call an AIBroker IPC method and return the result.\n *\n * Resolves with the `result` field of a successful response.\n * Rejects if the socket is not available, the call times out, or the\n * daemon returns an error.\n *\n * @param method IPC method name (e.g. \"session_content\", \"send_to_session\")\n * @param params Method parameters object\n * @param timeoutMs Connection + response timeout in milliseconds (default: 8 000)\n */\nexport function callAiBroker(\n method: string,\n params: Record<string, unknown> = {},\n timeoutMs = 8_000\n): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const socketPath = DEFAULT_SOCKET;\n let done = false;\n let buffer = \"\";\n let timer: ReturnType<typeof setTimeout> | null = null;\n\n function finish(err: Error | null, value?: Record<string, unknown>): void {\n if (done) return;\n done = true;\n if (timer !== null) {\n clearTimeout(timer);\n timer = null;\n }\n try {\n socket.destroy();\n } catch {\n /* ignore */\n }\n if (err) reject(err);\n else resolve(value!);\n }\n\n const socket = connect(socketPath, () => {\n const request = {\n id: randomUUID(),\n sessionId: process.env.TERM_SESSION_ID ?? \"pai-cli\",\n method,\n params,\n };\n const itermId = process.env.ITERM_SESSION_ID;\n if (itermId) Object.assign(request, { itermSessionId: itermId });\n socket.write(JSON.stringify(request) + \"\\n\");\n });\n\n socket.on(\"data\", (chunk: Buffer) => {\n buffer += chunk.toString(\"utf8\");\n const nl = buffer.indexOf(\"\\n\");\n if (nl === -1) return;\n const line = buffer.slice(0, nl);\n\n let response: { ok: boolean; result?: Record<string, unknown>; error?: string };\n try {\n response = JSON.parse(line);\n } catch {\n finish(new Error(`AIBroker IPC parse error: ${line.slice(0, 120)}`));\n return;\n }\n\n if (!response.ok) {\n finish(new Error(response.error ?? \"AIBroker IPC call failed\"));\n } else {\n finish(null, response.result ?? {});\n }\n });\n\n socket.on(\"error\", (e: NodeJS.ErrnoException) => {\n if (e.code === \"ENOENT\" || e.code === \"ECONNREFUSED\") {\n finish(new Error(\"AIBroker not running (socket not found).\"));\n } else {\n finish(e);\n }\n });\n\n socket.on(\"end\", () => {\n if (!done) finish(new Error(\"AIBroker IPC connection closed before response.\"));\n });\n\n timer = setTimeout(\n () => finish(new Error(\"AIBroker IPC call timed out.\")),\n timeoutMs\n );\n });\n}\n\n// ---------------------------------------------------------------------------\n// Typed helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch all live iTerm2 session metadata from AIBroker via the `sessions` method.\n * Returns an empty array if AIBroker is not running.\n *\n * This is metadata-only (no scrollback). It is faster than `session_content`\n * and the correct source for listing/routing purposes.\n */\nexport async function fetchLiveSessions(): Promise<AiBrokerSessionMeta[]> {\n try {\n const result = await callAiBroker(\"sessions\", {});\n const sessions = (result as unknown as AiBrokerSessionsResult).sessions;\n if (!Array.isArray(sessions)) return [];\n return sessions;\n } catch {\n return [];\n }\n}\n\n/**\n * Fetch live sessions WITH the last user prompt extracted from terminal scrollback.\n *\n * Heavier than `fetchLiveSessions` (one IPC call returning full content for\n * every session), but yields a `lastPrompt` field useful for the unified\n * listing.\n */\nexport async function fetchLiveSessionsWithPrompts(): Promise<\n (AiBrokerSessionMeta & { lastPrompt?: string })[]\n> {\n // Get the basic metadata first (always works, fast).\n const metas = await fetchLiveSessions();\n if (metas.length === 0) return [];\n\n // Then enrich with last prompts via session_content (single call, all sessions).\n try {\n const contentResult = (await callAiBroker(\"session_content\", { lines: 60 })) as {\n sessions?: Array<{ sessionId: string; content?: string }>;\n };\n const contentMap = new Map<string, string>();\n for (const s of contentResult.sessions ?? []) {\n if (s.sessionId && typeof s.content === \"string\") {\n contentMap.set(s.sessionId, s.content);\n }\n }\n return metas.map((m) => {\n const content = contentMap.get(m.sessionId);\n const lastPrompt = content ? extractLastUserPrompt(content) : undefined;\n return { ...m, lastPrompt };\n });\n } catch {\n return metas.map((m) => ({ ...m }));\n }\n}\n\n/**\n * Extract the most-recent user prompt from a terminal scrollback string.\n *\n * Claude Code's TUI shows user input lines prefixed with `❯ `. We scan from\n * the bottom up, skipping the active input box (between the two horizontal\n * rule lines) and the statusline footer.\n */\nfunction extractLastUserPrompt(content: string): string | undefined {\n const lines = content.split(\"\\n\");\n // Walk bottom-up looking for the most recent user-typed line.\n // Claude Code marks user prompts with one of these prefixes:\n // ❯ <text> (current/recent prompt in the input box or scrollback)\n // > <text> (older variant)\n // The line MUST have non-empty content after the prompt symbol.\n // Skip the active input box (often empty `❯`) and statusline (👋 PAI CC...).\n for (let i = lines.length - 1; i >= 0; i--) {\n const line = lines[i].trim();\n // Match ❯ or > (followed by space) then content\n const m = line.match(/^[❯>]\\s+(.+?)\\s*$/);\n if (!m) continue;\n let text = m[1].trim();\n if (!text) continue;\n // Skip lines that are just box-drawing or known UI noise\n if (/^[─━═]+/.test(text)) continue;\n if (text.startsWith(\"👋\")) continue;\n // Strip ANSI escape sequences that may leak in\n text = text.replace(/\\x1B\\[[0-9;]*[A-Za-z]/g, \"\").trim();\n if (text) return text;\n }\n return undefined;\n}\n\n/**\n * Send text to a specific AIBroker session by its iTerm2 sessionId.\n *\n * The wire keys are `target` and `message`, and neither is negotiable — the\n * handler rejects anything else with \"target is required\" before it looks at\n * the rest. This was written as `{ target: sessionId, message: text }`, which is the shape of\n * THIS function's own parameters rather than the shape of the IPC, so every\n * call failed identically. `pai pause all` was the only caller, so the live\n * path had never once executed: its --dry-run branch returns before sending,\n * and that was the only branch anyone had exercised.\n *\n * The caller must NOT terminate `text` with a newline. The transport sends with\n * `enter: true` and appends the Enter itself, so a trailing \\n submits twice —\n * once for the text and once for an empty prompt.\n */\nexport async function sendToSession(\n sessionId: string,\n text: string,\n timeoutMs = SEND_TIMEOUT_MS,\n opts?: { noReply?: boolean }\n): Promise<{ ok: boolean; error?: string; timedOut?: boolean }> {\n try {\n const params: Record<string, unknown> = { target: sessionId, message: text };\n if (opts?.noReply) params.noReply = true;\n await callAiBroker(\"send_to_session\", params, timeoutMs);\n return { ok: true };\n } catch (e) {\n const error = String(e);\n const timedOut = /timed out/i.test(error);\n // A timeout is NOT a delivery failure, and conflating the two is expensive.\n // The handler deposits into the target's mailbox BEFORE it waits for the\n // submit ack, so a send that times out has still been delivered — only the\n // confirmation is missing. Reported as a plain failure, the natural response\n // is to send again, which is how `pai pause all` produced nested\n // \"carried forward\" blocks in checkpoints that had already been written.\n // With noReply there is no mailbox deposit at all, so a timeout there really\n // is an unknown/failed delivery, not just a missing confirmation.\n if (opts?.noReply && timedOut) return { ok: false, timedOut: true, error };\n return { ok: false, error, timedOut };\n }\n}\n\n/**\n * Switch iTerm2 focus to the session identified by `target`.\n *\n * `target` can be a sessionId, paiName, or tab index number (as string).\n * After switching, activates the iTerm2 application itself so the window\n * comes to the foreground.\n *\n * Returns { ok: true } if AIBroker confirmed the switch, or\n * { ok: false, error } if AIBroker is not running or the session was not found.\n */\nexport async function switchToSession(target: string): Promise<{ ok: boolean; error?: string }> {\n try {\n await callAiBroker(\"switch\", { target });\n // Bring iTerm2 itself to the foreground (the IPC only selects the tab)\n const { spawnSync } = await import(\"node:child_process\");\n spawnSync(\"osascript\", [\"-e\", 'tell application \"iTerm\" to activate'], {\n stdio: \"ignore\",\n });\n return { ok: true };\n } catch (e) {\n return { ok: false, error: String(e) };\n }\n}\n\n/**\n * Bring the iTerm2 tab containing a specific session to the front.\n *\n * This is the mechanism AIBroker's screenshot path uses: match the session by\n * its iTerm2 session id (the `sessionId` returned by `fetchLiveSessions`, which\n * is iTerm's own `id of session`), then `select` its window, tab, and session.\n * Unlike the `switch` IPC (which only flips an internal index and never touches\n * iTerm), this actually reveals the tab.\n */\nexport function revealItermSession(itermSessionId: string): { ok: boolean; error?: string } {\n // Strip any \"iterm:\" style prefix, matching AIBroker's stripItermPrefix.\n const id = itermSessionId.replace(/^iterm:/i, \"\").trim();\n const script = `tell application \"iTerm2\"\n activate\n repeat with w in windows\n repeat with t in tabs of w\n repeat with s in sessions of t\n if id of s is \"${id}\" then\n select w\n select t\n select s\n return \"ok\"\n end if\n end repeat\n end repeat\n end repeat\n return \"not-found\"\nend tell`;\n try {\n const r = spawnSync(\"osascript\", [\"-e\", script], { encoding: \"utf8\" });\n if (r.status !== 0) {\n return { ok: false, error: (r.stderr || \"osascript failed\").trim() };\n }\n if ((r.stdout ?? \"\").trim() === \"ok\") return { ok: true };\n return { ok: false, error: \"session not found in any iTerm2 window\" };\n } catch (e) {\n return { ok: false, error: String(e) };\n }\n}\n"],"mappings":"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"}
|
package/dist/cli/index.mjs
CHANGED
|
@@ -7,20 +7,20 @@ import "../helpers-crDEr6S2.mjs";
|
|
|
7
7
|
import "../sync-Btcb6xA4.mjs";
|
|
8
8
|
import "../embeddings-DvRKcQyt.mjs";
|
|
9
9
|
import "../search-B69cQwDB.mjs";
|
|
10
|
-
import { n as drainStdio, t as buildProgram } from "../program-
|
|
10
|
+
import { n as drainStdio, t as buildProgram } from "../program-ClTUv9-k.mjs";
|
|
11
11
|
import "../context-handover-cache-yOuK9RIk.mjs";
|
|
12
12
|
import "../config-Bn9jpblO.mjs";
|
|
13
13
|
import "../config-DYXARgk8.mjs";
|
|
14
14
|
import "../run-TChOnMO_.mjs";
|
|
15
|
-
import "../session-keepalive-
|
|
15
|
+
import "../session-keepalive-BkLOTZf6.mjs";
|
|
16
16
|
import "../ipc-client-C6NryMMb.mjs";
|
|
17
17
|
import "../factory-Bt7TWQje.mjs";
|
|
18
18
|
import "../fallback-CIGspCSi.mjs";
|
|
19
19
|
import "../wakeup-Yk5lQ0jb.mjs";
|
|
20
|
-
import "../main-resolver-
|
|
20
|
+
import "../main-resolver-Dv-oC46Z.mjs";
|
|
21
21
|
import "../server-R9UkCn3v.mjs";
|
|
22
22
|
import "../state-DwrsOoMi.mjs";
|
|
23
|
-
import "../aibroker-client-
|
|
23
|
+
import "../aibroker-client-DzkTpVjx.mjs";
|
|
24
24
|
import "../chain-BBbVbWVv.mjs";
|
|
25
25
|
import { CommanderError } from "commander";
|
|
26
26
|
|
package/dist/cli/program.mjs
CHANGED
|
@@ -6,20 +6,20 @@ import "../helpers-crDEr6S2.mjs";
|
|
|
6
6
|
import "../sync-Btcb6xA4.mjs";
|
|
7
7
|
import "../embeddings-DvRKcQyt.mjs";
|
|
8
8
|
import "../search-B69cQwDB.mjs";
|
|
9
|
-
import { t as buildProgram } from "../program-
|
|
9
|
+
import { t as buildProgram } from "../program-ClTUv9-k.mjs";
|
|
10
10
|
import "../context-handover-cache-yOuK9RIk.mjs";
|
|
11
11
|
import "../config-Bn9jpblO.mjs";
|
|
12
12
|
import "../config-DYXARgk8.mjs";
|
|
13
13
|
import "../run-TChOnMO_.mjs";
|
|
14
|
-
import "../session-keepalive-
|
|
14
|
+
import "../session-keepalive-BkLOTZf6.mjs";
|
|
15
15
|
import "../ipc-client-C6NryMMb.mjs";
|
|
16
16
|
import "../factory-Bt7TWQje.mjs";
|
|
17
17
|
import "../fallback-CIGspCSi.mjs";
|
|
18
18
|
import "../wakeup-Yk5lQ0jb.mjs";
|
|
19
|
-
import "../main-resolver-
|
|
19
|
+
import "../main-resolver-Dv-oC46Z.mjs";
|
|
20
20
|
import "../server-R9UkCn3v.mjs";
|
|
21
21
|
import "../state-DwrsOoMi.mjs";
|
|
22
|
-
import "../aibroker-client-
|
|
22
|
+
import "../aibroker-client-DzkTpVjx.mjs";
|
|
23
23
|
import "../chain-BBbVbWVv.mjs";
|
|
24
24
|
|
|
25
25
|
export { buildProgram };
|
package/dist/daemon/index.mjs
CHANGED
|
@@ -11,14 +11,14 @@ import "../context-handover-cache-yOuK9RIk.mjs";
|
|
|
11
11
|
import { a as ensureConfigDir, s as loadConfig } from "../config-Bn9jpblO.mjs";
|
|
12
12
|
import "../config-DYXARgk8.mjs";
|
|
13
13
|
import "../run-TChOnMO_.mjs";
|
|
14
|
-
import "../session-keepalive-
|
|
14
|
+
import "../session-keepalive-BkLOTZf6.mjs";
|
|
15
15
|
import { t as PaiClient } from "../ipc-client-C6NryMMb.mjs";
|
|
16
16
|
import "../factory-Bt7TWQje.mjs";
|
|
17
17
|
import "../wakeup-Yk5lQ0jb.mjs";
|
|
18
18
|
import "../server-R9UkCn3v.mjs";
|
|
19
19
|
import "../state-DwrsOoMi.mjs";
|
|
20
|
-
import "../aibroker-client-
|
|
21
|
-
import { t as serve } from "../daemon-
|
|
20
|
+
import "../aibroker-client-DzkTpVjx.mjs";
|
|
21
|
+
import { t as serve } from "../daemon-COyx4FGM.mjs";
|
|
22
22
|
import "../router-DBAZfE7X.mjs";
|
|
23
23
|
import "../tools-BEqiJt_j.mjs";
|
|
24
24
|
import "../detector-DWXkeTlk.mjs";
|
|
@@ -10,13 +10,13 @@ import "./context-handover-cache-yOuK9RIk.mjs";
|
|
|
10
10
|
import "./config-Bn9jpblO.mjs";
|
|
11
11
|
import "./config-DYXARgk8.mjs";
|
|
12
12
|
import "./run-TChOnMO_.mjs";
|
|
13
|
-
import "./session-keepalive-
|
|
13
|
+
import "./session-keepalive-BkLOTZf6.mjs";
|
|
14
14
|
import "./factory-Bt7TWQje.mjs";
|
|
15
15
|
import "./wakeup-Yk5lQ0jb.mjs";
|
|
16
16
|
import "./server-R9UkCn3v.mjs";
|
|
17
17
|
import "./state-DwrsOoMi.mjs";
|
|
18
|
-
import "./aibroker-client-
|
|
19
|
-
import { t as serve } from "./daemon-
|
|
18
|
+
import "./aibroker-client-DzkTpVjx.mjs";
|
|
19
|
+
import { t as serve } from "./daemon-COyx4FGM.mjs";
|
|
20
20
|
import "./router-DBAZfE7X.mjs";
|
|
21
21
|
import "./tools-BEqiJt_j.mjs";
|
|
22
22
|
import "./detector-DWXkeTlk.mjs";
|
|
@@ -7,7 +7,7 @@ import { a as enqueue, c as loadQueue, o as getStats } from "./context-handover-
|
|
|
7
7
|
import { S as DEFAULT_NOTIFICATION_CONFIG, d as readMainConfigRaw, f as writeMainConfigRaw } from "./config-Bn9jpblO.mjs";
|
|
8
8
|
import { C as readWorkersSection } from "./config-DYXARgk8.mjs";
|
|
9
9
|
import { F as loadStatuses, L as nowStamp, M as isChatPane, P as loadStatus, T as appendLedger, g as itermForClaudeSession, k as alive, n as runWorker } from "./run-TChOnMO_.mjs";
|
|
10
|
-
import { n as runSessionKeepaliveTick } from "./session-keepalive-
|
|
10
|
+
import { n as runSessionKeepaliveTick } from "./session-keepalive-BkLOTZf6.mjs";
|
|
11
11
|
import { n as getBackendOutage, t as createStorageBackend } from "./factory-Bt7TWQje.mjs";
|
|
12
12
|
import { g as ledgerPath, h as eventsPath, y as workersLogDir } from "./server-R9UkCn3v.mjs";
|
|
13
13
|
import { A as vaultIndexInProgress, C as setShutdownRequested, D as shutdownRequested, E as setVaultIndexInProgress, O as startTime, S as setRegistryDb, T as setStorageBackend, _ as setIndexSchedulerTimer, a as indexInProgress, b as setLastVaultIndexTime, c as lastIndexTime, d as registryDb, f as setCacheKeepaliveTimer, g as setIndexInProgress, h as setEmbedSchedulerTimer, i as embedSchedulerTimer, k as storageBackend, l as lastVaultIndexTime, m as setEmbedInProgress, n as daemonConfig, o as indexSchedulerTimer, p as setDaemonConfig, r as embedInProgress, s as lastEmbedTime, t as cacheKeepaliveTimer, u as notificationConfig, v as setLastEmbedTime, w as setStartTime, x as setNotificationConfig, y as setLastIndexTime } from "./state-DwrsOoMi.mjs";
|
|
@@ -442,7 +442,7 @@ const aibrokerPush = async (logDir, target, ev) => {
|
|
|
442
442
|
const iterm = target.iterm ?? (target.claudeSession ? itermForClaudeSession(logDir, target.claudeSession) : null);
|
|
443
443
|
if (!iterm) return false;
|
|
444
444
|
try {
|
|
445
|
-
const { sendToSession } = await import("./aibroker-client-
|
|
445
|
+
const { sendToSession } = await import("./aibroker-client-CNfIBrl5.mjs");
|
|
446
446
|
const r = await sendToSession(iterm, ev.text);
|
|
447
447
|
return r.ok || r.timedOut === true;
|
|
448
448
|
} catch {
|
|
@@ -1964,4 +1964,4 @@ async function serve(config) {
|
|
|
1964
1964
|
|
|
1965
1965
|
//#endregion
|
|
1966
1966
|
export { serve as t };
|
|
1967
|
-
//# sourceMappingURL=daemon-
|
|
1967
|
+
//# sourceMappingURL=daemon-COyx4FGM.mjs.map
|