agent-theatre 1.3.4 → 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-DZmL9FJ-.js.map → browserAll-DaED764O.js.map} +1 -1
- package/web/assets/{index-BiD-j7f6.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-8ZSiX6ZJ.js.map → webworkerAll-ihAbZR47.js.map} +1 -1
- package/web/index.html +1 -1
- package/web/assets/browserAll-DZmL9FJ-.js +0 -2
- package/web/assets/index-BiD-j7f6.js.map +0 -1
- package/web/assets/webworkerAll-8ZSiX6ZJ.js +0 -2
package/dist/cli.js
CHANGED
|
@@ -81,11 +81,16 @@ function cleanTarget(t) {
|
|
|
81
81
|
if (/^\/dev\//.test(s) || /^&\d/.test(s)) return null;
|
|
82
82
|
return s;
|
|
83
83
|
}
|
|
84
|
-
function
|
|
84
|
+
function withoutHeredocBodies(command) {
|
|
85
|
+
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] ?? "");
|
|
86
|
+
}
|
|
87
|
+
var plausibleFile = (t) => /[A-Za-z/.]/.test(t) && !/^\d+$/.test(t) && !/[()]$/.test(t);
|
|
88
|
+
function extractWrites(commandRaw) {
|
|
89
|
+
const command = withoutHeredocBodies(commandRaw);
|
|
85
90
|
const out = /* @__PURE__ */ new Set();
|
|
86
91
|
for (const m of command.matchAll(/(?:^|[\s)])\d?>{1,2}\s*([^\s|&;<>]+)/g)) {
|
|
87
92
|
const t = cleanTarget(m[1] ?? "");
|
|
88
|
-
if (t) out.add(t);
|
|
93
|
+
if (t && plausibleFile(t)) out.add(t);
|
|
89
94
|
}
|
|
90
95
|
for (const m of command.matchAll(/\btee\s+(?:-[a-z]+\s+)*((?:[^\s|&;<>]+\s*)+)/g)) {
|
|
91
96
|
for (const f of (m[1] ?? "").split(/\s+/)) {
|
|
@@ -369,13 +374,15 @@ function hookPayloadToEvents(payload, opts = {}) {
|
|
|
369
374
|
}
|
|
370
375
|
function noteOf(text) {
|
|
371
376
|
if (!text) return {};
|
|
372
|
-
const clean = text.replace(/```[\s\S]*?```/g, " ").replace(/`([^`]*)`/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/\*+|#+|>+/g, "").replace(/(^|\s)_+|_+(?=\s|$)/g, "$1").replace(/^\s*[
|
|
377
|
+
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();
|
|
373
378
|
if (!clean) return {};
|
|
374
|
-
const sentences = clean.
|
|
379
|
+
const sentences = clean.split(/(?<=[.!?])\s+(?=["'(A-Z])/).map((x) => x.trim()).filter(Boolean);
|
|
380
|
+
if (!sentences.length) return {};
|
|
375
381
|
const questions = sentences.filter((x) => x.endsWith("?"));
|
|
376
382
|
let note = questions.length ? questions[questions.length - 1] : sentences[0];
|
|
377
|
-
if (!questions.length) for (const
|
|
378
|
-
|
|
383
|
+
if (!questions.length) for (const raw of sentences.slice(1)) {
|
|
384
|
+
const next = /[.!?]$/.test(raw) ? raw : raw.replace(/[^.!?]*$/, "").trim();
|
|
385
|
+
if (!next || note.length + next.length + 1 > 160) break;
|
|
379
386
|
note = `${note} ${next}`;
|
|
380
387
|
}
|
|
381
388
|
if (note.length > 200) note = note.slice(0, 197).replace(/\s+\S*$/, "") + "\u2026";
|
|
@@ -924,7 +931,7 @@ var Director = class {
|
|
|
924
931
|
this.forge = world.places.find((p) => p.kind === "forge") ?? world.places[0];
|
|
925
932
|
this.dock = world.places.find((p) => p.kind === "dock") ?? this.forge;
|
|
926
933
|
this.maxGap = opts.maxGapMs ?? 2500;
|
|
927
|
-
this.msPerCell = opts.walkMsPerCell ??
|
|
934
|
+
this.msPerCell = opts.walkMsPerCell ?? 150;
|
|
928
935
|
this.mood = new MoodTracker(opts.lostWindowMs ?? 9e4);
|
|
929
936
|
this.actorAt.set("pip", this.forge.id);
|
|
930
937
|
}
|
|
@@ -1090,7 +1097,7 @@ var Director = class {
|
|
|
1090
1097
|
if (fromId === to.id) return;
|
|
1091
1098
|
const from = this.places.get(fromId) ?? this.forge;
|
|
1092
1099
|
const cells = Math.hypot(to.gx - from.gx, to.gy - from.gy);
|
|
1093
|
-
this.emit(e, actor, { kind: "walk_to", target: to.id }, clamp(Math.round(cells * this.msPerCell),
|
|
1100
|
+
this.emit(e, actor, { kind: "walk_to", target: to.id }, clamp(Math.round(cells * this.msPerCell), 700, 3500));
|
|
1094
1101
|
this.actorAt.set(actor, to.id);
|
|
1095
1102
|
}
|
|
1096
1103
|
raised = 0;
|
|
@@ -1215,6 +1222,7 @@ var Theatre = class {
|
|
|
1215
1222
|
lastSessionId = null;
|
|
1216
1223
|
/** The most recent cwd of a Claude Code session that is NOT this repo (so an empty stage can point the person there). */
|
|
1217
1224
|
elsewhere = null;
|
|
1225
|
+
openSessions = /* @__PURE__ */ new Set();
|
|
1218
1226
|
timer = null;
|
|
1219
1227
|
port = 0;
|
|
1220
1228
|
routes() {
|
|
@@ -1236,7 +1244,13 @@ var Theatre = class {
|
|
|
1236
1244
|
}
|
|
1237
1245
|
const sid = payload.session_id;
|
|
1238
1246
|
if (typeof sid === "string" && sid) this.lastSessionId = sid;
|
|
1239
|
-
const
|
|
1247
|
+
const hookName = payload.hook_event_name;
|
|
1248
|
+
if (typeof sid === "string" && sid) {
|
|
1249
|
+
if (hookName === "SessionEnd") this.openSessions.delete(sid);
|
|
1250
|
+
else this.openSessions.add(sid);
|
|
1251
|
+
}
|
|
1252
|
+
let { events } = hookPayloadToEvents(payload, { home: homedir2() });
|
|
1253
|
+
if (this.openSessions.size > 0) events = events.filter((e) => e.kind !== "session_end");
|
|
1240
1254
|
if (events.length) this.ingest(events);
|
|
1241
1255
|
return c.body(null, 204);
|
|
1242
1256
|
});
|
|
@@ -1268,8 +1282,33 @@ var Theatre = class {
|
|
|
1268
1282
|
if (!text) return c.json({ ok: false, error: "empty prompt" }, 400);
|
|
1269
1283
|
if (!bin) return c.json({ ok: false, error: "Claude Code 2.x not found on PATH" }, 503);
|
|
1270
1284
|
if (!this.lastSessionId) return c.json({ ok: false, error: "no session to resume yet" }, 409);
|
|
1271
|
-
const
|
|
1285
|
+
const logPath = join2(this.opts.home ?? join2(homedir2(), ".agent-theatre"), "prompt.log");
|
|
1286
|
+
const child = spawn(bin, ["-p", "--resume", this.lastSessionId, text], { cwd: this.opts.cwd, stdio: ["ignore", "pipe", "pipe"], detached: true, env: process.env });
|
|
1287
|
+
let err = "";
|
|
1288
|
+
child.stdout?.on("data", (d) => {
|
|
1289
|
+
try {
|
|
1290
|
+
writeFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] out: ${String(d).slice(0, 2e3)}
|
|
1291
|
+
`, { flag: "a" });
|
|
1292
|
+
} catch {
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
1295
|
+
child.stderr?.on("data", (d) => {
|
|
1296
|
+
err += String(d);
|
|
1297
|
+
try {
|
|
1298
|
+
writeFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] err: ${String(d).slice(0, 2e3)}
|
|
1299
|
+
`, { flag: "a" });
|
|
1300
|
+
} catch {
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1272
1303
|
child.unref();
|
|
1304
|
+
const early = await new Promise((res) => {
|
|
1305
|
+
const t = setTimeout(() => res(null), 2500);
|
|
1306
|
+
child.once("exit", (code) => {
|
|
1307
|
+
clearTimeout(t);
|
|
1308
|
+
res(code ?? 1);
|
|
1309
|
+
});
|
|
1310
|
+
});
|
|
1311
|
+
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);
|
|
1273
1312
|
return c.json({ ok: true, session: this.lastSessionId });
|
|
1274
1313
|
});
|
|
1275
1314
|
a.get("/healthz", (c) => c.json({ ok: true, port: this.port, events: this.live.events.length }));
|