@threadbase-sh/streamer 1.15.3 → 1.16.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.cjs +6131 -5654
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +64 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +65 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -596,6 +596,7 @@ type ApiDeps = {
|
|
|
596
596
|
handleGetOutput: (sessionId: string, res: ServerResponse) => void;
|
|
597
597
|
handleSendInput: (sessionId: string, req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
598
598
|
handleCancel: (sessionId: string, res: ServerResponse) => void;
|
|
599
|
+
handleStopSession: (sessionId: string, res: ServerResponse) => Promise<void>;
|
|
599
600
|
handleSetSessionName: (sessionId: string, req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
600
601
|
handleUploadFile: (sessionId: string, req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
601
602
|
handleAdopt: (sessionId: string, res: ServerResponse) => Promise<void>;
|
|
@@ -725,6 +726,7 @@ declare class StreamerServer {
|
|
|
725
726
|
private log;
|
|
726
727
|
private agentConfig;
|
|
727
728
|
private agentClient;
|
|
729
|
+
private sessionStatusBus;
|
|
728
730
|
constructor(config: ServerConfig & {
|
|
729
731
|
apiKey: string;
|
|
730
732
|
});
|
|
@@ -771,6 +773,7 @@ declare class StreamerServer {
|
|
|
771
773
|
private handleUploadFile;
|
|
772
774
|
private handleGetOutput;
|
|
773
775
|
private handleCancel;
|
|
776
|
+
private handleStopSession;
|
|
774
777
|
private handleAdopt;
|
|
775
778
|
private handleStartSession;
|
|
776
779
|
private linkSessionToProject;
|
package/dist/index.d.ts
CHANGED
|
@@ -596,6 +596,7 @@ type ApiDeps = {
|
|
|
596
596
|
handleGetOutput: (sessionId: string, res: ServerResponse) => void;
|
|
597
597
|
handleSendInput: (sessionId: string, req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
598
598
|
handleCancel: (sessionId: string, res: ServerResponse) => void;
|
|
599
|
+
handleStopSession: (sessionId: string, res: ServerResponse) => Promise<void>;
|
|
599
600
|
handleSetSessionName: (sessionId: string, req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
600
601
|
handleUploadFile: (sessionId: string, req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
|
601
602
|
handleAdopt: (sessionId: string, res: ServerResponse) => Promise<void>;
|
|
@@ -725,6 +726,7 @@ declare class StreamerServer {
|
|
|
725
726
|
private log;
|
|
726
727
|
private agentConfig;
|
|
727
728
|
private agentClient;
|
|
729
|
+
private sessionStatusBus;
|
|
728
730
|
constructor(config: ServerConfig & {
|
|
729
731
|
apiKey: string;
|
|
730
732
|
});
|
|
@@ -771,6 +773,7 @@ declare class StreamerServer {
|
|
|
771
773
|
private handleUploadFile;
|
|
772
774
|
private handleGetOutput;
|
|
773
775
|
private handleCancel;
|
|
776
|
+
private handleStopSession;
|
|
774
777
|
private handleAdopt;
|
|
775
778
|
private handleStartSession;
|
|
776
779
|
private linkSessionToProject;
|
package/dist/index.js
CHANGED
|
@@ -1189,6 +1189,7 @@ import {
|
|
|
1189
1189
|
ConversationScanner,
|
|
1190
1190
|
search
|
|
1191
1191
|
} from "@threadbase-sh/scanner";
|
|
1192
|
+
import { EventEmitter } from "events";
|
|
1192
1193
|
import {
|
|
1193
1194
|
createReadStream,
|
|
1194
1195
|
existsSync as existsSync6,
|
|
@@ -1561,7 +1562,7 @@ var createConversationRoutes = (deps) => {
|
|
|
1561
1562
|
import { Hono as Hono4 } from "hono";
|
|
1562
1563
|
|
|
1563
1564
|
// src/version.ts
|
|
1564
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
1565
|
+
import { readFileSync as readFileSync3, realpathSync } from "fs";
|
|
1565
1566
|
import { dirname as dirname4, join as join6 } from "path";
|
|
1566
1567
|
var cached;
|
|
1567
1568
|
function getVersion() {
|
|
@@ -1572,7 +1573,13 @@ function getVersion() {
|
|
|
1572
1573
|
function resolveVersion() {
|
|
1573
1574
|
const scriptPath = process.argv[1] ?? "";
|
|
1574
1575
|
const here = scriptPath ? dirname4(scriptPath) : process.cwd();
|
|
1575
|
-
|
|
1576
|
+
let realHere = here;
|
|
1577
|
+
try {
|
|
1578
|
+
realHere = dirname4(realpathSync(scriptPath));
|
|
1579
|
+
} catch {
|
|
1580
|
+
}
|
|
1581
|
+
const searchDirs = realHere === here ? [here, join6(here, "..")] : [here, join6(here, ".."), realHere, join6(realHere, "..")];
|
|
1582
|
+
for (const dir of searchDirs) {
|
|
1576
1583
|
try {
|
|
1577
1584
|
const v = readFileSync3(join6(dir, "version.txt"), "utf8").trim();
|
|
1578
1585
|
if (v) return v;
|
|
@@ -1839,6 +1846,10 @@ var createSessionRoutes = (deps) => {
|
|
|
1839
1846
|
await deps.handleAdopt(c.req.param("id"), c.env.outgoing);
|
|
1840
1847
|
return alreadyHandled6();
|
|
1841
1848
|
});
|
|
1849
|
+
app.post("/:id/stop", async (c) => {
|
|
1850
|
+
await deps.handleStopSession(c.req.param("id"), c.env.outgoing);
|
|
1851
|
+
return alreadyHandled6();
|
|
1852
|
+
});
|
|
1842
1853
|
app.get("/:id", (c) => {
|
|
1843
1854
|
deps.handleGetSession(c.req.param("id"), c.env.outgoing);
|
|
1844
1855
|
return alreadyHandled6();
|
|
@@ -3921,7 +3932,9 @@ var StreamerServer = class {
|
|
|
3921
3932
|
log = getLogger("server");
|
|
3922
3933
|
agentConfig;
|
|
3923
3934
|
agentClient = null;
|
|
3935
|
+
sessionStatusBus = new EventEmitter();
|
|
3924
3936
|
constructor(config) {
|
|
3937
|
+
this.sessionStatusBus.setMaxListeners(0);
|
|
3925
3938
|
this.apiKey = config.apiKey;
|
|
3926
3939
|
this.localNoAuth = config.localNoAuth ?? false;
|
|
3927
3940
|
this.verbose = config.verbose ?? false;
|
|
@@ -4038,6 +4051,7 @@ var StreamerServer = class {
|
|
|
4038
4051
|
if (resp) {
|
|
4039
4052
|
this.wsHub.broadcast({ type: "session_update", session: resp });
|
|
4040
4053
|
}
|
|
4054
|
+
this.sessionStatusBus.emit(`status:${session.id}`, session.status);
|
|
4041
4055
|
}
|
|
4042
4056
|
});
|
|
4043
4057
|
this.agentConfig = readAgentConfig();
|
|
@@ -4083,6 +4097,7 @@ var StreamerServer = class {
|
|
|
4083
4097
|
handleGetOutput: (id, res) => this.handleGetOutput(id, res),
|
|
4084
4098
|
handleSendInput: (id, req, res) => this.handleSendInput(id, req, res),
|
|
4085
4099
|
handleCancel: (id, res) => this.handleCancel(id, res),
|
|
4100
|
+
handleStopSession: (id, res) => this.handleStopSession(id, res),
|
|
4086
4101
|
handleSetSessionName: (id, req, res) => this.handleSetSessionName(id, req, res),
|
|
4087
4102
|
handleUploadFile: (id, req, res) => this.handleUploadFile(id, req, res),
|
|
4088
4103
|
handleAdopt: (id, res) => this.handleAdopt(id, res),
|
|
@@ -5261,6 +5276,54 @@ var StreamerServer = class {
|
|
|
5261
5276
|
json(res, 400, { error: message });
|
|
5262
5277
|
}
|
|
5263
5278
|
}
|
|
5279
|
+
async handleStopSession(sessionId, res) {
|
|
5280
|
+
const STOP_TIMEOUT_MS = 5e3;
|
|
5281
|
+
const session = this.ptyManager.getSession(sessionId);
|
|
5282
|
+
if (!session) {
|
|
5283
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
5284
|
+
res.end(JSON.stringify({ error: "Session not found" }));
|
|
5285
|
+
return;
|
|
5286
|
+
}
|
|
5287
|
+
if (session.status === "idle") {
|
|
5288
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5289
|
+
res.end(JSON.stringify({ status: "already_idle", sessionId }));
|
|
5290
|
+
return;
|
|
5291
|
+
}
|
|
5292
|
+
res.writeHead(200, {
|
|
5293
|
+
"Content-Type": "application/x-ndjson",
|
|
5294
|
+
"Transfer-Encoding": "chunked",
|
|
5295
|
+
"Cache-Control": "no-cache",
|
|
5296
|
+
"X-Accel-Buffering": "no"
|
|
5297
|
+
});
|
|
5298
|
+
res.write(`${JSON.stringify({ event: "stopping", sessionId })}
|
|
5299
|
+
`);
|
|
5300
|
+
const idlePromise = new Promise((resolve2) => {
|
|
5301
|
+
const handler = (status) => {
|
|
5302
|
+
if (status === "idle") {
|
|
5303
|
+
this.sessionStatusBus.off(`status:${sessionId}`, handler);
|
|
5304
|
+
resolve2("idle");
|
|
5305
|
+
}
|
|
5306
|
+
};
|
|
5307
|
+
this.sessionStatusBus.on(`status:${sessionId}`, handler);
|
|
5308
|
+
});
|
|
5309
|
+
const timeoutPromise = new Promise(
|
|
5310
|
+
(resolve2) => setTimeout(() => resolve2("timeout"), STOP_TIMEOUT_MS)
|
|
5311
|
+
);
|
|
5312
|
+
this.ptyManager.putOnHold(sessionId);
|
|
5313
|
+
this.discoveryCache = null;
|
|
5314
|
+
const outcome = await Promise.race([idlePromise, timeoutPromise]);
|
|
5315
|
+
if (outcome === "idle") {
|
|
5316
|
+
res.write(`${JSON.stringify({ event: "stopped", sessionId })}
|
|
5317
|
+
`);
|
|
5318
|
+
} else {
|
|
5319
|
+
res.write(`${JSON.stringify({ event: "timeout", sessionId })}
|
|
5320
|
+
`);
|
|
5321
|
+
this.log.warn(
|
|
5322
|
+
`[stop] session ${sessionId.slice(0, 8)} did not idle within ${STOP_TIMEOUT_MS}ms`
|
|
5323
|
+
);
|
|
5324
|
+
}
|
|
5325
|
+
res.end();
|
|
5326
|
+
}
|
|
5264
5327
|
async handleAdopt(sessionId, res) {
|
|
5265
5328
|
const discovered = await discoverClaudeProcesses();
|
|
5266
5329
|
this.sessionStore.setDiscovered(discovered);
|