agent-theatre 1.1.3 → 1.2.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/cli.js +37 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +38 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/web/assets/browserAll-MBabRn1_.js +2 -0
- package/web/assets/{browserAll-CPur5J05.js.map → browserAll-MBabRn1_.js.map} +1 -1
- package/web/assets/{index-BcMndIlk.css → index-DUimS_fe.css} +1 -1
- package/web/assets/index-K7cJxdMz.js +956 -0
- package/web/assets/index-K7cJxdMz.js.map +1 -0
- package/web/assets/webworkerAll-tVQIHJQB.js +2 -0
- package/web/assets/{webworkerAll-BBlOlInV.js.map → webworkerAll-tVQIHJQB.js.map} +1 -1
- package/web/index.html +2 -2
- package/web/assets/browserAll-CPur5J05.js +0 -2
- package/web/assets/index-CDDD_0gz.js +0 -956
- package/web/assets/index-CDDD_0gz.js.map +0 -1
- package/web/assets/webworkerAll-BBlOlInV.js +0 -2
package/dist/index.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ declare class Theatre {
|
|
|
26
26
|
private wss;
|
|
27
27
|
private live;
|
|
28
28
|
private signal;
|
|
29
|
+
/** The most recent Claude Code session that spoke to this stage; what a prompt from the stage resumes. */
|
|
30
|
+
private lastSessionId;
|
|
29
31
|
private timer;
|
|
30
32
|
port: number;
|
|
31
33
|
constructor(opts: TheatreOptions);
|
|
@@ -38,6 +40,8 @@ declare class Theatre {
|
|
|
38
40
|
get url(): string;
|
|
39
41
|
get name(): string;
|
|
40
42
|
}
|
|
43
|
+
/** Claude Code 2.x on PATH, or the binary the VS Code extension ships; null if neither. Overridable with AGENT_THEATRE_CLAUDE. */
|
|
44
|
+
declare function claudeBinary(): string | null;
|
|
41
45
|
|
|
42
46
|
/** The repo's file tree as FileNodes. Counts lines only; never keeps contents. Bounded for huge repos. */
|
|
43
47
|
declare function scanRepo(root: string, opts?: {
|
|
@@ -81,4 +85,4 @@ declare function hooksStatus(paths?: InstallPaths): {
|
|
|
81
85
|
settings: string;
|
|
82
86
|
};
|
|
83
87
|
|
|
84
|
-
export { type InstallPaths, type SessionInfo, Theatre, type TheatreOptions, hooksStatus, installHooks, installPaths, listSessions, repoIdFor, scanRepo, sessionTitle, uninstallHooks };
|
|
88
|
+
export { type InstallPaths, type SessionInfo, Theatre, type TheatreOptions, claudeBinary, hooksStatus, installHooks, installPaths, listSessions, repoIdFor, scanRepo, sessionTitle, uninstallHooks };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// src/server.ts
|
|
2
2
|
import { createServer } from "http";
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync as readFileSync2, rmSync, writeFileSync, realpathSync } from "fs";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync as readFileSync2, readdirSync as readdirSync2, rmSync, writeFileSync, realpathSync } from "fs";
|
|
4
4
|
import { homedir as homedir2 } from "os";
|
|
5
5
|
import { join as join2, basename as basename2, resolve, sep } from "path";
|
|
6
|
+
import { spawn, spawnSync } from "child_process";
|
|
6
7
|
import { Hono } from "hono";
|
|
7
8
|
import { getRequestListener } from "@hono/node-server";
|
|
8
9
|
import { WebSocketServer } from "ws";
|
|
@@ -1186,6 +1187,8 @@ var Theatre = class {
|
|
|
1186
1187
|
wss = null;
|
|
1187
1188
|
live;
|
|
1188
1189
|
signal = "ok";
|
|
1190
|
+
/** The most recent Claude Code session that spoke to this stage; what a prompt from the stage resumes. */
|
|
1191
|
+
lastSessionId = null;
|
|
1189
1192
|
timer = null;
|
|
1190
1193
|
port = 0;
|
|
1191
1194
|
routes() {
|
|
@@ -1199,6 +1202,8 @@ var Theatre = class {
|
|
|
1199
1202
|
}
|
|
1200
1203
|
const cwd = typeof payload?.cwd === "string" ? payload.cwd : "";
|
|
1201
1204
|
if (cwd && !isWithin(cwd, this.opts.cwd)) return c.body(null, 204);
|
|
1205
|
+
const sid = payload.session_id;
|
|
1206
|
+
if (typeof sid === "string" && sid) this.lastSessionId = sid;
|
|
1202
1207
|
const { events } = hookPayloadToEvents(payload, { home: homedir2() });
|
|
1203
1208
|
if (events.length) this.ingest(events);
|
|
1204
1209
|
return c.body(null, 204);
|
|
@@ -1223,6 +1228,18 @@ var Theatre = class {
|
|
|
1223
1228
|
const beats = direct(events, world);
|
|
1224
1229
|
return c.json({ mode: "replay", repoId: this.opts.repoId, title: s.title, world, events, beats, warnings: warnings.length });
|
|
1225
1230
|
});
|
|
1231
|
+
a.get("/api/prompt", (c) => c.json({ available: !!claudeBinary() && !!this.lastSessionId, session: this.lastSessionId }));
|
|
1232
|
+
a.post("/api/prompt", async (c) => {
|
|
1233
|
+
const body = await c.req.json().catch(() => ({}));
|
|
1234
|
+
const text = typeof body.text === "string" ? body.text.trim() : "";
|
|
1235
|
+
const bin = claudeBinary();
|
|
1236
|
+
if (!text) return c.json({ ok: false, error: "empty prompt" }, 400);
|
|
1237
|
+
if (!bin) return c.json({ ok: false, error: "Claude Code 2.x not found on PATH" }, 503);
|
|
1238
|
+
if (!this.lastSessionId) return c.json({ ok: false, error: "no session to resume yet" }, 409);
|
|
1239
|
+
const child = spawn(bin, ["-p", "--resume", this.lastSessionId, text], { cwd: this.opts.cwd, stdio: "ignore", detached: true, env: process.env });
|
|
1240
|
+
child.unref();
|
|
1241
|
+
return c.json({ ok: true, session: this.lastSessionId });
|
|
1242
|
+
});
|
|
1226
1243
|
a.get("/healthz", (c) => c.json({ ok: true, port: this.port, events: this.live.events.length }));
|
|
1227
1244
|
if (this.opts.webDir) {
|
|
1228
1245
|
const dir = this.opts.webDir;
|
|
@@ -1316,9 +1333,26 @@ function isWithin(dir, root) {
|
|
|
1316
1333
|
const d = norm3(dir), r = norm3(root);
|
|
1317
1334
|
return d === r || d.startsWith(r.endsWith(sep) ? r : r + sep);
|
|
1318
1335
|
}
|
|
1336
|
+
function claudeBinary() {
|
|
1337
|
+
const cands = [process.env.AGENT_THEATRE_CLAUDE, "claude"].filter((x) => !!x);
|
|
1338
|
+
try {
|
|
1339
|
+
const ext = join2(homedir2(), ".vscode", "extensions");
|
|
1340
|
+
for (const d of (existsSync(ext) ? readdirSync2(ext) : []).filter((n) => n.startsWith("anthropic.claude-code-")).sort().reverse()) cands.push(join2(ext, d, "resources", "native-binary", "claude"));
|
|
1341
|
+
} catch {
|
|
1342
|
+
}
|
|
1343
|
+
for (const c of cands) {
|
|
1344
|
+
try {
|
|
1345
|
+
const r = spawnSync(c, ["--version"], { encoding: "utf8", timeout: 4e3 });
|
|
1346
|
+
const m = /^(\d+)\./.exec(r.stdout.trim());
|
|
1347
|
+
if (r.status === 0 && m && Number(m[1]) >= 2) return c;
|
|
1348
|
+
} catch {
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
return null;
|
|
1352
|
+
}
|
|
1319
1353
|
|
|
1320
1354
|
// src/scan.ts
|
|
1321
|
-
import { readdirSync as
|
|
1355
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
|
|
1322
1356
|
import { join as join3, relative } from "path";
|
|
1323
1357
|
function scanRepo(root, opts = {}) {
|
|
1324
1358
|
const maxFiles = opts.maxFiles ?? 2e4, maxBytes = opts.maxBytesForLoc ?? 512e3;
|
|
@@ -1327,7 +1361,7 @@ function scanRepo(root, opts = {}) {
|
|
|
1327
1361
|
if (files.length >= maxFiles) return;
|
|
1328
1362
|
let ents;
|
|
1329
1363
|
try {
|
|
1330
|
-
ents =
|
|
1364
|
+
ents = readdirSync3(dir, { withFileTypes: true });
|
|
1331
1365
|
} catch {
|
|
1332
1366
|
return;
|
|
1333
1367
|
}
|
|
@@ -1509,6 +1543,7 @@ function hooksStatus(paths = installPaths()) {
|
|
|
1509
1543
|
}
|
|
1510
1544
|
export {
|
|
1511
1545
|
Theatre,
|
|
1546
|
+
claudeBinary,
|
|
1512
1547
|
hooksStatus,
|
|
1513
1548
|
installHooks,
|
|
1514
1549
|
installPaths,
|