@threadbase-sh/streamer 1.31.1 → 1.31.3
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 +145 -55
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +28 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +28 -19
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/cli.cjs
CHANGED
|
@@ -29489,6 +29489,7 @@ var require_receiver = __commonJS({
|
|
|
29489
29489
|
this._opcode = 0;
|
|
29490
29490
|
this._totalPayloadLength = 0;
|
|
29491
29491
|
this._messageLength = 0;
|
|
29492
|
+
this._numFragments = 0;
|
|
29492
29493
|
this._fragments = [];
|
|
29493
29494
|
this._errored = false;
|
|
29494
29495
|
this._loop = false;
|
|
@@ -29839,23 +29840,23 @@ var require_receiver = __commonJS({
|
|
|
29839
29840
|
this.controlMessage(data, cb2);
|
|
29840
29841
|
return;
|
|
29841
29842
|
}
|
|
29843
|
+
if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) {
|
|
29844
|
+
const error51 = this.createError(
|
|
29845
|
+
RangeError,
|
|
29846
|
+
"Too many message fragments",
|
|
29847
|
+
false,
|
|
29848
|
+
1008,
|
|
29849
|
+
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
29850
|
+
);
|
|
29851
|
+
cb2(error51);
|
|
29852
|
+
return;
|
|
29853
|
+
}
|
|
29842
29854
|
if (this._compressed) {
|
|
29843
29855
|
this._state = INFLATING;
|
|
29844
29856
|
this.decompress(data, cb2);
|
|
29845
29857
|
return;
|
|
29846
29858
|
}
|
|
29847
29859
|
if (data.length) {
|
|
29848
|
-
if (this._maxFragments > 0 && this._fragments.length >= this._maxFragments) {
|
|
29849
|
-
const error51 = this.createError(
|
|
29850
|
-
RangeError,
|
|
29851
|
-
"Too many message fragments",
|
|
29852
|
-
false,
|
|
29853
|
-
1008,
|
|
29854
|
-
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
29855
|
-
);
|
|
29856
|
-
cb2(error51);
|
|
29857
|
-
return;
|
|
29858
|
-
}
|
|
29859
29860
|
this._messageLength = this._totalPayloadLength;
|
|
29860
29861
|
this._fragments.push(data);
|
|
29861
29862
|
}
|
|
@@ -29885,17 +29886,6 @@ var require_receiver = __commonJS({
|
|
|
29885
29886
|
cb2(error51);
|
|
29886
29887
|
return;
|
|
29887
29888
|
}
|
|
29888
|
-
if (this._maxFragments > 0 && this._fragments.length >= this._maxFragments) {
|
|
29889
|
-
const error51 = this.createError(
|
|
29890
|
-
RangeError,
|
|
29891
|
-
"Too many message fragments",
|
|
29892
|
-
false,
|
|
29893
|
-
1008,
|
|
29894
|
-
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
29895
|
-
);
|
|
29896
|
-
cb2(error51);
|
|
29897
|
-
return;
|
|
29898
|
-
}
|
|
29899
29889
|
this._fragments.push(buf);
|
|
29900
29890
|
}
|
|
29901
29891
|
this.dataMessage(cb2);
|
|
@@ -29918,6 +29908,7 @@ var require_receiver = __commonJS({
|
|
|
29918
29908
|
this._totalPayloadLength = 0;
|
|
29919
29909
|
this._messageLength = 0;
|
|
29920
29910
|
this._fragmented = 0;
|
|
29911
|
+
this._numFragments = 0;
|
|
29921
29912
|
this._fragments = [];
|
|
29922
29913
|
if (this._opcode === 2) {
|
|
29923
29914
|
let data;
|
|
@@ -31418,8 +31409,8 @@ var require_websocket = __commonJS({
|
|
|
31418
31409
|
autoPong: true,
|
|
31419
31410
|
closeTimeout: CLOSE_TIMEOUT,
|
|
31420
31411
|
protocolVersion: protocolVersions[1],
|
|
31421
|
-
maxBufferedChunks:
|
|
31422
|
-
maxFragments:
|
|
31412
|
+
maxBufferedChunks: 256 * 1024,
|
|
31413
|
+
maxFragments: 16 * 1024,
|
|
31423
31414
|
maxPayload: 100 * 1024 * 1024,
|
|
31424
31415
|
skipUTF8Validation: false,
|
|
31425
31416
|
perMessageDeflate: true,
|
|
@@ -32006,9 +31997,9 @@ var require_websocket_server = __commonJS({
|
|
|
32006
31997
|
* called
|
|
32007
31998
|
* @param {Function} [options.handleProtocols] A hook to handle protocols
|
|
32008
31999
|
* @param {String} [options.host] The hostname where to bind the server
|
|
32009
|
-
* @param {Number} [options.maxBufferedChunks=
|
|
32000
|
+
* @param {Number} [options.maxBufferedChunks=262144] The maximum number of
|
|
32010
32001
|
* buffered data chunks
|
|
32011
|
-
* @param {Number} [options.maxFragments=
|
|
32002
|
+
* @param {Number} [options.maxFragments=16384] The maximum number of message
|
|
32012
32003
|
* fragments
|
|
32013
32004
|
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
|
|
32014
32005
|
* size
|
|
@@ -32031,8 +32022,8 @@ var require_websocket_server = __commonJS({
|
|
|
32031
32022
|
options = {
|
|
32032
32023
|
allowSynchronousEvents: true,
|
|
32033
32024
|
autoPong: true,
|
|
32034
|
-
maxBufferedChunks:
|
|
32035
|
-
maxFragments:
|
|
32025
|
+
maxBufferedChunks: 256 * 1024,
|
|
32026
|
+
maxFragments: 16 * 1024,
|
|
32036
32027
|
maxPayload: 100 * 1024 * 1024,
|
|
32037
32028
|
skipUTF8Validation: false,
|
|
32038
32029
|
perMessageDeflate: false,
|
|
@@ -145337,14 +145328,8 @@ var StreamerServer = class {
|
|
|
145337
145328
|
this.conversationsRepo = new ConversationsRepository(this.cache);
|
|
145338
145329
|
this.sessionsRepo = new SessionsRepository(this.sessionStore);
|
|
145339
145330
|
this.cacheMetadataRepo = new CacheMetadataRepository(db);
|
|
145340
|
-
|
|
145341
|
-
|
|
145342
|
-
if (profile.enabled) {
|
|
145343
|
-
this.fileWatcher.watchDirectory((0, import_path23.join)(profile.configDir, "projects"));
|
|
145344
|
-
}
|
|
145345
|
-
}
|
|
145346
|
-
} else {
|
|
145347
|
-
this.fileWatcher.watchDirectory((0, import_path23.join)((0, import_os11.homedir)(), ".claude", "projects"));
|
|
145331
|
+
for (const dir of this.projectsDirs()) {
|
|
145332
|
+
this.fileWatcher.watchDirectory(dir);
|
|
145348
145333
|
}
|
|
145349
145334
|
} catch (err) {
|
|
145350
145335
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -145925,20 +145910,35 @@ var StreamerServer = class {
|
|
|
145925
145910
|
await this.scannerReady;
|
|
145926
145911
|
return scanner;
|
|
145927
145912
|
}
|
|
145913
|
+
/**
|
|
145914
|
+
* The projects dirs disk discovery should walk — the single source of truth
|
|
145915
|
+
* for "where do this server's JSONLs live", mirroring the warm-up watcher
|
|
145916
|
+
* (see listen()). Derived from the enabled scanProfiles' configDirs, or the
|
|
145917
|
+
* real ~/.claude/projects when no profiles are configured. An all-disabled
|
|
145918
|
+
* profile set intentionally yields [] (nothing to discover), matching the
|
|
145919
|
+
* watcher — it does NOT fall back to home in that case.
|
|
145920
|
+
*/
|
|
145921
|
+
projectsDirs() {
|
|
145922
|
+
if (this.scanProfiles && this.scanProfiles.length > 0) {
|
|
145923
|
+
return this.scanProfiles.filter((p2) => p2.enabled).map((p2) => (0, import_path23.join)(p2.configDir, "projects"));
|
|
145924
|
+
}
|
|
145925
|
+
return [(0, import_path23.join)((0, import_os11.homedir)(), ".claude", "projects")];
|
|
145926
|
+
}
|
|
145928
145927
|
findJsonlPath(uuid3) {
|
|
145929
|
-
const projectsDir = (0, import_path23.join)((0, import_os11.homedir)(), ".claude", "projects");
|
|
145930
|
-
if (!(0, import_fs26.existsSync)(projectsDir)) return null;
|
|
145931
145928
|
const filename = `${uuid3}.jsonl`;
|
|
145932
|
-
for (const
|
|
145933
|
-
|
|
145934
|
-
|
|
145935
|
-
|
|
145936
|
-
|
|
145937
|
-
|
|
145938
|
-
|
|
145939
|
-
|
|
145929
|
+
for (const projectsDir of this.projectsDirs()) {
|
|
145930
|
+
if (!(0, import_fs26.existsSync)(projectsDir)) continue;
|
|
145931
|
+
for (const dir of (0, import_fs26.readdirSync)(projectsDir)) {
|
|
145932
|
+
const fp = (0, import_path23.join)(projectsDir, dir, filename);
|
|
145933
|
+
if ((0, import_fs26.existsSync)(fp)) return fp;
|
|
145934
|
+
const projectDir = (0, import_path23.join)(projectsDir, dir);
|
|
145935
|
+
try {
|
|
145936
|
+
for (const sub of (0, import_fs26.readdirSync)(projectDir)) {
|
|
145937
|
+
const subagentPath = (0, import_path23.join)(projectDir, sub, "subagents", filename);
|
|
145938
|
+
if ((0, import_fs26.existsSync)(subagentPath)) return subagentPath;
|
|
145939
|
+
}
|
|
145940
|
+
} catch {
|
|
145940
145941
|
}
|
|
145941
|
-
} catch {
|
|
145942
145942
|
}
|
|
145943
145943
|
}
|
|
145944
145944
|
return null;
|
|
@@ -147757,7 +147757,81 @@ async function stopService(opts = {}) {
|
|
|
147757
147757
|
const { stdout: stdout2, stderr } = await execFileP("schtasks.exe", ["/End", "/TN", label]).catch(
|
|
147758
147758
|
(err) => ({ stdout: "", stderr: String(err) })
|
|
147759
147759
|
);
|
|
147760
|
-
|
|
147760
|
+
const listenerResult = await stopWindowsListener(opts.port ?? 8766);
|
|
147761
|
+
return {
|
|
147762
|
+
method: "schtasks-end",
|
|
147763
|
+
stdout: `${stdout2}
|
|
147764
|
+
${listenerResult.stdout}`,
|
|
147765
|
+
stderr: `${stderr}
|
|
147766
|
+
${listenerResult.stderr}`
|
|
147767
|
+
};
|
|
147768
|
+
}
|
|
147769
|
+
async function stopWindowsListener(port) {
|
|
147770
|
+
let netstat;
|
|
147771
|
+
try {
|
|
147772
|
+
netstat = await execFileP("netstat.exe", ["-ano", "-p", "tcp"]);
|
|
147773
|
+
} catch (err) {
|
|
147774
|
+
return { stdout: "", stderr: `Could not inspect port ${port}: ${String(err)}` };
|
|
147775
|
+
}
|
|
147776
|
+
const pids = /* @__PURE__ */ new Set();
|
|
147777
|
+
for (const line of netstat.stdout.split(/\r?\n/)) {
|
|
147778
|
+
const columns = line.trim().split(/\s+/);
|
|
147779
|
+
if (columns.length < 5 || columns[0]?.toUpperCase() !== "TCP") continue;
|
|
147780
|
+
const [localAddress, state, pid] = [columns[1], columns[3], columns[4]];
|
|
147781
|
+
if (state?.toUpperCase() !== "LISTENING" || !pid || pid === "0") continue;
|
|
147782
|
+
if (localAddress?.endsWith(`:${port}`)) pids.add(pid);
|
|
147783
|
+
}
|
|
147784
|
+
const output = [];
|
|
147785
|
+
const errors = [];
|
|
147786
|
+
for (const pid of pids) {
|
|
147787
|
+
try {
|
|
147788
|
+
const result = await execFileP("taskkill.exe", ["/PID", pid, "/T", "/F"]);
|
|
147789
|
+
output.push(result.stdout);
|
|
147790
|
+
if (result.stderr) errors.push(result.stderr);
|
|
147791
|
+
} catch (err) {
|
|
147792
|
+
errors.push(`Could not stop PID ${pid} on port ${port}: ${String(err)}`);
|
|
147793
|
+
}
|
|
147794
|
+
}
|
|
147795
|
+
return { stdout: output.join("\n"), stderr: errors.join("\n") };
|
|
147796
|
+
}
|
|
147797
|
+
|
|
147798
|
+
// src/updater/restart-health.ts
|
|
147799
|
+
function isExpectedVersion(actual, expected) {
|
|
147800
|
+
return actual === expected || actual.startsWith(`${expected}+`);
|
|
147801
|
+
}
|
|
147802
|
+
async function waitForRestartHealth(opts) {
|
|
147803
|
+
const timeoutMs = opts.timeoutMs ?? 15e3;
|
|
147804
|
+
const pollIntervalMs = opts.pollIntervalMs ?? 250;
|
|
147805
|
+
const deadline = Date.now() + timeoutMs;
|
|
147806
|
+
let lastFailure = "server did not respond";
|
|
147807
|
+
while (Date.now() <= deadline) {
|
|
147808
|
+
const controller = new AbortController();
|
|
147809
|
+
const requestTimer = setTimeout(() => controller.abort(), Math.min(2e3, timeoutMs));
|
|
147810
|
+
try {
|
|
147811
|
+
const response = await fetch(`http://127.0.0.1:${opts.port}/healthz`, {
|
|
147812
|
+
signal: controller.signal
|
|
147813
|
+
});
|
|
147814
|
+
if (response.ok) {
|
|
147815
|
+
const body = await response.json();
|
|
147816
|
+
if (body.ok === true && typeof body.version === "string") {
|
|
147817
|
+
if (isExpectedVersion(body.version, opts.expectedVersion)) return;
|
|
147818
|
+
lastFailure = `running version is ${body.version}, expected ${opts.expectedVersion}`;
|
|
147819
|
+
} else {
|
|
147820
|
+
lastFailure = "health response is missing ok/version";
|
|
147821
|
+
}
|
|
147822
|
+
} else {
|
|
147823
|
+
lastFailure = `health endpoint returned ${response.status}`;
|
|
147824
|
+
}
|
|
147825
|
+
} catch (err) {
|
|
147826
|
+
lastFailure = err instanceof Error ? err.message : String(err);
|
|
147827
|
+
} finally {
|
|
147828
|
+
clearTimeout(requestTimer);
|
|
147829
|
+
}
|
|
147830
|
+
const remaining = deadline - Date.now();
|
|
147831
|
+
if (remaining <= 0) break;
|
|
147832
|
+
await new Promise((resolve6) => setTimeout(resolve6, Math.min(pollIntervalMs, remaining)));
|
|
147833
|
+
}
|
|
147834
|
+
throw new Error(`restart verification failed: ${lastFailure}`);
|
|
147761
147835
|
}
|
|
147762
147836
|
|
|
147763
147837
|
// src/updater/stamp-version.ts
|
|
@@ -150899,7 +150973,7 @@ async function runInstall(opts) {
|
|
|
150899
150973
|
await unpackTarball({ tarballPath, destDir });
|
|
150900
150974
|
stampVersionTxt(destDir, targetVersion);
|
|
150901
150975
|
if (process.platform === "win32") {
|
|
150902
|
-
await stopService().catch(() => {
|
|
150976
|
+
await stopService({ port: opts.runningServer?.port }).catch(() => {
|
|
150903
150977
|
});
|
|
150904
150978
|
}
|
|
150905
150979
|
swapCurrent(targetVersion);
|
|
@@ -150908,6 +150982,12 @@ async function runInstall(opts) {
|
|
|
150908
150982
|
try {
|
|
150909
150983
|
const r = await restartService();
|
|
150910
150984
|
restartMethod = r.method;
|
|
150985
|
+
if (opts.runningServer && r.method !== "none") {
|
|
150986
|
+
await waitForRestartHealth({
|
|
150987
|
+
port: opts.runningServer.port,
|
|
150988
|
+
expectedVersion: targetVersion
|
|
150989
|
+
});
|
|
150990
|
+
}
|
|
150911
150991
|
} catch (err) {
|
|
150912
150992
|
restartMethod = `failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
150913
150993
|
}
|
|
@@ -150918,8 +150998,9 @@ async function runInstall(opts) {
|
|
|
150918
150998
|
pruned,
|
|
150919
150999
|
restart: { method: restartMethod }
|
|
150920
151000
|
};
|
|
151001
|
+
const outcome = restartMethod.startsWith("failed:") ? "failed" : "installed";
|
|
150921
151002
|
appendUpdateLog(
|
|
150922
|
-
`[
|
|
151003
|
+
`[${outcome}] ${installed.previous} \u2192 ${installed.installed} restart=${installed.restart.method}${pruned.length > 0 ? ` pruned=${pruned.length}` : ""}`
|
|
150923
151004
|
);
|
|
150924
151005
|
return installed;
|
|
150925
151006
|
}
|
|
@@ -151378,11 +151459,20 @@ program2.command("update").description("Check for streamer updates from GitHub R
|
|
|
151378
151459
|
);
|
|
151379
151460
|
break;
|
|
151380
151461
|
case "installed":
|
|
151381
|
-
|
|
151382
|
-
|
|
151383
|
-
|
|
151384
|
-
|
|
151385
|
-
|
|
151462
|
+
if (result.restart.method.startsWith("failed:")) {
|
|
151463
|
+
log7.error(
|
|
151464
|
+
`Installed ${result.installed} on disk, but the running service was not updated. Restart: ${result.restart.method}.`,
|
|
151465
|
+
void 0,
|
|
151466
|
+
"console"
|
|
151467
|
+
);
|
|
151468
|
+
process.exitCode = 1;
|
|
151469
|
+
} else {
|
|
151470
|
+
log7.info(
|
|
151471
|
+
`Installed ${result.installed} (was ${result.previous}). Restart: ${result.restart.method}.`,
|
|
151472
|
+
void 0,
|
|
151473
|
+
"console"
|
|
151474
|
+
);
|
|
151475
|
+
}
|
|
151386
151476
|
if (result.pruned.length > 0) {
|
|
151387
151477
|
log7.info(`Pruned old releases: ${result.pruned.join(", ")}`, void 0, "console");
|
|
151388
151478
|
}
|