aibroker 0.7.13 → 0.8.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 +47 -1
- package/dist/daemon/cli.js +13 -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 +24 -0
- package/dist/daemon/core-handlers.js.map +1 -1
- package/dist/daemon/dispatch-cli.d.ts +2 -0
- package/dist/daemon/dispatch-cli.d.ts.map +1 -0
- package/dist/daemon/dispatch-cli.js +113 -0
- package/dist/daemon/dispatch-cli.js.map +1 -0
- package/dist/daemon/dispatch.d.ts +136 -0
- package/dist/daemon/dispatch.d.ts.map +1 -0
- package/dist/daemon/dispatch.js +275 -0
- package/dist/daemon/dispatch.js.map +1 -0
- package/dist/daemon/pai-projects.d.ts +28 -0
- package/dist/daemon/pai-projects.d.ts.map +1 -1
- package/dist/daemon/pai-projects.js +40 -5
- package/dist/daemon/pai-projects.js.map +1 -1
- package/dist/daemon/sessions.d.ts +60 -0
- package/dist/daemon/sessions.d.ts.map +1 -0
- package/dist/daemon/sessions.js +597 -0
- package/dist/daemon/sessions.js.map +1 -0
- package/dist/mcp/index.js +2 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/transport/sync-facade.d.ts +6 -0
- package/dist/transport/sync-facade.d.ts.map +1 -1
- package/dist/transport/sync-facade.js +12 -0
- package/dist/transport/sync-facade.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* daemon/dispatch.ts — deliver a work order to a project's session.
|
|
3
|
+
*
|
|
4
|
+
* The transport half of PAI's task bus: PAI decides which project owns a task,
|
|
5
|
+
* hands us the project name plus a message body, and we resolve that to a live
|
|
6
|
+
* session and deliver it — spawning the session if none is running.
|
|
7
|
+
*
|
|
8
|
+
* ONE atomic call on purpose. A caller doing list → launch → send itself races:
|
|
9
|
+
* a session can start or die between the check and the send, and the caller ends
|
|
10
|
+
* up duplicating session-lifecycle logic it doesn't own.
|
|
11
|
+
*
|
|
12
|
+
* Outcomes are RESULTS, not errors. A task the bus can't route is an ordinary
|
|
13
|
+
* thing to report and move past — a batch must not abort because one project
|
|
14
|
+
* lacks an alias. Only genuine infrastructure failure throws.
|
|
15
|
+
*
|
|
16
|
+
* delivered — a live session accepted it
|
|
17
|
+
* spawned — no session ran; we launched one and it accepted it
|
|
18
|
+
* unlaunchable — no curated alias. Setup gap: `pai project name <id> <short>`
|
|
19
|
+
* unreachable — tab opened but the session never accepted input. Runtime bug.
|
|
20
|
+
* skipped — no live session and spawning was disabled
|
|
21
|
+
*
|
|
22
|
+
* `unlaunchable` and `unreachable` are deliberately distinct: the first is a
|
|
23
|
+
* missing alias, the second is a session that failed to come up. Collapsing
|
|
24
|
+
* them sends whoever reads the result looking in the wrong place.
|
|
25
|
+
*/
|
|
26
|
+
import { snapshotAllSessions } from "../transport/sync-facade.js";
|
|
27
|
+
import { findCuratedPaiProject, launchResolvedPaiProject, invalidatePaiProjectCache, } from "./pai-projects.js";
|
|
28
|
+
import { getAllPersistentSessionNames, lookupPersistentName } from "../core/persistence.js";
|
|
29
|
+
import { captureSession, typeIntoSession } from "../transport/sync-facade.js";
|
|
30
|
+
import { log } from "../core/log.js";
|
|
31
|
+
/** A spawned Claude needs to boot and run its `/Name … go` preamble first. */
|
|
32
|
+
const DEFAULT_SPAWN_TIMEOUT_MS = 90_000;
|
|
33
|
+
const DEFAULT_DELIVER_TIMEOUT_MS = 120_000;
|
|
34
|
+
const READY_POLL_MS = 1_000;
|
|
35
|
+
/**
|
|
36
|
+
* Routing prefix for dispatched work.
|
|
37
|
+
*
|
|
38
|
+
* Deliberately NOT `[Session:PAI]`. That prefix means "reply to the sender on
|
|
39
|
+
* this channel", and for a dispatched task there is no sender left to reply to —
|
|
40
|
+
* the CLI that sent it has already exited. Promising a reply path that doesn't
|
|
41
|
+
* exist is worse than promising none, so `[Task]` says: act on it, don't reply,
|
|
42
|
+
* report by closing it on the tracker.
|
|
43
|
+
*
|
|
44
|
+
* The body carries the same contract in words, because a session that has never
|
|
45
|
+
* seen `[Task]` before must still do the right thing.
|
|
46
|
+
*/
|
|
47
|
+
export const TASK_PREFIX = "[Task]";
|
|
48
|
+
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
49
|
+
const realIO = {
|
|
50
|
+
capture: (id) => captureSession(id, 60),
|
|
51
|
+
send: (id, text) => { typeIntoSession(id, text); },
|
|
52
|
+
sleep,
|
|
53
|
+
now: () => Date.now(),
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Find a running session for `project`.
|
|
57
|
+
*
|
|
58
|
+
* Matches the project's display name, canonical name and every curated alias,
|
|
59
|
+
* case-insensitively — session labels and aliases disagree on capitalisation
|
|
60
|
+
* often enough that an exact match silently spawns a duplicate tab.
|
|
61
|
+
*/
|
|
62
|
+
export function findSessionForProject(project, sessions) {
|
|
63
|
+
const wanted = new Set([project.displayName, project.name, project.slug, ...project.names]
|
|
64
|
+
.filter(Boolean)
|
|
65
|
+
.map((s) => s.toLowerCase()));
|
|
66
|
+
for (const s of sessions) {
|
|
67
|
+
const label = s.paiName ?? s.name;
|
|
68
|
+
if (label && wanted.has(label.toLowerCase()))
|
|
69
|
+
return { id: s.id, label };
|
|
70
|
+
}
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
/** Enumerate live sessions with their persistent (PAI) names resolved. */
|
|
74
|
+
function liveSessions() {
|
|
75
|
+
const snaps = snapshotAllSessions();
|
|
76
|
+
const persistent = getAllPersistentSessionNames();
|
|
77
|
+
return snaps.map((s) => ({
|
|
78
|
+
id: s.id,
|
|
79
|
+
name: s.name,
|
|
80
|
+
paiName: lookupPersistentName(persistent, s.id, s.aibrokerId),
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
/** The line Claude's input box is drawn on. */
|
|
84
|
+
const INPUT_LINE = /^\s*❯/;
|
|
85
|
+
/** Claude's input box: a prompt caret sitting inside a run of box-drawing rule. */
|
|
86
|
+
const CLAUDE_UI = /─{20,}/;
|
|
87
|
+
/** Collapse whitespace so wrapped/padded terminal text compares sanely. */
|
|
88
|
+
function flatten(s) { return s.replace(/\s+/g, " ").trim(); }
|
|
89
|
+
/**
|
|
90
|
+
* Wait until a freshly launched session can ACCEPT input.
|
|
91
|
+
*
|
|
92
|
+
* Note "accept", not "be idle". A launched session immediately runs its
|
|
93
|
+
* `/Name … go` preamble and stays busy for minutes; waiting for the screen to
|
|
94
|
+
* settle times out on a session that is perfectly healthy — which is exactly
|
|
95
|
+
* what the first version did. Claude Code queues typed input while it works, so
|
|
96
|
+
* the real gate is whether the input box has been drawn yet.
|
|
97
|
+
*/
|
|
98
|
+
export async function waitForReady(sessionId, timeoutMs, io = realIO) {
|
|
99
|
+
const deadline = io.now() + timeoutMs;
|
|
100
|
+
while (io.now() < deadline) {
|
|
101
|
+
await io.sleep(READY_POLL_MS);
|
|
102
|
+
const frame = io.capture(sessionId);
|
|
103
|
+
if (frame === null)
|
|
104
|
+
continue;
|
|
105
|
+
if (isClaudeReady(frame))
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
/** True when a frame shows Claude's input box drawn and ready to take text. */
|
|
111
|
+
export function isClaudeReady(frame) {
|
|
112
|
+
return CLAUDE_UI.test(frame) && frame.split("\n").some((l) => INPUT_LINE.test(l));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Type `body` into a session and confirm Claude actually took it.
|
|
116
|
+
*
|
|
117
|
+
* Frame-counting (what `sessions checkpoint` uses) can't be trusted here: a
|
|
118
|
+
* session mid-task animates constantly, so "the screen changed" is true whether
|
|
119
|
+
* or not our text was submitted. Instead we use the one transition that only
|
|
120
|
+
* happens on submit — the text leaves the input box and appears above it:
|
|
121
|
+
*
|
|
122
|
+
* present in the frame, AND no longer on the ❯ input line -> submitted
|
|
123
|
+
*
|
|
124
|
+
* That works identically whether the session is idle or busy, which is the
|
|
125
|
+
* whole point for a freshly spawned session that is still running `go`.
|
|
126
|
+
*/
|
|
127
|
+
export async function submitAndConfirm(sessionId, body, timeoutMs, io = realIO, retries = 3) {
|
|
128
|
+
if (io.capture(sessionId) === null)
|
|
129
|
+
return "unreadable";
|
|
130
|
+
// A short distinctive slice: long bodies wrap and get truncated on screen.
|
|
131
|
+
const needle = flatten(body.split("\n").find((l) => l.trim().length > 0) ?? body).slice(0, 48);
|
|
132
|
+
if (!needle)
|
|
133
|
+
return "no-ack";
|
|
134
|
+
const perAttempt = Math.max(4000, Math.floor(timeoutMs / retries));
|
|
135
|
+
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
136
|
+
io.send(sessionId, body);
|
|
137
|
+
const deadline = io.now() + perAttempt;
|
|
138
|
+
while (io.now() < deadline) {
|
|
139
|
+
await io.sleep(500);
|
|
140
|
+
const frame = io.capture(sessionId);
|
|
141
|
+
if (frame === null)
|
|
142
|
+
continue;
|
|
143
|
+
if (hasBeenSubmitted(frame, needle))
|
|
144
|
+
return "ok";
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return "no-ack";
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Has `needle` left the input box and landed in the transcript?
|
|
151
|
+
*
|
|
152
|
+
* Present on screen is not enough — text sitting unsubmitted in the input box is
|
|
153
|
+
* also "present". Submission is the moment it appears while the ❯ line no longer
|
|
154
|
+
* holds it.
|
|
155
|
+
*/
|
|
156
|
+
export function hasBeenSubmitted(frame, needle) {
|
|
157
|
+
const stillTyped = inputBoxLines(frame).some((l) => flatten(l).includes(needle.slice(0, 24)));
|
|
158
|
+
return !stillTyped && flatten(frame).includes(needle);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* The lines inside Claude's input box.
|
|
162
|
+
*
|
|
163
|
+
* A caret alone will not do: Claude echoes each submitted message into the
|
|
164
|
+
* transcript with the SAME `❯` marker, so "a ❯ line contains our text" is true
|
|
165
|
+
* both before and after submitting — the check it was meant to power would
|
|
166
|
+
* never fire. The input box is identified structurally instead, as the region
|
|
167
|
+
* between the last two horizontal rules at the bottom of the frame.
|
|
168
|
+
*/
|
|
169
|
+
function inputBoxLines(frame) {
|
|
170
|
+
const lines = frame.split("\n");
|
|
171
|
+
const rules = [];
|
|
172
|
+
lines.forEach((l, i) => { if (CLAUDE_UI.test(l))
|
|
173
|
+
rules.push(i); });
|
|
174
|
+
if (rules.length >= 2) {
|
|
175
|
+
const [open, close] = [rules[rules.length - 2], rules[rules.length - 1]];
|
|
176
|
+
return lines.slice(open + 1, close);
|
|
177
|
+
}
|
|
178
|
+
return lines.filter((l) => INPUT_LINE.test(l)); // no box drawn — best effort
|
|
179
|
+
}
|
|
180
|
+
/** Production wiring for DispatchDeps. */
|
|
181
|
+
const realDeps = {
|
|
182
|
+
resolve: findCuratedPaiProject,
|
|
183
|
+
sessions: liveSessions,
|
|
184
|
+
deliver: submitAndConfirm,
|
|
185
|
+
launch: launchResolvedPaiProject,
|
|
186
|
+
waitReady: waitForReady,
|
|
187
|
+
};
|
|
188
|
+
function ackReason(res) {
|
|
189
|
+
switch (res) {
|
|
190
|
+
case "no-ack": return "session did not accept the message (never reacted)";
|
|
191
|
+
case "no-settle": return "session accepted the message but was still working when the timeout expired";
|
|
192
|
+
case "unreadable": return "session terminal could not be read";
|
|
193
|
+
default: return "";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Resolve `project` to a session and deliver `message`, spawning if needed.
|
|
198
|
+
*
|
|
199
|
+
* Never throws for a routing outcome — see the module comment.
|
|
200
|
+
*/
|
|
201
|
+
export async function dispatch(projectName, message, opts = {}, deps = realDeps) {
|
|
202
|
+
const spawnTimeoutMs = opts.spawnTimeoutMs ?? DEFAULT_SPAWN_TIMEOUT_MS;
|
|
203
|
+
const deliverTimeoutMs = opts.deliverTimeoutMs ?? DEFAULT_DELIVER_TIMEOUT_MS;
|
|
204
|
+
const project = await deps.resolve(projectName);
|
|
205
|
+
if (!project) {
|
|
206
|
+
return {
|
|
207
|
+
outcome: "unlaunchable",
|
|
208
|
+
project: projectName,
|
|
209
|
+
session: "",
|
|
210
|
+
reason: `No curated alias for "${projectName}". Bus participation is opt-in: ` +
|
|
211
|
+
`run \`pai project name <identifier> ${projectName}\` to register one.`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const label = project.displayName || project.name;
|
|
215
|
+
const body = `${TASK_PREFIX} ${message}`;
|
|
216
|
+
// ── already running? ──
|
|
217
|
+
const existing = findSessionForProject(project, deps.sessions());
|
|
218
|
+
if (existing) {
|
|
219
|
+
const res = await deps.deliver(existing.id, body, deliverTimeoutMs);
|
|
220
|
+
if (res === "ok") {
|
|
221
|
+
return { outcome: "delivered", project: label, session: existing.label, reason: "" };
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
outcome: "unreachable",
|
|
225
|
+
project: label,
|
|
226
|
+
session: existing.label,
|
|
227
|
+
reason: `Live session found but ${ackReason(res)}.`,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (opts.noSpawn) {
|
|
231
|
+
return {
|
|
232
|
+
outcome: "skipped",
|
|
233
|
+
project: label,
|
|
234
|
+
session: "",
|
|
235
|
+
reason: "No live session and spawning was disabled (--no-spawn).",
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
// ── spawn, wait for it to come up, then deliver ──
|
|
239
|
+
let itermSessionId;
|
|
240
|
+
try {
|
|
241
|
+
({ itermSessionId } = await deps.launch(project));
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
return {
|
|
245
|
+
outcome: "unreachable",
|
|
246
|
+
project: label,
|
|
247
|
+
session: "",
|
|
248
|
+
reason: `Failed to launch a session: ${err instanceof Error ? err.message : String(err)}`,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
invalidatePaiProjectCache();
|
|
252
|
+
log(`dispatch: launched "${label}" as ${itermSessionId}, waiting for it to accept input`);
|
|
253
|
+
if (!(await deps.waitReady(itermSessionId, spawnTimeoutMs))) {
|
|
254
|
+
return {
|
|
255
|
+
outcome: "unreachable",
|
|
256
|
+
project: label,
|
|
257
|
+
session: label,
|
|
258
|
+
reason: `Launched a session in ${project.rootPath} but it did not become ready ` +
|
|
259
|
+
`within ${Math.round(spawnTimeoutMs / 1000)}s. The tab is open — check why it did not start.`,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
const res = await deps.deliver(itermSessionId, body, deliverTimeoutMs);
|
|
263
|
+
if (res === "ok") {
|
|
264
|
+
return { outcome: "spawned", project: label, session: label, reason: "" };
|
|
265
|
+
}
|
|
266
|
+
// Deliberately NOT "spawned": the tab exists but the work order never landed,
|
|
267
|
+
// and reporting success here is how a task silently disappears.
|
|
268
|
+
return {
|
|
269
|
+
outcome: "unreachable",
|
|
270
|
+
project: label,
|
|
271
|
+
session: label,
|
|
272
|
+
reason: `Spawned a session but ${ackReason(res)}.`,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/daemon/dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,20 @@ export declare function invalidatePaiProjectCache(): void;
|
|
|
31
31
|
* Results are cached for 30 seconds.
|
|
32
32
|
*/
|
|
33
33
|
export declare function listPaiProjects(all?: boolean): Promise<PaiProject[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Find a project by any of its names or aliases, among CURATED projects only.
|
|
36
|
+
*
|
|
37
|
+
* Deliberately narrower than findPaiProject(). The `--all` set is ~118 entries
|
|
38
|
+
* with empty `names` and genuine ambiguity — three separate registry rows share
|
|
39
|
+
* the display name "Glidr" at different paths — so resolving a task against it
|
|
40
|
+
* silently dispatches work to the wrong directory. Bus participation therefore
|
|
41
|
+
* stays opt-in: a project joins by being given an alias
|
|
42
|
+
* (`pai project name <identifier> <shortname>`), and anything without one is
|
|
43
|
+
* reported as unlaunchable rather than guessed at.
|
|
44
|
+
*
|
|
45
|
+
* Matching is case-insensitive.
|
|
46
|
+
*/
|
|
47
|
+
export declare function findCuratedPaiProject(name: string): Promise<PaiProject | undefined>;
|
|
34
48
|
/**
|
|
35
49
|
* Find a project by any of its names or aliases.
|
|
36
50
|
* Matching is case-insensitive.
|
|
@@ -65,4 +79,18 @@ export declare function launchPaiProject(name: string): Promise<{
|
|
|
65
79
|
itermSessionId: string;
|
|
66
80
|
sessionId: string;
|
|
67
81
|
}>;
|
|
82
|
+
/**
|
|
83
|
+
* Launch an ALREADY-RESOLVED project.
|
|
84
|
+
*
|
|
85
|
+
* Callers that resolved against a narrower set than findPaiProject() must use
|
|
86
|
+
* this. Passing a name back into launchPaiProject() launders it through the
|
|
87
|
+
* `--all` set a second time, so a careful curated resolve can still end up
|
|
88
|
+
* opening a different project that happens to share the display name — there
|
|
89
|
+
* are three "Glidr" rows at three different paths. Once resolution has picked
|
|
90
|
+
* a row, that row is what gets launched.
|
|
91
|
+
*/
|
|
92
|
+
export declare function launchResolvedPaiProject(project: PaiProject): Promise<{
|
|
93
|
+
itermSessionId: string;
|
|
94
|
+
sessionId: string;
|
|
95
|
+
}>;
|
|
68
96
|
//# sourceMappingURL=pai-projects.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pai-projects.d.ts","sourceRoot":"","sources":["../../src/daemon/pai-projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAaD,0EAA0E;AAC1E,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AA+DD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,UAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAWxE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"pai-projects.d.ts","sourceRoot":"","sources":["../../src/daemon/pai-projects.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;CACH;AAaD,0EAA0E;AAC1E,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AA+DD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,UAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAWxE;AAcD;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEzF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAMlF;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,SAAS,CAAC,CAWb;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAMxD;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA6CxD"}
|
|
@@ -97,6 +97,31 @@ export async function listPaiProjects(all = false) {
|
|
|
97
97
|
log(`pai-projects: loaded ${projects.length} project(s)${all ? " (all)" : ""}`);
|
|
98
98
|
return projects;
|
|
99
99
|
}
|
|
100
|
+
/** Case-insensitive match of a needle against a project's name, aliases or slug. */
|
|
101
|
+
function matchProject(projects, name) {
|
|
102
|
+
const needle = name.trim().toLowerCase();
|
|
103
|
+
if (!needle)
|
|
104
|
+
return undefined;
|
|
105
|
+
return projects.find((p) => p.name.toLowerCase() === needle ||
|
|
106
|
+
p.names.some((n) => n.toLowerCase() === needle) ||
|
|
107
|
+
p.slug.toLowerCase() === needle);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Find a project by any of its names or aliases, among CURATED projects only.
|
|
111
|
+
*
|
|
112
|
+
* Deliberately narrower than findPaiProject(). The `--all` set is ~118 entries
|
|
113
|
+
* with empty `names` and genuine ambiguity — three separate registry rows share
|
|
114
|
+
* the display name "Glidr" at different paths — so resolving a task against it
|
|
115
|
+
* silently dispatches work to the wrong directory. Bus participation therefore
|
|
116
|
+
* stays opt-in: a project joins by being given an alias
|
|
117
|
+
* (`pai project name <identifier> <shortname>`), and anything without one is
|
|
118
|
+
* reported as unlaunchable rather than guessed at.
|
|
119
|
+
*
|
|
120
|
+
* Matching is case-insensitive.
|
|
121
|
+
*/
|
|
122
|
+
export async function findCuratedPaiProject(name) {
|
|
123
|
+
return matchProject(await listPaiProjects(false), name);
|
|
124
|
+
}
|
|
100
125
|
/**
|
|
101
126
|
* Find a project by any of its names or aliases.
|
|
102
127
|
* Matching is case-insensitive.
|
|
@@ -106,11 +131,7 @@ export async function findPaiProject(name) {
|
|
|
106
131
|
// the picker now offers every project (listPaiProjects(true)), so a launch of a
|
|
107
132
|
// non-shortlisted project (e.g. glidr) must resolve here too, or it fails with
|
|
108
133
|
// "project not found".
|
|
109
|
-
|
|
110
|
-
const needle = name.toLowerCase();
|
|
111
|
-
return projects.find((p) => p.name.toLowerCase() === needle ||
|
|
112
|
-
p.names.some((n) => n.toLowerCase() === needle) ||
|
|
113
|
-
p.slug.toLowerCase() === needle);
|
|
134
|
+
return matchProject(await listPaiProjects(true), name);
|
|
114
135
|
}
|
|
115
136
|
/**
|
|
116
137
|
* Get the effective (merged) config for a PAI project.
|
|
@@ -149,6 +170,20 @@ export async function launchPaiProject(name) {
|
|
|
149
170
|
if (!project) {
|
|
150
171
|
throw new Error(`PAI project "${name}" not found`);
|
|
151
172
|
}
|
|
173
|
+
return launchResolvedPaiProject(project);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Launch an ALREADY-RESOLVED project.
|
|
177
|
+
*
|
|
178
|
+
* Callers that resolved against a narrower set than findPaiProject() must use
|
|
179
|
+
* this. Passing a name back into launchPaiProject() launders it through the
|
|
180
|
+
* `--all` set a second time, so a careful curated resolve can still end up
|
|
181
|
+
* opening a different project that happens to share the display name — there
|
|
182
|
+
* are three "Glidr" rows at three different paths. Once resolution has picked
|
|
183
|
+
* a row, that row is what gets launched.
|
|
184
|
+
*/
|
|
185
|
+
export async function launchResolvedPaiProject(project) {
|
|
186
|
+
const name = project.name;
|
|
152
187
|
// Get effective config (project overrides global defaults)
|
|
153
188
|
const effective = await getEffectiveConfig(name) ?? project.sessionConfig ?? {};
|
|
154
189
|
const flags = effective.flags ?? "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pai-projects.js","sourceRoot":"","sources":["../../src/daemon/pai-projects.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"pai-projects.js","sourceRoot":"","sources":["../../src/daemon/pai-projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
interface Entry {
|
|
2
|
+
name: string;
|
|
3
|
+
cwd: string;
|
|
4
|
+
/** ISO timestamp of the last snapshot that saw this session open. */
|
|
5
|
+
lastSeen?: string;
|
|
6
|
+
/** ISO timestamp of the first snapshot that ever saw it. */
|
|
7
|
+
addedAt?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Union `fresh` (what is open right now) into `existing` (the restore list).
|
|
11
|
+
*
|
|
12
|
+
* Pure and exported so the property that actually matters is testable: this
|
|
13
|
+
* never returns fewer entries than `existing`. Every historical way of losing
|
|
14
|
+
* the manifest — /exit-ing tabs one by one, a daemon outage, an iTerm restart —
|
|
15
|
+
* reaches this function as a small or empty `fresh`, and must be a no-op rather
|
|
16
|
+
* than a truncation.
|
|
17
|
+
*/
|
|
18
|
+
export declare function mergeEntries(existing: Entry[], fresh: Entry[], now: string): Entry[];
|
|
19
|
+
export type AckResult = "ok" | "no-ack" | "no-settle" | "unreadable";
|
|
20
|
+
/** Injected so the ack state machine can be tested against a simulated terminal. */
|
|
21
|
+
export interface SessionProbe {
|
|
22
|
+
capture: (id: string) => string | null;
|
|
23
|
+
send: (id: string, text: string) => void;
|
|
24
|
+
sleep: (ms: number) => Promise<void>;
|
|
25
|
+
now: () => number;
|
|
26
|
+
onRetry?: (attempt: number, of: number) => void;
|
|
27
|
+
}
|
|
28
|
+
export declare const POLL_MS = 500;
|
|
29
|
+
/** Consecutive identical frames that mean "Claude stopped writing". */
|
|
30
|
+
export declare const SETTLE_TICKS = 4;
|
|
31
|
+
/** Distinct frames required before we believe the prompt was actually SUBMITTED. */
|
|
32
|
+
export declare const ACK_TRANSITIONS = 2;
|
|
33
|
+
/**
|
|
34
|
+
* Send `message` to one session and prove it was consumed.
|
|
35
|
+
*
|
|
36
|
+
* A successful `write text` only means keystrokes reached the terminal — not
|
|
37
|
+
* that Claude accepted the prompt. That gap is exactly what leaves you walking
|
|
38
|
+
* to every tab by hand after a hiccup. So we watch the screen instead.
|
|
39
|
+
*
|
|
40
|
+
* The subtlety: "the screen changed" is NOT proof of submission. Text typed into
|
|
41
|
+
* Claude's input box changes the screen too, so a send whose Enter was swallowed
|
|
42
|
+
* looks identical to a successful one for one frame — and then freezes. We
|
|
43
|
+
* therefore require ACK_TRANSITIONS *distinct* frames: a working Claude animates
|
|
44
|
+
* (spinner, streaming tokens) and trivially clears the bar, whereas text sitting
|
|
45
|
+
* unsubmitted in the box produces exactly one change and then stillness, so it
|
|
46
|
+
* correctly fails and retries.
|
|
47
|
+
*
|
|
48
|
+
* 1. send, then poll for ACK_TRANSITIONS distinct frames -> genuinely submitted
|
|
49
|
+
* 2. poll until SETTLE_TICKS identical frames -> Claude finished
|
|
50
|
+
*
|
|
51
|
+
* Frame-diffing is deliberately content-agnostic: it never parses what `pause
|
|
52
|
+
* session` prints, so it keeps working when that output changes.
|
|
53
|
+
*/
|
|
54
|
+
export declare function sendVerified(sessionId: string, message: string, opts: {
|
|
55
|
+
timeoutMs: number;
|
|
56
|
+
retries: number;
|
|
57
|
+
}, probe: SessionProbe): Promise<AckResult>;
|
|
58
|
+
export declare function runSessions(args: string[]): Promise<void>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/daemon/sessions.ts"],"names":[],"mappings":"AAmDA,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyHD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,EAAE,CAYpF;AAqED,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,CAAC;AAErE,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,eAAO,MAAM,OAAO,MAAM,CAAC;AAC3B,uEAAuE;AACvE,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,oFAAoF;AACpF,eAAO,MAAM,eAAe,IAAI,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAC5C,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,SAAS,CAAC,CAoCpB;AA8JD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAU/D"}
|