@threadbase-sh/streamer 1.69.3 → 1.69.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/api/handlers/sessions.handlers.d.ts +2 -0
- package/dist/api/handlers/sessions.handlers.d.ts.map +1 -1
- package/dist/cli.cjs +95 -43
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +88 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +72 -20
- package/dist/index.js.map +1 -1
- package/dist/server-wiring.d.ts +2 -0
- package/dist/server-wiring.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/services/questions/answersToKeystrokes.d.ts +8 -0
- package/dist/services/questions/answersToKeystrokes.d.ts.map +1 -1
- package/dist/services/questions/resolveAnswer.d.ts +1 -1
- package/dist/services/questions/resolveAnswer.d.ts.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4089,7 +4089,7 @@ async function readGitBranch(dir) {
|
|
|
4089
4089
|
// src/server.ts
|
|
4090
4090
|
import { createNodeWebSocket } from "@hono/node-ws";
|
|
4091
4091
|
import { Connection, Client as TemporalClient } from "@temporalio/client";
|
|
4092
|
-
import { randomUUID as
|
|
4092
|
+
import { randomUUID as randomUUID6 } from "crypto";
|
|
4093
4093
|
import { EventEmitter } from "events";
|
|
4094
4094
|
import { existsSync as existsSync16 } from "fs";
|
|
4095
4095
|
import { realpath as realpath2 } from "fs/promises";
|
|
@@ -9211,6 +9211,7 @@ var ConversationHandlers = class {
|
|
|
9211
9211
|
};
|
|
9212
9212
|
|
|
9213
9213
|
// src/api/handlers/sessions.handlers.ts
|
|
9214
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
9214
9215
|
import { existsSync as existsSync10 } from "fs";
|
|
9215
9216
|
import { basename as basename6, dirname as dirname9, join as join16 } from "path";
|
|
9216
9217
|
|
|
@@ -9582,19 +9583,39 @@ var UnknownOptionError = class extends Error {
|
|
|
9582
9583
|
question;
|
|
9583
9584
|
value;
|
|
9584
9585
|
};
|
|
9586
|
+
var UnsupportedPromptShapeError = class extends Error {
|
|
9587
|
+
constructor(detail) {
|
|
9588
|
+
super(`Unsupported prompt shape: ${detail}`);
|
|
9589
|
+
this.detail = detail;
|
|
9590
|
+
this.name = "UnsupportedPromptShapeError";
|
|
9591
|
+
}
|
|
9592
|
+
detail;
|
|
9593
|
+
};
|
|
9594
|
+
var IncompleteAnswerError = class extends Error {
|
|
9595
|
+
constructor(question) {
|
|
9596
|
+
super(`Missing answer for question "${question}"`);
|
|
9597
|
+
this.question = question;
|
|
9598
|
+
this.name = "IncompleteAnswerError";
|
|
9599
|
+
}
|
|
9600
|
+
question;
|
|
9601
|
+
};
|
|
9585
9602
|
function answersToKeystrokes(questions, answers) {
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
const raw = answers[q.question];
|
|
9589
|
-
if (raw === void 0) {
|
|
9590
|
-
throw new Error(`Missing answer for question "${q.question}"`);
|
|
9591
|
-
}
|
|
9592
|
-
const label = Array.isArray(raw) ? raw[0] : raw;
|
|
9593
|
-
const target = q.options.findIndex((o) => o.label === label);
|
|
9594
|
-
if (target < 0) throw new UnknownOptionError(q.question, label);
|
|
9595
|
-
out += DOWN.repeat(target) + ENTER3;
|
|
9603
|
+
if (questions.length !== 1) {
|
|
9604
|
+
throw new UnsupportedPromptShapeError(`${questions.length} questions`);
|
|
9596
9605
|
}
|
|
9597
|
-
|
|
9606
|
+
const q = questions[0];
|
|
9607
|
+
if (q.multiSelect) throw new UnsupportedPromptShapeError("multiSelect");
|
|
9608
|
+
const raw = answers[q.question];
|
|
9609
|
+
if (raw === void 0 || Array.isArray(raw) && raw.length === 0) {
|
|
9610
|
+
throw new IncompleteAnswerError(q.question);
|
|
9611
|
+
}
|
|
9612
|
+
if (Array.isArray(raw) && raw.length > 1) {
|
|
9613
|
+
throw new UnsupportedPromptShapeError(`${raw.length} labels for a single-select question`);
|
|
9614
|
+
}
|
|
9615
|
+
const label = Array.isArray(raw) ? raw[0] : raw;
|
|
9616
|
+
const target = q.options.findIndex((o) => o.label === label);
|
|
9617
|
+
if (target < 0) throw new UnknownOptionError(q.question, label);
|
|
9618
|
+
return DOWN.repeat(target) + ENTER3;
|
|
9598
9619
|
}
|
|
9599
9620
|
|
|
9600
9621
|
// src/services/questions/resolveAnswer.ts
|
|
@@ -9608,6 +9629,10 @@ function resolveAnswer(pending, body) {
|
|
|
9608
9629
|
return { ok: true, keys: answersToKeystrokes(pending.questions, answers) };
|
|
9609
9630
|
} catch (e) {
|
|
9610
9631
|
if (e instanceof UnknownOptionError) return { ok: false, reason: "unknown_option" };
|
|
9632
|
+
if (e instanceof UnsupportedPromptShapeError) {
|
|
9633
|
+
return { ok: false, reason: "unsupported_prompt_shape" };
|
|
9634
|
+
}
|
|
9635
|
+
if (e instanceof IncompleteAnswerError) return { ok: false, reason: "incomplete_answer" };
|
|
9611
9636
|
throw e;
|
|
9612
9637
|
}
|
|
9613
9638
|
}
|
|
@@ -10506,7 +10531,9 @@ var SessionHandlers = class {
|
|
|
10506
10531
|
}
|
|
10507
10532
|
const key = permissionContentKey(gate);
|
|
10508
10533
|
if (this.pendingPermissionKey.get(sessionId) === key) return;
|
|
10509
|
-
this.pendingPermission.
|
|
10534
|
+
const prior = this.pendingPermission.get(sessionId);
|
|
10535
|
+
const gateId = prior && permissionGateKey(prior) === permissionGateKey(gate) ? prior.gateId : randomUUID4();
|
|
10536
|
+
this.pendingPermission.set(sessionId, { ...gate, gateId });
|
|
10510
10537
|
this.pendingPermissionKey.set(sessionId, key);
|
|
10511
10538
|
const subscriberCount = this.sessionSubscribers.get(sessionId)?.size ?? 0;
|
|
10512
10539
|
this.log.info(
|
|
@@ -10520,7 +10547,8 @@ var SessionHandlers = class {
|
|
|
10520
10547
|
...gate.detail ? { detail: gate.detail } : {},
|
|
10521
10548
|
options: gate.options,
|
|
10522
10549
|
...gate.cursor !== void 0 ? { cursor: gate.cursor } : {},
|
|
10523
|
-
contentKey: permissionGateKey(gate)
|
|
10550
|
+
contentKey: permissionGateKey(gate),
|
|
10551
|
+
gateId
|
|
10524
10552
|
});
|
|
10525
10553
|
}
|
|
10526
10554
|
/**
|
|
@@ -10548,10 +10576,15 @@ var SessionHandlers = class {
|
|
|
10548
10576
|
const body = await readBody2(req);
|
|
10549
10577
|
const contentKey = body?.contentKey;
|
|
10550
10578
|
const optionIndex = body?.optionIndex;
|
|
10579
|
+
const gateId = body?.gateId;
|
|
10551
10580
|
if (typeof contentKey !== "string" || !Number.isInteger(optionIndex) || optionIndex < 0) {
|
|
10552
10581
|
json(res, 400, { ok: false, reason: "Expected { contentKey: string, optionIndex: number }" });
|
|
10553
10582
|
return;
|
|
10554
10583
|
}
|
|
10584
|
+
if (gateId !== void 0 && typeof gateId !== "string") {
|
|
10585
|
+
json(res, 400, { ok: false, reason: "Expected gateId to be a string" });
|
|
10586
|
+
return;
|
|
10587
|
+
}
|
|
10555
10588
|
const gateClosed = () => {
|
|
10556
10589
|
this.pendingPermission.delete(sessionId);
|
|
10557
10590
|
this.pendingPermissionKey.delete(sessionId);
|
|
@@ -10563,6 +10596,16 @@ var SessionHandlers = class {
|
|
|
10563
10596
|
gateClosed();
|
|
10564
10597
|
return;
|
|
10565
10598
|
}
|
|
10599
|
+
if (gateId !== void 0 && gateId !== gate.gateId) {
|
|
10600
|
+
json(res, 409, { ok: false, reason: "gate_mismatch" });
|
|
10601
|
+
return;
|
|
10602
|
+
}
|
|
10603
|
+
if (gateId === void 0) {
|
|
10604
|
+
this.log.info(`[permission.answer_legacy_identity] ${sessionId.slice(0, 8)}`, {
|
|
10605
|
+
event: "permission.answer_legacy_identity",
|
|
10606
|
+
sessionId
|
|
10607
|
+
});
|
|
10608
|
+
}
|
|
10566
10609
|
if (permissionGateKey(gate) !== contentKey) {
|
|
10567
10610
|
json(res, 409, { ok: false, reason: "gate_mismatch" });
|
|
10568
10611
|
return;
|
|
@@ -10572,7 +10615,8 @@ var SessionHandlers = class {
|
|
|
10572
10615
|
json(res, 409, { ok: false, reason: "unknown_option" });
|
|
10573
10616
|
return;
|
|
10574
10617
|
}
|
|
10575
|
-
|
|
10618
|
+
const provider = this.sessionStore.getManaged(sessionId)?.provider;
|
|
10619
|
+
if (provider !== CODEX_CLI_PROVIDER && !await this.permissionGateStillOpen(sessionId, contentKey)) {
|
|
10576
10620
|
gateClosed();
|
|
10577
10621
|
return;
|
|
10578
10622
|
}
|
|
@@ -10616,7 +10660,14 @@ var SessionHandlers = class {
|
|
|
10616
10660
|
const pending = this.pendingQuestions.get(sessionId);
|
|
10617
10661
|
const resolution = resolveAnswer(pending, body);
|
|
10618
10662
|
if (!resolution.ok) {
|
|
10619
|
-
|
|
10663
|
+
const unanswerable = resolution.reason === "unsupported_prompt_shape" || resolution.reason === "incomplete_answer";
|
|
10664
|
+
json(res, 400, {
|
|
10665
|
+
ok: false,
|
|
10666
|
+
reason: resolution.reason,
|
|
10667
|
+
...unanswerable ? {
|
|
10668
|
+
error: "This prompt needs an answer the app cannot give yet; answer it in the terminal"
|
|
10669
|
+
} : {}
|
|
10670
|
+
});
|
|
10620
10671
|
return;
|
|
10621
10672
|
}
|
|
10622
10673
|
const toolUseId = pending?.toolUseId ?? "";
|
|
@@ -11280,7 +11331,7 @@ var ManagedSessionsRepository = class {
|
|
|
11280
11331
|
};
|
|
11281
11332
|
|
|
11282
11333
|
// src/db/repositories/projects.repository.ts
|
|
11283
|
-
import { randomUUID as
|
|
11334
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
11284
11335
|
function rowToProject(row) {
|
|
11285
11336
|
return {
|
|
11286
11337
|
id: row.id,
|
|
@@ -11365,7 +11416,7 @@ var ProjectsRepository = class {
|
|
|
11365
11416
|
});
|
|
11366
11417
|
return rowToProject(this.getById.get(existing.id));
|
|
11367
11418
|
}
|
|
11368
|
-
const id =
|
|
11419
|
+
const id = randomUUID5();
|
|
11369
11420
|
this.insert.run({
|
|
11370
11421
|
id,
|
|
11371
11422
|
path,
|
|
@@ -13142,7 +13193,8 @@ function createApiDeps(deps) {
|
|
|
13142
13193
|
...pendingGate.detail ? { detail: pendingGate.detail } : {},
|
|
13143
13194
|
options: pendingGate.options,
|
|
13144
13195
|
...pendingGate.cursor !== void 0 ? { cursor: pendingGate.cursor } : {},
|
|
13145
|
-
contentKey: permissionGateKey(pendingGate)
|
|
13196
|
+
contentKey: permissionGateKey(pendingGate),
|
|
13197
|
+
gateId: pendingGate.gateId
|
|
13146
13198
|
})
|
|
13147
13199
|
);
|
|
13148
13200
|
}
|
|
@@ -16000,7 +16052,7 @@ var StreamerServer = class {
|
|
|
16000
16052
|
runtimeStore = null;
|
|
16001
16053
|
// Identifies this streamer run. A registry row carrying a different id is a
|
|
16002
16054
|
// session that outlived the process that started it.
|
|
16003
|
-
streamerInstanceId =
|
|
16055
|
+
streamerInstanceId = randomUUID6();
|
|
16004
16056
|
cacheMetadataRepo = null;
|
|
16005
16057
|
// Push registration + delivery state (C7). Null when the cache DB failed to
|
|
16006
16058
|
// open — registration then degrades to a no-op rather than 500ing.
|