@threadbase-sh/streamer 1.69.6 → 1.70.1
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 +26 -15
- package/dist/api/handlers/sessions.handlers.d.ts.map +1 -1
- package/dist/api/routes/misc.routes.d.ts.map +1 -1
- package/dist/api/routes/sessions.routes.d.ts.map +1 -1
- package/dist/api/types/api-deps.d.ts +1 -0
- package/dist/api/types/api-deps.d.ts.map +1 -1
- package/dist/cli.cjs +1292 -315
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +885 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +884 -47
- package/dist/index.js.map +1 -1
- package/dist/pty-host/protocol.d.ts +21 -4
- package/dist/pty-host/protocol.d.ts.map +1 -1
- package/dist/pty-host/remote-session-runner.d.ts +1 -0
- package/dist/pty-host/remote-session-runner.d.ts.map +1 -1
- package/dist/schemas/prompt.schema.d.ts +113 -0
- package/dist/schemas/prompt.schema.d.ts.map +1 -0
- package/dist/server-wiring.d.ts +22 -0
- package/dist/server-wiring.d.ts.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/services/prompts/promptRegistry.d.ts +99 -0
- package/dist/services/prompts/promptRegistry.d.ts.map +1 -0
- package/dist/services/prompts/ptyPromptAdapter.d.ts +6 -0
- package/dist/services/prompts/ptyPromptAdapter.d.ts.map +1 -0
- package/dist/types.d.ts +4 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -116376,7 +116376,7 @@ var require_query = __commonJS({
|
|
|
116376
116376
|
if (typeof this.text !== "string" && typeof this.name !== "string") {
|
|
116377
116377
|
return new Error("A query must have either text or a name. Supplying neither is unsupported.");
|
|
116378
116378
|
}
|
|
116379
|
-
const previous = connection.parsedStatements[this.name];
|
|
116379
|
+
const previous = connection.parsedStatements[this.name] || connection.submittedNamedStatements[this.name];
|
|
116380
116380
|
if (this.text && previous && this.text !== previous) {
|
|
116381
116381
|
return new Error(`Prepared statements must be unique - '${this.name}' was used for a different statement`);
|
|
116382
116382
|
}
|
|
@@ -116396,7 +116396,7 @@ var require_query = __commonJS({
|
|
|
116396
116396
|
return null;
|
|
116397
116397
|
}
|
|
116398
116398
|
hasBeenParsed(connection) {
|
|
116399
|
-
return this.name && connection.parsedStatements[this.name];
|
|
116399
|
+
return this.name && (connection.parsedStatements[this.name] || connection.submittedNamedStatements[this.name]);
|
|
116400
116400
|
}
|
|
116401
116401
|
handlePortalSuspended(connection) {
|
|
116402
116402
|
this._getRows(connection, this.rows);
|
|
@@ -116420,6 +116420,9 @@ var require_query = __commonJS({
|
|
|
116420
116420
|
name: this.name,
|
|
116421
116421
|
types: this.types
|
|
116422
116422
|
});
|
|
116423
|
+
if (this.name) {
|
|
116424
|
+
connection.submittedNamedStatements[this.name] = this.text;
|
|
116425
|
+
}
|
|
116423
116426
|
}
|
|
116424
116427
|
try {
|
|
116425
116428
|
connection.bind({
|
|
@@ -117208,7 +117211,7 @@ var require_parser3 = __commonJS({
|
|
|
117208
117211
|
const parameterCount = reader.int16();
|
|
117209
117212
|
const message = new messages_1.ParameterDescriptionMessage(LATEINIT_LENGTH, parameterCount);
|
|
117210
117213
|
for (let i = 0; i < parameterCount; i++) {
|
|
117211
|
-
message.dataTypeIDs[i] = reader.
|
|
117214
|
+
message.dataTypeIDs[i] = reader.uint32();
|
|
117212
117215
|
}
|
|
117213
117216
|
return message;
|
|
117214
117217
|
};
|
|
@@ -117430,6 +117433,7 @@ var require_connection2 = __commonJS({
|
|
|
117430
117433
|
this._keepAlive = config2.keepAlive;
|
|
117431
117434
|
this._keepAliveInitialDelayMillis = config2.keepAliveInitialDelayMillis;
|
|
117432
117435
|
this.parsedStatements = {};
|
|
117436
|
+
this.submittedNamedStatements = {};
|
|
117433
117437
|
this.ssl = config2.ssl || false;
|
|
117434
117438
|
this.sslNegotiation = config2.sslNegotiation || "postgres";
|
|
117435
117439
|
this._ending = false;
|
|
@@ -117987,6 +117991,8 @@ var require_client3 = __commonJS({
|
|
|
117987
117991
|
encoding: this.connectionParameters.client_encoding || "utf8"
|
|
117988
117992
|
});
|
|
117989
117993
|
this._queryQueue = [];
|
|
117994
|
+
this._sentQueryQueue = [];
|
|
117995
|
+
this.pipeline = Boolean(c.pipeline);
|
|
117990
117996
|
this.binary = c.binary || defaults2.binary;
|
|
117991
117997
|
this.processID = null;
|
|
117992
117998
|
this.secretKey = null;
|
|
@@ -118021,6 +118027,8 @@ var require_client3 = __commonJS({
|
|
|
118021
118027
|
enqueueError(activeQuery);
|
|
118022
118028
|
this._activeQuery = null;
|
|
118023
118029
|
}
|
|
118030
|
+
this._sentQueryQueue.forEach(enqueueError);
|
|
118031
|
+
this._sentQueryQueue.length = 0;
|
|
118024
118032
|
this._queryQueue.forEach(enqueueError);
|
|
118025
118033
|
this._queryQueue.length = 0;
|
|
118026
118034
|
}
|
|
@@ -118263,6 +118271,9 @@ var require_client3 = __commonJS({
|
|
|
118263
118271
|
return;
|
|
118264
118272
|
}
|
|
118265
118273
|
this._activeQuery = null;
|
|
118274
|
+
if (activeQuery.name) {
|
|
118275
|
+
delete this.connection.submittedNamedStatements[activeQuery.name];
|
|
118276
|
+
}
|
|
118266
118277
|
activeQuery.handleError(msg, this.connection);
|
|
118267
118278
|
}
|
|
118268
118279
|
_handleRowDescription(msg) {
|
|
@@ -118319,6 +118330,7 @@ var require_client3 = __commonJS({
|
|
|
118319
118330
|
}
|
|
118320
118331
|
if (activeQuery.name) {
|
|
118321
118332
|
this.connection.parsedStatements[activeQuery.name] = activeQuery.text;
|
|
118333
|
+
delete this.connection.submittedNamedStatements[activeQuery.name];
|
|
118322
118334
|
}
|
|
118323
118335
|
}
|
|
118324
118336
|
_handleCopyInResponse(msg) {
|
|
@@ -118385,6 +118397,9 @@ var require_client3 = __commonJS({
|
|
|
118385
118397
|
});
|
|
118386
118398
|
} else if (client._queryQueue.indexOf(query) !== -1) {
|
|
118387
118399
|
client._queryQueue.splice(client._queryQueue.indexOf(query), 1);
|
|
118400
|
+
} else if (client._sentQueryQueue.indexOf(query) !== -1) {
|
|
118401
|
+
query.callback = () => {
|
|
118402
|
+
};
|
|
118388
118403
|
}
|
|
118389
118404
|
}
|
|
118390
118405
|
setTypeParser(oid, format, parseFn) {
|
|
@@ -118403,6 +118418,10 @@ var require_client3 = __commonJS({
|
|
|
118403
118418
|
return utils.escapeLiteral(str);
|
|
118404
118419
|
}
|
|
118405
118420
|
_pulseQueryQueue() {
|
|
118421
|
+
if (this.pipeline) {
|
|
118422
|
+
this._pulsePipelinedQueryQueue();
|
|
118423
|
+
return;
|
|
118424
|
+
}
|
|
118406
118425
|
if (this.readyForQuery === true) {
|
|
118407
118426
|
this._activeQuery = this._queryQueue.shift();
|
|
118408
118427
|
const activeQuery = this._getActiveQuery();
|
|
@@ -118423,6 +118442,30 @@ var require_client3 = __commonJS({
|
|
|
118423
118442
|
}
|
|
118424
118443
|
}
|
|
118425
118444
|
}
|
|
118445
|
+
_pulsePipelinedQueryQueue() {
|
|
118446
|
+
if (!this._connected || !this._queryable) {
|
|
118447
|
+
return;
|
|
118448
|
+
}
|
|
118449
|
+
while (this._queryQueue.length > 0) {
|
|
118450
|
+
const query = this._queryQueue.shift();
|
|
118451
|
+
this.hasExecuted = true;
|
|
118452
|
+
const queryError = query.submit(this.connection);
|
|
118453
|
+
if (queryError) {
|
|
118454
|
+
process.nextTick(() => {
|
|
118455
|
+
query.handleError(queryError, this.connection);
|
|
118456
|
+
});
|
|
118457
|
+
continue;
|
|
118458
|
+
}
|
|
118459
|
+
this._sentQueryQueue.push(query);
|
|
118460
|
+
}
|
|
118461
|
+
if (this.readyForQuery && !this._activeQuery && this._sentQueryQueue.length > 0) {
|
|
118462
|
+
this._activeQuery = this._sentQueryQueue.shift();
|
|
118463
|
+
this.readyForQuery = false;
|
|
118464
|
+
}
|
|
118465
|
+
if (!this._activeQuery && this._sentQueryQueue.length === 0 && this._queryQueue.length === 0 && this.hasExecuted) {
|
|
118466
|
+
this.emit("drain");
|
|
118467
|
+
}
|
|
118468
|
+
}
|
|
118426
118469
|
query(config2, values, callback) {
|
|
118427
118470
|
let query;
|
|
118428
118471
|
let result;
|
|
@@ -118466,6 +118509,9 @@ var require_client3 = __commonJS({
|
|
|
118466
118509
|
const index = this._queryQueue.indexOf(query);
|
|
118467
118510
|
if (index > -1) {
|
|
118468
118511
|
this._queryQueue.splice(index, 1);
|
|
118512
|
+
} else if (this.pipeline) {
|
|
118513
|
+
this.connection.stream.destroy();
|
|
118514
|
+
return;
|
|
118469
118515
|
}
|
|
118470
118516
|
this._pulseQueryQueue();
|
|
118471
118517
|
}, readTimeout);
|
|
@@ -118492,7 +118538,7 @@ var require_client3 = __commonJS({
|
|
|
118492
118538
|
});
|
|
118493
118539
|
return result;
|
|
118494
118540
|
}
|
|
118495
|
-
if (this._queryQueue.length > 0) {
|
|
118541
|
+
if (this._queryQueue.length > 0 && !this.pipeline) {
|
|
118496
118542
|
queryQueueLengthDeprecationNotice();
|
|
118497
118543
|
}
|
|
118498
118544
|
this._queryQueue.push(query);
|
|
@@ -118518,7 +118564,11 @@ var require_client3 = __commonJS({
|
|
|
118518
118564
|
return this._Promise.resolve();
|
|
118519
118565
|
}
|
|
118520
118566
|
}
|
|
118521
|
-
if (
|
|
118567
|
+
if (!this._queryable) {
|
|
118568
|
+
this.connection.stream.destroy();
|
|
118569
|
+
} else if (this.pipeline && (this._getActiveQuery() || this._sentQueryQueue.length > 0 || this._queryQueue.length > 0)) {
|
|
118570
|
+
this.once("drain", () => this.connection.end());
|
|
118571
|
+
} else if (this._getActiveQuery()) {
|
|
118522
118572
|
this.connection.stream.destroy();
|
|
118523
118573
|
} else {
|
|
118524
118574
|
this.connection.end();
|
|
@@ -119008,7 +119058,7 @@ var require_query2 = __commonJS({
|
|
|
119008
119058
|
sourceFunction: "routine"
|
|
119009
119059
|
};
|
|
119010
119060
|
NativeQuery.prototype.handleError = function(err) {
|
|
119011
|
-
const fields = this.native.pq.resultErrorFields();
|
|
119061
|
+
const fields = this.native && this.native.pq.resultErrorFields();
|
|
119012
119062
|
if (fields) {
|
|
119013
119063
|
for (const key in fields) {
|
|
119014
119064
|
const normalizedFieldName = errorFieldMap[key] || key;
|
|
@@ -119142,6 +119192,8 @@ var require_client4 = __commonJS({
|
|
|
119142
119192
|
this._connecting = false;
|
|
119143
119193
|
this._connected = false;
|
|
119144
119194
|
this._queryable = true;
|
|
119195
|
+
this.pipeline = Boolean(config2.pipeline);
|
|
119196
|
+
this._pipelineInFlight = false;
|
|
119145
119197
|
const cp = this.connectionParameters = new ConnectionParameters(config2);
|
|
119146
119198
|
if (config2.nativeConnectionString) cp.nativeConnectionString = config2.nativeConnectionString;
|
|
119147
119199
|
this.user = cp.user;
|
|
@@ -119285,7 +119337,7 @@ var require_client4 = __commonJS({
|
|
|
119285
119337
|
});
|
|
119286
119338
|
return result;
|
|
119287
119339
|
}
|
|
119288
|
-
if (this._queryQueue.length > 0) {
|
|
119340
|
+
if (this._queryQueue.length > 0 && !this.pipeline) {
|
|
119289
119341
|
queryQueueLengthDeprecationNotice();
|
|
119290
119342
|
}
|
|
119291
119343
|
this._queryQueue.push(query);
|
|
@@ -119307,14 +119359,21 @@ var require_client4 = __commonJS({
|
|
|
119307
119359
|
cb2 = (err) => err ? reject(err) : resolve4();
|
|
119308
119360
|
});
|
|
119309
119361
|
}
|
|
119310
|
-
|
|
119311
|
-
self2.
|
|
119312
|
-
|
|
119313
|
-
|
|
119314
|
-
|
|
119315
|
-
|
|
119362
|
+
const doEnd = function() {
|
|
119363
|
+
self2.native.end(function() {
|
|
119364
|
+
self2._connected = false;
|
|
119365
|
+
self2._errorAllQueries(new Error("Connection terminated"));
|
|
119366
|
+
process.nextTick(() => {
|
|
119367
|
+
self2.emit("end");
|
|
119368
|
+
if (cb2) cb2();
|
|
119369
|
+
});
|
|
119316
119370
|
});
|
|
119317
|
-
}
|
|
119371
|
+
};
|
|
119372
|
+
if (this.pipeline && (this._pipelineInFlight || this._queryQueue.length > 0)) {
|
|
119373
|
+
this.once("drain", doEnd);
|
|
119374
|
+
} else {
|
|
119375
|
+
doEnd();
|
|
119376
|
+
}
|
|
119318
119377
|
return result;
|
|
119319
119378
|
};
|
|
119320
119379
|
Client2.prototype._hasActiveQuery = function() {
|
|
@@ -119324,6 +119383,9 @@ var require_client4 = __commonJS({
|
|
|
119324
119383
|
if (!this._connected) {
|
|
119325
119384
|
return;
|
|
119326
119385
|
}
|
|
119386
|
+
if (this.pipeline && !initialConnection) {
|
|
119387
|
+
return this._pulsePipelinedQueryQueue();
|
|
119388
|
+
}
|
|
119327
119389
|
if (this._hasActiveQuery()) {
|
|
119328
119390
|
return;
|
|
119329
119391
|
}
|
|
@@ -119341,6 +119403,69 @@ var require_client4 = __commonJS({
|
|
|
119341
119403
|
self2._pulseQueryQueue();
|
|
119342
119404
|
});
|
|
119343
119405
|
};
|
|
119406
|
+
Client2.prototype._pulsePipelinedQueryQueue = function() {
|
|
119407
|
+
if (!this._connected || this._pipelineInFlight) {
|
|
119408
|
+
return;
|
|
119409
|
+
}
|
|
119410
|
+
if (this._queryQueue.length === 0) {
|
|
119411
|
+
if (this.hasExecuted) {
|
|
119412
|
+
this.emit("drain");
|
|
119413
|
+
}
|
|
119414
|
+
return;
|
|
119415
|
+
}
|
|
119416
|
+
this._pipelineInFlight = true;
|
|
119417
|
+
const self2 = this;
|
|
119418
|
+
const queries = [];
|
|
119419
|
+
const nativeQueries = [];
|
|
119420
|
+
const utils = require_utils5();
|
|
119421
|
+
while (this._queryQueue.length > 0) {
|
|
119422
|
+
const query = this._queryQueue.shift();
|
|
119423
|
+
this.hasExecuted = true;
|
|
119424
|
+
nativeQueries.push(query);
|
|
119425
|
+
const values = query.values ? query.values.map(utils.prepareValue) : null;
|
|
119426
|
+
const pipelineEntry = { text: query.text, name: query.name };
|
|
119427
|
+
if (values) {
|
|
119428
|
+
pipelineEntry.values = values;
|
|
119429
|
+
}
|
|
119430
|
+
if (query.name && this.namedQueries[query.name]) {
|
|
119431
|
+
pipelineEntry._alreadyPrepared = true;
|
|
119432
|
+
}
|
|
119433
|
+
queries.push(pipelineEntry);
|
|
119434
|
+
}
|
|
119435
|
+
this.native.pipeline(queries, function(err, results) {
|
|
119436
|
+
self2._pipelineInFlight = false;
|
|
119437
|
+
if (err) {
|
|
119438
|
+
for (let i = 0; i < nativeQueries.length; i++) {
|
|
119439
|
+
const q2 = nativeQueries[i];
|
|
119440
|
+
q2.native = self2.native;
|
|
119441
|
+
q2.handleError(err);
|
|
119442
|
+
}
|
|
119443
|
+
self2._pulsePipelinedQueryQueue();
|
|
119444
|
+
return;
|
|
119445
|
+
}
|
|
119446
|
+
for (let i = 0; i < nativeQueries.length; i++) {
|
|
119447
|
+
const q2 = nativeQueries[i];
|
|
119448
|
+
const r = results[i];
|
|
119449
|
+
q2.native = self2.native;
|
|
119450
|
+
if (r.err) {
|
|
119451
|
+
q2.handleError(r.err);
|
|
119452
|
+
} else {
|
|
119453
|
+
if (q2.name) {
|
|
119454
|
+
self2.namedQueries[q2.name] = q2.text;
|
|
119455
|
+
}
|
|
119456
|
+
q2.state = "end";
|
|
119457
|
+
q2.emit("end", r.result);
|
|
119458
|
+
if (q2.callback) {
|
|
119459
|
+
q2.callback(null, r.result);
|
|
119460
|
+
}
|
|
119461
|
+
}
|
|
119462
|
+
setImmediate(function() {
|
|
119463
|
+
q2.emit("_done");
|
|
119464
|
+
});
|
|
119465
|
+
}
|
|
119466
|
+
self2._pulsePipelinedQueryQueue();
|
|
119467
|
+
});
|
|
119468
|
+
};
|
|
119344
119469
|
Client2.prototype.cancel = function(query) {
|
|
119345
119470
|
if (this._activeQuery === query) {
|
|
119346
119471
|
this.native.cancel(function() {
|
|
@@ -120610,7 +120735,7 @@ var PTY_HOST_PROTOCOL_VERSION, SESSION_DATE_FIELDS, LineDecoder;
|
|
|
120610
120735
|
var init_protocol = __esm({
|
|
120611
120736
|
"src/pty-host/protocol.ts"() {
|
|
120612
120737
|
"use strict";
|
|
120613
|
-
PTY_HOST_PROTOCOL_VERSION =
|
|
120738
|
+
PTY_HOST_PROTOCOL_VERSION = 4;
|
|
120614
120739
|
SESSION_DATE_FIELDS = [
|
|
120615
120740
|
"startedAt",
|
|
120616
120741
|
"completedAt",
|
|
@@ -120690,8 +120815,12 @@ var init_remote_session_runner = __esm({
|
|
|
120690
120815
|
}
|
|
120691
120816
|
throw new PtyHostProtocolMismatchError(status.protocolVersion, PTY_HOST_PROTOCOL_VERSION);
|
|
120692
120817
|
}
|
|
120693
|
-
await runner.request({ type: "subscribe" });
|
|
120818
|
+
const subscribed = await runner.request({ type: "subscribe" });
|
|
120694
120819
|
runner.refreshMirror(status);
|
|
120820
|
+
runner.restorePromptSnapshots({
|
|
120821
|
+
...status,
|
|
120822
|
+
promptSnapshots: subscribed.promptSnapshots ?? status.promptSnapshots
|
|
120823
|
+
});
|
|
120695
120824
|
return runner;
|
|
120696
120825
|
}
|
|
120697
120826
|
constructor(transport, options) {
|
|
@@ -120784,6 +120913,19 @@ var init_remote_session_runner = __esm({
|
|
|
120784
120913
|
this.pids.set(session.id, entry.pid);
|
|
120785
120914
|
}
|
|
120786
120915
|
}
|
|
120916
|
+
restorePromptSnapshots(status) {
|
|
120917
|
+
for (const snapshot of status.promptSnapshots ?? []) {
|
|
120918
|
+
if (snapshot.kind === "permission") {
|
|
120919
|
+
this.options.onPermissionChange?.(snapshot.sessionId, snapshot.gate, snapshot.occurrenceId);
|
|
120920
|
+
} else {
|
|
120921
|
+
this.options.onLiveQuestion?.(
|
|
120922
|
+
snapshot.sessionId,
|
|
120923
|
+
snapshot.questions,
|
|
120924
|
+
snapshot.occurrenceId
|
|
120925
|
+
);
|
|
120926
|
+
}
|
|
120927
|
+
}
|
|
120928
|
+
}
|
|
120787
120929
|
async heartbeat(state, timeoutMs = HOST_HEARTBEAT_REQUEST_TIMEOUT_MS) {
|
|
120788
120930
|
await this.request({ type: "heartbeat", ...state }, timeoutMs);
|
|
120789
120931
|
}
|
|
@@ -120838,13 +120980,13 @@ var init_remote_session_runner = __esm({
|
|
|
120838
120980
|
break;
|
|
120839
120981
|
}
|
|
120840
120982
|
case "permission-change":
|
|
120841
|
-
this.options.onPermissionChange?.(event.sessionId, event.gate);
|
|
120983
|
+
this.options.onPermissionChange?.(event.sessionId, event.gate, event.occurrenceId);
|
|
120842
120984
|
break;
|
|
120843
120985
|
case "phase-change":
|
|
120844
120986
|
this.options.onPhaseChange?.(event.sessionId, event.phase);
|
|
120845
120987
|
break;
|
|
120846
120988
|
case "live-question":
|
|
120847
|
-
this.options.onLiveQuestion?.(event.sessionId, event.questions);
|
|
120989
|
+
this.options.onLiveQuestion?.(event.sessionId, event.questions, event.occurrenceId);
|
|
120848
120990
|
break;
|
|
120849
120991
|
case "live-question-gone":
|
|
120850
120992
|
this.options.onLiveQuestionGone?.(event.sessionId);
|
|
@@ -128466,12 +128608,15 @@ __export(host_exports, {
|
|
|
128466
128608
|
HOST_ORPHAN_SWEEP_MS: () => HOST_ORPHAN_SWEEP_MS,
|
|
128467
128609
|
SessionHost: () => SessionHost
|
|
128468
128610
|
});
|
|
128469
|
-
var HOST_IDLE_SWEEP_MS, HOST_IDLE_AFTER_MS, HOST_HEARTBEAT_TIMEOUT_MS, HOST_ORPHAN_SWEEP_MS, SessionHost;
|
|
128611
|
+
var import_node_crypto8, HOST_IDLE_SWEEP_MS, HOST_IDLE_AFTER_MS, HOST_HEARTBEAT_TIMEOUT_MS, HOST_ORPHAN_SWEEP_MS, SessionHost;
|
|
128470
128612
|
var init_host = __esm({
|
|
128471
128613
|
"src/pty-host/host.ts"() {
|
|
128472
128614
|
"use strict";
|
|
128615
|
+
import_node_crypto8 = require("crypto");
|
|
128473
128616
|
init_live_session_manager();
|
|
128474
128617
|
init_logger();
|
|
128618
|
+
init_detectPermissionGate();
|
|
128619
|
+
init_detectQuestionFromScreen();
|
|
128475
128620
|
init_protocol();
|
|
128476
128621
|
HOST_IDLE_SWEEP_MS = 5 * 60 * 1e3;
|
|
128477
128622
|
HOST_IDLE_AFTER_MS = 6 * 60 * 60 * 1e3;
|
|
@@ -128493,6 +128638,7 @@ var init_host = __esm({
|
|
|
128493
128638
|
orphanTimer = null;
|
|
128494
128639
|
onOrphaned;
|
|
128495
128640
|
orphaned = false;
|
|
128641
|
+
promptSnapshots = /* @__PURE__ */ new Map();
|
|
128496
128642
|
constructor(options = {}) {
|
|
128497
128643
|
this.log = options.logger ?? getLogger("pty-host");
|
|
128498
128644
|
this.idleAfterMs = options.idleAfterMs ?? HOST_IDLE_AFTER_MS;
|
|
@@ -128505,12 +128651,55 @@ var init_host = __esm({
|
|
|
128505
128651
|
this.lastAgentChunkAt.set(sessionId, Date.now());
|
|
128506
128652
|
this.emit({ type: "event", event: "output", sessionId, data });
|
|
128507
128653
|
},
|
|
128508
|
-
onStatusChange: (session) =>
|
|
128654
|
+
onStatusChange: (session) => {
|
|
128655
|
+
if (session.status === "idle") this.promptSnapshots.delete(session.id);
|
|
128656
|
+
this.emit({ type: "event", event: "status-change", session });
|
|
128657
|
+
},
|
|
128509
128658
|
onReady: (session) => this.emit({ type: "event", event: "ready", session }),
|
|
128510
|
-
onPermissionChange: (sessionId, gate) =>
|
|
128659
|
+
onPermissionChange: (sessionId, gate) => {
|
|
128660
|
+
const prior = this.promptSnapshots.get(sessionId);
|
|
128661
|
+
if (gate === null) {
|
|
128662
|
+
this.promptSnapshots.delete(sessionId);
|
|
128663
|
+
this.emit({
|
|
128664
|
+
type: "event",
|
|
128665
|
+
event: "permission-change",
|
|
128666
|
+
sessionId,
|
|
128667
|
+
gate,
|
|
128668
|
+
...prior ? { occurrenceId: prior.occurrenceId } : {}
|
|
128669
|
+
});
|
|
128670
|
+
return;
|
|
128671
|
+
}
|
|
128672
|
+
const occurrenceId = prior?.kind === "permission" && permissionGateKey(prior.gate) === permissionGateKey(gate) ? prior.occurrenceId : (0, import_node_crypto8.randomUUID)();
|
|
128673
|
+
this.promptSnapshots.set(sessionId, {
|
|
128674
|
+
kind: "permission",
|
|
128675
|
+
sessionId,
|
|
128676
|
+
occurrenceId,
|
|
128677
|
+
gate
|
|
128678
|
+
});
|
|
128679
|
+
this.emit({
|
|
128680
|
+
type: "event",
|
|
128681
|
+
event: "permission-change",
|
|
128682
|
+
sessionId,
|
|
128683
|
+
gate,
|
|
128684
|
+
occurrenceId
|
|
128685
|
+
});
|
|
128686
|
+
},
|
|
128511
128687
|
onPhaseChange: (sessionId, phase) => this.emit({ type: "event", event: "phase-change", sessionId, phase }),
|
|
128512
|
-
onLiveQuestion: (sessionId, questions) =>
|
|
128513
|
-
|
|
128688
|
+
onLiveQuestion: (sessionId, questions) => {
|
|
128689
|
+
const prior = this.promptSnapshots.get(sessionId);
|
|
128690
|
+
const occurrenceId = prior?.kind === "question" && questionContentKey(prior.questions) === questionContentKey(questions) ? prior.occurrenceId : (0, import_node_crypto8.randomUUID)();
|
|
128691
|
+
this.promptSnapshots.set(sessionId, {
|
|
128692
|
+
kind: "question",
|
|
128693
|
+
sessionId,
|
|
128694
|
+
occurrenceId,
|
|
128695
|
+
questions
|
|
128696
|
+
});
|
|
128697
|
+
this.emit({ type: "event", event: "live-question", sessionId, questions, occurrenceId });
|
|
128698
|
+
},
|
|
128699
|
+
onLiveQuestionGone: (sessionId) => {
|
|
128700
|
+
this.promptSnapshots.delete(sessionId);
|
|
128701
|
+
this.emit({ type: "event", event: "live-question-gone", sessionId });
|
|
128702
|
+
},
|
|
128514
128703
|
onUserMessage: (sessionId, text, ts2) => this.emit({ type: "event", event: "user-message", sessionId, text, ts: ts2 })
|
|
128515
128704
|
});
|
|
128516
128705
|
this.idleTimer = setInterval(() => this.reapIdle(), options.idleSweepMs ?? HOST_IDLE_SWEEP_MS);
|
|
@@ -128579,11 +128768,12 @@ var init_host = __esm({
|
|
|
128579
128768
|
event: "pty_host.streamer_subscribed",
|
|
128580
128769
|
subscribers: this.subscribers.size
|
|
128581
128770
|
});
|
|
128582
|
-
return {};
|
|
128771
|
+
return { promptSnapshots: [...this.promptSnapshots.values()] };
|
|
128583
128772
|
case "status":
|
|
128584
128773
|
return {
|
|
128585
128774
|
protocolVersion: PTY_HOST_PROTOCOL_VERSION,
|
|
128586
|
-
sessions: this.runner.listSessions().map((session) => this.toHostSession(session))
|
|
128775
|
+
sessions: this.runner.listSessions().map((session) => this.toHostSession(session)),
|
|
128776
|
+
promptSnapshots: [...this.promptSnapshots.values()]
|
|
128587
128777
|
};
|
|
128588
128778
|
case "heartbeat":
|
|
128589
128779
|
this.heartbeatLeases.set(transport, Date.now());
|
|
@@ -128641,6 +128831,7 @@ var init_host = __esm({
|
|
|
128641
128831
|
}
|
|
128642
128832
|
forget(sessionId) {
|
|
128643
128833
|
this.lastAgentChunkAt.delete(sessionId);
|
|
128834
|
+
this.promptSnapshots.delete(sessionId);
|
|
128644
128835
|
}
|
|
128645
128836
|
/**
|
|
128646
128837
|
* Release PTYs whose agent has been silent past the threshold.
|
|
@@ -132718,13 +132909,13 @@ var checkOptionalParameter = (path2) => {
|
|
|
132718
132909
|
if (segment !== "" && !/\:/.test(segment)) {
|
|
132719
132910
|
basePath += "/" + segment;
|
|
132720
132911
|
} else if (/\:/.test(segment)) {
|
|
132721
|
-
if (
|
|
132912
|
+
if (segment.charCodeAt(segment.length - 1) === 63) {
|
|
132722
132913
|
if (results.length === 0 && basePath === "") {
|
|
132723
132914
|
results.push("/");
|
|
132724
132915
|
} else {
|
|
132725
132916
|
results.push(basePath);
|
|
132726
132917
|
}
|
|
132727
|
-
const optionalSegment = segment.
|
|
132918
|
+
const optionalSegment = segment.slice(0, -1);
|
|
132728
132919
|
basePath += "/" + optionalSegment;
|
|
132729
132920
|
results.push(basePath);
|
|
132730
132921
|
} else {
|
|
@@ -132734,18 +132925,16 @@ var checkOptionalParameter = (path2) => {
|
|
|
132734
132925
|
});
|
|
132735
132926
|
return results.filter((v2, i, a) => a.indexOf(v2) === i);
|
|
132736
132927
|
};
|
|
132928
|
+
var tryDecodeURIComponent = (str) => str.indexOf("%") !== -1 ? tryDecode(str, decodeURIComponent_) : str;
|
|
132737
132929
|
var _decodeURI = (value) => {
|
|
132738
|
-
if (!/[%+]/.test(value)) {
|
|
132739
|
-
return value;
|
|
132740
|
-
}
|
|
132741
132930
|
if (value.indexOf("+") !== -1) {
|
|
132742
132931
|
value = value.replace(/\+/g, " ");
|
|
132743
132932
|
}
|
|
132744
|
-
return
|
|
132933
|
+
return tryDecodeURIComponent(value);
|
|
132745
132934
|
};
|
|
132746
132935
|
var _getQueryParam = (url2, key, multiple) => {
|
|
132747
132936
|
let encoded;
|
|
132748
|
-
if (!multiple && key &&
|
|
132937
|
+
if (!multiple && key && key.indexOf("%") === -1 && key.indexOf("+") === -1) {
|
|
132749
132938
|
let keyIndex2 = url2.indexOf("?", 8);
|
|
132750
132939
|
if (keyIndex2 === -1) {
|
|
132751
132940
|
return void 0;
|
|
@@ -132817,7 +133006,6 @@ var getQueryParams = (url2, key) => {
|
|
|
132817
133006
|
var decodeURIComponent_ = decodeURIComponent;
|
|
132818
133007
|
|
|
132819
133008
|
// node_modules/hono/dist/request.js
|
|
132820
|
-
var tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);
|
|
132821
133009
|
var HonoRequest = class {
|
|
132822
133010
|
/**
|
|
132823
133011
|
* `.raw` can get the raw Request object.
|
|
@@ -132856,7 +133044,6 @@ var HonoRequest = class {
|
|
|
132856
133044
|
this.raw = request;
|
|
132857
133045
|
this.path = path2;
|
|
132858
133046
|
this.#matchResult = matchResult;
|
|
132859
|
-
this.#validatedData = {};
|
|
132860
133047
|
}
|
|
132861
133048
|
param(key) {
|
|
132862
133049
|
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
|
|
@@ -132864,7 +133051,7 @@ var HonoRequest = class {
|
|
|
132864
133051
|
#getDecodedParam(key) {
|
|
132865
133052
|
const paramKey = this.#matchResult[0][this.routeIndex][1][key];
|
|
132866
133053
|
const param = this.#getParamValue(paramKey);
|
|
132867
|
-
return param &&
|
|
133054
|
+
return param && tryDecodeURIComponent(param);
|
|
132868
133055
|
}
|
|
132869
133056
|
#getAllDecodedParams() {
|
|
132870
133057
|
const decoded = {};
|
|
@@ -132872,7 +133059,7 @@ var HonoRequest = class {
|
|
|
132872
133059
|
for (const key of keys) {
|
|
132873
133060
|
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
|
|
132874
133061
|
if (value !== void 0) {
|
|
132875
|
-
decoded[key] =
|
|
133062
|
+
decoded[key] = tryDecodeURIComponent(value);
|
|
132876
133063
|
}
|
|
132877
133064
|
}
|
|
132878
133065
|
return decoded;
|
|
@@ -132905,8 +133092,7 @@ var HonoRequest = class {
|
|
|
132905
133092
|
if (cachedBody) {
|
|
132906
133093
|
return cachedBody;
|
|
132907
133094
|
}
|
|
132908
|
-
const anyCachedKey
|
|
132909
|
-
if (anyCachedKey) {
|
|
133095
|
+
for (const anyCachedKey in bodyCache) {
|
|
132910
133096
|
return bodyCache[anyCachedKey].then((body) => {
|
|
132911
133097
|
if (anyCachedKey === "json") {
|
|
132912
133098
|
body = JSON.stringify(body);
|
|
@@ -133009,10 +133195,11 @@ var HonoRequest = class {
|
|
|
133009
133195
|
* @param data - The validated data to add.
|
|
133010
133196
|
*/
|
|
133011
133197
|
addValidatedData(target, data) {
|
|
133012
|
-
|
|
133198
|
+
;
|
|
133199
|
+
(this.#validatedData ??= {})[target] = data;
|
|
133013
133200
|
}
|
|
133014
133201
|
valid(target) {
|
|
133015
|
-
return this.#validatedData[target];
|
|
133202
|
+
return this.#validatedData?.[target];
|
|
133016
133203
|
}
|
|
133017
133204
|
/**
|
|
133018
133205
|
* `.url()` can get the request url strings.
|
|
@@ -133343,6 +133530,10 @@ var Context = class {
|
|
|
133343
133530
|
* c.header('X-Message', 'Hello!')
|
|
133344
133531
|
* c.header('Content-Type', 'text/plain')
|
|
133345
133532
|
*
|
|
133533
|
+
* // Append multiple headers using the append option (e.g. Vary)
|
|
133534
|
+
* c.header('Vary', 'Accept-Encoding', { append: true })
|
|
133535
|
+
* c.header('Vary', 'User-Agent', { append: true })
|
|
133536
|
+
*
|
|
133346
133537
|
* return c.body('Thank you for coming')
|
|
133347
133538
|
* })
|
|
133348
133539
|
* ```
|
|
@@ -133414,11 +133605,11 @@ var Context = class {
|
|
|
133414
133605
|
return Object.fromEntries(this.#var);
|
|
133415
133606
|
}
|
|
133416
133607
|
#newResponse(data, arg, headers) {
|
|
133417
|
-
|
|
133418
|
-
if (typeof arg === "object" &&
|
|
133419
|
-
|
|
133420
|
-
for (const [key, value] of
|
|
133421
|
-
if (key
|
|
133608
|
+
let responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders;
|
|
133609
|
+
if (typeof arg === "object" && arg.headers) {
|
|
133610
|
+
responseHeaders ??= new Headers();
|
|
133611
|
+
for (const [key, value] of new Headers(arg.headers)) {
|
|
133612
|
+
if (key === "set-cookie") {
|
|
133422
133613
|
responseHeaders.append(key, value);
|
|
133423
133614
|
} else {
|
|
133424
133615
|
responseHeaders.set(key, value);
|
|
@@ -133426,19 +133617,34 @@ var Context = class {
|
|
|
133426
133617
|
}
|
|
133427
133618
|
}
|
|
133428
133619
|
if (headers) {
|
|
133429
|
-
|
|
133430
|
-
|
|
133431
|
-
|
|
133432
|
-
|
|
133433
|
-
|
|
133434
|
-
|
|
133435
|
-
|
|
133620
|
+
if (!responseHeaders) {
|
|
133621
|
+
let count = 0;
|
|
133622
|
+
for (const k2 in headers) {
|
|
133623
|
+
if (++count > 1 || typeof headers[k2] !== "string") {
|
|
133624
|
+
responseHeaders = new Headers();
|
|
133625
|
+
break;
|
|
133626
|
+
}
|
|
133627
|
+
}
|
|
133628
|
+
}
|
|
133629
|
+
if (responseHeaders) {
|
|
133630
|
+
for (const k2 in headers) {
|
|
133631
|
+
const v2 = headers[k2];
|
|
133632
|
+
if (typeof v2 === "string") {
|
|
133633
|
+
responseHeaders.set(k2, v2);
|
|
133634
|
+
} else {
|
|
133635
|
+
responseHeaders.delete(k2);
|
|
133636
|
+
for (const v22 of v2) {
|
|
133637
|
+
responseHeaders.append(k2, v22);
|
|
133638
|
+
}
|
|
133436
133639
|
}
|
|
133437
133640
|
}
|
|
133438
133641
|
}
|
|
133439
133642
|
}
|
|
133440
133643
|
const status = typeof arg === "number" ? arg : arg?.status ?? this.#status;
|
|
133441
|
-
return createResponseInstance(data, {
|
|
133644
|
+
return createResponseInstance(data, {
|
|
133645
|
+
status,
|
|
133646
|
+
headers: responseHeaders ?? headers
|
|
133647
|
+
});
|
|
133442
133648
|
}
|
|
133443
133649
|
newResponse = (...args) => this.#newResponse(...args);
|
|
133444
133650
|
/**
|
|
@@ -133551,7 +133757,7 @@ var Context = class {
|
|
|
133551
133757
|
// node_modules/hono/dist/router.js
|
|
133552
133758
|
var METHOD_NAME_ALL = "ALL";
|
|
133553
133759
|
var METHOD_NAME_ALL_LOWERCASE = "all";
|
|
133554
|
-
var METHODS = ["get", "post", "put", "delete", "options", "patch"];
|
|
133760
|
+
var METHODS = ["get", "post", "put", "delete", "options", "patch", "query"];
|
|
133555
133761
|
var MESSAGE_MATCHER_IS_ALREADY_BUILT = "Can not add a route since the matcher is already built.";
|
|
133556
133762
|
var UnsupportedPathError = class extends Error {
|
|
133557
133763
|
};
|
|
@@ -133578,6 +133784,7 @@ var Hono = class _Hono {
|
|
|
133578
133784
|
delete;
|
|
133579
133785
|
options;
|
|
133580
133786
|
patch;
|
|
133787
|
+
query;
|
|
133581
133788
|
all;
|
|
133582
133789
|
on;
|
|
133583
133790
|
use;
|
|
@@ -133877,8 +134084,8 @@ var Hono = class _Hono {
|
|
|
133877
134084
|
* @see {@link https://hono.dev/docs/api/hono#fetch}
|
|
133878
134085
|
*
|
|
133879
134086
|
* @param {Request} request - request Object of request
|
|
133880
|
-
* @param {Env}
|
|
133881
|
-
* @param {ExecutionContext} - context of execution
|
|
134087
|
+
* @param {Env} env - env Object
|
|
134088
|
+
* @param {ExecutionContext} executionCtx - context of execution
|
|
133882
134089
|
* @returns {Response | Promise<Response>} response of request
|
|
133883
134090
|
*
|
|
133884
134091
|
*/
|
|
@@ -133970,7 +134177,7 @@ function compareKey(a, b2) {
|
|
|
133970
134177
|
return 1;
|
|
133971
134178
|
}
|
|
133972
134179
|
if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
|
|
133973
|
-
return 1;
|
|
134180
|
+
return b2 === TAIL_WILDCARD_REG_EXP_STR ? -1 : 1;
|
|
133974
134181
|
} else if (b2 === ONLY_WILDCARD_REG_EXP_STR || b2 === TAIL_WILDCARD_REG_EXP_STR) {
|
|
133975
134182
|
return -1;
|
|
133976
134183
|
}
|
|
@@ -133982,76 +134189,75 @@ function compareKey(a, b2) {
|
|
|
133982
134189
|
return a.length === b2.length ? a < b2 ? -1 : 1 : b2.length - a.length;
|
|
133983
134190
|
}
|
|
133984
134191
|
var Node = class _Node {
|
|
134192
|
+
// handler index of a dynamic path, or -1 for a static path terminal
|
|
133985
134193
|
#index;
|
|
133986
134194
|
#varIndex;
|
|
133987
134195
|
#children = /* @__PURE__ */ Object.create(null);
|
|
133988
|
-
insert(tokens, index, paramMap, context,
|
|
133989
|
-
|
|
133990
|
-
|
|
133991
|
-
|
|
133992
|
-
}
|
|
133993
|
-
|
|
133994
|
-
|
|
133995
|
-
|
|
133996
|
-
|
|
133997
|
-
|
|
133998
|
-
|
|
133999
|
-
|
|
134000
|
-
|
|
134001
|
-
|
|
134002
|
-
|
|
134003
|
-
|
|
134004
|
-
|
|
134005
|
-
|
|
134006
|
-
|
|
134007
|
-
|
|
134008
|
-
}
|
|
134009
|
-
|
|
134010
|
-
if (
|
|
134011
|
-
|
|
134012
|
-
|
|
134013
|
-
|
|
134014
|
-
|
|
134015
|
-
|
|
134016
|
-
|
|
134017
|
-
|
|
134018
|
-
|
|
134019
|
-
|
|
134020
|
-
|
|
134021
|
-
|
|
134022
|
-
return;
|
|
134196
|
+
insert(tokens, index, paramMap, context, isStatic) {
|
|
134197
|
+
let node = this;
|
|
134198
|
+
for (let i = 0, len = tokens.length; i < len; i++) {
|
|
134199
|
+
const token = tokens[i];
|
|
134200
|
+
const pattern = token.length === 1 ? token === "*" ? i === len - 1 ? ["", "", ONLY_WILDCARD_REG_EXP_STR] : ["", "", LABEL_REG_EXP_STR] : null : token === "/*" ? ["", "", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
|
134201
|
+
let nextNode;
|
|
134202
|
+
if (pattern) {
|
|
134203
|
+
const name = pattern[1];
|
|
134204
|
+
let regexpStr = pattern[2] || LABEL_REG_EXP_STR;
|
|
134205
|
+
if (name && pattern[2]) {
|
|
134206
|
+
if (regexpStr === ".*") {
|
|
134207
|
+
throw PATH_ERROR;
|
|
134208
|
+
}
|
|
134209
|
+
regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, "(?:");
|
|
134210
|
+
if (/\((?!\?:)/.test(regexpStr)) {
|
|
134211
|
+
throw PATH_ERROR;
|
|
134212
|
+
}
|
|
134213
|
+
if (regexpStr.length === 1 && regExpMetaChars.has(regexpStr)) {
|
|
134214
|
+
throw PATH_ERROR;
|
|
134215
|
+
}
|
|
134216
|
+
}
|
|
134217
|
+
nextNode = node.#children[regexpStr];
|
|
134218
|
+
if (!nextNode) {
|
|
134219
|
+
if (regexpStr !== ONLY_WILDCARD_REG_EXP_STR && regexpStr !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
134220
|
+
for (const k2 in node.#children) {
|
|
134221
|
+
if (
|
|
134222
|
+
// a single-char pattern coexists with single-char literals as a literal does
|
|
134223
|
+
(regexpStr.length > 1 || k2.length > 1) && k2 !== ONLY_WILDCARD_REG_EXP_STR && k2 !== TAIL_WILDCARD_REG_EXP_STR
|
|
134224
|
+
) {
|
|
134225
|
+
throw PATH_ERROR;
|
|
134226
|
+
}
|
|
134227
|
+
}
|
|
134228
|
+
}
|
|
134229
|
+
nextNode = node.#children[regexpStr] = new _Node();
|
|
134023
134230
|
}
|
|
134024
|
-
node = this.#children[regexpStr] = new _Node();
|
|
134025
134231
|
if (name !== "") {
|
|
134026
|
-
|
|
134232
|
+
nextNode.#varIndex ??= context.varIndex++;
|
|
134233
|
+
paramMap.push([name, nextNode.#varIndex]);
|
|
134027
134234
|
}
|
|
134028
|
-
}
|
|
134029
|
-
|
|
134030
|
-
|
|
134031
|
-
|
|
134032
|
-
|
|
134033
|
-
|
|
134034
|
-
|
|
134035
|
-
|
|
134036
|
-
|
|
134037
|
-
)) {
|
|
134038
|
-
throw PATH_ERROR;
|
|
134039
|
-
}
|
|
134040
|
-
if (pathErrorCheckOnly) {
|
|
134041
|
-
return;
|
|
134235
|
+
} else {
|
|
134236
|
+
nextNode = node.#children[token];
|
|
134237
|
+
if (!nextNode) {
|
|
134238
|
+
for (const k2 in node.#children) {
|
|
134239
|
+
if (k2.length > 1 && k2 !== ONLY_WILDCARD_REG_EXP_STR && k2 !== TAIL_WILDCARD_REG_EXP_STR) {
|
|
134240
|
+
throw PATH_ERROR;
|
|
134241
|
+
}
|
|
134242
|
+
}
|
|
134243
|
+
nextNode = node.#children[token] = new _Node();
|
|
134042
134244
|
}
|
|
134043
|
-
node = this.#children[token] = new _Node();
|
|
134044
134245
|
}
|
|
134246
|
+
node = nextNode;
|
|
134247
|
+
}
|
|
134248
|
+
if (node.#index !== void 0) {
|
|
134249
|
+
throw PATH_ERROR;
|
|
134045
134250
|
}
|
|
134046
|
-
node
|
|
134251
|
+
node.#index = isStatic ? -1 : index;
|
|
134047
134252
|
}
|
|
134048
134253
|
buildRegExpStr() {
|
|
134049
134254
|
const childKeys = Object.keys(this.#children).sort(compareKey);
|
|
134050
134255
|
const strList = childKeys.map((k2) => {
|
|
134051
134256
|
const c = this.#children[k2];
|
|
134052
|
-
|
|
134053
|
-
|
|
134054
|
-
|
|
134257
|
+
const childStr = c.buildRegExpStr();
|
|
134258
|
+
return childStr === "" ? "" : (typeof c.#varIndex === "number" ? `(${k2})@${c.#varIndex}` : regExpMetaChars.has(k2) ? `\\${k2}` : k2) + childStr;
|
|
134259
|
+
}).filter(Boolean);
|
|
134260
|
+
if (typeof this.#index === "number" && this.#index !== -1) {
|
|
134055
134261
|
strList.unshift(`#${this.#index}`);
|
|
134056
134262
|
}
|
|
134057
134263
|
if (strList.length === 0) {
|
|
@@ -134068,12 +134274,20 @@ var Node = class _Node {
|
|
|
134068
134274
|
var Trie = class {
|
|
134069
134275
|
#context = { varIndex: 0 };
|
|
134070
134276
|
#root = new Node();
|
|
134071
|
-
|
|
134277
|
+
#index = 0;
|
|
134278
|
+
// dynamic path -> [handler index, param assoc]; static paths are not registered
|
|
134279
|
+
paths = /* @__PURE__ */ Object.create(null);
|
|
134280
|
+
insert(path2, isStatic) {
|
|
134281
|
+
if (isStatic) {
|
|
134282
|
+
this.#root.insert(path2.split(""), 0, [], this.#context, true);
|
|
134283
|
+
return;
|
|
134284
|
+
}
|
|
134072
134285
|
const paramAssoc = [];
|
|
134073
134286
|
const groups = [];
|
|
134287
|
+
let markedPath = path2;
|
|
134074
134288
|
for (let i = 0; ; ) {
|
|
134075
134289
|
let replaced = false;
|
|
134076
|
-
|
|
134290
|
+
markedPath = markedPath.replace(/\{[^}]+\}/g, (m2) => {
|
|
134077
134291
|
const mark = `@\\${i}`;
|
|
134078
134292
|
groups[i] = [mark, m2];
|
|
134079
134293
|
i++;
|
|
@@ -134084,7 +134298,7 @@ var Trie = class {
|
|
|
134084
134298
|
break;
|
|
134085
134299
|
}
|
|
134086
134300
|
}
|
|
134087
|
-
const tokens =
|
|
134301
|
+
const tokens = markedPath.match(/(?::[^\/]+)|(?:\/\*$)|./g) || [];
|
|
134088
134302
|
for (let i = groups.length - 1; i >= 0; i--) {
|
|
134089
134303
|
const [mark] = groups[i];
|
|
134090
134304
|
for (let j2 = tokens.length - 1; j2 >= 0; j2--) {
|
|
@@ -134094,8 +134308,8 @@ var Trie = class {
|
|
|
134094
134308
|
}
|
|
134095
134309
|
}
|
|
134096
134310
|
}
|
|
134097
|
-
this.#root.insert(tokens, index, paramAssoc, this.#context,
|
|
134098
|
-
|
|
134311
|
+
this.#root.insert(tokens, this.#index, paramAssoc, this.#context, false);
|
|
134312
|
+
this.paths[path2] = [this.#index++, paramAssoc];
|
|
134099
134313
|
}
|
|
134100
134314
|
buildRegExp() {
|
|
134101
134315
|
let regexp = this.#root.buildRegExpStr();
|
|
@@ -134121,7 +134335,6 @@ var Trie = class {
|
|
|
134121
134335
|
};
|
|
134122
134336
|
|
|
134123
134337
|
// node_modules/hono/dist/router/reg-exp-router/router.js
|
|
134124
|
-
var nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];
|
|
134125
134338
|
var wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
134126
134339
|
function buildWildcardRegExp(path2) {
|
|
134127
134340
|
return wildcardRegExpCache[path2] ??= new RegExp(
|
|
@@ -134134,63 +134347,6 @@ function buildWildcardRegExp(path2) {
|
|
|
134134
134347
|
function clearWildcardRegExpCache() {
|
|
134135
134348
|
wildcardRegExpCache = /* @__PURE__ */ Object.create(null);
|
|
134136
134349
|
}
|
|
134137
|
-
function buildMatcherFromPreprocessedRoutes(routes) {
|
|
134138
|
-
const trie = new Trie();
|
|
134139
|
-
const handlerData = [];
|
|
134140
|
-
if (routes.length === 0) {
|
|
134141
|
-
return nullMatcher;
|
|
134142
|
-
}
|
|
134143
|
-
const routesWithStaticPathFlag = routes.map(
|
|
134144
|
-
(route) => [!/\*|\/:/.test(route[0]), ...route]
|
|
134145
|
-
).sort(
|
|
134146
|
-
([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
|
|
134147
|
-
);
|
|
134148
|
-
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
134149
|
-
for (let i = 0, j2 = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
|
|
134150
|
-
const [pathErrorCheckOnly, path2, handlers] = routesWithStaticPathFlag[i];
|
|
134151
|
-
if (pathErrorCheckOnly) {
|
|
134152
|
-
staticMap[path2] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
134153
|
-
} else {
|
|
134154
|
-
j2++;
|
|
134155
|
-
}
|
|
134156
|
-
let paramAssoc;
|
|
134157
|
-
try {
|
|
134158
|
-
paramAssoc = trie.insert(path2, j2, pathErrorCheckOnly);
|
|
134159
|
-
} catch (e) {
|
|
134160
|
-
throw e === PATH_ERROR ? new UnsupportedPathError(path2) : e;
|
|
134161
|
-
}
|
|
134162
|
-
if (pathErrorCheckOnly) {
|
|
134163
|
-
continue;
|
|
134164
|
-
}
|
|
134165
|
-
handlerData[j2] = handlers.map(([h, paramCount]) => {
|
|
134166
|
-
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
134167
|
-
paramCount -= 1;
|
|
134168
|
-
for (; paramCount >= 0; paramCount--) {
|
|
134169
|
-
const [key, value] = paramAssoc[paramCount];
|
|
134170
|
-
paramIndexMap[key] = value;
|
|
134171
|
-
}
|
|
134172
|
-
return [h, paramIndexMap];
|
|
134173
|
-
});
|
|
134174
|
-
}
|
|
134175
|
-
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
134176
|
-
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
134177
|
-
for (let j2 = 0, len2 = handlerData[i].length; j2 < len2; j2++) {
|
|
134178
|
-
const map2 = handlerData[i][j2]?.[1];
|
|
134179
|
-
if (!map2) {
|
|
134180
|
-
continue;
|
|
134181
|
-
}
|
|
134182
|
-
const keys = Object.keys(map2);
|
|
134183
|
-
for (let k2 = 0, len3 = keys.length; k2 < len3; k2++) {
|
|
134184
|
-
map2[keys[k2]] = paramReplacementMap[map2[keys[k2]]];
|
|
134185
|
-
}
|
|
134186
|
-
}
|
|
134187
|
-
}
|
|
134188
|
-
const handlerMap = [];
|
|
134189
|
-
for (const i in indexReplacementMap) {
|
|
134190
|
-
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
134191
|
-
}
|
|
134192
|
-
return [regexp, handlerMap, staticMap];
|
|
134193
|
-
}
|
|
134194
134350
|
function findMiddleware(middleware, path2) {
|
|
134195
134351
|
if (!middleware) {
|
|
134196
134352
|
return void 0;
|
|
@@ -134206,9 +134362,18 @@ var RegExpRouter = class {
|
|
|
134206
134362
|
name = "RegExpRouter";
|
|
134207
134363
|
#middleware;
|
|
134208
134364
|
#routes;
|
|
134365
|
+
#tries;
|
|
134209
134366
|
constructor() {
|
|
134210
134367
|
this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
|
|
134211
134368
|
this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };
|
|
134369
|
+
this.#tries = { [METHOD_NAME_ALL]: new Trie() };
|
|
134370
|
+
}
|
|
134371
|
+
#insertPath(method, path2) {
|
|
134372
|
+
try {
|
|
134373
|
+
this.#tries[method].insert(path2, !/\*|\/:/.test(path2));
|
|
134374
|
+
} catch (e) {
|
|
134375
|
+
throw e === PATH_ERROR ? new UnsupportedPathError(path2) : e;
|
|
134376
|
+
}
|
|
134212
134377
|
}
|
|
134213
134378
|
add(method, path2, handler) {
|
|
134214
134379
|
const middleware = this.#middleware;
|
|
@@ -134217,11 +134382,12 @@ var RegExpRouter = class {
|
|
|
134217
134382
|
throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);
|
|
134218
134383
|
}
|
|
134219
134384
|
if (!middleware[method]) {
|
|
134220
|
-
;
|
|
134385
|
+
this.#tries[method] = new Trie();
|
|
134221
134386
|
[middleware, routes].forEach((handlerMap) => {
|
|
134222
134387
|
handlerMap[method] = /* @__PURE__ */ Object.create(null);
|
|
134223
134388
|
Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p2) => {
|
|
134224
134389
|
handlerMap[method][p2] = [...handlerMap[METHOD_NAME_ALL][p2]];
|
|
134390
|
+
this.#insertPath(method, p2);
|
|
134225
134391
|
});
|
|
134226
134392
|
});
|
|
134227
134393
|
}
|
|
@@ -134231,13 +134397,12 @@ var RegExpRouter = class {
|
|
|
134231
134397
|
const paramCount = (path2.match(/\/:/g) || []).length;
|
|
134232
134398
|
if (/\*$/.test(path2)) {
|
|
134233
134399
|
const re2 = buildWildcardRegExp(path2);
|
|
134234
|
-
|
|
134235
|
-
|
|
134236
|
-
|
|
134237
|
-
|
|
134238
|
-
|
|
134239
|
-
|
|
134240
|
-
}
|
|
134400
|
+
Object.keys(middleware).forEach((m2) => {
|
|
134401
|
+
if ((method === METHOD_NAME_ALL || method === m2) && !middleware[m2][path2]) {
|
|
134402
|
+
this.#insertPath(m2, path2);
|
|
134403
|
+
middleware[m2][path2] = findMiddleware(middleware[m2], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || [];
|
|
134404
|
+
}
|
|
134405
|
+
});
|
|
134241
134406
|
Object.keys(middleware).forEach((m2) => {
|
|
134242
134407
|
if (method === METHOD_NAME_ALL || method === m2) {
|
|
134243
134408
|
Object.keys(middleware[m2]).forEach((p2) => {
|
|
@@ -134259,9 +134424,12 @@ var RegExpRouter = class {
|
|
|
134259
134424
|
const path22 = paths[i];
|
|
134260
134425
|
Object.keys(routes).forEach((m2) => {
|
|
134261
134426
|
if (method === METHOD_NAME_ALL || method === m2) {
|
|
134262
|
-
routes[m2][path22]
|
|
134263
|
-
|
|
134264
|
-
|
|
134427
|
+
if (!routes[m2][path22]) {
|
|
134428
|
+
this.#insertPath(m2, path22);
|
|
134429
|
+
routes[m2][path22] = [
|
|
134430
|
+
...findMiddleware(middleware[m2], path22) || findMiddleware(middleware[METHOD_NAME_ALL], path22) || []
|
|
134431
|
+
];
|
|
134432
|
+
}
|
|
134265
134433
|
routes[m2][path22].push([handler, paramCount - len + i + 1]);
|
|
134266
134434
|
}
|
|
134267
134435
|
});
|
|
@@ -134273,29 +134441,54 @@ var RegExpRouter = class {
|
|
|
134273
134441
|
Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {
|
|
134274
134442
|
matchers[method] ||= this.#buildMatcher(method);
|
|
134275
134443
|
});
|
|
134276
|
-
this.#middleware = this.#routes = void 0;
|
|
134444
|
+
this.#middleware = this.#routes = this.#tries = void 0;
|
|
134277
134445
|
clearWildcardRegExpCache();
|
|
134278
134446
|
return matchers;
|
|
134279
134447
|
}
|
|
134280
134448
|
#buildMatcher(method) {
|
|
134281
|
-
const
|
|
134282
|
-
|
|
134283
|
-
|
|
134284
|
-
|
|
134285
|
-
|
|
134286
|
-
|
|
134287
|
-
|
|
134288
|
-
|
|
134289
|
-
|
|
134290
|
-
|
|
134291
|
-
|
|
134449
|
+
const middleware = this.#middleware[method];
|
|
134450
|
+
const routes = this.#routes[method];
|
|
134451
|
+
const trie = this.#tries[method];
|
|
134452
|
+
const staticMap = /* @__PURE__ */ Object.create(null);
|
|
134453
|
+
const handlerData = [];
|
|
134454
|
+
[middleware, routes].forEach((r) => {
|
|
134455
|
+
for (const path2 in r) {
|
|
134456
|
+
const handlers = r[path2];
|
|
134457
|
+
const pathData = trie.paths[path2];
|
|
134458
|
+
if (!pathData) {
|
|
134459
|
+
staticMap[path2] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];
|
|
134460
|
+
continue;
|
|
134461
|
+
}
|
|
134462
|
+
const paramAssoc = pathData[1];
|
|
134463
|
+
handlerData[pathData[0]] = handlers.map(([h, paramCount]) => {
|
|
134464
|
+
const paramIndexMap = /* @__PURE__ */ Object.create(null);
|
|
134465
|
+
paramCount -= 1;
|
|
134466
|
+
for (; paramCount >= 0; paramCount--) {
|
|
134467
|
+
const [key, value] = paramAssoc[paramCount];
|
|
134468
|
+
paramIndexMap[key] = value;
|
|
134469
|
+
}
|
|
134470
|
+
return [h, paramIndexMap];
|
|
134471
|
+
});
|
|
134292
134472
|
}
|
|
134293
134473
|
});
|
|
134294
|
-
|
|
134295
|
-
|
|
134296
|
-
|
|
134297
|
-
|
|
134474
|
+
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
134475
|
+
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
134476
|
+
for (let j2 = 0, len2 = handlerData[i].length; j2 < len2; j2++) {
|
|
134477
|
+
const map2 = handlerData[i][j2]?.[1];
|
|
134478
|
+
if (!map2) {
|
|
134479
|
+
continue;
|
|
134480
|
+
}
|
|
134481
|
+
const keys = Object.keys(map2);
|
|
134482
|
+
for (let k2 = 0, len3 = keys.length; k2 < len3; k2++) {
|
|
134483
|
+
map2[keys[k2]] = paramReplacementMap[map2[keys[k2]]];
|
|
134484
|
+
}
|
|
134485
|
+
}
|
|
134486
|
+
}
|
|
134487
|
+
const handlerMap = [];
|
|
134488
|
+
for (const i in indexReplacementMap) {
|
|
134489
|
+
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
134298
134490
|
}
|
|
134491
|
+
return [regexp, handlerMap, staticMap];
|
|
134299
134492
|
}
|
|
134300
134493
|
};
|
|
134301
134494
|
|
|
@@ -134356,76 +134549,51 @@ var SmartRouter = class {
|
|
|
134356
134549
|
|
|
134357
134550
|
// node_modules/hono/dist/router/trie-router/node.js
|
|
134358
134551
|
var emptyParams = /* @__PURE__ */ Object.create(null);
|
|
134359
|
-
var
|
|
134360
|
-
for (const _2 in children) {
|
|
134361
|
-
return true;
|
|
134362
|
-
}
|
|
134363
|
-
return false;
|
|
134364
|
-
};
|
|
134552
|
+
var order = 0;
|
|
134365
134553
|
var Node2 = class _Node2 {
|
|
134366
|
-
#methods;
|
|
134367
|
-
#children;
|
|
134368
|
-
#patterns;
|
|
134369
|
-
#
|
|
134554
|
+
#methods = [];
|
|
134555
|
+
#children = /* @__PURE__ */ Object.create(null);
|
|
134556
|
+
#patterns = [];
|
|
134557
|
+
#pattern;
|
|
134370
134558
|
#params = emptyParams;
|
|
134371
|
-
constructor(method, handler, children) {
|
|
134372
|
-
this.#children = children || /* @__PURE__ */ Object.create(null);
|
|
134373
|
-
this.#methods = [];
|
|
134374
|
-
if (method && handler) {
|
|
134375
|
-
const m2 = /* @__PURE__ */ Object.create(null);
|
|
134376
|
-
m2[method] = { handler, possibleKeys: [], score: 0 };
|
|
134377
|
-
this.#methods = [m2];
|
|
134378
|
-
}
|
|
134379
|
-
this.#patterns = [];
|
|
134380
|
-
}
|
|
134381
134559
|
insert(method, path2, handler) {
|
|
134382
|
-
this.#order = ++this.#order;
|
|
134383
134560
|
let curNode = this;
|
|
134384
134561
|
const parts = splitRoutingPath(path2);
|
|
134385
|
-
const possibleKeys =
|
|
134386
|
-
|
|
134387
|
-
|
|
134388
|
-
const nextP = parts[i
|
|
134389
|
-
const pattern = getPattern(p2, nextP);
|
|
134390
|
-
const
|
|
134391
|
-
|
|
134392
|
-
|
|
134393
|
-
|
|
134394
|
-
|
|
134395
|
-
|
|
134396
|
-
continue;
|
|
134562
|
+
const possibleKeys = /* @__PURE__ */ new Set();
|
|
134563
|
+
let i = 0;
|
|
134564
|
+
for (const p2 of parts) {
|
|
134565
|
+
const nextP = parts[++i];
|
|
134566
|
+
const pattern = getPattern(p2, nextP) || (nextP === void 0 && p2 && p2.indexOf("*") === p2.length - 1 ? p2 : null);
|
|
134567
|
+
const isParam = Array.isArray(pattern);
|
|
134568
|
+
const key = isParam ? pattern[0] : pattern || p2;
|
|
134569
|
+
const child = curNode.#children[key] ||= new _Node2();
|
|
134570
|
+
if (pattern && !child.#pattern) {
|
|
134571
|
+
child.#pattern = pattern;
|
|
134572
|
+
curNode.#patterns.push(child);
|
|
134397
134573
|
}
|
|
134398
|
-
curNode
|
|
134399
|
-
if (
|
|
134400
|
-
|
|
134401
|
-
possibleKeys.push(pattern[1]);
|
|
134574
|
+
curNode = child;
|
|
134575
|
+
if (isParam) {
|
|
134576
|
+
possibleKeys.add(pattern[1]);
|
|
134402
134577
|
}
|
|
134403
|
-
curNode = curNode.#children[key];
|
|
134404
134578
|
}
|
|
134405
134579
|
curNode.#methods.push({
|
|
134406
134580
|
[method]: {
|
|
134407
134581
|
handler,
|
|
134408
|
-
possibleKeys: possibleKeys
|
|
134409
|
-
score:
|
|
134582
|
+
possibleKeys: [...possibleKeys],
|
|
134583
|
+
score: ++order
|
|
134410
134584
|
}
|
|
134411
134585
|
});
|
|
134412
|
-
return curNode;
|
|
134413
134586
|
}
|
|
134414
134587
|
#pushHandlerSets(handlerSets, node, method, nodeParams, params) {
|
|
134415
134588
|
for (let i = 0, len = node.#methods.length; i < len; i++) {
|
|
134416
134589
|
const m2 = node.#methods[i];
|
|
134417
134590
|
const handlerSet = m2[method] || m2[METHOD_NAME_ALL];
|
|
134418
|
-
|
|
134419
|
-
if (handlerSet !== void 0) {
|
|
134591
|
+
if (handlerSet) {
|
|
134420
134592
|
handlerSet.params = /* @__PURE__ */ Object.create(null);
|
|
134421
134593
|
handlerSets.push(handlerSet);
|
|
134422
|
-
|
|
134423
|
-
|
|
134424
|
-
|
|
134425
|
-
const processed = processedSet[handlerSet.score];
|
|
134426
|
-
handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];
|
|
134427
|
-
processedSet[handlerSet.score] = true;
|
|
134428
|
-
}
|
|
134594
|
+
for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {
|
|
134595
|
+
const key = handlerSet.possibleKeys[i2];
|
|
134596
|
+
handlerSet.params[key] = params?.[key] && !i2 ? params[key] : nodeParams[key] ?? params?.[key];
|
|
134429
134597
|
}
|
|
134430
134598
|
}
|
|
134431
134599
|
}
|
|
@@ -134457,33 +134625,33 @@ var Node2 = class _Node2 {
|
|
|
134457
134625
|
tempNodes.push(nextNode);
|
|
134458
134626
|
}
|
|
134459
134627
|
}
|
|
134460
|
-
for (
|
|
134461
|
-
const pattern =
|
|
134628
|
+
for (const child of node.#patterns) {
|
|
134629
|
+
const pattern = child.#pattern;
|
|
134462
134630
|
const params = node.#params === emptyParams ? {} : { ...node.#params };
|
|
134463
|
-
if (pattern === "
|
|
134464
|
-
|
|
134465
|
-
|
|
134466
|
-
|
|
134467
|
-
|
|
134468
|
-
|
|
134631
|
+
if (typeof pattern === "string") {
|
|
134632
|
+
if (pattern === "*" || part.startsWith(pattern.slice(0, -1))) {
|
|
134633
|
+
this.#pushHandlerSets(handlerSets, child, method, node.#params);
|
|
134634
|
+
if (pattern === "*") {
|
|
134635
|
+
child.#params = params;
|
|
134636
|
+
tempNodes.push(child);
|
|
134637
|
+
}
|
|
134469
134638
|
}
|
|
134470
134639
|
continue;
|
|
134471
134640
|
}
|
|
134472
|
-
const [
|
|
134473
|
-
if (!part &&
|
|
134641
|
+
const [, name, matcher] = pattern;
|
|
134642
|
+
if (!part && matcher === true) {
|
|
134474
134643
|
continue;
|
|
134475
134644
|
}
|
|
134476
|
-
|
|
134477
|
-
|
|
134478
|
-
|
|
134479
|
-
partOffsets = new Array(len);
|
|
134645
|
+
if (matcher !== true) {
|
|
134646
|
+
if (!partOffsets) {
|
|
134647
|
+
partOffsets = [];
|
|
134480
134648
|
let offset = path2[0] === "/" ? 1 : 0;
|
|
134481
134649
|
for (let p2 = 0; p2 < len; p2++) {
|
|
134482
134650
|
partOffsets[p2] = offset;
|
|
134483
134651
|
offset += parts[p2].length + 1;
|
|
134484
134652
|
}
|
|
134485
134653
|
}
|
|
134486
|
-
const restPathString = path2.
|
|
134654
|
+
const restPathString = path2.slice(partOffsets[i]);
|
|
134487
134655
|
const m2 = matcher.exec(restPathString);
|
|
134488
134656
|
if (m2) {
|
|
134489
134657
|
params[name] = m2[0];
|
|
@@ -134497,11 +134665,12 @@ var Node2 = class _Node2 {
|
|
|
134497
134665
|
params
|
|
134498
134666
|
);
|
|
134499
134667
|
}
|
|
134500
|
-
|
|
134668
|
+
for (const _2 in child.#children) {
|
|
134501
134669
|
child.#params = params;
|
|
134502
|
-
const componentCount = m2[0].match(/\//)?.length ?? 0;
|
|
134670
|
+
const componentCount = m2[0].match(/\//g)?.length ?? 0;
|
|
134503
134671
|
const targetCurNodes = curNodesQueue[componentCount] ||= [];
|
|
134504
134672
|
targetCurNodes.push(child);
|
|
134673
|
+
break;
|
|
134505
134674
|
}
|
|
134506
134675
|
continue;
|
|
134507
134676
|
}
|
|
@@ -134529,7 +134698,7 @@ var Node2 = class _Node2 {
|
|
|
134529
134698
|
const shifted = curNodesQueue.shift();
|
|
134530
134699
|
curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;
|
|
134531
134700
|
}
|
|
134532
|
-
if (handlerSets
|
|
134701
|
+
if (handlerSets[1]) {
|
|
134533
134702
|
handlerSets.sort((a, b2) => {
|
|
134534
134703
|
return a.score - b2.score;
|
|
134535
134704
|
});
|
|
@@ -134541,19 +134710,11 @@ var Node2 = class _Node2 {
|
|
|
134541
134710
|
// node_modules/hono/dist/router/trie-router/router.js
|
|
134542
134711
|
var TrieRouter = class {
|
|
134543
134712
|
name = "TrieRouter";
|
|
134544
|
-
#node;
|
|
134545
|
-
constructor() {
|
|
134546
|
-
this.#node = new Node2();
|
|
134547
|
-
}
|
|
134713
|
+
#node = new Node2();
|
|
134548
134714
|
add(method, path2, handler) {
|
|
134549
|
-
const
|
|
134550
|
-
|
|
134551
|
-
for (let i = 0, len = results.length; i < len; i++) {
|
|
134552
|
-
this.#node.insert(method, results[i], handler);
|
|
134553
|
-
}
|
|
134554
|
-
return;
|
|
134715
|
+
for (const result of checkOptionalParameter(path2) || [path2]) {
|
|
134716
|
+
this.#node.insert(method, result, handler);
|
|
134555
134717
|
}
|
|
134556
|
-
this.#node.insert(method, path2, handler);
|
|
134557
134718
|
}
|
|
134558
134719
|
match(method, path2) {
|
|
134559
134720
|
return this.#node.search(method, path2);
|
|
@@ -136057,7 +136218,13 @@ var createMiscRoutes = (deps) => {
|
|
|
136057
136218
|
// the box is starved. Additive capability flag only — live readings stay
|
|
136058
136219
|
// off this polled endpoint. Absent means an older server that never
|
|
136059
136220
|
// samples. Informational: pressure never holds, kills, or refuses sessions.
|
|
136060
|
-
hostPressure: true
|
|
136221
|
+
hostPressure: true,
|
|
136222
|
+
// Provider-neutral prompt contract: normalized prompt events, opaque ids
|
|
136223
|
+
// and the atomic /prompt/answer route. A prompt_snapshot on subscribe
|
|
136224
|
+
// carries RETAINED prompts, terminal ones included — render on `state`,
|
|
136225
|
+
// not on presence — and an answer retry after that retention window is
|
|
136226
|
+
// answered 404 prompt_not_found rather than the recorded outcome.
|
|
136227
|
+
promptContract: { schemaVersion: 1, atomicAnswer: true }
|
|
136061
136228
|
});
|
|
136062
136229
|
});
|
|
136063
136230
|
app.get("/api/profiles", (c) => c.json([]));
|
|
@@ -136555,6 +136722,10 @@ var createSessionRoutes = (deps) => {
|
|
|
136555
136722
|
await deps.handleSendAnswer(c.req.param("id"), c.env.incoming, c.env.outgoing);
|
|
136556
136723
|
return alreadyHandled6();
|
|
136557
136724
|
});
|
|
136725
|
+
app.post("/:id/prompt/answer", async (c) => {
|
|
136726
|
+
await deps.handlePromptAnswer(c.req.param("id"), c.env.incoming, c.env.outgoing);
|
|
136727
|
+
return alreadyHandled6();
|
|
136728
|
+
});
|
|
136558
136729
|
app.post("/:id/permission/answer", async (c) => {
|
|
136559
136730
|
await deps.handlePermissionAnswer(c.req.param("id"), c.env.incoming, c.env.outgoing);
|
|
136560
136731
|
return alreadyHandled6();
|
|
@@ -140738,10 +140909,10 @@ function watch(paths, options = {}) {
|
|
|
140738
140909
|
var chokidar_default = { watch, FSWatcher };
|
|
140739
140910
|
|
|
140740
140911
|
// node_modules/@threadbase-sh/scanner/dist/index.js
|
|
140741
|
-
function applySort(metas,
|
|
140912
|
+
function applySort(metas, order2) {
|
|
140742
140913
|
const out = [...metas];
|
|
140743
140914
|
const tie = (a, b2) => a.id.localeCompare(b2.id);
|
|
140744
|
-
switch (
|
|
140915
|
+
switch (order2) {
|
|
140745
140916
|
case "recent":
|
|
140746
140917
|
out.sort((a, b2) => b2.timestamp.localeCompare(a.timestamp) || tie(a, b2));
|
|
140747
140918
|
break;
|
|
@@ -146251,7 +146422,7 @@ function parseSessionListQuery(url2) {
|
|
|
146251
146422
|
if (!VALID_ORDERS.includes(orderRaw)) {
|
|
146252
146423
|
return { error: `order must be asc or desc` };
|
|
146253
146424
|
}
|
|
146254
|
-
const
|
|
146425
|
+
const order2 = orderRaw;
|
|
146255
146426
|
const statusRaw = url2.searchParams.get("status");
|
|
146256
146427
|
let status;
|
|
146257
146428
|
if (statusRaw) {
|
|
@@ -146264,7 +146435,7 @@ function parseSessionListQuery(url2) {
|
|
|
146264
146435
|
status = parts;
|
|
146265
146436
|
}
|
|
146266
146437
|
const cursor = url2.searchParams.get("cursor") ?? void 0;
|
|
146267
|
-
return { query: { limit, sortBy, order, status, cursor } };
|
|
146438
|
+
return { query: { limit, sortBy, order: order2, status, cursor } };
|
|
146268
146439
|
}
|
|
146269
146440
|
function readBody2(req) {
|
|
146270
146441
|
return new Promise((resolve4, reject) => {
|
|
@@ -147672,6 +147843,522 @@ async function readGitBranch2(dir) {
|
|
|
147672
147843
|
// src/api/handlers/sessions.handlers.ts
|
|
147673
147844
|
init_providers();
|
|
147674
147845
|
init_pty_shared();
|
|
147846
|
+
|
|
147847
|
+
// src/schemas/prompt.schema.ts
|
|
147848
|
+
init_zod();
|
|
147849
|
+
var PROMPT_SCHEMA_VERSION = 1;
|
|
147850
|
+
var OpaqueIdSchema = external_exports.string().trim().min(1).max(200);
|
|
147851
|
+
var MeaningfulStringSchema = external_exports.string().trim().min(1);
|
|
147852
|
+
var PromptOptionSchema = external_exports.object({
|
|
147853
|
+
optionId: OpaqueIdSchema,
|
|
147854
|
+
label: MeaningfulStringSchema,
|
|
147855
|
+
description: external_exports.string().optional(),
|
|
147856
|
+
preview: external_exports.string().optional()
|
|
147857
|
+
});
|
|
147858
|
+
var PromptQuestionSchema = external_exports.object({
|
|
147859
|
+
questionId: OpaqueIdSchema,
|
|
147860
|
+
text: MeaningfulStringSchema,
|
|
147861
|
+
header: external_exports.string().optional(),
|
|
147862
|
+
inputMode: external_exports.enum(["single", "multi", "text"]),
|
|
147863
|
+
options: external_exports.array(PromptOptionSchema),
|
|
147864
|
+
allowOther: external_exports.boolean(),
|
|
147865
|
+
secret: external_exports.union([external_exports.boolean(), external_exports.literal("unknown")])
|
|
147866
|
+
}).superRefine((question, ctx) => {
|
|
147867
|
+
const optionIds = question.options.map((option) => option.optionId);
|
|
147868
|
+
if (new Set(optionIds).size !== optionIds.length) {
|
|
147869
|
+
ctx.addIssue({
|
|
147870
|
+
code: "custom",
|
|
147871
|
+
message: "optionId values must be unique",
|
|
147872
|
+
path: ["options"]
|
|
147873
|
+
});
|
|
147874
|
+
}
|
|
147875
|
+
if (question.inputMode === "text" && question.options.length !== 0) {
|
|
147876
|
+
ctx.addIssue({
|
|
147877
|
+
code: "custom",
|
|
147878
|
+
message: "text questions cannot carry options",
|
|
147879
|
+
path: ["options"]
|
|
147880
|
+
});
|
|
147881
|
+
}
|
|
147882
|
+
if (question.inputMode !== "text" && question.options.length === 0) {
|
|
147883
|
+
ctx.addIssue({
|
|
147884
|
+
code: "custom",
|
|
147885
|
+
message: "select questions require options",
|
|
147886
|
+
path: ["options"]
|
|
147887
|
+
});
|
|
147888
|
+
}
|
|
147889
|
+
});
|
|
147890
|
+
var TERMINAL_PROMPT_STATES = /* @__PURE__ */ new Set(["resolved", "cancelled", "expired", "unavailable"]);
|
|
147891
|
+
var PromptSchema = external_exports.object({
|
|
147892
|
+
schemaVersion: external_exports.literal(PROMPT_SCHEMA_VERSION),
|
|
147893
|
+
sessionId: OpaqueIdSchema,
|
|
147894
|
+
promptId: OpaqueIdSchema,
|
|
147895
|
+
revision: external_exports.number().int().positive(),
|
|
147896
|
+
state: external_exports.enum(["open", "updated", "resolved", "cancelled", "expired", "unavailable"]),
|
|
147897
|
+
terminalReason: MeaningfulStringSchema.optional(),
|
|
147898
|
+
intent: external_exports.enum(["approval", "question"]),
|
|
147899
|
+
title: external_exports.string().optional(),
|
|
147900
|
+
message: external_exports.string().optional(),
|
|
147901
|
+
detail: external_exports.string().optional(),
|
|
147902
|
+
questions: external_exports.array(PromptQuestionSchema).min(1),
|
|
147903
|
+
answerRequirement: external_exports.enum(["blocking", "non_blocking", "unknown"]),
|
|
147904
|
+
expiresAt: external_exports.string().datetime({ offset: true }).nullable(),
|
|
147905
|
+
provenance: external_exports.object({
|
|
147906
|
+
source: external_exports.enum(["provider", "screen", "transcript", "synthetic"]),
|
|
147907
|
+
confidence: external_exports.enum(["authoritative", "inferred"])
|
|
147908
|
+
})
|
|
147909
|
+
}).superRefine((prompt, ctx) => {
|
|
147910
|
+
if (![prompt.title, prompt.message, prompt.detail].some((value) => value?.trim())) {
|
|
147911
|
+
ctx.addIssue({
|
|
147912
|
+
code: "custom",
|
|
147913
|
+
message: "prompt requires a meaningful title, message, or detail",
|
|
147914
|
+
path: ["message"]
|
|
147915
|
+
});
|
|
147916
|
+
}
|
|
147917
|
+
const questionIds = prompt.questions.map((question) => question.questionId);
|
|
147918
|
+
if (new Set(questionIds).size !== questionIds.length) {
|
|
147919
|
+
ctx.addIssue({
|
|
147920
|
+
code: "custom",
|
|
147921
|
+
message: "questionId values must be unique",
|
|
147922
|
+
path: ["questions"]
|
|
147923
|
+
});
|
|
147924
|
+
}
|
|
147925
|
+
const optionIds = prompt.questions.flatMap(
|
|
147926
|
+
(question) => question.options.map((option) => option.optionId)
|
|
147927
|
+
);
|
|
147928
|
+
if (new Set(optionIds).size !== optionIds.length) {
|
|
147929
|
+
ctx.addIssue({
|
|
147930
|
+
code: "custom",
|
|
147931
|
+
message: "optionId values must be unique within a prompt",
|
|
147932
|
+
path: ["questions"]
|
|
147933
|
+
});
|
|
147934
|
+
}
|
|
147935
|
+
const terminal = TERMINAL_PROMPT_STATES.has(prompt.state);
|
|
147936
|
+
if (terminal !== (prompt.terminalReason !== void 0)) {
|
|
147937
|
+
ctx.addIssue({
|
|
147938
|
+
code: "custom",
|
|
147939
|
+
message: terminal ? "terminal prompts require terminalReason" : "actionable prompts cannot carry terminalReason",
|
|
147940
|
+
path: ["terminalReason"]
|
|
147941
|
+
});
|
|
147942
|
+
}
|
|
147943
|
+
});
|
|
147944
|
+
var OptionResponseSchema = external_exports.object({
|
|
147945
|
+
questionId: OpaqueIdSchema,
|
|
147946
|
+
optionIds: external_exports.array(OpaqueIdSchema).min(1).refine((ids) => new Set(ids).size === ids.length, "optionIds must be unique"),
|
|
147947
|
+
text: external_exports.never().optional()
|
|
147948
|
+
});
|
|
147949
|
+
var TextResponseSchema = external_exports.object({
|
|
147950
|
+
questionId: OpaqueIdSchema,
|
|
147951
|
+
text: external_exports.string(),
|
|
147952
|
+
optionIds: external_exports.never().optional()
|
|
147953
|
+
});
|
|
147954
|
+
var PromptResponseSchema = external_exports.union([OptionResponseSchema, TextResponseSchema]);
|
|
147955
|
+
var PromptAnswerSchema = external_exports.object({
|
|
147956
|
+
promptId: OpaqueIdSchema,
|
|
147957
|
+
revision: external_exports.number().int().positive(),
|
|
147958
|
+
responses: external_exports.array(PromptResponseSchema).min(1),
|
|
147959
|
+
idempotencyKey: OpaqueIdSchema
|
|
147960
|
+
}).superRefine((answer, ctx) => {
|
|
147961
|
+
const questionIds = answer.responses.map((response) => response.questionId);
|
|
147962
|
+
if (new Set(questionIds).size !== questionIds.length) {
|
|
147963
|
+
ctx.addIssue({
|
|
147964
|
+
code: "custom",
|
|
147965
|
+
message: "each questionId can be answered only once",
|
|
147966
|
+
path: ["responses"]
|
|
147967
|
+
});
|
|
147968
|
+
}
|
|
147969
|
+
});
|
|
147970
|
+
|
|
147971
|
+
// src/services/prompts/promptRegistry.ts
|
|
147972
|
+
var import_node_crypto5 = require("crypto");
|
|
147973
|
+
var PROMPT_TERMINAL_RETENTION_MS = 10 * 60 * 1e3;
|
|
147974
|
+
var PROMPT_MAX_RECORDS_PER_SESSION = 200;
|
|
147975
|
+
var MAX_TIMEOUT_MS = 2147483647;
|
|
147976
|
+
function copyPrompt(prompt) {
|
|
147977
|
+
return {
|
|
147978
|
+
...prompt,
|
|
147979
|
+
questions: prompt.questions.map((question) => ({
|
|
147980
|
+
...question,
|
|
147981
|
+
options: question.options.map((option) => ({ ...option }))
|
|
147982
|
+
})),
|
|
147983
|
+
provenance: { ...prompt.provenance }
|
|
147984
|
+
};
|
|
147985
|
+
}
|
|
147986
|
+
function terminalError(state) {
|
|
147987
|
+
switch (state) {
|
|
147988
|
+
case "resolved":
|
|
147989
|
+
return "already_resolved";
|
|
147990
|
+
case "expired":
|
|
147991
|
+
return "prompt_expired";
|
|
147992
|
+
case "cancelled":
|
|
147993
|
+
return "prompt_cancelled";
|
|
147994
|
+
case "unavailable":
|
|
147995
|
+
return "prompt_unavailable";
|
|
147996
|
+
}
|
|
147997
|
+
}
|
|
147998
|
+
var PromptRegistry = class {
|
|
147999
|
+
bySession = /* @__PURE__ */ new Map();
|
|
148000
|
+
byId = /* @__PURE__ */ new Map();
|
|
148001
|
+
sequences = /* @__PURE__ */ new Map();
|
|
148002
|
+
createId;
|
|
148003
|
+
emit;
|
|
148004
|
+
onExpire;
|
|
148005
|
+
now;
|
|
148006
|
+
terminalRetentionMs;
|
|
148007
|
+
maxRecordsPerSession;
|
|
148008
|
+
constructor(options = {}) {
|
|
148009
|
+
this.createId = options.createId ?? import_node_crypto5.randomUUID;
|
|
148010
|
+
this.emit = options.emit;
|
|
148011
|
+
this.onExpire = options.onExpire;
|
|
148012
|
+
this.now = options.now ?? Date.now;
|
|
148013
|
+
this.terminalRetentionMs = options.terminalRetentionMs ?? PROMPT_TERMINAL_RETENTION_MS;
|
|
148014
|
+
this.maxRecordsPerSession = options.maxRecordsPerSession ?? PROMPT_MAX_RECORDS_PER_SESSION;
|
|
148015
|
+
}
|
|
148016
|
+
open(draft, adapter, promptId = this.createId()) {
|
|
148017
|
+
this.sweepExpired(draft.sessionId);
|
|
148018
|
+
const held = this.byId.get(promptId);
|
|
148019
|
+
if (held && (held.prompt.state === "open" || held.prompt.state === "updated")) {
|
|
148020
|
+
throw new Error(`Prompt id already exists: ${promptId}`);
|
|
148021
|
+
}
|
|
148022
|
+
const id = held ? this.createId() : promptId;
|
|
148023
|
+
const prompt = PromptSchema.parse({
|
|
148024
|
+
...draft,
|
|
148025
|
+
schemaVersion: PROMPT_SCHEMA_VERSION,
|
|
148026
|
+
promptId: id,
|
|
148027
|
+
revision: 1,
|
|
148028
|
+
state: "open",
|
|
148029
|
+
questions: draft.questions.map((question) => ({
|
|
148030
|
+
...question,
|
|
148031
|
+
questionId: this.createId(),
|
|
148032
|
+
options: question.options.map((option) => ({ ...option, optionId: this.createId() }))
|
|
148033
|
+
})),
|
|
148034
|
+
provenance: { ...draft.provenance }
|
|
148035
|
+
});
|
|
148036
|
+
const entry = {
|
|
148037
|
+
prompt,
|
|
148038
|
+
adapter,
|
|
148039
|
+
queue: Promise.resolve(),
|
|
148040
|
+
inFlight: /* @__PURE__ */ new Map(),
|
|
148041
|
+
outcomes: /* @__PURE__ */ new Map()
|
|
148042
|
+
};
|
|
148043
|
+
const session = this.bySession.get(prompt.sessionId) ?? /* @__PURE__ */ new Map();
|
|
148044
|
+
session.set(prompt.promptId, entry);
|
|
148045
|
+
this.bySession.set(prompt.sessionId, session);
|
|
148046
|
+
this.byId.set(prompt.promptId, entry);
|
|
148047
|
+
this.publish(entry);
|
|
148048
|
+
this.scheduleExpiration(entry);
|
|
148049
|
+
this.enforceCap(prompt.sessionId);
|
|
148050
|
+
return copyPrompt(prompt);
|
|
148051
|
+
}
|
|
148052
|
+
update(promptId, draft, adapter) {
|
|
148053
|
+
const entry = this.requireEntry(promptId);
|
|
148054
|
+
this.expireIfDue(entry, this.now());
|
|
148055
|
+
if (entry.prompt.sessionId !== draft.sessionId) throw new Error("Prompt session cannot change");
|
|
148056
|
+
if (entry.prompt.state !== "open" && entry.prompt.state !== "updated") {
|
|
148057
|
+
throw new Error(`Cannot update terminal prompt ${promptId}`);
|
|
148058
|
+
}
|
|
148059
|
+
if (entry.prompt.questions.length !== draft.questions.length) {
|
|
148060
|
+
throw new Error("Prompt question cardinality cannot change during an update");
|
|
148061
|
+
}
|
|
148062
|
+
const questions = draft.questions.map((question, questionIndex) => {
|
|
148063
|
+
const prior = entry.prompt.questions[questionIndex];
|
|
148064
|
+
if (prior.options.length !== question.options.length) {
|
|
148065
|
+
throw new Error("Prompt option cardinality cannot change during an update");
|
|
148066
|
+
}
|
|
148067
|
+
return {
|
|
148068
|
+
...question,
|
|
148069
|
+
questionId: prior.questionId,
|
|
148070
|
+
options: question.options.map((option, optionIndex) => ({
|
|
148071
|
+
...option,
|
|
148072
|
+
optionId: prior.options[optionIndex].optionId
|
|
148073
|
+
}))
|
|
148074
|
+
};
|
|
148075
|
+
});
|
|
148076
|
+
const prompt = PromptSchema.parse({
|
|
148077
|
+
...draft,
|
|
148078
|
+
schemaVersion: PROMPT_SCHEMA_VERSION,
|
|
148079
|
+
promptId,
|
|
148080
|
+
revision: entry.prompt.revision + 1,
|
|
148081
|
+
state: "updated",
|
|
148082
|
+
questions,
|
|
148083
|
+
provenance: { ...draft.provenance }
|
|
148084
|
+
});
|
|
148085
|
+
entry.prompt = prompt;
|
|
148086
|
+
if (adapter) entry.adapter = adapter;
|
|
148087
|
+
this.publish(entry);
|
|
148088
|
+
this.scheduleExpiration(entry);
|
|
148089
|
+
return copyPrompt(entry.prompt);
|
|
148090
|
+
}
|
|
148091
|
+
transition(promptId, state, reason) {
|
|
148092
|
+
const entry = this.requireEntry(promptId);
|
|
148093
|
+
if (entry.prompt.state !== "open" && entry.prompt.state !== "updated") {
|
|
148094
|
+
throw new Error(`Cannot transition terminal prompt ${promptId}`);
|
|
148095
|
+
}
|
|
148096
|
+
entry.prompt = {
|
|
148097
|
+
...entry.prompt,
|
|
148098
|
+
revision: entry.prompt.revision + 1,
|
|
148099
|
+
state,
|
|
148100
|
+
terminalReason: reason
|
|
148101
|
+
};
|
|
148102
|
+
entry.terminalAt = this.now();
|
|
148103
|
+
this.clearExpiration(entry);
|
|
148104
|
+
this.publish(entry);
|
|
148105
|
+
return copyPrompt(entry.prompt);
|
|
148106
|
+
}
|
|
148107
|
+
invalidateSession(sessionId, reason = "session_ended") {
|
|
148108
|
+
const transitioned = [];
|
|
148109
|
+
for (const entry of this.bySession.get(sessionId)?.values() ?? []) {
|
|
148110
|
+
if (entry.prompt.state === "open" || entry.prompt.state === "updated") {
|
|
148111
|
+
transitioned.push(this.transition(entry.prompt.promptId, "unavailable", reason));
|
|
148112
|
+
}
|
|
148113
|
+
}
|
|
148114
|
+
return transitioned;
|
|
148115
|
+
}
|
|
148116
|
+
get(promptId) {
|
|
148117
|
+
const entry = this.byId.get(promptId);
|
|
148118
|
+
if (!entry) return null;
|
|
148119
|
+
this.sweepExpired(entry.prompt.sessionId);
|
|
148120
|
+
return this.byId.has(promptId) ? copyPrompt(entry.prompt) : null;
|
|
148121
|
+
}
|
|
148122
|
+
hasActionable(sessionId) {
|
|
148123
|
+
this.sweepExpired(sessionId);
|
|
148124
|
+
return [...this.bySession.get(sessionId)?.values() ?? []].some(
|
|
148125
|
+
(entry) => entry.prompt.state === "open" || entry.prompt.state === "updated"
|
|
148126
|
+
);
|
|
148127
|
+
}
|
|
148128
|
+
snapshot(sessionId) {
|
|
148129
|
+
this.sweepExpired(sessionId);
|
|
148130
|
+
return {
|
|
148131
|
+
type: "prompt_snapshot",
|
|
148132
|
+
schemaVersion: PROMPT_SCHEMA_VERSION,
|
|
148133
|
+
sessionId,
|
|
148134
|
+
sequence: this.sequences.get(sessionId) ?? 0,
|
|
148135
|
+
prompts: [...this.bySession.get(sessionId)?.values() ?? []].map(
|
|
148136
|
+
(entry) => copyPrompt(entry.prompt)
|
|
148137
|
+
)
|
|
148138
|
+
};
|
|
148139
|
+
}
|
|
148140
|
+
dispose() {
|
|
148141
|
+
for (const entry of this.byId.values()) this.clearExpiration(entry);
|
|
148142
|
+
}
|
|
148143
|
+
answer(sessionId, answer) {
|
|
148144
|
+
this.sweepExpired(sessionId);
|
|
148145
|
+
const entry = this.byId.get(answer.promptId);
|
|
148146
|
+
if (!entry || entry.prompt.sessionId !== sessionId) {
|
|
148147
|
+
return Promise.resolve({ ok: false, code: "prompt_not_found" });
|
|
148148
|
+
}
|
|
148149
|
+
this.pruneOutcomes(entry);
|
|
148150
|
+
const recorded = entry.outcomes.get(answer.idempotencyKey);
|
|
148151
|
+
if (recorded) return Promise.resolve(recorded.outcome);
|
|
148152
|
+
const pending = entry.inFlight.get(answer.idempotencyKey);
|
|
148153
|
+
if (pending) return pending;
|
|
148154
|
+
const task = entry.queue.then(() => this.performAnswer(entry, answer));
|
|
148155
|
+
entry.queue = task.then(
|
|
148156
|
+
() => void 0,
|
|
148157
|
+
() => void 0
|
|
148158
|
+
);
|
|
148159
|
+
entry.inFlight.set(answer.idempotencyKey, task);
|
|
148160
|
+
void task.then((outcome) => {
|
|
148161
|
+
entry.inFlight.delete(answer.idempotencyKey);
|
|
148162
|
+
entry.outcomes.set(answer.idempotencyKey, { at: this.now(), outcome });
|
|
148163
|
+
});
|
|
148164
|
+
return task;
|
|
148165
|
+
}
|
|
148166
|
+
async performAnswer(entry, answer) {
|
|
148167
|
+
const prompt = entry.prompt;
|
|
148168
|
+
if (prompt.state !== "open" && prompt.state !== "updated") {
|
|
148169
|
+
return { ok: false, code: terminalError(prompt.state) };
|
|
148170
|
+
}
|
|
148171
|
+
if (this.expireIfDue(entry, this.now())) {
|
|
148172
|
+
return { ok: false, code: "prompt_expired" };
|
|
148173
|
+
}
|
|
148174
|
+
if (prompt.revision !== answer.revision) {
|
|
148175
|
+
return {
|
|
148176
|
+
ok: false,
|
|
148177
|
+
code: "prompt_revision_mismatch",
|
|
148178
|
+
currentRevision: prompt.revision
|
|
148179
|
+
};
|
|
148180
|
+
}
|
|
148181
|
+
const responseError = this.validateResponses(prompt, answer);
|
|
148182
|
+
if (responseError) return { ok: false, code: responseError };
|
|
148183
|
+
if (!entry.adapter) return { ok: false, code: "prompt_unavailable" };
|
|
148184
|
+
let adapterResult;
|
|
148185
|
+
try {
|
|
148186
|
+
adapterResult = await entry.adapter({ prompt: copyPrompt(prompt), answer });
|
|
148187
|
+
} catch {
|
|
148188
|
+
return { ok: false, code: "provider_error" };
|
|
148189
|
+
}
|
|
148190
|
+
if (entry.prompt.state !== "open" && entry.prompt.state !== "updated") {
|
|
148191
|
+
return { ok: false, code: terminalError(entry.prompt.state) };
|
|
148192
|
+
}
|
|
148193
|
+
if (entry.prompt.revision !== answer.revision) {
|
|
148194
|
+
return {
|
|
148195
|
+
ok: false,
|
|
148196
|
+
code: "prompt_revision_mismatch",
|
|
148197
|
+
currentRevision: entry.prompt.revision
|
|
148198
|
+
};
|
|
148199
|
+
}
|
|
148200
|
+
if (!adapterResult.ok) {
|
|
148201
|
+
if (adapterResult.terminal) {
|
|
148202
|
+
this.transition(
|
|
148203
|
+
prompt.promptId,
|
|
148204
|
+
adapterResult.terminal.state,
|
|
148205
|
+
adapterResult.terminal.reason
|
|
148206
|
+
);
|
|
148207
|
+
}
|
|
148208
|
+
return { ok: false, code: adapterResult.code };
|
|
148209
|
+
}
|
|
148210
|
+
return { ok: true, prompt: this.transition(prompt.promptId, "resolved", "answered") };
|
|
148211
|
+
}
|
|
148212
|
+
validateResponses(prompt, answer) {
|
|
148213
|
+
const questions = new Map(prompt.questions.map((question) => [question.questionId, question]));
|
|
148214
|
+
for (const response of answer.responses) {
|
|
148215
|
+
if (!questions.has(response.questionId)) return "unknown_question";
|
|
148216
|
+
}
|
|
148217
|
+
if (answer.responses.length !== prompt.questions.length) return "incomplete_answer";
|
|
148218
|
+
const responses = new Map(answer.responses.map((response) => [response.questionId, response]));
|
|
148219
|
+
for (const question of prompt.questions) {
|
|
148220
|
+
const response = responses.get(question.questionId);
|
|
148221
|
+
if (!response) return "incomplete_answer";
|
|
148222
|
+
if (question.inputMode === "text") {
|
|
148223
|
+
if (typeof response.text !== "string") return "incomplete_answer";
|
|
148224
|
+
continue;
|
|
148225
|
+
}
|
|
148226
|
+
const optionIds = response.optionIds;
|
|
148227
|
+
if (!optionIds) return "incomplete_answer";
|
|
148228
|
+
if (question.inputMode === "single" && optionIds.length !== 1) {
|
|
148229
|
+
return "unsupported_prompt_shape";
|
|
148230
|
+
}
|
|
148231
|
+
const known = new Set(question.options.map((option) => option.optionId));
|
|
148232
|
+
if (optionIds.some((optionId) => !known.has(optionId))) return "unknown_option";
|
|
148233
|
+
}
|
|
148234
|
+
return null;
|
|
148235
|
+
}
|
|
148236
|
+
publish(entry) {
|
|
148237
|
+
const sessionId = entry.prompt.sessionId;
|
|
148238
|
+
const sequence = (this.sequences.get(sessionId) ?? 0) + 1;
|
|
148239
|
+
this.sequences.set(sessionId, sequence);
|
|
148240
|
+
this.emit?.({
|
|
148241
|
+
type: "prompt_event",
|
|
148242
|
+
sessionId,
|
|
148243
|
+
sequence,
|
|
148244
|
+
prompt: copyPrompt(entry.prompt)
|
|
148245
|
+
});
|
|
148246
|
+
}
|
|
148247
|
+
scheduleExpiration(entry) {
|
|
148248
|
+
this.clearExpiration(entry);
|
|
148249
|
+
const expiresAt = entry.prompt.expiresAt;
|
|
148250
|
+
if (expiresAt === null) return;
|
|
148251
|
+
const delay = Math.min(MAX_TIMEOUT_MS, Math.max(0, Date.parse(expiresAt) - this.now()));
|
|
148252
|
+
entry.expiryTimer = setTimeout(() => {
|
|
148253
|
+
entry.expiryTimer = void 0;
|
|
148254
|
+
if (!this.expireIfDue(entry, this.now())) this.scheduleExpiration(entry);
|
|
148255
|
+
}, delay);
|
|
148256
|
+
entry.expiryTimer.unref?.();
|
|
148257
|
+
}
|
|
148258
|
+
clearExpiration(entry) {
|
|
148259
|
+
if (entry.expiryTimer) clearTimeout(entry.expiryTimer);
|
|
148260
|
+
entry.expiryTimer = void 0;
|
|
148261
|
+
}
|
|
148262
|
+
expireIfDue(entry, now) {
|
|
148263
|
+
if (entry.prompt.state !== "open" && entry.prompt.state !== "updated") return false;
|
|
148264
|
+
if (entry.prompt.expiresAt === null || now < Date.parse(entry.prompt.expiresAt)) return false;
|
|
148265
|
+
const expired = this.transition(entry.prompt.promptId, "expired", "deadline_elapsed");
|
|
148266
|
+
this.onExpire?.(expired);
|
|
148267
|
+
return true;
|
|
148268
|
+
}
|
|
148269
|
+
requireEntry(promptId) {
|
|
148270
|
+
const entry = this.byId.get(promptId);
|
|
148271
|
+
if (!entry) throw new Error(`Unknown prompt: ${promptId}`);
|
|
148272
|
+
return entry;
|
|
148273
|
+
}
|
|
148274
|
+
sweepExpired(sessionId) {
|
|
148275
|
+
const now = this.now();
|
|
148276
|
+
const session = this.bySession.get(sessionId);
|
|
148277
|
+
if (!session) return;
|
|
148278
|
+
for (const [promptId, entry] of session) {
|
|
148279
|
+
this.expireIfDue(entry, now);
|
|
148280
|
+
if (entry.terminalAt !== void 0 && now - entry.terminalAt > this.terminalRetentionMs) {
|
|
148281
|
+
this.clearExpiration(entry);
|
|
148282
|
+
session.delete(promptId);
|
|
148283
|
+
this.byId.delete(promptId);
|
|
148284
|
+
}
|
|
148285
|
+
}
|
|
148286
|
+
if (session.size === 0) this.bySession.delete(sessionId);
|
|
148287
|
+
}
|
|
148288
|
+
enforceCap(sessionId) {
|
|
148289
|
+
const session = this.bySession.get(sessionId);
|
|
148290
|
+
if (!session || session.size <= this.maxRecordsPerSession) return;
|
|
148291
|
+
const terminal = [...session.entries()].filter(([, entry]) => entry.terminalAt !== void 0).sort((a, b2) => (a[1].terminalAt ?? 0) - (b2[1].terminalAt ?? 0));
|
|
148292
|
+
while (session.size > this.maxRecordsPerSession && terminal.length > 0) {
|
|
148293
|
+
const [promptId, entry] = terminal.shift();
|
|
148294
|
+
this.clearExpiration(entry);
|
|
148295
|
+
session.delete(promptId);
|
|
148296
|
+
this.byId.delete(promptId);
|
|
148297
|
+
}
|
|
148298
|
+
}
|
|
148299
|
+
pruneOutcomes(entry) {
|
|
148300
|
+
const now = this.now();
|
|
148301
|
+
for (const [key, recorded] of entry.outcomes) {
|
|
148302
|
+
if (now - recorded.at > this.terminalRetentionMs) entry.outcomes.delete(key);
|
|
148303
|
+
}
|
|
148304
|
+
}
|
|
148305
|
+
};
|
|
148306
|
+
|
|
148307
|
+
// src/services/prompts/ptyPromptAdapter.ts
|
|
148308
|
+
function permissionPromptDraft(sessionId, gate) {
|
|
148309
|
+
if (!gate) throw new Error("Cannot normalize an absent permission gate");
|
|
148310
|
+
const message = gate.prompt?.trim() || "Approval required";
|
|
148311
|
+
return {
|
|
148312
|
+
sessionId,
|
|
148313
|
+
intent: "approval",
|
|
148314
|
+
title: "Approval",
|
|
148315
|
+
message,
|
|
148316
|
+
...gate.detail?.trim() ? { detail: gate.detail } : {},
|
|
148317
|
+
questions: [
|
|
148318
|
+
{
|
|
148319
|
+
text: message,
|
|
148320
|
+
header: "Approval",
|
|
148321
|
+
inputMode: "single",
|
|
148322
|
+
options: gate.options.map((option) => ({ label: option.label })),
|
|
148323
|
+
allowOther: false,
|
|
148324
|
+
secret: "unknown"
|
|
148325
|
+
}
|
|
148326
|
+
],
|
|
148327
|
+
answerRequirement: "unknown",
|
|
148328
|
+
expiresAt: null,
|
|
148329
|
+
provenance: { source: "screen", confidence: "inferred" }
|
|
148330
|
+
};
|
|
148331
|
+
}
|
|
148332
|
+
function questionPromptDraft(sessionId, questions, source) {
|
|
148333
|
+
const first = questions[0];
|
|
148334
|
+
if (!first) throw new Error("Cannot normalize an empty question list");
|
|
148335
|
+
return {
|
|
148336
|
+
sessionId,
|
|
148337
|
+
intent: "question",
|
|
148338
|
+
...first.header.trim() ? { title: first.header } : {},
|
|
148339
|
+
message: first.question,
|
|
148340
|
+
questions: questions.map((question) => ({
|
|
148341
|
+
text: question.question,
|
|
148342
|
+
...question.header.trim() ? { header: question.header } : {},
|
|
148343
|
+
inputMode: question.multiSelect ? "multi" : "single",
|
|
148344
|
+
options: question.options.map((option) => ({
|
|
148345
|
+
label: option.label,
|
|
148346
|
+
...option.description ? { description: option.description } : {},
|
|
148347
|
+
...option.preview ? { preview: option.preview } : {}
|
|
148348
|
+
})),
|
|
148349
|
+
allowOther: false,
|
|
148350
|
+
secret: "unknown"
|
|
148351
|
+
})),
|
|
148352
|
+
answerRequirement: "unknown",
|
|
148353
|
+
expiresAt: null,
|
|
148354
|
+
provenance: {
|
|
148355
|
+
source,
|
|
148356
|
+
confidence: source === "transcript" ? "authoritative" : "inferred"
|
|
148357
|
+
}
|
|
148358
|
+
};
|
|
148359
|
+
}
|
|
148360
|
+
|
|
148361
|
+
// src/api/handlers/sessions.handlers.ts
|
|
147675
148362
|
init_codexScreen();
|
|
147676
148363
|
init_detectPermissionGate();
|
|
147677
148364
|
init_detectQuestionFromScreen();
|
|
@@ -148041,6 +148728,21 @@ function codexSessionActiveBody(outcome) {
|
|
|
148041
148728
|
...outcome.ownerSource != null && { ownerSource: outcome.ownerSource }
|
|
148042
148729
|
};
|
|
148043
148730
|
}
|
|
148731
|
+
function promptAnswerStatus(code) {
|
|
148732
|
+
switch (code) {
|
|
148733
|
+
case "prompt_not_found":
|
|
148734
|
+
return 404;
|
|
148735
|
+
case "provider_error":
|
|
148736
|
+
return 502;
|
|
148737
|
+
case "unknown_question":
|
|
148738
|
+
case "unknown_option":
|
|
148739
|
+
case "incomplete_answer":
|
|
148740
|
+
case "unsupported_prompt_shape":
|
|
148741
|
+
return 400;
|
|
148742
|
+
default:
|
|
148743
|
+
return 409;
|
|
148744
|
+
}
|
|
148745
|
+
}
|
|
148044
148746
|
var SessionHandlers = class {
|
|
148045
148747
|
constructor(deps) {
|
|
148046
148748
|
this.deps = deps;
|
|
@@ -148079,6 +148781,10 @@ var SessionHandlers = class {
|
|
|
148079
148781
|
get pendingQuestions() {
|
|
148080
148782
|
return this.deps.pendingQuestions;
|
|
148081
148783
|
}
|
|
148784
|
+
get promptRegistry() {
|
|
148785
|
+
if (!this.deps.promptRegistry) this.deps.promptRegistry = new PromptRegistry();
|
|
148786
|
+
return this.deps.promptRegistry;
|
|
148787
|
+
}
|
|
148082
148788
|
get pendingQuestionKey() {
|
|
148083
148789
|
return this.deps.pendingQuestionKey;
|
|
148084
148790
|
}
|
|
@@ -148597,18 +149303,26 @@ var SessionHandlers = class {
|
|
|
148597
149303
|
json2(res, 400, { error: "Missing input field" });
|
|
148598
149304
|
return;
|
|
148599
149305
|
}
|
|
149306
|
+
this.promptRegistry.sweepExpired(sessionId);
|
|
148600
149307
|
const openPrompt = this.pendingPermission.has(sessionId) ? "permission" : this.pendingQuestions.has(sessionId) ? "question" : null;
|
|
148601
149308
|
if (openPrompt) {
|
|
148602
|
-
this.
|
|
148603
|
-
|
|
148604
|
-
|
|
148605
|
-
|
|
148606
|
-
|
|
149309
|
+
const pendingGate = openPrompt === "permission" ? this.pendingPermission.get(sessionId) : void 0;
|
|
149310
|
+
const promptState = pendingGate?.promptId !== void 0 && this.promptRegistry.get(pendingGate.promptId)?.state === "resolved" ? "answered" : "open";
|
|
149311
|
+
this.log.info(
|
|
149312
|
+
`[input.prompt_pending] ${sessionId.slice(0, 8)} kind=${openPrompt} state=${promptState}`,
|
|
149313
|
+
{
|
|
149314
|
+
event: "input.prompt_pending",
|
|
149315
|
+
sessionId,
|
|
149316
|
+
promptKind: openPrompt,
|
|
149317
|
+
promptState
|
|
149318
|
+
}
|
|
149319
|
+
);
|
|
148607
149320
|
json2(res, 409, {
|
|
148608
149321
|
ok: false,
|
|
148609
149322
|
reason: "prompt_pending",
|
|
148610
149323
|
promptKind: openPrompt,
|
|
148611
|
-
|
|
149324
|
+
promptState,
|
|
149325
|
+
error: promptState === "answered" ? "Your answer was sent; wait for the prompt to close before sending text" : "A prompt is waiting for an answer; answer or dismiss it before sending text"
|
|
148612
149326
|
});
|
|
148613
149327
|
return;
|
|
148614
149328
|
}
|
|
@@ -148652,30 +149366,99 @@ var SessionHandlers = class {
|
|
|
148652
149366
|
// the later JSONL flush of the same question is de-duped. We synthesize a
|
|
148653
149367
|
// screen-scoped toolUseId; the JSONL path overwrites pendingQuestions with the
|
|
148654
149368
|
// real toolUseId when it lands, so answering works once JSONL catches up.
|
|
148655
|
-
handleLiveQuestion(sessionId, questions) {
|
|
149369
|
+
handleLiveQuestion(sessionId, questions, occurrenceId) {
|
|
148656
149370
|
const key = questionContentKey(questions);
|
|
148657
149371
|
if (this.pendingQuestionKey.get(sessionId) === key) return;
|
|
148658
149372
|
const toolUseId = `screen:${sessionId}:${key.length}`;
|
|
148659
|
-
this.pendingQuestions.
|
|
149373
|
+
const prior = this.pendingQuestions.get(sessionId);
|
|
149374
|
+
const priorPrompt = prior ? this.promptRegistry.get(prior.promptId) : null;
|
|
149375
|
+
if (priorPrompt?.state === "open" || priorPrompt?.state === "updated") {
|
|
149376
|
+
this.promptRegistry.transition(priorPrompt.promptId, "cancelled", "replaced");
|
|
149377
|
+
}
|
|
149378
|
+
const prompt = this.promptRegistry.open(
|
|
149379
|
+
questionPromptDraft(sessionId, questions, "screen"),
|
|
149380
|
+
this.questionAnswerAdapter(sessionId),
|
|
149381
|
+
occurrenceId
|
|
149382
|
+
);
|
|
149383
|
+
this.pendingQuestions.set(sessionId, {
|
|
149384
|
+
toolUseId,
|
|
149385
|
+
questions,
|
|
149386
|
+
origin: "pty",
|
|
149387
|
+
promptId: prompt.promptId
|
|
149388
|
+
});
|
|
148660
149389
|
this.pendingQuestionKey.set(sessionId, key);
|
|
148661
149390
|
this.broadcastToSession(sessionId, { type: "question", sessionId, toolUseId, questions });
|
|
148662
149391
|
}
|
|
149392
|
+
handleJsonlQuestion(sessionId, toolUseId, questions, origin) {
|
|
149393
|
+
const prior = this.pendingQuestions.get(sessionId);
|
|
149394
|
+
const sameQuestion = prior !== void 0 && questionContentKey(prior.questions) === questionContentKey(questions);
|
|
149395
|
+
let prompt;
|
|
149396
|
+
if (sameQuestion) {
|
|
149397
|
+
const current = this.promptRegistry.get(prior.promptId);
|
|
149398
|
+
prompt = current?.provenance.source === "transcript" ? current : this.promptRegistry.update(
|
|
149399
|
+
prior.promptId,
|
|
149400
|
+
questionPromptDraft(sessionId, questions, "transcript"),
|
|
149401
|
+
this.questionAnswerAdapter(sessionId)
|
|
149402
|
+
);
|
|
149403
|
+
} else {
|
|
149404
|
+
const priorPrompt = prior ? this.promptRegistry.get(prior.promptId) : null;
|
|
149405
|
+
if (priorPrompt?.state === "open" || priorPrompt?.state === "updated") {
|
|
149406
|
+
this.promptRegistry.transition(priorPrompt.promptId, "cancelled", "replaced");
|
|
149407
|
+
}
|
|
149408
|
+
prompt = this.promptRegistry.open(
|
|
149409
|
+
questionPromptDraft(sessionId, questions, "transcript"),
|
|
149410
|
+
this.questionAnswerAdapter(sessionId)
|
|
149411
|
+
);
|
|
149412
|
+
}
|
|
149413
|
+
this.pendingQuestions.set(sessionId, {
|
|
149414
|
+
toolUseId,
|
|
149415
|
+
questions,
|
|
149416
|
+
origin,
|
|
149417
|
+
promptId: prompt.promptId
|
|
149418
|
+
});
|
|
149419
|
+
}
|
|
148663
149420
|
// Permission gate opened/closed (OSC 777 + scraped options). Broadcasts the
|
|
148664
149421
|
// additive `permission` / `permission_cancelled` events. Mobile answers by
|
|
148665
149422
|
// sending the chosen option index via /input { keys } (e.g. "2\r").
|
|
148666
|
-
handlePermissionChange(sessionId, gate) {
|
|
149423
|
+
handlePermissionChange(sessionId, gate, occurrenceId) {
|
|
148667
149424
|
if (gate === null) {
|
|
148668
|
-
|
|
149425
|
+
const prior2 = this.pendingPermission.get(sessionId);
|
|
149426
|
+
if (!prior2) return;
|
|
149427
|
+
const prompt2 = prior2.promptId ? this.promptRegistry.get(prior2.promptId) : null;
|
|
149428
|
+
if (prompt2?.state === "open" || prompt2?.state === "updated") {
|
|
149429
|
+
this.promptRegistry.transition(prompt2.promptId, "cancelled", "provider_closed");
|
|
149430
|
+
}
|
|
148669
149431
|
this.pendingPermission.delete(sessionId);
|
|
148670
149432
|
this.pendingPermissionKey.delete(sessionId);
|
|
148671
149433
|
this.broadcastToSession(sessionId, { type: "permission_cancelled", sessionId });
|
|
148672
149434
|
return;
|
|
148673
149435
|
}
|
|
148674
149436
|
const key = permissionContentKey(gate);
|
|
148675
|
-
if (this.pendingPermissionKey.get(sessionId) === key) return;
|
|
148676
149437
|
const prior = this.pendingPermission.get(sessionId);
|
|
148677
|
-
const
|
|
148678
|
-
this.
|
|
149438
|
+
const priorPromptId = prior?.promptId;
|
|
149439
|
+
if (this.pendingPermissionKey.get(sessionId) === key && (occurrenceId === void 0 || prior?.occurrenceId === occurrenceId)) {
|
|
149440
|
+
return;
|
|
149441
|
+
}
|
|
149442
|
+
const samePrompt = prior && priorPromptId !== void 0 && permissionGateKey(prior) === permissionGateKey(gate) && (occurrenceId === void 0 || prior.occurrenceId === occurrenceId);
|
|
149443
|
+
if (prior && !samePrompt) {
|
|
149444
|
+
const priorPrompt = prior.promptId ? this.promptRegistry.get(prior.promptId) : null;
|
|
149445
|
+
if (priorPrompt?.state === "open" || priorPrompt?.state === "updated") {
|
|
149446
|
+
this.promptRegistry.transition(priorPrompt.promptId, "cancelled", "replaced");
|
|
149447
|
+
}
|
|
149448
|
+
}
|
|
149449
|
+
const prompt = gate.options.length === 0 ? null : samePrompt ? this.promptRegistry.get(priorPromptId) : this.promptRegistry.open(
|
|
149450
|
+
permissionPromptDraft(sessionId, gate),
|
|
149451
|
+
this.permissionAnswerAdapter(sessionId),
|
|
149452
|
+
occurrenceId
|
|
149453
|
+
);
|
|
149454
|
+
if (samePrompt && !prompt) throw new Error("Pending permission prompt disappeared");
|
|
149455
|
+
const gateId = prompt?.promptId ?? occurrenceId ?? prior?.gateId ?? (0, import_crypto9.randomUUID)();
|
|
149456
|
+
this.pendingPermission.set(sessionId, {
|
|
149457
|
+
...gate,
|
|
149458
|
+
gateId,
|
|
149459
|
+
...prompt ? { promptId: prompt.promptId } : {},
|
|
149460
|
+
...occurrenceId !== void 0 ? { occurrenceId } : {}
|
|
149461
|
+
});
|
|
148679
149462
|
this.pendingPermissionKey.set(sessionId, key);
|
|
148680
149463
|
const subscriberCount = this.sessionSubscribers.get(sessionId)?.size ?? 0;
|
|
148681
149464
|
this.log.info(
|
|
@@ -148693,6 +149476,107 @@ var SessionHandlers = class {
|
|
|
148693
149476
|
gateId
|
|
148694
149477
|
});
|
|
148695
149478
|
}
|
|
149479
|
+
permissionAnswerAdapter(sessionId) {
|
|
149480
|
+
return async ({ prompt, answer }) => {
|
|
149481
|
+
const gate = this.pendingPermission.get(sessionId);
|
|
149482
|
+
if (!gate || gate.promptId !== prompt.promptId) {
|
|
149483
|
+
return {
|
|
149484
|
+
ok: false,
|
|
149485
|
+
code: "prompt_unavailable",
|
|
149486
|
+
terminal: { state: "unavailable", reason: "provider_prompt_missing" }
|
|
149487
|
+
};
|
|
149488
|
+
}
|
|
149489
|
+
const response = answer.responses[0];
|
|
149490
|
+
const selectedId = response?.optionIds?.[0];
|
|
149491
|
+
const selectedIndex = prompt.questions[0]?.options.findIndex(
|
|
149492
|
+
(option2) => option2.optionId === selectedId
|
|
149493
|
+
);
|
|
149494
|
+
if (selectedIndex === void 0 || selectedIndex < 0) {
|
|
149495
|
+
return { ok: false, code: "unknown_option" };
|
|
149496
|
+
}
|
|
149497
|
+
const option = gate.options[selectedIndex];
|
|
149498
|
+
if (!option) return { ok: false, code: "unknown_option" };
|
|
149499
|
+
const provider = this.sessionStore.getManaged(sessionId)?.provider;
|
|
149500
|
+
if (provider !== CODEX_CLI_PROVIDER && !await this.permissionGateStillOpen(sessionId, permissionGateKey(gate))) {
|
|
149501
|
+
return {
|
|
149502
|
+
ok: false,
|
|
149503
|
+
code: "prompt_cancelled",
|
|
149504
|
+
terminal: { state: "cancelled", reason: "provider_closed" }
|
|
149505
|
+
};
|
|
149506
|
+
}
|
|
149507
|
+
if (this.pendingPermission.get(sessionId)?.promptId !== prompt.promptId) {
|
|
149508
|
+
return { ok: false, code: "prompt_cancelled" };
|
|
149509
|
+
}
|
|
149510
|
+
try {
|
|
149511
|
+
this.ptyManager.sendKeys(
|
|
149512
|
+
sessionId,
|
|
149513
|
+
option.answerKeys ?? permissionAnswerKeys(option.index)
|
|
149514
|
+
);
|
|
149515
|
+
} catch {
|
|
149516
|
+
return { ok: false, code: "provider_error" };
|
|
149517
|
+
}
|
|
149518
|
+
return { ok: true };
|
|
149519
|
+
};
|
|
149520
|
+
}
|
|
149521
|
+
questionAnswerAdapter(sessionId) {
|
|
149522
|
+
return async ({ prompt, answer }) => {
|
|
149523
|
+
const pending = this.pendingQuestions.get(sessionId);
|
|
149524
|
+
if (!pending || pending.promptId !== prompt.promptId) {
|
|
149525
|
+
return {
|
|
149526
|
+
ok: false,
|
|
149527
|
+
code: "prompt_unavailable",
|
|
149528
|
+
terminal: { state: "unavailable", reason: "provider_prompt_missing" }
|
|
149529
|
+
};
|
|
149530
|
+
}
|
|
149531
|
+
const answers = {};
|
|
149532
|
+
for (const question of prompt.questions) {
|
|
149533
|
+
const response = answer.responses.find((item) => item.questionId === question.questionId);
|
|
149534
|
+
if (!response?.optionIds) return { ok: false, code: "unsupported_prompt_shape" };
|
|
149535
|
+
answers[question.text] = response.optionIds.map((optionId) => {
|
|
149536
|
+
const option = question.options.find((item) => item.optionId === optionId);
|
|
149537
|
+
return option?.label ?? "";
|
|
149538
|
+
});
|
|
149539
|
+
}
|
|
149540
|
+
const resolution = resolveAnswer(pending, {
|
|
149541
|
+
toolUseId: pending.toolUseId,
|
|
149542
|
+
answers
|
|
149543
|
+
});
|
|
149544
|
+
if (!resolution.ok) {
|
|
149545
|
+
const code = resolution.reason === "unknown_option" || resolution.reason === "incomplete_answer" || resolution.reason === "unsupported_prompt_shape" ? resolution.reason : "prompt_unavailable";
|
|
149546
|
+
return { ok: false, code };
|
|
149547
|
+
}
|
|
149548
|
+
if (!await this.questionMenuStillOpen(sessionId)) {
|
|
149549
|
+
this.pendingQuestions.delete(sessionId);
|
|
149550
|
+
this.pendingQuestionKey.delete(sessionId);
|
|
149551
|
+
this.broadcastToSession(sessionId, {
|
|
149552
|
+
type: "question_cancelled",
|
|
149553
|
+
sessionId,
|
|
149554
|
+
toolUseId: pending.toolUseId
|
|
149555
|
+
});
|
|
149556
|
+
return {
|
|
149557
|
+
ok: false,
|
|
149558
|
+
code: "prompt_cancelled",
|
|
149559
|
+
terminal: { state: "cancelled", reason: "provider_closed" }
|
|
149560
|
+
};
|
|
149561
|
+
}
|
|
149562
|
+
if (this.pendingQuestions.get(sessionId)?.promptId !== prompt.promptId) {
|
|
149563
|
+
return { ok: false, code: "prompt_cancelled" };
|
|
149564
|
+
}
|
|
149565
|
+
try {
|
|
149566
|
+
this.ptyManager.sendKeys(sessionId, resolution.keys);
|
|
149567
|
+
} catch {
|
|
149568
|
+
return { ok: false, code: "provider_error" };
|
|
149569
|
+
}
|
|
149570
|
+
this.pendingQuestions.delete(sessionId);
|
|
149571
|
+
this.pendingQuestionKey.delete(sessionId);
|
|
149572
|
+
this.broadcastToSession(sessionId, {
|
|
149573
|
+
type: "question_cancelled",
|
|
149574
|
+
sessionId,
|
|
149575
|
+
toolUseId: pending.toolUseId
|
|
149576
|
+
});
|
|
149577
|
+
return { ok: true };
|
|
149578
|
+
};
|
|
149579
|
+
}
|
|
148696
149580
|
/**
|
|
148697
149581
|
* Answer a permission gate — the validated counterpart of POST /:id/input.
|
|
148698
149582
|
*
|
|
@@ -148728,6 +149612,11 @@ var SessionHandlers = class {
|
|
|
148728
149612
|
return;
|
|
148729
149613
|
}
|
|
148730
149614
|
const gateClosed = () => {
|
|
149615
|
+
const pending = this.pendingPermission.get(sessionId);
|
|
149616
|
+
const prompt = pending?.promptId ? this.promptRegistry.get(pending.promptId) : null;
|
|
149617
|
+
if (prompt?.state === "open" || prompt?.state === "updated") {
|
|
149618
|
+
this.promptRegistry.transition(prompt.promptId, "cancelled", "provider_closed");
|
|
149619
|
+
}
|
|
148731
149620
|
this.pendingPermission.delete(sessionId);
|
|
148732
149621
|
this.pendingPermissionKey.delete(sessionId);
|
|
148733
149622
|
this.broadcastToSession(sessionId, { type: "permission_cancelled", sessionId });
|
|
@@ -148769,6 +149658,10 @@ var SessionHandlers = class {
|
|
|
148769
149658
|
json2(res, 400, { ok: false, reason: message });
|
|
148770
149659
|
return;
|
|
148771
149660
|
}
|
|
149661
|
+
const normalized = gate.promptId ? this.promptRegistry.get(gate.promptId) : null;
|
|
149662
|
+
if (normalized?.state === "open" || normalized?.state === "updated") {
|
|
149663
|
+
this.promptRegistry.transition(normalized.promptId, "resolved", "answered_legacy");
|
|
149664
|
+
}
|
|
148772
149665
|
json2(res, 200, { ok: true });
|
|
148773
149666
|
}
|
|
148774
149667
|
/**
|
|
@@ -148814,6 +149707,10 @@ var SessionHandlers = class {
|
|
|
148814
149707
|
}
|
|
148815
149708
|
const toolUseId = pending?.toolUseId ?? "";
|
|
148816
149709
|
if (!await this.questionMenuStillOpen(sessionId)) {
|
|
149710
|
+
const prompt = this.promptRegistry.get(pending?.promptId ?? "");
|
|
149711
|
+
if (prompt?.state === "open" || prompt?.state === "updated") {
|
|
149712
|
+
this.promptRegistry.transition(prompt.promptId, "cancelled", "provider_closed");
|
|
149713
|
+
}
|
|
148817
149714
|
this.pendingQuestions.delete(sessionId);
|
|
148818
149715
|
this.pendingQuestionKey.delete(sessionId);
|
|
148819
149716
|
this.broadcastToSession(sessionId, { type: "question_cancelled", sessionId, toolUseId });
|
|
@@ -148827,10 +149724,41 @@ var SessionHandlers = class {
|
|
|
148827
149724
|
json2(res, 400, { ok: false, reason: message });
|
|
148828
149725
|
return;
|
|
148829
149726
|
}
|
|
149727
|
+
const normalized = this.promptRegistry.get(pending?.promptId ?? "");
|
|
149728
|
+
if (normalized?.state === "open" || normalized?.state === "updated") {
|
|
149729
|
+
this.promptRegistry.transition(normalized.promptId, "resolved", "answered_legacy");
|
|
149730
|
+
}
|
|
148830
149731
|
this.pendingQuestions.delete(sessionId);
|
|
148831
149732
|
this.broadcastToSession(sessionId, { type: "question_cancelled", sessionId, toolUseId });
|
|
148832
149733
|
json2(res, 200, { ok: true });
|
|
148833
149734
|
}
|
|
149735
|
+
/**
|
|
149736
|
+
* Answer a normalized prompt by its opaque ids.
|
|
149737
|
+
*
|
|
149738
|
+
* Refusals are keyed by `code` — the stable machine taxonomy of the prompt
|
|
149739
|
+
* contract. The released legacy routes (`/answer`, `/permission/answer`) key
|
|
149740
|
+
* theirs by `reason` and keep doing so; a client reads whichever key belongs
|
|
149741
|
+
* to the route it called, and the two vocabularies are not merged.
|
|
149742
|
+
*
|
|
149743
|
+
* Status follows the same split as the legacy routes: a malformed or
|
|
149744
|
+
* unanswerable *request* is 400, a prompt whose *state* refuses the answer is
|
|
149745
|
+
* 409. A retry after PROMPT_TERMINAL_RETENTION_MS answers 404
|
|
149746
|
+
* `prompt_not_found`, not the recorded outcome — the record it would replay
|
|
149747
|
+
* is gone by then.
|
|
149748
|
+
*/
|
|
149749
|
+
async handlePromptAnswer(sessionId, req, res) {
|
|
149750
|
+
const parsed = PromptAnswerSchema.safeParse(await readBody2(req));
|
|
149751
|
+
if (!parsed.success) {
|
|
149752
|
+
json2(res, 400, { ok: false, code: "invalid_prompt_answer" });
|
|
149753
|
+
return;
|
|
149754
|
+
}
|
|
149755
|
+
const outcome = await this.promptRegistry.answer(sessionId, parsed.data);
|
|
149756
|
+
if (outcome.ok) {
|
|
149757
|
+
json2(res, 200, outcome);
|
|
149758
|
+
return;
|
|
149759
|
+
}
|
|
149760
|
+
json2(res, promptAnswerStatus(outcome.code), outcome);
|
|
149761
|
+
}
|
|
148834
149762
|
// Best-effort: a session we don't own a PTY for, or one that raced away
|
|
148835
149763
|
// mid-read, is not ours to veto — say yes and let the write decide.
|
|
148836
149764
|
async questionMenuStillOpen(sessionId) {
|
|
@@ -151175,6 +152103,27 @@ init_capabilities();
|
|
|
151175
152103
|
function wsAllows(principal, required2) {
|
|
151176
152104
|
return principal === null || hasCapability(principal, required2);
|
|
151177
152105
|
}
|
|
152106
|
+
function clearExpiredPendingPrompt(deps, prompt) {
|
|
152107
|
+
const permission = deps.pendingPermission.get(prompt.sessionId);
|
|
152108
|
+
if (permission?.promptId === prompt.promptId) {
|
|
152109
|
+
deps.pendingPermission.delete(prompt.sessionId);
|
|
152110
|
+
deps.pendingPermissionKey.delete(prompt.sessionId);
|
|
152111
|
+
deps.wsHub.broadcastToClients(deps.sessionSubscribers.get(prompt.sessionId) ?? [], {
|
|
152112
|
+
type: "permission_cancelled",
|
|
152113
|
+
sessionId: prompt.sessionId
|
|
152114
|
+
});
|
|
152115
|
+
}
|
|
152116
|
+
const question = deps.pendingQuestions.get(prompt.sessionId);
|
|
152117
|
+
if (question?.promptId === prompt.promptId) {
|
|
152118
|
+
deps.pendingQuestions.delete(prompt.sessionId);
|
|
152119
|
+
deps.pendingQuestionKey.delete(prompt.sessionId);
|
|
152120
|
+
deps.wsHub.broadcastToClients(deps.sessionSubscribers.get(prompt.sessionId) ?? [], {
|
|
152121
|
+
type: "question_cancelled",
|
|
152122
|
+
sessionId: prompt.sessionId,
|
|
152123
|
+
toolUseId: question.toolUseId
|
|
152124
|
+
});
|
|
152125
|
+
}
|
|
152126
|
+
}
|
|
151178
152127
|
function createConversationWatcherEvents(deps) {
|
|
151179
152128
|
return {
|
|
151180
152129
|
onNewLineSpans: (filePath, spans, readFrom, endOffset) => {
|
|
@@ -151297,11 +152246,11 @@ function createLiveSessionOptions(deps) {
|
|
|
151297
152246
|
ts: ts2
|
|
151298
152247
|
});
|
|
151299
152248
|
},
|
|
151300
|
-
onPermissionChange: (sessionId, gate) => {
|
|
151301
|
-
deps.sessionHandlers().handlePermissionChange(sessionId, gate);
|
|
152249
|
+
onPermissionChange: (sessionId, gate, occurrenceId) => {
|
|
152250
|
+
deps.sessionHandlers().handlePermissionChange(sessionId, gate, occurrenceId);
|
|
151302
152251
|
},
|
|
151303
|
-
onLiveQuestion: (sessionId, questions) => {
|
|
151304
|
-
deps.sessionHandlers().handleLiveQuestion(sessionId, questions);
|
|
152252
|
+
onLiveQuestion: (sessionId, questions, occurrenceId) => {
|
|
152253
|
+
deps.sessionHandlers().handleLiveQuestion(sessionId, questions, occurrenceId);
|
|
151305
152254
|
},
|
|
151306
152255
|
onLiveQuestionGone: (sessionId) => {
|
|
151307
152256
|
deps.pendingQuestionKey.delete(sessionId);
|
|
@@ -151382,10 +152331,11 @@ function createLiveSessionOptions(deps) {
|
|
|
151382
152331
|
if (filePath) {
|
|
151383
152332
|
deps.fileWatcher.unwatch(filePath);
|
|
151384
152333
|
deps.sessionFileMap.delete(session.id);
|
|
151385
|
-
deps.cancelPendingQuestion(session.id);
|
|
151386
152334
|
}
|
|
152335
|
+
deps.cancelPendingQuestion(session.id);
|
|
151387
152336
|
deps.pendingPermission.delete(session.id);
|
|
151388
152337
|
deps.pendingPermissionKey.delete(session.id);
|
|
152338
|
+
deps.promptRegistry.invalidateSession(session.id, "session_ended");
|
|
151389
152339
|
deps.contendedSessions.delete(session.id);
|
|
151390
152340
|
deps.rememberSelfPtyEnded(session.id);
|
|
151391
152341
|
}
|
|
@@ -151440,6 +152390,7 @@ function createApiDeps(deps) {
|
|
|
151440
152390
|
handleGetOutput: (id, res) => deps.sessionHandlers.handleGetOutput(id, res),
|
|
151441
152391
|
handleSendInput: (id, req, res) => deps.sessionHandlers.handleSendInput(id, req, res),
|
|
151442
152392
|
handleSendAnswer: (id, req, res) => deps.sessionHandlers.handleSendAnswer(id, req, res),
|
|
152393
|
+
handlePromptAnswer: (id, req, res) => deps.sessionHandlers.handlePromptAnswer(id, req, res),
|
|
151443
152394
|
handlePermissionAnswer: (id, req, res) => deps.sessionHandlers.handlePermissionAnswer(id, req, res),
|
|
151444
152395
|
handleCancel: (id, res) => deps.sessionHandlers.handleCancel(id, res),
|
|
151445
152396
|
handleStopSession: (id, res) => deps.sessionHandlers.handleStopSession(id, res),
|
|
@@ -151498,6 +152449,9 @@ function createApiDeps(deps) {
|
|
|
151498
152449
|
return;
|
|
151499
152450
|
}
|
|
151500
152451
|
deps.addSessionSubscriber(msg.sessionId, ws2);
|
|
152452
|
+
if (deps.promptRegistry) {
|
|
152453
|
+
ws2.send(JSON.stringify(deps.promptRegistry.snapshot(msg.sessionId)));
|
|
152454
|
+
}
|
|
151501
152455
|
if (deps.ptyManager.hasSession(msg.sessionId)) {
|
|
151502
152456
|
const lines = await deps.ptyManager.getOutputLines(msg.sessionId, REPLAY_MAX_LINES);
|
|
151503
152457
|
const userMessages = deps.ptyManager.getInputHistory(msg.sessionId);
|
|
@@ -153727,16 +154681,16 @@ function compareValues(a, b2) {
|
|
|
153727
154681
|
if (typeof a === "number" && typeof b2 === "number") return a - b2;
|
|
153728
154682
|
return String(a).localeCompare(String(b2));
|
|
153729
154683
|
}
|
|
153730
|
-
function makeComparator(key,
|
|
153731
|
-
const dir =
|
|
154684
|
+
function makeComparator(key, order2) {
|
|
154685
|
+
const dir = order2 === "asc" ? 1 : -1;
|
|
153732
154686
|
return (a, b2) => {
|
|
153733
154687
|
const cmp = compareValues(getSortValue(a, key), getSortValue(b2, key)) * dir;
|
|
153734
154688
|
if (cmp !== 0) return cmp;
|
|
153735
154689
|
return a.id.localeCompare(b2.id);
|
|
153736
154690
|
};
|
|
153737
154691
|
}
|
|
153738
|
-
function findCursorBoundary(sorted, cursor, key,
|
|
153739
|
-
const dir =
|
|
154692
|
+
function findCursorBoundary(sorted, cursor, key, order2) {
|
|
154693
|
+
const dir = order2 === "asc" ? 1 : -1;
|
|
153740
154694
|
for (let i = 0; i < sorted.length; i++) {
|
|
153741
154695
|
const item = sorted[i];
|
|
153742
154696
|
const cmp = compareValues(getSortValue(item, key), cursor.k) * dir;
|
|
@@ -154312,6 +155266,7 @@ var StreamerServer = class {
|
|
|
154312
155266
|
// repaint of the same gate doesn't re-broadcast on every tick. Cleared
|
|
154313
155267
|
// alongside pendingPermission.
|
|
154314
155268
|
pendingPermissionKey = /* @__PURE__ */ new Map();
|
|
155269
|
+
promptRegistry;
|
|
154315
155270
|
// Scanner lifecycle, freshness state and the cache↔disk reconcile.
|
|
154316
155271
|
scannerManager;
|
|
154317
155272
|
// Binds a live session to the JSONL/rollout its provider writes.
|
|
@@ -154564,6 +155519,20 @@ var StreamerServer = class {
|
|
|
154564
155519
|
this.browserCors = config2.browserCors ?? loadBrowserCors();
|
|
154565
155520
|
this.sessionStore = new SessionStore();
|
|
154566
155521
|
this.wsHub = new WSHub();
|
|
155522
|
+
this.promptRegistry = new PromptRegistry({
|
|
155523
|
+
emit: (event) => this.wsHub.broadcastToClients(this.sessionSubscribers.get(event.sessionId) ?? [], event),
|
|
155524
|
+
onExpire: (prompt) => clearExpiredPendingPrompt(
|
|
155525
|
+
{
|
|
155526
|
+
pendingPermission: this.pendingPermission,
|
|
155527
|
+
pendingPermissionKey: this.pendingPermissionKey,
|
|
155528
|
+
pendingQuestions: this.pendingQuestions,
|
|
155529
|
+
pendingQuestionKey: this.pendingQuestionKey,
|
|
155530
|
+
sessionSubscribers: this.sessionSubscribers,
|
|
155531
|
+
wsHub: this.wsHub
|
|
155532
|
+
},
|
|
155533
|
+
prompt
|
|
155534
|
+
)
|
|
155535
|
+
});
|
|
154567
155536
|
this.fileWatcher = new ConversationWatcher(
|
|
154568
155537
|
createConversationWatcherEvents({
|
|
154569
155538
|
sessionFileMap: this.sessionFileMap,
|
|
@@ -154607,6 +155576,7 @@ var StreamerServer = class {
|
|
|
154607
155576
|
pendingQuestionKey: this.pendingQuestionKey,
|
|
154608
155577
|
pendingPermission: this.pendingPermission,
|
|
154609
155578
|
pendingPermissionKey: this.pendingPermissionKey,
|
|
155579
|
+
promptRegistry: this.promptRegistry,
|
|
154610
155580
|
contendedSessions: this.contendedSessions,
|
|
154611
155581
|
// Thunks, not values: sessionHandlers is constructed below, the
|
|
154612
155582
|
// registry repo and the push notifiers are bound during listen(), and
|
|
@@ -154697,6 +155667,7 @@ var StreamerServer = class {
|
|
|
154697
155667
|
sessionStatusBus: this.sessionStatusBus,
|
|
154698
155668
|
sessionFileMap: this.sessionFileMap,
|
|
154699
155669
|
pendingQuestions: this.pendingQuestions,
|
|
155670
|
+
promptRegistry: this.promptRegistry,
|
|
154700
155671
|
pendingQuestionKey: this.pendingQuestionKey,
|
|
154701
155672
|
pendingPermission: this.pendingPermission,
|
|
154702
155673
|
pendingPermissionKey: this.pendingPermissionKey,
|
|
@@ -154797,6 +155768,7 @@ var StreamerServer = class {
|
|
|
154797
155768
|
terminalSeq: this.terminalSeq,
|
|
154798
155769
|
pendingPermission: this.pendingPermission,
|
|
154799
155770
|
pendingQuestions: this.pendingQuestions,
|
|
155771
|
+
promptRegistry: this.promptRegistry,
|
|
154800
155772
|
agentClient,
|
|
154801
155773
|
conversationWriter,
|
|
154802
155774
|
agentConfig
|
|
@@ -155577,6 +156549,7 @@ var StreamerServer = class {
|
|
|
155577
156549
|
if (!this.ptyManager.isRemote()) this.ptyManager.dispose();
|
|
155578
156550
|
this.fileWatcher.dispose();
|
|
155579
156551
|
this.externalTails.clear();
|
|
156552
|
+
this.promptRegistry.dispose();
|
|
155580
156553
|
this.wsHub.dispose();
|
|
155581
156554
|
this.pairTokens.dispose();
|
|
155582
156555
|
this.liveActivityRenewal?.stop();
|
|
@@ -156165,7 +157138,7 @@ var StreamerServer = class {
|
|
|
156165
157138
|
for (const p2 of pending) {
|
|
156166
157139
|
if (contended || foreignVsPty(p2.questions)) continue;
|
|
156167
157140
|
const origin = priorPtyKey !== null && questionContentKey(p2.questions) === priorPtyKey ? "pty" : "jsonl";
|
|
156168
|
-
this.
|
|
157141
|
+
this.sessionHandlers.handleJsonlQuestion(sessionId, p2.toolUseId, p2.questions, origin);
|
|
156169
157142
|
const t = setTimeout(() => {
|
|
156170
157143
|
if (this.pendingQuestions.get(sessionId)?.toolUseId === p2.toolUseId) {
|
|
156171
157144
|
this.cancelPendingQuestion(sessionId);
|
|
@@ -156191,6 +157164,10 @@ var StreamerServer = class {
|
|
|
156191
157164
|
if (!pq) return;
|
|
156192
157165
|
this.pendingQuestions.delete(sessionId);
|
|
156193
157166
|
this.pendingQuestionKey.delete(sessionId);
|
|
157167
|
+
const prompt = this.promptRegistry.get(pq.promptId);
|
|
157168
|
+
if (prompt?.state === "open" || prompt?.state === "updated") {
|
|
157169
|
+
this.promptRegistry.transition(pq.promptId, "cancelled", "provider_closed");
|
|
157170
|
+
}
|
|
156194
157171
|
this.wsHub.broadcastToClients(this.sessionSubscribers.get(sessionId) ?? [], {
|
|
156195
157172
|
type: "question_cancelled",
|
|
156196
157173
|
sessionId,
|
|
@@ -156526,7 +157503,7 @@ function isBrewInstall(scriptPath = process.argv[1] ?? "") {
|
|
|
156526
157503
|
}
|
|
156527
157504
|
|
|
156528
157505
|
// src/updater/download.ts
|
|
156529
|
-
var
|
|
157506
|
+
var import_node_crypto6 = require("crypto");
|
|
156530
157507
|
var import_node_fs10 = require("fs");
|
|
156531
157508
|
var import_node_path11 = require("path");
|
|
156532
157509
|
var import_promises17 = require("stream/promises");
|
|
@@ -156593,7 +157570,7 @@ async function downloadAndVerify(opts) {
|
|
|
156593
157570
|
if (!res.ok || !res.body) {
|
|
156594
157571
|
throw new Error(`Failed to download ${artifact.filename}: ${res.status} ${res.statusText}`);
|
|
156595
157572
|
}
|
|
156596
|
-
const hash2 = (0,
|
|
157573
|
+
const hash2 = (0, import_node_crypto6.createHash)("sha256");
|
|
156597
157574
|
const out = (0, import_node_fs10.createWriteStream)(targetPath);
|
|
156598
157575
|
let bytes = 0;
|
|
156599
157576
|
const measured = new TransformStream({
|
|
@@ -156898,7 +157875,7 @@ var import_node_path18 = require("path");
|
|
|
156898
157875
|
var import_path38 = __toESM(require("path"), 1);
|
|
156899
157876
|
var import_node_fs14 = __toESM(require("fs"), 1);
|
|
156900
157877
|
var import_node_assert = __toESM(require("assert"), 1);
|
|
156901
|
-
var
|
|
157878
|
+
var import_node_crypto7 = require("crypto");
|
|
156902
157879
|
var import_node_fs15 = __toESM(require("fs"), 1);
|
|
156903
157880
|
var import_node_path19 = __toESM(require("path"), 1);
|
|
156904
157881
|
var import_fs43 = __toESM(require("fs"), 1);
|
|
@@ -159313,7 +160290,7 @@ var Te = fo === "win32";
|
|
|
159313
160290
|
var uo = 1024;
|
|
159314
160291
|
var mo = (s3, t) => {
|
|
159315
160292
|
if (!Te) return import_node_fs15.default.unlink(s3, t);
|
|
159316
|
-
let e = s3 + ".DELETE." + (0,
|
|
160293
|
+
let e = s3 + ".DELETE." + (0, import_node_crypto7.randomBytes)(16).toString("hex");
|
|
159317
160294
|
import_node_fs15.default.rename(s3, e, (i) => {
|
|
159318
160295
|
if (i) return t(i);
|
|
159319
160296
|
import_node_fs15.default.unlink(e, t);
|
|
@@ -159321,7 +160298,7 @@ var mo = (s3, t) => {
|
|
|
159321
160298
|
};
|
|
159322
160299
|
var po = (s3) => {
|
|
159323
160300
|
if (!Te) return import_node_fs15.default.unlinkSync(s3);
|
|
159324
|
-
let t = s3 + ".DELETE." + (0,
|
|
160301
|
+
let t = s3 + ".DELETE." + (0, import_node_crypto7.randomBytes)(16).toString("hex");
|
|
159325
160302
|
import_node_fs15.default.renameSync(s3, t), import_node_fs15.default.unlinkSync(t);
|
|
159326
160303
|
};
|
|
159327
160304
|
var vr = (s3, t, e) => s3 !== void 0 && s3 === s3 >>> 0 ? s3 : t !== void 0 && t === t >>> 0 ? t : e;
|