agent-theatre 1.3.3 → 1.3.5
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/cli.js +49 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +49 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/web/assets/browserAll-DaED764O.js +2 -0
- package/web/assets/{browserAll-DMruipHl.js.map → browserAll-DaED764O.js.map} +1 -1
- package/web/assets/{index-CSVCrpUG.js → index-CER3V845.js} +8 -7
- package/web/assets/index-CER3V845.js.map +1 -0
- package/web/assets/webworkerAll-ihAbZR47.js +2 -0
- package/web/assets/{webworkerAll-DVbAiE6j.js.map → webworkerAll-ihAbZR47.js.map} +1 -1
- package/web/index.html +1 -1
- package/web/assets/browserAll-DMruipHl.js +0 -2
- package/web/assets/index-CSVCrpUG.js.map +0 -1
- package/web/assets/webworkerAll-DVbAiE6j.js +0 -2
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ declare class Theatre {
|
|
|
30
30
|
private lastSessionId;
|
|
31
31
|
/** The most recent cwd of a Claude Code session that is NOT this repo (so an empty stage can point the person there). */
|
|
32
32
|
private elsewhere;
|
|
33
|
+
private readonly openSessions;
|
|
33
34
|
private timer;
|
|
34
35
|
port: number;
|
|
35
36
|
constructor(opts: TheatreOptions);
|
package/dist/index.js
CHANGED
|
@@ -72,11 +72,16 @@ function cleanTarget(t) {
|
|
|
72
72
|
if (/^\/dev\//.test(s) || /^&\d/.test(s)) return null;
|
|
73
73
|
return s;
|
|
74
74
|
}
|
|
75
|
-
function
|
|
75
|
+
function withoutHeredocBodies(command) {
|
|
76
|
+
return command.replace(/<<-?\s*(['"]?)([A-Za-z_][A-Za-z0-9_]*)\1[^\n]*\n[\s\S]*?\n\s*\2(?=\s*(?:\n|$))/g, (m) => m.split("\n")[0] ?? "");
|
|
77
|
+
}
|
|
78
|
+
var plausibleFile = (t) => /[A-Za-z/.]/.test(t) && !/^\d+$/.test(t) && !/[()]$/.test(t);
|
|
79
|
+
function extractWrites(commandRaw) {
|
|
80
|
+
const command = withoutHeredocBodies(commandRaw);
|
|
76
81
|
const out = /* @__PURE__ */ new Set();
|
|
77
82
|
for (const m of command.matchAll(/(?:^|[\s)])\d?>{1,2}\s*([^\s|&;<>]+)/g)) {
|
|
78
83
|
const t = cleanTarget(m[1] ?? "");
|
|
79
|
-
if (t) out.add(t);
|
|
84
|
+
if (t && plausibleFile(t)) out.add(t);
|
|
80
85
|
}
|
|
81
86
|
for (const m of command.matchAll(/\btee\s+(?:-[a-z]+\s+)*((?:[^\s|&;<>]+\s*)+)/g)) {
|
|
82
87
|
for (const f of (m[1] ?? "").split(/\s+/)) {
|
|
@@ -360,13 +365,15 @@ function hookPayloadToEvents(payload, opts = {}) {
|
|
|
360
365
|
}
|
|
361
366
|
function noteOf(text) {
|
|
362
367
|
if (!text) return {};
|
|
363
|
-
const clean = text.replace(/```[\s\S]*?```/g, " ").replace(/`([^`]*)`/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/\*+|#+|>+/g, "").replace(/(^|\s)_+|_+(?=\s|$)/g, "$1").replace(/^\s*[
|
|
368
|
+
const clean = text.replace(/```[\s\S]*?```/g, " ").replace(/`([^`]*)`/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/\*+|#+|>+/g, "").replace(/(^|\s)_+|_+(?=\s|$)/g, "$1").replace(/^\s*(?:[-•]|\d+[.)])\s+/gm, "").replace(/\s+/g, " ").trim();
|
|
364
369
|
if (!clean) return {};
|
|
365
|
-
const sentences = clean.
|
|
370
|
+
const sentences = clean.split(/(?<=[.!?])\s+(?=["'(A-Z])/).map((x) => x.trim()).filter(Boolean);
|
|
371
|
+
if (!sentences.length) return {};
|
|
366
372
|
const questions = sentences.filter((x) => x.endsWith("?"));
|
|
367
373
|
let note = questions.length ? questions[questions.length - 1] : sentences[0];
|
|
368
|
-
if (!questions.length) for (const
|
|
369
|
-
|
|
374
|
+
if (!questions.length) for (const raw of sentences.slice(1)) {
|
|
375
|
+
const next = /[.!?]$/.test(raw) ? raw : raw.replace(/[^.!?]*$/, "").trim();
|
|
376
|
+
if (!next || note.length + next.length + 1 > 160) break;
|
|
370
377
|
note = `${note} ${next}`;
|
|
371
378
|
}
|
|
372
379
|
if (note.length > 200) note = note.slice(0, 197).replace(/\s+\S*$/, "") + "\u2026";
|
|
@@ -915,7 +922,7 @@ var Director = class {
|
|
|
915
922
|
this.forge = world.places.find((p) => p.kind === "forge") ?? world.places[0];
|
|
916
923
|
this.dock = world.places.find((p) => p.kind === "dock") ?? this.forge;
|
|
917
924
|
this.maxGap = opts.maxGapMs ?? 2500;
|
|
918
|
-
this.msPerCell = opts.walkMsPerCell ??
|
|
925
|
+
this.msPerCell = opts.walkMsPerCell ?? 150;
|
|
919
926
|
this.mood = new MoodTracker(opts.lostWindowMs ?? 9e4);
|
|
920
927
|
this.actorAt.set("pip", this.forge.id);
|
|
921
928
|
}
|
|
@@ -1081,7 +1088,7 @@ var Director = class {
|
|
|
1081
1088
|
if (fromId === to.id) return;
|
|
1082
1089
|
const from = this.places.get(fromId) ?? this.forge;
|
|
1083
1090
|
const cells = Math.hypot(to.gx - from.gx, to.gy - from.gy);
|
|
1084
|
-
this.emit(e, actor, { kind: "walk_to", target: to.id }, clamp(Math.round(cells * this.msPerCell),
|
|
1091
|
+
this.emit(e, actor, { kind: "walk_to", target: to.id }, clamp(Math.round(cells * this.msPerCell), 700, 3500));
|
|
1085
1092
|
this.actorAt.set(actor, to.id);
|
|
1086
1093
|
}
|
|
1087
1094
|
raised = 0;
|
|
@@ -1206,6 +1213,7 @@ var Theatre = class {
|
|
|
1206
1213
|
lastSessionId = null;
|
|
1207
1214
|
/** The most recent cwd of a Claude Code session that is NOT this repo (so an empty stage can point the person there). */
|
|
1208
1215
|
elsewhere = null;
|
|
1216
|
+
openSessions = /* @__PURE__ */ new Set();
|
|
1209
1217
|
timer = null;
|
|
1210
1218
|
port = 0;
|
|
1211
1219
|
routes() {
|
|
@@ -1227,7 +1235,13 @@ var Theatre = class {
|
|
|
1227
1235
|
}
|
|
1228
1236
|
const sid = payload.session_id;
|
|
1229
1237
|
if (typeof sid === "string" && sid) this.lastSessionId = sid;
|
|
1230
|
-
const
|
|
1238
|
+
const hookName = payload.hook_event_name;
|
|
1239
|
+
if (typeof sid === "string" && sid) {
|
|
1240
|
+
if (hookName === "SessionEnd") this.openSessions.delete(sid);
|
|
1241
|
+
else this.openSessions.add(sid);
|
|
1242
|
+
}
|
|
1243
|
+
let { events } = hookPayloadToEvents(payload, { home: homedir2() });
|
|
1244
|
+
if (this.openSessions.size > 0) events = events.filter((e) => e.kind !== "session_end");
|
|
1231
1245
|
if (events.length) this.ingest(events);
|
|
1232
1246
|
return c.body(null, 204);
|
|
1233
1247
|
});
|
|
@@ -1259,8 +1273,33 @@ var Theatre = class {
|
|
|
1259
1273
|
if (!text) return c.json({ ok: false, error: "empty prompt" }, 400);
|
|
1260
1274
|
if (!bin) return c.json({ ok: false, error: "Claude Code 2.x not found on PATH" }, 503);
|
|
1261
1275
|
if (!this.lastSessionId) return c.json({ ok: false, error: "no session to resume yet" }, 409);
|
|
1262
|
-
const
|
|
1276
|
+
const logPath = join2(this.opts.home ?? join2(homedir2(), ".agent-theatre"), "prompt.log");
|
|
1277
|
+
const child = spawn(bin, ["-p", "--resume", this.lastSessionId, text], { cwd: this.opts.cwd, stdio: ["ignore", "pipe", "pipe"], detached: true, env: process.env });
|
|
1278
|
+
let err = "";
|
|
1279
|
+
child.stdout?.on("data", (d) => {
|
|
1280
|
+
try {
|
|
1281
|
+
writeFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] out: ${String(d).slice(0, 2e3)}
|
|
1282
|
+
`, { flag: "a" });
|
|
1283
|
+
} catch {
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
child.stderr?.on("data", (d) => {
|
|
1287
|
+
err += String(d);
|
|
1288
|
+
try {
|
|
1289
|
+
writeFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] err: ${String(d).slice(0, 2e3)}
|
|
1290
|
+
`, { flag: "a" });
|
|
1291
|
+
} catch {
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1263
1294
|
child.unref();
|
|
1295
|
+
const early = await new Promise((res) => {
|
|
1296
|
+
const t = setTimeout(() => res(null), 2500);
|
|
1297
|
+
child.once("exit", (code) => {
|
|
1298
|
+
clearTimeout(t);
|
|
1299
|
+
res(code ?? 1);
|
|
1300
|
+
});
|
|
1301
|
+
});
|
|
1302
|
+
if (early !== null && early !== 0) return c.json({ ok: false, error: `Claude Code exited ${early}: ${err.trim().split("\n").pop() ?? "see ~/.agent-theatre/prompt.log"}` }, 502);
|
|
1264
1303
|
return c.json({ ok: true, session: this.lastSessionId });
|
|
1265
1304
|
});
|
|
1266
1305
|
a.get("/healthz", (c) => c.json({ ok: true, port: this.port, events: this.live.events.length }));
|