@alivault/pico 0.9.0 → 0.10.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-BXfOqRXc.js → index-7ls3Zqfs.js} +10 -10
- package/.output/public/assets/routes-CNpFhMfH.js +2161 -0
- package/.output/public/assets/styles-oRWMaOB0.css +2 -0
- package/.output/server/_libs/@base-ui/react+[...].mjs +106 -1
- package/.output/server/_libs/@dnd-kit/core+[...].mjs +1 -1
- package/.output/server/_libs/@pierre/diffs+[...].mjs +2 -2
- package/.output/server/_libs/@pierre/trees+[...].mjs +1 -1
- package/.output/server/_libs/@radix-ui/react-dialog+[...].mjs +1 -1
- package/.output/server/_libs/@radix-ui/react-primitive+[...].mjs +1 -1
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
- package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +1 -1
- package/.output/server/_libs/cmdk.mjs +1 -1
- package/.output/server/_libs/dnd-kit__accessibility.mjs +1 -1
- package/.output/server/_libs/dnd-kit__sortable.mjs +1 -1
- package/.output/server/_libs/hast-util-from-parse5+[...].mjs +1 -1
- package/.output/server/_libs/hast-util-raw+[...].mjs +1 -1
- package/.output/server/_libs/hast-util-to-jsx-runtime+[...].mjs +1 -1
- package/.output/server/_libs/lucide-react.mjs +104 -11
- package/.output/server/_libs/mdast-util-gfm+[...].mjs +1 -1
- package/.output/server/_libs/next-themes.mjs +1 -1
- package/.output/server/_libs/radix-ui__react-compose-refs.mjs +1 -1
- package/.output/server/_libs/radix-ui__react-context.mjs +1 -1
- package/.output/server/_libs/react-markdown+[...].mjs +1 -1
- package/.output/server/_libs/sonner.mjs +1 -1
- package/.output/server/_libs/tanstack__react-hotkeys.mjs +1 -1
- package/.output/server/_libs/tanstack__react-query.mjs +1 -1
- package/.output/server/_libs/tanstack__react-store.mjs +1 -1
- package/.output/server/_libs/vaul.mjs +1 -1
- package/.output/server/_ssr/{router-DIdiRf-y.mjs → router-DhVJ7gcL.mjs} +1137 -423
- package/.output/server/_ssr/{routes-bPw2DezY.mjs → routes-DbGwM-bj.mjs} +51 -32
- package/.output/server/_ssr/{routes-7x8dHcec.mjs → routes-NB2wmfpS.mjs} +6227 -2516
- package/.output/server/_ssr/ssr.mjs +3 -3
- package/.output/server/{_tanstack-start-manifest_v-CMhyz9t-.mjs → _tanstack-start-manifest_v-DrOsJYxt.mjs} +9 -4
- package/.output/server/index.mjs +474 -474
- package/package.json +1 -1
- package/.output/public/assets/routes-CnNf4Tfg.js +0 -2160
- package/.output/public/assets/styles-DueiniTy.css +0 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as __toESM } from "../_runtime.mjs";
|
|
2
|
-
import {
|
|
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
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { I as CircleCheck, S as Info, _ as OctagonX, a as TriangleAlert } from "../_libs/lucide-react.mjs";
|
|
5
|
+
import { A as TooltipProvider, B as extractMessageImages, F as buildItemsFromSync, G as mergeAssistantBlocksForStreaming, H as extractToolText, L as createCompactionSummaryItem, P as assistantBlocksFromMessage, S as Spinner, St as toolCategoryFromTool, V as extractMessageText$1, n as APPLIED_THEME_STORAGE_KEY, t as APPLIED_THEME_CLASSES, v as Route$54 } from "./routes-DbGwM-bj.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";
|
|
@@ -20,7 +20,7 @@ import os, { homedir } from "node:os";
|
|
|
20
20
|
import { performance } from "node:perf_hooks";
|
|
21
21
|
import { isMainThread } from "node:worker_threads";
|
|
22
22
|
import { execSync, spawn } from "node:child_process";
|
|
23
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/router-
|
|
23
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/router-DhVJ7gcL.js
|
|
24
24
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
25
25
|
var import_jsx_runtime = require_jsx_runtime();
|
|
26
26
|
var Toaster$1 = ({ ...props }) => {
|
|
@@ -71,7 +71,7 @@ function AppProviders({ children }) {
|
|
|
71
71
|
})
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
|
-
var styles_default = "/assets/styles-
|
|
74
|
+
var styles_default = "/assets/styles-oRWMaOB0.css";
|
|
75
75
|
var TANSTACK_DEVTOOLS_SETTINGS_KEY = "tanstack_devtools_settings";
|
|
76
76
|
var TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY = "pico-tanstack-devtools-defaults-v1";
|
|
77
77
|
var TANSTACK_DEVTOOLS_CONFIG = {
|
|
@@ -79,7 +79,7 @@ var TANSTACK_DEVTOOLS_CONFIG = {
|
|
|
79
79
|
openHotkey: ["Control", "`"],
|
|
80
80
|
triggerHidden: true
|
|
81
81
|
};
|
|
82
|
-
var Route$
|
|
82
|
+
var Route$53 = createRootRoute({
|
|
83
83
|
head: () => ({
|
|
84
84
|
meta: [
|
|
85
85
|
{ charSet: "utf-8" },
|
|
@@ -142,25 +142,30 @@ function RootDocument({ children }) {
|
|
|
142
142
|
})]
|
|
143
143
|
});
|
|
144
144
|
}
|
|
145
|
+
function subscribeTanStackDevtoolsReady() {
|
|
146
|
+
return () => {};
|
|
147
|
+
}
|
|
148
|
+
function getTanStackDevtoolsReadySnapshot() {
|
|
149
|
+
try {
|
|
150
|
+
if (window.localStorage.getItem(TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY) !== "true") {
|
|
151
|
+
const rawSettings = window.localStorage.getItem(TANSTACK_DEVTOOLS_SETTINGS_KEY);
|
|
152
|
+
const parsedSettings = rawSettings ? JSON.parse(rawSettings) : void 0;
|
|
153
|
+
const existingSettings = parsedSettings && typeof parsedSettings === "object" && !Array.isArray(parsedSettings) ? parsedSettings : {};
|
|
154
|
+
window.localStorage.setItem(TANSTACK_DEVTOOLS_SETTINGS_KEY, JSON.stringify({
|
|
155
|
+
...existingSettings,
|
|
156
|
+
openHotkey: TANSTACK_DEVTOOLS_CONFIG.openHotkey,
|
|
157
|
+
triggerHidden: TANSTACK_DEVTOOLS_CONFIG.triggerHidden
|
|
158
|
+
}));
|
|
159
|
+
window.localStorage.setItem(TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY, "true");
|
|
160
|
+
}
|
|
161
|
+
} catch {}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
function getTanStackDevtoolsServerSnapshot() {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
145
167
|
function AppTanStackDevtools() {
|
|
146
|
-
|
|
147
|
-
import_react.useEffect(() => {
|
|
148
|
-
try {
|
|
149
|
-
if (window.localStorage.getItem(TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY) !== "true") {
|
|
150
|
-
const rawSettings = window.localStorage.getItem(TANSTACK_DEVTOOLS_SETTINGS_KEY);
|
|
151
|
-
const parsedSettings = rawSettings ? JSON.parse(rawSettings) : void 0;
|
|
152
|
-
const existingSettings = parsedSettings && typeof parsedSettings === "object" && !Array.isArray(parsedSettings) ? parsedSettings : {};
|
|
153
|
-
window.localStorage.setItem(TANSTACK_DEVTOOLS_SETTINGS_KEY, JSON.stringify({
|
|
154
|
-
...existingSettings,
|
|
155
|
-
openHotkey: TANSTACK_DEVTOOLS_CONFIG.openHotkey,
|
|
156
|
-
triggerHidden: TANSTACK_DEVTOOLS_CONFIG.triggerHidden
|
|
157
|
-
}));
|
|
158
|
-
window.localStorage.setItem(TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY, "true");
|
|
159
|
-
}
|
|
160
|
-
} catch {}
|
|
161
|
-
setIsReady(true);
|
|
162
|
-
}, []);
|
|
163
|
-
if (!isReady) return null;
|
|
168
|
+
if (!import_react.useSyncExternalStore(subscribeTanStackDevtoolsReady, getTanStackDevtoolsReadySnapshot, getTanStackDevtoolsServerSnapshot)) return null;
|
|
164
169
|
}
|
|
165
170
|
var PI_CODING_AGENT_PACKAGES = ["@earendil-works/pi-coding-agent", "@mariozechner/pi-coding-agent"];
|
|
166
171
|
function normalizeSdkDir(candidate) {
|
|
@@ -455,7 +460,7 @@ async function generateSessionNameWithLlm(entry, text, imageCount) {
|
|
|
455
460
|
headers: auth.headers,
|
|
456
461
|
reasoningEffort: "minimal"
|
|
457
462
|
});
|
|
458
|
-
const raw = Array.isArray(response?.content) ? response.content.
|
|
463
|
+
const raw = Array.isArray(response?.content) ? response.content.flatMap((block) => block?.type === "text" && typeof block.text === "string" ? [block.text] : []).join(" ") : "";
|
|
459
464
|
if (!raw.trim()) return { reason: `refinement model ${model.provider}/${model.id} returned no text` };
|
|
460
465
|
const cleaned = cleanupSessionNameCandidate(raw);
|
|
461
466
|
if (!cleaned) return { reason: `refinement model ${model.provider}/${model.id} returned no usable title` };
|
|
@@ -524,15 +529,15 @@ async function resolveRequestedEntry(options) {
|
|
|
524
529
|
const requestedEntry = getSessionEntryByKey(requestedSessionKey);
|
|
525
530
|
if (requestedEntry) return await activateRequestedEntry(requestedEntry);
|
|
526
531
|
}
|
|
527
|
-
if (preferActiveDraft && context.draftKey) {
|
|
528
|
-
const draftEntry = getSessionEntryByKey(context.draftKey);
|
|
529
|
-
if (draftEntry && isDraftEntry(draftEntry)) return await activateRequestedEntry(draftEntry);
|
|
530
|
-
}
|
|
531
532
|
const requestedSessionId = url.searchParams.get("session");
|
|
532
533
|
if (requestedSessionId) {
|
|
533
534
|
const requestedEntry = await ensureSessionEntryById(requestedSessionId);
|
|
534
535
|
if (requestedEntry) return await activateRequestedEntry(requestedEntry);
|
|
535
536
|
}
|
|
537
|
+
if (preferActiveDraft && context.draftKey) {
|
|
538
|
+
const draftEntry = getSessionEntryByKey(context.draftKey);
|
|
539
|
+
if (draftEntry && isDraftEntry(draftEntry)) return await activateRequestedEntry(draftEntry);
|
|
540
|
+
}
|
|
536
541
|
const activeEntry = getActiveEntry(context);
|
|
537
542
|
if (activeEntry) return await activateRequestedEntry(activeEntry);
|
|
538
543
|
return await getOrCreateDraftEntry(context);
|
|
@@ -743,7 +748,14 @@ function updateToolBlock(state, callId, update) {
|
|
|
743
748
|
for (let itemIndex = state.items.length - 1; itemIndex >= 0; itemIndex -= 1) {
|
|
744
749
|
const item = state.items[itemIndex];
|
|
745
750
|
if (item?.kind !== "assistant") continue;
|
|
746
|
-
|
|
751
|
+
let blockIndex = -1;
|
|
752
|
+
for (let index = item.blocks.length - 1; index >= 0; index -= 1) {
|
|
753
|
+
const block = item.blocks[index];
|
|
754
|
+
if (block?.type === "tool" && block.callId === callId) {
|
|
755
|
+
blockIndex = index;
|
|
756
|
+
break;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
747
759
|
if (blockIndex < 0) continue;
|
|
748
760
|
const block = item.blocks[blockIndex];
|
|
749
761
|
if (block?.type !== "tool") return;
|
|
@@ -936,7 +948,8 @@ function applyRetainedConversationEvent(state, event) {
|
|
|
936
948
|
}];
|
|
937
949
|
return;
|
|
938
950
|
}
|
|
939
|
-
state.items = state.items.
|
|
951
|
+
state.items = state.items.flatMap((entry) => {
|
|
952
|
+
if (entry.kind === "assistant" && entry.streaming && entry.blocks.length === 0) return [];
|
|
940
953
|
if (entry.kind !== "assistant") return entry;
|
|
941
954
|
if (!entry.streaming && entry.done !== false) return entry;
|
|
942
955
|
return {
|
|
@@ -967,7 +980,7 @@ function extractSessionListMessageText(message) {
|
|
|
967
980
|
const content = message.content;
|
|
968
981
|
if (typeof content === "string") return content;
|
|
969
982
|
if (!Array.isArray(content)) return "";
|
|
970
|
-
return content.
|
|
983
|
+
return content.flatMap((part) => isRecord(part) && part.type === "text" ? [typeof part.text === "string" ? part.text : ""] : []).join("\n");
|
|
971
984
|
}
|
|
972
985
|
function extractSessionListImagePreview(message) {
|
|
973
986
|
const content = message.content;
|
|
@@ -1100,40 +1113,85 @@ function countFullTurnUserAndAssistantMessages(messages) {
|
|
|
1100
1113
|
finishTurn(false);
|
|
1101
1114
|
return count;
|
|
1102
1115
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
let
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1116
|
+
function readSessionListMetricEntries(content) {
|
|
1117
|
+
const entries = [];
|
|
1118
|
+
for (const line of content.split("\n")) {
|
|
1119
|
+
if (!line.trim()) continue;
|
|
1120
|
+
let entry;
|
|
1121
|
+
try {
|
|
1122
|
+
entry = JSON.parse(line);
|
|
1123
|
+
} catch {
|
|
1124
|
+
continue;
|
|
1125
|
+
}
|
|
1126
|
+
if (!isRecord(entry) || entry.type === "session") continue;
|
|
1127
|
+
entries.push(entry);
|
|
1128
|
+
}
|
|
1129
|
+
return entries;
|
|
1130
|
+
}
|
|
1131
|
+
function sessionListMetricEntryId(entry) {
|
|
1132
|
+
return typeof entry.id === "string" && entry.id ? entry.id : "";
|
|
1133
|
+
}
|
|
1134
|
+
function sessionListMetricEntryParentId(entry) {
|
|
1135
|
+
return typeof entry.parentId === "string" && entry.parentId ? entry.parentId : "";
|
|
1136
|
+
}
|
|
1137
|
+
function sessionListMetricBranchEntries(entries, leafId) {
|
|
1138
|
+
if (leafId === void 0) return entries;
|
|
1139
|
+
if (leafId === null) return [];
|
|
1140
|
+
const byId = new Map(entries.flatMap((entry) => {
|
|
1141
|
+
const id = sessionListMetricEntryId(entry);
|
|
1142
|
+
return id ? [[id, entry]] : [];
|
|
1143
|
+
}));
|
|
1144
|
+
const leaf = byId.get(leafId);
|
|
1145
|
+
if (!leaf) return entries;
|
|
1146
|
+
const branch = [];
|
|
1147
|
+
let current = leaf;
|
|
1148
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1149
|
+
while (current) {
|
|
1150
|
+
const id = sessionListMetricEntryId(current);
|
|
1151
|
+
if (id) {
|
|
1152
|
+
if (visited.has(id)) break;
|
|
1153
|
+
visited.add(id);
|
|
1154
|
+
}
|
|
1155
|
+
branch.unshift(current);
|
|
1156
|
+
const parentId = sessionListMetricEntryParentId(current);
|
|
1157
|
+
current = parentId ? byId.get(parentId) : void 0;
|
|
1158
|
+
}
|
|
1159
|
+
return branch;
|
|
1160
|
+
}
|
|
1161
|
+
function collectSessionListMetricMessages(entries) {
|
|
1162
|
+
let lastTimestamp = 0;
|
|
1163
|
+
let lastValue;
|
|
1164
|
+
const messages = [];
|
|
1165
|
+
for (const entry of entries) {
|
|
1166
|
+
if (entry.type !== "message") continue;
|
|
1167
|
+
const message = isRecord(entry.message) ? entry.message : void 0;
|
|
1168
|
+
if (!message) continue;
|
|
1169
|
+
const messageWithTimestamp = {
|
|
1170
|
+
...message,
|
|
1171
|
+
timestamp: message.timestamp ?? entry.timestamp
|
|
1172
|
+
};
|
|
1173
|
+
if (messageWithTimestamp.role === "user") {
|
|
1174
|
+
const normalized = normalizeModifiedTimestamp(messageWithTimestamp.timestamp);
|
|
1175
|
+
const timestamp = modifiedTimestampValue(normalized);
|
|
1176
|
+
if (timestamp && timestamp >= lastTimestamp) {
|
|
1177
|
+
lastTimestamp = timestamp;
|
|
1178
|
+
lastValue = normalized;
|
|
1131
1179
|
}
|
|
1132
|
-
if (messageWithTimestamp.role === "user" || messageWithTimestamp.role === "assistant") messages.push(messageWithTimestamp);
|
|
1133
1180
|
}
|
|
1181
|
+
if (messageWithTimestamp.role === "user" || messageWithTimestamp.role === "assistant") messages.push(messageWithTimestamp);
|
|
1182
|
+
}
|
|
1183
|
+
return {
|
|
1184
|
+
lastUserMessageAt: lastValue,
|
|
1185
|
+
messages
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
async function readSessionListMetrics(sessionPath, options) {
|
|
1189
|
+
try {
|
|
1190
|
+
const entries = readSessionListMetricEntries(await readFile(sessionPath, "utf8"));
|
|
1191
|
+
const { lastUserMessageAt, messages } = collectSessionListMetricMessages(Object.prototype.hasOwnProperty.call(options ?? {}, "leafId") ? sessionListMetricBranchEntries(entries, options?.leafId) : entries);
|
|
1134
1192
|
const lastMessage = getSessionLastCompleteMessageInfo(messages);
|
|
1135
1193
|
return {
|
|
1136
|
-
lastUserMessageAt
|
|
1194
|
+
lastUserMessageAt,
|
|
1137
1195
|
lastMessageAt: lastMessage.timestamp,
|
|
1138
1196
|
lastMessagePreview: lastMessage.preview,
|
|
1139
1197
|
messageCount: countFullTurnUserAndAssistantMessages(messages)
|
|
@@ -1209,12 +1267,12 @@ function extractMessageText(message) {
|
|
|
1209
1267
|
const content = message.content;
|
|
1210
1268
|
if (typeof content === "string") return content.trim();
|
|
1211
1269
|
if (!Array.isArray(content)) return "";
|
|
1212
|
-
return content.
|
|
1270
|
+
return content.flatMap((part) => part?.type === "text" && typeof part.text === "string" ? [part.text] : []).join(" ").trim();
|
|
1213
1271
|
}
|
|
1214
1272
|
function extractSessionContentText(content) {
|
|
1215
1273
|
if (typeof content === "string") return content.trim();
|
|
1216
1274
|
if (!Array.isArray(content)) return "";
|
|
1217
|
-
const text = content.
|
|
1275
|
+
const text = content.flatMap((part) => part && typeof part === "object" && part.type === "text" && typeof part.text === "string" ? [part.text] : []).join(" ").trim();
|
|
1218
1276
|
if (text) return text;
|
|
1219
1277
|
const imageCount = content.filter((part) => part && typeof part === "object" && (part.type === "image" || part.type === "input_image")).length;
|
|
1220
1278
|
if (imageCount > 0) return `${imageCount} image${imageCount === 1 ? "" : "s"}`;
|
|
@@ -1318,15 +1376,22 @@ function serializeSessionTreeNode(node) {
|
|
|
1318
1376
|
if (entry.type === "custom") serialized.entry.customType = typeof entry.customType === "string" ? entry.customType : "custom";
|
|
1319
1377
|
if (entry.type === "label") serialized.entry.label = typeof entry.label === "string" ? entry.label : void 0;
|
|
1320
1378
|
if (entry.type === "session_info") serialized.entry.name = typeof entry.name === "string" ? entry.name : "";
|
|
1321
|
-
serialized.children = (Array.isArray(node.children) ? node.children : []).
|
|
1379
|
+
serialized.children = (Array.isArray(node.children) ? node.children : []).flatMap((child) => {
|
|
1380
|
+
const treeNode = serializeSessionTreeNode(child);
|
|
1381
|
+
return treeNode ? [treeNode] : [];
|
|
1382
|
+
});
|
|
1322
1383
|
return serialized;
|
|
1323
1384
|
}
|
|
1324
1385
|
function extractForkableUserMessages(entry) {
|
|
1325
1386
|
const messages = entry.session.getUserMessagesForForking?.();
|
|
1326
|
-
if (Array.isArray(messages) && messages.length > 0) return messages.
|
|
1327
|
-
entryId
|
|
1328
|
-
text
|
|
1329
|
-
|
|
1387
|
+
if (Array.isArray(messages) && messages.length > 0) return messages.flatMap((message) => {
|
|
1388
|
+
const entryId = typeof message.entryId === "string" ? message.entryId.trim() : "";
|
|
1389
|
+
const text = typeof message.text === "string" ? message.text.trim() : "";
|
|
1390
|
+
return entryId && text ? [{
|
|
1391
|
+
entryId,
|
|
1392
|
+
text
|
|
1393
|
+
}] : [];
|
|
1394
|
+
});
|
|
1330
1395
|
const stack = [...entry.session.sessionManager.getTree?.() ?? []];
|
|
1331
1396
|
const results = [];
|
|
1332
1397
|
while (stack.length > 0) {
|
|
@@ -1351,7 +1416,7 @@ async function createForkedInMemorySessionManager(options) {
|
|
|
1351
1416
|
if (!leafId) return nextManager;
|
|
1352
1417
|
const branchEntries = sourceManager.getBranch?.(leafId);
|
|
1353
1418
|
if (!Array.isArray(branchEntries) || branchEntries.length === 0) throw new Error(`Entry ${leafId} not found`);
|
|
1354
|
-
const pathWithoutLabels = branchEntries.
|
|
1419
|
+
const pathWithoutLabels = branchEntries.flatMap((branchEntry) => branchEntry?.type !== "label" ? [cloneSessionData(branchEntry)] : []);
|
|
1355
1420
|
const header = cloneSessionData(sourceManager.getHeader?.() ?? nextManager.fileEntries?.[0]);
|
|
1356
1421
|
if (!header) throw new Error("Failed to initialize forked in-memory session.");
|
|
1357
1422
|
nextManager.fileEntries = [header, ...pathWithoutLabels];
|
|
@@ -1471,6 +1536,9 @@ async function createPicoEditToolDefinition(sdk, cwd) {
|
|
|
1471
1536
|
}
|
|
1472
1537
|
};
|
|
1473
1538
|
}
|
|
1539
|
+
function gitTextContains(text, query) {
|
|
1540
|
+
return text.indexOf(query) >= 0;
|
|
1541
|
+
}
|
|
1474
1542
|
var GIT_STATUS_CACHE_TTL_MS = 5e3;
|
|
1475
1543
|
var GIT_CHANGES_CACHE_TTL_MS = 5e3;
|
|
1476
1544
|
var GIT_COMMITS_DEFAULT_LIMIT = 50;
|
|
@@ -1655,7 +1723,10 @@ function parseCommandNullList(output) {
|
|
|
1655
1723
|
return output.split("\0").filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
1656
1724
|
}
|
|
1657
1725
|
function parseCommandLines(output, { trim = false } = {}) {
|
|
1658
|
-
return output.split(/\r?\n/).
|
|
1726
|
+
return output.split(/\r?\n/).flatMap((entry) => {
|
|
1727
|
+
const line = trim ? entry.trim() : entry;
|
|
1728
|
+
return trim ? line ? [line] : [] : line.length ? [line] : [];
|
|
1729
|
+
});
|
|
1659
1730
|
}
|
|
1660
1731
|
function isGitCommitGraphLine(line) {
|
|
1661
1732
|
const tabIndex = line.indexOf(" ");
|
|
@@ -1711,7 +1782,10 @@ function enrichGitCommitGraphLinesWithStats(lines, statsByHash) {
|
|
|
1711
1782
|
});
|
|
1712
1783
|
}
|
|
1713
1784
|
function gitCommandErrorMessage(fallback, result) {
|
|
1714
|
-
const details = [result.stderr, result.stdout].
|
|
1785
|
+
const details = [result.stderr, result.stdout].flatMap((value) => {
|
|
1786
|
+
const detail = value.trim();
|
|
1787
|
+
return detail ? [detail] : [];
|
|
1788
|
+
}).join("\n");
|
|
1715
1789
|
if (result.timedOut) return `${fallback}: command timed out`;
|
|
1716
1790
|
if (details) return `${fallback}: ${details}`;
|
|
1717
1791
|
return fallback;
|
|
@@ -1743,7 +1817,10 @@ function deriveHeuristicCommitMessage(files) {
|
|
|
1743
1817
|
}
|
|
1744
1818
|
if (addedCount > modifiedCount && addedCount >= deletedCount) return `Add ${files.length} files`;
|
|
1745
1819
|
if (deletedCount > modifiedCount && deletedCount >= addedCount) return `Remove ${files.length} files`;
|
|
1746
|
-
const commonDirectory = files.
|
|
1820
|
+
const commonDirectory = files.flatMap((file) => {
|
|
1821
|
+
const directory = file.path.split("/").slice(0, -1).join("/");
|
|
1822
|
+
return directory ? [directory] : [];
|
|
1823
|
+
}).reduce((common, directory) => {
|
|
1747
1824
|
if (common === void 0) return directory;
|
|
1748
1825
|
return common === directory ? common : "";
|
|
1749
1826
|
}, void 0);
|
|
@@ -1771,12 +1848,31 @@ function parseGitStatusEntries(output) {
|
|
|
1771
1848
|
}
|
|
1772
1849
|
return files;
|
|
1773
1850
|
}
|
|
1851
|
+
function parseGitNameStatusEntries(output) {
|
|
1852
|
+
const entries = parseCommandNullList(output);
|
|
1853
|
+
const files = [];
|
|
1854
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
1855
|
+
const status = entries[index];
|
|
1856
|
+
if (typeof status !== "string" || !status) continue;
|
|
1857
|
+
const isRenamedOrCopied = status.startsWith("R") || status.startsWith("C");
|
|
1858
|
+
const previousPath = isRenamedOrCopied ? entries[index + 1] : void 0;
|
|
1859
|
+
const filePath = isRenamedOrCopied ? entries[index + 2] : entries[index + 1];
|
|
1860
|
+
index += isRenamedOrCopied ? 2 : 1;
|
|
1861
|
+
if (typeof filePath !== "string" || !filePath) continue;
|
|
1862
|
+
files.push({
|
|
1863
|
+
status: /^[RC]\d+/.test(status) ? status.slice(0, 1) : status,
|
|
1864
|
+
path: filePath,
|
|
1865
|
+
...typeof previousPath === "string" && previousPath ? { previousPath } : {}
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
1868
|
+
return files;
|
|
1869
|
+
}
|
|
1774
1870
|
function parseGitNumstatEntries(output) {
|
|
1775
1871
|
const entries = parseCommandNullList(output);
|
|
1776
1872
|
const diffs = /* @__PURE__ */ new Map();
|
|
1777
1873
|
for (let index = 0; index < entries.length; index += 1) {
|
|
1778
1874
|
const entry = entries[index];
|
|
1779
|
-
if (typeof entry !== "string" || !entry
|
|
1875
|
+
if (typeof entry !== "string" || !gitTextContains(entry, " ")) continue;
|
|
1780
1876
|
const [addedRaw = "", deletedRaw = "", ...pathParts] = entry.split(" ");
|
|
1781
1877
|
let filePath = pathParts.join(" ");
|
|
1782
1878
|
let previousPath;
|
|
@@ -1797,7 +1893,10 @@ function parseGitNumstatEntries(output) {
|
|
|
1797
1893
|
return diffs;
|
|
1798
1894
|
}
|
|
1799
1895
|
function parseGitRefRows(output) {
|
|
1800
|
-
return parseCommandLines(output).
|
|
1896
|
+
return parseCommandLines(output).flatMap((line) => {
|
|
1897
|
+
const fields = line.split("\0");
|
|
1898
|
+
return fields.some((field) => typeof field === "string" && field.length > 0) ? [fields] : [];
|
|
1899
|
+
});
|
|
1801
1900
|
}
|
|
1802
1901
|
function parseGitBranchTrack(track, upstream) {
|
|
1803
1902
|
const trackValue = typeof track === "string" ? track.trim() : "";
|
|
@@ -1852,12 +1951,28 @@ function assertGitFilePath(path) {
|
|
|
1852
1951
|
if (normalizedPath.split(/[\\/]+/).some((part) => part === "..")) throw new Error("file path must stay inside the repository");
|
|
1853
1952
|
return normalizedPath.replaceAll("\\", "/");
|
|
1854
1953
|
}
|
|
1954
|
+
function assertGitCommitHash(commit) {
|
|
1955
|
+
const normalizedCommit = typeof commit === "string" ? commit.trim() : "";
|
|
1956
|
+
if (!normalizedCommit) throw new Error("commit is required");
|
|
1957
|
+
if (!/^[0-9a-f]{5,40}$/i.test(normalizedCommit)) throw new Error("commit must be a valid hash");
|
|
1958
|
+
return normalizedCommit;
|
|
1959
|
+
}
|
|
1960
|
+
function assertGitTagName(tagName) {
|
|
1961
|
+
const normalizedTagName = typeof tagName === "string" ? tagName.trim() : "";
|
|
1962
|
+
if (!normalizedTagName) throw new Error("tag name is required");
|
|
1963
|
+
if (normalizedTagName.startsWith("-") || /\s/.test(normalizedTagName)) throw new Error("Invalid tag name");
|
|
1964
|
+
return normalizedTagName;
|
|
1965
|
+
}
|
|
1966
|
+
function normalizeGitResetMode(mode) {
|
|
1967
|
+
if (mode === "soft" || mode === "mixed" || mode === "hard") return mode;
|
|
1968
|
+
throw new Error("reset mode must be soft, mixed, or hard");
|
|
1969
|
+
}
|
|
1855
1970
|
function parseGitRemoteBranches(output) {
|
|
1856
1971
|
const branches = [];
|
|
1857
1972
|
for (const fields of parseGitRefRows(output)) {
|
|
1858
1973
|
const [name = "", hash = "", subject = "", relativeDate = "", committerDate = ""] = fields;
|
|
1859
1974
|
const branchName = typeof name === "string" ? name.trim() : "";
|
|
1860
|
-
if (!branchName || !branchName
|
|
1975
|
+
if (!branchName || !gitTextContains(branchName, "/") || /\/HEAD$/i.test(branchName)) continue;
|
|
1861
1976
|
branches.push({
|
|
1862
1977
|
name: branchName,
|
|
1863
1978
|
hash: typeof hash === "string" && hash.trim() ? hash.trim() : void 0,
|
|
@@ -2086,11 +2201,12 @@ async function readDirectoryGitFileReview(cwd, path, previousPath) {
|
|
|
2086
2201
|
const normalizedPreviousPath = previousPath ? assertGitFilePath(previousPath) : void 0;
|
|
2087
2202
|
if (!normalizedCwd) return null;
|
|
2088
2203
|
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2204
|
+
const [oldContent, newContent] = await Promise.all([readGitHeadFileContent(normalizedCwd, normalizedPreviousPath || normalizedPath), readWorktreeFileContent(normalizedCwd, normalizedPath)]);
|
|
2089
2205
|
return {
|
|
2090
2206
|
path: normalizedPath,
|
|
2091
2207
|
previousPath: normalizedPreviousPath,
|
|
2092
|
-
oldContent
|
|
2093
|
-
newContent
|
|
2208
|
+
oldContent,
|
|
2209
|
+
newContent
|
|
2094
2210
|
};
|
|
2095
2211
|
}
|
|
2096
2212
|
async function readDirectoryGitFileDiff(cwd, path) {
|
|
@@ -2409,14 +2525,20 @@ async function readUnpushedCommitMessages(cwd) {
|
|
|
2409
2525
|
});
|
|
2410
2526
|
return result.code === 0 ? parseCommandLines(result.stdout, { trim: true }).filter(Boolean) : [];
|
|
2411
2527
|
}
|
|
2528
|
+
async function runGitPushCommand(cwd, context) {
|
|
2529
|
+
return await runCommand("git", context.force ? ["push", "--force-with-lease"] : ["push"], {
|
|
2530
|
+
cwd,
|
|
2531
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2532
|
+
});
|
|
2533
|
+
}
|
|
2412
2534
|
async function pushDirectoryGitChanges(cwd, { force = false } = {}) {
|
|
2413
2535
|
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2414
2536
|
if (!normalizedCwd) throw new Error("cwd is required");
|
|
2415
2537
|
if (!await isInsideWorkTree(normalizedCwd)) throw new Error("No git repository detected");
|
|
2416
2538
|
const pushedCommitMessages = await readUnpushedCommitMessages(normalizedCwd);
|
|
2417
|
-
const result = await
|
|
2418
|
-
|
|
2419
|
-
|
|
2539
|
+
const result = await runGitPushCommand(normalizedCwd, {
|
|
2540
|
+
force,
|
|
2541
|
+
pushedCommitMessages
|
|
2420
2542
|
});
|
|
2421
2543
|
if (result.code !== 0) throw new Error(gitCommandErrorMessage(force ? "Failed to force push changes" : "Failed to push changes", result));
|
|
2422
2544
|
invalidateDirectoryGitCaches(normalizedCwd);
|
|
@@ -2467,6 +2589,294 @@ async function checkoutDirectoryGitBranch(cwd, branch, options = {}) {
|
|
|
2467
2589
|
stderr: result.stderr
|
|
2468
2590
|
};
|
|
2469
2591
|
}
|
|
2592
|
+
function gitCommitActionLabel(action) {
|
|
2593
|
+
switch (action) {
|
|
2594
|
+
case "checkout": return "checkout commit";
|
|
2595
|
+
case "cherry-pick": return "cherry-pick commit";
|
|
2596
|
+
case "revert": return "revert commit";
|
|
2597
|
+
case "tag": return "tag commit";
|
|
2598
|
+
case "reset": return "reset branch";
|
|
2599
|
+
case "rebase": return "rebase branch";
|
|
2600
|
+
case "drop": return "drop commit";
|
|
2601
|
+
case "squash": return "squash commits";
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
function remoteBaseUrlFromGitUrl(remoteUrl) {
|
|
2605
|
+
const trimmed = remoteUrl.trim();
|
|
2606
|
+
if (!trimmed) return "";
|
|
2607
|
+
const scpLikeMatch = trimmed.match(/^git@([^:]+):(.+)$/);
|
|
2608
|
+
if (scpLikeMatch) {
|
|
2609
|
+
const host = scpLikeMatch[1];
|
|
2610
|
+
const path = scpLikeMatch[2]?.replace(/\.git$/i, "");
|
|
2611
|
+
return host && path ? `https://${host}/${path}` : "";
|
|
2612
|
+
}
|
|
2613
|
+
try {
|
|
2614
|
+
const url = new URL(trimmed);
|
|
2615
|
+
if (url.protocol === "ssh:" && url.username === "git") return `https://${url.host}${url.pathname.replace(/\.git$/i, "")}`;
|
|
2616
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
2617
|
+
url.username = "";
|
|
2618
|
+
url.password = "";
|
|
2619
|
+
url.pathname = url.pathname.replace(/\.git$/i, "");
|
|
2620
|
+
url.search = "";
|
|
2621
|
+
url.hash = "";
|
|
2622
|
+
return url.toString().replace(/\/$/, "");
|
|
2623
|
+
}
|
|
2624
|
+
} catch {}
|
|
2625
|
+
return "";
|
|
2626
|
+
}
|
|
2627
|
+
function commitUrlPathForHost(host, commit) {
|
|
2628
|
+
return host.toLowerCase().includes("gitlab") ? `/-/commit/${commit}` : `/commit/${commit}`;
|
|
2629
|
+
}
|
|
2630
|
+
async function readPrimaryRemoteName(cwd) {
|
|
2631
|
+
const branchResult = await runCommand("git", [
|
|
2632
|
+
"symbolic-ref",
|
|
2633
|
+
"--quiet",
|
|
2634
|
+
"--short",
|
|
2635
|
+
"HEAD"
|
|
2636
|
+
], {
|
|
2637
|
+
cwd,
|
|
2638
|
+
timeoutMs: 1500
|
|
2639
|
+
});
|
|
2640
|
+
const branch = branchResult.code === 0 ? branchResult.stdout.trim() : "";
|
|
2641
|
+
if (branch) {
|
|
2642
|
+
const branchRemoteResult = await runCommand("git", [
|
|
2643
|
+
"config",
|
|
2644
|
+
"--get",
|
|
2645
|
+
`branch.${branch}.remote`
|
|
2646
|
+
], {
|
|
2647
|
+
cwd,
|
|
2648
|
+
timeoutMs: 1500
|
|
2649
|
+
});
|
|
2650
|
+
const branchRemote = branchRemoteResult.stdout.trim();
|
|
2651
|
+
if (branchRemoteResult.code === 0 && branchRemote) return branchRemote;
|
|
2652
|
+
}
|
|
2653
|
+
const pushDefaultResult = await runCommand("git", [
|
|
2654
|
+
"config",
|
|
2655
|
+
"--get",
|
|
2656
|
+
"remote.pushDefault"
|
|
2657
|
+
], {
|
|
2658
|
+
cwd,
|
|
2659
|
+
timeoutMs: 1500
|
|
2660
|
+
});
|
|
2661
|
+
const pushDefault = pushDefaultResult.stdout.trim();
|
|
2662
|
+
if (pushDefaultResult.code === 0 && pushDefault) return pushDefault;
|
|
2663
|
+
return "origin";
|
|
2664
|
+
}
|
|
2665
|
+
async function readDirectoryGitCommitFiles(cwd, commit) {
|
|
2666
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2667
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2668
|
+
if (!normalizedCwd) return null;
|
|
2669
|
+
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2670
|
+
const [statusResult, numstatResult] = await Promise.all([runCommand("git", [
|
|
2671
|
+
"show",
|
|
2672
|
+
"--name-status",
|
|
2673
|
+
"-z",
|
|
2674
|
+
"--find-renames=50%",
|
|
2675
|
+
"--format=",
|
|
2676
|
+
normalizedCommit
|
|
2677
|
+
], {
|
|
2678
|
+
cwd: normalizedCwd,
|
|
2679
|
+
timeoutMs: 1e4
|
|
2680
|
+
}), runCommand("git", [
|
|
2681
|
+
"show",
|
|
2682
|
+
"--numstat",
|
|
2683
|
+
"-z",
|
|
2684
|
+
"--find-renames=50%",
|
|
2685
|
+
"--format=",
|
|
2686
|
+
normalizedCommit
|
|
2687
|
+
], {
|
|
2688
|
+
cwd: normalizedCwd,
|
|
2689
|
+
timeoutMs: 1e4
|
|
2690
|
+
})]);
|
|
2691
|
+
if (statusResult.code !== 0) throw new Error(gitCommandErrorMessage("Failed to read commit files", statusResult));
|
|
2692
|
+
if (numstatResult.code !== 0) throw new Error(gitCommandErrorMessage("Failed to read commit file stats", numstatResult));
|
|
2693
|
+
const stats = parseGitNumstatEntries(numstatResult.stdout);
|
|
2694
|
+
return parseGitNameStatusEntries(statusResult.stdout).map((file) => ({
|
|
2695
|
+
...file,
|
|
2696
|
+
...stats.get(file.path)
|
|
2697
|
+
}));
|
|
2698
|
+
}
|
|
2699
|
+
async function readDirectoryGitCommitDiff(cwd, commit, mode = "commit", path, previousPath) {
|
|
2700
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2701
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2702
|
+
const normalizedPath = path ? assertGitFilePath(path) : void 0;
|
|
2703
|
+
const normalizedPreviousPath = previousPath ? assertGitFilePath(previousPath) : void 0;
|
|
2704
|
+
if (!normalizedCwd) return null;
|
|
2705
|
+
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2706
|
+
const pathArgs = normalizedPath ? ["--", ...uniqueGitActionPaths([normalizedPreviousPath, normalizedPath])] : [];
|
|
2707
|
+
const result = await runCommand("git", mode === "head" ? [
|
|
2708
|
+
"diff",
|
|
2709
|
+
"--patch",
|
|
2710
|
+
"--no-color",
|
|
2711
|
+
"--no-ext-diff",
|
|
2712
|
+
"--find-renames=50%",
|
|
2713
|
+
`${normalizedCommit}..HEAD`,
|
|
2714
|
+
...pathArgs
|
|
2715
|
+
] : mode === "previous" ? [
|
|
2716
|
+
"diff",
|
|
2717
|
+
"--patch",
|
|
2718
|
+
"--no-color",
|
|
2719
|
+
"--no-ext-diff",
|
|
2720
|
+
"--find-renames=50%",
|
|
2721
|
+
`${normalizedCommit}^`,
|
|
2722
|
+
normalizedCommit,
|
|
2723
|
+
...pathArgs
|
|
2724
|
+
] : [
|
|
2725
|
+
"show",
|
|
2726
|
+
"--patch",
|
|
2727
|
+
"--no-color",
|
|
2728
|
+
"--no-ext-diff",
|
|
2729
|
+
"--find-renames=50%",
|
|
2730
|
+
"--format=",
|
|
2731
|
+
normalizedCommit,
|
|
2732
|
+
...pathArgs
|
|
2733
|
+
], {
|
|
2734
|
+
cwd: normalizedCwd,
|
|
2735
|
+
timeoutMs: 3e4
|
|
2736
|
+
});
|
|
2737
|
+
if (result.code !== 0) throw new Error(gitCommandErrorMessage("Failed to read commit diff", result));
|
|
2738
|
+
const title = mode === "head" ? `${normalizedCommit.slice(0, 7)}..HEAD` : mode === "previous" ? `${normalizedCommit.slice(0, 7)}^..${normalizedCommit.slice(0, 7)}` : normalizedCommit.slice(0, 7);
|
|
2739
|
+
return {
|
|
2740
|
+
commit: normalizedCommit,
|
|
2741
|
+
mode,
|
|
2742
|
+
title: normalizedPath ? `${title}:${normalizedPath}` : title,
|
|
2743
|
+
...normalizedPath ? { path: normalizedPath } : {},
|
|
2744
|
+
...normalizedPreviousPath ? { previousPath: normalizedPreviousPath } : {},
|
|
2745
|
+
patch: result.stdout.trim()
|
|
2746
|
+
};
|
|
2747
|
+
}
|
|
2748
|
+
async function readDirectoryGitCommitRemoteUrl(cwd, commit) {
|
|
2749
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2750
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2751
|
+
if (!normalizedCwd) return null;
|
|
2752
|
+
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2753
|
+
const remoteResult = await runCommand("git", [
|
|
2754
|
+
"remote",
|
|
2755
|
+
"get-url",
|
|
2756
|
+
await readPrimaryRemoteName(normalizedCwd)
|
|
2757
|
+
], {
|
|
2758
|
+
cwd: normalizedCwd,
|
|
2759
|
+
timeoutMs: 1500
|
|
2760
|
+
});
|
|
2761
|
+
if (remoteResult.code !== 0 || !remoteResult.stdout.trim()) throw new Error("No remote URL found");
|
|
2762
|
+
const baseUrl = remoteBaseUrlFromGitUrl(remoteResult.stdout);
|
|
2763
|
+
if (!baseUrl) throw new Error("Remote URL cannot be opened in the browser");
|
|
2764
|
+
return {
|
|
2765
|
+
commit: normalizedCommit,
|
|
2766
|
+
remoteUrl: `${baseUrl}${commitUrlPathForHost(new URL(baseUrl).host, normalizedCommit)}`
|
|
2767
|
+
};
|
|
2768
|
+
}
|
|
2769
|
+
async function runDirectoryGitCommitAction(cwd, action, commit, options = {}) {
|
|
2770
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2771
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2772
|
+
if (!normalizedCwd) throw new Error("cwd is required");
|
|
2773
|
+
if (!await isInsideWorkTree(normalizedCwd)) throw new Error("No git repository detected");
|
|
2774
|
+
let result;
|
|
2775
|
+
switch (action) {
|
|
2776
|
+
case "checkout":
|
|
2777
|
+
result = await runCommand("git", [
|
|
2778
|
+
"switch",
|
|
2779
|
+
"--detach",
|
|
2780
|
+
normalizedCommit
|
|
2781
|
+
], {
|
|
2782
|
+
cwd: normalizedCwd,
|
|
2783
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2784
|
+
});
|
|
2785
|
+
break;
|
|
2786
|
+
case "cherry-pick":
|
|
2787
|
+
result = await runCommand("git", ["cherry-pick", normalizedCommit], {
|
|
2788
|
+
cwd: normalizedCwd,
|
|
2789
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2790
|
+
});
|
|
2791
|
+
break;
|
|
2792
|
+
case "revert":
|
|
2793
|
+
result = await runCommand("git", [
|
|
2794
|
+
"revert",
|
|
2795
|
+
"--no-edit",
|
|
2796
|
+
normalizedCommit
|
|
2797
|
+
], {
|
|
2798
|
+
cwd: normalizedCwd,
|
|
2799
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2800
|
+
});
|
|
2801
|
+
break;
|
|
2802
|
+
case "tag":
|
|
2803
|
+
result = await runCommand("git", [
|
|
2804
|
+
"tag",
|
|
2805
|
+
assertGitTagName(options.tagName || ""),
|
|
2806
|
+
normalizedCommit
|
|
2807
|
+
], {
|
|
2808
|
+
cwd: normalizedCwd,
|
|
2809
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2810
|
+
});
|
|
2811
|
+
break;
|
|
2812
|
+
case "reset":
|
|
2813
|
+
result = await runCommand("git", [
|
|
2814
|
+
"reset",
|
|
2815
|
+
`--${normalizeGitResetMode(options.resetMode)}`,
|
|
2816
|
+
normalizedCommit
|
|
2817
|
+
], {
|
|
2818
|
+
cwd: normalizedCwd,
|
|
2819
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2820
|
+
});
|
|
2821
|
+
break;
|
|
2822
|
+
case "rebase":
|
|
2823
|
+
result = await runCommand("git", ["rebase", normalizedCommit], {
|
|
2824
|
+
cwd: normalizedCwd,
|
|
2825
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2826
|
+
});
|
|
2827
|
+
break;
|
|
2828
|
+
case "drop":
|
|
2829
|
+
result = await runCommand("git", [
|
|
2830
|
+
"rebase",
|
|
2831
|
+
"--onto",
|
|
2832
|
+
`${normalizedCommit}^`,
|
|
2833
|
+
normalizedCommit,
|
|
2834
|
+
"HEAD"
|
|
2835
|
+
], {
|
|
2836
|
+
cwd: normalizedCwd,
|
|
2837
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2838
|
+
});
|
|
2839
|
+
break;
|
|
2840
|
+
case "squash": {
|
|
2841
|
+
const message = cleanupCommitMessageCandidate(options.message || "");
|
|
2842
|
+
if (!message) throw new Error("commit message is required");
|
|
2843
|
+
const resetResult = await runCommand("git", [
|
|
2844
|
+
"reset",
|
|
2845
|
+
"--soft",
|
|
2846
|
+
normalizedCommit
|
|
2847
|
+
], {
|
|
2848
|
+
cwd: normalizedCwd,
|
|
2849
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2850
|
+
});
|
|
2851
|
+
if (resetResult.code !== 0) throw new Error(gitCommandErrorMessage("Failed to squash commits", resetResult));
|
|
2852
|
+
if ((await runCommand("git", [
|
|
2853
|
+
"diff",
|
|
2854
|
+
"--cached",
|
|
2855
|
+
"--quiet"
|
|
2856
|
+
], {
|
|
2857
|
+
cwd: normalizedCwd,
|
|
2858
|
+
timeoutMs: 5e3
|
|
2859
|
+
})).code === 0) throw new Error("No commits after this commit to squash");
|
|
2860
|
+
result = await runCommand("git", [
|
|
2861
|
+
"commit",
|
|
2862
|
+
"-m",
|
|
2863
|
+
message
|
|
2864
|
+
], {
|
|
2865
|
+
cwd: normalizedCwd,
|
|
2866
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2867
|
+
});
|
|
2868
|
+
result.stdout = [resetResult.stdout, result.stdout].filter(Boolean).join("\n");
|
|
2869
|
+
result.stderr = [resetResult.stderr, result.stderr].filter(Boolean).join("\n");
|
|
2870
|
+
break;
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
if (result.code !== 0) throw new Error(gitCommandErrorMessage(`Failed to ${gitCommitActionLabel(action)}`, result));
|
|
2874
|
+
invalidateDirectoryGitCaches(normalizedCwd);
|
|
2875
|
+
return {
|
|
2876
|
+
stdout: result.stdout,
|
|
2877
|
+
stderr: result.stderr
|
|
2878
|
+
};
|
|
2879
|
+
}
|
|
2470
2880
|
async function generateDirectoryGitCommitMessage(cwd, modelRegistry) {
|
|
2471
2881
|
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2472
2882
|
if (!normalizedCwd) throw new Error("cwd is required");
|
|
@@ -2544,7 +2954,7 @@ async function generateDirectoryGitCommitMessage(cwd, modelRegistry) {
|
|
|
2544
2954
|
headers: auth.headers,
|
|
2545
2955
|
reasoningEffort: "low"
|
|
2546
2956
|
});
|
|
2547
|
-
const message = cleanupCommitMessageCandidate(Array.isArray(response?.content) ? response.content.
|
|
2957
|
+
const message = cleanupCommitMessageCandidate(Array.isArray(response?.content) ? response.content.flatMap((block) => block?.type === "text" && typeof block.text === "string" ? [block.text] : []).join("\n") : "");
|
|
2548
2958
|
if (message) return {
|
|
2549
2959
|
message,
|
|
2550
2960
|
source: "ai"
|
|
@@ -2710,10 +3120,11 @@ var GitWatchManager = class {
|
|
|
2710
3120
|
}
|
|
2711
3121
|
async resolveDirectory(state) {
|
|
2712
3122
|
const generation = state.generation;
|
|
3123
|
+
if (this.directories.get(state.cwd) !== state) return;
|
|
2713
3124
|
const repository = await resolveDirectoryGitRepository(state.cwd).catch(() => null);
|
|
3125
|
+
if (!repository) return;
|
|
2714
3126
|
if (this.directories.get(state.cwd) !== state) return;
|
|
2715
3127
|
if (state.generation !== generation) return;
|
|
2716
|
-
if (!repository) return;
|
|
2717
3128
|
const repoKey = repositoryWatchKey(repository);
|
|
2718
3129
|
state.repoKey = repoKey;
|
|
2719
3130
|
(this.repositories.get(repoKey) ?? this.createRepositoryWatch(repoKey, repository)).subscribers.add(state.cwd);
|
|
@@ -3067,6 +3478,7 @@ function getApiKeyProviderDisplayName(providerId) {
|
|
|
3067
3478
|
return API_KEY_LOGIN_PROVIDER_NAMES[providerId] ?? providerId;
|
|
3068
3479
|
}
|
|
3069
3480
|
var STATE_SYNC_SCALAR_FIELDS = [
|
|
3481
|
+
"activationRevision",
|
|
3070
3482
|
"sessionKey",
|
|
3071
3483
|
"draft",
|
|
3072
3484
|
"streaming",
|
|
@@ -3144,7 +3556,10 @@ function sanitizeMessageContentPart(part) {
|
|
|
3144
3556
|
function sanitizeSessionMessage(message) {
|
|
3145
3557
|
const role = typeof message?.role === "string" ? message.role : "";
|
|
3146
3558
|
const metadata = message?.metadata && typeof message.metadata === "object" ? message.metadata : void 0;
|
|
3147
|
-
const sanitizedContent = Array.isArray(message?.content) ? message.content.
|
|
3559
|
+
const sanitizedContent = Array.isArray(message?.content) ? message.content.flatMap((part) => {
|
|
3560
|
+
const sanitizedPart = sanitizeMessageContentPart(part);
|
|
3561
|
+
return sanitizedPart ? [sanitizedPart] : [];
|
|
3562
|
+
}) : typeof message?.content === "string" ? message.content : void 0;
|
|
3148
3563
|
return {
|
|
3149
3564
|
...role ? { role } : {},
|
|
3150
3565
|
...sanitizedContent !== void 0 ? { content: sanitizedContent } : {},
|
|
@@ -3216,10 +3631,11 @@ function createStateSyncPatch(previous, next) {
|
|
|
3216
3631
|
let changed = false;
|
|
3217
3632
|
const patch = {
|
|
3218
3633
|
type: "state_sync",
|
|
3634
|
+
activationRevision: next.activationRevision,
|
|
3219
3635
|
sessionKey: next.sessionKey
|
|
3220
3636
|
};
|
|
3221
3637
|
for (const field of STATE_SYNC_SCALAR_FIELDS) {
|
|
3222
|
-
if (field === "sessionKey") continue;
|
|
3638
|
+
if (field === "activationRevision" || field === "sessionKey") continue;
|
|
3223
3639
|
const nextValue = next[field];
|
|
3224
3640
|
if (Object.is(previous.scalarValues[field], nextValue)) continue;
|
|
3225
3641
|
patch[field] = nextValue;
|
|
@@ -3254,17 +3670,17 @@ function createInitialUiState() {
|
|
|
3254
3670
|
}
|
|
3255
3671
|
function normalizePromptImages(rawImages) {
|
|
3256
3672
|
if (!Array.isArray(rawImages)) return [];
|
|
3257
|
-
return rawImages.
|
|
3258
|
-
if (!image || typeof image !== "object") return
|
|
3673
|
+
return rawImages.flatMap((image) => {
|
|
3674
|
+
if (!image || typeof image !== "object") return [];
|
|
3259
3675
|
const mimeType = typeof image.mimeType === "string" ? image.mimeType.trim() : "";
|
|
3260
3676
|
const data = typeof image.data === "string" ? image.data.trim() : "";
|
|
3261
|
-
if (!mimeType || !/^image\//i.test(mimeType) || !data) return
|
|
3262
|
-
return {
|
|
3677
|
+
if (!mimeType || !/^image\//i.test(mimeType) || !data) return [];
|
|
3678
|
+
return [{
|
|
3263
3679
|
type: "image",
|
|
3264
3680
|
mimeType,
|
|
3265
3681
|
data
|
|
3266
|
-
};
|
|
3267
|
-
}).
|
|
3682
|
+
}];
|
|
3683
|
+
}).slice(0, 8);
|
|
3268
3684
|
}
|
|
3269
3685
|
function serializeModel(model) {
|
|
3270
3686
|
if (!model) return void 0;
|
|
@@ -3317,6 +3733,7 @@ var PicoRuntime = class {
|
|
|
3317
3733
|
encoder = new TextEncoder();
|
|
3318
3734
|
contexts = /* @__PURE__ */ new Map();
|
|
3319
3735
|
sessionEntries = /* @__PURE__ */ new Map();
|
|
3736
|
+
sessionTreeLeafOverrides = /* @__PURE__ */ new Map();
|
|
3320
3737
|
servicesByCwd = /* @__PURE__ */ new Map();
|
|
3321
3738
|
pendingUiRequests = /* @__PURE__ */ new Map();
|
|
3322
3739
|
activeOAuthLogins = /* @__PURE__ */ new Map();
|
|
@@ -3471,7 +3888,10 @@ var PicoRuntime = class {
|
|
|
3471
3888
|
});
|
|
3472
3889
|
}
|
|
3473
3890
|
listAvailableModels(entry) {
|
|
3474
|
-
return entry.services.modelRegistry.getAvailable().
|
|
3891
|
+
return entry.services.modelRegistry.getAvailable().flatMap((model) => {
|
|
3892
|
+
const serializedModel = serializeModel(model);
|
|
3893
|
+
return serializedModel ? [serializedModel] : [];
|
|
3894
|
+
}).sort((left, right) => {
|
|
3475
3895
|
const providerCompare = (left.provider || "").localeCompare(right.provider || "");
|
|
3476
3896
|
if (providerCompare !== 0) return providerCompare;
|
|
3477
3897
|
return (left.name || left.id).localeCompare(right.name || right.id);
|
|
@@ -3491,6 +3911,8 @@ var PicoRuntime = class {
|
|
|
3491
3911
|
const next = {
|
|
3492
3912
|
id,
|
|
3493
3913
|
clients: /* @__PURE__ */ new Set(),
|
|
3914
|
+
activeRevision: 0,
|
|
3915
|
+
selectionNonce: 0,
|
|
3494
3916
|
activeKey: void 0,
|
|
3495
3917
|
draftKey: void 0,
|
|
3496
3918
|
sessionScope: process.cwd(),
|
|
@@ -3503,6 +3925,31 @@ var PicoRuntime = class {
|
|
|
3503
3925
|
getSessionPath(entry) {
|
|
3504
3926
|
return entry.session.sessionFile ?? entry.key;
|
|
3505
3927
|
}
|
|
3928
|
+
getSessionTreeLeafOverrideKey(entry) {
|
|
3929
|
+
return entry.session.sessionFile || "";
|
|
3930
|
+
}
|
|
3931
|
+
rememberSessionTreeLeaf(entry, onlyExisting = false) {
|
|
3932
|
+
const key = this.getSessionTreeLeafOverrideKey(entry);
|
|
3933
|
+
if (!key) return;
|
|
3934
|
+
if (onlyExisting && !this.sessionTreeLeafOverrides.has(key)) return;
|
|
3935
|
+
const leafId = entry.session.sessionManager.getLeafId?.() ?? null;
|
|
3936
|
+
if (this.sessionTreeLeafOverrides.get(key) === leafId) return;
|
|
3937
|
+
this.sessionTreeLeafOverrides.set(key, leafId);
|
|
3938
|
+
this.invalidateSessionIndexCache();
|
|
3939
|
+
}
|
|
3940
|
+
restoreSessionTreeLeafOverride(manager, sessionPath) {
|
|
3941
|
+
if (!this.sessionTreeLeafOverrides.has(sessionPath)) return;
|
|
3942
|
+
const leafId = this.sessionTreeLeafOverrides.get(sessionPath) ?? null;
|
|
3943
|
+
if (leafId === null) {
|
|
3944
|
+
manager.resetLeaf?.();
|
|
3945
|
+
return;
|
|
3946
|
+
}
|
|
3947
|
+
if (!manager.getEntry?.(leafId)) {
|
|
3948
|
+
this.sessionTreeLeafOverrides.delete(sessionPath);
|
|
3949
|
+
return;
|
|
3950
|
+
}
|
|
3951
|
+
manager.branch?.(leafId);
|
|
3952
|
+
}
|
|
3506
3953
|
getActiveEntry(context) {
|
|
3507
3954
|
return context.activeKey ? this.sessionEntries.get(context.activeKey) : void 0;
|
|
3508
3955
|
}
|
|
@@ -3524,13 +3971,13 @@ var PicoRuntime = class {
|
|
|
3524
3971
|
return false;
|
|
3525
3972
|
}
|
|
3526
3973
|
async disposeUnreferencedSessionEntries() {
|
|
3527
|
-
const candidates = [...this.sessionEntries.values()]
|
|
3528
|
-
|
|
3529
|
-
if (this.
|
|
3530
|
-
if (this.
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3974
|
+
const candidates = [...this.sessionEntries.values()].filter((entry) => {
|
|
3975
|
+
if (this.sessionEntries.get(entry.key) !== entry) return false;
|
|
3976
|
+
if (this.isSessionEntryReferenced(entry)) return false;
|
|
3977
|
+
if (this.isSessionBusyForDone(entry)) return false;
|
|
3978
|
+
return true;
|
|
3979
|
+
});
|
|
3980
|
+
await Promise.all(candidates.map((entry) => this.disposeSessionEntry(entry)));
|
|
3534
3981
|
}
|
|
3535
3982
|
async cleanupInactiveContexts() {
|
|
3536
3983
|
for (const context of this.contexts.values()) {
|
|
@@ -3579,11 +4026,12 @@ var PicoRuntime = class {
|
|
|
3579
4026
|
}
|
|
3580
4027
|
return lastValue;
|
|
3581
4028
|
}
|
|
3582
|
-
currentStatePayload(entry) {
|
|
4029
|
+
currentStatePayload(entry, context) {
|
|
3583
4030
|
const draft = this.isDraftEntry(entry);
|
|
3584
4031
|
const historyTotalCount = entry.session.messages.length;
|
|
3585
4032
|
return {
|
|
3586
4033
|
type: "state_sync",
|
|
4034
|
+
activationRevision: context.activeRevision,
|
|
3587
4035
|
sessionKey: entry.key,
|
|
3588
4036
|
items: entry.retainedConversationItems,
|
|
3589
4037
|
pendingUserMessages: entry.pendingUserMessages.map((message) => clonePendingUserMessage(message)),
|
|
@@ -3647,13 +4095,17 @@ var PicoRuntime = class {
|
|
|
3647
4095
|
const sessions = allSessions.filter((entry) => (entry.messageCount ?? 0) > 0);
|
|
3648
4096
|
const metricsStartedAt = performance.now();
|
|
3649
4097
|
const withMetrics = await Promise.all(sessions.map(async (entry) => {
|
|
3650
|
-
|
|
4098
|
+
let metrics;
|
|
4099
|
+
if (entry.path) {
|
|
4100
|
+
const hasLeafOverride = this.sessionTreeLeafOverrides.has(entry.path);
|
|
4101
|
+
metrics = await readSessionListMetrics(entry.path, hasLeafOverride ? { leafId: this.sessionTreeLeafOverrides.get(entry.path) ?? null } : void 0);
|
|
4102
|
+
}
|
|
3651
4103
|
return {
|
|
3652
4104
|
...entry,
|
|
3653
|
-
lastUserMessageAt: metrics
|
|
3654
|
-
lastMessageAt: metrics
|
|
3655
|
-
lastMessagePreview: metrics
|
|
3656
|
-
messageCount: metrics
|
|
4105
|
+
lastUserMessageAt: metrics ? metrics.lastUserMessageAt : entry.lastUserMessageAt,
|
|
4106
|
+
lastMessageAt: metrics ? metrics.lastMessageAt : entry.lastMessageAt,
|
|
4107
|
+
lastMessagePreview: metrics ? metrics.lastMessagePreview : entry.lastMessagePreview,
|
|
4108
|
+
messageCount: metrics ? metrics.messageCount : entry.messageCount
|
|
3657
4109
|
};
|
|
3658
4110
|
}));
|
|
3659
4111
|
this.logSessionLoadDebug("session_index:metrics", {
|
|
@@ -3708,12 +4160,12 @@ var PicoRuntime = class {
|
|
|
3708
4160
|
});
|
|
3709
4161
|
}
|
|
3710
4162
|
async listEntriesForDirectory(allSessions, directoryPath) {
|
|
3711
|
-
const sessions = allSessions.
|
|
3712
|
-
const byPath = new Map(sessions.
|
|
3713
|
-
const byId = new Map(sessions.
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
4163
|
+
const sessions = allSessions.flatMap((entry) => entry.cwd === directoryPath ? [{ ...entry }] : []);
|
|
4164
|
+
const byPath = new Map(sessions.flatMap((entry) => entry.path ? [[entry.path, entry]] : []));
|
|
4165
|
+
const byId = new Map(sessions.flatMap((entry) => entry.id ? [[entry.id, entry]] : []));
|
|
4166
|
+
const fallbackEntries = [...this.sessionEntries.values()].filter((entry) => entry.cwd === directoryPath && this.hasVisibleSessionContent(entry));
|
|
4167
|
+
const fallbacks = await Promise.all(fallbackEntries.map((entry) => this.sessionFallbackInfo(entry)));
|
|
4168
|
+
for (const fallback of fallbacks) {
|
|
3717
4169
|
const existing = (fallback.path ? byPath.get(fallback.path) : void 0) || (fallback.id ? byId.get(fallback.id) : void 0);
|
|
3718
4170
|
if (existing) {
|
|
3719
4171
|
this.mergeSessionListEntry(existing, fallback);
|
|
@@ -3726,7 +4178,7 @@ var PicoRuntime = class {
|
|
|
3726
4178
|
return sessions.sort((left, right) => this.compareSessionListEntriesByLastUserMessage(left, right));
|
|
3727
4179
|
}
|
|
3728
4180
|
buildStreamingPaths() {
|
|
3729
|
-
return new Set([...this.sessionEntries.values()].
|
|
4181
|
+
return new Set([...this.sessionEntries.values()].flatMap((entry) => this.getEntryStreamingState(entry) ? [this.getSessionPath(entry)] : []));
|
|
3730
4182
|
}
|
|
3731
4183
|
async collectDirectoryEntries(allSessions, directories) {
|
|
3732
4184
|
const entriesByDirectory = /* @__PURE__ */ new Map();
|
|
@@ -3928,7 +4380,7 @@ var PicoRuntime = class {
|
|
|
3928
4380
|
if (!entry) return;
|
|
3929
4381
|
const startedAt = performance.now();
|
|
3930
4382
|
const payloadStartedAt = performance.now();
|
|
3931
|
-
const payload = this.currentStatePayload(entry);
|
|
4383
|
+
const payload = this.currentStatePayload(entry, context);
|
|
3932
4384
|
const payloadDurationMs = roundedDurationMs(payloadStartedAt);
|
|
3933
4385
|
let sentCount = 0;
|
|
3934
4386
|
for (const client of context.clients) if (this.sendStatePayloadToClient(context, client, payload, options)) sentCount += 1;
|
|
@@ -3986,6 +4438,24 @@ var PicoRuntime = class {
|
|
|
3986
4438
|
}
|
|
3987
4439
|
await Promise.all(connectedContexts.map((context) => this.sendSessionsToContext(context)));
|
|
3988
4440
|
}
|
|
4441
|
+
async activateContextsSessionAndBroadcast(contexts, entry) {
|
|
4442
|
+
await Promise.all(contexts.map((context) => this.activateContextSession(context, entry)));
|
|
4443
|
+
await this.broadcastSessionsAll();
|
|
4444
|
+
}
|
|
4445
|
+
async bindSessionEntryAndBroadcast(entry) {
|
|
4446
|
+
await this.bindSessionEntry(entry);
|
|
4447
|
+
await Promise.all([this.broadcastEntryState(entry), this.broadcastSessionsAll()]);
|
|
4448
|
+
}
|
|
4449
|
+
scheduleTreeNavigationSessionListChange(entry, previousLeafId, result) {
|
|
4450
|
+
if (result.cancelled || result.aborted) return;
|
|
4451
|
+
const nextLeafId = entry.session.sessionManager.getLeafId?.() ?? null;
|
|
4452
|
+
if (!result.summaryEntry && previousLeafId === nextLeafId) return;
|
|
4453
|
+
this.rememberSessionTreeLeaf(entry);
|
|
4454
|
+
this.touchSessionEntry(entry);
|
|
4455
|
+
this.broadcastSessionsAll().catch((error) => {
|
|
4456
|
+
console.error("[pico] failed to broadcast tree navigation sessions:", error);
|
|
4457
|
+
});
|
|
4458
|
+
}
|
|
3989
4459
|
syncGitWatchDirectories() {
|
|
3990
4460
|
const cwds = /* @__PURE__ */ new Set();
|
|
3991
4461
|
for (const context of this.contexts.values()) {
|
|
@@ -4157,6 +4627,7 @@ var PicoRuntime = class {
|
|
|
4157
4627
|
async activateContextSession(context, entry, options) {
|
|
4158
4628
|
const previousActiveKey = context.activeKey;
|
|
4159
4629
|
const startedAt = performance.now();
|
|
4630
|
+
context.activeRevision += 1;
|
|
4160
4631
|
await activateContextSession({
|
|
4161
4632
|
context,
|
|
4162
4633
|
entry,
|
|
@@ -4185,6 +4656,7 @@ var PicoRuntime = class {
|
|
|
4185
4656
|
this.syncGitWatchDirectories();
|
|
4186
4657
|
this.logSessionLoadDebug("context_session:activate", {
|
|
4187
4658
|
contextId: context.id,
|
|
4659
|
+
activeRevision: context.activeRevision,
|
|
4188
4660
|
previousActiveKey,
|
|
4189
4661
|
notify: options?.notify !== false,
|
|
4190
4662
|
statusDurationMs,
|
|
@@ -4407,6 +4879,7 @@ var PicoRuntime = class {
|
|
|
4407
4879
|
const sdk = await this.getSdk();
|
|
4408
4880
|
const openStartedAt = performance.now();
|
|
4409
4881
|
const sessionManager = sdk.SessionManager.open(sessionPath);
|
|
4882
|
+
this.restoreSessionTreeLeafOverride(sessionManager, sessionPath);
|
|
4410
4883
|
this.logSessionLoadDebug("session_manager:open", {
|
|
4411
4884
|
sessionPath,
|
|
4412
4885
|
cwd: sessionManager.getCwd(),
|
|
@@ -4423,7 +4896,9 @@ var PicoRuntime = class {
|
|
|
4423
4896
|
if (currentManager.isPersisted?.()) {
|
|
4424
4897
|
const currentSessionFile = entry.session.sessionFile;
|
|
4425
4898
|
if (!currentSessionFile) throw new Error("Persisted session is missing a session file");
|
|
4426
|
-
|
|
4899
|
+
const sessionManager = (await this.getSdk()).SessionManager.open(currentSessionFile, currentManager.getSessionDir?.(), entry.cwd);
|
|
4900
|
+
this.restoreSessionTreeLeafOverride(sessionManager, currentSessionFile);
|
|
4901
|
+
return sessionManager;
|
|
4427
4902
|
}
|
|
4428
4903
|
return await this.createForkedInMemorySessionManager(currentManager, currentManager.getLeafId?.(), entry.session.sessionFile);
|
|
4429
4904
|
}
|
|
@@ -4609,25 +5084,26 @@ var PicoRuntime = class {
|
|
|
4609
5084
|
}
|
|
4610
5085
|
pendingMessagesFromClientUpdate(entry, pendingMessagesUpdate) {
|
|
4611
5086
|
const pendingMessages = entry.pendingUserMessages.map((message) => clonePendingUserMessage(message));
|
|
4612
|
-
const normalizedUpdates = Array.isArray(pendingMessagesUpdate) ? pendingMessagesUpdate.
|
|
5087
|
+
const normalizedUpdates = Array.isArray(pendingMessagesUpdate) ? pendingMessagesUpdate.flatMap((message) => {
|
|
5088
|
+
const pendingId = typeof message?.pendingId === "string" ? message.pendingId : "";
|
|
5089
|
+
if (!pendingId) return [];
|
|
4613
5090
|
const hasImages = hasOwnProperty(message, "images");
|
|
4614
5091
|
const hasText = hasOwnProperty(message, "text");
|
|
4615
|
-
return {
|
|
4616
|
-
pendingId
|
|
5092
|
+
return [{
|
|
5093
|
+
pendingId,
|
|
4617
5094
|
hasImages,
|
|
4618
5095
|
hasText,
|
|
4619
5096
|
images: hasImages ? normalizePromptImages(message?.images) : [],
|
|
4620
5097
|
streamingBehavior: normalizePendingStreamingBehavior(message?.streamingBehavior),
|
|
4621
5098
|
text: hasText && typeof message?.text === "string" ? message.text : ""
|
|
4622
|
-
};
|
|
4623
|
-
})
|
|
4624
|
-
if (normalizedUpdates.length !== pendingMessages.length) throw new Error("pendingMessages must include every pending prompt exactly once.");
|
|
5099
|
+
}];
|
|
5100
|
+
}) : [];
|
|
4625
5101
|
const pendingMessagesById = new Map(pendingMessages.map((message) => [message.pendingId, message]));
|
|
4626
5102
|
if (pendingMessagesById.size !== pendingMessages.length) throw new Error("Pending prompt order is out of date. Refresh and try again.");
|
|
4627
5103
|
const nextPendingMessages = [];
|
|
4628
5104
|
for (const update of normalizedUpdates) {
|
|
4629
5105
|
const existing = pendingMessagesById.get(update.pendingId);
|
|
4630
|
-
if (!existing)
|
|
5106
|
+
if (!existing) continue;
|
|
4631
5107
|
const text = update.hasText ? update.text : existing.text;
|
|
4632
5108
|
const images = update.hasImages ? update.images : existing.images;
|
|
4633
5109
|
if (!text.trim() && images.length === 0) throw new Error("Pending prompt text or image is required.");
|
|
@@ -4642,23 +5118,30 @@ var PicoRuntime = class {
|
|
|
4642
5118
|
if (pendingMessagesById.size > 0) throw new Error("pendingMessages must include every pending prompt exactly once.");
|
|
4643
5119
|
return sortPendingUserMessages(nextPendingMessages);
|
|
4644
5120
|
}
|
|
5121
|
+
async replayPendingUserMessages(entry, pendingMessages, index = 0) {
|
|
5122
|
+
const pendingMessage = pendingMessages[index];
|
|
5123
|
+
if (!pendingMessage) return;
|
|
5124
|
+
const text = pendingMessage.text;
|
|
5125
|
+
const images = normalizePromptImages(pendingMessage.images);
|
|
5126
|
+
if (text.trim() || images.length > 0) await entry.session.prompt(text, {
|
|
5127
|
+
...images.length > 0 ? { images } : {},
|
|
5128
|
+
streamingBehavior: pendingMessage.streamingBehavior
|
|
5129
|
+
});
|
|
5130
|
+
await this.replayPendingUserMessages(entry, pendingMessages, index + 1);
|
|
5131
|
+
}
|
|
4645
5132
|
async replacePendingUserMessages(entry, pendingMessages) {
|
|
4646
5133
|
const nextPending = sortPendingUserMessages(pendingMessages);
|
|
4647
5134
|
const canReplayPending = Boolean(entry.session.isStreaming);
|
|
4648
|
-
if (!canReplayPending
|
|
5135
|
+
if (!canReplayPending) {
|
|
5136
|
+
entry.pendingUserMessages = nextPending;
|
|
5137
|
+
await this.broadcastEntryState(entry);
|
|
5138
|
+
return entry.pendingUserMessages;
|
|
5139
|
+
}
|
|
4649
5140
|
entry.pendingQueueMutation = true;
|
|
4650
5141
|
try {
|
|
4651
5142
|
entry.session.clearQueue();
|
|
4652
5143
|
entry.pendingUserMessages = [];
|
|
4653
|
-
if (canReplayPending)
|
|
4654
|
-
const text = pendingMessage.text;
|
|
4655
|
-
const images = normalizePromptImages(pendingMessage.images);
|
|
4656
|
-
if (!text.trim() && images.length === 0) continue;
|
|
4657
|
-
await entry.session.prompt(text, {
|
|
4658
|
-
...images.length > 0 ? { images } : {},
|
|
4659
|
-
streamingBehavior: pendingMessage.streamingBehavior
|
|
4660
|
-
});
|
|
4661
|
-
}
|
|
5144
|
+
if (canReplayPending) await this.replayPendingUserMessages(entry, nextPending);
|
|
4662
5145
|
entry.pendingUserMessages = nextPending;
|
|
4663
5146
|
this.reconcilePendingUserMessages(entry);
|
|
4664
5147
|
} finally {
|
|
@@ -4779,11 +5262,9 @@ var PicoRuntime = class {
|
|
|
4779
5262
|
sessionId: void 0,
|
|
4780
5263
|
sessionFile: void 0
|
|
4781
5264
|
};
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
}
|
|
4786
|
-
await this.broadcastSessionsAll();
|
|
5265
|
+
const activeViewers = viewers();
|
|
5266
|
+
for (const context of activeViewers) context.draftKey = result.entry.key;
|
|
5267
|
+
await this.activateContextsSessionAndBroadcast(activeViewers, result.entry);
|
|
4787
5268
|
return {
|
|
4788
5269
|
sessionId: void 0,
|
|
4789
5270
|
sessionFile: void 0
|
|
@@ -4793,22 +5274,19 @@ var PicoRuntime = class {
|
|
|
4793
5274
|
const branchedPath = session.sessionManager.createBranchedSession?.(branchEntryId);
|
|
4794
5275
|
if (!branchedPath) return { cancelled: true };
|
|
4795
5276
|
const nextEntry = await this.ensureSessionEntryByPath(branchedPath);
|
|
4796
|
-
|
|
4797
|
-
await this.broadcastSessionsAll();
|
|
5277
|
+
await this.activateContextsSessionAndBroadcast(viewers(), nextEntry);
|
|
4798
5278
|
return {
|
|
4799
5279
|
sessionId: nextEntry.session.sessionId,
|
|
4800
5280
|
sessionFile: nextEntry.session.sessionFile
|
|
4801
5281
|
};
|
|
4802
5282
|
},
|
|
4803
5283
|
navigateTree: async (targetId, navigateOptions) => {
|
|
5284
|
+
const previousLeafId = session.sessionManager.getLeafId?.() ?? null;
|
|
4804
5285
|
const result = await session.navigateTree(targetId, navigateOptions);
|
|
4805
5286
|
this.refreshRetainedConversationItems(entry);
|
|
4806
5287
|
if (result.editorText != null) entry.uiState.editorText = result.editorText;
|
|
4807
5288
|
await this.broadcastEntryState(entry);
|
|
4808
|
-
|
|
4809
|
-
this.touchSessionEntry(entry);
|
|
4810
|
-
await this.broadcastSessionsAll();
|
|
4811
|
-
}
|
|
5289
|
+
this.scheduleTreeNavigationSessionListChange(entry, previousLeafId, result);
|
|
4812
5290
|
return {
|
|
4813
5291
|
cancelled: Boolean(result.cancelled),
|
|
4814
5292
|
aborted: Boolean(result.aborted)
|
|
@@ -4825,8 +5303,7 @@ var PicoRuntime = class {
|
|
|
4825
5303
|
sessionId: entry.session.sessionId,
|
|
4826
5304
|
sessionFile: entry.session.sessionFile
|
|
4827
5305
|
};
|
|
4828
|
-
|
|
4829
|
-
await this.broadcastSessionsAll();
|
|
5306
|
+
await this.activateContextsSessionAndBroadcast(viewers(), nextEntry);
|
|
4830
5307
|
return {
|
|
4831
5308
|
sessionId: nextEntry.session.sessionId,
|
|
4832
5309
|
sessionFile: nextEntry.session.sessionFile
|
|
@@ -4834,9 +5311,7 @@ var PicoRuntime = class {
|
|
|
4834
5311
|
},
|
|
4835
5312
|
reload: async () => {
|
|
4836
5313
|
await session.reload?.();
|
|
4837
|
-
await this.
|
|
4838
|
-
await this.broadcastEntryState(entry);
|
|
4839
|
-
await this.broadcastSessionsAll();
|
|
5314
|
+
await this.bindSessionEntryAndBroadcast(entry);
|
|
4840
5315
|
}
|
|
4841
5316
|
},
|
|
4842
5317
|
shutdownHandler: () => {
|
|
@@ -4938,6 +5413,7 @@ var PicoRuntime = class {
|
|
|
4938
5413
|
statusChanged = true;
|
|
4939
5414
|
}
|
|
4940
5415
|
if (statusChanged) this.broadcastSessionStatusAll(entry);
|
|
5416
|
+
this.rememberSessionTreeLeaf(entry, true);
|
|
4941
5417
|
await this.broadcastEntryState(entry);
|
|
4942
5418
|
if (type === "agent_start" || type === "agent_end" || type === "message_end" || type === "compaction_end" || type === "queue_update") await this.broadcastSessionsAll();
|
|
4943
5419
|
if (type === "agent_end" || type === "compaction_end") await this.cleanupInactiveContexts();
|
|
@@ -4995,12 +5471,13 @@ var PicoRuntime = class {
|
|
|
4995
5471
|
const bootstrapStartedAt = performance.now();
|
|
4996
5472
|
try {
|
|
4997
5473
|
const stateStartedAt = performance.now();
|
|
4998
|
-
|
|
5474
|
+
const bootstrapEntry = this.getActiveEntry(context) ?? activeEntry;
|
|
5475
|
+
this.sendStatePayloadToClient(context, client, this.currentStatePayload(bootstrapEntry, context), { forceFull: true });
|
|
4999
5476
|
this.logSessionLoadDebug("events_response:bootstrap_state", {
|
|
5000
5477
|
contextId: context.id,
|
|
5001
5478
|
clientId: client.id,
|
|
5002
5479
|
durationMs: roundedDurationMs(stateStartedAt),
|
|
5003
|
-
...this.sessionDebugDetails(
|
|
5480
|
+
...this.sessionDebugDetails(bootstrapEntry)
|
|
5004
5481
|
});
|
|
5005
5482
|
if (client.closed || request.signal.aborted) return;
|
|
5006
5483
|
const sessionsStartedAt = performance.now();
|
|
@@ -5162,7 +5639,6 @@ var PicoRuntime = class {
|
|
|
5162
5639
|
const pendingMessages = Array.isArray(body.pendingMessages) ? body.pendingMessages : Array.isArray(body.pendingIds) ? body.pendingIds.map((pendingId) => ({ pendingId })) : null;
|
|
5163
5640
|
if (!pendingMessages) throw new Error("pendingMessages must be an array");
|
|
5164
5641
|
const nextPendingMessages = this.pendingMessagesFromClientUpdate(activeEntry, pendingMessages);
|
|
5165
|
-
if (!activeEntry.session.isStreaming && nextPendingMessages.length > 0) throw new Error("Pending prompts can only be changed while the session is streaming.");
|
|
5166
5642
|
await this.replacePendingUserMessages(activeEntry, nextPendingMessages);
|
|
5167
5643
|
return {
|
|
5168
5644
|
ok: true,
|
|
@@ -5181,7 +5657,9 @@ var PicoRuntime = class {
|
|
|
5181
5657
|
const pendingMessages = activeEntry.pendingUserMessages.map((message) => clonePendingUserMessage(message));
|
|
5182
5658
|
const pendingIndex = pendingMessages.findIndex((message) => message.pendingId === pendingId);
|
|
5183
5659
|
if (pendingIndex === -1) {
|
|
5184
|
-
|
|
5660
|
+
const isKnownClientPendingId = Boolean(normalizeClientPendingId(pendingId));
|
|
5661
|
+
const isKnownServerPendingId = pendingId.startsWith("pending:");
|
|
5662
|
+
if (isKnownClientPendingId || isKnownServerPendingId) {
|
|
5185
5663
|
activeEntry.canceledPendingUserMessageIds.add(pendingId);
|
|
5186
5664
|
return {
|
|
5187
5665
|
ok: true,
|
|
@@ -5192,7 +5670,6 @@ var PicoRuntime = class {
|
|
|
5192
5670
|
}
|
|
5193
5671
|
activeEntry.canceledPendingUserMessageIds.delete(pendingId);
|
|
5194
5672
|
pendingMessages.splice(pendingIndex, 1);
|
|
5195
|
-
if (!activeEntry.session.isStreaming && pendingMessages.length > 0) throw new Error("Pending prompts can only be changed while the session is streaming.");
|
|
5196
5673
|
await this.replacePendingUserMessages(activeEntry, pendingMessages);
|
|
5197
5674
|
return {
|
|
5198
5675
|
ok: true,
|
|
@@ -5232,11 +5709,16 @@ var PicoRuntime = class {
|
|
|
5232
5709
|
const url = new URL(request.url);
|
|
5233
5710
|
const requestedSessionId = url.searchParams.get("session")?.trim() || "";
|
|
5234
5711
|
const requestedSessionPath = url.searchParams.get("sessionPath")?.trim() || "";
|
|
5712
|
+
const rawSelectionNonce = Number(url.searchParams.get("selectionNonce"));
|
|
5713
|
+
const selectionNonce = Number.isSafeInteger(rawSelectionNonce) && rawSelectionNonce > 0 ? rawSelectionNonce : 0;
|
|
5235
5714
|
const context = this.ensureContext(url.searchParams.get("context") || "default");
|
|
5236
5715
|
context.sessionScope = normalizeSessionScope(url.searchParams.get("scope"), process.cwd());
|
|
5716
|
+
if (selectionNonce > context.selectionNonce) context.selectionNonce = selectionNonce;
|
|
5237
5717
|
this.logSessionLoadDebug("select_session:start", {
|
|
5238
5718
|
requestedSessionId,
|
|
5239
5719
|
requestedSessionPath,
|
|
5720
|
+
selectionNonce,
|
|
5721
|
+
latestSelectionNonce: context.selectionNonce,
|
|
5240
5722
|
contextId: context.id
|
|
5241
5723
|
});
|
|
5242
5724
|
try {
|
|
@@ -5252,6 +5734,26 @@ var PicoRuntime = class {
|
|
|
5252
5734
|
...this.sessionDebugDetails(nextEntry)
|
|
5253
5735
|
});
|
|
5254
5736
|
if (!nextEntry) throw new Error(`Unknown session: ${requestedSessionId}`);
|
|
5737
|
+
if (request.signal.aborted) {
|
|
5738
|
+
this.logSessionLoadDebug("select_session:skip_aborted", {
|
|
5739
|
+
requestedSessionId,
|
|
5740
|
+
requestedSessionPath,
|
|
5741
|
+
selectionNonce,
|
|
5742
|
+
latestSelectionNonce: context.selectionNonce,
|
|
5743
|
+
...this.sessionDebugDetails(nextEntry)
|
|
5744
|
+
});
|
|
5745
|
+
return { ok: true };
|
|
5746
|
+
}
|
|
5747
|
+
if (selectionNonce > 0 && selectionNonce < context.selectionNonce) {
|
|
5748
|
+
this.logSessionLoadDebug("select_session:skip_stale", {
|
|
5749
|
+
requestedSessionId,
|
|
5750
|
+
requestedSessionPath,
|
|
5751
|
+
selectionNonce,
|
|
5752
|
+
latestSelectionNonce: context.selectionNonce,
|
|
5753
|
+
...this.sessionDebugDetails(nextEntry)
|
|
5754
|
+
});
|
|
5755
|
+
return { ok: true };
|
|
5756
|
+
}
|
|
5255
5757
|
const activateStartedAt = performance.now();
|
|
5256
5758
|
await this.activateContextSession(context, nextEntry);
|
|
5257
5759
|
this.logSessionLoadDebug("select_session:activate", {
|
|
@@ -5332,7 +5834,10 @@ var PicoRuntime = class {
|
|
|
5332
5834
|
return {
|
|
5333
5835
|
leafId,
|
|
5334
5836
|
streamingEntryId,
|
|
5335
|
-
tree: (manager.getTree() || []).
|
|
5837
|
+
tree: (manager.getTree() || []).flatMap((node) => {
|
|
5838
|
+
const treeNode = serializeSessionTreeNode(node);
|
|
5839
|
+
return treeNode ? [markStreamingNode(treeNode)] : [];
|
|
5840
|
+
})
|
|
5336
5841
|
};
|
|
5337
5842
|
}
|
|
5338
5843
|
async getSessionTreeForRequest(request) {
|
|
@@ -5372,6 +5877,7 @@ var PicoRuntime = class {
|
|
|
5372
5877
|
const targetId = typeof body.targetId === "string" ? body.targetId.trim() : "";
|
|
5373
5878
|
if (!targetId) throw new Error("targetId is required");
|
|
5374
5879
|
if (this.getEntryStreamingState(activeEntry) || activeEntry.session.isStreaming) throw new Error("Abort the current response before navigating the tree.");
|
|
5880
|
+
const previousLeafId = activeEntry.session.sessionManager.getLeafId?.() ?? null;
|
|
5375
5881
|
const result = await activeEntry.session.navigateTree(targetId, {
|
|
5376
5882
|
summarize: Boolean(body.summarize),
|
|
5377
5883
|
customInstructions: typeof body.customInstructions === "string" ? body.customInstructions : void 0,
|
|
@@ -5380,11 +5886,8 @@ var PicoRuntime = class {
|
|
|
5380
5886
|
});
|
|
5381
5887
|
this.refreshRetainedConversationItems(activeEntry);
|
|
5382
5888
|
if (result.editorText != null) activeEntry.uiState.editorText = result.editorText;
|
|
5383
|
-
if (result.summaryEntry) {
|
|
5384
|
-
this.touchSessionEntry(activeEntry);
|
|
5385
|
-
await this.broadcastSessionsAll();
|
|
5386
|
-
}
|
|
5387
5889
|
await this.broadcastEntryState(activeEntry);
|
|
5890
|
+
this.scheduleTreeNavigationSessionListChange(activeEntry, previousLeafId, result);
|
|
5388
5891
|
return {
|
|
5389
5892
|
ok: true,
|
|
5390
5893
|
cancelled: Boolean(result.cancelled),
|
|
@@ -5532,6 +6035,27 @@ var PicoRuntime = class {
|
|
|
5532
6035
|
name: nextName
|
|
5533
6036
|
};
|
|
5534
6037
|
}
|
|
6038
|
+
async setSessionReadState(request, body) {
|
|
6039
|
+
const { context } = await this.resolveRequest(request);
|
|
6040
|
+
const sessionPath = typeof body.path === "string" ? body.path.trim() : "";
|
|
6041
|
+
const unread = typeof body.unread === "boolean" ? body.unread : false;
|
|
6042
|
+
if (!sessionPath) throw new Error("path is required");
|
|
6043
|
+
if (unread) context.unreadFinished.add(sessionPath);
|
|
6044
|
+
else context.unreadFinished.delete(sessionPath);
|
|
6045
|
+
const loadedEntry = [...this.sessionEntries.values()].find((entry) => this.getSessionPath(entry) === sessionPath);
|
|
6046
|
+
if (loadedEntry) this.sendSessionStatusToContext(context, loadedEntry);
|
|
6047
|
+
else this.sendToContext(context, {
|
|
6048
|
+
type: "session_status",
|
|
6049
|
+
sessionPath,
|
|
6050
|
+
unread
|
|
6051
|
+
});
|
|
6052
|
+
await this.sendSessionsToContext(context);
|
|
6053
|
+
return {
|
|
6054
|
+
ok: true,
|
|
6055
|
+
path: sessionPath,
|
|
6056
|
+
unread
|
|
6057
|
+
};
|
|
6058
|
+
}
|
|
5535
6059
|
async writeMovedSessionFile(sessionPath, nextCwd, targetSessionDirectory) {
|
|
5536
6060
|
const sourcePath = resolve(sessionPath);
|
|
5537
6061
|
const targetPath = resolve(await uniqueSessionMovePath(sourcePath, targetSessionDirectory));
|
|
@@ -5563,20 +6087,23 @@ var PicoRuntime = class {
|
|
|
5563
6087
|
const previousPath = resolve(sessionPath);
|
|
5564
6088
|
const previousEntry = loadedEntries[0];
|
|
5565
6089
|
const previousCwd = previousEntry?.cwd || "";
|
|
5566
|
-
const affectedContexts = [...this.contexts.values()].
|
|
5567
|
-
context
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
6090
|
+
const affectedContexts = [...this.contexts.values()].flatMap((context) => {
|
|
6091
|
+
const wasActive = loadedEntries.some((entry) => context.activeKey === entry.key);
|
|
6092
|
+
const wasDraft = loadedEntries.some((entry) => context.draftKey === entry.key);
|
|
6093
|
+
return wasActive || wasDraft ? [{
|
|
6094
|
+
context,
|
|
6095
|
+
wasActive,
|
|
6096
|
+
wasDraft
|
|
6097
|
+
}] : [];
|
|
6098
|
+
});
|
|
5571
6099
|
const nextPath = await this.writeMovedSessionFile(previousPath, nextCwd, targetSessionDirectory);
|
|
5572
|
-
|
|
6100
|
+
await Promise.all(loadedEntries.map((loadedEntry) => this.disposeSessionEntry(loadedEntry)));
|
|
5573
6101
|
let nextEntry;
|
|
5574
6102
|
if (affectedContexts.some((entry) => entry.wasActive)) {
|
|
5575
6103
|
nextEntry = await this.ensureSessionEntryByPath(nextPath);
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
}
|
|
6104
|
+
const activeNextEntry = nextEntry;
|
|
6105
|
+
for (const affected of affectedContexts) if (affected.wasDraft) affected.context.draftKey = void 0;
|
|
6106
|
+
await Promise.all(affectedContexts.flatMap((affected) => affected.wasActive ? [this.activateContextSession(affected.context, activeNextEntry, { refreshSessions: false })] : []));
|
|
5580
6107
|
} else for (const affected of affectedContexts) if (affected.wasDraft) affected.context.draftKey = void 0;
|
|
5581
6108
|
for (const context of this.contexts.values()) if (context.unreadFinished.delete(previousPath)) context.unreadFinished.add(nextPath);
|
|
5582
6109
|
this.invalidateSessionIndexCache();
|
|
@@ -5621,21 +6148,20 @@ var PicoRuntime = class {
|
|
|
5621
6148
|
const allSessions = await this.listSessionIndexEntries();
|
|
5622
6149
|
const directorySessions = await this.listEntriesForDirectory(allSessions, directory);
|
|
5623
6150
|
const streamingPaths = this.buildStreamingPaths();
|
|
5624
|
-
const activeKeys = new Set([...this.contexts.values()].
|
|
5625
|
-
const activePaths = new Set([...this.sessionEntries.values()].
|
|
6151
|
+
const activeKeys = new Set([...this.contexts.values()].flatMap((ctx) => ctx.activeKey ? [ctx.activeKey] : []));
|
|
6152
|
+
const activePaths = new Set([...this.sessionEntries.values()].flatMap((entry) => activeKeys.has(entry.key) ? [this.getSessionPath(entry)] : []));
|
|
5626
6153
|
const includeActiveSession = body.includeActiveSession === true;
|
|
5627
|
-
const matchingSessions = directorySessions.
|
|
6154
|
+
const matchingSessions = directorySessions.flatMap((entry) => {
|
|
5628
6155
|
const activityAt = normalizeModifiedTimestamp(entry.lastUserMessageAt) || normalizeModifiedTimestamp(entry.modified);
|
|
5629
|
-
|
|
6156
|
+
const serializedEntry = {
|
|
5630
6157
|
...this.serializeSessionListEntry(entry, context, streamingPaths),
|
|
5631
6158
|
activityAt
|
|
5632
6159
|
};
|
|
5633
|
-
|
|
5634
|
-
if (
|
|
5635
|
-
if (
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
return activityTime > 0 && activityTime < cutoffTime;
|
|
6160
|
+
if (!serializedEntry.path) return [];
|
|
6161
|
+
if (streamingPaths.has(serializedEntry.path)) return [];
|
|
6162
|
+
if (!includeActiveSession && activePaths.has(serializedEntry.path)) return [];
|
|
6163
|
+
const activityTime = modifiedTimestampValue(serializedEntry.activityAt);
|
|
6164
|
+
return activityTime > 0 && activityTime < cutoffTime ? [serializedEntry] : [];
|
|
5639
6165
|
});
|
|
5640
6166
|
if (body.dryRun !== false) return {
|
|
5641
6167
|
ok: true,
|
|
@@ -5645,10 +6171,10 @@ var PicoRuntime = class {
|
|
|
5645
6171
|
deletedSessionIds: [],
|
|
5646
6172
|
matchingSessions
|
|
5647
6173
|
};
|
|
5648
|
-
const deletedSessionIds = matchingSessions.
|
|
5649
|
-
const matchingPaths = matchingSessions.
|
|
6174
|
+
const deletedSessionIds = matchingSessions.flatMap((session) => session.id ? [session.id] : []);
|
|
6175
|
+
const matchingPaths = matchingSessions.flatMap((session) => session.path ? [session.path] : []);
|
|
5650
6176
|
const matchingPathSet = new Set(matchingPaths);
|
|
5651
|
-
await Promise.all([...this.sessionEntries.values()].
|
|
6177
|
+
await Promise.all([...this.sessionEntries.values()].flatMap((entry) => matchingPathSet.has(this.getSessionPath(entry)) ? [this.disposeSessionEntry(entry)] : []));
|
|
5652
6178
|
for (const ctx of this.contexts.values()) for (const sessionPath of matchingPaths) ctx.unreadFinished.delete(sessionPath);
|
|
5653
6179
|
await Promise.all(matchingPaths.map((sessionPath) => this.trashOrDeleteSessionFile(sessionPath)));
|
|
5654
6180
|
this.invalidateSessionIndexCache();
|
|
@@ -5664,23 +6190,32 @@ var PicoRuntime = class {
|
|
|
5664
6190
|
}
|
|
5665
6191
|
async deleteSessions(request, body) {
|
|
5666
6192
|
const { context } = await this.resolveRequest(request);
|
|
5667
|
-
const paths = Array.isArray(body.paths) ? body.paths.
|
|
6193
|
+
const paths = Array.isArray(body.paths) ? body.paths.flatMap((path) => {
|
|
6194
|
+
if (typeof path !== "string") return [];
|
|
6195
|
+
const trimmedPath = path.trim();
|
|
6196
|
+
return trimmedPath ? [trimmedPath] : [];
|
|
6197
|
+
}) : [];
|
|
5668
6198
|
const sessionPaths = [...new Set(paths)];
|
|
5669
6199
|
if (sessionPaths.length === 0) throw new Error("paths are required");
|
|
5670
6200
|
const sessionPathSet = new Set(sessionPaths);
|
|
5671
6201
|
const loadedEntries = [...this.sessionEntries.values()].filter((entry) => sessionPathSet.has(this.getSessionPath(entry)));
|
|
5672
|
-
|
|
5673
|
-
for (const loadedEntry of loadedEntries) {
|
|
6202
|
+
const replacementRequests = loadedEntries.flatMap((loadedEntry) => {
|
|
5674
6203
|
const affectedContexts = [...this.contexts.values()].filter((ctx) => ctx.activeKey === loadedEntry.key);
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
}
|
|
6204
|
+
return affectedContexts.length > 0 ? [{
|
|
6205
|
+
affectedContexts,
|
|
6206
|
+
cwd: loadedEntry.cwd
|
|
6207
|
+
}] : [];
|
|
6208
|
+
});
|
|
6209
|
+
const replacementResults = await Promise.all(replacementRequests.map(async (request) => ({
|
|
6210
|
+
affectedContexts: request.affectedContexts,
|
|
6211
|
+
entry: await this.createNewSessionEntry(request.cwd, { draft: true })
|
|
6212
|
+
})));
|
|
6213
|
+
let replacementEntry;
|
|
6214
|
+
for (const result of replacementResults) {
|
|
6215
|
+
replacementEntry = replacementEntry ?? result.entry;
|
|
6216
|
+
for (const affected of result.affectedContexts) affected.draftKey = result.entry.key;
|
|
5683
6217
|
}
|
|
6218
|
+
await Promise.all(replacementResults.flatMap((result) => result.affectedContexts.map((affected) => this.activateContextSession(affected, result.entry))));
|
|
5684
6219
|
for (const ctx of this.contexts.values()) for (const sessionPath of sessionPaths) ctx.unreadFinished.delete(sessionPath);
|
|
5685
6220
|
await Promise.all(loadedEntries.map((entry) => this.disposeSessionEntry(entry)));
|
|
5686
6221
|
await Promise.all(sessionPaths.map((sessionPath) => this.trashOrDeleteSessionFile(sessionPath)));
|
|
@@ -5742,15 +6277,15 @@ var PicoRuntime = class {
|
|
|
5742
6277
|
authType: "oauth",
|
|
5743
6278
|
...authStatus(provider.id)
|
|
5744
6279
|
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
5745
|
-
const apiKeyOptions = Array.from(providerIds).
|
|
5746
|
-
if (BUILT_IN_API_KEY_LOGIN_PROVIDERS.has(providerId)) return
|
|
5747
|
-
return
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
})
|
|
6280
|
+
const apiKeyOptions = Array.from(providerIds).flatMap((providerId) => {
|
|
6281
|
+
if (!BUILT_IN_API_KEY_LOGIN_PROVIDERS.has(providerId) && oauthProviderIds.has(providerId)) return [];
|
|
6282
|
+
return [{
|
|
6283
|
+
id: providerId,
|
|
6284
|
+
name: getApiKeyProviderDisplayName(providerId),
|
|
6285
|
+
authType: "api_key",
|
|
6286
|
+
...authStatus(providerId)
|
|
6287
|
+
}];
|
|
6288
|
+
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
5754
6289
|
const nameByProvider = new Map([...oauthOptions, ...apiKeyOptions].map((option) => [option.id, option.name]));
|
|
5755
6290
|
const authTypeByProvider = new Map([...oauthOptions, ...apiKeyOptions].map((option) => [option.id, option.authType]));
|
|
5756
6291
|
return {
|
|
@@ -5997,14 +6532,14 @@ var PicoRuntime = class {
|
|
|
5997
6532
|
pending.resolve({ cancelled: true });
|
|
5998
6533
|
} catch {}
|
|
5999
6534
|
this.pendingUiRequests.clear();
|
|
6000
|
-
|
|
6535
|
+
await Promise.all([...this.sessionEntries.values()].map((entry) => this.disposeSessionEntry(entry)));
|
|
6001
6536
|
}
|
|
6002
6537
|
};
|
|
6003
6538
|
function getPicoRuntime() {
|
|
6004
6539
|
globalThis.__picoRuntime ??= new PicoRuntime();
|
|
6005
6540
|
return globalThis.__picoRuntime;
|
|
6006
6541
|
}
|
|
6007
|
-
var Route$
|
|
6542
|
+
var Route$52 = createFileRoute("/events")({ server: { handlers: { GET: ({ request }) => getPicoRuntime().createEventsResponse(request) } } });
|
|
6008
6543
|
function jsonResponse(data, init = 200) {
|
|
6009
6544
|
const responseInit = typeof init === "number" ? { status: init } : init;
|
|
6010
6545
|
const headers = new Headers(responseInit.headers);
|
|
@@ -6040,7 +6575,7 @@ function routeErrorResponse(error, fallbackMessage) {
|
|
|
6040
6575
|
async function readRequestJson(request) {
|
|
6041
6576
|
return await request.json().catch(() => ({}));
|
|
6042
6577
|
}
|
|
6043
|
-
var Route$
|
|
6578
|
+
var Route$51 = createFileRoute("/api/thinking")({ server: { handlers: { POST: async ({ request }) => {
|
|
6044
6579
|
try {
|
|
6045
6580
|
const body = await readRequestJson(request);
|
|
6046
6581
|
return jsonResponse(await getPicoRuntime().setThinking(request, body));
|
|
@@ -6048,7 +6583,7 @@ var Route$46 = createFileRoute("/api/thinking")({ server: { handlers: { POST: as
|
|
|
6048
6583
|
return routeErrorResponse(error, "Failed to update thinking level");
|
|
6049
6584
|
}
|
|
6050
6585
|
} } } });
|
|
6051
|
-
var Route$
|
|
6586
|
+
var Route$50 = createFileRoute("/api/slash-command")({ server: { handlers: { POST: async ({ request }) => {
|
|
6052
6587
|
try {
|
|
6053
6588
|
const body = await readRequestJson(request);
|
|
6054
6589
|
return jsonResponse(await getPicoRuntime().runSlashCommand(request, body));
|
|
@@ -6056,7 +6591,7 @@ var Route$45 = createFileRoute("/api/slash-command")({ server: { handlers: { POS
|
|
|
6056
6591
|
return routeErrorResponse(error, "Failed to run slash command");
|
|
6057
6592
|
}
|
|
6058
6593
|
} } } });
|
|
6059
|
-
var Route$
|
|
6594
|
+
var Route$49 = createFileRoute("/api/provider-usage")({ server: { handlers: { GET: async ({ request }) => {
|
|
6060
6595
|
const provider = new URL(request.url).searchParams.get("provider") || void 0;
|
|
6061
6596
|
try {
|
|
6062
6597
|
return jsonResponse({
|
|
@@ -6067,7 +6602,7 @@ var Route$44 = createFileRoute("/api/provider-usage")({ server: { handlers: { GE
|
|
|
6067
6602
|
return routeErrorResponse(error, "Failed to read provider usage");
|
|
6068
6603
|
}
|
|
6069
6604
|
} } } });
|
|
6070
|
-
var Route$
|
|
6605
|
+
var Route$48 = createFileRoute("/api/prompt")({ server: { handlers: { POST: async ({ request }) => {
|
|
6071
6606
|
try {
|
|
6072
6607
|
const body = await readRequestJson(request);
|
|
6073
6608
|
return jsonResponse(await getPicoRuntime().prompt(request, body));
|
|
@@ -6097,6 +6632,9 @@ var DIRECTORY_SEARCH_IGNORE_DIRECTORIES = new Set([
|
|
|
6097
6632
|
function displayPath(value = "") {
|
|
6098
6633
|
return String(value).replace(/\\/g, "/");
|
|
6099
6634
|
}
|
|
6635
|
+
function projectPathTextContains(text, query) {
|
|
6636
|
+
return text.indexOf(query) >= 0;
|
|
6637
|
+
}
|
|
6100
6638
|
function expandHomeDirectory(inputPath) {
|
|
6101
6639
|
if (inputPath === "~") return os.homedir();
|
|
6102
6640
|
if (inputPath.startsWith("~/")) return `${os.homedir()}${inputPath.slice(1)}`;
|
|
@@ -6165,13 +6703,12 @@ async function listPathCompletionEntries(prefix, baseCwd) {
|
|
|
6165
6703
|
return [];
|
|
6166
6704
|
}
|
|
6167
6705
|
const normalizedSearchPrefix = searchPrefix.toLowerCase();
|
|
6168
|
-
const
|
|
6169
|
-
|
|
6170
|
-
if (!entry.name.toLowerCase().startsWith(normalizedSearchPrefix)) continue;
|
|
6706
|
+
const matchingEntries = entries.filter((entry) => entry.name.toLowerCase().startsWith(normalizedSearchPrefix));
|
|
6707
|
+
const suggestions = await Promise.all(matchingEntries.map(async (entry) => {
|
|
6171
6708
|
const isDirectory = await completionEntryIsDirectory(entry, join(searchDir, entry.name));
|
|
6172
6709
|
let completionPath;
|
|
6173
6710
|
if (displayPrefix.endsWith("/") || displayPrefix.endsWith("\\")) completionPath = `${displayPrefix}${entry.name}`;
|
|
6174
|
-
else if (displayPrefix
|
|
6711
|
+
else if (projectPathTextContains(displayPrefix, "/") || projectPathTextContains(displayPrefix, "\\")) if (displayPrefix === "~") completionPath = `~/${entry.name}`;
|
|
6175
6712
|
else if (displayPrefix.startsWith("~/")) {
|
|
6176
6713
|
const parentDir = dirname(displayPrefix.slice(2));
|
|
6177
6714
|
completionPath = parentDir === "." ? `~/${entry.name}` : `~/${displayPath(parentDir)}/${entry.name}`;
|
|
@@ -6184,13 +6721,12 @@ async function listPathCompletionEntries(prefix, baseCwd) {
|
|
|
6184
6721
|
}
|
|
6185
6722
|
else if (displayPrefix.startsWith("~")) completionPath = `~/${entry.name}`;
|
|
6186
6723
|
else completionPath = entry.name;
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
value,
|
|
6724
|
+
return {
|
|
6725
|
+
value: isDirectory ? `${displayPath(completionPath)}/` : displayPath(completionPath),
|
|
6190
6726
|
label: `${entry.name}${isDirectory ? "/" : ""}`,
|
|
6191
6727
|
isDirectory
|
|
6192
|
-
}
|
|
6193
|
-
}
|
|
6728
|
+
};
|
|
6729
|
+
}));
|
|
6194
6730
|
suggestions.sort((left, right) => {
|
|
6195
6731
|
if (left.isDirectory && !right.isDirectory) return -1;
|
|
6196
6732
|
if (!left.isDirectory && right.isDirectory) return 1;
|
|
@@ -6257,7 +6793,7 @@ async function runFdSearch(command, args) {
|
|
|
6257
6793
|
const displayedLine = displayPath(line);
|
|
6258
6794
|
const hasTrailingSeparator = displayedLine.endsWith("/");
|
|
6259
6795
|
const normalizedPath = hasTrailingSeparator ? displayedLine.slice(0, -1) : displayedLine;
|
|
6260
|
-
if (normalizedPath === ".git" || normalizedPath.startsWith(".git/") || normalizedPath
|
|
6796
|
+
if (normalizedPath === ".git" || normalizedPath.startsWith(".git/") || projectPathTextContains(normalizedPath, "/.git/")) continue;
|
|
6261
6797
|
results.push({
|
|
6262
6798
|
path: displayedLine,
|
|
6263
6799
|
isDirectory: hasTrailingSeparator
|
|
@@ -6267,52 +6803,72 @@ async function runFdSearch(command, args) {
|
|
|
6267
6803
|
});
|
|
6268
6804
|
});
|
|
6269
6805
|
}
|
|
6806
|
+
async function runFdSearchCandidates(args) {
|
|
6807
|
+
return (await Promise.all(["fd", "fdfind"].map((command) => runFdSearch(command, args)))).find((result) => result !== void 0);
|
|
6808
|
+
}
|
|
6270
6809
|
function escapePathQueryRegex(value = "") {
|
|
6271
6810
|
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6272
6811
|
}
|
|
6273
6812
|
function buildFdPathQuery(query = "") {
|
|
6274
6813
|
const normalized = displayPath(query);
|
|
6275
|
-
if (!normalized
|
|
6814
|
+
if (!projectPathTextContains(normalized, "/")) return normalized;
|
|
6276
6815
|
const hasTrailingSeparator = normalized.endsWith("/");
|
|
6277
6816
|
const trimmed = normalized.replace(/^\/+|\/+$/g, "");
|
|
6278
6817
|
if (!trimmed) return normalized;
|
|
6279
6818
|
const separatorPattern = "[\\\\/]";
|
|
6280
|
-
const segments = trimmed.split("/").
|
|
6819
|
+
const segments = trimmed.split("/").flatMap((segment) => segment ? [escapePathQueryRegex(segment)] : []);
|
|
6281
6820
|
if (segments.length === 0) return normalized;
|
|
6282
6821
|
let pattern = segments.join(separatorPattern);
|
|
6283
6822
|
if (hasTrailingSeparator) pattern += separatorPattern;
|
|
6284
6823
|
return pattern;
|
|
6285
6824
|
}
|
|
6825
|
+
async function readDirectoryEntries(directory) {
|
|
6826
|
+
try {
|
|
6827
|
+
return await readdir(directory, {
|
|
6828
|
+
withFileTypes: true,
|
|
6829
|
+
encoding: "utf8"
|
|
6830
|
+
});
|
|
6831
|
+
} catch {
|
|
6832
|
+
return [];
|
|
6833
|
+
}
|
|
6834
|
+
}
|
|
6835
|
+
async function walkDirectoryFallbackLayer({ baseDir, normalizedQuery, currentDirs, matches, maxResults }) {
|
|
6836
|
+
if (currentDirs.length === 0 || matches.length >= maxResults) return;
|
|
6837
|
+
const directoryEntries = await Promise.all(currentDirs.map(async (currentDir) => ({
|
|
6838
|
+
currentDir,
|
|
6839
|
+
entries: await readDirectoryEntries(currentDir)
|
|
6840
|
+
})));
|
|
6841
|
+
const nextDirs = [];
|
|
6842
|
+
for (const { currentDir, entries } of directoryEntries) for (const entry of entries) {
|
|
6843
|
+
if (matches.length >= maxResults) break;
|
|
6844
|
+
if (WALK_IGNORE_DIRECTORIES.has(entry.name)) continue;
|
|
6845
|
+
const fullPath = join(currentDir, entry.name);
|
|
6846
|
+
const relativePath = displayPath(path.relative(baseDir, fullPath));
|
|
6847
|
+
const isDirectory = entry.isDirectory();
|
|
6848
|
+
const displayValue = isDirectory ? `${relativePath}/` : relativePath;
|
|
6849
|
+
if (!normalizedQuery || projectPathTextContains(displayValue.toLowerCase(), normalizedQuery)) matches.push({
|
|
6850
|
+
path: displayValue,
|
|
6851
|
+
isDirectory
|
|
6852
|
+
});
|
|
6853
|
+
if (isDirectory) nextDirs.push(fullPath);
|
|
6854
|
+
}
|
|
6855
|
+
await walkDirectoryFallbackLayer({
|
|
6856
|
+
baseDir,
|
|
6857
|
+
normalizedQuery,
|
|
6858
|
+
currentDirs: nextDirs,
|
|
6859
|
+
matches,
|
|
6860
|
+
maxResults
|
|
6861
|
+
});
|
|
6862
|
+
}
|
|
6286
6863
|
async function walkDirectoryWithFallback(baseDir, query = "", maxResults = 100) {
|
|
6287
|
-
const queue = [baseDir];
|
|
6288
6864
|
const matches = [];
|
|
6289
|
-
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
withFileTypes: true,
|
|
6297
|
-
encoding: "utf8"
|
|
6298
|
-
});
|
|
6299
|
-
} catch {
|
|
6300
|
-
continue;
|
|
6301
|
-
}
|
|
6302
|
-
for (const entry of entries) {
|
|
6303
|
-
if (matches.length >= maxResults) break;
|
|
6304
|
-
if (WALK_IGNORE_DIRECTORIES.has(entry.name)) continue;
|
|
6305
|
-
const fullPath = join(currentDir, entry.name);
|
|
6306
|
-
const relativePath = displayPath(path.relative(baseDir, fullPath));
|
|
6307
|
-
const isDirectory = entry.isDirectory();
|
|
6308
|
-
const displayValue = isDirectory ? `${relativePath}/` : relativePath;
|
|
6309
|
-
if (!normalizedQuery || displayValue.toLowerCase().includes(normalizedQuery)) matches.push({
|
|
6310
|
-
path: displayValue,
|
|
6311
|
-
isDirectory
|
|
6312
|
-
});
|
|
6313
|
-
if (isDirectory) queue.push(fullPath);
|
|
6314
|
-
}
|
|
6315
|
-
}
|
|
6865
|
+
await walkDirectoryFallbackLayer({
|
|
6866
|
+
baseDir,
|
|
6867
|
+
normalizedQuery: displayPath(query).toLowerCase(),
|
|
6868
|
+
currentDirs: [baseDir],
|
|
6869
|
+
matches,
|
|
6870
|
+
maxResults
|
|
6871
|
+
});
|
|
6316
6872
|
return matches;
|
|
6317
6873
|
}
|
|
6318
6874
|
async function walkDirectory(baseDir, query = "", maxResults = 100) {
|
|
@@ -6345,10 +6901,8 @@ async function walkDirectory(baseDir, query = "", maxResults = 100) {
|
|
|
6345
6901
|
"node_modules"
|
|
6346
6902
|
];
|
|
6347
6903
|
if (query) args.push(buildFdPathQuery(query));
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
if (results !== void 0) return results;
|
|
6351
|
-
}
|
|
6904
|
+
const results = await runFdSearchCandidates(args);
|
|
6905
|
+
if (results !== void 0) return results;
|
|
6352
6906
|
return await walkDirectoryWithFallback(baseDir, query, maxResults);
|
|
6353
6907
|
}
|
|
6354
6908
|
async function resolveScopedFileReferenceQuery(rawQuery, baseCwd) {
|
|
@@ -6394,7 +6948,11 @@ function resolveProjectFilePath(baseCwd, filePath) {
|
|
|
6394
6948
|
};
|
|
6395
6949
|
}
|
|
6396
6950
|
async function listProjectFileTreePaths(baseCwd) {
|
|
6397
|
-
return (await walkDirectory(baseCwd, "", PROJECT_FILE_TREE_LIMIT)).
|
|
6951
|
+
return (await walkDirectory(baseCwd, "", PROJECT_FILE_TREE_LIMIT)).flatMap((entry) => {
|
|
6952
|
+
if (entry.isDirectory) return [];
|
|
6953
|
+
const path = displayPath(entry.path).replace(/\/+$/g, "");
|
|
6954
|
+
return path ? [path] : [];
|
|
6955
|
+
}).sort((left, right) => left.localeCompare(right));
|
|
6398
6956
|
}
|
|
6399
6957
|
async function readProjectFileContent(baseCwd, filePath) {
|
|
6400
6958
|
const resolved = resolveProjectFilePath(baseCwd, filePath);
|
|
@@ -6423,46 +6981,54 @@ function directorySearchScore({ absolutePath, query, root }) {
|
|
|
6423
6981
|
if (score === 0) return 0;
|
|
6424
6982
|
return score - depth * 5;
|
|
6425
6983
|
}
|
|
6984
|
+
async function searchDirectoriesFallbackLayer({ root, normalizedQuery, currentDirectories, results, maxResults }) {
|
|
6985
|
+
const eligibleDirectories = currentDirectories.filter((current) => current.depth < DIRECTORY_SEARCH_MAX_DEPTH);
|
|
6986
|
+
if (eligibleDirectories.length === 0 || results.length >= maxResults) return;
|
|
6987
|
+
const directoryEntries = await Promise.all(eligibleDirectories.map(async (current) => ({
|
|
6988
|
+
current,
|
|
6989
|
+
entries: await readDirectoryEntries(current.directory)
|
|
6990
|
+
})));
|
|
6991
|
+
const nextDirectories = [];
|
|
6992
|
+
for (const { current, entries } of directoryEntries) for (const entry of entries) {
|
|
6993
|
+
if (results.length >= maxResults) break;
|
|
6994
|
+
if (!entry.isDirectory()) continue;
|
|
6995
|
+
if (DIRECTORY_SEARCH_IGNORE_DIRECTORIES.has(entry.name)) continue;
|
|
6996
|
+
if (!normalizedQuery.startsWith(".") && entry.name.startsWith(".")) continue;
|
|
6997
|
+
const fullPath = join(current.directory, entry.name);
|
|
6998
|
+
const relativePath = `${displayPath(path.relative(root, fullPath))}/`;
|
|
6999
|
+
if (projectPathTextContains(relativePath.toLowerCase(), normalizedQuery)) results.push({
|
|
7000
|
+
path: relativePath,
|
|
7001
|
+
isDirectory: true
|
|
7002
|
+
});
|
|
7003
|
+
nextDirectories.push({
|
|
7004
|
+
directory: fullPath,
|
|
7005
|
+
depth: current.depth + 1
|
|
7006
|
+
});
|
|
7007
|
+
}
|
|
7008
|
+
await searchDirectoriesFallbackLayer({
|
|
7009
|
+
root,
|
|
7010
|
+
normalizedQuery,
|
|
7011
|
+
currentDirectories: nextDirectories,
|
|
7012
|
+
results,
|
|
7013
|
+
maxResults
|
|
7014
|
+
});
|
|
7015
|
+
}
|
|
6426
7016
|
async function searchDirectoriesWithFallback({ root, query, maxResults }) {
|
|
6427
|
-
const normalizedQuery = query.trim().toLowerCase();
|
|
6428
7017
|
const results = [];
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
withFileTypes: true,
|
|
6440
|
-
encoding: "utf8"
|
|
6441
|
-
});
|
|
6442
|
-
} catch {
|
|
6443
|
-
continue;
|
|
6444
|
-
}
|
|
6445
|
-
for (const entry of entries) {
|
|
6446
|
-
if (results.length >= maxResults) break;
|
|
6447
|
-
if (!entry.isDirectory()) continue;
|
|
6448
|
-
if (DIRECTORY_SEARCH_IGNORE_DIRECTORIES.has(entry.name)) continue;
|
|
6449
|
-
if (!normalizedQuery.startsWith(".") && entry.name.startsWith(".")) continue;
|
|
6450
|
-
const fullPath = join(current.directory, entry.name);
|
|
6451
|
-
const relativePath = `${displayPath(path.relative(root, fullPath))}/`;
|
|
6452
|
-
if (relativePath.toLowerCase().includes(normalizedQuery)) results.push({
|
|
6453
|
-
path: relativePath,
|
|
6454
|
-
isDirectory: true
|
|
6455
|
-
});
|
|
6456
|
-
queue.push({
|
|
6457
|
-
directory: fullPath,
|
|
6458
|
-
depth: current.depth + 1
|
|
6459
|
-
});
|
|
6460
|
-
}
|
|
6461
|
-
}
|
|
7018
|
+
await searchDirectoriesFallbackLayer({
|
|
7019
|
+
root,
|
|
7020
|
+
normalizedQuery: query.trim().toLowerCase(),
|
|
7021
|
+
currentDirectories: [{
|
|
7022
|
+
directory: root,
|
|
7023
|
+
depth: 0
|
|
7024
|
+
}],
|
|
7025
|
+
results,
|
|
7026
|
+
maxResults
|
|
7027
|
+
});
|
|
6462
7028
|
return results;
|
|
6463
7029
|
}
|
|
6464
7030
|
async function searchDirectoriesInRoot({ root, query, maxResults }) {
|
|
6465
|
-
const
|
|
7031
|
+
const results = await runFdSearchCandidates([
|
|
6466
7032
|
"--base-directory",
|
|
6467
7033
|
root,
|
|
6468
7034
|
"--max-depth",
|
|
@@ -6498,11 +7064,8 @@ async function searchDirectoriesInRoot({ root, query, maxResults }) {
|
|
|
6498
7064
|
"--exclude",
|
|
6499
7065
|
"node_modules",
|
|
6500
7066
|
buildFdPathQuery(query)
|
|
6501
|
-
];
|
|
6502
|
-
|
|
6503
|
-
const results = await runFdSearch(command, args);
|
|
6504
|
-
if (results !== void 0) return results.filter((entry) => entry.isDirectory);
|
|
6505
|
-
}
|
|
7067
|
+
]);
|
|
7068
|
+
if (results !== void 0) return results.filter((entry) => entry.isDirectory);
|
|
6506
7069
|
return await searchDirectoriesWithFallback({
|
|
6507
7070
|
root,
|
|
6508
7071
|
query,
|
|
@@ -6521,37 +7084,40 @@ async function searchDirectoryEntries(query, baseCwd) {
|
|
|
6521
7084
|
if (baseCwd && !pathIsInside(baseCwd, homeDirectory)) roots.push(baseCwd);
|
|
6522
7085
|
const seen = /* @__PURE__ */ new Set();
|
|
6523
7086
|
const matches = [];
|
|
6524
|
-
|
|
7087
|
+
const rootEntries = await Promise.all(roots.map(async (root) => {
|
|
6525
7088
|
let rootStats;
|
|
6526
7089
|
try {
|
|
6527
7090
|
rootStats = await stat(root);
|
|
6528
7091
|
} catch {
|
|
6529
|
-
|
|
7092
|
+
return [];
|
|
6530
7093
|
}
|
|
6531
|
-
if (!rootStats.isDirectory())
|
|
6532
|
-
|
|
7094
|
+
if (!rootStats.isDirectory()) return [];
|
|
7095
|
+
return (await searchDirectoriesInRoot({
|
|
6533
7096
|
root,
|
|
6534
7097
|
query: normalizedQuery,
|
|
6535
7098
|
maxResults: DIRECTORY_SEARCH_LIMIT * 4
|
|
7099
|
+
})).map((entry) => ({
|
|
7100
|
+
entry,
|
|
7101
|
+
root
|
|
7102
|
+
}));
|
|
7103
|
+
}));
|
|
7104
|
+
for (const { entry, root } of rootEntries.flat()) {
|
|
7105
|
+
const relativePath = displayPath(entry.path).replace(/\/+$/g, "");
|
|
7106
|
+
if (!relativePath) continue;
|
|
7107
|
+
const absolutePath = resolve(root, relativePath);
|
|
7108
|
+
if (seen.has(absolutePath)) continue;
|
|
7109
|
+
seen.add(absolutePath);
|
|
7110
|
+
const score = directorySearchScore({
|
|
7111
|
+
absolutePath,
|
|
7112
|
+
query: normalizedQuery,
|
|
7113
|
+
root
|
|
7114
|
+
});
|
|
7115
|
+
if (score <= 0) continue;
|
|
7116
|
+
matches.push({
|
|
7117
|
+
absolutePath,
|
|
7118
|
+
root,
|
|
7119
|
+
score
|
|
6536
7120
|
});
|
|
6537
|
-
for (const entry of entries) {
|
|
6538
|
-
const relativePath = displayPath(entry.path).replace(/\/+$/g, "");
|
|
6539
|
-
if (!relativePath) continue;
|
|
6540
|
-
const absolutePath = resolve(root, relativePath);
|
|
6541
|
-
if (seen.has(absolutePath)) continue;
|
|
6542
|
-
seen.add(absolutePath);
|
|
6543
|
-
const score = directorySearchScore({
|
|
6544
|
-
absolutePath,
|
|
6545
|
-
query: normalizedQuery,
|
|
6546
|
-
root
|
|
6547
|
-
});
|
|
6548
|
-
if (score <= 0) continue;
|
|
6549
|
-
matches.push({
|
|
6550
|
-
absolutePath,
|
|
6551
|
-
root,
|
|
6552
|
-
score
|
|
6553
|
-
});
|
|
6554
|
-
}
|
|
6555
7121
|
}
|
|
6556
7122
|
return matches.sort((left, right) => {
|
|
6557
7123
|
if (right.score !== left.score) return right.score - left.score;
|
|
@@ -6571,10 +7137,13 @@ async function listFileReferenceEntries(query, baseCwd, { isQuotedPrefix = false
|
|
|
6571
7137
|
const scopedQuery = await resolveScopedFileReferenceQuery(normalizedQuery, baseCwd);
|
|
6572
7138
|
const searchBaseDir = scopedQuery?.searchBaseDir ?? baseCwd;
|
|
6573
7139
|
const searchQuery = scopedQuery?.query ?? normalizedQuery;
|
|
6574
|
-
return (await walkDirectory(searchBaseDir, searchQuery, 100)).
|
|
6575
|
-
|
|
6576
|
-
score
|
|
6577
|
-
|
|
7140
|
+
return (await walkDirectory(searchBaseDir, searchQuery, 100)).flatMap((entry) => {
|
|
7141
|
+
const score = scoreFileReferenceEntry(entry.path, searchQuery, entry.isDirectory);
|
|
7142
|
+
return score > 0 ? [{
|
|
7143
|
+
...entry,
|
|
7144
|
+
score
|
|
7145
|
+
}] : [];
|
|
7146
|
+
}).sort((left, right) => right.score - left.score).slice(0, 20).map((entry) => {
|
|
6578
7147
|
const pathWithoutSlash = entry.isDirectory ? entry.path.slice(0, -1) : entry.path;
|
|
6579
7148
|
const displayValue = scopedQuery ? scopedDisplayPath(scopedQuery.displayBase, pathWithoutSlash) : pathWithoutSlash;
|
|
6580
7149
|
return {
|
|
@@ -6588,7 +7157,7 @@ async function listFileReferenceEntries(query, baseCwd, { isQuotedPrefix = false
|
|
|
6588
7157
|
};
|
|
6589
7158
|
});
|
|
6590
7159
|
}
|
|
6591
|
-
var Route$
|
|
7160
|
+
var Route$47 = createFileRoute("/api/path-completions")({ server: { handlers: { POST: async ({ request }) => {
|
|
6592
7161
|
try {
|
|
6593
7162
|
const body = await readRequestJson(request);
|
|
6594
7163
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -6604,7 +7173,7 @@ var Route$42 = createFileRoute("/api/path-completions")({ server: { handlers: {
|
|
|
6604
7173
|
return routeErrorResponse(error, "Failed to list path completions");
|
|
6605
7174
|
}
|
|
6606
7175
|
} } } });
|
|
6607
|
-
var Route$
|
|
7176
|
+
var Route$46 = createFileRoute("/api/model")({ server: { handlers: { POST: async ({ request }) => {
|
|
6608
7177
|
try {
|
|
6609
7178
|
const body = await readRequestJson(request);
|
|
6610
7179
|
return jsonResponse(await getPicoRuntime().setModel(request, body));
|
|
@@ -6612,7 +7181,7 @@ var Route$41 = createFileRoute("/api/model")({ server: { handlers: { POST: async
|
|
|
6612
7181
|
return routeErrorResponse(error, "Failed to update model");
|
|
6613
7182
|
}
|
|
6614
7183
|
} } } });
|
|
6615
|
-
var Route$
|
|
7184
|
+
var Route$45 = createFileRoute("/api/highlight")({ server: { handlers: { POST: async ({ request }) => {
|
|
6616
7185
|
try {
|
|
6617
7186
|
const body = await readRequestJson(request);
|
|
6618
7187
|
return jsonResponse(await getPicoRuntime().highlightCode(body.code, body.language));
|
|
@@ -6620,7 +7189,7 @@ var Route$40 = createFileRoute("/api/highlight")({ server: { handlers: { POST: a
|
|
|
6620
7189
|
return routeErrorResponse(error, "Failed to highlight code");
|
|
6621
7190
|
}
|
|
6622
7191
|
} } } });
|
|
6623
|
-
var Route$
|
|
7192
|
+
var Route$44 = createFileRoute("/api/git-status")({ server: { handlers: { GET: async ({ request }) => {
|
|
6624
7193
|
const requestedCwd = new URL(request.url).searchParams.get("cwd") || "";
|
|
6625
7194
|
if (!requestedCwd.trim()) return errorResponse("cwd is required");
|
|
6626
7195
|
try {
|
|
@@ -6635,7 +7204,7 @@ var Route$39 = createFileRoute("/api/git-status")({ server: { handlers: { GET: a
|
|
|
6635
7204
|
return routeErrorResponse(error, "Failed to read git status");
|
|
6636
7205
|
}
|
|
6637
7206
|
} } } });
|
|
6638
|
-
var Route$
|
|
7207
|
+
var Route$43 = createFileRoute("/api/git-stage")({ server: { handlers: { POST: async ({ request }) => {
|
|
6639
7208
|
try {
|
|
6640
7209
|
const body = await readRequestJson(request);
|
|
6641
7210
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6656,7 +7225,7 @@ var Route$38 = createFileRoute("/api/git-stage")({ server: { handlers: { POST: a
|
|
|
6656
7225
|
return routeErrorResponse(error, "Failed to stage changes");
|
|
6657
7226
|
}
|
|
6658
7227
|
} } } });
|
|
6659
|
-
var Route$
|
|
7228
|
+
var Route$42 = createFileRoute("/api/git-review")({ server: { handlers: { GET: async ({ request }) => {
|
|
6660
7229
|
const url = new URL(request.url);
|
|
6661
7230
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
6662
7231
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -6679,7 +7248,7 @@ var Route$37 = createFileRoute("/api/git-review")({ server: { handlers: { GET: a
|
|
|
6679
7248
|
return routeErrorResponse(error, "Failed to read git review file");
|
|
6680
7249
|
}
|
|
6681
7250
|
} } } });
|
|
6682
|
-
var Route$
|
|
7251
|
+
var Route$41 = createFileRoute("/api/git-push")({ server: { handlers: { POST: async ({ request }) => {
|
|
6683
7252
|
try {
|
|
6684
7253
|
const body = await readRequestJson(request);
|
|
6685
7254
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6698,7 +7267,7 @@ var Route$36 = createFileRoute("/api/git-push")({ server: { handlers: { POST: as
|
|
|
6698
7267
|
return routeErrorResponse(error, "Failed to push changes");
|
|
6699
7268
|
}
|
|
6700
7269
|
} } } });
|
|
6701
|
-
var Route$
|
|
7270
|
+
var Route$40 = createFileRoute("/api/git-pull")({ server: { handlers: { POST: async ({ request }) => {
|
|
6702
7271
|
try {
|
|
6703
7272
|
const body = await readRequestJson(request);
|
|
6704
7273
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6716,7 +7285,7 @@ var Route$35 = createFileRoute("/api/git-pull")({ server: { handlers: { POST: as
|
|
|
6716
7285
|
return routeErrorResponse(error, "Failed to pull changes");
|
|
6717
7286
|
}
|
|
6718
7287
|
} } } });
|
|
6719
|
-
var Route$
|
|
7288
|
+
var Route$39 = createFileRoute("/api/git-discard")({ server: { handlers: { POST: async ({ request }) => {
|
|
6720
7289
|
try {
|
|
6721
7290
|
const body = await readRequestJson(request);
|
|
6722
7291
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6738,7 +7307,7 @@ var Route$34 = createFileRoute("/api/git-discard")({ server: { handlers: { POST:
|
|
|
6738
7307
|
return routeErrorResponse(error, "Failed to discard changes");
|
|
6739
7308
|
}
|
|
6740
7309
|
} } } });
|
|
6741
|
-
var Route$
|
|
7310
|
+
var Route$38 = createFileRoute("/api/git-diff")({ server: { handlers: { GET: async ({ request }) => {
|
|
6742
7311
|
const url = new URL(request.url);
|
|
6743
7312
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
6744
7313
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -6758,7 +7327,28 @@ var Route$33 = createFileRoute("/api/git-diff")({ server: { handlers: { GET: asy
|
|
|
6758
7327
|
return routeErrorResponse(error, "Failed to read git diff");
|
|
6759
7328
|
}
|
|
6760
7329
|
} } } });
|
|
6761
|
-
var Route$
|
|
7330
|
+
var Route$37 = createFileRoute("/api/git-commit-remote-url")({ server: { handlers: { GET: async ({ request }) => {
|
|
7331
|
+
try {
|
|
7332
|
+
const url = new URL(request.url);
|
|
7333
|
+
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7334
|
+
const commit = url.searchParams.get("commit") || "";
|
|
7335
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7336
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7337
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7338
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7339
|
+
const result = await readDirectoryGitCommitRemoteUrl(cwd, commit);
|
|
7340
|
+
if (!result?.remoteUrl) throw new Error("No remote URL found");
|
|
7341
|
+
return jsonResponse({
|
|
7342
|
+
ok: true,
|
|
7343
|
+
cwd,
|
|
7344
|
+
commit: result.commit,
|
|
7345
|
+
remoteUrl: result.remoteUrl
|
|
7346
|
+
});
|
|
7347
|
+
} catch (error) {
|
|
7348
|
+
return routeErrorResponse(error, "Failed to read commit remote URL");
|
|
7349
|
+
}
|
|
7350
|
+
} } } });
|
|
7351
|
+
var Route$36 = createFileRoute("/api/git-commit-message")({ server: { handlers: { POST: async ({ request }) => {
|
|
6762
7352
|
try {
|
|
6763
7353
|
const body = await readRequestJson(request);
|
|
6764
7354
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6777,7 +7367,93 @@ var Route$32 = createFileRoute("/api/git-commit-message")({ server: { handlers:
|
|
|
6777
7367
|
return routeErrorResponse(error, "Failed to generate commit message");
|
|
6778
7368
|
}
|
|
6779
7369
|
} } } });
|
|
6780
|
-
var Route$
|
|
7370
|
+
var Route$35 = createFileRoute("/api/git-commit-files")({ server: { handlers: { GET: async ({ request }) => {
|
|
7371
|
+
try {
|
|
7372
|
+
const url = new URL(request.url);
|
|
7373
|
+
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7374
|
+
const commit = url.searchParams.get("commit") || "";
|
|
7375
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7376
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7377
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7378
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7379
|
+
return jsonResponse({
|
|
7380
|
+
ok: true,
|
|
7381
|
+
cwd,
|
|
7382
|
+
commit,
|
|
7383
|
+
files: await readDirectoryGitCommitFiles(cwd, commit) || []
|
|
7384
|
+
});
|
|
7385
|
+
} catch (error) {
|
|
7386
|
+
return routeErrorResponse(error, "Failed to read commit files");
|
|
7387
|
+
}
|
|
7388
|
+
} } } });
|
|
7389
|
+
function normalizeGitCommitDiffMode(value) {
|
|
7390
|
+
if (value === "head" || value === "previous") return value;
|
|
7391
|
+
return "commit";
|
|
7392
|
+
}
|
|
7393
|
+
var Route$34 = createFileRoute("/api/git-commit-diff")({ server: { handlers: { GET: async ({ request }) => {
|
|
7394
|
+
try {
|
|
7395
|
+
const url = new URL(request.url);
|
|
7396
|
+
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7397
|
+
const commit = url.searchParams.get("commit") || "";
|
|
7398
|
+
const mode = normalizeGitCommitDiffMode(url.searchParams.get("mode"));
|
|
7399
|
+
const path = url.searchParams.get("path") || void 0;
|
|
7400
|
+
const previousPath = url.searchParams.get("previousPath") || void 0;
|
|
7401
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7402
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7403
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7404
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7405
|
+
const result = await readDirectoryGitCommitDiff(cwd, commit, mode, path, previousPath);
|
|
7406
|
+
return jsonResponse({
|
|
7407
|
+
ok: true,
|
|
7408
|
+
cwd,
|
|
7409
|
+
commit: result?.commit || commit,
|
|
7410
|
+
mode,
|
|
7411
|
+
title: result?.title || commit,
|
|
7412
|
+
...result?.path ? { path: result.path } : {},
|
|
7413
|
+
...result?.previousPath ? { previousPath: result.previousPath } : {},
|
|
7414
|
+
patch: result?.patch || "No git repository detected."
|
|
7415
|
+
});
|
|
7416
|
+
} catch (error) {
|
|
7417
|
+
return routeErrorResponse(error, "Failed to read commit diff");
|
|
7418
|
+
}
|
|
7419
|
+
} } } });
|
|
7420
|
+
var gitCommitActions = new Set([
|
|
7421
|
+
"checkout",
|
|
7422
|
+
"cherry-pick",
|
|
7423
|
+
"revert",
|
|
7424
|
+
"tag",
|
|
7425
|
+
"reset",
|
|
7426
|
+
"rebase",
|
|
7427
|
+
"drop",
|
|
7428
|
+
"squash"
|
|
7429
|
+
]);
|
|
7430
|
+
var Route$33 = createFileRoute("/api/git-commit-action")({ server: { handlers: { POST: async ({ request }) => {
|
|
7431
|
+
try {
|
|
7432
|
+
const body = await readRequestJson(request);
|
|
7433
|
+
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
7434
|
+
const action = typeof body.action === "string" ? body.action : "";
|
|
7435
|
+
const commit = typeof body.commit === "string" ? body.commit : "";
|
|
7436
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7437
|
+
if (!gitCommitActions.has(action)) throw new Error("action is required");
|
|
7438
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7439
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7440
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7441
|
+
const result = await runDirectoryGitCommitAction(cwd, action, commit, {
|
|
7442
|
+
tagName: typeof body.tagName === "string" ? body.tagName : "",
|
|
7443
|
+
resetMode: typeof body.resetMode === "string" ? body.resetMode : "",
|
|
7444
|
+
message: typeof body.message === "string" ? body.message : ""
|
|
7445
|
+
});
|
|
7446
|
+
return jsonResponse({
|
|
7447
|
+
ok: true,
|
|
7448
|
+
cwd,
|
|
7449
|
+
stdout: result.stdout,
|
|
7450
|
+
stderr: result.stderr
|
|
7451
|
+
});
|
|
7452
|
+
} catch (error) {
|
|
7453
|
+
return routeErrorResponse(error, "Failed to run commit action");
|
|
7454
|
+
}
|
|
7455
|
+
} } } });
|
|
7456
|
+
var Route$32 = createFileRoute("/api/git-commit")({ server: { handlers: { POST: async ({ request }) => {
|
|
6781
7457
|
try {
|
|
6782
7458
|
const body = await readRequestJson(request);
|
|
6783
7459
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6802,7 +7478,7 @@ var Route$31 = createFileRoute("/api/git-commit")({ server: { handlers: { POST:
|
|
|
6802
7478
|
return routeErrorResponse(error, "Failed to commit changes");
|
|
6803
7479
|
}
|
|
6804
7480
|
} } } });
|
|
6805
|
-
var Route$
|
|
7481
|
+
var Route$31 = createFileRoute("/api/git-checkout")({ server: { handlers: { POST: async ({ request }) => {
|
|
6806
7482
|
try {
|
|
6807
7483
|
const body = await readRequestJson(request);
|
|
6808
7484
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6852,7 +7528,7 @@ function getRuntimeRequestForGitChanges(request, url) {
|
|
|
6852
7528
|
method: request.method
|
|
6853
7529
|
});
|
|
6854
7530
|
}
|
|
6855
|
-
var Route$
|
|
7531
|
+
var Route$30 = createFileRoute("/api/git-changes")({ server: { handlers: { GET: async ({ request }) => {
|
|
6856
7532
|
const url = new URL(request.url);
|
|
6857
7533
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
6858
7534
|
const gitScope = getGitChangesScope(url);
|
|
@@ -6922,7 +7598,7 @@ var Route$29 = createFileRoute("/api/git-changes")({ server: { handlers: { GET:
|
|
|
6922
7598
|
return routeErrorResponse(error, "Failed to read git changes");
|
|
6923
7599
|
}
|
|
6924
7600
|
} } } });
|
|
6925
|
-
var Route$
|
|
7601
|
+
var Route$29 = createFileRoute("/api/file-completions")({ server: { handlers: { POST: async ({ request }) => {
|
|
6926
7602
|
try {
|
|
6927
7603
|
const body = await readRequestJson(request);
|
|
6928
7604
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -6939,7 +7615,7 @@ var Route$28 = createFileRoute("/api/file-completions")({ server: { handlers: {
|
|
|
6939
7615
|
return routeErrorResponse(error, "Failed to list file completions");
|
|
6940
7616
|
}
|
|
6941
7617
|
} } } });
|
|
6942
|
-
var Route$
|
|
7618
|
+
var Route$28 = createFileRoute("/api/directory-sessions-indexes")({ server: { handlers: { GET: async ({ request }) => {
|
|
6943
7619
|
const directories = new URL(request.url).searchParams.getAll("directory");
|
|
6944
7620
|
if (directories.length === 0) return errorResponse("at least one directory is required");
|
|
6945
7621
|
try {
|
|
@@ -6948,7 +7624,7 @@ var Route$27 = createFileRoute("/api/directory-sessions-indexes")({ server: { ha
|
|
|
6948
7624
|
return routeErrorResponse(error, "Failed to list directory session indexes");
|
|
6949
7625
|
}
|
|
6950
7626
|
} } } });
|
|
6951
|
-
var Route$
|
|
7627
|
+
var Route$27 = createFileRoute("/api/directory-sessions-index")({ server: { handlers: { GET: async ({ request }) => {
|
|
6952
7628
|
const directory = new URL(request.url).searchParams.get("directory") || "";
|
|
6953
7629
|
if (!directory.trim()) return errorResponse("directory is required");
|
|
6954
7630
|
try {
|
|
@@ -6957,7 +7633,7 @@ var Route$26 = createFileRoute("/api/directory-sessions-index")({ server: { hand
|
|
|
6957
7633
|
return routeErrorResponse(error, "Failed to list directory session index");
|
|
6958
7634
|
}
|
|
6959
7635
|
} } } });
|
|
6960
|
-
var Route$
|
|
7636
|
+
var Route$26 = createFileRoute("/api/directory-sessions")({ server: { handlers: { GET: async ({ request }) => {
|
|
6961
7637
|
const url = new URL(request.url);
|
|
6962
7638
|
const directory = url.searchParams.get("directory") || "";
|
|
6963
7639
|
const offset = Number.parseInt(url.searchParams.get("offset") || "0", 10);
|
|
@@ -6972,7 +7648,7 @@ var Route$25 = createFileRoute("/api/directory-sessions")({ server: { handlers:
|
|
|
6972
7648
|
return routeErrorResponse(error, "Failed to list directory sessions");
|
|
6973
7649
|
}
|
|
6974
7650
|
} } } });
|
|
6975
|
-
var Route$
|
|
7651
|
+
var Route$25 = createFileRoute("/api/directory-search")({ server: { handlers: { POST: async ({ request }) => {
|
|
6976
7652
|
try {
|
|
6977
7653
|
const body = await readRequestJson(request);
|
|
6978
7654
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -6988,14 +7664,14 @@ var Route$24 = createFileRoute("/api/directory-search")({ server: { handlers: {
|
|
|
6988
7664
|
return routeErrorResponse(error, "Failed to search directories");
|
|
6989
7665
|
}
|
|
6990
7666
|
} } } });
|
|
6991
|
-
var Route$
|
|
7667
|
+
var Route$24 = createFileRoute("/api/abort")({ server: { handlers: { POST: async ({ request }) => {
|
|
6992
7668
|
try {
|
|
6993
7669
|
return jsonResponse(await getPicoRuntime().abort(request));
|
|
6994
7670
|
} catch (error) {
|
|
6995
7671
|
return routeErrorResponse(error, "Failed to abort session");
|
|
6996
7672
|
}
|
|
6997
7673
|
} } } });
|
|
6998
|
-
var Route$
|
|
7674
|
+
var Route$23 = createFileRoute("/api/ui/$id")({ server: { handlers: { POST: async ({ request, params }) => {
|
|
6999
7675
|
try {
|
|
7000
7676
|
const body = await readRequestJson(request);
|
|
7001
7677
|
return jsonResponse(await getPicoRuntime().resolveUiRequest(params.id, body));
|
|
@@ -7003,7 +7679,7 @@ var Route$22 = createFileRoute("/api/ui/$id")({ server: { handlers: { POST: asyn
|
|
|
7003
7679
|
return routeErrorResponse(error, "Failed to resolve UI request");
|
|
7004
7680
|
}
|
|
7005
7681
|
} } } });
|
|
7006
|
-
var Route$
|
|
7682
|
+
var Route$22 = createFileRoute("/api/settings/hide-thinking")({ server: { handlers: { POST: async ({ request }) => {
|
|
7007
7683
|
try {
|
|
7008
7684
|
const body = await readRequestJson(request);
|
|
7009
7685
|
return jsonResponse(await getPicoRuntime().setHideThinking(body));
|
|
@@ -7011,7 +7687,7 @@ var Route$21 = createFileRoute("/api/settings/hide-thinking")({ server: { handle
|
|
|
7011
7687
|
return routeErrorResponse(error, "Failed to update hide-thinking setting");
|
|
7012
7688
|
}
|
|
7013
7689
|
} } } });
|
|
7014
|
-
var Route$
|
|
7690
|
+
var Route$21 = createFileRoute("/api/sessions/delete")({ server: { handlers: { POST: async ({ request }) => {
|
|
7015
7691
|
try {
|
|
7016
7692
|
const body = await readRequestJson(request);
|
|
7017
7693
|
return jsonResponse(await getPicoRuntime().deleteSessions(request, body));
|
|
@@ -7019,7 +7695,7 @@ var Route$20 = createFileRoute("/api/sessions/delete")({ server: { handlers: { P
|
|
|
7019
7695
|
return routeErrorResponse(error, "Failed to delete sessions");
|
|
7020
7696
|
}
|
|
7021
7697
|
} } } });
|
|
7022
|
-
var Route$
|
|
7698
|
+
var Route$20 = createFileRoute("/api/session/tree")({ server: { handlers: {
|
|
7023
7699
|
GET: async ({ request }) => {
|
|
7024
7700
|
try {
|
|
7025
7701
|
return jsonResponse(await getPicoRuntime().getSessionTreeForRequest(request));
|
|
@@ -7036,14 +7712,14 @@ var Route$19 = createFileRoute("/api/session/tree")({ server: { handlers: {
|
|
|
7036
7712
|
}
|
|
7037
7713
|
}
|
|
7038
7714
|
} } });
|
|
7039
|
-
var Route$
|
|
7715
|
+
var Route$19 = createFileRoute("/api/session/select")({ server: { handlers: { POST: async ({ request }) => {
|
|
7040
7716
|
try {
|
|
7041
7717
|
return jsonResponse(await getPicoRuntime().selectSession(request));
|
|
7042
7718
|
} catch (error) {
|
|
7043
7719
|
return routeErrorResponse(error, "Failed to select session");
|
|
7044
7720
|
}
|
|
7045
7721
|
} } } });
|
|
7046
|
-
var Route$
|
|
7722
|
+
var Route$18 = createFileRoute("/api/session/rename")({ server: { handlers: { POST: async ({ request }) => {
|
|
7047
7723
|
try {
|
|
7048
7724
|
const body = await readRequestJson(request);
|
|
7049
7725
|
return jsonResponse(await getPicoRuntime().renameSession(body));
|
|
@@ -7051,6 +7727,14 @@ var Route$17 = createFileRoute("/api/session/rename")({ server: { handlers: { PO
|
|
|
7051
7727
|
return routeErrorResponse(error, "Failed to rename session");
|
|
7052
7728
|
}
|
|
7053
7729
|
} } } });
|
|
7730
|
+
var Route$17 = createFileRoute("/api/session/read-state")({ server: { handlers: { POST: async ({ request }) => {
|
|
7731
|
+
try {
|
|
7732
|
+
const body = await readRequestJson(request);
|
|
7733
|
+
return jsonResponse(await getPicoRuntime().setSessionReadState(request, body));
|
|
7734
|
+
} catch (error) {
|
|
7735
|
+
return routeErrorResponse(error, "Failed to update session read state");
|
|
7736
|
+
}
|
|
7737
|
+
} } } });
|
|
7054
7738
|
var Route$16 = createFileRoute("/api/session/new")({ server: { handlers: { POST: async ({ request }) => {
|
|
7055
7739
|
try {
|
|
7056
7740
|
const body = await readRequestJson(request);
|
|
@@ -7224,220 +7908,245 @@ var Route = createFileRoute("/api/session/tree/label")({ server: { handlers: { P
|
|
|
7224
7908
|
return routeErrorResponse(error, "Failed to update tree label");
|
|
7225
7909
|
}
|
|
7226
7910
|
} } } });
|
|
7227
|
-
var EventsRoute = Route$
|
|
7911
|
+
var EventsRoute = Route$52.update({
|
|
7228
7912
|
id: "/events",
|
|
7229
7913
|
path: "/events",
|
|
7230
|
-
getParentRoute: () => Route$
|
|
7914
|
+
getParentRoute: () => Route$53
|
|
7231
7915
|
});
|
|
7232
|
-
var IndexRoute = Route$
|
|
7916
|
+
var IndexRoute = Route$54.update({
|
|
7233
7917
|
id: "/",
|
|
7234
7918
|
path: "/",
|
|
7235
|
-
getParentRoute: () => Route$
|
|
7919
|
+
getParentRoute: () => Route$53
|
|
7236
7920
|
});
|
|
7237
|
-
var ApiThinkingRoute = Route$
|
|
7921
|
+
var ApiThinkingRoute = Route$51.update({
|
|
7238
7922
|
id: "/api/thinking",
|
|
7239
7923
|
path: "/api/thinking",
|
|
7240
|
-
getParentRoute: () => Route$
|
|
7924
|
+
getParentRoute: () => Route$53
|
|
7241
7925
|
});
|
|
7242
|
-
var ApiSlashCommandRoute = Route$
|
|
7926
|
+
var ApiSlashCommandRoute = Route$50.update({
|
|
7243
7927
|
id: "/api/slash-command",
|
|
7244
7928
|
path: "/api/slash-command",
|
|
7245
|
-
getParentRoute: () => Route$
|
|
7929
|
+
getParentRoute: () => Route$53
|
|
7246
7930
|
});
|
|
7247
|
-
var ApiProviderUsageRoute = Route$
|
|
7931
|
+
var ApiProviderUsageRoute = Route$49.update({
|
|
7248
7932
|
id: "/api/provider-usage",
|
|
7249
7933
|
path: "/api/provider-usage",
|
|
7250
|
-
getParentRoute: () => Route$
|
|
7934
|
+
getParentRoute: () => Route$53
|
|
7251
7935
|
});
|
|
7252
|
-
var ApiPromptRoute = Route$
|
|
7936
|
+
var ApiPromptRoute = Route$48.update({
|
|
7253
7937
|
id: "/api/prompt",
|
|
7254
7938
|
path: "/api/prompt",
|
|
7255
|
-
getParentRoute: () => Route$
|
|
7939
|
+
getParentRoute: () => Route$53
|
|
7256
7940
|
});
|
|
7257
|
-
var ApiPathCompletionsRoute = Route$
|
|
7941
|
+
var ApiPathCompletionsRoute = Route$47.update({
|
|
7258
7942
|
id: "/api/path-completions",
|
|
7259
7943
|
path: "/api/path-completions",
|
|
7260
|
-
getParentRoute: () => Route$
|
|
7944
|
+
getParentRoute: () => Route$53
|
|
7261
7945
|
});
|
|
7262
|
-
var ApiModelRoute = Route$
|
|
7946
|
+
var ApiModelRoute = Route$46.update({
|
|
7263
7947
|
id: "/api/model",
|
|
7264
7948
|
path: "/api/model",
|
|
7265
|
-
getParentRoute: () => Route$
|
|
7949
|
+
getParentRoute: () => Route$53
|
|
7266
7950
|
});
|
|
7267
|
-
var ApiHighlightRoute = Route$
|
|
7951
|
+
var ApiHighlightRoute = Route$45.update({
|
|
7268
7952
|
id: "/api/highlight",
|
|
7269
7953
|
path: "/api/highlight",
|
|
7270
|
-
getParentRoute: () => Route$
|
|
7954
|
+
getParentRoute: () => Route$53
|
|
7271
7955
|
});
|
|
7272
|
-
var ApiGitStatusRoute = Route$
|
|
7956
|
+
var ApiGitStatusRoute = Route$44.update({
|
|
7273
7957
|
id: "/api/git-status",
|
|
7274
7958
|
path: "/api/git-status",
|
|
7275
|
-
getParentRoute: () => Route$
|
|
7959
|
+
getParentRoute: () => Route$53
|
|
7276
7960
|
});
|
|
7277
|
-
var ApiGitStageRoute = Route$
|
|
7961
|
+
var ApiGitStageRoute = Route$43.update({
|
|
7278
7962
|
id: "/api/git-stage",
|
|
7279
7963
|
path: "/api/git-stage",
|
|
7280
|
-
getParentRoute: () => Route$
|
|
7964
|
+
getParentRoute: () => Route$53
|
|
7281
7965
|
});
|
|
7282
|
-
var ApiGitReviewRoute = Route$
|
|
7966
|
+
var ApiGitReviewRoute = Route$42.update({
|
|
7283
7967
|
id: "/api/git-review",
|
|
7284
7968
|
path: "/api/git-review",
|
|
7285
|
-
getParentRoute: () => Route$
|
|
7969
|
+
getParentRoute: () => Route$53
|
|
7286
7970
|
});
|
|
7287
|
-
var ApiGitPushRoute = Route$
|
|
7971
|
+
var ApiGitPushRoute = Route$41.update({
|
|
7288
7972
|
id: "/api/git-push",
|
|
7289
7973
|
path: "/api/git-push",
|
|
7290
|
-
getParentRoute: () => Route$
|
|
7974
|
+
getParentRoute: () => Route$53
|
|
7291
7975
|
});
|
|
7292
|
-
var ApiGitPullRoute = Route$
|
|
7976
|
+
var ApiGitPullRoute = Route$40.update({
|
|
7293
7977
|
id: "/api/git-pull",
|
|
7294
7978
|
path: "/api/git-pull",
|
|
7295
|
-
getParentRoute: () => Route$
|
|
7979
|
+
getParentRoute: () => Route$53
|
|
7296
7980
|
});
|
|
7297
|
-
var ApiGitDiscardRoute = Route$
|
|
7981
|
+
var ApiGitDiscardRoute = Route$39.update({
|
|
7298
7982
|
id: "/api/git-discard",
|
|
7299
7983
|
path: "/api/git-discard",
|
|
7300
|
-
getParentRoute: () => Route$
|
|
7984
|
+
getParentRoute: () => Route$53
|
|
7301
7985
|
});
|
|
7302
|
-
var ApiGitDiffRoute = Route$
|
|
7986
|
+
var ApiGitDiffRoute = Route$38.update({
|
|
7303
7987
|
id: "/api/git-diff",
|
|
7304
7988
|
path: "/api/git-diff",
|
|
7305
|
-
getParentRoute: () => Route$
|
|
7989
|
+
getParentRoute: () => Route$53
|
|
7306
7990
|
});
|
|
7307
|
-
var
|
|
7991
|
+
var ApiGitCommitRemoteUrlRoute = Route$37.update({
|
|
7992
|
+
id: "/api/git-commit-remote-url",
|
|
7993
|
+
path: "/api/git-commit-remote-url",
|
|
7994
|
+
getParentRoute: () => Route$53
|
|
7995
|
+
});
|
|
7996
|
+
var ApiGitCommitMessageRoute = Route$36.update({
|
|
7308
7997
|
id: "/api/git-commit-message",
|
|
7309
7998
|
path: "/api/git-commit-message",
|
|
7310
|
-
getParentRoute: () => Route$
|
|
7999
|
+
getParentRoute: () => Route$53
|
|
8000
|
+
});
|
|
8001
|
+
var ApiGitCommitFilesRoute = Route$35.update({
|
|
8002
|
+
id: "/api/git-commit-files",
|
|
8003
|
+
path: "/api/git-commit-files",
|
|
8004
|
+
getParentRoute: () => Route$53
|
|
8005
|
+
});
|
|
8006
|
+
var ApiGitCommitDiffRoute = Route$34.update({
|
|
8007
|
+
id: "/api/git-commit-diff",
|
|
8008
|
+
path: "/api/git-commit-diff",
|
|
8009
|
+
getParentRoute: () => Route$53
|
|
7311
8010
|
});
|
|
7312
|
-
var
|
|
8011
|
+
var ApiGitCommitActionRoute = Route$33.update({
|
|
8012
|
+
id: "/api/git-commit-action",
|
|
8013
|
+
path: "/api/git-commit-action",
|
|
8014
|
+
getParentRoute: () => Route$53
|
|
8015
|
+
});
|
|
8016
|
+
var ApiGitCommitRoute = Route$32.update({
|
|
7313
8017
|
id: "/api/git-commit",
|
|
7314
8018
|
path: "/api/git-commit",
|
|
7315
|
-
getParentRoute: () => Route$
|
|
8019
|
+
getParentRoute: () => Route$53
|
|
7316
8020
|
});
|
|
7317
|
-
var ApiGitCheckoutRoute = Route$
|
|
8021
|
+
var ApiGitCheckoutRoute = Route$31.update({
|
|
7318
8022
|
id: "/api/git-checkout",
|
|
7319
8023
|
path: "/api/git-checkout",
|
|
7320
|
-
getParentRoute: () => Route$
|
|
8024
|
+
getParentRoute: () => Route$53
|
|
7321
8025
|
});
|
|
7322
|
-
var ApiGitChangesRoute = Route$
|
|
8026
|
+
var ApiGitChangesRoute = Route$30.update({
|
|
7323
8027
|
id: "/api/git-changes",
|
|
7324
8028
|
path: "/api/git-changes",
|
|
7325
|
-
getParentRoute: () => Route$
|
|
8029
|
+
getParentRoute: () => Route$53
|
|
7326
8030
|
});
|
|
7327
|
-
var ApiFileCompletionsRoute = Route$
|
|
8031
|
+
var ApiFileCompletionsRoute = Route$29.update({
|
|
7328
8032
|
id: "/api/file-completions",
|
|
7329
8033
|
path: "/api/file-completions",
|
|
7330
|
-
getParentRoute: () => Route$
|
|
8034
|
+
getParentRoute: () => Route$53
|
|
7331
8035
|
});
|
|
7332
|
-
var ApiDirectorySessionsIndexesRoute = Route$
|
|
8036
|
+
var ApiDirectorySessionsIndexesRoute = Route$28.update({
|
|
7333
8037
|
id: "/api/directory-sessions-indexes",
|
|
7334
8038
|
path: "/api/directory-sessions-indexes",
|
|
7335
|
-
getParentRoute: () => Route$
|
|
8039
|
+
getParentRoute: () => Route$53
|
|
7336
8040
|
});
|
|
7337
|
-
var ApiDirectorySessionsIndexRoute = Route$
|
|
8041
|
+
var ApiDirectorySessionsIndexRoute = Route$27.update({
|
|
7338
8042
|
id: "/api/directory-sessions-index",
|
|
7339
8043
|
path: "/api/directory-sessions-index",
|
|
7340
|
-
getParentRoute: () => Route$
|
|
8044
|
+
getParentRoute: () => Route$53
|
|
7341
8045
|
});
|
|
7342
|
-
var ApiDirectorySessionsRoute = Route$
|
|
8046
|
+
var ApiDirectorySessionsRoute = Route$26.update({
|
|
7343
8047
|
id: "/api/directory-sessions",
|
|
7344
8048
|
path: "/api/directory-sessions",
|
|
7345
|
-
getParentRoute: () => Route$
|
|
8049
|
+
getParentRoute: () => Route$53
|
|
7346
8050
|
});
|
|
7347
|
-
var ApiDirectorySearchRoute = Route$
|
|
8051
|
+
var ApiDirectorySearchRoute = Route$25.update({
|
|
7348
8052
|
id: "/api/directory-search",
|
|
7349
8053
|
path: "/api/directory-search",
|
|
7350
|
-
getParentRoute: () => Route$
|
|
8054
|
+
getParentRoute: () => Route$53
|
|
7351
8055
|
});
|
|
7352
|
-
var ApiAbortRoute = Route$
|
|
8056
|
+
var ApiAbortRoute = Route$24.update({
|
|
7353
8057
|
id: "/api/abort",
|
|
7354
8058
|
path: "/api/abort",
|
|
7355
|
-
getParentRoute: () => Route$
|
|
8059
|
+
getParentRoute: () => Route$53
|
|
7356
8060
|
});
|
|
7357
|
-
var ApiUiIdRoute = Route$
|
|
8061
|
+
var ApiUiIdRoute = Route$23.update({
|
|
7358
8062
|
id: "/api/ui/$id",
|
|
7359
8063
|
path: "/api/ui/$id",
|
|
7360
|
-
getParentRoute: () => Route$
|
|
8064
|
+
getParentRoute: () => Route$53
|
|
7361
8065
|
});
|
|
7362
|
-
var ApiSettingsHideThinkingRoute = Route$
|
|
8066
|
+
var ApiSettingsHideThinkingRoute = Route$22.update({
|
|
7363
8067
|
id: "/api/settings/hide-thinking",
|
|
7364
8068
|
path: "/api/settings/hide-thinking",
|
|
7365
|
-
getParentRoute: () => Route$
|
|
8069
|
+
getParentRoute: () => Route$53
|
|
7366
8070
|
});
|
|
7367
|
-
var ApiSessionsDeleteRoute = Route$
|
|
8071
|
+
var ApiSessionsDeleteRoute = Route$21.update({
|
|
7368
8072
|
id: "/api/sessions/delete",
|
|
7369
8073
|
path: "/api/sessions/delete",
|
|
7370
|
-
getParentRoute: () => Route$
|
|
8074
|
+
getParentRoute: () => Route$53
|
|
7371
8075
|
});
|
|
7372
|
-
var ApiSessionTreeRoute = Route$
|
|
8076
|
+
var ApiSessionTreeRoute = Route$20.update({
|
|
7373
8077
|
id: "/api/session/tree",
|
|
7374
8078
|
path: "/api/session/tree",
|
|
7375
|
-
getParentRoute: () => Route$
|
|
8079
|
+
getParentRoute: () => Route$53
|
|
7376
8080
|
});
|
|
7377
|
-
var ApiSessionSelectRoute = Route$
|
|
8081
|
+
var ApiSessionSelectRoute = Route$19.update({
|
|
7378
8082
|
id: "/api/session/select",
|
|
7379
8083
|
path: "/api/session/select",
|
|
7380
|
-
getParentRoute: () => Route$
|
|
8084
|
+
getParentRoute: () => Route$53
|
|
7381
8085
|
});
|
|
7382
|
-
var ApiSessionRenameRoute = Route$
|
|
8086
|
+
var ApiSessionRenameRoute = Route$18.update({
|
|
7383
8087
|
id: "/api/session/rename",
|
|
7384
8088
|
path: "/api/session/rename",
|
|
7385
|
-
getParentRoute: () => Route$
|
|
8089
|
+
getParentRoute: () => Route$53
|
|
8090
|
+
});
|
|
8091
|
+
var ApiSessionReadStateRoute = Route$17.update({
|
|
8092
|
+
id: "/api/session/read-state",
|
|
8093
|
+
path: "/api/session/read-state",
|
|
8094
|
+
getParentRoute: () => Route$53
|
|
7386
8095
|
});
|
|
7387
8096
|
var ApiSessionNewRoute = Route$16.update({
|
|
7388
8097
|
id: "/api/session/new",
|
|
7389
8098
|
path: "/api/session/new",
|
|
7390
|
-
getParentRoute: () => Route$
|
|
8099
|
+
getParentRoute: () => Route$53
|
|
7391
8100
|
});
|
|
7392
8101
|
var ApiSessionMoveRoute = Route$15.update({
|
|
7393
8102
|
id: "/api/session/move",
|
|
7394
8103
|
path: "/api/session/move",
|
|
7395
|
-
getParentRoute: () => Route$
|
|
8104
|
+
getParentRoute: () => Route$53
|
|
7396
8105
|
});
|
|
7397
8106
|
var ApiSessionHistoryRoute = Route$14.update({
|
|
7398
8107
|
id: "/api/session/history",
|
|
7399
8108
|
path: "/api/session/history",
|
|
7400
|
-
getParentRoute: () => Route$
|
|
8109
|
+
getParentRoute: () => Route$53
|
|
7401
8110
|
});
|
|
7402
8111
|
var ApiSessionForkRoute = Route$13.update({
|
|
7403
8112
|
id: "/api/session/fork",
|
|
7404
8113
|
path: "/api/session/fork",
|
|
7405
|
-
getParentRoute: () => Route$
|
|
8114
|
+
getParentRoute: () => Route$53
|
|
7406
8115
|
});
|
|
7407
8116
|
var ApiSessionDeleteRoute = Route$12.update({
|
|
7408
8117
|
id: "/api/session/delete",
|
|
7409
8118
|
path: "/api/session/delete",
|
|
7410
|
-
getParentRoute: () => Route$
|
|
8119
|
+
getParentRoute: () => Route$53
|
|
7411
8120
|
});
|
|
7412
8121
|
var ApiSessionCloneRoute = Route$11.update({
|
|
7413
8122
|
id: "/api/session/clone",
|
|
7414
8123
|
path: "/api/session/clone",
|
|
7415
|
-
getParentRoute: () => Route$
|
|
8124
|
+
getParentRoute: () => Route$53
|
|
7416
8125
|
});
|
|
7417
8126
|
var ApiPendingMessagesReorderRoute = Route$10.update({
|
|
7418
8127
|
id: "/api/pending-messages/reorder",
|
|
7419
8128
|
path: "/api/pending-messages/reorder",
|
|
7420
|
-
getParentRoute: () => Route$
|
|
8129
|
+
getParentRoute: () => Route$53
|
|
7421
8130
|
});
|
|
7422
8131
|
var ApiPendingMessageRemoveRoute = Route$9.update({
|
|
7423
8132
|
id: "/api/pending-message/remove",
|
|
7424
8133
|
path: "/api/pending-message/remove",
|
|
7425
|
-
getParentRoute: () => Route$
|
|
8134
|
+
getParentRoute: () => Route$53
|
|
7426
8135
|
});
|
|
7427
8136
|
var ApiFilesTreeRoute = Route$8.update({
|
|
7428
8137
|
id: "/api/files/tree",
|
|
7429
8138
|
path: "/api/files/tree",
|
|
7430
|
-
getParentRoute: () => Route$
|
|
8139
|
+
getParentRoute: () => Route$53
|
|
7431
8140
|
});
|
|
7432
8141
|
var ApiFilesReadRoute = Route$7.update({
|
|
7433
8142
|
id: "/api/files/read",
|
|
7434
8143
|
path: "/api/files/read",
|
|
7435
|
-
getParentRoute: () => Route$
|
|
8144
|
+
getParentRoute: () => Route$53
|
|
7436
8145
|
});
|
|
7437
8146
|
var ApiDirectoryResolveRoute = Route$6.update({
|
|
7438
8147
|
id: "/api/directory/resolve",
|
|
7439
8148
|
path: "/api/directory/resolve",
|
|
7440
|
-
getParentRoute: () => Route$
|
|
8149
|
+
getParentRoute: () => Route$53
|
|
7441
8150
|
});
|
|
7442
8151
|
var ApiDirectorySessionsCleanupRoute = Route$5.update({
|
|
7443
8152
|
id: "/cleanup",
|
|
@@ -7447,22 +8156,22 @@ var ApiDirectorySessionsCleanupRoute = Route$5.update({
|
|
|
7447
8156
|
var ApiAuthProvidersRoute = Route$4.update({
|
|
7448
8157
|
id: "/api/auth/providers",
|
|
7449
8158
|
path: "/api/auth/providers",
|
|
7450
|
-
getParentRoute: () => Route$
|
|
8159
|
+
getParentRoute: () => Route$53
|
|
7451
8160
|
});
|
|
7452
8161
|
var ApiAuthOauthRoute = Route$3.update({
|
|
7453
8162
|
id: "/api/auth/oauth",
|
|
7454
8163
|
path: "/api/auth/oauth",
|
|
7455
|
-
getParentRoute: () => Route$
|
|
8164
|
+
getParentRoute: () => Route$53
|
|
7456
8165
|
});
|
|
7457
8166
|
var ApiAuthLogoutRoute = Route$2.update({
|
|
7458
8167
|
id: "/api/auth/logout",
|
|
7459
8168
|
path: "/api/auth/logout",
|
|
7460
|
-
getParentRoute: () => Route$
|
|
8169
|
+
getParentRoute: () => Route$53
|
|
7461
8170
|
});
|
|
7462
8171
|
var ApiAuthApiKeyRoute = Route$1.update({
|
|
7463
8172
|
id: "/api/auth/api-key",
|
|
7464
8173
|
path: "/api/auth/api-key",
|
|
7465
|
-
getParentRoute: () => Route$
|
|
8174
|
+
getParentRoute: () => Route$53
|
|
7466
8175
|
});
|
|
7467
8176
|
var ApiSessionTreeLabelRoute = Route.update({
|
|
7468
8177
|
id: "/label",
|
|
@@ -7484,7 +8193,11 @@ var rootRouteChildren = {
|
|
|
7484
8193
|
ApiGitChangesRoute,
|
|
7485
8194
|
ApiGitCheckoutRoute,
|
|
7486
8195
|
ApiGitCommitRoute,
|
|
8196
|
+
ApiGitCommitActionRoute,
|
|
8197
|
+
ApiGitCommitDiffRoute,
|
|
8198
|
+
ApiGitCommitFilesRoute,
|
|
7487
8199
|
ApiGitCommitMessageRoute,
|
|
8200
|
+
ApiGitCommitRemoteUrlRoute,
|
|
7488
8201
|
ApiGitDiffRoute,
|
|
7489
8202
|
ApiGitDiscardRoute,
|
|
7490
8203
|
ApiGitPullRoute,
|
|
@@ -7514,6 +8227,7 @@ var rootRouteChildren = {
|
|
|
7514
8227
|
ApiSessionHistoryRoute,
|
|
7515
8228
|
ApiSessionMoveRoute,
|
|
7516
8229
|
ApiSessionNewRoute,
|
|
8230
|
+
ApiSessionReadStateRoute,
|
|
7517
8231
|
ApiSessionRenameRoute,
|
|
7518
8232
|
ApiSessionSelectRoute,
|
|
7519
8233
|
ApiSessionTreeRoute: ApiSessionTreeRoute._addFileChildren(ApiSessionTreeRouteChildren),
|
|
@@ -7521,7 +8235,7 @@ var rootRouteChildren = {
|
|
|
7521
8235
|
ApiSettingsHideThinkingRoute,
|
|
7522
8236
|
ApiUiIdRoute
|
|
7523
8237
|
};
|
|
7524
|
-
var routeTree = Route$
|
|
8238
|
+
var routeTree = Route$53._addFileChildren(rootRouteChildren)._addFileTypes();
|
|
7525
8239
|
function getRouter() {
|
|
7526
8240
|
const queryClient = new QueryClient({ defaultOptions: { queries: {
|
|
7527
8241
|
retry: 1,
|