@alivault/pico 0.13.0 → 0.14.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/.output/nitro.json +1 -1
- package/.output/public/assets/{index-CW1T9dk-.js → index-DBVxXDtw.js} +4 -4
- package/.output/public/assets/routes-yUxD2q-l.js +2194 -0
- package/.output/public/assets/styles-CUVz7jV9.css +2 -0
- package/.output/public/screenshots/pico-ios-dark.png +0 -0
- package/.output/public/screenshots/pico-ios-light.png +0 -0
- package/.output/public/screenshots/pico-macos-dark.jpg +0 -0
- package/.output/public/screenshots/pico-macos-light.jpg +0 -0
- package/.output/server/_chunks/ssr-renderer.mjs +3 -3
- package/.output/server/_libs/crossws.mjs +2929 -0
- package/.output/server/_libs/h3+rou3+srvx.mjs +7 -1
- package/.output/server/_libs/unctx.mjs +1 -1
- package/.output/server/_routes/api/terminal/[id]/ws.mjs +8874 -0
- package/.output/server/_ssr/{router-l__gf5Y7.mjs → router-CN4JMm2A.mjs} +1074 -316
- package/.output/server/_ssr/{routes-DySm_W8N.mjs → routes-BsQ26pbY.mjs} +738 -189
- package/.output/server/_ssr/{routes-CuWg5WTI.mjs → routes-DbjuMLFI.mjs} +19 -10
- package/.output/server/_ssr/ssr.mjs +3 -3
- package/.output/server/_ssr/start-jIczsXlR.mjs +4 -0
- package/.output/server/{_tanstack-start-manifest_v-CVoKKKc_.mjs → _tanstack-start-manifest_v-Bs4g_j1_.mjs} +7 -4
- package/.output/server/index.mjs +644 -565
- package/.output/server/node_modules/node-pty/build/Makefile +2 -2
- package/.output/server/node_modules/node-pty/build/pty.target.mk +14 -14
- package/README.md +68 -6
- package/bin/pico.mjs +103 -1
- package/package.json +4 -4
- package/public/screenshots/pico-ios-dark.png +0 -0
- package/public/screenshots/pico-ios-light.png +0 -0
- package/public/screenshots/pico-macos-dark.jpg +0 -0
- package/public/screenshots/pico-macos-light.jpg +0 -0
- package/.output/public/assets/routes-2LboeUx4.js +0 -2194
- package/.output/public/assets/styles-B1ITYh-r.css +0 -2
- package/.output/server/_ssr/start-Captdpmb.mjs +0 -4
|
@@ -2,7 +2,7 @@ import { i as __toESM } from "../_runtime.mjs";
|
|
|
2
2
|
import { $ as require_react, Q as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
|
|
3
3
|
import { a as createRouter, c as createRootRoute, n as Scripts, r as HeadContent, s as createFileRoute } from "../_libs/@tanstack/react-router+[...].mjs";
|
|
4
4
|
import { T as Info, a as TriangleAlert, y as OctagonX, z as CircleCheck } from "../_libs/lucide-react.mjs";
|
|
5
|
-
import { B as buildItemsFromSync, H as createCompactionSummaryItem, J as extractToolText, K as extractMessageImages, Lt as toolCategoryFromTool, P as TooltipProvider, R as appliedThemeClassColorMode, T as Spinner, Z as mergeAssistantBlocksForStreaming, f as PICO_SHIKI_VARIABLE_DEFAULTS, n as APPLIED_THEME_STORAGE_KEY, q as extractMessageText$1, t as APPLIED_THEME_CLASSES, u as PICO_CODE_SHIKI_THEME, x as Route$
|
|
5
|
+
import { B as buildItemsFromSync, H as createCompactionSummaryItem, J as extractToolText, K as extractMessageImages, Lt as toolCategoryFromTool, P as TooltipProvider, R as appliedThemeClassColorMode, T as Spinner, Z as mergeAssistantBlocksForStreaming, f as PICO_SHIKI_VARIABLE_DEFAULTS, n as APPLIED_THEME_STORAGE_KEY, q as extractMessageText$1, t as APPLIED_THEME_CLASSES, u as PICO_CODE_SHIKI_THEME, x as Route$62, z as assistantBlocksFromMessage } from "./routes-DbjuMLFI.mjs";
|
|
6
6
|
import { t as QueryClient } from "../_libs/tanstack__query-core.mjs";
|
|
7
7
|
import { t as setupRouterSsrQueryIntegration } from "../_libs/@tanstack/react-router-ssr-query+[...].mjs";
|
|
8
8
|
import { n as HotkeysProvider } from "../_libs/tanstack__react-hotkeys.mjs";
|
|
@@ -21,7 +21,7 @@ import os, { homedir } from "node:os";
|
|
|
21
21
|
import { performance } from "node:perf_hooks";
|
|
22
22
|
import { isMainThread } from "node:worker_threads";
|
|
23
23
|
import { execSync, spawn } from "node:child_process";
|
|
24
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/router-
|
|
24
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/router-CN4JMm2A.js
|
|
25
25
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
26
26
|
var import_jsx_runtime = require_jsx_runtime();
|
|
27
27
|
function sonnerThemeFromAppliedTheme(theme) {
|
|
@@ -88,7 +88,7 @@ function AppProviders({ children }) {
|
|
|
88
88
|
})
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
-
var styles_default = "/assets/styles-
|
|
91
|
+
var styles_default = "/assets/styles-CUVz7jV9.css";
|
|
92
92
|
var TANSTACK_DEVTOOLS_SETTINGS_KEY = "tanstack_devtools_settings";
|
|
93
93
|
var TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY = "pico-tanstack-devtools-defaults-v2";
|
|
94
94
|
var TANSTACK_DEVTOOLS_CONFIG = {
|
|
@@ -100,7 +100,7 @@ var TANSTACK_DEVTOOLS_CONFIG = {
|
|
|
100
100
|
],
|
|
101
101
|
triggerHidden: true
|
|
102
102
|
};
|
|
103
|
-
var Route$
|
|
103
|
+
var Route$61 = createRootRoute({
|
|
104
104
|
head: () => ({
|
|
105
105
|
meta: [
|
|
106
106
|
{ charSet: "utf-8" },
|
|
@@ -269,15 +269,18 @@ async function loadPiSdk() {
|
|
|
269
269
|
const sdkDir = resolvePiSdkDir();
|
|
270
270
|
return patchSdkForWorkerThreads(await importExternalModule(path.join(sdkDir, "dist", "index.js")));
|
|
271
271
|
}
|
|
272
|
+
function addPiAiCandidateEntries(candidates, packageDir) {
|
|
273
|
+
candidates.push(path.join(packageDir, "dist", "compat.js"), path.join(packageDir, "dist", "index.js"));
|
|
274
|
+
}
|
|
272
275
|
function getPiAiCandidates(sdkDir) {
|
|
273
276
|
const candidates = [];
|
|
274
|
-
for (const scope of ["@earendil-works", "@mariozechner"]) candidates
|
|
277
|
+
for (const scope of ["@earendil-works", "@mariozechner"]) addPiAiCandidateEntries(candidates, path.join(sdkDir, "node_modules", scope, "pi-ai"));
|
|
275
278
|
try {
|
|
276
279
|
const realSdkDir = fs.realpathSync(sdkDir);
|
|
277
|
-
for (const scope of ["@earendil-works", "@mariozechner"]) candidates
|
|
278
|
-
candidates
|
|
280
|
+
for (const scope of ["@earendil-works", "@mariozechner"]) addPiAiCandidateEntries(candidates, path.join(realSdkDir, "node_modules", scope, "pi-ai"));
|
|
281
|
+
addPiAiCandidateEntries(candidates, path.join(path.dirname(realSdkDir), "pi-ai"));
|
|
279
282
|
} catch {}
|
|
280
|
-
candidates
|
|
283
|
+
addPiAiCandidateEntries(candidates, path.join(path.dirname(sdkDir), "pi-ai"));
|
|
281
284
|
return candidates;
|
|
282
285
|
}
|
|
283
286
|
function resolvePiAiEntry(sdkDir) {
|
|
@@ -461,11 +464,62 @@ function buildSessionNamePrompt(prompt, cwdBasename, imageCount) {
|
|
|
461
464
|
normalizedPrompt
|
|
462
465
|
].filter(Boolean).join("\n");
|
|
463
466
|
}
|
|
467
|
+
function modelLabel(model) {
|
|
468
|
+
return `${model.provider}/${model.id}`;
|
|
469
|
+
}
|
|
470
|
+
function formatSessionNamingError(error) {
|
|
471
|
+
if (error instanceof Error) return error.message;
|
|
472
|
+
if (typeof error === "string") return error;
|
|
473
|
+
return "Unknown error";
|
|
474
|
+
}
|
|
475
|
+
function modelSupportsTextInput(model) {
|
|
476
|
+
if (!Array.isArray(model.input)) return true;
|
|
477
|
+
return model.input.includes("text");
|
|
478
|
+
}
|
|
479
|
+
function collectSessionNamingModelCandidates(entry) {
|
|
480
|
+
const candidates = [];
|
|
481
|
+
const seen = /* @__PURE__ */ new Set();
|
|
482
|
+
const addCandidate = (model, source) => {
|
|
483
|
+
if (!model || !modelSupportsTextInput(model)) return;
|
|
484
|
+
const key = modelLabel(model);
|
|
485
|
+
if (seen.has(key)) return;
|
|
486
|
+
seen.add(key);
|
|
487
|
+
candidates.push({
|
|
488
|
+
model,
|
|
489
|
+
source
|
|
490
|
+
});
|
|
491
|
+
};
|
|
492
|
+
addCandidate(entry.model, "active");
|
|
493
|
+
for (const model of entry.services.modelRegistry.getAvailable()) addCandidate(model, "available");
|
|
494
|
+
return candidates;
|
|
495
|
+
}
|
|
496
|
+
async function selectSessionNamingModel(entry) {
|
|
497
|
+
const candidates = collectSessionNamingModelCandidates(entry);
|
|
498
|
+
if (candidates.length === 0) return {
|
|
499
|
+
ok: false,
|
|
500
|
+
reason: "no text-capable models are available for session naming"
|
|
501
|
+
};
|
|
502
|
+
const failures = [];
|
|
503
|
+
for (const candidate of candidates) try {
|
|
504
|
+
const auth = await entry.services.modelRegistry.getApiKeyAndHeaders(candidate.model);
|
|
505
|
+
if (auth?.ok) return {
|
|
506
|
+
ok: true,
|
|
507
|
+
...candidate,
|
|
508
|
+
auth
|
|
509
|
+
};
|
|
510
|
+
failures.push(`${modelLabel(candidate.model)}: ${auth?.error || "not authenticated"}`);
|
|
511
|
+
} catch (error) {
|
|
512
|
+
failures.push(`${modelLabel(candidate.model)}: ${formatSessionNamingError(error)}`);
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
ok: false,
|
|
516
|
+
reason: `no authenticated text model is available for session naming${failures.length > 0 ? ` (${failures.slice(0, 3).join("; ")})` : ""}`
|
|
517
|
+
};
|
|
518
|
+
}
|
|
464
519
|
async function generateSessionNameWithLlm(entry, text, imageCount) {
|
|
465
|
-
const
|
|
466
|
-
if (!
|
|
467
|
-
const auth =
|
|
468
|
-
if (!auth?.ok) return { reason: auth?.error || `failed to authenticate ${model.provider}/${model.id} for session naming` };
|
|
520
|
+
const selectedModel = await selectSessionNamingModel(entry);
|
|
521
|
+
if (!selectedModel.ok) return { reason: selectedModel.reason };
|
|
522
|
+
const { model, auth } = selectedModel;
|
|
469
523
|
const response = await (await loadPiAi()).complete(model, {
|
|
470
524
|
systemPrompt: SESSION_NAME_SYSTEM_PROMPT,
|
|
471
525
|
messages: [{
|
|
@@ -493,8 +547,12 @@ function normalizeSessionScope(rawScope, defaultCwd) {
|
|
|
493
547
|
function resolveScopeCwd(scope, defaultCwd) {
|
|
494
548
|
return normalizeSessionScope(scope ?? null, defaultCwd);
|
|
495
549
|
}
|
|
496
|
-
function
|
|
497
|
-
|
|
550
|
+
function formatSsePayloadText(payload, options) {
|
|
551
|
+
const prefixLines = [];
|
|
552
|
+
if (options?.id) prefixLines.push(`id: ${options.id}`);
|
|
553
|
+
if (typeof options?.retry === "number" && Number.isFinite(options.retry)) prefixLines.push(`retry: ${Math.max(0, Math.round(options.retry))}`);
|
|
554
|
+
const dataLines = JSON.stringify(payload).split(/\r?\n/).map((line) => `data: ${line}`);
|
|
555
|
+
return `${[...prefixLines, ...dataLines].join("\n")}\n\n`;
|
|
498
556
|
}
|
|
499
557
|
function writeRawToClient(options) {
|
|
500
558
|
const { encoder, context, client, text, closeSseClient } = options;
|
|
@@ -508,12 +566,15 @@ function writeRawToClient(options) {
|
|
|
508
566
|
}
|
|
509
567
|
}
|
|
510
568
|
function sendPayloadToClient(options) {
|
|
511
|
-
const { context, client, payload, closeSseClient, encoder } = options;
|
|
569
|
+
const { context, client, payload, closeSseClient, encoder, eventId, retry } = options;
|
|
512
570
|
return writeRawToClient({
|
|
513
571
|
encoder,
|
|
514
572
|
context,
|
|
515
573
|
client,
|
|
516
|
-
text:
|
|
574
|
+
text: formatSsePayloadText(payload, {
|
|
575
|
+
id: eventId,
|
|
576
|
+
retry
|
|
577
|
+
}),
|
|
517
578
|
closeSseClient
|
|
518
579
|
});
|
|
519
580
|
}
|
|
@@ -694,7 +755,7 @@ function formatTerminalError(error) {
|
|
|
694
755
|
return "Unknown terminal error";
|
|
695
756
|
}
|
|
696
757
|
function sseFrame(event) {
|
|
697
|
-
return `data: ${JSON.stringify(event)}\n\n`;
|
|
758
|
+
return `${event.type === "output" ? `id: ${event.seq}\n` : ""}data: ${JSON.stringify(event)}\n\n`;
|
|
698
759
|
}
|
|
699
760
|
function exitPayload(exitCode, signal) {
|
|
700
761
|
return typeof signal === "number" && signal > 0 ? {
|
|
@@ -708,6 +769,23 @@ function exitEvent(exitCode, signal) {
|
|
|
708
769
|
...exitPayload(exitCode, signal)
|
|
709
770
|
};
|
|
710
771
|
}
|
|
772
|
+
function readyEvent(record) {
|
|
773
|
+
return {
|
|
774
|
+
type: "ready",
|
|
775
|
+
backend: record.backend,
|
|
776
|
+
id: record.id,
|
|
777
|
+
cwd: record.cwd,
|
|
778
|
+
shell: terminalLabel(record.shell),
|
|
779
|
+
nextInputSeq: record.lastInputSeq + 1
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
function parseTerminalWebSocketMessage(text) {
|
|
783
|
+
const parsed = JSON.parse(text);
|
|
784
|
+
if (!parsed || typeof parsed !== "object") throw new Error("Terminal WebSocket message must be an object.");
|
|
785
|
+
const message = parsed;
|
|
786
|
+
if (message.type !== "input" && message.type !== "resize" && message.type !== "ping") throw new Error("Unknown terminal WebSocket message type.");
|
|
787
|
+
return message;
|
|
788
|
+
}
|
|
711
789
|
function normalizeTerminalKey(value) {
|
|
712
790
|
if (typeof value !== "string") return void 0;
|
|
713
791
|
const normalized = value.trim();
|
|
@@ -763,6 +841,8 @@ var PicoTerminalManager = class {
|
|
|
763
841
|
subscribers: /* @__PURE__ */ new Set(),
|
|
764
842
|
backlog: [],
|
|
765
843
|
backlogBytes: 0,
|
|
844
|
+
nextOutputSeq: 1,
|
|
845
|
+
lastInputSeq: 0,
|
|
766
846
|
createdAt: now,
|
|
767
847
|
lastUsedAt: now
|
|
768
848
|
};
|
|
@@ -779,7 +859,7 @@ var PicoTerminalManager = class {
|
|
|
779
859
|
reused: false
|
|
780
860
|
};
|
|
781
861
|
}
|
|
782
|
-
createEventsResponse(id, scopeKey, signal) {
|
|
862
|
+
createEventsResponse(id, scopeKey, signal, lastSeq) {
|
|
783
863
|
const record = this.assertTerminalScope(id, scopeKey);
|
|
784
864
|
record.lastUsedAt = Date.now();
|
|
785
865
|
let cleanupStream = () => {};
|
|
@@ -806,15 +886,7 @@ var PicoTerminalManager = class {
|
|
|
806
886
|
cleanupStream = cleanup;
|
|
807
887
|
record.subscribers.add(send);
|
|
808
888
|
signal.addEventListener("abort", cleanup, { once: true });
|
|
809
|
-
send
|
|
810
|
-
type: "ready",
|
|
811
|
-
backend: record.backend,
|
|
812
|
-
id: record.id,
|
|
813
|
-
cwd: record.cwd,
|
|
814
|
-
shell: terminalLabel(record.shell)
|
|
815
|
-
});
|
|
816
|
-
for (const event of record.backlog) send(event);
|
|
817
|
-
if (record.exited) send(exitEvent(record.exited.exitCode, record.exited.signal));
|
|
889
|
+
this.sendInitialEvents(record, send, lastSeq);
|
|
818
890
|
},
|
|
819
891
|
cancel: () => {
|
|
820
892
|
cleanupStream();
|
|
@@ -827,12 +899,69 @@ var PicoTerminalManager = class {
|
|
|
827
899
|
"x-accel-buffering": "no"
|
|
828
900
|
} });
|
|
829
901
|
}
|
|
830
|
-
|
|
902
|
+
validateTerminal(id, scopeKey) {
|
|
903
|
+
this.assertTerminalScope(id, scopeKey);
|
|
904
|
+
}
|
|
905
|
+
connectWebSocket(options) {
|
|
906
|
+
const { id, lastSeq, peer, scopeKey } = options;
|
|
907
|
+
const record = this.assertTerminalScope(id, scopeKey);
|
|
908
|
+
record.lastUsedAt = Date.now();
|
|
909
|
+
let closed = false;
|
|
910
|
+
const send = (event) => {
|
|
911
|
+
if (closed) return;
|
|
912
|
+
try {
|
|
913
|
+
peer.send(JSON.stringify(event));
|
|
914
|
+
} catch {
|
|
915
|
+
cleanup();
|
|
916
|
+
}
|
|
917
|
+
};
|
|
918
|
+
const cleanup = () => {
|
|
919
|
+
if (closed) return;
|
|
920
|
+
closed = true;
|
|
921
|
+
record.subscribers.delete(send);
|
|
922
|
+
};
|
|
923
|
+
record.subscribers.add(send);
|
|
924
|
+
this.sendInitialEvents(record, send, lastSeq);
|
|
925
|
+
return cleanup;
|
|
926
|
+
}
|
|
927
|
+
handleWebSocketMessage(options) {
|
|
928
|
+
const { id, message, peer, scopeKey } = options;
|
|
929
|
+
try {
|
|
930
|
+
const payload = parseTerminalWebSocketMessage(message);
|
|
931
|
+
if (payload.type === "input") {
|
|
932
|
+
const inputSeq = this.writeTerminal(id, scopeKey, payload.data, payload.inputSeq);
|
|
933
|
+
if (typeof inputSeq === "number" && inputSeq > 0) peer.send(JSON.stringify({
|
|
934
|
+
type: "input_ack",
|
|
935
|
+
inputSeq
|
|
936
|
+
}));
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
if (payload.type === "resize") {
|
|
940
|
+
this.resizeTerminal(id, scopeKey, payload);
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
peer.send(JSON.stringify({ type: "pong" }));
|
|
944
|
+
} catch (error) {
|
|
945
|
+
try {
|
|
946
|
+
peer.send(JSON.stringify({
|
|
947
|
+
type: "error",
|
|
948
|
+
error: formatTerminalError(error)
|
|
949
|
+
}));
|
|
950
|
+
} catch {}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
writeTerminal(id, scopeKey, data, inputSeq) {
|
|
831
954
|
const record = this.assertTerminalScope(id, scopeKey);
|
|
832
955
|
if (record.exited) throw new Error("Terminal has exited.");
|
|
833
956
|
if (typeof data !== "string") throw new Error("Terminal input data is required.");
|
|
957
|
+
const normalizedInputSeq = normalizeDimension(inputSeq, 0, 0, Number.MAX_SAFE_INTEGER);
|
|
958
|
+
if (normalizedInputSeq > 0) {
|
|
959
|
+
if (normalizedInputSeq <= record.lastInputSeq) return normalizedInputSeq;
|
|
960
|
+
record.lastInputSeq = normalizedInputSeq;
|
|
961
|
+
}
|
|
834
962
|
record.lastUsedAt = Date.now();
|
|
835
963
|
record.pty.write(data);
|
|
964
|
+
return normalizedInputSeq > 0 ? normalizedInputSeq : void 0;
|
|
836
965
|
}
|
|
837
966
|
resizeTerminal(id, scopeKey, dimensions) {
|
|
838
967
|
const record = this.assertTerminalScope(id, scopeKey);
|
|
@@ -861,9 +990,12 @@ var PicoTerminalManager = class {
|
|
|
861
990
|
}
|
|
862
991
|
attachPtyHandlers(record) {
|
|
863
992
|
record.dataDisposable = record.pty.onData((data) => {
|
|
993
|
+
const seq = record.nextOutputSeq;
|
|
994
|
+
record.nextOutputSeq += 1;
|
|
864
995
|
this.publish(record, {
|
|
865
996
|
type: "output",
|
|
866
|
-
data
|
|
997
|
+
data,
|
|
998
|
+
seq
|
|
867
999
|
});
|
|
868
1000
|
});
|
|
869
1001
|
record.exitDisposable = record.pty.onExit((event) => {
|
|
@@ -890,6 +1022,21 @@ var PicoTerminalManager = class {
|
|
|
890
1022
|
if (record.scopeKey !== scopeKey) throw new Error("Terminal not found for this session.");
|
|
891
1023
|
return record;
|
|
892
1024
|
}
|
|
1025
|
+
sendInitialEvents(record, send, lastSeq) {
|
|
1026
|
+
send(readyEvent(record));
|
|
1027
|
+
const firstSeq = record.backlog[0]?.seq;
|
|
1028
|
+
if (typeof lastSeq === "number" && firstSeq !== void 0 && lastSeq < firstSeq - 1) send({
|
|
1029
|
+
type: "reset",
|
|
1030
|
+
reason: "backlog_gap",
|
|
1031
|
+
firstSeq,
|
|
1032
|
+
nextSeq: record.nextOutputSeq
|
|
1033
|
+
});
|
|
1034
|
+
for (const event of record.backlog) {
|
|
1035
|
+
if (typeof lastSeq === "number" && event.seq <= lastSeq) continue;
|
|
1036
|
+
send(event);
|
|
1037
|
+
}
|
|
1038
|
+
if (record.exited) send(exitEvent(record.exited.exitCode, record.exited.signal));
|
|
1039
|
+
}
|
|
893
1040
|
publish(record, event) {
|
|
894
1041
|
record.lastUsedAt = Date.now();
|
|
895
1042
|
this.rememberBacklog(record, event);
|
|
@@ -1710,6 +1857,22 @@ function serializeSessionTreeNode(node) {
|
|
|
1710
1857
|
});
|
|
1711
1858
|
return serialized;
|
|
1712
1859
|
}
|
|
1860
|
+
function extractBranchableMessages(entry) {
|
|
1861
|
+
const manager = entry.session.sessionManager;
|
|
1862
|
+
const leafId = manager.getLeafId?.() ?? null;
|
|
1863
|
+
const branchEntries = manager.getBranch?.(leafId) ?? [];
|
|
1864
|
+
return (branchEntries.length > 0 ? branchEntries : []).flatMap((entry) => {
|
|
1865
|
+
const entryId = typeof entry.id === "string" ? entry.id.trim() : "";
|
|
1866
|
+
const message = entry.message;
|
|
1867
|
+
const role = typeof message?.role === "string" ? message.role : "";
|
|
1868
|
+
if (!entryId || entry.type !== "message" || role !== "user" && role !== "assistant") return [];
|
|
1869
|
+
return [{
|
|
1870
|
+
entryId,
|
|
1871
|
+
role,
|
|
1872
|
+
text: extractMessageText(message)
|
|
1873
|
+
}];
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1713
1876
|
function extractForkableUserMessages(entry) {
|
|
1714
1877
|
const messages = entry.session.getUserMessagesForForking?.();
|
|
1715
1878
|
if (Array.isArray(messages) && messages.length > 0) return messages.flatMap((message) => {
|
|
@@ -3883,12 +4046,20 @@ var VALID_THINKING_LEVELS = new Set([
|
|
|
3883
4046
|
"high",
|
|
3884
4047
|
"xhigh"
|
|
3885
4048
|
]);
|
|
4049
|
+
var PICO_DEFAULT_MODEL_PROVIDER = "openai-codex";
|
|
4050
|
+
var PICO_DEFAULT_MODEL_ID = "gpt-5.5";
|
|
4051
|
+
var PICO_DEFAULT_THINKING_LEVEL = "xhigh";
|
|
3886
4052
|
var SESSION_LIST_LIMIT_DEFAULT = 5;
|
|
3887
4053
|
var SESSION_LIST_LIMIT_MAX = 100;
|
|
3888
4054
|
var SESSION_HISTORY_PAGE_LIMIT_DEFAULT = 50;
|
|
3889
4055
|
var SESSION_HISTORY_PAGE_LIMIT_MAX = 200;
|
|
3890
4056
|
var SESSION_NAME_MAX_LENGTH = 48;
|
|
3891
4057
|
var HEARTBEAT_INTERVAL_MS = 2e4;
|
|
4058
|
+
var SSE_RETRY_MS = 1e3;
|
|
4059
|
+
var SSE_REPLAY_MAX_EVENTS = 200;
|
|
4060
|
+
var CONTEXT_INACTIVE_GRACE_MS = 3e4;
|
|
4061
|
+
var PROMPT_IDEMPOTENCY_TTL_MS = 1440 * 60 * 1e3;
|
|
4062
|
+
var PROMPT_IDEMPOTENCY_MAX_RECORDS = 200;
|
|
3892
4063
|
var SESSION_INDEX_CACHE_TTL_MS = 5e3;
|
|
3893
4064
|
var SESSION_LOAD_DEBUG_ENV_KEYS = [
|
|
3894
4065
|
"PICO_DEBUG_SESSION_LOAD",
|
|
@@ -4046,17 +4217,40 @@ function normalizeRequestedDirectories(values) {
|
|
|
4046
4217
|
}
|
|
4047
4218
|
return nextDirectories;
|
|
4048
4219
|
}
|
|
4220
|
+
function textFromThinkingSignature(value) {
|
|
4221
|
+
if (typeof value !== "string" || !value.trim()) return "";
|
|
4222
|
+
let parsed;
|
|
4223
|
+
try {
|
|
4224
|
+
parsed = JSON.parse(value);
|
|
4225
|
+
} catch {
|
|
4226
|
+
return "";
|
|
4227
|
+
}
|
|
4228
|
+
if (!parsed || typeof parsed !== "object") return "";
|
|
4229
|
+
const content = parsed.content;
|
|
4230
|
+
if (!Array.isArray(content)) return "";
|
|
4231
|
+
return content.flatMap((part) => {
|
|
4232
|
+
if (!part || typeof part !== "object") return [];
|
|
4233
|
+
const type = part.type;
|
|
4234
|
+
const text = part.text;
|
|
4235
|
+
return type === "reasoning_text" && typeof text === "string" && text.trim() ? [text] : [];
|
|
4236
|
+
}).join("\n\n").trim();
|
|
4237
|
+
}
|
|
4049
4238
|
function sanitizeMessageContentPart(part) {
|
|
4050
4239
|
const type = typeof part?.type === "string" ? part.type : "";
|
|
4051
4240
|
if (type === "text") return {
|
|
4052
4241
|
type: "text",
|
|
4053
4242
|
text: typeof part.text === "string" ? part.text : ""
|
|
4054
4243
|
};
|
|
4055
|
-
if (type === "thinking")
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4244
|
+
if (type === "thinking") {
|
|
4245
|
+
const rawThinking = typeof part.thinking === "string" ? part.thinking : "";
|
|
4246
|
+
const signatureThinking = textFromThinkingSignature(part.thinkingSignature);
|
|
4247
|
+
const summaryLabel = typeof part.summaryLabel === "string" ? part.summaryLabel : signatureThinking && rawThinking.trim() ? rawThinking : void 0;
|
|
4248
|
+
return {
|
|
4249
|
+
type: "thinking",
|
|
4250
|
+
thinking: signatureThinking || rawThinking,
|
|
4251
|
+
...summaryLabel ? { summaryLabel } : {}
|
|
4252
|
+
};
|
|
4253
|
+
}
|
|
4060
4254
|
if (type === "toolCall") return {
|
|
4061
4255
|
type: "toolCall",
|
|
4062
4256
|
...typeof part.id === "string" ? { id: part.id } : {},
|
|
@@ -4077,6 +4271,8 @@ function sanitizeSessionMessage(message) {
|
|
|
4077
4271
|
const sanitizedPart = sanitizeMessageContentPart(part);
|
|
4078
4272
|
return sanitizedPart ? [sanitizedPart] : [];
|
|
4079
4273
|
}) : typeof message?.content === "string" ? message.content : void 0;
|
|
4274
|
+
const tokensBefore = Number(message?.tokensBefore);
|
|
4275
|
+
const estimatedTokensAfter = message?.estimatedTokensAfter == null ? NaN : Number(message.estimatedTokensAfter);
|
|
4080
4276
|
return {
|
|
4081
4277
|
...role ? { role } : {},
|
|
4082
4278
|
...sanitizedContent !== void 0 ? { content: sanitizedContent } : {},
|
|
@@ -4087,7 +4283,8 @@ function sanitizeSessionMessage(message) {
|
|
|
4087
4283
|
...message?.queued || metadata?.queued ? { queued: true } : {},
|
|
4088
4284
|
...message?.streamingBehavior === "steer" || message?.streamingBehavior === "followUp" ? { streamingBehavior: message.streamingBehavior } : message?.deliverAs === "steer" || message?.deliverAs === "followUp" ? { streamingBehavior: message.deliverAs } : metadata?.streamingBehavior === "steer" || metadata?.streamingBehavior === "followUp" ? { streamingBehavior: metadata.streamingBehavior } : metadata?.deliverAs === "steer" || metadata?.deliverAs === "followUp" ? { streamingBehavior: metadata.deliverAs } : {},
|
|
4089
4285
|
...typeof message?.summary === "string" ? { summary: message.summary } : {},
|
|
4090
|
-
...Number.isFinite(
|
|
4286
|
+
...Number.isFinite(tokensBefore) ? { tokensBefore } : {},
|
|
4287
|
+
...Number.isFinite(estimatedTokensAfter) ? { estimatedTokensAfter } : {},
|
|
4091
4288
|
...typeof message?.toolCallId === "string" ? { toolCallId: message.toolCallId } : {},
|
|
4092
4289
|
...Object.prototype.hasOwnProperty.call(message, "details") ? { details: message.details } : {},
|
|
4093
4290
|
...message?.isError ? { isError: true } : {}
|
|
@@ -4246,6 +4443,43 @@ function normalizeClientPendingId(value) {
|
|
|
4246
4443
|
if (pendingId.length > 128) return void 0;
|
|
4247
4444
|
return pendingId;
|
|
4248
4445
|
}
|
|
4446
|
+
function normalizeClientPromptRequestId(value) {
|
|
4447
|
+
if (typeof value !== "string") return void 0;
|
|
4448
|
+
const requestId = value.trim();
|
|
4449
|
+
if (!requestId.startsWith("prompt:")) return void 0;
|
|
4450
|
+
if (requestId.length > 160) return void 0;
|
|
4451
|
+
return requestId;
|
|
4452
|
+
}
|
|
4453
|
+
function parsePositiveInteger(value) {
|
|
4454
|
+
if (!value) return void 0;
|
|
4455
|
+
const parsed = Number(value);
|
|
4456
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0) return void 0;
|
|
4457
|
+
return parsed;
|
|
4458
|
+
}
|
|
4459
|
+
function terminalWebSocketIdFromRequest(request) {
|
|
4460
|
+
const pathname = new URL(request.url).pathname;
|
|
4461
|
+
const match = /^\/api\/terminal\/([^/]+)\/ws\/?$/.exec(pathname);
|
|
4462
|
+
if (!match?.[1]) throw new Response("Terminal WebSocket route not found.", { status: 404 });
|
|
4463
|
+
try {
|
|
4464
|
+
return decodeURIComponent(match[1]);
|
|
4465
|
+
} catch {
|
|
4466
|
+
throw new Response("Invalid terminal id.", { status: 400 });
|
|
4467
|
+
}
|
|
4468
|
+
}
|
|
4469
|
+
function terminalWebSocketCleanupFromPeer(peer) {
|
|
4470
|
+
const cleanup = peer.context.terminalCleanup;
|
|
4471
|
+
return typeof cleanup === "function" ? cleanup : void 0;
|
|
4472
|
+
}
|
|
4473
|
+
function terminalWebSocketContextFromPeer(peer) {
|
|
4474
|
+
const { terminalId, terminalLastSeq, terminalScopeKey } = peer.context;
|
|
4475
|
+
if (typeof terminalId !== "string" || !terminalId) throw new Error("Terminal WebSocket is missing a terminal id.");
|
|
4476
|
+
if (typeof terminalScopeKey !== "string" || !terminalScopeKey) throw new Error("Terminal WebSocket is missing a terminal scope.");
|
|
4477
|
+
return {
|
|
4478
|
+
terminalId,
|
|
4479
|
+
terminalLastSeq: typeof terminalLastSeq === "number" ? terminalLastSeq : void 0,
|
|
4480
|
+
terminalScopeKey
|
|
4481
|
+
};
|
|
4482
|
+
}
|
|
4249
4483
|
function normalizePromptDraftOwnerKey(value) {
|
|
4250
4484
|
if (typeof value !== "string") return "";
|
|
4251
4485
|
const ownerKey = value.trim();
|
|
@@ -4274,6 +4508,7 @@ var PicoRuntime = class {
|
|
|
4274
4508
|
encoder = new TextEncoder();
|
|
4275
4509
|
contexts = /* @__PURE__ */ new Map();
|
|
4276
4510
|
sessionEntries = /* @__PURE__ */ new Map();
|
|
4511
|
+
contextCleanupTimeout;
|
|
4277
4512
|
sessionTreeLeafOverrides = /* @__PURE__ */ new Map();
|
|
4278
4513
|
servicesByCwd = /* @__PURE__ */ new Map();
|
|
4279
4514
|
pendingUiRequests = /* @__PURE__ */ new Map();
|
|
@@ -4429,6 +4664,20 @@ var PicoRuntime = class {
|
|
|
4429
4664
|
});
|
|
4430
4665
|
});
|
|
4431
4666
|
}
|
|
4667
|
+
findPicoDefaultModel(entry) {
|
|
4668
|
+
return entry.services.modelRegistry.getAvailable().find((model) => model.provider === PICO_DEFAULT_MODEL_PROVIDER && model.id === PICO_DEFAULT_MODEL_ID);
|
|
4669
|
+
}
|
|
4670
|
+
async applyPicoDefaultSessionPreferences(entry) {
|
|
4671
|
+
const settingsManager = entry.services.settingsManager;
|
|
4672
|
+
const configuredProvider = settingsManager.getDefaultProvider?.()?.trim();
|
|
4673
|
+
const configuredModel = settingsManager.getDefaultModel?.()?.trim();
|
|
4674
|
+
const configuredThinkingLevel = settingsManager.getDefaultThinkingLevel?.()?.trim();
|
|
4675
|
+
if (!configuredProvider && !configuredModel) {
|
|
4676
|
+
const defaultModel = this.findPicoDefaultModel(entry);
|
|
4677
|
+
if (defaultModel && (entry.session.model?.provider !== defaultModel.provider || entry.session.model?.id !== defaultModel.id)) await entry.session.setModel(defaultModel);
|
|
4678
|
+
}
|
|
4679
|
+
if (!configuredThinkingLevel && entry.session.thinkingLevel !== PICO_DEFAULT_THINKING_LEVEL && entry.session.getAvailableThinkingLevels().includes(PICO_DEFAULT_THINKING_LEVEL)) entry.session.setThinkingLevel(PICO_DEFAULT_THINKING_LEVEL);
|
|
4680
|
+
}
|
|
4432
4681
|
listAvailableModels(entry) {
|
|
4433
4682
|
return entry.services.modelRegistry.getAvailable().flatMap((model) => {
|
|
4434
4683
|
const serializedModel = serializeModel(model);
|
|
@@ -4459,7 +4708,10 @@ var PicoRuntime = class {
|
|
|
4459
4708
|
draftKey: void 0,
|
|
4460
4709
|
sessionScope: process.cwd(),
|
|
4461
4710
|
unreadFinished: /* @__PURE__ */ new Set(),
|
|
4462
|
-
sidebarBootstrapDirectories: []
|
|
4711
|
+
sidebarBootstrapDirectories: [],
|
|
4712
|
+
nextSseEventId: 1,
|
|
4713
|
+
replayEvents: [],
|
|
4714
|
+
inactiveSince: void 0
|
|
4463
4715
|
};
|
|
4464
4716
|
this.contexts.set(id, next);
|
|
4465
4717
|
return next;
|
|
@@ -4521,11 +4773,27 @@ var PicoRuntime = class {
|
|
|
4521
4773
|
});
|
|
4522
4774
|
await Promise.all(candidates.map((entry) => this.disposeSessionEntry(entry)));
|
|
4523
4775
|
}
|
|
4776
|
+
scheduleInactiveContextCleanup() {
|
|
4777
|
+
if (this.contextCleanupTimeout) return;
|
|
4778
|
+
this.contextCleanupTimeout = setTimeout(() => {
|
|
4779
|
+
this.contextCleanupTimeout = void 0;
|
|
4780
|
+
this.cleanupInactiveContexts();
|
|
4781
|
+
}, CONTEXT_INACTIVE_GRACE_MS + 100);
|
|
4782
|
+
}
|
|
4524
4783
|
async cleanupInactiveContexts() {
|
|
4784
|
+
const now = performance.now();
|
|
4525
4785
|
for (const context of this.contexts.values()) {
|
|
4526
|
-
if (context.clients.size > 0)
|
|
4786
|
+
if (context.clients.size > 0) {
|
|
4787
|
+
context.inactiveSince = void 0;
|
|
4788
|
+
continue;
|
|
4789
|
+
}
|
|
4527
4790
|
const activeEntry = this.getActiveEntry(context);
|
|
4528
4791
|
if (activeEntry && this.isSessionBusyForDone(activeEntry)) continue;
|
|
4792
|
+
context.inactiveSince ??= now;
|
|
4793
|
+
if (now - context.inactiveSince < CONTEXT_INACTIVE_GRACE_MS) {
|
|
4794
|
+
this.scheduleInactiveContextCleanup();
|
|
4795
|
+
continue;
|
|
4796
|
+
}
|
|
4529
4797
|
this.contexts.delete(context.id);
|
|
4530
4798
|
}
|
|
4531
4799
|
this.syncGitWatchDirectories();
|
|
@@ -4568,6 +4836,49 @@ var PicoRuntime = class {
|
|
|
4568
4836
|
}
|
|
4569
4837
|
return lastValue;
|
|
4570
4838
|
}
|
|
4839
|
+
stateConversationItems(entry) {
|
|
4840
|
+
const branchableMessages = extractBranchableMessages(entry);
|
|
4841
|
+
const forkableMessages = branchableMessages.length === 0 ? extractForkableUserMessages(entry) : [];
|
|
4842
|
+
if (branchableMessages.length === 0 && forkableMessages.length === 0) return entry.retainedConversationItems;
|
|
4843
|
+
let branchableIndex = 0;
|
|
4844
|
+
let forkableIndex = 0;
|
|
4845
|
+
let changed = false;
|
|
4846
|
+
const nextBranchableMessage = (role) => {
|
|
4847
|
+
const matchedIndex = branchableMessages.findIndex((message, index) => index >= branchableIndex && message.role === role);
|
|
4848
|
+
if (matchedIndex < 0) return void 0;
|
|
4849
|
+
branchableIndex = matchedIndex + 1;
|
|
4850
|
+
return branchableMessages[matchedIndex];
|
|
4851
|
+
};
|
|
4852
|
+
const nextForkableUserEntryId = (text) => {
|
|
4853
|
+
const normalizedText = text.trim();
|
|
4854
|
+
if (!normalizedText) return void 0;
|
|
4855
|
+
const matchedIndex = forkableMessages.findIndex((message, index) => index >= forkableIndex && message.text.trim() === normalizedText);
|
|
4856
|
+
if (matchedIndex < 0) return void 0;
|
|
4857
|
+
forkableIndex = matchedIndex + 1;
|
|
4858
|
+
return forkableMessages[matchedIndex]?.entryId;
|
|
4859
|
+
};
|
|
4860
|
+
const items = entry.retainedConversationItems.map((item) => {
|
|
4861
|
+
if (item.kind === "user") {
|
|
4862
|
+
const entryId = nextBranchableMessage("user")?.entryId ?? nextForkableUserEntryId(item.text);
|
|
4863
|
+
if (!entryId || item.forkEntryId === entryId) return item;
|
|
4864
|
+
changed = true;
|
|
4865
|
+
return {
|
|
4866
|
+
...item,
|
|
4867
|
+
forkEntryId: entryId
|
|
4868
|
+
};
|
|
4869
|
+
}
|
|
4870
|
+
if (item.streaming) return item;
|
|
4871
|
+
const entryId = nextBranchableMessage("assistant")?.entryId;
|
|
4872
|
+
if (!entryId || item.branchEntryId === entryId) return item;
|
|
4873
|
+
changed = true;
|
|
4874
|
+
return {
|
|
4875
|
+
...item,
|
|
4876
|
+
branchEntryId: entryId
|
|
4877
|
+
};
|
|
4878
|
+
});
|
|
4879
|
+
if (changed) entry.retainedConversationItems = items;
|
|
4880
|
+
return entry.retainedConversationItems;
|
|
4881
|
+
}
|
|
4571
4882
|
currentStatePayload(entry, context) {
|
|
4572
4883
|
const draft = this.isDraftEntry(entry);
|
|
4573
4884
|
const historyTotalCount = entry.session.messages.length;
|
|
@@ -4575,7 +4886,7 @@ var PicoRuntime = class {
|
|
|
4575
4886
|
type: "state_sync",
|
|
4576
4887
|
activationRevision: context.activeRevision,
|
|
4577
4888
|
sessionKey: entry.key,
|
|
4578
|
-
items: entry
|
|
4889
|
+
items: this.stateConversationItems(entry),
|
|
4579
4890
|
pendingUserMessages: entry.pendingUserMessages.map((message) => clonePendingUserMessage(message)),
|
|
4580
4891
|
draft,
|
|
4581
4892
|
streaming: this.getEntryStreamingState(entry),
|
|
@@ -4873,8 +5184,32 @@ var PicoRuntime = class {
|
|
|
4873
5184
|
messages
|
|
4874
5185
|
};
|
|
4875
5186
|
}
|
|
5187
|
+
shouldReplayPayload(payload) {
|
|
5188
|
+
if (!payload || typeof payload !== "object") return false;
|
|
5189
|
+
const type = payload.type;
|
|
5190
|
+
return type === "session_done" || type === "request_error" || type === "extension_error" || type === "extension_ui_request" || type === "auto_session_naming_error" || type === "git_changed";
|
|
5191
|
+
}
|
|
5192
|
+
rememberReplayPayload(context, payload) {
|
|
5193
|
+
if (!this.shouldReplayPayload(payload)) return void 0;
|
|
5194
|
+
const eventId = context.nextSseEventId;
|
|
5195
|
+
context.nextSseEventId += 1;
|
|
5196
|
+
context.replayEvents.push({
|
|
5197
|
+
id: eventId,
|
|
5198
|
+
text: formatSsePayloadText(payload, { id: String(eventId) })
|
|
5199
|
+
});
|
|
5200
|
+
while (context.replayEvents.length > SSE_REPLAY_MAX_EVENTS) context.replayEvents.shift();
|
|
5201
|
+
return String(eventId);
|
|
5202
|
+
}
|
|
5203
|
+
replayEventsToClient(context, client, lastEventId) {
|
|
5204
|
+
if (lastEventId === void 0 || context.replayEvents.length === 0) return;
|
|
5205
|
+
for (const event of context.replayEvents) {
|
|
5206
|
+
if (event.id <= lastEventId) continue;
|
|
5207
|
+
this.writeRawToClient(context, client, event.text);
|
|
5208
|
+
}
|
|
5209
|
+
}
|
|
4876
5210
|
sendToContext(context, payload) {
|
|
4877
|
-
|
|
5211
|
+
const eventId = this.rememberReplayPayload(context, payload);
|
|
5212
|
+
for (const client of context.clients) this.sendPayloadToClient(context, client, payload, { eventId });
|
|
4878
5213
|
}
|
|
4879
5214
|
sendStatePayloadToClient(context, client, payload, options) {
|
|
4880
5215
|
const debug = isSessionLoadDebugEnabled();
|
|
@@ -5388,6 +5723,7 @@ var PicoRuntime = class {
|
|
|
5388
5723
|
retainedConversationItems: createRetainedConversationState(session.messages.map((message) => sanitizeSessionMessage(message))).items,
|
|
5389
5724
|
pendingUserMessages: [],
|
|
5390
5725
|
pendingQueueMutation: false,
|
|
5726
|
+
pausedPendingUserMessageIds: /* @__PURE__ */ new Set(),
|
|
5391
5727
|
canceledPendingUserMessageIds: /* @__PURE__ */ new Set(),
|
|
5392
5728
|
firstMessageHint: "",
|
|
5393
5729
|
modifiedAt: void 0,
|
|
@@ -5402,6 +5738,7 @@ var PicoRuntime = class {
|
|
|
5402
5738
|
disposed: false
|
|
5403
5739
|
},
|
|
5404
5740
|
promptRequestChain: Promise.resolve(),
|
|
5741
|
+
promptRequestRecords: /* @__PURE__ */ new Map(),
|
|
5405
5742
|
doneNotificationSuppressed: false
|
|
5406
5743
|
};
|
|
5407
5744
|
this.sessionEntries.set(key, entry);
|
|
@@ -5437,10 +5774,12 @@ var PicoRuntime = class {
|
|
|
5437
5774
|
async createNewSessionEntry(cwd, options) {
|
|
5438
5775
|
const sessionManager = (await this.getSdk()).SessionManager.create(cwd, options?.sessionDir);
|
|
5439
5776
|
if (options?.newSessionOptions && sessionManager.newSession) sessionManager.newSession(options.newSessionOptions);
|
|
5440
|
-
|
|
5777
|
+
const entry = await this.createSessionEntry(sessionManager, {
|
|
5441
5778
|
draft: options?.draft,
|
|
5442
5779
|
sessionStartEvent: options?.sessionStartEvent
|
|
5443
5780
|
});
|
|
5781
|
+
await this.applyPicoDefaultSessionPreferences(entry);
|
|
5782
|
+
return entry;
|
|
5444
5783
|
}
|
|
5445
5784
|
async ensureSessionEntryByPath(sessionPath) {
|
|
5446
5785
|
const existing = this.sessionEntries.get(sessionPath);
|
|
@@ -5570,6 +5909,18 @@ var PicoRuntime = class {
|
|
|
5570
5909
|
refinementReason: input.refinementReason
|
|
5571
5910
|
});
|
|
5572
5911
|
}
|
|
5912
|
+
applyHeuristicSessionNameAttempt(entry, text, imageCount) {
|
|
5913
|
+
const heuristic = deriveHeuristicSessionNameAttempt(text, imageCount);
|
|
5914
|
+
if (heuristic.name) this.applyManagedSessionName(entry, heuristic.name, "initial");
|
|
5915
|
+
return heuristic;
|
|
5916
|
+
}
|
|
5917
|
+
applySessionNameFallbackAfterRefinementFailure(entry, text, imageCount) {
|
|
5918
|
+
if (this.getCurrentSessionName(entry)) return true;
|
|
5919
|
+
if (this.applyHeuristicSessionNameAttempt(entry, text, imageCount).name && this.getCurrentSessionName(entry)) return true;
|
|
5920
|
+
const fallbackName = cleanupSessionNameCandidate(normalizeSessionListTitle(text, SESSION_NAME_MAX_LENGTH));
|
|
5921
|
+
if (!fallbackName) return false;
|
|
5922
|
+
return this.applyManagedSessionName(entry, fallbackName, "initial");
|
|
5923
|
+
}
|
|
5573
5924
|
scheduleSessionNameRefinement(entry, text, imageCount, heuristicReason) {
|
|
5574
5925
|
if (entry.sessionNaming.pendingGeneration) return;
|
|
5575
5926
|
entry.sessionNaming.pendingGeneration = true;
|
|
@@ -5579,10 +5930,11 @@ var PicoRuntime = class {
|
|
|
5579
5930
|
try {
|
|
5580
5931
|
const generated = await generateSessionNameWithLlm({
|
|
5581
5932
|
cwd: entry.cwd,
|
|
5933
|
+
model: entry.session.model,
|
|
5582
5934
|
services: { modelRegistry: entry.services.modelRegistry }
|
|
5583
5935
|
}, text, imageCount);
|
|
5584
5936
|
if (!generated?.name) {
|
|
5585
|
-
if (!entry.sessionNaming.disposed && entry.sessionNaming.nonce === nonce && sessionId === entry.session.sessionId && !this.
|
|
5937
|
+
if (!entry.sessionNaming.disposed && entry.sessionNaming.nonce === nonce && sessionId === entry.session.sessionId && !this.applySessionNameFallbackAfterRefinementFailure(entry, text, imageCount)) this.emitAutoSessionNamingFailure(entry, {
|
|
5586
5938
|
heuristicReason,
|
|
5587
5939
|
refinementReason: generated?.reason || "session name refinement returned no usable title",
|
|
5588
5940
|
text,
|
|
@@ -5593,7 +5945,7 @@ var PicoRuntime = class {
|
|
|
5593
5945
|
if (entry.sessionNaming.disposed || entry.sessionNaming.nonce !== nonce || sessionId !== entry.session.sessionId) return;
|
|
5594
5946
|
this.applyManagedSessionName(entry, generated.name, "refine");
|
|
5595
5947
|
} catch (error) {
|
|
5596
|
-
if (!entry.sessionNaming.disposed && entry.sessionNaming.nonce === nonce && sessionId === entry.session.sessionId && !this.
|
|
5948
|
+
if (!entry.sessionNaming.disposed && entry.sessionNaming.nonce === nonce && sessionId === entry.session.sessionId && !this.applySessionNameFallbackAfterRefinementFailure(entry, text, imageCount)) this.emitAutoSessionNamingFailure(entry, {
|
|
5597
5949
|
heuristicReason,
|
|
5598
5950
|
refinementReason: formatError(error),
|
|
5599
5951
|
text,
|
|
@@ -5606,21 +5958,28 @@ var PicoRuntime = class {
|
|
|
5606
5958
|
}
|
|
5607
5959
|
startAutoSessionNaming(entry, text, imageCount) {
|
|
5608
5960
|
if (this.getCurrentSessionName(entry)) return;
|
|
5609
|
-
const heuristic =
|
|
5610
|
-
if (heuristic.name) this.applyManagedSessionName(entry, heuristic.name, "initial");
|
|
5961
|
+
const heuristic = this.applyHeuristicSessionNameAttempt(entry, text, imageCount);
|
|
5611
5962
|
this.scheduleSessionNameRefinement(entry, text, imageCount, heuristic.reason);
|
|
5612
5963
|
}
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
for (const message of entry.session.messages) {
|
|
5964
|
+
getFirstPromptForNamingFromMessages(messages, firstMessageHint = "") {
|
|
5965
|
+
for (const message of messages) {
|
|
5616
5966
|
if (message?.role !== "user") continue;
|
|
5617
5967
|
const firstPrompt = summarizePromptContent(message.content);
|
|
5618
|
-
if (firstPrompt.text || firstPrompt.imageCount > 0)
|
|
5619
|
-
this.startAutoSessionNaming(entry, firstPrompt.text, firstPrompt.imageCount);
|
|
5620
|
-
return;
|
|
5621
|
-
}
|
|
5968
|
+
if (firstPrompt.text || firstPrompt.imageCount > 0) return firstPrompt;
|
|
5622
5969
|
}
|
|
5623
|
-
|
|
5970
|
+
const trimmedHint = firstMessageHint.trim();
|
|
5971
|
+
return trimmedHint ? {
|
|
5972
|
+
text: trimmedHint,
|
|
5973
|
+
imageCount: 0
|
|
5974
|
+
} : null;
|
|
5975
|
+
}
|
|
5976
|
+
getSessionFirstPromptForNaming(entry) {
|
|
5977
|
+
return this.getFirstPromptForNamingFromMessages(entry.session.messages, entry.firstMessageHint);
|
|
5978
|
+
}
|
|
5979
|
+
maybeAutoNameSession(entry) {
|
|
5980
|
+
if (this.getCurrentSessionName(entry)) return;
|
|
5981
|
+
const firstPrompt = this.getSessionFirstPromptForNaming(entry);
|
|
5982
|
+
if (firstPrompt) this.startAutoSessionNaming(entry, firstPrompt.text, firstPrompt.imageCount);
|
|
5624
5983
|
}
|
|
5625
5984
|
reconcilePendingUserMessages(entry, queueState) {
|
|
5626
5985
|
const nextQueueState = queueState ?? {
|
|
@@ -5629,7 +5988,10 @@ var PicoRuntime = class {
|
|
|
5629
5988
|
};
|
|
5630
5989
|
const steering = [...nextQueueState.steering].filter((text) => typeof text === "string");
|
|
5631
5990
|
const followUp = [...nextQueueState.followUp].filter((text) => typeof text === "string");
|
|
5632
|
-
const
|
|
5991
|
+
const allPending = entry.pendingUserMessages.map((message) => clonePendingUserMessage(message));
|
|
5992
|
+
const pausedPending = allPending.filter((message) => entry.pausedPendingUserMessageIds.has(message.pendingId));
|
|
5993
|
+
const pending = allPending.filter((message) => !entry.pausedPendingUserMessageIds.has(message.pendingId));
|
|
5994
|
+
entry.pausedPendingUserMessageIds = new Set(pausedPending.map((message) => message.pendingId));
|
|
5633
5995
|
const steeringCounts = /* @__PURE__ */ new Map();
|
|
5634
5996
|
const followUpCounts = /* @__PURE__ */ new Map();
|
|
5635
5997
|
for (const text of steering) steeringCounts.set(text, (steeringCounts.get(text) ?? 0) + 1);
|
|
@@ -5655,7 +6017,7 @@ var PicoRuntime = class {
|
|
|
5655
6017
|
nextPending.push(createPendingUserMessage(text, [], "followUp"));
|
|
5656
6018
|
followUpCounts.set(text, count - 1);
|
|
5657
6019
|
}
|
|
5658
|
-
entry.pendingUserMessages = sortPendingUserMessages(nextPending);
|
|
6020
|
+
entry.pendingUserMessages = sortPendingUserMessages([...pausedPending, ...nextPending]);
|
|
5659
6021
|
return entry.pendingUserMessages;
|
|
5660
6022
|
}
|
|
5661
6023
|
pendingMessagesFromClientUpdate(entry, pendingMessagesUpdate) {
|
|
@@ -5726,6 +6088,75 @@ var PicoRuntime = class {
|
|
|
5726
6088
|
await this.broadcastEntryState(entry);
|
|
5727
6089
|
return entry.pendingUserMessages;
|
|
5728
6090
|
}
|
|
6091
|
+
drainPendingUserMessagesWhenIdle(entry) {
|
|
6092
|
+
if (entry.pendingQueueDrainPromise) return entry.pendingQueueDrainPromise;
|
|
6093
|
+
const drainPromise = this.runSerializedPromptRequest(entry, async () => {
|
|
6094
|
+
if (this.getEntryStreamingState(entry) || entry.session.isStreaming || this.getEntryCompactingState(entry) || entry.session.isCompacting) return;
|
|
6095
|
+
const pendingMessages = sortPendingUserMessages(entry.pendingUserMessages.map((message) => clonePendingUserMessage(message)));
|
|
6096
|
+
const pendingMessage = pendingMessages[0];
|
|
6097
|
+
if (!pendingMessage) return;
|
|
6098
|
+
const remainingMessages = pendingMessages.slice(1);
|
|
6099
|
+
const message = pendingMessage.text;
|
|
6100
|
+
const images = normalizePromptImages(pendingMessage.images);
|
|
6101
|
+
if (!message.trim() && images.length === 0) {
|
|
6102
|
+
await this.replacePendingUserMessages(entry, remainingMessages);
|
|
6103
|
+
return;
|
|
6104
|
+
}
|
|
6105
|
+
entry.streamingState = true;
|
|
6106
|
+
this.markSessionUserMessage(entry);
|
|
6107
|
+
entry.pendingUserMessages = remainingMessages;
|
|
6108
|
+
await this.broadcastEntryState(entry);
|
|
6109
|
+
await this.broadcastSessionsAll();
|
|
6110
|
+
this.broadcastToViewers(entry.key, {
|
|
6111
|
+
type: "user_message",
|
|
6112
|
+
message,
|
|
6113
|
+
images,
|
|
6114
|
+
queued: false
|
|
6115
|
+
});
|
|
6116
|
+
let promptPreflightComplete;
|
|
6117
|
+
let promptPreflightSettled = false;
|
|
6118
|
+
const promptPreflight = new Promise((resolve) => {
|
|
6119
|
+
promptPreflightComplete = resolve;
|
|
6120
|
+
});
|
|
6121
|
+
const settlePromptPreflight = () => {
|
|
6122
|
+
if (promptPreflightSettled) return;
|
|
6123
|
+
promptPreflightSettled = true;
|
|
6124
|
+
promptPreflightComplete?.();
|
|
6125
|
+
};
|
|
6126
|
+
const promptOptions = images.length > 0 ? { images } : void 0;
|
|
6127
|
+
const promptPromise = entry.session.prompt(message, {
|
|
6128
|
+
...promptOptions,
|
|
6129
|
+
preflightResult: settlePromptPreflight
|
|
6130
|
+
});
|
|
6131
|
+
const finishPromptIfIdle = async () => {
|
|
6132
|
+
if (!entry.streamingState || entry.session.isStreaming) return;
|
|
6133
|
+
entry.streamingState = false;
|
|
6134
|
+
this.reconcilePendingUserMessages(entry);
|
|
6135
|
+
await this.broadcastEntryState(entry);
|
|
6136
|
+
await this.broadcastSessionsAll();
|
|
6137
|
+
};
|
|
6138
|
+
promptPromise.then(() => {}).catch(async (error) => {
|
|
6139
|
+
await finishPromptIfIdle();
|
|
6140
|
+
console.error("[pico] queued prompt error", error);
|
|
6141
|
+
this.broadcastToViewers(entry.key, {
|
|
6142
|
+
type: "request_error",
|
|
6143
|
+
scope: "prompt",
|
|
6144
|
+
message,
|
|
6145
|
+
error: formatError(error)
|
|
6146
|
+
});
|
|
6147
|
+
}).finally(() => {
|
|
6148
|
+
settlePromptPreflight();
|
|
6149
|
+
});
|
|
6150
|
+
await promptPreflight;
|
|
6151
|
+
if (remainingMessages.length > 0) await this.replacePendingUserMessages(entry, remainingMessages);
|
|
6152
|
+
});
|
|
6153
|
+
let trackedPromise = Promise.resolve();
|
|
6154
|
+
trackedPromise = drainPromise.finally(() => {
|
|
6155
|
+
if (entry.pendingQueueDrainPromise === trackedPromise) entry.pendingQueueDrainPromise = void 0;
|
|
6156
|
+
});
|
|
6157
|
+
entry.pendingQueueDrainPromise = trackedPromise;
|
|
6158
|
+
return trackedPromise;
|
|
6159
|
+
}
|
|
5729
6160
|
refreshRetainedConversationItems(entry) {
|
|
5730
6161
|
entry.retainedConversationItems = createRetainedConversationState(entry.session.messages.map((message) => sanitizeSessionMessage(message))).items;
|
|
5731
6162
|
}
|
|
@@ -5928,7 +6359,8 @@ var PicoRuntime = class {
|
|
|
5928
6359
|
const state = createRetainedConversationState(entry.session.messages.map((message) => sanitizeSessionMessage(message)));
|
|
5929
6360
|
const summary = result.summary;
|
|
5930
6361
|
const tokensBefore = result.tokensBefore;
|
|
5931
|
-
|
|
6362
|
+
const estimatedTokensAfter = result.estimatedTokensAfter;
|
|
6363
|
+
state.items = [...state.items, createCompactionSummaryItem(summary, tokensBefore, `compaction:live:${state.items.length}`, estimatedTokensAfter)];
|
|
5932
6364
|
entry.retainedConversationItems = state.items;
|
|
5933
6365
|
return;
|
|
5934
6366
|
}
|
|
@@ -5961,6 +6393,7 @@ var PicoRuntime = class {
|
|
|
5961
6393
|
followUp: Array.isArray(event.followUp) ? event.followUp : []
|
|
5962
6394
|
});
|
|
5963
6395
|
}
|
|
6396
|
+
if (type === "session_info_changed") this.touchSessionEntry(entry);
|
|
5964
6397
|
if (type === "message_end" && event.message?.role === "user") {
|
|
5965
6398
|
this.touchSessionEntry(entry);
|
|
5966
6399
|
this.reconcilePendingUserMessages(entry);
|
|
@@ -5973,6 +6406,7 @@ var PicoRuntime = class {
|
|
|
5973
6406
|
const willRetry = Boolean(event.willRetry);
|
|
5974
6407
|
if (compactionReason === "manual" && compactionSucceeded) this.scheduleSessionDoneCheck(entry, "manual_compaction");
|
|
5975
6408
|
else if (entry.pendingDoneReason === "agent" && !willRetry) this.scheduleSessionDoneCheck(entry, "agent", entry.pendingDoneOutcome ?? "success");
|
|
6409
|
+
this.drainPendingUserMessagesWhenIdle(entry);
|
|
5976
6410
|
}
|
|
5977
6411
|
if (type === "auto_retry_end") {
|
|
5978
6412
|
if (entry.pendingDoneReason === "agent" && event.success === false) this.scheduleSessionDoneCheck(entry, "agent", "error");
|
|
@@ -5991,7 +6425,7 @@ var PicoRuntime = class {
|
|
|
5991
6425
|
if (statusChanged) this.broadcastSessionStatusAll(entry);
|
|
5992
6426
|
this.rememberSessionTreeLeaf(entry, true);
|
|
5993
6427
|
await this.broadcastEntryState(entry);
|
|
5994
|
-
if (type === "agent_start" || type === "agent_end" || type === "message_end" || type === "compaction_end" || type === "queue_update") await this.broadcastSessionsAll();
|
|
6428
|
+
if (type === "agent_start" || type === "agent_end" || type === "message_end" || type === "compaction_end" || type === "queue_update" || type === "session_info_changed") await this.broadcastSessionsAll();
|
|
5995
6429
|
if (type === "agent_end" || type === "compaction_end") await this.cleanupInactiveContexts();
|
|
5996
6430
|
}
|
|
5997
6431
|
writeRawToClient(context, client, text) {
|
|
@@ -6003,12 +6437,14 @@ var PicoRuntime = class {
|
|
|
6003
6437
|
closeSseClient: (activeContext, activeClient) => this.closeSseClient(activeContext, activeClient)
|
|
6004
6438
|
});
|
|
6005
6439
|
}
|
|
6006
|
-
sendPayloadToClient(context, client, payload) {
|
|
6440
|
+
sendPayloadToClient(context, client, payload, options) {
|
|
6007
6441
|
return sendPayloadToClient({
|
|
6008
6442
|
encoder: this.encoder,
|
|
6009
6443
|
context,
|
|
6010
6444
|
client,
|
|
6011
6445
|
payload,
|
|
6446
|
+
eventId: options?.eventId,
|
|
6447
|
+
retry: options?.retry,
|
|
6012
6448
|
closeSseClient: (activeContext, activeClient) => this.closeSseClient(activeContext, activeClient)
|
|
6013
6449
|
});
|
|
6014
6450
|
}
|
|
@@ -6016,6 +6452,10 @@ var PicoRuntime = class {
|
|
|
6016
6452
|
if (client.closed) return;
|
|
6017
6453
|
client.closed = true;
|
|
6018
6454
|
context.clients.delete(client);
|
|
6455
|
+
if (context.clients.size === 0) {
|
|
6456
|
+
context.inactiveSince = performance.now();
|
|
6457
|
+
this.scheduleInactiveContextCleanup();
|
|
6458
|
+
}
|
|
6019
6459
|
this.syncGitWatchDirectories();
|
|
6020
6460
|
try {
|
|
6021
6461
|
client.controller.close();
|
|
@@ -6025,6 +6465,7 @@ var PicoRuntime = class {
|
|
|
6025
6465
|
const startedAt = performance.now();
|
|
6026
6466
|
const { url, context, activeEntry } = await this.resolveRequest(request, { preferActiveDraft: false });
|
|
6027
6467
|
context.sidebarBootstrapDirectories = normalizeRequestedDirectories(url.searchParams.getAll("sidebarDirectory"));
|
|
6468
|
+
const lastEventId = parsePositiveInteger(request.headers.get("last-event-id") || url.searchParams.get("lastEventId"));
|
|
6028
6469
|
this.logSessionLoadDebug("events_response:create", {
|
|
6029
6470
|
contextId: context.id,
|
|
6030
6471
|
sidebarBootstrapDirectoryCount: context.sidebarBootstrapDirectories.length,
|
|
@@ -6040,9 +6481,11 @@ var PicoRuntime = class {
|
|
|
6040
6481
|
controller,
|
|
6041
6482
|
lastStateSyncSnapshot: void 0
|
|
6042
6483
|
};
|
|
6484
|
+
context.inactiveSince = void 0;
|
|
6043
6485
|
context.clients.add(client);
|
|
6044
6486
|
this.syncGitWatchDirectories();
|
|
6045
|
-
this.writeRawToClient(context, client,
|
|
6487
|
+
this.writeRawToClient(context, client, `retry: ${SSE_RETRY_MS}\n: connected\n\n`);
|
|
6488
|
+
this.replayEventsToClient(context, client, lastEventId);
|
|
6046
6489
|
(async () => {
|
|
6047
6490
|
const bootstrapStartedAt = performance.now();
|
|
6048
6491
|
try {
|
|
@@ -6102,6 +6545,15 @@ var PicoRuntime = class {
|
|
|
6102
6545
|
release?.();
|
|
6103
6546
|
}
|
|
6104
6547
|
}
|
|
6548
|
+
prunePromptRequestRecords(entry) {
|
|
6549
|
+
const now = Date.now();
|
|
6550
|
+
for (const [requestId, record] of entry.promptRequestRecords) if (now - record.createdAt > PROMPT_IDEMPOTENCY_TTL_MS) entry.promptRequestRecords.delete(requestId);
|
|
6551
|
+
while (entry.promptRequestRecords.size > PROMPT_IDEMPOTENCY_MAX_RECORDS) {
|
|
6552
|
+
const oldestRequestId = entry.promptRequestRecords.keys().next().value;
|
|
6553
|
+
if (!oldestRequestId) break;
|
|
6554
|
+
entry.promptRequestRecords.delete(oldestRequestId);
|
|
6555
|
+
}
|
|
6556
|
+
}
|
|
6105
6557
|
async prompt(request, body) {
|
|
6106
6558
|
const url = new URL(request.url);
|
|
6107
6559
|
const requestedSessionKey = url.searchParams.get("sessionKey")?.trim() || "";
|
|
@@ -6140,104 +6592,132 @@ var PicoRuntime = class {
|
|
|
6140
6592
|
if (requestedThinkingLevel && !VALID_THINKING_LEVELS.has(requestedThinkingLevel)) throw new Error(`Invalid thinking level: ${requestedThinkingLevel || "(empty)"}`);
|
|
6141
6593
|
const streamingBehavior = body.streamingBehavior === "steer" ? "steer" : body.streamingBehavior === "followUp" ? "followUp" : void 0;
|
|
6142
6594
|
const clientPendingId = normalizeClientPendingId(body.pendingId);
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
|
|
6153
|
-
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
activeEntry.
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
|
|
6171
|
-
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6595
|
+
const clientRequestId = normalizeClientPromptRequestId(body.clientRequestId);
|
|
6596
|
+
const executePromptRequest = async () => {
|
|
6597
|
+
return await this.runSerializedPromptRequest(activeEntry, async () => {
|
|
6598
|
+
if (requestedThinkingLevel && activeEntry.session.thinkingLevel !== requestedThinkingLevel) activeEntry.session.setThinkingLevel(requestedThinkingLevel);
|
|
6599
|
+
const promptOptions = images.length > 0 ? { images } : void 0;
|
|
6600
|
+
const promotedDraft = this.isDraftEntry(activeEntry);
|
|
6601
|
+
const isAlreadyStreaming = this.getEntryStreamingState(activeEntry);
|
|
6602
|
+
const isCompactingOnly = !isAlreadyStreaming && Boolean(this.getEntryCompactingState(activeEntry) || activeEntry.session.isCompacting);
|
|
6603
|
+
const isAlreadyBusy = isAlreadyStreaming || isCompactingOnly;
|
|
6604
|
+
if (clientPendingId && activeEntry.canceledPendingUserMessageIds.delete(clientPendingId)) {
|
|
6605
|
+
await this.broadcastEntryState(activeEntry);
|
|
6606
|
+
return {
|
|
6607
|
+
ok: true,
|
|
6608
|
+
queued: isAlreadyBusy,
|
|
6609
|
+
pendingId: clientPendingId,
|
|
6610
|
+
canceled: true
|
|
6611
|
+
};
|
|
6612
|
+
}
|
|
6613
|
+
if (!this.getSessionFirstMessage(activeEntry)) {
|
|
6614
|
+
activeEntry.firstMessageHint = message.trim();
|
|
6615
|
+
this.startAutoSessionNaming(activeEntry, message.trim(), images.length);
|
|
6616
|
+
}
|
|
6617
|
+
if (activeEntry.uiState.editorText) activeEntry.uiState.editorText = "";
|
|
6618
|
+
if (isAlreadyBusy) {
|
|
6619
|
+
const queuedStreamingBehavior = streamingBehavior ?? "steer";
|
|
6620
|
+
const pendingMessage = createPendingUserMessage(message, images, queuedStreamingBehavior, clientPendingId);
|
|
6621
|
+
this.markSessionUserMessage(activeEntry);
|
|
6622
|
+
activeEntry.canceledPendingUserMessageIds.delete(pendingMessage.pendingId);
|
|
6623
|
+
activeEntry.pendingUserMessages.push(pendingMessage);
|
|
6624
|
+
activeEntry.pendingUserMessages = sortPendingUserMessages(activeEntry.pendingUserMessages);
|
|
6625
|
+
await this.broadcastEntryState(activeEntry);
|
|
6626
|
+
if (isCompactingOnly) {
|
|
6627
|
+
await this.broadcastSessionsAll();
|
|
6628
|
+
return {
|
|
6629
|
+
ok: true,
|
|
6630
|
+
queued: true,
|
|
6631
|
+
pendingId: pendingMessage.pendingId
|
|
6632
|
+
};
|
|
6633
|
+
}
|
|
6634
|
+
try {
|
|
6635
|
+
await activeEntry.session.prompt(message, {
|
|
6636
|
+
...promptOptions,
|
|
6637
|
+
streamingBehavior: queuedStreamingBehavior
|
|
6638
|
+
});
|
|
6639
|
+
} catch (error) {
|
|
6640
|
+
activeEntry.pendingUserMessages = activeEntry.pendingUserMessages.filter((entry) => entry.pendingId !== pendingMessage.pendingId);
|
|
6641
|
+
this.reconcilePendingUserMessages(activeEntry);
|
|
6642
|
+
await this.broadcastEntryState(activeEntry);
|
|
6643
|
+
throw error;
|
|
6644
|
+
}
|
|
6175
6645
|
this.reconcilePendingUserMessages(activeEntry);
|
|
6176
6646
|
await this.broadcastEntryState(activeEntry);
|
|
6177
|
-
|
|
6647
|
+
await this.broadcastSessionsAll();
|
|
6648
|
+
return {
|
|
6649
|
+
ok: true,
|
|
6650
|
+
queued: true,
|
|
6651
|
+
pendingId: pendingMessage.pendingId
|
|
6652
|
+
};
|
|
6653
|
+
}
|
|
6654
|
+
activeEntry.streamingState = true;
|
|
6655
|
+
this.markSessionUserMessage(activeEntry);
|
|
6656
|
+
if (promotedDraft) {
|
|
6657
|
+
activeEntry.draft = false;
|
|
6658
|
+
if (context.draftKey === activeEntry.key) context.draftKey = void 0;
|
|
6659
|
+
await this.broadcastEntryState(activeEntry);
|
|
6660
|
+
await this.broadcastSessionsAll();
|
|
6178
6661
|
}
|
|
6179
|
-
this.reconcilePendingUserMessages(activeEntry);
|
|
6180
|
-
await this.broadcastEntryState(activeEntry);
|
|
6181
|
-
await this.broadcastSessionsAll();
|
|
6182
|
-
return {
|
|
6183
|
-
ok: true,
|
|
6184
|
-
queued: true,
|
|
6185
|
-
pendingId: pendingMessage.pendingId
|
|
6186
|
-
};
|
|
6187
|
-
}
|
|
6188
|
-
activeEntry.streamingState = true;
|
|
6189
|
-
this.markSessionUserMessage(activeEntry);
|
|
6190
|
-
if (promotedDraft) {
|
|
6191
|
-
activeEntry.draft = false;
|
|
6192
|
-
if (context.draftKey === activeEntry.key) context.draftKey = void 0;
|
|
6193
|
-
await this.broadcastEntryState(activeEntry);
|
|
6194
|
-
await this.broadcastSessionsAll();
|
|
6195
|
-
}
|
|
6196
|
-
this.broadcastToViewers(activeEntry.key, {
|
|
6197
|
-
type: "user_message",
|
|
6198
|
-
message,
|
|
6199
|
-
images,
|
|
6200
|
-
queued: false
|
|
6201
|
-
});
|
|
6202
|
-
let promptPreflightComplete;
|
|
6203
|
-
let promptPreflightSettled = false;
|
|
6204
|
-
const promptPreflight = new Promise((resolve) => {
|
|
6205
|
-
promptPreflightComplete = resolve;
|
|
6206
|
-
});
|
|
6207
|
-
const settlePromptPreflight = () => {
|
|
6208
|
-
if (promptPreflightSettled) return;
|
|
6209
|
-
promptPreflightSettled = true;
|
|
6210
|
-
promptPreflightComplete?.();
|
|
6211
|
-
};
|
|
6212
|
-
const promptPromise = activeEntry.session.prompt(message, {
|
|
6213
|
-
...promptOptions,
|
|
6214
|
-
preflightResult: settlePromptPreflight
|
|
6215
|
-
});
|
|
6216
|
-
const finishPromptIfIdle = async () => {
|
|
6217
|
-
if (!activeEntry.streamingState || activeEntry.session.isStreaming) return;
|
|
6218
|
-
activeEntry.streamingState = false;
|
|
6219
|
-
this.reconcilePendingUserMessages(activeEntry);
|
|
6220
|
-
await this.broadcastEntryState(activeEntry);
|
|
6221
|
-
await this.broadcastSessionsAll();
|
|
6222
|
-
};
|
|
6223
|
-
promptPromise.then(() => {}).catch(async (error) => {
|
|
6224
|
-
await finishPromptIfIdle();
|
|
6225
|
-
console.error("[pico] prompt error", error);
|
|
6226
6662
|
this.broadcastToViewers(activeEntry.key, {
|
|
6227
|
-
type: "
|
|
6228
|
-
scope: "prompt",
|
|
6663
|
+
type: "user_message",
|
|
6229
6664
|
message,
|
|
6230
|
-
|
|
6665
|
+
images,
|
|
6666
|
+
queued: false
|
|
6231
6667
|
});
|
|
6232
|
-
|
|
6233
|
-
|
|
6668
|
+
let promptPreflightComplete;
|
|
6669
|
+
let promptPreflightSettled = false;
|
|
6670
|
+
const promptPreflight = new Promise((resolve) => {
|
|
6671
|
+
promptPreflightComplete = resolve;
|
|
6672
|
+
});
|
|
6673
|
+
const settlePromptPreflight = () => {
|
|
6674
|
+
if (promptPreflightSettled) return;
|
|
6675
|
+
promptPreflightSettled = true;
|
|
6676
|
+
promptPreflightComplete?.();
|
|
6677
|
+
};
|
|
6678
|
+
const promptPromise = activeEntry.session.prompt(message, {
|
|
6679
|
+
...promptOptions,
|
|
6680
|
+
preflightResult: settlePromptPreflight
|
|
6681
|
+
});
|
|
6682
|
+
const finishPromptIfIdle = async () => {
|
|
6683
|
+
if (!activeEntry.streamingState || activeEntry.session.isStreaming) return;
|
|
6684
|
+
activeEntry.streamingState = false;
|
|
6685
|
+
this.reconcilePendingUserMessages(activeEntry);
|
|
6686
|
+
await this.broadcastEntryState(activeEntry);
|
|
6687
|
+
await this.broadcastSessionsAll();
|
|
6688
|
+
};
|
|
6689
|
+
promptPromise.then(() => {}).catch(async (error) => {
|
|
6690
|
+
await finishPromptIfIdle();
|
|
6691
|
+
console.error("[pico] prompt error", error);
|
|
6692
|
+
this.broadcastToViewers(activeEntry.key, {
|
|
6693
|
+
type: "request_error",
|
|
6694
|
+
scope: "prompt",
|
|
6695
|
+
message,
|
|
6696
|
+
error: formatError(error)
|
|
6697
|
+
});
|
|
6698
|
+
}).finally(() => {
|
|
6699
|
+
settlePromptPreflight();
|
|
6700
|
+
});
|
|
6701
|
+
await promptPreflight;
|
|
6702
|
+
return {
|
|
6703
|
+
ok: true,
|
|
6704
|
+
queued: false
|
|
6705
|
+
};
|
|
6234
6706
|
});
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6707
|
+
};
|
|
6708
|
+
if (!clientRequestId) return await executePromptRequest();
|
|
6709
|
+
const existingRequest = activeEntry.promptRequestRecords.get(clientRequestId);
|
|
6710
|
+
if (existingRequest) return await existingRequest.promise;
|
|
6711
|
+
this.prunePromptRequestRecords(activeEntry);
|
|
6712
|
+
const promptPromise = executePromptRequest().catch((error) => {
|
|
6713
|
+
activeEntry.promptRequestRecords.delete(clientRequestId);
|
|
6714
|
+
throw error;
|
|
6240
6715
|
});
|
|
6716
|
+
activeEntry.promptRequestRecords.set(clientRequestId, {
|
|
6717
|
+
createdAt: Date.now(),
|
|
6718
|
+
promise: promptPromise
|
|
6719
|
+
});
|
|
6720
|
+
return await promptPromise;
|
|
6241
6721
|
}
|
|
6242
6722
|
async reorderPendingMessages(request, body) {
|
|
6243
6723
|
const { activeEntry } = await this.resolveRequest(request);
|
|
@@ -6274,6 +6754,7 @@ var PicoRuntime = class {
|
|
|
6274
6754
|
throw new Error("Pending prompt not found");
|
|
6275
6755
|
}
|
|
6276
6756
|
activeEntry.canceledPendingUserMessageIds.delete(pendingId);
|
|
6757
|
+
activeEntry.pausedPendingUserMessageIds.delete(pendingId);
|
|
6277
6758
|
pendingMessages.splice(pendingIndex, 1);
|
|
6278
6759
|
await this.replacePendingUserMessages(activeEntry, pendingMessages);
|
|
6279
6760
|
return {
|
|
@@ -6281,13 +6762,42 @@ var PicoRuntime = class {
|
|
|
6281
6762
|
pendingId
|
|
6282
6763
|
};
|
|
6283
6764
|
}
|
|
6765
|
+
async startPendingQueue(request) {
|
|
6766
|
+
const { activeEntry } = await this.resolveRequest(request);
|
|
6767
|
+
if (activeEntry.pendingUserMessages.length === 0) return {
|
|
6768
|
+
ok: true,
|
|
6769
|
+
pendingMessages: []
|
|
6770
|
+
};
|
|
6771
|
+
if (this.getEntryStreamingState(activeEntry) || activeEntry.session.isStreaming || this.getEntryCompactingState(activeEntry) || activeEntry.session.isCompacting) throw new Error("Wait for the current response to finish before starting the queue.");
|
|
6772
|
+
activeEntry.pausedPendingUserMessageIds.clear();
|
|
6773
|
+
await this.drainPendingUserMessagesWhenIdle(activeEntry);
|
|
6774
|
+
return {
|
|
6775
|
+
ok: true,
|
|
6776
|
+
pendingMessages: activeEntry.pendingUserMessages.map((message) => ({
|
|
6777
|
+
pendingId: message.pendingId,
|
|
6778
|
+
text: message.text,
|
|
6779
|
+
images: message.images,
|
|
6780
|
+
streamingBehavior: message.streamingBehavior
|
|
6781
|
+
}))
|
|
6782
|
+
};
|
|
6783
|
+
}
|
|
6284
6784
|
async abort(request) {
|
|
6285
6785
|
const { activeEntry } = await this.resolveRequest(request);
|
|
6286
6786
|
activeEntry.doneNotificationSuppressed = true;
|
|
6287
6787
|
this.clearPendingSessionDone(activeEntry);
|
|
6788
|
+
const pendingMessages = activeEntry.pendingUserMessages.map((message) => clonePendingUserMessage(message));
|
|
6789
|
+
if (pendingMessages.length > 0) for (const message of pendingMessages) activeEntry.pausedPendingUserMessageIds.add(message.pendingId);
|
|
6790
|
+
activeEntry.pendingQueueMutation = true;
|
|
6791
|
+
try {
|
|
6792
|
+
activeEntry.session.clearQueue?.();
|
|
6793
|
+
activeEntry.pendingUserMessages = pendingMessages;
|
|
6794
|
+
} finally {
|
|
6795
|
+
activeEntry.pendingQueueMutation = false;
|
|
6796
|
+
}
|
|
6288
6797
|
activeEntry.session.abortCompaction?.();
|
|
6289
6798
|
activeEntry.session.abortBranchSummary?.();
|
|
6290
6799
|
await activeEntry.session.abort();
|
|
6800
|
+
await this.broadcastEntryState(activeEntry);
|
|
6291
6801
|
return { ok: true };
|
|
6292
6802
|
}
|
|
6293
6803
|
async createNewSession(request, body) {
|
|
@@ -6398,7 +6908,8 @@ var PicoRuntime = class {
|
|
|
6398
6908
|
return {
|
|
6399
6909
|
ok: true,
|
|
6400
6910
|
model: serializeModel(activeEntry.session.model),
|
|
6401
|
-
thinkingLevel: activeEntry.session.thinkingLevel
|
|
6911
|
+
thinkingLevel: activeEntry.session.thinkingLevel,
|
|
6912
|
+
availableThinkingLevels: activeEntry.session.getAvailableThinkingLevels()
|
|
6402
6913
|
};
|
|
6403
6914
|
}
|
|
6404
6915
|
async setThinking(request, body) {
|
|
@@ -6566,13 +7077,18 @@ var PicoRuntime = class {
|
|
|
6566
7077
|
const { context, activeEntry } = await this.resolveRequest(request);
|
|
6567
7078
|
const entryId = typeof body.entryId === "string" ? body.entryId.trim() : "";
|
|
6568
7079
|
if (!entryId) throw new Error("entryId is required");
|
|
7080
|
+
const forkPosition = body.position === "at" ? "at" : "before";
|
|
7081
|
+
const isEditFork = forkPosition === "before";
|
|
6569
7082
|
const currentManager = activeEntry.session.sessionManager;
|
|
6570
7083
|
const selectedEntry = currentManager.getEntry?.(entryId);
|
|
6571
7084
|
const selectedParentId = typeof selectedEntry?.parentId === "string" ? selectedEntry.parentId : void 0;
|
|
6572
|
-
|
|
6573
|
-
|
|
7085
|
+
const selectedRole = typeof selectedEntry?.message?.role === "string" ? selectedEntry.message.role : "";
|
|
7086
|
+
if (!selectedEntry || selectedEntry.type !== "message" || (isEditFork ? selectedRole !== "user" : selectedRole !== "assistant")) throw new Error("Invalid entry ID for forking");
|
|
7087
|
+
const selectedText = isEditFork ? extractMessageText(selectedEntry.message) : "";
|
|
6574
7088
|
const previousSessionFile = activeEntry.session.sessionFile;
|
|
6575
7089
|
const sourceSessionDir = currentManager.getSessionDir?.();
|
|
7090
|
+
const forkLeafId = isEditFork ? selectedParentId : entryId;
|
|
7091
|
+
const draft = isEditFork ? !selectedParentId : false;
|
|
6576
7092
|
let nextEntry;
|
|
6577
7093
|
if (currentManager.isPersisted?.()) {
|
|
6578
7094
|
const sdk = await this.getSdk();
|
|
@@ -6581,7 +7097,7 @@ var PicoRuntime = class {
|
|
|
6581
7097
|
const sourceManager = sdk.SessionManager.open(currentSessionFile, sourceSessionDir, activeEntry.cwd);
|
|
6582
7098
|
const runtime = await this.createSessionRuntime(sourceManager);
|
|
6583
7099
|
try {
|
|
6584
|
-
const result = await runtime.fork(entryId, { position:
|
|
7100
|
+
const result = await runtime.fork(entryId, { position: forkPosition });
|
|
6585
7101
|
if (result.cancelled) {
|
|
6586
7102
|
await runtime.dispose();
|
|
6587
7103
|
return {
|
|
@@ -6589,8 +7105,8 @@ var PicoRuntime = class {
|
|
|
6589
7105
|
cancelled: true
|
|
6590
7106
|
};
|
|
6591
7107
|
}
|
|
6592
|
-
nextEntry = await this.createSessionEntryFromRuntime(runtime, { draft
|
|
6593
|
-
if (result.selectedText) nextEntry.uiState.editorText = result.selectedText;
|
|
7108
|
+
nextEntry = await this.createSessionEntryFromRuntime(runtime, { draft });
|
|
7109
|
+
if (isEditFork && result.selectedText) nextEntry.uiState.editorText = result.selectedText;
|
|
6594
7110
|
} catch (error) {
|
|
6595
7111
|
await runtime.dispose().catch(() => {});
|
|
6596
7112
|
throw error;
|
|
@@ -6601,30 +7117,102 @@ var PicoRuntime = class {
|
|
|
6601
7117
|
reason: "fork",
|
|
6602
7118
|
previousSessionFile
|
|
6603
7119
|
};
|
|
6604
|
-
const sessionManager = await this.createForkedInMemorySessionManager(currentManager,
|
|
7120
|
+
const sessionManager = await this.createForkedInMemorySessionManager(currentManager, forkLeafId, previousSessionFile);
|
|
6605
7121
|
nextEntry = await this.createSessionEntry(sessionManager, {
|
|
6606
|
-
draft
|
|
7122
|
+
draft,
|
|
6607
7123
|
sessionStartEvent
|
|
6608
7124
|
});
|
|
6609
7125
|
}
|
|
6610
|
-
if (!nextEntry.uiState.editorText) nextEntry.uiState.editorText = selectedText;
|
|
7126
|
+
if (isEditFork && !nextEntry.uiState.editorText) nextEntry.uiState.editorText = selectedText;
|
|
6611
7127
|
const baseName = cleanupSessionNameCandidate(activeEntry.session.sessionName) || getSessionListTitle({
|
|
6612
7128
|
name: activeEntry.session.sessionName,
|
|
6613
7129
|
firstMessage: this.getSessionFirstMessage(activeEntry)
|
|
6614
7130
|
});
|
|
6615
|
-
if (baseName) nextEntry.session.setSessionName(clampSessionNameLength(`${baseName} fork`));
|
|
6616
|
-
|
|
6617
|
-
|
|
7131
|
+
if (baseName) nextEntry.session.setSessionName(clampSessionNameLength(`${baseName} ${isEditFork ? "fork" : "branch"}`));
|
|
7132
|
+
if (isEditFork) {
|
|
7133
|
+
nextEntry.uiState.editorText = selectedText;
|
|
7134
|
+
if (!selectedParentId) nextEntry.firstMessageHint = selectedText;
|
|
7135
|
+
} else nextEntry.uiState.editorText = "";
|
|
6618
7136
|
this.touchSessionEntry(nextEntry);
|
|
6619
7137
|
await this.activateContextSession(context, nextEntry);
|
|
6620
7138
|
await this.broadcastSessionsAll();
|
|
6621
7139
|
return {
|
|
6622
7140
|
ok: true,
|
|
6623
7141
|
draft: this.isDraftEntry(nextEntry),
|
|
7142
|
+
sessionKey: nextEntry.key,
|
|
6624
7143
|
sessionId: nextEntry.session.sessionId,
|
|
6625
7144
|
sessionFile: nextEntry.session.sessionFile
|
|
6626
7145
|
};
|
|
6627
7146
|
}
|
|
7147
|
+
async generateSessionName(request, body) {
|
|
7148
|
+
const sessionPath = typeof body.path === "string" ? body.path.trim() : "";
|
|
7149
|
+
let source;
|
|
7150
|
+
let temporaryRuntime;
|
|
7151
|
+
try {
|
|
7152
|
+
if (sessionPath) {
|
|
7153
|
+
const targetEntry = this.sessionEntries.get(sessionPath);
|
|
7154
|
+
if (targetEntry) {
|
|
7155
|
+
const firstPrompt = this.getSessionFirstPromptForNaming(targetEntry);
|
|
7156
|
+
if (firstPrompt) source = {
|
|
7157
|
+
cwd: targetEntry.cwd,
|
|
7158
|
+
model: targetEntry.session.model,
|
|
7159
|
+
modelRegistry: targetEntry.services.modelRegistry,
|
|
7160
|
+
firstPrompt
|
|
7161
|
+
};
|
|
7162
|
+
} else {
|
|
7163
|
+
const sessionManager = (await this.getSdk()).SessionManager.open(sessionPath);
|
|
7164
|
+
this.restoreSessionTreeLeafOverride(sessionManager, sessionPath);
|
|
7165
|
+
temporaryRuntime = await this.createSessionRuntime(sessionManager);
|
|
7166
|
+
const firstPrompt = this.getFirstPromptForNamingFromMessages(temporaryRuntime.session.messages);
|
|
7167
|
+
if (firstPrompt) source = {
|
|
7168
|
+
cwd: temporaryRuntime.cwd,
|
|
7169
|
+
model: temporaryRuntime.session.model,
|
|
7170
|
+
modelRegistry: temporaryRuntime.services.modelRegistry,
|
|
7171
|
+
firstPrompt
|
|
7172
|
+
};
|
|
7173
|
+
}
|
|
7174
|
+
} else {
|
|
7175
|
+
const { activeEntry } = await this.resolveRequest(request);
|
|
7176
|
+
const firstPrompt = this.getSessionFirstPromptForNaming(activeEntry);
|
|
7177
|
+
if (firstPrompt) source = {
|
|
7178
|
+
cwd: activeEntry.cwd,
|
|
7179
|
+
model: activeEntry.session.model,
|
|
7180
|
+
modelRegistry: activeEntry.services.modelRegistry,
|
|
7181
|
+
firstPrompt
|
|
7182
|
+
};
|
|
7183
|
+
}
|
|
7184
|
+
if (!source) throw new Error("Session has no user message to name from");
|
|
7185
|
+
const heuristic = deriveHeuristicSessionNameAttempt(source.firstPrompt.text, source.firstPrompt.imageCount);
|
|
7186
|
+
const generated = await generateSessionNameWithLlm({
|
|
7187
|
+
cwd: source.cwd,
|
|
7188
|
+
model: source.model,
|
|
7189
|
+
services: { modelRegistry: source.modelRegistry }
|
|
7190
|
+
}, source.firstPrompt.text, source.firstPrompt.imageCount);
|
|
7191
|
+
if (generated.name) return {
|
|
7192
|
+
ok: true,
|
|
7193
|
+
name: clampSessionNameLength(generated.name),
|
|
7194
|
+
source: "llm"
|
|
7195
|
+
};
|
|
7196
|
+
if (heuristic.name) return {
|
|
7197
|
+
ok: true,
|
|
7198
|
+
name: clampSessionNameLength(heuristic.name),
|
|
7199
|
+
source: "heuristic",
|
|
7200
|
+
reason: generated.reason || heuristic.reason
|
|
7201
|
+
};
|
|
7202
|
+
const fallbackName = cleanupSessionNameCandidate(normalizeSessionListTitle(source.firstPrompt.text, SESSION_NAME_MAX_LENGTH));
|
|
7203
|
+
if (fallbackName) return {
|
|
7204
|
+
ok: true,
|
|
7205
|
+
name: clampSessionNameLength(fallbackName),
|
|
7206
|
+
source: "heuristic",
|
|
7207
|
+
reason: generated.reason || heuristic.reason
|
|
7208
|
+
};
|
|
7209
|
+
throw new Error(generated.reason || heuristic.reason || "Could not generate a session name from the first user message");
|
|
7210
|
+
} finally {
|
|
7211
|
+
await temporaryRuntime?.dispose().catch((error) => {
|
|
7212
|
+
console.error("[pico] temporary session dispose error:", error);
|
|
7213
|
+
});
|
|
7214
|
+
}
|
|
7215
|
+
}
|
|
6628
7216
|
async renameSession(body) {
|
|
6629
7217
|
const sessionPath = typeof body.path === "string" ? body.path : "";
|
|
6630
7218
|
const nextName = typeof body.name === "string" ? body.name.trim() : "";
|
|
@@ -6864,6 +7452,7 @@ var PicoRuntime = class {
|
|
|
6864
7452
|
}
|
|
6865
7453
|
async getAuthProviders(request) {
|
|
6866
7454
|
const { activeEntry } = await this.resolveRequest(request);
|
|
7455
|
+
this.refreshModelRegistries();
|
|
6867
7456
|
const modelRegistry = activeEntry.services.modelRegistry;
|
|
6868
7457
|
const authStorage = this.requireAuthStorage(activeEntry);
|
|
6869
7458
|
const oauthProviders = authStorage.getOAuthProviders();
|
|
@@ -6908,7 +7497,8 @@ var PicoRuntime = class {
|
|
|
6908
7497
|
...authStatus(providerId),
|
|
6909
7498
|
configured: true
|
|
6910
7499
|
};
|
|
6911
|
-
}).sort((left, right) => left.name.localeCompare(right.name))
|
|
7500
|
+
}).sort((left, right) => left.name.localeCompare(right.name)),
|
|
7501
|
+
availableModels: this.listAvailableModels(activeEntry)
|
|
6912
7502
|
};
|
|
6913
7503
|
}
|
|
6914
7504
|
async saveProviderApiKey(request, body) {
|
|
@@ -7077,6 +7667,7 @@ var PicoRuntime = class {
|
|
|
7077
7667
|
activeEntry.compactingState = false;
|
|
7078
7668
|
await this.broadcastEntryState(activeEntry);
|
|
7079
7669
|
await this.broadcastSessionsAll();
|
|
7670
|
+
this.drainPendingUserMessagesWhenIdle(activeEntry);
|
|
7080
7671
|
}
|
|
7081
7672
|
}
|
|
7082
7673
|
async resolveUiRequest(id, body) {
|
|
@@ -7098,11 +7689,52 @@ var PicoRuntime = class {
|
|
|
7098
7689
|
}
|
|
7099
7690
|
async createTerminalEventsResponse(request, id) {
|
|
7100
7691
|
const { context, activeEntry } = await this.resolveRequest(request);
|
|
7101
|
-
|
|
7692
|
+
const lastSeq = parsePositiveInteger(request.headers.get("last-event-id") || new URL(request.url).searchParams.get("lastSeq"));
|
|
7693
|
+
return this.terminalManager.createEventsResponse(id, this.getTerminalScopeKey(activeEntry, context), request.signal, lastSeq);
|
|
7694
|
+
}
|
|
7695
|
+
async createTerminalWebSocketContext(request) {
|
|
7696
|
+
try {
|
|
7697
|
+
const id = terminalWebSocketIdFromRequest(request);
|
|
7698
|
+
const { context, activeEntry } = await this.resolveRequest(request);
|
|
7699
|
+
const scopeKey = this.getTerminalScopeKey(activeEntry, context);
|
|
7700
|
+
const lastSeq = parsePositiveInteger(request.headers.get("last-event-id") || new URL(request.url).searchParams.get("lastSeq"));
|
|
7701
|
+
this.terminalManager.validateTerminal(id, scopeKey);
|
|
7702
|
+
return {
|
|
7703
|
+
terminalId: id,
|
|
7704
|
+
terminalLastSeq: lastSeq,
|
|
7705
|
+
terminalScopeKey: scopeKey
|
|
7706
|
+
};
|
|
7707
|
+
} catch (error) {
|
|
7708
|
+
if (error instanceof Response) throw error;
|
|
7709
|
+
throw new Response(safeErrorMessage(error), { status: 400 });
|
|
7710
|
+
}
|
|
7711
|
+
}
|
|
7712
|
+
openTerminalWebSocket(peer) {
|
|
7713
|
+
const context = terminalWebSocketContextFromPeer(peer);
|
|
7714
|
+
const cleanup = this.terminalManager.connectWebSocket({
|
|
7715
|
+
id: context.terminalId,
|
|
7716
|
+
lastSeq: context.terminalLastSeq,
|
|
7717
|
+
peer,
|
|
7718
|
+
scopeKey: context.terminalScopeKey
|
|
7719
|
+
});
|
|
7720
|
+
peer.context.terminalCleanup = cleanup;
|
|
7721
|
+
}
|
|
7722
|
+
handleTerminalWebSocketMessage(peer, message) {
|
|
7723
|
+
const context = terminalWebSocketContextFromPeer(peer);
|
|
7724
|
+
this.terminalManager.handleWebSocketMessage({
|
|
7725
|
+
id: context.terminalId,
|
|
7726
|
+
message,
|
|
7727
|
+
peer,
|
|
7728
|
+
scopeKey: context.terminalScopeKey
|
|
7729
|
+
});
|
|
7730
|
+
}
|
|
7731
|
+
closeTerminalWebSocket(peer) {
|
|
7732
|
+
terminalWebSocketCleanupFromPeer(peer)?.();
|
|
7733
|
+
delete peer.context.terminalCleanup;
|
|
7102
7734
|
}
|
|
7103
7735
|
async writeTerminalInput(request, id, body) {
|
|
7104
7736
|
const { context, activeEntry } = await this.resolveRequest(request);
|
|
7105
|
-
this.terminalManager.writeTerminal(id, this.getTerminalScopeKey(activeEntry, context), body.data);
|
|
7737
|
+
this.terminalManager.writeTerminal(id, this.getTerminalScopeKey(activeEntry, context), body.data, body.inputSeq);
|
|
7106
7738
|
return { ok: true };
|
|
7107
7739
|
}
|
|
7108
7740
|
async resizeTerminal(request, id, body) {
|
|
@@ -7180,7 +7812,7 @@ function getPicoRuntime() {
|
|
|
7180
7812
|
globalThis.__picoRuntime ??= new PicoRuntime();
|
|
7181
7813
|
return globalThis.__picoRuntime;
|
|
7182
7814
|
}
|
|
7183
|
-
var Route$
|
|
7815
|
+
var Route$60 = createFileRoute("/events")({ server: { handlers: { GET: ({ request }) => getPicoRuntime().createEventsResponse(request) } } });
|
|
7184
7816
|
function jsonResponse(data, init = 200) {
|
|
7185
7817
|
const responseInit = typeof init === "number" ? { status: init } : init;
|
|
7186
7818
|
const headers = new Headers(responseInit.headers);
|
|
@@ -7216,7 +7848,7 @@ function routeErrorResponse(error, fallbackMessage) {
|
|
|
7216
7848
|
async function readRequestJson(request) {
|
|
7217
7849
|
return await request.json().catch(() => ({}));
|
|
7218
7850
|
}
|
|
7219
|
-
var Route$
|
|
7851
|
+
var Route$59 = createFileRoute("/api/thinking")({ server: { handlers: { POST: async ({ request }) => {
|
|
7220
7852
|
try {
|
|
7221
7853
|
const body = await readRequestJson(request);
|
|
7222
7854
|
return jsonResponse(await getPicoRuntime().setThinking(request, body));
|
|
@@ -7224,7 +7856,7 @@ var Route$56 = createFileRoute("/api/thinking")({ server: { handlers: { POST: as
|
|
|
7224
7856
|
return routeErrorResponse(error, "Failed to update thinking level");
|
|
7225
7857
|
}
|
|
7226
7858
|
} } } });
|
|
7227
|
-
var Route$
|
|
7859
|
+
var Route$58 = createFileRoute("/api/terminal")({ server: { handlers: { POST: async ({ request }) => {
|
|
7228
7860
|
try {
|
|
7229
7861
|
const body = await readRequestJson(request);
|
|
7230
7862
|
return jsonResponse(await getPicoRuntime().createTerminal(request, body));
|
|
@@ -7232,7 +7864,7 @@ var Route$55 = createFileRoute("/api/terminal")({ server: { handlers: { POST: as
|
|
|
7232
7864
|
return routeErrorResponse(error, "Failed to create terminal");
|
|
7233
7865
|
}
|
|
7234
7866
|
} } } });
|
|
7235
|
-
var Route$
|
|
7867
|
+
var Route$57 = createFileRoute("/api/slash-command")({ server: { handlers: { POST: async ({ request }) => {
|
|
7236
7868
|
try {
|
|
7237
7869
|
const body = await readRequestJson(request);
|
|
7238
7870
|
return jsonResponse(await getPicoRuntime().runSlashCommand(request, body));
|
|
@@ -7240,7 +7872,7 @@ var Route$54 = createFileRoute("/api/slash-command")({ server: { handlers: { POS
|
|
|
7240
7872
|
return routeErrorResponse(error, "Failed to run slash command");
|
|
7241
7873
|
}
|
|
7242
7874
|
} } } });
|
|
7243
|
-
var Route$
|
|
7875
|
+
var Route$56 = createFileRoute("/api/provider-usage")({ server: { handlers: { GET: async ({ request }) => {
|
|
7244
7876
|
const provider = new URL(request.url).searchParams.get("provider") || void 0;
|
|
7245
7877
|
try {
|
|
7246
7878
|
return jsonResponse({
|
|
@@ -7251,7 +7883,7 @@ var Route$53 = createFileRoute("/api/provider-usage")({ server: { handlers: { GE
|
|
|
7251
7883
|
return routeErrorResponse(error, "Failed to read provider usage");
|
|
7252
7884
|
}
|
|
7253
7885
|
} } } });
|
|
7254
|
-
var Route$
|
|
7886
|
+
var Route$55 = createFileRoute("/api/prompt")({ server: { handlers: { POST: async ({ request }) => {
|
|
7255
7887
|
try {
|
|
7256
7888
|
const body = await readRequestJson(request);
|
|
7257
7889
|
return jsonResponse(await getPicoRuntime().prompt(request, body));
|
|
@@ -7806,7 +8438,7 @@ async function listFileReferenceEntries(query, baseCwd, { isQuotedPrefix = false
|
|
|
7806
8438
|
};
|
|
7807
8439
|
});
|
|
7808
8440
|
}
|
|
7809
|
-
var Route$
|
|
8441
|
+
var Route$54 = createFileRoute("/api/path-completions")({ server: { handlers: { POST: async ({ request }) => {
|
|
7810
8442
|
try {
|
|
7811
8443
|
const body = await readRequestJson(request);
|
|
7812
8444
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -7822,7 +8454,7 @@ var Route$51 = createFileRoute("/api/path-completions")({ server: { handlers: {
|
|
|
7822
8454
|
return routeErrorResponse(error, "Failed to list path completions");
|
|
7823
8455
|
}
|
|
7824
8456
|
} } } });
|
|
7825
|
-
var Route$
|
|
8457
|
+
var Route$53 = createFileRoute("/api/model")({ server: { handlers: { POST: async ({ request }) => {
|
|
7826
8458
|
try {
|
|
7827
8459
|
const body = await readRequestJson(request);
|
|
7828
8460
|
return jsonResponse(await getPicoRuntime().setModel(request, body));
|
|
@@ -7830,7 +8462,7 @@ var Route$50 = createFileRoute("/api/model")({ server: { handlers: { POST: async
|
|
|
7830
8462
|
return routeErrorResponse(error, "Failed to update model");
|
|
7831
8463
|
}
|
|
7832
8464
|
} } } });
|
|
7833
|
-
var Route$
|
|
8465
|
+
var Route$52 = createFileRoute("/api/highlight")({ server: { handlers: { POST: async ({ request }) => {
|
|
7834
8466
|
try {
|
|
7835
8467
|
const body = await readRequestJson(request);
|
|
7836
8468
|
return jsonResponse(await getPicoRuntime().highlightCode(body.code, body.language));
|
|
@@ -7838,7 +8470,7 @@ var Route$49 = createFileRoute("/api/highlight")({ server: { handlers: { POST: a
|
|
|
7838
8470
|
return routeErrorResponse(error, "Failed to highlight code");
|
|
7839
8471
|
}
|
|
7840
8472
|
} } } });
|
|
7841
|
-
var Route$
|
|
8473
|
+
var Route$51 = createFileRoute("/api/git-status")({ server: { handlers: { GET: async ({ request }) => {
|
|
7842
8474
|
const requestedCwd = new URL(request.url).searchParams.get("cwd") || "";
|
|
7843
8475
|
if (!requestedCwd.trim()) return errorResponse("cwd is required");
|
|
7844
8476
|
try {
|
|
@@ -7853,7 +8485,7 @@ var Route$48 = createFileRoute("/api/git-status")({ server: { handlers: { GET: a
|
|
|
7853
8485
|
return routeErrorResponse(error, "Failed to read git status");
|
|
7854
8486
|
}
|
|
7855
8487
|
} } } });
|
|
7856
|
-
var Route$
|
|
8488
|
+
var Route$50 = createFileRoute("/api/git-stage")({ server: { handlers: { POST: async ({ request }) => {
|
|
7857
8489
|
let errorFallback = "Failed to stage changes";
|
|
7858
8490
|
try {
|
|
7859
8491
|
const body = await readRequestJson(request);
|
|
@@ -7878,7 +8510,7 @@ var Route$47 = createFileRoute("/api/git-stage")({ server: { handlers: { POST: a
|
|
|
7878
8510
|
return routeErrorResponse(error, errorFallback);
|
|
7879
8511
|
}
|
|
7880
8512
|
} } } });
|
|
7881
|
-
var Route$
|
|
8513
|
+
var Route$49 = createFileRoute("/api/git-review")({ server: { handlers: { GET: async ({ request }) => {
|
|
7882
8514
|
const url = new URL(request.url);
|
|
7883
8515
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7884
8516
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -7901,7 +8533,7 @@ var Route$46 = createFileRoute("/api/git-review")({ server: { handlers: { GET: a
|
|
|
7901
8533
|
return routeErrorResponse(error, "Failed to read git review file");
|
|
7902
8534
|
}
|
|
7903
8535
|
} } } });
|
|
7904
|
-
var Route$
|
|
8536
|
+
var Route$48 = createFileRoute("/api/git-push")({ server: { handlers: { POST: async ({ request }) => {
|
|
7905
8537
|
try {
|
|
7906
8538
|
const body = await readRequestJson(request);
|
|
7907
8539
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -7920,7 +8552,7 @@ var Route$45 = createFileRoute("/api/git-push")({ server: { handlers: { POST: as
|
|
|
7920
8552
|
return routeErrorResponse(error, "Failed to push changes");
|
|
7921
8553
|
}
|
|
7922
8554
|
} } } });
|
|
7923
|
-
var Route$
|
|
8555
|
+
var Route$47 = createFileRoute("/api/git-pull")({ server: { handlers: { POST: async ({ request }) => {
|
|
7924
8556
|
try {
|
|
7925
8557
|
const body = await readRequestJson(request);
|
|
7926
8558
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -7938,7 +8570,7 @@ var Route$44 = createFileRoute("/api/git-pull")({ server: { handlers: { POST: as
|
|
|
7938
8570
|
return routeErrorResponse(error, "Failed to pull changes");
|
|
7939
8571
|
}
|
|
7940
8572
|
} } } });
|
|
7941
|
-
var Route$
|
|
8573
|
+
var Route$46 = createFileRoute("/api/git-discard")({ server: { handlers: { POST: async ({ request }) => {
|
|
7942
8574
|
try {
|
|
7943
8575
|
const body = await readRequestJson(request);
|
|
7944
8576
|
const action = typeof body.action === "string" ? body.action : "";
|
|
@@ -7962,7 +8594,7 @@ var Route$43 = createFileRoute("/api/git-discard")({ server: { handlers: { POST:
|
|
|
7962
8594
|
return routeErrorResponse(error, "Failed to discard changes");
|
|
7963
8595
|
}
|
|
7964
8596
|
} } } });
|
|
7965
|
-
var Route$
|
|
8597
|
+
var Route$45 = createFileRoute("/api/git-diff")({ server: { handlers: { GET: async ({ request }) => {
|
|
7966
8598
|
const url = new URL(request.url);
|
|
7967
8599
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7968
8600
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -7982,7 +8614,7 @@ var Route$42 = createFileRoute("/api/git-diff")({ server: { handlers: { GET: asy
|
|
|
7982
8614
|
return routeErrorResponse(error, "Failed to read git diff");
|
|
7983
8615
|
}
|
|
7984
8616
|
} } } });
|
|
7985
|
-
var Route$
|
|
8617
|
+
var Route$44 = createFileRoute("/api/git-commit-remote-url")({ server: { handlers: { GET: async ({ request }) => {
|
|
7986
8618
|
try {
|
|
7987
8619
|
const url = new URL(request.url);
|
|
7988
8620
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
@@ -8003,7 +8635,7 @@ var Route$41 = createFileRoute("/api/git-commit-remote-url")({ server: { handler
|
|
|
8003
8635
|
return routeErrorResponse(error, "Failed to read commit remote URL");
|
|
8004
8636
|
}
|
|
8005
8637
|
} } } });
|
|
8006
|
-
var Route$
|
|
8638
|
+
var Route$43 = createFileRoute("/api/git-commit-message")({ server: { handlers: { POST: async ({ request }) => {
|
|
8007
8639
|
try {
|
|
8008
8640
|
const body = await readRequestJson(request);
|
|
8009
8641
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -8022,7 +8654,7 @@ var Route$40 = createFileRoute("/api/git-commit-message")({ server: { handlers:
|
|
|
8022
8654
|
return routeErrorResponse(error, "Failed to generate commit message");
|
|
8023
8655
|
}
|
|
8024
8656
|
} } } });
|
|
8025
|
-
var Route$
|
|
8657
|
+
var Route$42 = createFileRoute("/api/git-commit-files")({ server: { handlers: { GET: async ({ request }) => {
|
|
8026
8658
|
try {
|
|
8027
8659
|
const url = new URL(request.url);
|
|
8028
8660
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
@@ -8045,7 +8677,7 @@ function normalizeGitCommitDiffMode(value) {
|
|
|
8045
8677
|
if (value === "head" || value === "previous") return value;
|
|
8046
8678
|
return "commit";
|
|
8047
8679
|
}
|
|
8048
|
-
var Route$
|
|
8680
|
+
var Route$41 = createFileRoute("/api/git-commit-diff")({ server: { handlers: { GET: async ({ request }) => {
|
|
8049
8681
|
try {
|
|
8050
8682
|
const url = new URL(request.url);
|
|
8051
8683
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
@@ -8082,7 +8714,7 @@ var gitCommitActions = new Set([
|
|
|
8082
8714
|
"drop",
|
|
8083
8715
|
"squash"
|
|
8084
8716
|
]);
|
|
8085
|
-
var Route$
|
|
8717
|
+
var Route$40 = createFileRoute("/api/git-commit-action")({ server: { handlers: { POST: async ({ request }) => {
|
|
8086
8718
|
try {
|
|
8087
8719
|
const body = await readRequestJson(request);
|
|
8088
8720
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -8108,7 +8740,7 @@ var Route$37 = createFileRoute("/api/git-commit-action")({ server: { handlers: {
|
|
|
8108
8740
|
return routeErrorResponse(error, "Failed to run commit action");
|
|
8109
8741
|
}
|
|
8110
8742
|
} } } });
|
|
8111
|
-
var Route$
|
|
8743
|
+
var Route$39 = createFileRoute("/api/git-commit")({ server: { handlers: { POST: async ({ request }) => {
|
|
8112
8744
|
try {
|
|
8113
8745
|
const body = await readRequestJson(request);
|
|
8114
8746
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -8133,7 +8765,7 @@ var Route$36 = createFileRoute("/api/git-commit")({ server: { handlers: { POST:
|
|
|
8133
8765
|
return routeErrorResponse(error, "Failed to commit changes");
|
|
8134
8766
|
}
|
|
8135
8767
|
} } } });
|
|
8136
|
-
var Route$
|
|
8768
|
+
var Route$38 = createFileRoute("/api/git-checkout")({ server: { handlers: { POST: async ({ request }) => {
|
|
8137
8769
|
try {
|
|
8138
8770
|
const body = await readRequestJson(request);
|
|
8139
8771
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -8183,7 +8815,7 @@ function getRuntimeRequestForGitChanges(request, url) {
|
|
|
8183
8815
|
method: request.method
|
|
8184
8816
|
});
|
|
8185
8817
|
}
|
|
8186
|
-
var Route$
|
|
8818
|
+
var Route$37 = createFileRoute("/api/git-changes")({ server: { handlers: { GET: async ({ request }) => {
|
|
8187
8819
|
const url = new URL(request.url);
|
|
8188
8820
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
8189
8821
|
const gitScope = getGitChangesScope(url);
|
|
@@ -8253,7 +8885,7 @@ var Route$34 = createFileRoute("/api/git-changes")({ server: { handlers: { GET:
|
|
|
8253
8885
|
return routeErrorResponse(error, "Failed to read git changes");
|
|
8254
8886
|
}
|
|
8255
8887
|
} } } });
|
|
8256
|
-
var Route$
|
|
8888
|
+
var Route$36 = createFileRoute("/api/file-completions")({ server: { handlers: { POST: async ({ request }) => {
|
|
8257
8889
|
try {
|
|
8258
8890
|
const body = await readRequestJson(request);
|
|
8259
8891
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -8270,7 +8902,7 @@ var Route$33 = createFileRoute("/api/file-completions")({ server: { handlers: {
|
|
|
8270
8902
|
return routeErrorResponse(error, "Failed to list file completions");
|
|
8271
8903
|
}
|
|
8272
8904
|
} } } });
|
|
8273
|
-
var Route$
|
|
8905
|
+
var Route$35 = createFileRoute("/api/directory-sessions-indexes")({ server: { handlers: { GET: async ({ request }) => {
|
|
8274
8906
|
const directories = new URL(request.url).searchParams.getAll("directory");
|
|
8275
8907
|
if (directories.length === 0) return errorResponse("at least one directory is required");
|
|
8276
8908
|
try {
|
|
@@ -8279,7 +8911,7 @@ var Route$32 = createFileRoute("/api/directory-sessions-indexes")({ server: { ha
|
|
|
8279
8911
|
return routeErrorResponse(error, "Failed to list directory session indexes");
|
|
8280
8912
|
}
|
|
8281
8913
|
} } } });
|
|
8282
|
-
var Route$
|
|
8914
|
+
var Route$34 = createFileRoute("/api/directory-sessions-index")({ server: { handlers: { GET: async ({ request }) => {
|
|
8283
8915
|
const directory = new URL(request.url).searchParams.get("directory") || "";
|
|
8284
8916
|
if (!directory.trim()) return errorResponse("directory is required");
|
|
8285
8917
|
try {
|
|
@@ -8288,7 +8920,7 @@ var Route$31 = createFileRoute("/api/directory-sessions-index")({ server: { hand
|
|
|
8288
8920
|
return routeErrorResponse(error, "Failed to list directory session index");
|
|
8289
8921
|
}
|
|
8290
8922
|
} } } });
|
|
8291
|
-
var Route$
|
|
8923
|
+
var Route$33 = createFileRoute("/api/directory-sessions")({ server: { handlers: { GET: async ({ request }) => {
|
|
8292
8924
|
const url = new URL(request.url);
|
|
8293
8925
|
const directory = url.searchParams.get("directory") || "";
|
|
8294
8926
|
const offset = Number.parseInt(url.searchParams.get("offset") || "0", 10);
|
|
@@ -8303,7 +8935,7 @@ var Route$30 = createFileRoute("/api/directory-sessions")({ server: { handlers:
|
|
|
8303
8935
|
return routeErrorResponse(error, "Failed to list directory sessions");
|
|
8304
8936
|
}
|
|
8305
8937
|
} } } });
|
|
8306
|
-
var Route$
|
|
8938
|
+
var Route$32 = createFileRoute("/api/directory-search")({ server: { handlers: { POST: async ({ request }) => {
|
|
8307
8939
|
try {
|
|
8308
8940
|
const body = await readRequestJson(request);
|
|
8309
8941
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -8319,14 +8951,14 @@ var Route$29 = createFileRoute("/api/directory-search")({ server: { handlers: {
|
|
|
8319
8951
|
return routeErrorResponse(error, "Failed to search directories");
|
|
8320
8952
|
}
|
|
8321
8953
|
} } } });
|
|
8322
|
-
var Route$
|
|
8954
|
+
var Route$31 = createFileRoute("/api/abort")({ server: { handlers: { POST: async ({ request }) => {
|
|
8323
8955
|
try {
|
|
8324
8956
|
return jsonResponse(await getPicoRuntime().abort(request));
|
|
8325
8957
|
} catch (error) {
|
|
8326
8958
|
return routeErrorResponse(error, "Failed to abort session");
|
|
8327
8959
|
}
|
|
8328
8960
|
} } } });
|
|
8329
|
-
var Route$
|
|
8961
|
+
var Route$30 = createFileRoute("/api/ui/$id")({ server: { handlers: { POST: async ({ request, params }) => {
|
|
8330
8962
|
try {
|
|
8331
8963
|
const body = await readRequestJson(request);
|
|
8332
8964
|
return jsonResponse(await getPicoRuntime().resolveUiRequest(params.id, body));
|
|
@@ -8334,7 +8966,7 @@ var Route$27 = createFileRoute("/api/ui/$id")({ server: { handlers: { POST: asyn
|
|
|
8334
8966
|
return routeErrorResponse(error, "Failed to resolve UI request");
|
|
8335
8967
|
}
|
|
8336
8968
|
} } } });
|
|
8337
|
-
var Route$
|
|
8969
|
+
var Route$29 = createFileRoute("/api/settings/hide-thinking")({ server: { handlers: { POST: async ({ request }) => {
|
|
8338
8970
|
try {
|
|
8339
8971
|
const body = await readRequestJson(request);
|
|
8340
8972
|
return jsonResponse(await getPicoRuntime().setHideThinking(body));
|
|
@@ -8342,7 +8974,7 @@ var Route$26 = createFileRoute("/api/settings/hide-thinking")({ server: { handle
|
|
|
8342
8974
|
return routeErrorResponse(error, "Failed to update hide-thinking setting");
|
|
8343
8975
|
}
|
|
8344
8976
|
} } } });
|
|
8345
|
-
var Route$
|
|
8977
|
+
var Route$28 = createFileRoute("/api/sessions/delete")({ server: { handlers: { POST: async ({ request }) => {
|
|
8346
8978
|
try {
|
|
8347
8979
|
const body = await readRequestJson(request);
|
|
8348
8980
|
return jsonResponse(await getPicoRuntime().deleteSessions(request, body));
|
|
@@ -8350,7 +8982,7 @@ var Route$25 = createFileRoute("/api/sessions/delete")({ server: { handlers: { P
|
|
|
8350
8982
|
return routeErrorResponse(error, "Failed to delete sessions");
|
|
8351
8983
|
}
|
|
8352
8984
|
} } } });
|
|
8353
|
-
var Route$
|
|
8985
|
+
var Route$27 = createFileRoute("/api/session/tree")({ server: { handlers: {
|
|
8354
8986
|
GET: async ({ request }) => {
|
|
8355
8987
|
try {
|
|
8356
8988
|
return jsonResponse(await getPicoRuntime().getSessionTreeForRequest(request));
|
|
@@ -8367,14 +8999,14 @@ var Route$24 = createFileRoute("/api/session/tree")({ server: { handlers: {
|
|
|
8367
8999
|
}
|
|
8368
9000
|
}
|
|
8369
9001
|
} } });
|
|
8370
|
-
var Route$
|
|
9002
|
+
var Route$26 = createFileRoute("/api/session/select")({ server: { handlers: { POST: async ({ request }) => {
|
|
8371
9003
|
try {
|
|
8372
9004
|
return jsonResponse(await getPicoRuntime().selectSession(request));
|
|
8373
9005
|
} catch (error) {
|
|
8374
9006
|
return routeErrorResponse(error, "Failed to select session");
|
|
8375
9007
|
}
|
|
8376
9008
|
} } } });
|
|
8377
|
-
var Route$
|
|
9009
|
+
var Route$25 = createFileRoute("/api/session/rename")({ server: { handlers: { POST: async ({ request }) => {
|
|
8378
9010
|
try {
|
|
8379
9011
|
const body = await readRequestJson(request);
|
|
8380
9012
|
return jsonResponse(await getPicoRuntime().renameSession(body));
|
|
@@ -8382,7 +9014,7 @@ var Route$22 = createFileRoute("/api/session/rename")({ server: { handlers: { PO
|
|
|
8382
9014
|
return routeErrorResponse(error, "Failed to rename session");
|
|
8383
9015
|
}
|
|
8384
9016
|
} } } });
|
|
8385
|
-
var Route$
|
|
9017
|
+
var Route$24 = createFileRoute("/api/session/read-state")({ server: { handlers: { POST: async ({ request }) => {
|
|
8386
9018
|
try {
|
|
8387
9019
|
const body = await readRequestJson(request);
|
|
8388
9020
|
return jsonResponse(await getPicoRuntime().setSessionReadState(request, body));
|
|
@@ -8390,7 +9022,7 @@ var Route$21 = createFileRoute("/api/session/read-state")({ server: { handlers:
|
|
|
8390
9022
|
return routeErrorResponse(error, "Failed to update session read state");
|
|
8391
9023
|
}
|
|
8392
9024
|
} } } });
|
|
8393
|
-
var Route$
|
|
9025
|
+
var Route$23 = createFileRoute("/api/session/new")({ server: { handlers: { POST: async ({ request }) => {
|
|
8394
9026
|
try {
|
|
8395
9027
|
const body = await readRequestJson(request);
|
|
8396
9028
|
return jsonResponse(await getPicoRuntime().createNewSession(request, body));
|
|
@@ -8398,7 +9030,15 @@ var Route$20 = createFileRoute("/api/session/new")({ server: { handlers: { POST:
|
|
|
8398
9030
|
return routeErrorResponse(error, "Failed to create session");
|
|
8399
9031
|
}
|
|
8400
9032
|
} } } });
|
|
8401
|
-
var Route$
|
|
9033
|
+
var Route$22 = createFileRoute("/api/session/name")({ server: { handlers: { POST: async ({ request }) => {
|
|
9034
|
+
try {
|
|
9035
|
+
const body = await readRequestJson(request);
|
|
9036
|
+
return jsonResponse(await getPicoRuntime().generateSessionName(request, body));
|
|
9037
|
+
} catch (error) {
|
|
9038
|
+
return routeErrorResponse(error, "Failed to generate session name");
|
|
9039
|
+
}
|
|
9040
|
+
} } } });
|
|
9041
|
+
var Route$21 = createFileRoute("/api/session/move")({ server: { handlers: { POST: async ({ request }) => {
|
|
8402
9042
|
try {
|
|
8403
9043
|
const body = await readRequestJson(request);
|
|
8404
9044
|
return jsonResponse(await getPicoRuntime().moveSession(request, body));
|
|
@@ -8406,7 +9046,7 @@ var Route$19 = createFileRoute("/api/session/move")({ server: { handlers: { POST
|
|
|
8406
9046
|
return routeErrorResponse(error, "Failed to move session");
|
|
8407
9047
|
}
|
|
8408
9048
|
} } } });
|
|
8409
|
-
var Route$
|
|
9049
|
+
var Route$20 = createFileRoute("/api/session/history")({ server: { handlers: { GET: async ({ request }) => {
|
|
8410
9050
|
try {
|
|
8411
9051
|
const url = new URL(request.url);
|
|
8412
9052
|
const before = Number(url.searchParams.get("before"));
|
|
@@ -8419,7 +9059,7 @@ var Route$18 = createFileRoute("/api/session/history")({ server: { handlers: { G
|
|
|
8419
9059
|
return routeErrorResponse(error, "Failed to load session history");
|
|
8420
9060
|
}
|
|
8421
9061
|
} } } });
|
|
8422
|
-
var Route$
|
|
9062
|
+
var Route$19 = createFileRoute("/api/session/fork")({ server: { handlers: {
|
|
8423
9063
|
GET: async ({ request }) => {
|
|
8424
9064
|
try {
|
|
8425
9065
|
return jsonResponse(await getPicoRuntime().getForkableMessages(request));
|
|
@@ -8436,7 +9076,7 @@ var Route$17 = createFileRoute("/api/session/fork")({ server: { handlers: {
|
|
|
8436
9076
|
}
|
|
8437
9077
|
}
|
|
8438
9078
|
} } });
|
|
8439
|
-
var Route$
|
|
9079
|
+
var Route$18 = createFileRoute("/api/session/delete")({ server: { handlers: { POST: async ({ request }) => {
|
|
8440
9080
|
try {
|
|
8441
9081
|
const body = await readRequestJson(request);
|
|
8442
9082
|
return jsonResponse(await getPicoRuntime().deleteSession(request, body));
|
|
@@ -8444,14 +9084,21 @@ var Route$16 = createFileRoute("/api/session/delete")({ server: { handlers: { PO
|
|
|
8444
9084
|
return routeErrorResponse(error, "Failed to delete session");
|
|
8445
9085
|
}
|
|
8446
9086
|
} } } });
|
|
8447
|
-
var Route$
|
|
9087
|
+
var Route$17 = createFileRoute("/api/session/clone")({ server: { handlers: { POST: async ({ request }) => {
|
|
8448
9088
|
try {
|
|
8449
9089
|
return jsonResponse(await getPicoRuntime().cloneSession(request));
|
|
8450
9090
|
} catch (error) {
|
|
8451
9091
|
return routeErrorResponse(error, "Failed to clone session");
|
|
8452
9092
|
}
|
|
8453
9093
|
} } } });
|
|
8454
|
-
var Route$
|
|
9094
|
+
var Route$16 = createFileRoute("/api/pending-messages/start")({ server: { handlers: { POST: async ({ request }) => {
|
|
9095
|
+
try {
|
|
9096
|
+
return jsonResponse(await getPicoRuntime().startPendingQueue(request));
|
|
9097
|
+
} catch (error) {
|
|
9098
|
+
return routeErrorResponse(error, "Failed to start queued prompts");
|
|
9099
|
+
}
|
|
9100
|
+
} } } });
|
|
9101
|
+
var Route$15 = createFileRoute("/api/pending-messages/reorder")({ server: { handlers: { POST: async ({ request }) => {
|
|
8455
9102
|
try {
|
|
8456
9103
|
const body = await readRequestJson(request);
|
|
8457
9104
|
return jsonResponse(await getPicoRuntime().reorderPendingMessages(request, body));
|
|
@@ -8459,7 +9106,7 @@ var Route$14 = createFileRoute("/api/pending-messages/reorder")({ server: { hand
|
|
|
8459
9106
|
return routeErrorResponse(error, "Failed to update pending prompts");
|
|
8460
9107
|
}
|
|
8461
9108
|
} } } });
|
|
8462
|
-
var Route$
|
|
9109
|
+
var Route$14 = createFileRoute("/api/pending-message/remove")({ server: { handlers: { POST: async ({ request }) => {
|
|
8463
9110
|
try {
|
|
8464
9111
|
const body = await readRequestJson(request);
|
|
8465
9112
|
return jsonResponse(await getPicoRuntime().removePendingMessage(request, body));
|
|
@@ -8467,7 +9114,7 @@ var Route$13 = createFileRoute("/api/pending-message/remove")({ server: { handle
|
|
|
8467
9114
|
return routeErrorResponse(error, "Failed to remove pending prompt");
|
|
8468
9115
|
}
|
|
8469
9116
|
} } } });
|
|
8470
|
-
var Route$
|
|
9117
|
+
var Route$13 = createFileRoute("/api/files/tree")({ server: { handlers: { GET: async ({ request }) => {
|
|
8471
9118
|
const requestedCwd = new URL(request.url).searchParams.get("cwd") || "";
|
|
8472
9119
|
if (!requestedCwd.trim()) return errorResponse("cwd is required");
|
|
8473
9120
|
try {
|
|
@@ -8484,7 +9131,7 @@ var Route$12 = createFileRoute("/api/files/tree")({ server: { handlers: { GET: a
|
|
|
8484
9131
|
return routeErrorResponse(error, "Failed to read file tree");
|
|
8485
9132
|
}
|
|
8486
9133
|
} } } });
|
|
8487
|
-
var Route$
|
|
9134
|
+
var Route$12 = createFileRoute("/api/files/read")({ server: { handlers: { GET: async ({ request }) => {
|
|
8488
9135
|
const url = new URL(request.url);
|
|
8489
9136
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
8490
9137
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -8504,7 +9151,7 @@ var Route$11 = createFileRoute("/api/files/read")({ server: { handlers: { GET: a
|
|
|
8504
9151
|
return routeErrorResponse(error, "Failed to read file");
|
|
8505
9152
|
}
|
|
8506
9153
|
} } } });
|
|
8507
|
-
var Route$
|
|
9154
|
+
var Route$11 = createFileRoute("/api/directory/resolve")({ server: { handlers: { POST: async ({ request }) => {
|
|
8508
9155
|
try {
|
|
8509
9156
|
const body = await readRequestJson(request);
|
|
8510
9157
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -8516,7 +9163,7 @@ var Route$10 = createFileRoute("/api/directory/resolve")({ server: { handlers: {
|
|
|
8516
9163
|
return routeErrorResponse(error, "Failed to resolve directory");
|
|
8517
9164
|
}
|
|
8518
9165
|
} } } });
|
|
8519
|
-
var Route$
|
|
9166
|
+
var Route$10 = createFileRoute("/api/directory-sessions/cleanup")({ server: { handlers: { POST: async ({ request }) => {
|
|
8520
9167
|
try {
|
|
8521
9168
|
const body = await readRequestJson(request);
|
|
8522
9169
|
return jsonResponse(await getPicoRuntime().deleteOldDirectorySessions(request, body));
|
|
@@ -8524,6 +9171,99 @@ var Route$9 = createFileRoute("/api/directory-sessions/cleanup")({ server: { han
|
|
|
8524
9171
|
return routeErrorResponse(error, "Failed to clean up sessions");
|
|
8525
9172
|
}
|
|
8526
9173
|
} } } });
|
|
9174
|
+
var API_CONTRACT_VERSION = 1;
|
|
9175
|
+
function readPicoPackageVersion() {
|
|
9176
|
+
let currentDir = dirname(fileURLToPath(import.meta.url));
|
|
9177
|
+
while (currentDir && currentDir !== dirname(currentDir)) {
|
|
9178
|
+
const packageJsonPath = join(currentDir, "package.json");
|
|
9179
|
+
if (existsSync(packageJsonPath)) try {
|
|
9180
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
9181
|
+
if (packageJson.name === "@alivault/pico" && typeof packageJson.version === "string") return packageJson.version;
|
|
9182
|
+
} catch {
|
|
9183
|
+
return "0.0.0";
|
|
9184
|
+
}
|
|
9185
|
+
currentDir = dirname(currentDir);
|
|
9186
|
+
}
|
|
9187
|
+
return "0.0.0";
|
|
9188
|
+
}
|
|
9189
|
+
function buildClientManifest() {
|
|
9190
|
+
return {
|
|
9191
|
+
ok: true,
|
|
9192
|
+
name: "@alivault/pico",
|
|
9193
|
+
version: readPicoPackageVersion(),
|
|
9194
|
+
displayName: "Pico",
|
|
9195
|
+
apiContractVersion: API_CONTRACT_VERSION,
|
|
9196
|
+
pairingRequired: false,
|
|
9197
|
+
authentication: { type: "none" },
|
|
9198
|
+
transport: {
|
|
9199
|
+
sse: true,
|
|
9200
|
+
httpsRequired: false,
|
|
9201
|
+
localHttpAllowed: true
|
|
9202
|
+
},
|
|
9203
|
+
capabilities: {
|
|
9204
|
+
events: [
|
|
9205
|
+
"state_sync",
|
|
9206
|
+
"sessions",
|
|
9207
|
+
"session_status",
|
|
9208
|
+
"session_done",
|
|
9209
|
+
"request_error",
|
|
9210
|
+
"extension_error",
|
|
9211
|
+
"extension_ui_request",
|
|
9212
|
+
"user_message",
|
|
9213
|
+
"auto_session_naming_error",
|
|
9214
|
+
"git_changed"
|
|
9215
|
+
],
|
|
9216
|
+
endpoints: [
|
|
9217
|
+
"/events",
|
|
9218
|
+
"/api/prompt",
|
|
9219
|
+
"/api/abort",
|
|
9220
|
+
"/api/session/new",
|
|
9221
|
+
"/api/session/select",
|
|
9222
|
+
"/api/session/fork",
|
|
9223
|
+
"/api/session/name",
|
|
9224
|
+
"/api/session/rename",
|
|
9225
|
+
"/api/session/delete",
|
|
9226
|
+
"/api/session/read-state",
|
|
9227
|
+
"/api/directory-sessions-indexes",
|
|
9228
|
+
"/api/directory/resolve",
|
|
9229
|
+
"/api/directory-search",
|
|
9230
|
+
"/api/path-completions",
|
|
9231
|
+
"/api/model",
|
|
9232
|
+
"/api/thinking",
|
|
9233
|
+
"/api/auth/providers",
|
|
9234
|
+
"/api/auth/api-key",
|
|
9235
|
+
"/api/auth/oauth",
|
|
9236
|
+
"/api/auth/logout",
|
|
9237
|
+
"/api/ui/$id",
|
|
9238
|
+
"/api/settings/hide-thinking",
|
|
9239
|
+
"/api/pending-message/remove",
|
|
9240
|
+
"/api/pending-messages/reorder",
|
|
9241
|
+
"/api/pending-messages/start"
|
|
9242
|
+
],
|
|
9243
|
+
features: [
|
|
9244
|
+
"sse",
|
|
9245
|
+
"session-browser",
|
|
9246
|
+
"conversation",
|
|
9247
|
+
"prompt-composer",
|
|
9248
|
+
"queue-and-steer",
|
|
9249
|
+
"model-selection",
|
|
9250
|
+
"thinking-selection",
|
|
9251
|
+
"provider-authentication",
|
|
9252
|
+
"native-directory-browser",
|
|
9253
|
+
"post-compaction-token-estimates",
|
|
9254
|
+
"edit-user-message-fork",
|
|
9255
|
+
"assistant-message-actions"
|
|
9256
|
+
]
|
|
9257
|
+
}
|
|
9258
|
+
};
|
|
9259
|
+
}
|
|
9260
|
+
var Route$9 = createFileRoute("/api/client/manifest")({ server: { handlers: { GET: async () => {
|
|
9261
|
+
try {
|
|
9262
|
+
return jsonResponse(buildClientManifest());
|
|
9263
|
+
} catch (error) {
|
|
9264
|
+
return routeErrorResponse(error, "Failed to build client manifest");
|
|
9265
|
+
}
|
|
9266
|
+
} } } });
|
|
8527
9267
|
var Route$8 = createFileRoute("/api/auth/providers")({ server: { handlers: { GET: async ({ request }) => {
|
|
8528
9268
|
try {
|
|
8529
9269
|
return jsonResponse(await getPicoRuntime().getAuthProviders(request));
|
|
@@ -8593,275 +9333,290 @@ var Route = createFileRoute("/api/session/tree/label")({ server: { handlers: { P
|
|
|
8593
9333
|
return routeErrorResponse(error, "Failed to update tree label");
|
|
8594
9334
|
}
|
|
8595
9335
|
} } } });
|
|
8596
|
-
var EventsRoute = Route$
|
|
9336
|
+
var EventsRoute = Route$60.update({
|
|
8597
9337
|
id: "/events",
|
|
8598
9338
|
path: "/events",
|
|
8599
|
-
getParentRoute: () => Route$
|
|
9339
|
+
getParentRoute: () => Route$61
|
|
8600
9340
|
});
|
|
8601
|
-
var IndexRoute = Route$
|
|
9341
|
+
var IndexRoute = Route$62.update({
|
|
8602
9342
|
id: "/",
|
|
8603
9343
|
path: "/",
|
|
8604
|
-
getParentRoute: () => Route$
|
|
9344
|
+
getParentRoute: () => Route$61
|
|
8605
9345
|
});
|
|
8606
|
-
var ApiThinkingRoute = Route$
|
|
9346
|
+
var ApiThinkingRoute = Route$59.update({
|
|
8607
9347
|
id: "/api/thinking",
|
|
8608
9348
|
path: "/api/thinking",
|
|
8609
|
-
getParentRoute: () => Route$
|
|
9349
|
+
getParentRoute: () => Route$61
|
|
8610
9350
|
});
|
|
8611
|
-
var ApiTerminalRoute = Route$
|
|
9351
|
+
var ApiTerminalRoute = Route$58.update({
|
|
8612
9352
|
id: "/api/terminal",
|
|
8613
9353
|
path: "/api/terminal",
|
|
8614
|
-
getParentRoute: () => Route$
|
|
9354
|
+
getParentRoute: () => Route$61
|
|
8615
9355
|
});
|
|
8616
|
-
var ApiSlashCommandRoute = Route$
|
|
9356
|
+
var ApiSlashCommandRoute = Route$57.update({
|
|
8617
9357
|
id: "/api/slash-command",
|
|
8618
9358
|
path: "/api/slash-command",
|
|
8619
|
-
getParentRoute: () => Route$
|
|
9359
|
+
getParentRoute: () => Route$61
|
|
8620
9360
|
});
|
|
8621
|
-
var ApiProviderUsageRoute = Route$
|
|
9361
|
+
var ApiProviderUsageRoute = Route$56.update({
|
|
8622
9362
|
id: "/api/provider-usage",
|
|
8623
9363
|
path: "/api/provider-usage",
|
|
8624
|
-
getParentRoute: () => Route$
|
|
9364
|
+
getParentRoute: () => Route$61
|
|
8625
9365
|
});
|
|
8626
|
-
var ApiPromptRoute = Route$
|
|
9366
|
+
var ApiPromptRoute = Route$55.update({
|
|
8627
9367
|
id: "/api/prompt",
|
|
8628
9368
|
path: "/api/prompt",
|
|
8629
|
-
getParentRoute: () => Route$
|
|
9369
|
+
getParentRoute: () => Route$61
|
|
8630
9370
|
});
|
|
8631
|
-
var ApiPathCompletionsRoute = Route$
|
|
9371
|
+
var ApiPathCompletionsRoute = Route$54.update({
|
|
8632
9372
|
id: "/api/path-completions",
|
|
8633
9373
|
path: "/api/path-completions",
|
|
8634
|
-
getParentRoute: () => Route$
|
|
9374
|
+
getParentRoute: () => Route$61
|
|
8635
9375
|
});
|
|
8636
|
-
var ApiModelRoute = Route$
|
|
9376
|
+
var ApiModelRoute = Route$53.update({
|
|
8637
9377
|
id: "/api/model",
|
|
8638
9378
|
path: "/api/model",
|
|
8639
|
-
getParentRoute: () => Route$
|
|
9379
|
+
getParentRoute: () => Route$61
|
|
8640
9380
|
});
|
|
8641
|
-
var ApiHighlightRoute = Route$
|
|
9381
|
+
var ApiHighlightRoute = Route$52.update({
|
|
8642
9382
|
id: "/api/highlight",
|
|
8643
9383
|
path: "/api/highlight",
|
|
8644
|
-
getParentRoute: () => Route$
|
|
9384
|
+
getParentRoute: () => Route$61
|
|
8645
9385
|
});
|
|
8646
|
-
var ApiGitStatusRoute = Route$
|
|
9386
|
+
var ApiGitStatusRoute = Route$51.update({
|
|
8647
9387
|
id: "/api/git-status",
|
|
8648
9388
|
path: "/api/git-status",
|
|
8649
|
-
getParentRoute: () => Route$
|
|
9389
|
+
getParentRoute: () => Route$61
|
|
8650
9390
|
});
|
|
8651
|
-
var ApiGitStageRoute = Route$
|
|
9391
|
+
var ApiGitStageRoute = Route$50.update({
|
|
8652
9392
|
id: "/api/git-stage",
|
|
8653
9393
|
path: "/api/git-stage",
|
|
8654
|
-
getParentRoute: () => Route$
|
|
9394
|
+
getParentRoute: () => Route$61
|
|
8655
9395
|
});
|
|
8656
|
-
var ApiGitReviewRoute = Route$
|
|
9396
|
+
var ApiGitReviewRoute = Route$49.update({
|
|
8657
9397
|
id: "/api/git-review",
|
|
8658
9398
|
path: "/api/git-review",
|
|
8659
|
-
getParentRoute: () => Route$
|
|
9399
|
+
getParentRoute: () => Route$61
|
|
8660
9400
|
});
|
|
8661
|
-
var ApiGitPushRoute = Route$
|
|
9401
|
+
var ApiGitPushRoute = Route$48.update({
|
|
8662
9402
|
id: "/api/git-push",
|
|
8663
9403
|
path: "/api/git-push",
|
|
8664
|
-
getParentRoute: () => Route$
|
|
9404
|
+
getParentRoute: () => Route$61
|
|
8665
9405
|
});
|
|
8666
|
-
var ApiGitPullRoute = Route$
|
|
9406
|
+
var ApiGitPullRoute = Route$47.update({
|
|
8667
9407
|
id: "/api/git-pull",
|
|
8668
9408
|
path: "/api/git-pull",
|
|
8669
|
-
getParentRoute: () => Route$
|
|
9409
|
+
getParentRoute: () => Route$61
|
|
8670
9410
|
});
|
|
8671
|
-
var ApiGitDiscardRoute = Route$
|
|
9411
|
+
var ApiGitDiscardRoute = Route$46.update({
|
|
8672
9412
|
id: "/api/git-discard",
|
|
8673
9413
|
path: "/api/git-discard",
|
|
8674
|
-
getParentRoute: () => Route$
|
|
9414
|
+
getParentRoute: () => Route$61
|
|
8675
9415
|
});
|
|
8676
|
-
var ApiGitDiffRoute = Route$
|
|
9416
|
+
var ApiGitDiffRoute = Route$45.update({
|
|
8677
9417
|
id: "/api/git-diff",
|
|
8678
9418
|
path: "/api/git-diff",
|
|
8679
|
-
getParentRoute: () => Route$
|
|
9419
|
+
getParentRoute: () => Route$61
|
|
8680
9420
|
});
|
|
8681
|
-
var ApiGitCommitRemoteUrlRoute = Route$
|
|
9421
|
+
var ApiGitCommitRemoteUrlRoute = Route$44.update({
|
|
8682
9422
|
id: "/api/git-commit-remote-url",
|
|
8683
9423
|
path: "/api/git-commit-remote-url",
|
|
8684
|
-
getParentRoute: () => Route$
|
|
9424
|
+
getParentRoute: () => Route$61
|
|
8685
9425
|
});
|
|
8686
|
-
var ApiGitCommitMessageRoute = Route$
|
|
9426
|
+
var ApiGitCommitMessageRoute = Route$43.update({
|
|
8687
9427
|
id: "/api/git-commit-message",
|
|
8688
9428
|
path: "/api/git-commit-message",
|
|
8689
|
-
getParentRoute: () => Route$
|
|
9429
|
+
getParentRoute: () => Route$61
|
|
8690
9430
|
});
|
|
8691
|
-
var ApiGitCommitFilesRoute = Route$
|
|
9431
|
+
var ApiGitCommitFilesRoute = Route$42.update({
|
|
8692
9432
|
id: "/api/git-commit-files",
|
|
8693
9433
|
path: "/api/git-commit-files",
|
|
8694
|
-
getParentRoute: () => Route$
|
|
9434
|
+
getParentRoute: () => Route$61
|
|
8695
9435
|
});
|
|
8696
|
-
var ApiGitCommitDiffRoute = Route$
|
|
9436
|
+
var ApiGitCommitDiffRoute = Route$41.update({
|
|
8697
9437
|
id: "/api/git-commit-diff",
|
|
8698
9438
|
path: "/api/git-commit-diff",
|
|
8699
|
-
getParentRoute: () => Route$
|
|
9439
|
+
getParentRoute: () => Route$61
|
|
8700
9440
|
});
|
|
8701
|
-
var ApiGitCommitActionRoute = Route$
|
|
9441
|
+
var ApiGitCommitActionRoute = Route$40.update({
|
|
8702
9442
|
id: "/api/git-commit-action",
|
|
8703
9443
|
path: "/api/git-commit-action",
|
|
8704
|
-
getParentRoute: () => Route$
|
|
9444
|
+
getParentRoute: () => Route$61
|
|
8705
9445
|
});
|
|
8706
|
-
var ApiGitCommitRoute = Route$
|
|
9446
|
+
var ApiGitCommitRoute = Route$39.update({
|
|
8707
9447
|
id: "/api/git-commit",
|
|
8708
9448
|
path: "/api/git-commit",
|
|
8709
|
-
getParentRoute: () => Route$
|
|
9449
|
+
getParentRoute: () => Route$61
|
|
8710
9450
|
});
|
|
8711
|
-
var ApiGitCheckoutRoute = Route$
|
|
9451
|
+
var ApiGitCheckoutRoute = Route$38.update({
|
|
8712
9452
|
id: "/api/git-checkout",
|
|
8713
9453
|
path: "/api/git-checkout",
|
|
8714
|
-
getParentRoute: () => Route$
|
|
9454
|
+
getParentRoute: () => Route$61
|
|
8715
9455
|
});
|
|
8716
|
-
var ApiGitChangesRoute = Route$
|
|
9456
|
+
var ApiGitChangesRoute = Route$37.update({
|
|
8717
9457
|
id: "/api/git-changes",
|
|
8718
9458
|
path: "/api/git-changes",
|
|
8719
|
-
getParentRoute: () => Route$
|
|
9459
|
+
getParentRoute: () => Route$61
|
|
8720
9460
|
});
|
|
8721
|
-
var ApiFileCompletionsRoute = Route$
|
|
9461
|
+
var ApiFileCompletionsRoute = Route$36.update({
|
|
8722
9462
|
id: "/api/file-completions",
|
|
8723
9463
|
path: "/api/file-completions",
|
|
8724
|
-
getParentRoute: () => Route$
|
|
9464
|
+
getParentRoute: () => Route$61
|
|
8725
9465
|
});
|
|
8726
|
-
var ApiDirectorySessionsIndexesRoute = Route$
|
|
9466
|
+
var ApiDirectorySessionsIndexesRoute = Route$35.update({
|
|
8727
9467
|
id: "/api/directory-sessions-indexes",
|
|
8728
9468
|
path: "/api/directory-sessions-indexes",
|
|
8729
|
-
getParentRoute: () => Route$
|
|
9469
|
+
getParentRoute: () => Route$61
|
|
8730
9470
|
});
|
|
8731
|
-
var ApiDirectorySessionsIndexRoute = Route$
|
|
9471
|
+
var ApiDirectorySessionsIndexRoute = Route$34.update({
|
|
8732
9472
|
id: "/api/directory-sessions-index",
|
|
8733
9473
|
path: "/api/directory-sessions-index",
|
|
8734
|
-
getParentRoute: () => Route$
|
|
9474
|
+
getParentRoute: () => Route$61
|
|
8735
9475
|
});
|
|
8736
|
-
var ApiDirectorySessionsRoute = Route$
|
|
9476
|
+
var ApiDirectorySessionsRoute = Route$33.update({
|
|
8737
9477
|
id: "/api/directory-sessions",
|
|
8738
9478
|
path: "/api/directory-sessions",
|
|
8739
|
-
getParentRoute: () => Route$
|
|
9479
|
+
getParentRoute: () => Route$61
|
|
8740
9480
|
});
|
|
8741
|
-
var ApiDirectorySearchRoute = Route$
|
|
9481
|
+
var ApiDirectorySearchRoute = Route$32.update({
|
|
8742
9482
|
id: "/api/directory-search",
|
|
8743
9483
|
path: "/api/directory-search",
|
|
8744
|
-
getParentRoute: () => Route$
|
|
9484
|
+
getParentRoute: () => Route$61
|
|
8745
9485
|
});
|
|
8746
|
-
var ApiAbortRoute = Route$
|
|
9486
|
+
var ApiAbortRoute = Route$31.update({
|
|
8747
9487
|
id: "/api/abort",
|
|
8748
9488
|
path: "/api/abort",
|
|
8749
|
-
getParentRoute: () => Route$
|
|
9489
|
+
getParentRoute: () => Route$61
|
|
8750
9490
|
});
|
|
8751
|
-
var ApiUiIdRoute = Route$
|
|
9491
|
+
var ApiUiIdRoute = Route$30.update({
|
|
8752
9492
|
id: "/api/ui/$id",
|
|
8753
9493
|
path: "/api/ui/$id",
|
|
8754
|
-
getParentRoute: () => Route$
|
|
9494
|
+
getParentRoute: () => Route$61
|
|
8755
9495
|
});
|
|
8756
|
-
var ApiSettingsHideThinkingRoute = Route$
|
|
9496
|
+
var ApiSettingsHideThinkingRoute = Route$29.update({
|
|
8757
9497
|
id: "/api/settings/hide-thinking",
|
|
8758
9498
|
path: "/api/settings/hide-thinking",
|
|
8759
|
-
getParentRoute: () => Route$
|
|
9499
|
+
getParentRoute: () => Route$61
|
|
8760
9500
|
});
|
|
8761
|
-
var ApiSessionsDeleteRoute = Route$
|
|
9501
|
+
var ApiSessionsDeleteRoute = Route$28.update({
|
|
8762
9502
|
id: "/api/sessions/delete",
|
|
8763
9503
|
path: "/api/sessions/delete",
|
|
8764
|
-
getParentRoute: () => Route$
|
|
9504
|
+
getParentRoute: () => Route$61
|
|
8765
9505
|
});
|
|
8766
|
-
var ApiSessionTreeRoute = Route$
|
|
9506
|
+
var ApiSessionTreeRoute = Route$27.update({
|
|
8767
9507
|
id: "/api/session/tree",
|
|
8768
9508
|
path: "/api/session/tree",
|
|
8769
|
-
getParentRoute: () => Route$
|
|
9509
|
+
getParentRoute: () => Route$61
|
|
8770
9510
|
});
|
|
8771
|
-
var ApiSessionSelectRoute = Route$
|
|
9511
|
+
var ApiSessionSelectRoute = Route$26.update({
|
|
8772
9512
|
id: "/api/session/select",
|
|
8773
9513
|
path: "/api/session/select",
|
|
8774
|
-
getParentRoute: () => Route$
|
|
9514
|
+
getParentRoute: () => Route$61
|
|
8775
9515
|
});
|
|
8776
|
-
var ApiSessionRenameRoute = Route$
|
|
9516
|
+
var ApiSessionRenameRoute = Route$25.update({
|
|
8777
9517
|
id: "/api/session/rename",
|
|
8778
9518
|
path: "/api/session/rename",
|
|
8779
|
-
getParentRoute: () => Route$
|
|
9519
|
+
getParentRoute: () => Route$61
|
|
8780
9520
|
});
|
|
8781
|
-
var ApiSessionReadStateRoute = Route$
|
|
9521
|
+
var ApiSessionReadStateRoute = Route$24.update({
|
|
8782
9522
|
id: "/api/session/read-state",
|
|
8783
9523
|
path: "/api/session/read-state",
|
|
8784
|
-
getParentRoute: () => Route$
|
|
9524
|
+
getParentRoute: () => Route$61
|
|
8785
9525
|
});
|
|
8786
|
-
var ApiSessionNewRoute = Route$
|
|
9526
|
+
var ApiSessionNewRoute = Route$23.update({
|
|
8787
9527
|
id: "/api/session/new",
|
|
8788
9528
|
path: "/api/session/new",
|
|
8789
|
-
getParentRoute: () => Route$
|
|
9529
|
+
getParentRoute: () => Route$61
|
|
9530
|
+
});
|
|
9531
|
+
var ApiSessionNameRoute = Route$22.update({
|
|
9532
|
+
id: "/api/session/name",
|
|
9533
|
+
path: "/api/session/name",
|
|
9534
|
+
getParentRoute: () => Route$61
|
|
8790
9535
|
});
|
|
8791
|
-
var ApiSessionMoveRoute = Route$
|
|
9536
|
+
var ApiSessionMoveRoute = Route$21.update({
|
|
8792
9537
|
id: "/api/session/move",
|
|
8793
9538
|
path: "/api/session/move",
|
|
8794
|
-
getParentRoute: () => Route$
|
|
9539
|
+
getParentRoute: () => Route$61
|
|
8795
9540
|
});
|
|
8796
|
-
var ApiSessionHistoryRoute = Route$
|
|
9541
|
+
var ApiSessionHistoryRoute = Route$20.update({
|
|
8797
9542
|
id: "/api/session/history",
|
|
8798
9543
|
path: "/api/session/history",
|
|
8799
|
-
getParentRoute: () => Route$
|
|
9544
|
+
getParentRoute: () => Route$61
|
|
8800
9545
|
});
|
|
8801
|
-
var ApiSessionForkRoute = Route$
|
|
9546
|
+
var ApiSessionForkRoute = Route$19.update({
|
|
8802
9547
|
id: "/api/session/fork",
|
|
8803
9548
|
path: "/api/session/fork",
|
|
8804
|
-
getParentRoute: () => Route$
|
|
9549
|
+
getParentRoute: () => Route$61
|
|
8805
9550
|
});
|
|
8806
|
-
var ApiSessionDeleteRoute = Route$
|
|
9551
|
+
var ApiSessionDeleteRoute = Route$18.update({
|
|
8807
9552
|
id: "/api/session/delete",
|
|
8808
9553
|
path: "/api/session/delete",
|
|
8809
|
-
getParentRoute: () => Route$
|
|
9554
|
+
getParentRoute: () => Route$61
|
|
8810
9555
|
});
|
|
8811
|
-
var ApiSessionCloneRoute = Route$
|
|
9556
|
+
var ApiSessionCloneRoute = Route$17.update({
|
|
8812
9557
|
id: "/api/session/clone",
|
|
8813
9558
|
path: "/api/session/clone",
|
|
8814
|
-
getParentRoute: () => Route$
|
|
9559
|
+
getParentRoute: () => Route$61
|
|
8815
9560
|
});
|
|
8816
|
-
var
|
|
9561
|
+
var ApiPendingMessagesStartRoute = Route$16.update({
|
|
9562
|
+
id: "/api/pending-messages/start",
|
|
9563
|
+
path: "/api/pending-messages/start",
|
|
9564
|
+
getParentRoute: () => Route$61
|
|
9565
|
+
});
|
|
9566
|
+
var ApiPendingMessagesReorderRoute = Route$15.update({
|
|
8817
9567
|
id: "/api/pending-messages/reorder",
|
|
8818
9568
|
path: "/api/pending-messages/reorder",
|
|
8819
|
-
getParentRoute: () => Route$
|
|
9569
|
+
getParentRoute: () => Route$61
|
|
8820
9570
|
});
|
|
8821
|
-
var ApiPendingMessageRemoveRoute = Route$
|
|
9571
|
+
var ApiPendingMessageRemoveRoute = Route$14.update({
|
|
8822
9572
|
id: "/api/pending-message/remove",
|
|
8823
9573
|
path: "/api/pending-message/remove",
|
|
8824
|
-
getParentRoute: () => Route$
|
|
9574
|
+
getParentRoute: () => Route$61
|
|
8825
9575
|
});
|
|
8826
|
-
var ApiFilesTreeRoute = Route$
|
|
9576
|
+
var ApiFilesTreeRoute = Route$13.update({
|
|
8827
9577
|
id: "/api/files/tree",
|
|
8828
9578
|
path: "/api/files/tree",
|
|
8829
|
-
getParentRoute: () => Route$
|
|
9579
|
+
getParentRoute: () => Route$61
|
|
8830
9580
|
});
|
|
8831
|
-
var ApiFilesReadRoute = Route$
|
|
9581
|
+
var ApiFilesReadRoute = Route$12.update({
|
|
8832
9582
|
id: "/api/files/read",
|
|
8833
9583
|
path: "/api/files/read",
|
|
8834
|
-
getParentRoute: () => Route$
|
|
9584
|
+
getParentRoute: () => Route$61
|
|
8835
9585
|
});
|
|
8836
|
-
var ApiDirectoryResolveRoute = Route$
|
|
9586
|
+
var ApiDirectoryResolveRoute = Route$11.update({
|
|
8837
9587
|
id: "/api/directory/resolve",
|
|
8838
9588
|
path: "/api/directory/resolve",
|
|
8839
|
-
getParentRoute: () => Route$
|
|
9589
|
+
getParentRoute: () => Route$61
|
|
8840
9590
|
});
|
|
8841
|
-
var ApiDirectorySessionsCleanupRoute = Route$
|
|
9591
|
+
var ApiDirectorySessionsCleanupRoute = Route$10.update({
|
|
8842
9592
|
id: "/cleanup",
|
|
8843
9593
|
path: "/cleanup",
|
|
8844
9594
|
getParentRoute: () => ApiDirectorySessionsRoute
|
|
8845
9595
|
});
|
|
9596
|
+
var ApiClientManifestRoute = Route$9.update({
|
|
9597
|
+
id: "/api/client/manifest",
|
|
9598
|
+
path: "/api/client/manifest",
|
|
9599
|
+
getParentRoute: () => Route$61
|
|
9600
|
+
});
|
|
8846
9601
|
var ApiAuthProvidersRoute = Route$8.update({
|
|
8847
9602
|
id: "/api/auth/providers",
|
|
8848
9603
|
path: "/api/auth/providers",
|
|
8849
|
-
getParentRoute: () => Route$
|
|
9604
|
+
getParentRoute: () => Route$61
|
|
8850
9605
|
});
|
|
8851
9606
|
var ApiAuthOauthRoute = Route$7.update({
|
|
8852
9607
|
id: "/api/auth/oauth",
|
|
8853
9608
|
path: "/api/auth/oauth",
|
|
8854
|
-
getParentRoute: () => Route$
|
|
9609
|
+
getParentRoute: () => Route$61
|
|
8855
9610
|
});
|
|
8856
9611
|
var ApiAuthLogoutRoute = Route$6.update({
|
|
8857
9612
|
id: "/api/auth/logout",
|
|
8858
9613
|
path: "/api/auth/logout",
|
|
8859
|
-
getParentRoute: () => Route$
|
|
9614
|
+
getParentRoute: () => Route$61
|
|
8860
9615
|
});
|
|
8861
9616
|
var ApiAuthApiKeyRoute = Route$5.update({
|
|
8862
9617
|
id: "/api/auth/api-key",
|
|
8863
9618
|
path: "/api/auth/api-key",
|
|
8864
|
-
getParentRoute: () => Route$
|
|
9619
|
+
getParentRoute: () => Route$61
|
|
8865
9620
|
});
|
|
8866
9621
|
var ApiTerminalIdResizeRoute = Route$4.update({
|
|
8867
9622
|
id: "/$id/resize",
|
|
@@ -8934,16 +9689,19 @@ var rootRouteChildren = {
|
|
|
8934
9689
|
ApiAuthLogoutRoute,
|
|
8935
9690
|
ApiAuthOauthRoute,
|
|
8936
9691
|
ApiAuthProvidersRoute,
|
|
9692
|
+
ApiClientManifestRoute,
|
|
8937
9693
|
ApiDirectoryResolveRoute,
|
|
8938
9694
|
ApiFilesReadRoute,
|
|
8939
9695
|
ApiFilesTreeRoute,
|
|
8940
9696
|
ApiPendingMessageRemoveRoute,
|
|
8941
9697
|
ApiPendingMessagesReorderRoute,
|
|
9698
|
+
ApiPendingMessagesStartRoute,
|
|
8942
9699
|
ApiSessionCloneRoute,
|
|
8943
9700
|
ApiSessionDeleteRoute,
|
|
8944
9701
|
ApiSessionForkRoute,
|
|
8945
9702
|
ApiSessionHistoryRoute,
|
|
8946
9703
|
ApiSessionMoveRoute,
|
|
9704
|
+
ApiSessionNameRoute,
|
|
8947
9705
|
ApiSessionNewRoute,
|
|
8948
9706
|
ApiSessionReadStateRoute,
|
|
8949
9707
|
ApiSessionRenameRoute,
|
|
@@ -8953,7 +9711,7 @@ var rootRouteChildren = {
|
|
|
8953
9711
|
ApiSettingsHideThinkingRoute,
|
|
8954
9712
|
ApiUiIdRoute
|
|
8955
9713
|
};
|
|
8956
|
-
var routeTree = Route$
|
|
9714
|
+
var routeTree = Route$61._addFileChildren(rootRouteChildren)._addFileTypes();
|
|
8957
9715
|
function getRouter() {
|
|
8958
9716
|
const queryClient = new QueryClient({ defaultOptions: { queries: {
|
|
8959
9717
|
retry: 1,
|