@alivault/pico 0.9.0 → 0.10.0
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-Cv9CWbsI.js} +9 -9
- package/.output/public/assets/routes-FmISceu0.js +2160 -0
- package/.output/public/assets/styles-DgbW000h.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 +36 -5
- 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 +78 -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-BfWi4RfZ.mjs} +976 -374
- package/.output/server/_ssr/{routes-7x8dHcec.mjs → routes-CSvcOSyF.mjs} +5535 -2345
- package/.output/server/_ssr/{routes-bPw2DezY.mjs → routes-D6yf6dMU.mjs} +46 -32
- package/.output/server/_ssr/ssr.mjs +3 -3
- package/.output/server/{_tanstack-start-manifest_v-CMhyz9t-.mjs → _tanstack-start-manifest_v-Am6Tm4xr.mjs} +9 -4
- package/.output/server/index.mjs +533 -533
- 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 { F 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, V as extractMessageText$1, n as APPLIED_THEME_STORAGE_KEY, t as APPLIED_THEME_CLASSES, v as Route$54, xt as toolCategoryFromTool } from "./routes-D6yf6dMU.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-BfWi4RfZ.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-DgbW000h.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` };
|
|
@@ -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;
|
|
@@ -1209,12 +1222,12 @@ function extractMessageText(message) {
|
|
|
1209
1222
|
const content = message.content;
|
|
1210
1223
|
if (typeof content === "string") return content.trim();
|
|
1211
1224
|
if (!Array.isArray(content)) return "";
|
|
1212
|
-
return content.
|
|
1225
|
+
return content.flatMap((part) => part?.type === "text" && typeof part.text === "string" ? [part.text] : []).join(" ").trim();
|
|
1213
1226
|
}
|
|
1214
1227
|
function extractSessionContentText(content) {
|
|
1215
1228
|
if (typeof content === "string") return content.trim();
|
|
1216
1229
|
if (!Array.isArray(content)) return "";
|
|
1217
|
-
const text = content.
|
|
1230
|
+
const text = content.flatMap((part) => part && typeof part === "object" && part.type === "text" && typeof part.text === "string" ? [part.text] : []).join(" ").trim();
|
|
1218
1231
|
if (text) return text;
|
|
1219
1232
|
const imageCount = content.filter((part) => part && typeof part === "object" && (part.type === "image" || part.type === "input_image")).length;
|
|
1220
1233
|
if (imageCount > 0) return `${imageCount} image${imageCount === 1 ? "" : "s"}`;
|
|
@@ -1318,15 +1331,22 @@ function serializeSessionTreeNode(node) {
|
|
|
1318
1331
|
if (entry.type === "custom") serialized.entry.customType = typeof entry.customType === "string" ? entry.customType : "custom";
|
|
1319
1332
|
if (entry.type === "label") serialized.entry.label = typeof entry.label === "string" ? entry.label : void 0;
|
|
1320
1333
|
if (entry.type === "session_info") serialized.entry.name = typeof entry.name === "string" ? entry.name : "";
|
|
1321
|
-
serialized.children = (Array.isArray(node.children) ? node.children : []).
|
|
1334
|
+
serialized.children = (Array.isArray(node.children) ? node.children : []).flatMap((child) => {
|
|
1335
|
+
const treeNode = serializeSessionTreeNode(child);
|
|
1336
|
+
return treeNode ? [treeNode] : [];
|
|
1337
|
+
});
|
|
1322
1338
|
return serialized;
|
|
1323
1339
|
}
|
|
1324
1340
|
function extractForkableUserMessages(entry) {
|
|
1325
1341
|
const messages = entry.session.getUserMessagesForForking?.();
|
|
1326
|
-
if (Array.isArray(messages) && messages.length > 0) return messages.
|
|
1327
|
-
entryId
|
|
1328
|
-
text
|
|
1329
|
-
|
|
1342
|
+
if (Array.isArray(messages) && messages.length > 0) return messages.flatMap((message) => {
|
|
1343
|
+
const entryId = typeof message.entryId === "string" ? message.entryId.trim() : "";
|
|
1344
|
+
const text = typeof message.text === "string" ? message.text.trim() : "";
|
|
1345
|
+
return entryId && text ? [{
|
|
1346
|
+
entryId,
|
|
1347
|
+
text
|
|
1348
|
+
}] : [];
|
|
1349
|
+
});
|
|
1330
1350
|
const stack = [...entry.session.sessionManager.getTree?.() ?? []];
|
|
1331
1351
|
const results = [];
|
|
1332
1352
|
while (stack.length > 0) {
|
|
@@ -1351,7 +1371,7 @@ async function createForkedInMemorySessionManager(options) {
|
|
|
1351
1371
|
if (!leafId) return nextManager;
|
|
1352
1372
|
const branchEntries = sourceManager.getBranch?.(leafId);
|
|
1353
1373
|
if (!Array.isArray(branchEntries) || branchEntries.length === 0) throw new Error(`Entry ${leafId} not found`);
|
|
1354
|
-
const pathWithoutLabels = branchEntries.
|
|
1374
|
+
const pathWithoutLabels = branchEntries.flatMap((branchEntry) => branchEntry?.type !== "label" ? [cloneSessionData(branchEntry)] : []);
|
|
1355
1375
|
const header = cloneSessionData(sourceManager.getHeader?.() ?? nextManager.fileEntries?.[0]);
|
|
1356
1376
|
if (!header) throw new Error("Failed to initialize forked in-memory session.");
|
|
1357
1377
|
nextManager.fileEntries = [header, ...pathWithoutLabels];
|
|
@@ -1471,6 +1491,9 @@ async function createPicoEditToolDefinition(sdk, cwd) {
|
|
|
1471
1491
|
}
|
|
1472
1492
|
};
|
|
1473
1493
|
}
|
|
1494
|
+
function gitTextContains(text, query) {
|
|
1495
|
+
return text.indexOf(query) >= 0;
|
|
1496
|
+
}
|
|
1474
1497
|
var GIT_STATUS_CACHE_TTL_MS = 5e3;
|
|
1475
1498
|
var GIT_CHANGES_CACHE_TTL_MS = 5e3;
|
|
1476
1499
|
var GIT_COMMITS_DEFAULT_LIMIT = 50;
|
|
@@ -1655,7 +1678,10 @@ function parseCommandNullList(output) {
|
|
|
1655
1678
|
return output.split("\0").filter((entry) => typeof entry === "string" && entry.length > 0);
|
|
1656
1679
|
}
|
|
1657
1680
|
function parseCommandLines(output, { trim = false } = {}) {
|
|
1658
|
-
return output.split(/\r?\n/).
|
|
1681
|
+
return output.split(/\r?\n/).flatMap((entry) => {
|
|
1682
|
+
const line = trim ? entry.trim() : entry;
|
|
1683
|
+
return trim ? line ? [line] : [] : line.length ? [line] : [];
|
|
1684
|
+
});
|
|
1659
1685
|
}
|
|
1660
1686
|
function isGitCommitGraphLine(line) {
|
|
1661
1687
|
const tabIndex = line.indexOf(" ");
|
|
@@ -1711,7 +1737,10 @@ function enrichGitCommitGraphLinesWithStats(lines, statsByHash) {
|
|
|
1711
1737
|
});
|
|
1712
1738
|
}
|
|
1713
1739
|
function gitCommandErrorMessage(fallback, result) {
|
|
1714
|
-
const details = [result.stderr, result.stdout].
|
|
1740
|
+
const details = [result.stderr, result.stdout].flatMap((value) => {
|
|
1741
|
+
const detail = value.trim();
|
|
1742
|
+
return detail ? [detail] : [];
|
|
1743
|
+
}).join("\n");
|
|
1715
1744
|
if (result.timedOut) return `${fallback}: command timed out`;
|
|
1716
1745
|
if (details) return `${fallback}: ${details}`;
|
|
1717
1746
|
return fallback;
|
|
@@ -1743,7 +1772,10 @@ function deriveHeuristicCommitMessage(files) {
|
|
|
1743
1772
|
}
|
|
1744
1773
|
if (addedCount > modifiedCount && addedCount >= deletedCount) return `Add ${files.length} files`;
|
|
1745
1774
|
if (deletedCount > modifiedCount && deletedCount >= addedCount) return `Remove ${files.length} files`;
|
|
1746
|
-
const commonDirectory = files.
|
|
1775
|
+
const commonDirectory = files.flatMap((file) => {
|
|
1776
|
+
const directory = file.path.split("/").slice(0, -1).join("/");
|
|
1777
|
+
return directory ? [directory] : [];
|
|
1778
|
+
}).reduce((common, directory) => {
|
|
1747
1779
|
if (common === void 0) return directory;
|
|
1748
1780
|
return common === directory ? common : "";
|
|
1749
1781
|
}, void 0);
|
|
@@ -1771,12 +1803,31 @@ function parseGitStatusEntries(output) {
|
|
|
1771
1803
|
}
|
|
1772
1804
|
return files;
|
|
1773
1805
|
}
|
|
1806
|
+
function parseGitNameStatusEntries(output) {
|
|
1807
|
+
const entries = parseCommandNullList(output);
|
|
1808
|
+
const files = [];
|
|
1809
|
+
for (let index = 0; index < entries.length; index += 1) {
|
|
1810
|
+
const status = entries[index];
|
|
1811
|
+
if (typeof status !== "string" || !status) continue;
|
|
1812
|
+
const isRenamedOrCopied = status.startsWith("R") || status.startsWith("C");
|
|
1813
|
+
const previousPath = isRenamedOrCopied ? entries[index + 1] : void 0;
|
|
1814
|
+
const filePath = isRenamedOrCopied ? entries[index + 2] : entries[index + 1];
|
|
1815
|
+
index += isRenamedOrCopied ? 2 : 1;
|
|
1816
|
+
if (typeof filePath !== "string" || !filePath) continue;
|
|
1817
|
+
files.push({
|
|
1818
|
+
status: /^[RC]\d+/.test(status) ? status.slice(0, 1) : status,
|
|
1819
|
+
path: filePath,
|
|
1820
|
+
...typeof previousPath === "string" && previousPath ? { previousPath } : {}
|
|
1821
|
+
});
|
|
1822
|
+
}
|
|
1823
|
+
return files;
|
|
1824
|
+
}
|
|
1774
1825
|
function parseGitNumstatEntries(output) {
|
|
1775
1826
|
const entries = parseCommandNullList(output);
|
|
1776
1827
|
const diffs = /* @__PURE__ */ new Map();
|
|
1777
1828
|
for (let index = 0; index < entries.length; index += 1) {
|
|
1778
1829
|
const entry = entries[index];
|
|
1779
|
-
if (typeof entry !== "string" || !entry
|
|
1830
|
+
if (typeof entry !== "string" || !gitTextContains(entry, " ")) continue;
|
|
1780
1831
|
const [addedRaw = "", deletedRaw = "", ...pathParts] = entry.split(" ");
|
|
1781
1832
|
let filePath = pathParts.join(" ");
|
|
1782
1833
|
let previousPath;
|
|
@@ -1797,7 +1848,10 @@ function parseGitNumstatEntries(output) {
|
|
|
1797
1848
|
return diffs;
|
|
1798
1849
|
}
|
|
1799
1850
|
function parseGitRefRows(output) {
|
|
1800
|
-
return parseCommandLines(output).
|
|
1851
|
+
return parseCommandLines(output).flatMap((line) => {
|
|
1852
|
+
const fields = line.split("\0");
|
|
1853
|
+
return fields.some((field) => typeof field === "string" && field.length > 0) ? [fields] : [];
|
|
1854
|
+
});
|
|
1801
1855
|
}
|
|
1802
1856
|
function parseGitBranchTrack(track, upstream) {
|
|
1803
1857
|
const trackValue = typeof track === "string" ? track.trim() : "";
|
|
@@ -1852,12 +1906,28 @@ function assertGitFilePath(path) {
|
|
|
1852
1906
|
if (normalizedPath.split(/[\\/]+/).some((part) => part === "..")) throw new Error("file path must stay inside the repository");
|
|
1853
1907
|
return normalizedPath.replaceAll("\\", "/");
|
|
1854
1908
|
}
|
|
1909
|
+
function assertGitCommitHash(commit) {
|
|
1910
|
+
const normalizedCommit = typeof commit === "string" ? commit.trim() : "";
|
|
1911
|
+
if (!normalizedCommit) throw new Error("commit is required");
|
|
1912
|
+
if (!/^[0-9a-f]{5,40}$/i.test(normalizedCommit)) throw new Error("commit must be a valid hash");
|
|
1913
|
+
return normalizedCommit;
|
|
1914
|
+
}
|
|
1915
|
+
function assertGitTagName(tagName) {
|
|
1916
|
+
const normalizedTagName = typeof tagName === "string" ? tagName.trim() : "";
|
|
1917
|
+
if (!normalizedTagName) throw new Error("tag name is required");
|
|
1918
|
+
if (normalizedTagName.startsWith("-") || /\s/.test(normalizedTagName)) throw new Error("Invalid tag name");
|
|
1919
|
+
return normalizedTagName;
|
|
1920
|
+
}
|
|
1921
|
+
function normalizeGitResetMode(mode) {
|
|
1922
|
+
if (mode === "soft" || mode === "mixed" || mode === "hard") return mode;
|
|
1923
|
+
throw new Error("reset mode must be soft, mixed, or hard");
|
|
1924
|
+
}
|
|
1855
1925
|
function parseGitRemoteBranches(output) {
|
|
1856
1926
|
const branches = [];
|
|
1857
1927
|
for (const fields of parseGitRefRows(output)) {
|
|
1858
1928
|
const [name = "", hash = "", subject = "", relativeDate = "", committerDate = ""] = fields;
|
|
1859
1929
|
const branchName = typeof name === "string" ? name.trim() : "";
|
|
1860
|
-
if (!branchName || !branchName
|
|
1930
|
+
if (!branchName || !gitTextContains(branchName, "/") || /\/HEAD$/i.test(branchName)) continue;
|
|
1861
1931
|
branches.push({
|
|
1862
1932
|
name: branchName,
|
|
1863
1933
|
hash: typeof hash === "string" && hash.trim() ? hash.trim() : void 0,
|
|
@@ -2086,11 +2156,12 @@ async function readDirectoryGitFileReview(cwd, path, previousPath) {
|
|
|
2086
2156
|
const normalizedPreviousPath = previousPath ? assertGitFilePath(previousPath) : void 0;
|
|
2087
2157
|
if (!normalizedCwd) return null;
|
|
2088
2158
|
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2159
|
+
const [oldContent, newContent] = await Promise.all([readGitHeadFileContent(normalizedCwd, normalizedPreviousPath || normalizedPath), readWorktreeFileContent(normalizedCwd, normalizedPath)]);
|
|
2089
2160
|
return {
|
|
2090
2161
|
path: normalizedPath,
|
|
2091
2162
|
previousPath: normalizedPreviousPath,
|
|
2092
|
-
oldContent
|
|
2093
|
-
newContent
|
|
2163
|
+
oldContent,
|
|
2164
|
+
newContent
|
|
2094
2165
|
};
|
|
2095
2166
|
}
|
|
2096
2167
|
async function readDirectoryGitFileDiff(cwd, path) {
|
|
@@ -2409,14 +2480,20 @@ async function readUnpushedCommitMessages(cwd) {
|
|
|
2409
2480
|
});
|
|
2410
2481
|
return result.code === 0 ? parseCommandLines(result.stdout, { trim: true }).filter(Boolean) : [];
|
|
2411
2482
|
}
|
|
2483
|
+
async function runGitPushCommand(cwd, context) {
|
|
2484
|
+
return await runCommand("git", context.force ? ["push", "--force-with-lease"] : ["push"], {
|
|
2485
|
+
cwd,
|
|
2486
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2487
|
+
});
|
|
2488
|
+
}
|
|
2412
2489
|
async function pushDirectoryGitChanges(cwd, { force = false } = {}) {
|
|
2413
2490
|
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2414
2491
|
if (!normalizedCwd) throw new Error("cwd is required");
|
|
2415
2492
|
if (!await isInsideWorkTree(normalizedCwd)) throw new Error("No git repository detected");
|
|
2416
2493
|
const pushedCommitMessages = await readUnpushedCommitMessages(normalizedCwd);
|
|
2417
|
-
const result = await
|
|
2418
|
-
|
|
2419
|
-
|
|
2494
|
+
const result = await runGitPushCommand(normalizedCwd, {
|
|
2495
|
+
force,
|
|
2496
|
+
pushedCommitMessages
|
|
2420
2497
|
});
|
|
2421
2498
|
if (result.code !== 0) throw new Error(gitCommandErrorMessage(force ? "Failed to force push changes" : "Failed to push changes", result));
|
|
2422
2499
|
invalidateDirectoryGitCaches(normalizedCwd);
|
|
@@ -2467,6 +2544,294 @@ async function checkoutDirectoryGitBranch(cwd, branch, options = {}) {
|
|
|
2467
2544
|
stderr: result.stderr
|
|
2468
2545
|
};
|
|
2469
2546
|
}
|
|
2547
|
+
function gitCommitActionLabel(action) {
|
|
2548
|
+
switch (action) {
|
|
2549
|
+
case "checkout": return "checkout commit";
|
|
2550
|
+
case "cherry-pick": return "cherry-pick commit";
|
|
2551
|
+
case "revert": return "revert commit";
|
|
2552
|
+
case "tag": return "tag commit";
|
|
2553
|
+
case "reset": return "reset branch";
|
|
2554
|
+
case "rebase": return "rebase branch";
|
|
2555
|
+
case "drop": return "drop commit";
|
|
2556
|
+
case "squash": return "squash commits";
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
function remoteBaseUrlFromGitUrl(remoteUrl) {
|
|
2560
|
+
const trimmed = remoteUrl.trim();
|
|
2561
|
+
if (!trimmed) return "";
|
|
2562
|
+
const scpLikeMatch = trimmed.match(/^git@([^:]+):(.+)$/);
|
|
2563
|
+
if (scpLikeMatch) {
|
|
2564
|
+
const host = scpLikeMatch[1];
|
|
2565
|
+
const path = scpLikeMatch[2]?.replace(/\.git$/i, "");
|
|
2566
|
+
return host && path ? `https://${host}/${path}` : "";
|
|
2567
|
+
}
|
|
2568
|
+
try {
|
|
2569
|
+
const url = new URL(trimmed);
|
|
2570
|
+
if (url.protocol === "ssh:" && url.username === "git") return `https://${url.host}${url.pathname.replace(/\.git$/i, "")}`;
|
|
2571
|
+
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
2572
|
+
url.username = "";
|
|
2573
|
+
url.password = "";
|
|
2574
|
+
url.pathname = url.pathname.replace(/\.git$/i, "");
|
|
2575
|
+
url.search = "";
|
|
2576
|
+
url.hash = "";
|
|
2577
|
+
return url.toString().replace(/\/$/, "");
|
|
2578
|
+
}
|
|
2579
|
+
} catch {}
|
|
2580
|
+
return "";
|
|
2581
|
+
}
|
|
2582
|
+
function commitUrlPathForHost(host, commit) {
|
|
2583
|
+
return host.toLowerCase().includes("gitlab") ? `/-/commit/${commit}` : `/commit/${commit}`;
|
|
2584
|
+
}
|
|
2585
|
+
async function readPrimaryRemoteName(cwd) {
|
|
2586
|
+
const branchResult = await runCommand("git", [
|
|
2587
|
+
"symbolic-ref",
|
|
2588
|
+
"--quiet",
|
|
2589
|
+
"--short",
|
|
2590
|
+
"HEAD"
|
|
2591
|
+
], {
|
|
2592
|
+
cwd,
|
|
2593
|
+
timeoutMs: 1500
|
|
2594
|
+
});
|
|
2595
|
+
const branch = branchResult.code === 0 ? branchResult.stdout.trim() : "";
|
|
2596
|
+
if (branch) {
|
|
2597
|
+
const branchRemoteResult = await runCommand("git", [
|
|
2598
|
+
"config",
|
|
2599
|
+
"--get",
|
|
2600
|
+
`branch.${branch}.remote`
|
|
2601
|
+
], {
|
|
2602
|
+
cwd,
|
|
2603
|
+
timeoutMs: 1500
|
|
2604
|
+
});
|
|
2605
|
+
const branchRemote = branchRemoteResult.stdout.trim();
|
|
2606
|
+
if (branchRemoteResult.code === 0 && branchRemote) return branchRemote;
|
|
2607
|
+
}
|
|
2608
|
+
const pushDefaultResult = await runCommand("git", [
|
|
2609
|
+
"config",
|
|
2610
|
+
"--get",
|
|
2611
|
+
"remote.pushDefault"
|
|
2612
|
+
], {
|
|
2613
|
+
cwd,
|
|
2614
|
+
timeoutMs: 1500
|
|
2615
|
+
});
|
|
2616
|
+
const pushDefault = pushDefaultResult.stdout.trim();
|
|
2617
|
+
if (pushDefaultResult.code === 0 && pushDefault) return pushDefault;
|
|
2618
|
+
return "origin";
|
|
2619
|
+
}
|
|
2620
|
+
async function readDirectoryGitCommitFiles(cwd, commit) {
|
|
2621
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2622
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2623
|
+
if (!normalizedCwd) return null;
|
|
2624
|
+
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2625
|
+
const [statusResult, numstatResult] = await Promise.all([runCommand("git", [
|
|
2626
|
+
"show",
|
|
2627
|
+
"--name-status",
|
|
2628
|
+
"-z",
|
|
2629
|
+
"--find-renames=50%",
|
|
2630
|
+
"--format=",
|
|
2631
|
+
normalizedCommit
|
|
2632
|
+
], {
|
|
2633
|
+
cwd: normalizedCwd,
|
|
2634
|
+
timeoutMs: 1e4
|
|
2635
|
+
}), runCommand("git", [
|
|
2636
|
+
"show",
|
|
2637
|
+
"--numstat",
|
|
2638
|
+
"-z",
|
|
2639
|
+
"--find-renames=50%",
|
|
2640
|
+
"--format=",
|
|
2641
|
+
normalizedCommit
|
|
2642
|
+
], {
|
|
2643
|
+
cwd: normalizedCwd,
|
|
2644
|
+
timeoutMs: 1e4
|
|
2645
|
+
})]);
|
|
2646
|
+
if (statusResult.code !== 0) throw new Error(gitCommandErrorMessage("Failed to read commit files", statusResult));
|
|
2647
|
+
if (numstatResult.code !== 0) throw new Error(gitCommandErrorMessage("Failed to read commit file stats", numstatResult));
|
|
2648
|
+
const stats = parseGitNumstatEntries(numstatResult.stdout);
|
|
2649
|
+
return parseGitNameStatusEntries(statusResult.stdout).map((file) => ({
|
|
2650
|
+
...file,
|
|
2651
|
+
...stats.get(file.path)
|
|
2652
|
+
}));
|
|
2653
|
+
}
|
|
2654
|
+
async function readDirectoryGitCommitDiff(cwd, commit, mode = "commit", path, previousPath) {
|
|
2655
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2656
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2657
|
+
const normalizedPath = path ? assertGitFilePath(path) : void 0;
|
|
2658
|
+
const normalizedPreviousPath = previousPath ? assertGitFilePath(previousPath) : void 0;
|
|
2659
|
+
if (!normalizedCwd) return null;
|
|
2660
|
+
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2661
|
+
const pathArgs = normalizedPath ? ["--", ...uniqueGitActionPaths([normalizedPreviousPath, normalizedPath])] : [];
|
|
2662
|
+
const result = await runCommand("git", mode === "head" ? [
|
|
2663
|
+
"diff",
|
|
2664
|
+
"--patch",
|
|
2665
|
+
"--no-color",
|
|
2666
|
+
"--no-ext-diff",
|
|
2667
|
+
"--find-renames=50%",
|
|
2668
|
+
`${normalizedCommit}..HEAD`,
|
|
2669
|
+
...pathArgs
|
|
2670
|
+
] : mode === "previous" ? [
|
|
2671
|
+
"diff",
|
|
2672
|
+
"--patch",
|
|
2673
|
+
"--no-color",
|
|
2674
|
+
"--no-ext-diff",
|
|
2675
|
+
"--find-renames=50%",
|
|
2676
|
+
`${normalizedCommit}^`,
|
|
2677
|
+
normalizedCommit,
|
|
2678
|
+
...pathArgs
|
|
2679
|
+
] : [
|
|
2680
|
+
"show",
|
|
2681
|
+
"--patch",
|
|
2682
|
+
"--no-color",
|
|
2683
|
+
"--no-ext-diff",
|
|
2684
|
+
"--find-renames=50%",
|
|
2685
|
+
"--format=",
|
|
2686
|
+
normalizedCommit,
|
|
2687
|
+
...pathArgs
|
|
2688
|
+
], {
|
|
2689
|
+
cwd: normalizedCwd,
|
|
2690
|
+
timeoutMs: 3e4
|
|
2691
|
+
});
|
|
2692
|
+
if (result.code !== 0) throw new Error(gitCommandErrorMessage("Failed to read commit diff", result));
|
|
2693
|
+
const title = mode === "head" ? `${normalizedCommit.slice(0, 7)}..HEAD` : mode === "previous" ? `${normalizedCommit.slice(0, 7)}^..${normalizedCommit.slice(0, 7)}` : normalizedCommit.slice(0, 7);
|
|
2694
|
+
return {
|
|
2695
|
+
commit: normalizedCommit,
|
|
2696
|
+
mode,
|
|
2697
|
+
title: normalizedPath ? `${title}:${normalizedPath}` : title,
|
|
2698
|
+
...normalizedPath ? { path: normalizedPath } : {},
|
|
2699
|
+
...normalizedPreviousPath ? { previousPath: normalizedPreviousPath } : {},
|
|
2700
|
+
patch: result.stdout.trim()
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
async function readDirectoryGitCommitRemoteUrl(cwd, commit) {
|
|
2704
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2705
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2706
|
+
if (!normalizedCwd) return null;
|
|
2707
|
+
if (!await isInsideWorkTree(normalizedCwd)) return null;
|
|
2708
|
+
const remoteResult = await runCommand("git", [
|
|
2709
|
+
"remote",
|
|
2710
|
+
"get-url",
|
|
2711
|
+
await readPrimaryRemoteName(normalizedCwd)
|
|
2712
|
+
], {
|
|
2713
|
+
cwd: normalizedCwd,
|
|
2714
|
+
timeoutMs: 1500
|
|
2715
|
+
});
|
|
2716
|
+
if (remoteResult.code !== 0 || !remoteResult.stdout.trim()) throw new Error("No remote URL found");
|
|
2717
|
+
const baseUrl = remoteBaseUrlFromGitUrl(remoteResult.stdout);
|
|
2718
|
+
if (!baseUrl) throw new Error("Remote URL cannot be opened in the browser");
|
|
2719
|
+
return {
|
|
2720
|
+
commit: normalizedCommit,
|
|
2721
|
+
remoteUrl: `${baseUrl}${commitUrlPathForHost(new URL(baseUrl).host, normalizedCommit)}`
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
async function runDirectoryGitCommitAction(cwd, action, commit, options = {}) {
|
|
2725
|
+
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2726
|
+
const normalizedCommit = assertGitCommitHash(commit);
|
|
2727
|
+
if (!normalizedCwd) throw new Error("cwd is required");
|
|
2728
|
+
if (!await isInsideWorkTree(normalizedCwd)) throw new Error("No git repository detected");
|
|
2729
|
+
let result;
|
|
2730
|
+
switch (action) {
|
|
2731
|
+
case "checkout":
|
|
2732
|
+
result = await runCommand("git", [
|
|
2733
|
+
"switch",
|
|
2734
|
+
"--detach",
|
|
2735
|
+
normalizedCommit
|
|
2736
|
+
], {
|
|
2737
|
+
cwd: normalizedCwd,
|
|
2738
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2739
|
+
});
|
|
2740
|
+
break;
|
|
2741
|
+
case "cherry-pick":
|
|
2742
|
+
result = await runCommand("git", ["cherry-pick", normalizedCommit], {
|
|
2743
|
+
cwd: normalizedCwd,
|
|
2744
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2745
|
+
});
|
|
2746
|
+
break;
|
|
2747
|
+
case "revert":
|
|
2748
|
+
result = await runCommand("git", [
|
|
2749
|
+
"revert",
|
|
2750
|
+
"--no-edit",
|
|
2751
|
+
normalizedCommit
|
|
2752
|
+
], {
|
|
2753
|
+
cwd: normalizedCwd,
|
|
2754
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2755
|
+
});
|
|
2756
|
+
break;
|
|
2757
|
+
case "tag":
|
|
2758
|
+
result = await runCommand("git", [
|
|
2759
|
+
"tag",
|
|
2760
|
+
assertGitTagName(options.tagName || ""),
|
|
2761
|
+
normalizedCommit
|
|
2762
|
+
], {
|
|
2763
|
+
cwd: normalizedCwd,
|
|
2764
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2765
|
+
});
|
|
2766
|
+
break;
|
|
2767
|
+
case "reset":
|
|
2768
|
+
result = await runCommand("git", [
|
|
2769
|
+
"reset",
|
|
2770
|
+
`--${normalizeGitResetMode(options.resetMode)}`,
|
|
2771
|
+
normalizedCommit
|
|
2772
|
+
], {
|
|
2773
|
+
cwd: normalizedCwd,
|
|
2774
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2775
|
+
});
|
|
2776
|
+
break;
|
|
2777
|
+
case "rebase":
|
|
2778
|
+
result = await runCommand("git", ["rebase", normalizedCommit], {
|
|
2779
|
+
cwd: normalizedCwd,
|
|
2780
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2781
|
+
});
|
|
2782
|
+
break;
|
|
2783
|
+
case "drop":
|
|
2784
|
+
result = await runCommand("git", [
|
|
2785
|
+
"rebase",
|
|
2786
|
+
"--onto",
|
|
2787
|
+
`${normalizedCommit}^`,
|
|
2788
|
+
normalizedCommit,
|
|
2789
|
+
"HEAD"
|
|
2790
|
+
], {
|
|
2791
|
+
cwd: normalizedCwd,
|
|
2792
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2793
|
+
});
|
|
2794
|
+
break;
|
|
2795
|
+
case "squash": {
|
|
2796
|
+
const message = cleanupCommitMessageCandidate(options.message || "");
|
|
2797
|
+
if (!message) throw new Error("commit message is required");
|
|
2798
|
+
const resetResult = await runCommand("git", [
|
|
2799
|
+
"reset",
|
|
2800
|
+
"--soft",
|
|
2801
|
+
normalizedCommit
|
|
2802
|
+
], {
|
|
2803
|
+
cwd: normalizedCwd,
|
|
2804
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2805
|
+
});
|
|
2806
|
+
if (resetResult.code !== 0) throw new Error(gitCommandErrorMessage("Failed to squash commits", resetResult));
|
|
2807
|
+
if ((await runCommand("git", [
|
|
2808
|
+
"diff",
|
|
2809
|
+
"--cached",
|
|
2810
|
+
"--quiet"
|
|
2811
|
+
], {
|
|
2812
|
+
cwd: normalizedCwd,
|
|
2813
|
+
timeoutMs: 5e3
|
|
2814
|
+
})).code === 0) throw new Error("No commits after this commit to squash");
|
|
2815
|
+
result = await runCommand("git", [
|
|
2816
|
+
"commit",
|
|
2817
|
+
"-m",
|
|
2818
|
+
message
|
|
2819
|
+
], {
|
|
2820
|
+
cwd: normalizedCwd,
|
|
2821
|
+
timeoutMs: GIT_ACTION_TIMEOUT_MS
|
|
2822
|
+
});
|
|
2823
|
+
result.stdout = [resetResult.stdout, result.stdout].filter(Boolean).join("\n");
|
|
2824
|
+
result.stderr = [resetResult.stderr, result.stderr].filter(Boolean).join("\n");
|
|
2825
|
+
break;
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
if (result.code !== 0) throw new Error(gitCommandErrorMessage(`Failed to ${gitCommitActionLabel(action)}`, result));
|
|
2829
|
+
invalidateDirectoryGitCaches(normalizedCwd);
|
|
2830
|
+
return {
|
|
2831
|
+
stdout: result.stdout,
|
|
2832
|
+
stderr: result.stderr
|
|
2833
|
+
};
|
|
2834
|
+
}
|
|
2470
2835
|
async function generateDirectoryGitCommitMessage(cwd, modelRegistry) {
|
|
2471
2836
|
const normalizedCwd = normalizeGitCwd(cwd);
|
|
2472
2837
|
if (!normalizedCwd) throw new Error("cwd is required");
|
|
@@ -2544,7 +2909,7 @@ async function generateDirectoryGitCommitMessage(cwd, modelRegistry) {
|
|
|
2544
2909
|
headers: auth.headers,
|
|
2545
2910
|
reasoningEffort: "low"
|
|
2546
2911
|
});
|
|
2547
|
-
const message = cleanupCommitMessageCandidate(Array.isArray(response?.content) ? response.content.
|
|
2912
|
+
const message = cleanupCommitMessageCandidate(Array.isArray(response?.content) ? response.content.flatMap((block) => block?.type === "text" && typeof block.text === "string" ? [block.text] : []).join("\n") : "");
|
|
2548
2913
|
if (message) return {
|
|
2549
2914
|
message,
|
|
2550
2915
|
source: "ai"
|
|
@@ -2710,10 +3075,11 @@ var GitWatchManager = class {
|
|
|
2710
3075
|
}
|
|
2711
3076
|
async resolveDirectory(state) {
|
|
2712
3077
|
const generation = state.generation;
|
|
3078
|
+
if (this.directories.get(state.cwd) !== state) return;
|
|
2713
3079
|
const repository = await resolveDirectoryGitRepository(state.cwd).catch(() => null);
|
|
3080
|
+
if (!repository) return;
|
|
2714
3081
|
if (this.directories.get(state.cwd) !== state) return;
|
|
2715
3082
|
if (state.generation !== generation) return;
|
|
2716
|
-
if (!repository) return;
|
|
2717
3083
|
const repoKey = repositoryWatchKey(repository);
|
|
2718
3084
|
state.repoKey = repoKey;
|
|
2719
3085
|
(this.repositories.get(repoKey) ?? this.createRepositoryWatch(repoKey, repository)).subscribers.add(state.cwd);
|
|
@@ -3067,6 +3433,7 @@ function getApiKeyProviderDisplayName(providerId) {
|
|
|
3067
3433
|
return API_KEY_LOGIN_PROVIDER_NAMES[providerId] ?? providerId;
|
|
3068
3434
|
}
|
|
3069
3435
|
var STATE_SYNC_SCALAR_FIELDS = [
|
|
3436
|
+
"activationRevision",
|
|
3070
3437
|
"sessionKey",
|
|
3071
3438
|
"draft",
|
|
3072
3439
|
"streaming",
|
|
@@ -3144,7 +3511,10 @@ function sanitizeMessageContentPart(part) {
|
|
|
3144
3511
|
function sanitizeSessionMessage(message) {
|
|
3145
3512
|
const role = typeof message?.role === "string" ? message.role : "";
|
|
3146
3513
|
const metadata = message?.metadata && typeof message.metadata === "object" ? message.metadata : void 0;
|
|
3147
|
-
const sanitizedContent = Array.isArray(message?.content) ? message.content.
|
|
3514
|
+
const sanitizedContent = Array.isArray(message?.content) ? message.content.flatMap((part) => {
|
|
3515
|
+
const sanitizedPart = sanitizeMessageContentPart(part);
|
|
3516
|
+
return sanitizedPart ? [sanitizedPart] : [];
|
|
3517
|
+
}) : typeof message?.content === "string" ? message.content : void 0;
|
|
3148
3518
|
return {
|
|
3149
3519
|
...role ? { role } : {},
|
|
3150
3520
|
...sanitizedContent !== void 0 ? { content: sanitizedContent } : {},
|
|
@@ -3216,10 +3586,11 @@ function createStateSyncPatch(previous, next) {
|
|
|
3216
3586
|
let changed = false;
|
|
3217
3587
|
const patch = {
|
|
3218
3588
|
type: "state_sync",
|
|
3589
|
+
activationRevision: next.activationRevision,
|
|
3219
3590
|
sessionKey: next.sessionKey
|
|
3220
3591
|
};
|
|
3221
3592
|
for (const field of STATE_SYNC_SCALAR_FIELDS) {
|
|
3222
|
-
if (field === "sessionKey") continue;
|
|
3593
|
+
if (field === "activationRevision" || field === "sessionKey") continue;
|
|
3223
3594
|
const nextValue = next[field];
|
|
3224
3595
|
if (Object.is(previous.scalarValues[field], nextValue)) continue;
|
|
3225
3596
|
patch[field] = nextValue;
|
|
@@ -3254,17 +3625,17 @@ function createInitialUiState() {
|
|
|
3254
3625
|
}
|
|
3255
3626
|
function normalizePromptImages(rawImages) {
|
|
3256
3627
|
if (!Array.isArray(rawImages)) return [];
|
|
3257
|
-
return rawImages.
|
|
3258
|
-
if (!image || typeof image !== "object") return
|
|
3628
|
+
return rawImages.flatMap((image) => {
|
|
3629
|
+
if (!image || typeof image !== "object") return [];
|
|
3259
3630
|
const mimeType = typeof image.mimeType === "string" ? image.mimeType.trim() : "";
|
|
3260
3631
|
const data = typeof image.data === "string" ? image.data.trim() : "";
|
|
3261
|
-
if (!mimeType || !/^image\//i.test(mimeType) || !data) return
|
|
3262
|
-
return {
|
|
3632
|
+
if (!mimeType || !/^image\//i.test(mimeType) || !data) return [];
|
|
3633
|
+
return [{
|
|
3263
3634
|
type: "image",
|
|
3264
3635
|
mimeType,
|
|
3265
3636
|
data
|
|
3266
|
-
};
|
|
3267
|
-
}).
|
|
3637
|
+
}];
|
|
3638
|
+
}).slice(0, 8);
|
|
3268
3639
|
}
|
|
3269
3640
|
function serializeModel(model) {
|
|
3270
3641
|
if (!model) return void 0;
|
|
@@ -3471,7 +3842,10 @@ var PicoRuntime = class {
|
|
|
3471
3842
|
});
|
|
3472
3843
|
}
|
|
3473
3844
|
listAvailableModels(entry) {
|
|
3474
|
-
return entry.services.modelRegistry.getAvailable().
|
|
3845
|
+
return entry.services.modelRegistry.getAvailable().flatMap((model) => {
|
|
3846
|
+
const serializedModel = serializeModel(model);
|
|
3847
|
+
return serializedModel ? [serializedModel] : [];
|
|
3848
|
+
}).sort((left, right) => {
|
|
3475
3849
|
const providerCompare = (left.provider || "").localeCompare(right.provider || "");
|
|
3476
3850
|
if (providerCompare !== 0) return providerCompare;
|
|
3477
3851
|
return (left.name || left.id).localeCompare(right.name || right.id);
|
|
@@ -3491,6 +3865,7 @@ var PicoRuntime = class {
|
|
|
3491
3865
|
const next = {
|
|
3492
3866
|
id,
|
|
3493
3867
|
clients: /* @__PURE__ */ new Set(),
|
|
3868
|
+
activeRevision: 0,
|
|
3494
3869
|
activeKey: void 0,
|
|
3495
3870
|
draftKey: void 0,
|
|
3496
3871
|
sessionScope: process.cwd(),
|
|
@@ -3524,13 +3899,13 @@ var PicoRuntime = class {
|
|
|
3524
3899
|
return false;
|
|
3525
3900
|
}
|
|
3526
3901
|
async disposeUnreferencedSessionEntries() {
|
|
3527
|
-
const candidates = [...this.sessionEntries.values()]
|
|
3528
|
-
|
|
3529
|
-
if (this.
|
|
3530
|
-
if (this.
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3902
|
+
const candidates = [...this.sessionEntries.values()].filter((entry) => {
|
|
3903
|
+
if (this.sessionEntries.get(entry.key) !== entry) return false;
|
|
3904
|
+
if (this.isSessionEntryReferenced(entry)) return false;
|
|
3905
|
+
if (this.isSessionBusyForDone(entry)) return false;
|
|
3906
|
+
return true;
|
|
3907
|
+
});
|
|
3908
|
+
await Promise.all(candidates.map((entry) => this.disposeSessionEntry(entry)));
|
|
3534
3909
|
}
|
|
3535
3910
|
async cleanupInactiveContexts() {
|
|
3536
3911
|
for (const context of this.contexts.values()) {
|
|
@@ -3579,11 +3954,12 @@ var PicoRuntime = class {
|
|
|
3579
3954
|
}
|
|
3580
3955
|
return lastValue;
|
|
3581
3956
|
}
|
|
3582
|
-
currentStatePayload(entry) {
|
|
3957
|
+
currentStatePayload(entry, context) {
|
|
3583
3958
|
const draft = this.isDraftEntry(entry);
|
|
3584
3959
|
const historyTotalCount = entry.session.messages.length;
|
|
3585
3960
|
return {
|
|
3586
3961
|
type: "state_sync",
|
|
3962
|
+
activationRevision: context.activeRevision,
|
|
3587
3963
|
sessionKey: entry.key,
|
|
3588
3964
|
items: entry.retainedConversationItems,
|
|
3589
3965
|
pendingUserMessages: entry.pendingUserMessages.map((message) => clonePendingUserMessage(message)),
|
|
@@ -3708,12 +4084,12 @@ var PicoRuntime = class {
|
|
|
3708
4084
|
});
|
|
3709
4085
|
}
|
|
3710
4086
|
async listEntriesForDirectory(allSessions, directoryPath) {
|
|
3711
|
-
const sessions = allSessions.
|
|
3712
|
-
const byPath = new Map(sessions.
|
|
3713
|
-
const byId = new Map(sessions.
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
4087
|
+
const sessions = allSessions.flatMap((entry) => entry.cwd === directoryPath ? [{ ...entry }] : []);
|
|
4088
|
+
const byPath = new Map(sessions.flatMap((entry) => entry.path ? [[entry.path, entry]] : []));
|
|
4089
|
+
const byId = new Map(sessions.flatMap((entry) => entry.id ? [[entry.id, entry]] : []));
|
|
4090
|
+
const fallbackEntries = [...this.sessionEntries.values()].filter((entry) => entry.cwd === directoryPath && this.hasVisibleSessionContent(entry));
|
|
4091
|
+
const fallbacks = await Promise.all(fallbackEntries.map((entry) => this.sessionFallbackInfo(entry)));
|
|
4092
|
+
for (const fallback of fallbacks) {
|
|
3717
4093
|
const existing = (fallback.path ? byPath.get(fallback.path) : void 0) || (fallback.id ? byId.get(fallback.id) : void 0);
|
|
3718
4094
|
if (existing) {
|
|
3719
4095
|
this.mergeSessionListEntry(existing, fallback);
|
|
@@ -3726,7 +4102,7 @@ var PicoRuntime = class {
|
|
|
3726
4102
|
return sessions.sort((left, right) => this.compareSessionListEntriesByLastUserMessage(left, right));
|
|
3727
4103
|
}
|
|
3728
4104
|
buildStreamingPaths() {
|
|
3729
|
-
return new Set([...this.sessionEntries.values()].
|
|
4105
|
+
return new Set([...this.sessionEntries.values()].flatMap((entry) => this.getEntryStreamingState(entry) ? [this.getSessionPath(entry)] : []));
|
|
3730
4106
|
}
|
|
3731
4107
|
async collectDirectoryEntries(allSessions, directories) {
|
|
3732
4108
|
const entriesByDirectory = /* @__PURE__ */ new Map();
|
|
@@ -3928,7 +4304,7 @@ var PicoRuntime = class {
|
|
|
3928
4304
|
if (!entry) return;
|
|
3929
4305
|
const startedAt = performance.now();
|
|
3930
4306
|
const payloadStartedAt = performance.now();
|
|
3931
|
-
const payload = this.currentStatePayload(entry);
|
|
4307
|
+
const payload = this.currentStatePayload(entry, context);
|
|
3932
4308
|
const payloadDurationMs = roundedDurationMs(payloadStartedAt);
|
|
3933
4309
|
let sentCount = 0;
|
|
3934
4310
|
for (const client of context.clients) if (this.sendStatePayloadToClient(context, client, payload, options)) sentCount += 1;
|
|
@@ -3986,6 +4362,14 @@ var PicoRuntime = class {
|
|
|
3986
4362
|
}
|
|
3987
4363
|
await Promise.all(connectedContexts.map((context) => this.sendSessionsToContext(context)));
|
|
3988
4364
|
}
|
|
4365
|
+
async activateContextsSessionAndBroadcast(contexts, entry) {
|
|
4366
|
+
await Promise.all(contexts.map((context) => this.activateContextSession(context, entry)));
|
|
4367
|
+
await this.broadcastSessionsAll();
|
|
4368
|
+
}
|
|
4369
|
+
async bindSessionEntryAndBroadcast(entry) {
|
|
4370
|
+
await this.bindSessionEntry(entry);
|
|
4371
|
+
await Promise.all([this.broadcastEntryState(entry), this.broadcastSessionsAll()]);
|
|
4372
|
+
}
|
|
3989
4373
|
syncGitWatchDirectories() {
|
|
3990
4374
|
const cwds = /* @__PURE__ */ new Set();
|
|
3991
4375
|
for (const context of this.contexts.values()) {
|
|
@@ -4157,6 +4541,7 @@ var PicoRuntime = class {
|
|
|
4157
4541
|
async activateContextSession(context, entry, options) {
|
|
4158
4542
|
const previousActiveKey = context.activeKey;
|
|
4159
4543
|
const startedAt = performance.now();
|
|
4544
|
+
context.activeRevision += 1;
|
|
4160
4545
|
await activateContextSession({
|
|
4161
4546
|
context,
|
|
4162
4547
|
entry,
|
|
@@ -4185,6 +4570,7 @@ var PicoRuntime = class {
|
|
|
4185
4570
|
this.syncGitWatchDirectories();
|
|
4186
4571
|
this.logSessionLoadDebug("context_session:activate", {
|
|
4187
4572
|
contextId: context.id,
|
|
4573
|
+
activeRevision: context.activeRevision,
|
|
4188
4574
|
previousActiveKey,
|
|
4189
4575
|
notify: options?.notify !== false,
|
|
4190
4576
|
statusDurationMs,
|
|
@@ -4609,25 +4995,26 @@ var PicoRuntime = class {
|
|
|
4609
4995
|
}
|
|
4610
4996
|
pendingMessagesFromClientUpdate(entry, pendingMessagesUpdate) {
|
|
4611
4997
|
const pendingMessages = entry.pendingUserMessages.map((message) => clonePendingUserMessage(message));
|
|
4612
|
-
const normalizedUpdates = Array.isArray(pendingMessagesUpdate) ? pendingMessagesUpdate.
|
|
4998
|
+
const normalizedUpdates = Array.isArray(pendingMessagesUpdate) ? pendingMessagesUpdate.flatMap((message) => {
|
|
4999
|
+
const pendingId = typeof message?.pendingId === "string" ? message.pendingId : "";
|
|
5000
|
+
if (!pendingId) return [];
|
|
4613
5001
|
const hasImages = hasOwnProperty(message, "images");
|
|
4614
5002
|
const hasText = hasOwnProperty(message, "text");
|
|
4615
|
-
return {
|
|
4616
|
-
pendingId
|
|
5003
|
+
return [{
|
|
5004
|
+
pendingId,
|
|
4617
5005
|
hasImages,
|
|
4618
5006
|
hasText,
|
|
4619
5007
|
images: hasImages ? normalizePromptImages(message?.images) : [],
|
|
4620
5008
|
streamingBehavior: normalizePendingStreamingBehavior(message?.streamingBehavior),
|
|
4621
5009
|
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.");
|
|
5010
|
+
}];
|
|
5011
|
+
}) : [];
|
|
4625
5012
|
const pendingMessagesById = new Map(pendingMessages.map((message) => [message.pendingId, message]));
|
|
4626
5013
|
if (pendingMessagesById.size !== pendingMessages.length) throw new Error("Pending prompt order is out of date. Refresh and try again.");
|
|
4627
5014
|
const nextPendingMessages = [];
|
|
4628
5015
|
for (const update of normalizedUpdates) {
|
|
4629
5016
|
const existing = pendingMessagesById.get(update.pendingId);
|
|
4630
|
-
if (!existing)
|
|
5017
|
+
if (!existing) continue;
|
|
4631
5018
|
const text = update.hasText ? update.text : existing.text;
|
|
4632
5019
|
const images = update.hasImages ? update.images : existing.images;
|
|
4633
5020
|
if (!text.trim() && images.length === 0) throw new Error("Pending prompt text or image is required.");
|
|
@@ -4642,23 +5029,30 @@ var PicoRuntime = class {
|
|
|
4642
5029
|
if (pendingMessagesById.size > 0) throw new Error("pendingMessages must include every pending prompt exactly once.");
|
|
4643
5030
|
return sortPendingUserMessages(nextPendingMessages);
|
|
4644
5031
|
}
|
|
5032
|
+
async replayPendingUserMessages(entry, pendingMessages, index = 0) {
|
|
5033
|
+
const pendingMessage = pendingMessages[index];
|
|
5034
|
+
if (!pendingMessage) return;
|
|
5035
|
+
const text = pendingMessage.text;
|
|
5036
|
+
const images = normalizePromptImages(pendingMessage.images);
|
|
5037
|
+
if (text.trim() || images.length > 0) await entry.session.prompt(text, {
|
|
5038
|
+
...images.length > 0 ? { images } : {},
|
|
5039
|
+
streamingBehavior: pendingMessage.streamingBehavior
|
|
5040
|
+
});
|
|
5041
|
+
await this.replayPendingUserMessages(entry, pendingMessages, index + 1);
|
|
5042
|
+
}
|
|
4645
5043
|
async replacePendingUserMessages(entry, pendingMessages) {
|
|
4646
5044
|
const nextPending = sortPendingUserMessages(pendingMessages);
|
|
4647
5045
|
const canReplayPending = Boolean(entry.session.isStreaming);
|
|
4648
|
-
if (!canReplayPending
|
|
5046
|
+
if (!canReplayPending) {
|
|
5047
|
+
entry.pendingUserMessages = nextPending;
|
|
5048
|
+
await this.broadcastEntryState(entry);
|
|
5049
|
+
return entry.pendingUserMessages;
|
|
5050
|
+
}
|
|
4649
5051
|
entry.pendingQueueMutation = true;
|
|
4650
5052
|
try {
|
|
4651
5053
|
entry.session.clearQueue();
|
|
4652
5054
|
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
|
-
}
|
|
5055
|
+
if (canReplayPending) await this.replayPendingUserMessages(entry, nextPending);
|
|
4662
5056
|
entry.pendingUserMessages = nextPending;
|
|
4663
5057
|
this.reconcilePendingUserMessages(entry);
|
|
4664
5058
|
} finally {
|
|
@@ -4779,11 +5173,9 @@ var PicoRuntime = class {
|
|
|
4779
5173
|
sessionId: void 0,
|
|
4780
5174
|
sessionFile: void 0
|
|
4781
5175
|
};
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
}
|
|
4786
|
-
await this.broadcastSessionsAll();
|
|
5176
|
+
const activeViewers = viewers();
|
|
5177
|
+
for (const context of activeViewers) context.draftKey = result.entry.key;
|
|
5178
|
+
await this.activateContextsSessionAndBroadcast(activeViewers, result.entry);
|
|
4787
5179
|
return {
|
|
4788
5180
|
sessionId: void 0,
|
|
4789
5181
|
sessionFile: void 0
|
|
@@ -4793,8 +5185,7 @@ var PicoRuntime = class {
|
|
|
4793
5185
|
const branchedPath = session.sessionManager.createBranchedSession?.(branchEntryId);
|
|
4794
5186
|
if (!branchedPath) return { cancelled: true };
|
|
4795
5187
|
const nextEntry = await this.ensureSessionEntryByPath(branchedPath);
|
|
4796
|
-
|
|
4797
|
-
await this.broadcastSessionsAll();
|
|
5188
|
+
await this.activateContextsSessionAndBroadcast(viewers(), nextEntry);
|
|
4798
5189
|
return {
|
|
4799
5190
|
sessionId: nextEntry.session.sessionId,
|
|
4800
5191
|
sessionFile: nextEntry.session.sessionFile
|
|
@@ -4825,8 +5216,7 @@ var PicoRuntime = class {
|
|
|
4825
5216
|
sessionId: entry.session.sessionId,
|
|
4826
5217
|
sessionFile: entry.session.sessionFile
|
|
4827
5218
|
};
|
|
4828
|
-
|
|
4829
|
-
await this.broadcastSessionsAll();
|
|
5219
|
+
await this.activateContextsSessionAndBroadcast(viewers(), nextEntry);
|
|
4830
5220
|
return {
|
|
4831
5221
|
sessionId: nextEntry.session.sessionId,
|
|
4832
5222
|
sessionFile: nextEntry.session.sessionFile
|
|
@@ -4834,9 +5224,7 @@ var PicoRuntime = class {
|
|
|
4834
5224
|
},
|
|
4835
5225
|
reload: async () => {
|
|
4836
5226
|
await session.reload?.();
|
|
4837
|
-
await this.
|
|
4838
|
-
await this.broadcastEntryState(entry);
|
|
4839
|
-
await this.broadcastSessionsAll();
|
|
5227
|
+
await this.bindSessionEntryAndBroadcast(entry);
|
|
4840
5228
|
}
|
|
4841
5229
|
},
|
|
4842
5230
|
shutdownHandler: () => {
|
|
@@ -4995,7 +5383,7 @@ var PicoRuntime = class {
|
|
|
4995
5383
|
const bootstrapStartedAt = performance.now();
|
|
4996
5384
|
try {
|
|
4997
5385
|
const stateStartedAt = performance.now();
|
|
4998
|
-
this.sendStatePayloadToClient(context, client, this.currentStatePayload(activeEntry), { forceFull: true });
|
|
5386
|
+
this.sendStatePayloadToClient(context, client, this.currentStatePayload(activeEntry, context), { forceFull: true });
|
|
4999
5387
|
this.logSessionLoadDebug("events_response:bootstrap_state", {
|
|
5000
5388
|
contextId: context.id,
|
|
5001
5389
|
clientId: client.id,
|
|
@@ -5162,7 +5550,6 @@ var PicoRuntime = class {
|
|
|
5162
5550
|
const pendingMessages = Array.isArray(body.pendingMessages) ? body.pendingMessages : Array.isArray(body.pendingIds) ? body.pendingIds.map((pendingId) => ({ pendingId })) : null;
|
|
5163
5551
|
if (!pendingMessages) throw new Error("pendingMessages must be an array");
|
|
5164
5552
|
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
5553
|
await this.replacePendingUserMessages(activeEntry, nextPendingMessages);
|
|
5167
5554
|
return {
|
|
5168
5555
|
ok: true,
|
|
@@ -5181,7 +5568,9 @@ var PicoRuntime = class {
|
|
|
5181
5568
|
const pendingMessages = activeEntry.pendingUserMessages.map((message) => clonePendingUserMessage(message));
|
|
5182
5569
|
const pendingIndex = pendingMessages.findIndex((message) => message.pendingId === pendingId);
|
|
5183
5570
|
if (pendingIndex === -1) {
|
|
5184
|
-
|
|
5571
|
+
const isKnownClientPendingId = Boolean(normalizeClientPendingId(pendingId));
|
|
5572
|
+
const isKnownServerPendingId = pendingId.startsWith("pending:");
|
|
5573
|
+
if (isKnownClientPendingId || isKnownServerPendingId) {
|
|
5185
5574
|
activeEntry.canceledPendingUserMessageIds.add(pendingId);
|
|
5186
5575
|
return {
|
|
5187
5576
|
ok: true,
|
|
@@ -5192,7 +5581,6 @@ var PicoRuntime = class {
|
|
|
5192
5581
|
}
|
|
5193
5582
|
activeEntry.canceledPendingUserMessageIds.delete(pendingId);
|
|
5194
5583
|
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
5584
|
await this.replacePendingUserMessages(activeEntry, pendingMessages);
|
|
5197
5585
|
return {
|
|
5198
5586
|
ok: true,
|
|
@@ -5332,7 +5720,10 @@ var PicoRuntime = class {
|
|
|
5332
5720
|
return {
|
|
5333
5721
|
leafId,
|
|
5334
5722
|
streamingEntryId,
|
|
5335
|
-
tree: (manager.getTree() || []).
|
|
5723
|
+
tree: (manager.getTree() || []).flatMap((node) => {
|
|
5724
|
+
const treeNode = serializeSessionTreeNode(node);
|
|
5725
|
+
return treeNode ? [markStreamingNode(treeNode)] : [];
|
|
5726
|
+
})
|
|
5336
5727
|
};
|
|
5337
5728
|
}
|
|
5338
5729
|
async getSessionTreeForRequest(request) {
|
|
@@ -5532,6 +5923,27 @@ var PicoRuntime = class {
|
|
|
5532
5923
|
name: nextName
|
|
5533
5924
|
};
|
|
5534
5925
|
}
|
|
5926
|
+
async setSessionReadState(request, body) {
|
|
5927
|
+
const { context } = await this.resolveRequest(request);
|
|
5928
|
+
const sessionPath = typeof body.path === "string" ? body.path.trim() : "";
|
|
5929
|
+
const unread = typeof body.unread === "boolean" ? body.unread : false;
|
|
5930
|
+
if (!sessionPath) throw new Error("path is required");
|
|
5931
|
+
if (unread) context.unreadFinished.add(sessionPath);
|
|
5932
|
+
else context.unreadFinished.delete(sessionPath);
|
|
5933
|
+
const loadedEntry = [...this.sessionEntries.values()].find((entry) => this.getSessionPath(entry) === sessionPath);
|
|
5934
|
+
if (loadedEntry) this.sendSessionStatusToContext(context, loadedEntry);
|
|
5935
|
+
else this.sendToContext(context, {
|
|
5936
|
+
type: "session_status",
|
|
5937
|
+
sessionPath,
|
|
5938
|
+
unread
|
|
5939
|
+
});
|
|
5940
|
+
await this.sendSessionsToContext(context);
|
|
5941
|
+
return {
|
|
5942
|
+
ok: true,
|
|
5943
|
+
path: sessionPath,
|
|
5944
|
+
unread
|
|
5945
|
+
};
|
|
5946
|
+
}
|
|
5535
5947
|
async writeMovedSessionFile(sessionPath, nextCwd, targetSessionDirectory) {
|
|
5536
5948
|
const sourcePath = resolve(sessionPath);
|
|
5537
5949
|
const targetPath = resolve(await uniqueSessionMovePath(sourcePath, targetSessionDirectory));
|
|
@@ -5563,20 +5975,23 @@ var PicoRuntime = class {
|
|
|
5563
5975
|
const previousPath = resolve(sessionPath);
|
|
5564
5976
|
const previousEntry = loadedEntries[0];
|
|
5565
5977
|
const previousCwd = previousEntry?.cwd || "";
|
|
5566
|
-
const affectedContexts = [...this.contexts.values()].
|
|
5567
|
-
context
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5978
|
+
const affectedContexts = [...this.contexts.values()].flatMap((context) => {
|
|
5979
|
+
const wasActive = loadedEntries.some((entry) => context.activeKey === entry.key);
|
|
5980
|
+
const wasDraft = loadedEntries.some((entry) => context.draftKey === entry.key);
|
|
5981
|
+
return wasActive || wasDraft ? [{
|
|
5982
|
+
context,
|
|
5983
|
+
wasActive,
|
|
5984
|
+
wasDraft
|
|
5985
|
+
}] : [];
|
|
5986
|
+
});
|
|
5571
5987
|
const nextPath = await this.writeMovedSessionFile(previousPath, nextCwd, targetSessionDirectory);
|
|
5572
|
-
|
|
5988
|
+
await Promise.all(loadedEntries.map((loadedEntry) => this.disposeSessionEntry(loadedEntry)));
|
|
5573
5989
|
let nextEntry;
|
|
5574
5990
|
if (affectedContexts.some((entry) => entry.wasActive)) {
|
|
5575
5991
|
nextEntry = await this.ensureSessionEntryByPath(nextPath);
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
}
|
|
5992
|
+
const activeNextEntry = nextEntry;
|
|
5993
|
+
for (const affected of affectedContexts) if (affected.wasDraft) affected.context.draftKey = void 0;
|
|
5994
|
+
await Promise.all(affectedContexts.flatMap((affected) => affected.wasActive ? [this.activateContextSession(affected.context, activeNextEntry, { refreshSessions: false })] : []));
|
|
5580
5995
|
} else for (const affected of affectedContexts) if (affected.wasDraft) affected.context.draftKey = void 0;
|
|
5581
5996
|
for (const context of this.contexts.values()) if (context.unreadFinished.delete(previousPath)) context.unreadFinished.add(nextPath);
|
|
5582
5997
|
this.invalidateSessionIndexCache();
|
|
@@ -5621,21 +6036,20 @@ var PicoRuntime = class {
|
|
|
5621
6036
|
const allSessions = await this.listSessionIndexEntries();
|
|
5622
6037
|
const directorySessions = await this.listEntriesForDirectory(allSessions, directory);
|
|
5623
6038
|
const streamingPaths = this.buildStreamingPaths();
|
|
5624
|
-
const activeKeys = new Set([...this.contexts.values()].
|
|
5625
|
-
const activePaths = new Set([...this.sessionEntries.values()].
|
|
6039
|
+
const activeKeys = new Set([...this.contexts.values()].flatMap((ctx) => ctx.activeKey ? [ctx.activeKey] : []));
|
|
6040
|
+
const activePaths = new Set([...this.sessionEntries.values()].flatMap((entry) => activeKeys.has(entry.key) ? [this.getSessionPath(entry)] : []));
|
|
5626
6041
|
const includeActiveSession = body.includeActiveSession === true;
|
|
5627
|
-
const matchingSessions = directorySessions.
|
|
6042
|
+
const matchingSessions = directorySessions.flatMap((entry) => {
|
|
5628
6043
|
const activityAt = normalizeModifiedTimestamp(entry.lastUserMessageAt) || normalizeModifiedTimestamp(entry.modified);
|
|
5629
|
-
|
|
6044
|
+
const serializedEntry = {
|
|
5630
6045
|
...this.serializeSessionListEntry(entry, context, streamingPaths),
|
|
5631
6046
|
activityAt
|
|
5632
6047
|
};
|
|
5633
|
-
|
|
5634
|
-
if (
|
|
5635
|
-
if (
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
return activityTime > 0 && activityTime < cutoffTime;
|
|
6048
|
+
if (!serializedEntry.path) return [];
|
|
6049
|
+
if (streamingPaths.has(serializedEntry.path)) return [];
|
|
6050
|
+
if (!includeActiveSession && activePaths.has(serializedEntry.path)) return [];
|
|
6051
|
+
const activityTime = modifiedTimestampValue(serializedEntry.activityAt);
|
|
6052
|
+
return activityTime > 0 && activityTime < cutoffTime ? [serializedEntry] : [];
|
|
5639
6053
|
});
|
|
5640
6054
|
if (body.dryRun !== false) return {
|
|
5641
6055
|
ok: true,
|
|
@@ -5645,10 +6059,10 @@ var PicoRuntime = class {
|
|
|
5645
6059
|
deletedSessionIds: [],
|
|
5646
6060
|
matchingSessions
|
|
5647
6061
|
};
|
|
5648
|
-
const deletedSessionIds = matchingSessions.
|
|
5649
|
-
const matchingPaths = matchingSessions.
|
|
6062
|
+
const deletedSessionIds = matchingSessions.flatMap((session) => session.id ? [session.id] : []);
|
|
6063
|
+
const matchingPaths = matchingSessions.flatMap((session) => session.path ? [session.path] : []);
|
|
5650
6064
|
const matchingPathSet = new Set(matchingPaths);
|
|
5651
|
-
await Promise.all([...this.sessionEntries.values()].
|
|
6065
|
+
await Promise.all([...this.sessionEntries.values()].flatMap((entry) => matchingPathSet.has(this.getSessionPath(entry)) ? [this.disposeSessionEntry(entry)] : []));
|
|
5652
6066
|
for (const ctx of this.contexts.values()) for (const sessionPath of matchingPaths) ctx.unreadFinished.delete(sessionPath);
|
|
5653
6067
|
await Promise.all(matchingPaths.map((sessionPath) => this.trashOrDeleteSessionFile(sessionPath)));
|
|
5654
6068
|
this.invalidateSessionIndexCache();
|
|
@@ -5664,23 +6078,32 @@ var PicoRuntime = class {
|
|
|
5664
6078
|
}
|
|
5665
6079
|
async deleteSessions(request, body) {
|
|
5666
6080
|
const { context } = await this.resolveRequest(request);
|
|
5667
|
-
const paths = Array.isArray(body.paths) ? body.paths.
|
|
6081
|
+
const paths = Array.isArray(body.paths) ? body.paths.flatMap((path) => {
|
|
6082
|
+
if (typeof path !== "string") return [];
|
|
6083
|
+
const trimmedPath = path.trim();
|
|
6084
|
+
return trimmedPath ? [trimmedPath] : [];
|
|
6085
|
+
}) : [];
|
|
5668
6086
|
const sessionPaths = [...new Set(paths)];
|
|
5669
6087
|
if (sessionPaths.length === 0) throw new Error("paths are required");
|
|
5670
6088
|
const sessionPathSet = new Set(sessionPaths);
|
|
5671
6089
|
const loadedEntries = [...this.sessionEntries.values()].filter((entry) => sessionPathSet.has(this.getSessionPath(entry)));
|
|
5672
|
-
|
|
5673
|
-
for (const loadedEntry of loadedEntries) {
|
|
6090
|
+
const replacementRequests = loadedEntries.flatMap((loadedEntry) => {
|
|
5674
6091
|
const affectedContexts = [...this.contexts.values()].filter((ctx) => ctx.activeKey === loadedEntry.key);
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
}
|
|
6092
|
+
return affectedContexts.length > 0 ? [{
|
|
6093
|
+
affectedContexts,
|
|
6094
|
+
cwd: loadedEntry.cwd
|
|
6095
|
+
}] : [];
|
|
6096
|
+
});
|
|
6097
|
+
const replacementResults = await Promise.all(replacementRequests.map(async (request) => ({
|
|
6098
|
+
affectedContexts: request.affectedContexts,
|
|
6099
|
+
entry: await this.createNewSessionEntry(request.cwd, { draft: true })
|
|
6100
|
+
})));
|
|
6101
|
+
let replacementEntry;
|
|
6102
|
+
for (const result of replacementResults) {
|
|
6103
|
+
replacementEntry = replacementEntry ?? result.entry;
|
|
6104
|
+
for (const affected of result.affectedContexts) affected.draftKey = result.entry.key;
|
|
5683
6105
|
}
|
|
6106
|
+
await Promise.all(replacementResults.flatMap((result) => result.affectedContexts.map((affected) => this.activateContextSession(affected, result.entry))));
|
|
5684
6107
|
for (const ctx of this.contexts.values()) for (const sessionPath of sessionPaths) ctx.unreadFinished.delete(sessionPath);
|
|
5685
6108
|
await Promise.all(loadedEntries.map((entry) => this.disposeSessionEntry(entry)));
|
|
5686
6109
|
await Promise.all(sessionPaths.map((sessionPath) => this.trashOrDeleteSessionFile(sessionPath)));
|
|
@@ -5742,15 +6165,15 @@ var PicoRuntime = class {
|
|
|
5742
6165
|
authType: "oauth",
|
|
5743
6166
|
...authStatus(provider.id)
|
|
5744
6167
|
})).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
|
-
})
|
|
6168
|
+
const apiKeyOptions = Array.from(providerIds).flatMap((providerId) => {
|
|
6169
|
+
if (!BUILT_IN_API_KEY_LOGIN_PROVIDERS.has(providerId) && oauthProviderIds.has(providerId)) return [];
|
|
6170
|
+
return [{
|
|
6171
|
+
id: providerId,
|
|
6172
|
+
name: getApiKeyProviderDisplayName(providerId),
|
|
6173
|
+
authType: "api_key",
|
|
6174
|
+
...authStatus(providerId)
|
|
6175
|
+
}];
|
|
6176
|
+
}).sort((left, right) => left.name.localeCompare(right.name));
|
|
5754
6177
|
const nameByProvider = new Map([...oauthOptions, ...apiKeyOptions].map((option) => [option.id, option.name]));
|
|
5755
6178
|
const authTypeByProvider = new Map([...oauthOptions, ...apiKeyOptions].map((option) => [option.id, option.authType]));
|
|
5756
6179
|
return {
|
|
@@ -5997,14 +6420,14 @@ var PicoRuntime = class {
|
|
|
5997
6420
|
pending.resolve({ cancelled: true });
|
|
5998
6421
|
} catch {}
|
|
5999
6422
|
this.pendingUiRequests.clear();
|
|
6000
|
-
|
|
6423
|
+
await Promise.all([...this.sessionEntries.values()].map((entry) => this.disposeSessionEntry(entry)));
|
|
6001
6424
|
}
|
|
6002
6425
|
};
|
|
6003
6426
|
function getPicoRuntime() {
|
|
6004
6427
|
globalThis.__picoRuntime ??= new PicoRuntime();
|
|
6005
6428
|
return globalThis.__picoRuntime;
|
|
6006
6429
|
}
|
|
6007
|
-
var Route$
|
|
6430
|
+
var Route$52 = createFileRoute("/events")({ server: { handlers: { GET: ({ request }) => getPicoRuntime().createEventsResponse(request) } } });
|
|
6008
6431
|
function jsonResponse(data, init = 200) {
|
|
6009
6432
|
const responseInit = typeof init === "number" ? { status: init } : init;
|
|
6010
6433
|
const headers = new Headers(responseInit.headers);
|
|
@@ -6040,7 +6463,7 @@ function routeErrorResponse(error, fallbackMessage) {
|
|
|
6040
6463
|
async function readRequestJson(request) {
|
|
6041
6464
|
return await request.json().catch(() => ({}));
|
|
6042
6465
|
}
|
|
6043
|
-
var Route$
|
|
6466
|
+
var Route$51 = createFileRoute("/api/thinking")({ server: { handlers: { POST: async ({ request }) => {
|
|
6044
6467
|
try {
|
|
6045
6468
|
const body = await readRequestJson(request);
|
|
6046
6469
|
return jsonResponse(await getPicoRuntime().setThinking(request, body));
|
|
@@ -6048,7 +6471,7 @@ var Route$46 = createFileRoute("/api/thinking")({ server: { handlers: { POST: as
|
|
|
6048
6471
|
return routeErrorResponse(error, "Failed to update thinking level");
|
|
6049
6472
|
}
|
|
6050
6473
|
} } } });
|
|
6051
|
-
var Route$
|
|
6474
|
+
var Route$50 = createFileRoute("/api/slash-command")({ server: { handlers: { POST: async ({ request }) => {
|
|
6052
6475
|
try {
|
|
6053
6476
|
const body = await readRequestJson(request);
|
|
6054
6477
|
return jsonResponse(await getPicoRuntime().runSlashCommand(request, body));
|
|
@@ -6056,7 +6479,7 @@ var Route$45 = createFileRoute("/api/slash-command")({ server: { handlers: { POS
|
|
|
6056
6479
|
return routeErrorResponse(error, "Failed to run slash command");
|
|
6057
6480
|
}
|
|
6058
6481
|
} } } });
|
|
6059
|
-
var Route$
|
|
6482
|
+
var Route$49 = createFileRoute("/api/provider-usage")({ server: { handlers: { GET: async ({ request }) => {
|
|
6060
6483
|
const provider = new URL(request.url).searchParams.get("provider") || void 0;
|
|
6061
6484
|
try {
|
|
6062
6485
|
return jsonResponse({
|
|
@@ -6067,7 +6490,7 @@ var Route$44 = createFileRoute("/api/provider-usage")({ server: { handlers: { GE
|
|
|
6067
6490
|
return routeErrorResponse(error, "Failed to read provider usage");
|
|
6068
6491
|
}
|
|
6069
6492
|
} } } });
|
|
6070
|
-
var Route$
|
|
6493
|
+
var Route$48 = createFileRoute("/api/prompt")({ server: { handlers: { POST: async ({ request }) => {
|
|
6071
6494
|
try {
|
|
6072
6495
|
const body = await readRequestJson(request);
|
|
6073
6496
|
return jsonResponse(await getPicoRuntime().prompt(request, body));
|
|
@@ -6097,6 +6520,9 @@ var DIRECTORY_SEARCH_IGNORE_DIRECTORIES = new Set([
|
|
|
6097
6520
|
function displayPath(value = "") {
|
|
6098
6521
|
return String(value).replace(/\\/g, "/");
|
|
6099
6522
|
}
|
|
6523
|
+
function projectPathTextContains(text, query) {
|
|
6524
|
+
return text.indexOf(query) >= 0;
|
|
6525
|
+
}
|
|
6100
6526
|
function expandHomeDirectory(inputPath) {
|
|
6101
6527
|
if (inputPath === "~") return os.homedir();
|
|
6102
6528
|
if (inputPath.startsWith("~/")) return `${os.homedir()}${inputPath.slice(1)}`;
|
|
@@ -6165,13 +6591,12 @@ async function listPathCompletionEntries(prefix, baseCwd) {
|
|
|
6165
6591
|
return [];
|
|
6166
6592
|
}
|
|
6167
6593
|
const normalizedSearchPrefix = searchPrefix.toLowerCase();
|
|
6168
|
-
const
|
|
6169
|
-
|
|
6170
|
-
if (!entry.name.toLowerCase().startsWith(normalizedSearchPrefix)) continue;
|
|
6594
|
+
const matchingEntries = entries.filter((entry) => entry.name.toLowerCase().startsWith(normalizedSearchPrefix));
|
|
6595
|
+
const suggestions = await Promise.all(matchingEntries.map(async (entry) => {
|
|
6171
6596
|
const isDirectory = await completionEntryIsDirectory(entry, join(searchDir, entry.name));
|
|
6172
6597
|
let completionPath;
|
|
6173
6598
|
if (displayPrefix.endsWith("/") || displayPrefix.endsWith("\\")) completionPath = `${displayPrefix}${entry.name}`;
|
|
6174
|
-
else if (displayPrefix
|
|
6599
|
+
else if (projectPathTextContains(displayPrefix, "/") || projectPathTextContains(displayPrefix, "\\")) if (displayPrefix === "~") completionPath = `~/${entry.name}`;
|
|
6175
6600
|
else if (displayPrefix.startsWith("~/")) {
|
|
6176
6601
|
const parentDir = dirname(displayPrefix.slice(2));
|
|
6177
6602
|
completionPath = parentDir === "." ? `~/${entry.name}` : `~/${displayPath(parentDir)}/${entry.name}`;
|
|
@@ -6184,13 +6609,12 @@ async function listPathCompletionEntries(prefix, baseCwd) {
|
|
|
6184
6609
|
}
|
|
6185
6610
|
else if (displayPrefix.startsWith("~")) completionPath = `~/${entry.name}`;
|
|
6186
6611
|
else completionPath = entry.name;
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
value,
|
|
6612
|
+
return {
|
|
6613
|
+
value: isDirectory ? `${displayPath(completionPath)}/` : displayPath(completionPath),
|
|
6190
6614
|
label: `${entry.name}${isDirectory ? "/" : ""}`,
|
|
6191
6615
|
isDirectory
|
|
6192
|
-
}
|
|
6193
|
-
}
|
|
6616
|
+
};
|
|
6617
|
+
}));
|
|
6194
6618
|
suggestions.sort((left, right) => {
|
|
6195
6619
|
if (left.isDirectory && !right.isDirectory) return -1;
|
|
6196
6620
|
if (!left.isDirectory && right.isDirectory) return 1;
|
|
@@ -6257,7 +6681,7 @@ async function runFdSearch(command, args) {
|
|
|
6257
6681
|
const displayedLine = displayPath(line);
|
|
6258
6682
|
const hasTrailingSeparator = displayedLine.endsWith("/");
|
|
6259
6683
|
const normalizedPath = hasTrailingSeparator ? displayedLine.slice(0, -1) : displayedLine;
|
|
6260
|
-
if (normalizedPath === ".git" || normalizedPath.startsWith(".git/") || normalizedPath
|
|
6684
|
+
if (normalizedPath === ".git" || normalizedPath.startsWith(".git/") || projectPathTextContains(normalizedPath, "/.git/")) continue;
|
|
6261
6685
|
results.push({
|
|
6262
6686
|
path: displayedLine,
|
|
6263
6687
|
isDirectory: hasTrailingSeparator
|
|
@@ -6267,52 +6691,72 @@ async function runFdSearch(command, args) {
|
|
|
6267
6691
|
});
|
|
6268
6692
|
});
|
|
6269
6693
|
}
|
|
6694
|
+
async function runFdSearchCandidates(args) {
|
|
6695
|
+
return (await Promise.all(["fd", "fdfind"].map((command) => runFdSearch(command, args)))).find((result) => result !== void 0);
|
|
6696
|
+
}
|
|
6270
6697
|
function escapePathQueryRegex(value = "") {
|
|
6271
6698
|
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6272
6699
|
}
|
|
6273
6700
|
function buildFdPathQuery(query = "") {
|
|
6274
6701
|
const normalized = displayPath(query);
|
|
6275
|
-
if (!normalized
|
|
6702
|
+
if (!projectPathTextContains(normalized, "/")) return normalized;
|
|
6276
6703
|
const hasTrailingSeparator = normalized.endsWith("/");
|
|
6277
6704
|
const trimmed = normalized.replace(/^\/+|\/+$/g, "");
|
|
6278
6705
|
if (!trimmed) return normalized;
|
|
6279
6706
|
const separatorPattern = "[\\\\/]";
|
|
6280
|
-
const segments = trimmed.split("/").
|
|
6707
|
+
const segments = trimmed.split("/").flatMap((segment) => segment ? [escapePathQueryRegex(segment)] : []);
|
|
6281
6708
|
if (segments.length === 0) return normalized;
|
|
6282
6709
|
let pattern = segments.join(separatorPattern);
|
|
6283
6710
|
if (hasTrailingSeparator) pattern += separatorPattern;
|
|
6284
6711
|
return pattern;
|
|
6285
6712
|
}
|
|
6713
|
+
async function readDirectoryEntries(directory) {
|
|
6714
|
+
try {
|
|
6715
|
+
return await readdir(directory, {
|
|
6716
|
+
withFileTypes: true,
|
|
6717
|
+
encoding: "utf8"
|
|
6718
|
+
});
|
|
6719
|
+
} catch {
|
|
6720
|
+
return [];
|
|
6721
|
+
}
|
|
6722
|
+
}
|
|
6723
|
+
async function walkDirectoryFallbackLayer({ baseDir, normalizedQuery, currentDirs, matches, maxResults }) {
|
|
6724
|
+
if (currentDirs.length === 0 || matches.length >= maxResults) return;
|
|
6725
|
+
const directoryEntries = await Promise.all(currentDirs.map(async (currentDir) => ({
|
|
6726
|
+
currentDir,
|
|
6727
|
+
entries: await readDirectoryEntries(currentDir)
|
|
6728
|
+
})));
|
|
6729
|
+
const nextDirs = [];
|
|
6730
|
+
for (const { currentDir, entries } of directoryEntries) for (const entry of entries) {
|
|
6731
|
+
if (matches.length >= maxResults) break;
|
|
6732
|
+
if (WALK_IGNORE_DIRECTORIES.has(entry.name)) continue;
|
|
6733
|
+
const fullPath = join(currentDir, entry.name);
|
|
6734
|
+
const relativePath = displayPath(path.relative(baseDir, fullPath));
|
|
6735
|
+
const isDirectory = entry.isDirectory();
|
|
6736
|
+
const displayValue = isDirectory ? `${relativePath}/` : relativePath;
|
|
6737
|
+
if (!normalizedQuery || projectPathTextContains(displayValue.toLowerCase(), normalizedQuery)) matches.push({
|
|
6738
|
+
path: displayValue,
|
|
6739
|
+
isDirectory
|
|
6740
|
+
});
|
|
6741
|
+
if (isDirectory) nextDirs.push(fullPath);
|
|
6742
|
+
}
|
|
6743
|
+
await walkDirectoryFallbackLayer({
|
|
6744
|
+
baseDir,
|
|
6745
|
+
normalizedQuery,
|
|
6746
|
+
currentDirs: nextDirs,
|
|
6747
|
+
matches,
|
|
6748
|
+
maxResults
|
|
6749
|
+
});
|
|
6750
|
+
}
|
|
6286
6751
|
async function walkDirectoryWithFallback(baseDir, query = "", maxResults = 100) {
|
|
6287
|
-
const queue = [baseDir];
|
|
6288
6752
|
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
|
-
}
|
|
6753
|
+
await walkDirectoryFallbackLayer({
|
|
6754
|
+
baseDir,
|
|
6755
|
+
normalizedQuery: displayPath(query).toLowerCase(),
|
|
6756
|
+
currentDirs: [baseDir],
|
|
6757
|
+
matches,
|
|
6758
|
+
maxResults
|
|
6759
|
+
});
|
|
6316
6760
|
return matches;
|
|
6317
6761
|
}
|
|
6318
6762
|
async function walkDirectory(baseDir, query = "", maxResults = 100) {
|
|
@@ -6345,10 +6789,8 @@ async function walkDirectory(baseDir, query = "", maxResults = 100) {
|
|
|
6345
6789
|
"node_modules"
|
|
6346
6790
|
];
|
|
6347
6791
|
if (query) args.push(buildFdPathQuery(query));
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
if (results !== void 0) return results;
|
|
6351
|
-
}
|
|
6792
|
+
const results = await runFdSearchCandidates(args);
|
|
6793
|
+
if (results !== void 0) return results;
|
|
6352
6794
|
return await walkDirectoryWithFallback(baseDir, query, maxResults);
|
|
6353
6795
|
}
|
|
6354
6796
|
async function resolveScopedFileReferenceQuery(rawQuery, baseCwd) {
|
|
@@ -6394,7 +6836,11 @@ function resolveProjectFilePath(baseCwd, filePath) {
|
|
|
6394
6836
|
};
|
|
6395
6837
|
}
|
|
6396
6838
|
async function listProjectFileTreePaths(baseCwd) {
|
|
6397
|
-
return (await walkDirectory(baseCwd, "", PROJECT_FILE_TREE_LIMIT)).
|
|
6839
|
+
return (await walkDirectory(baseCwd, "", PROJECT_FILE_TREE_LIMIT)).flatMap((entry) => {
|
|
6840
|
+
if (entry.isDirectory) return [];
|
|
6841
|
+
const path = displayPath(entry.path).replace(/\/+$/g, "");
|
|
6842
|
+
return path ? [path] : [];
|
|
6843
|
+
}).sort((left, right) => left.localeCompare(right));
|
|
6398
6844
|
}
|
|
6399
6845
|
async function readProjectFileContent(baseCwd, filePath) {
|
|
6400
6846
|
const resolved = resolveProjectFilePath(baseCwd, filePath);
|
|
@@ -6423,46 +6869,54 @@ function directorySearchScore({ absolutePath, query, root }) {
|
|
|
6423
6869
|
if (score === 0) return 0;
|
|
6424
6870
|
return score - depth * 5;
|
|
6425
6871
|
}
|
|
6872
|
+
async function searchDirectoriesFallbackLayer({ root, normalizedQuery, currentDirectories, results, maxResults }) {
|
|
6873
|
+
const eligibleDirectories = currentDirectories.filter((current) => current.depth < DIRECTORY_SEARCH_MAX_DEPTH);
|
|
6874
|
+
if (eligibleDirectories.length === 0 || results.length >= maxResults) return;
|
|
6875
|
+
const directoryEntries = await Promise.all(eligibleDirectories.map(async (current) => ({
|
|
6876
|
+
current,
|
|
6877
|
+
entries: await readDirectoryEntries(current.directory)
|
|
6878
|
+
})));
|
|
6879
|
+
const nextDirectories = [];
|
|
6880
|
+
for (const { current, entries } of directoryEntries) for (const entry of entries) {
|
|
6881
|
+
if (results.length >= maxResults) break;
|
|
6882
|
+
if (!entry.isDirectory()) continue;
|
|
6883
|
+
if (DIRECTORY_SEARCH_IGNORE_DIRECTORIES.has(entry.name)) continue;
|
|
6884
|
+
if (!normalizedQuery.startsWith(".") && entry.name.startsWith(".")) continue;
|
|
6885
|
+
const fullPath = join(current.directory, entry.name);
|
|
6886
|
+
const relativePath = `${displayPath(path.relative(root, fullPath))}/`;
|
|
6887
|
+
if (projectPathTextContains(relativePath.toLowerCase(), normalizedQuery)) results.push({
|
|
6888
|
+
path: relativePath,
|
|
6889
|
+
isDirectory: true
|
|
6890
|
+
});
|
|
6891
|
+
nextDirectories.push({
|
|
6892
|
+
directory: fullPath,
|
|
6893
|
+
depth: current.depth + 1
|
|
6894
|
+
});
|
|
6895
|
+
}
|
|
6896
|
+
await searchDirectoriesFallbackLayer({
|
|
6897
|
+
root,
|
|
6898
|
+
normalizedQuery,
|
|
6899
|
+
currentDirectories: nextDirectories,
|
|
6900
|
+
results,
|
|
6901
|
+
maxResults
|
|
6902
|
+
});
|
|
6903
|
+
}
|
|
6426
6904
|
async function searchDirectoriesWithFallback({ root, query, maxResults }) {
|
|
6427
|
-
const normalizedQuery = query.trim().toLowerCase();
|
|
6428
6905
|
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
|
-
}
|
|
6906
|
+
await searchDirectoriesFallbackLayer({
|
|
6907
|
+
root,
|
|
6908
|
+
normalizedQuery: query.trim().toLowerCase(),
|
|
6909
|
+
currentDirectories: [{
|
|
6910
|
+
directory: root,
|
|
6911
|
+
depth: 0
|
|
6912
|
+
}],
|
|
6913
|
+
results,
|
|
6914
|
+
maxResults
|
|
6915
|
+
});
|
|
6462
6916
|
return results;
|
|
6463
6917
|
}
|
|
6464
6918
|
async function searchDirectoriesInRoot({ root, query, maxResults }) {
|
|
6465
|
-
const
|
|
6919
|
+
const results = await runFdSearchCandidates([
|
|
6466
6920
|
"--base-directory",
|
|
6467
6921
|
root,
|
|
6468
6922
|
"--max-depth",
|
|
@@ -6498,11 +6952,8 @@ async function searchDirectoriesInRoot({ root, query, maxResults }) {
|
|
|
6498
6952
|
"--exclude",
|
|
6499
6953
|
"node_modules",
|
|
6500
6954
|
buildFdPathQuery(query)
|
|
6501
|
-
];
|
|
6502
|
-
|
|
6503
|
-
const results = await runFdSearch(command, args);
|
|
6504
|
-
if (results !== void 0) return results.filter((entry) => entry.isDirectory);
|
|
6505
|
-
}
|
|
6955
|
+
]);
|
|
6956
|
+
if (results !== void 0) return results.filter((entry) => entry.isDirectory);
|
|
6506
6957
|
return await searchDirectoriesWithFallback({
|
|
6507
6958
|
root,
|
|
6508
6959
|
query,
|
|
@@ -6521,37 +6972,40 @@ async function searchDirectoryEntries(query, baseCwd) {
|
|
|
6521
6972
|
if (baseCwd && !pathIsInside(baseCwd, homeDirectory)) roots.push(baseCwd);
|
|
6522
6973
|
const seen = /* @__PURE__ */ new Set();
|
|
6523
6974
|
const matches = [];
|
|
6524
|
-
|
|
6975
|
+
const rootEntries = await Promise.all(roots.map(async (root) => {
|
|
6525
6976
|
let rootStats;
|
|
6526
6977
|
try {
|
|
6527
6978
|
rootStats = await stat(root);
|
|
6528
6979
|
} catch {
|
|
6529
|
-
|
|
6980
|
+
return [];
|
|
6530
6981
|
}
|
|
6531
|
-
if (!rootStats.isDirectory())
|
|
6532
|
-
|
|
6982
|
+
if (!rootStats.isDirectory()) return [];
|
|
6983
|
+
return (await searchDirectoriesInRoot({
|
|
6533
6984
|
root,
|
|
6534
6985
|
query: normalizedQuery,
|
|
6535
6986
|
maxResults: DIRECTORY_SEARCH_LIMIT * 4
|
|
6987
|
+
})).map((entry) => ({
|
|
6988
|
+
entry,
|
|
6989
|
+
root
|
|
6990
|
+
}));
|
|
6991
|
+
}));
|
|
6992
|
+
for (const { entry, root } of rootEntries.flat()) {
|
|
6993
|
+
const relativePath = displayPath(entry.path).replace(/\/+$/g, "");
|
|
6994
|
+
if (!relativePath) continue;
|
|
6995
|
+
const absolutePath = resolve(root, relativePath);
|
|
6996
|
+
if (seen.has(absolutePath)) continue;
|
|
6997
|
+
seen.add(absolutePath);
|
|
6998
|
+
const score = directorySearchScore({
|
|
6999
|
+
absolutePath,
|
|
7000
|
+
query: normalizedQuery,
|
|
7001
|
+
root
|
|
7002
|
+
});
|
|
7003
|
+
if (score <= 0) continue;
|
|
7004
|
+
matches.push({
|
|
7005
|
+
absolutePath,
|
|
7006
|
+
root,
|
|
7007
|
+
score
|
|
6536
7008
|
});
|
|
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
7009
|
}
|
|
6556
7010
|
return matches.sort((left, right) => {
|
|
6557
7011
|
if (right.score !== left.score) return right.score - left.score;
|
|
@@ -6571,10 +7025,13 @@ async function listFileReferenceEntries(query, baseCwd, { isQuotedPrefix = false
|
|
|
6571
7025
|
const scopedQuery = await resolveScopedFileReferenceQuery(normalizedQuery, baseCwd);
|
|
6572
7026
|
const searchBaseDir = scopedQuery?.searchBaseDir ?? baseCwd;
|
|
6573
7027
|
const searchQuery = scopedQuery?.query ?? normalizedQuery;
|
|
6574
|
-
return (await walkDirectory(searchBaseDir, searchQuery, 100)).
|
|
6575
|
-
|
|
6576
|
-
score
|
|
6577
|
-
|
|
7028
|
+
return (await walkDirectory(searchBaseDir, searchQuery, 100)).flatMap((entry) => {
|
|
7029
|
+
const score = scoreFileReferenceEntry(entry.path, searchQuery, entry.isDirectory);
|
|
7030
|
+
return score > 0 ? [{
|
|
7031
|
+
...entry,
|
|
7032
|
+
score
|
|
7033
|
+
}] : [];
|
|
7034
|
+
}).sort((left, right) => right.score - left.score).slice(0, 20).map((entry) => {
|
|
6578
7035
|
const pathWithoutSlash = entry.isDirectory ? entry.path.slice(0, -1) : entry.path;
|
|
6579
7036
|
const displayValue = scopedQuery ? scopedDisplayPath(scopedQuery.displayBase, pathWithoutSlash) : pathWithoutSlash;
|
|
6580
7037
|
return {
|
|
@@ -6588,7 +7045,7 @@ async function listFileReferenceEntries(query, baseCwd, { isQuotedPrefix = false
|
|
|
6588
7045
|
};
|
|
6589
7046
|
});
|
|
6590
7047
|
}
|
|
6591
|
-
var Route$
|
|
7048
|
+
var Route$47 = createFileRoute("/api/path-completions")({ server: { handlers: { POST: async ({ request }) => {
|
|
6592
7049
|
try {
|
|
6593
7050
|
const body = await readRequestJson(request);
|
|
6594
7051
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -6604,7 +7061,7 @@ var Route$42 = createFileRoute("/api/path-completions")({ server: { handlers: {
|
|
|
6604
7061
|
return routeErrorResponse(error, "Failed to list path completions");
|
|
6605
7062
|
}
|
|
6606
7063
|
} } } });
|
|
6607
|
-
var Route$
|
|
7064
|
+
var Route$46 = createFileRoute("/api/model")({ server: { handlers: { POST: async ({ request }) => {
|
|
6608
7065
|
try {
|
|
6609
7066
|
const body = await readRequestJson(request);
|
|
6610
7067
|
return jsonResponse(await getPicoRuntime().setModel(request, body));
|
|
@@ -6612,7 +7069,7 @@ var Route$41 = createFileRoute("/api/model")({ server: { handlers: { POST: async
|
|
|
6612
7069
|
return routeErrorResponse(error, "Failed to update model");
|
|
6613
7070
|
}
|
|
6614
7071
|
} } } });
|
|
6615
|
-
var Route$
|
|
7072
|
+
var Route$45 = createFileRoute("/api/highlight")({ server: { handlers: { POST: async ({ request }) => {
|
|
6616
7073
|
try {
|
|
6617
7074
|
const body = await readRequestJson(request);
|
|
6618
7075
|
return jsonResponse(await getPicoRuntime().highlightCode(body.code, body.language));
|
|
@@ -6620,7 +7077,7 @@ var Route$40 = createFileRoute("/api/highlight")({ server: { handlers: { POST: a
|
|
|
6620
7077
|
return routeErrorResponse(error, "Failed to highlight code");
|
|
6621
7078
|
}
|
|
6622
7079
|
} } } });
|
|
6623
|
-
var Route$
|
|
7080
|
+
var Route$44 = createFileRoute("/api/git-status")({ server: { handlers: { GET: async ({ request }) => {
|
|
6624
7081
|
const requestedCwd = new URL(request.url).searchParams.get("cwd") || "";
|
|
6625
7082
|
if (!requestedCwd.trim()) return errorResponse("cwd is required");
|
|
6626
7083
|
try {
|
|
@@ -6635,7 +7092,7 @@ var Route$39 = createFileRoute("/api/git-status")({ server: { handlers: { GET: a
|
|
|
6635
7092
|
return routeErrorResponse(error, "Failed to read git status");
|
|
6636
7093
|
}
|
|
6637
7094
|
} } } });
|
|
6638
|
-
var Route$
|
|
7095
|
+
var Route$43 = createFileRoute("/api/git-stage")({ server: { handlers: { POST: async ({ request }) => {
|
|
6639
7096
|
try {
|
|
6640
7097
|
const body = await readRequestJson(request);
|
|
6641
7098
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6656,7 +7113,7 @@ var Route$38 = createFileRoute("/api/git-stage")({ server: { handlers: { POST: a
|
|
|
6656
7113
|
return routeErrorResponse(error, "Failed to stage changes");
|
|
6657
7114
|
}
|
|
6658
7115
|
} } } });
|
|
6659
|
-
var Route$
|
|
7116
|
+
var Route$42 = createFileRoute("/api/git-review")({ server: { handlers: { GET: async ({ request }) => {
|
|
6660
7117
|
const url = new URL(request.url);
|
|
6661
7118
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
6662
7119
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -6679,7 +7136,7 @@ var Route$37 = createFileRoute("/api/git-review")({ server: { handlers: { GET: a
|
|
|
6679
7136
|
return routeErrorResponse(error, "Failed to read git review file");
|
|
6680
7137
|
}
|
|
6681
7138
|
} } } });
|
|
6682
|
-
var Route$
|
|
7139
|
+
var Route$41 = createFileRoute("/api/git-push")({ server: { handlers: { POST: async ({ request }) => {
|
|
6683
7140
|
try {
|
|
6684
7141
|
const body = await readRequestJson(request);
|
|
6685
7142
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6698,7 +7155,7 @@ var Route$36 = createFileRoute("/api/git-push")({ server: { handlers: { POST: as
|
|
|
6698
7155
|
return routeErrorResponse(error, "Failed to push changes");
|
|
6699
7156
|
}
|
|
6700
7157
|
} } } });
|
|
6701
|
-
var Route$
|
|
7158
|
+
var Route$40 = createFileRoute("/api/git-pull")({ server: { handlers: { POST: async ({ request }) => {
|
|
6702
7159
|
try {
|
|
6703
7160
|
const body = await readRequestJson(request);
|
|
6704
7161
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6716,7 +7173,7 @@ var Route$35 = createFileRoute("/api/git-pull")({ server: { handlers: { POST: as
|
|
|
6716
7173
|
return routeErrorResponse(error, "Failed to pull changes");
|
|
6717
7174
|
}
|
|
6718
7175
|
} } } });
|
|
6719
|
-
var Route$
|
|
7176
|
+
var Route$39 = createFileRoute("/api/git-discard")({ server: { handlers: { POST: async ({ request }) => {
|
|
6720
7177
|
try {
|
|
6721
7178
|
const body = await readRequestJson(request);
|
|
6722
7179
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6738,7 +7195,7 @@ var Route$34 = createFileRoute("/api/git-discard")({ server: { handlers: { POST:
|
|
|
6738
7195
|
return routeErrorResponse(error, "Failed to discard changes");
|
|
6739
7196
|
}
|
|
6740
7197
|
} } } });
|
|
6741
|
-
var Route$
|
|
7198
|
+
var Route$38 = createFileRoute("/api/git-diff")({ server: { handlers: { GET: async ({ request }) => {
|
|
6742
7199
|
const url = new URL(request.url);
|
|
6743
7200
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
6744
7201
|
const requestedPath = url.searchParams.get("path") || "";
|
|
@@ -6758,7 +7215,28 @@ var Route$33 = createFileRoute("/api/git-diff")({ server: { handlers: { GET: asy
|
|
|
6758
7215
|
return routeErrorResponse(error, "Failed to read git diff");
|
|
6759
7216
|
}
|
|
6760
7217
|
} } } });
|
|
6761
|
-
var Route$
|
|
7218
|
+
var Route$37 = createFileRoute("/api/git-commit-remote-url")({ server: { handlers: { GET: async ({ request }) => {
|
|
7219
|
+
try {
|
|
7220
|
+
const url = new URL(request.url);
|
|
7221
|
+
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7222
|
+
const commit = url.searchParams.get("commit") || "";
|
|
7223
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7224
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7225
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7226
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7227
|
+
const result = await readDirectoryGitCommitRemoteUrl(cwd, commit);
|
|
7228
|
+
if (!result?.remoteUrl) throw new Error("No remote URL found");
|
|
7229
|
+
return jsonResponse({
|
|
7230
|
+
ok: true,
|
|
7231
|
+
cwd,
|
|
7232
|
+
commit: result.commit,
|
|
7233
|
+
remoteUrl: result.remoteUrl
|
|
7234
|
+
});
|
|
7235
|
+
} catch (error) {
|
|
7236
|
+
return routeErrorResponse(error, "Failed to read commit remote URL");
|
|
7237
|
+
}
|
|
7238
|
+
} } } });
|
|
7239
|
+
var Route$36 = createFileRoute("/api/git-commit-message")({ server: { handlers: { POST: async ({ request }) => {
|
|
6762
7240
|
try {
|
|
6763
7241
|
const body = await readRequestJson(request);
|
|
6764
7242
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6777,7 +7255,93 @@ var Route$32 = createFileRoute("/api/git-commit-message")({ server: { handlers:
|
|
|
6777
7255
|
return routeErrorResponse(error, "Failed to generate commit message");
|
|
6778
7256
|
}
|
|
6779
7257
|
} } } });
|
|
6780
|
-
var Route$
|
|
7258
|
+
var Route$35 = createFileRoute("/api/git-commit-files")({ server: { handlers: { GET: async ({ request }) => {
|
|
7259
|
+
try {
|
|
7260
|
+
const url = new URL(request.url);
|
|
7261
|
+
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7262
|
+
const commit = url.searchParams.get("commit") || "";
|
|
7263
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7264
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7265
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7266
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7267
|
+
return jsonResponse({
|
|
7268
|
+
ok: true,
|
|
7269
|
+
cwd,
|
|
7270
|
+
commit,
|
|
7271
|
+
files: await readDirectoryGitCommitFiles(cwd, commit) || []
|
|
7272
|
+
});
|
|
7273
|
+
} catch (error) {
|
|
7274
|
+
return routeErrorResponse(error, "Failed to read commit files");
|
|
7275
|
+
}
|
|
7276
|
+
} } } });
|
|
7277
|
+
function normalizeGitCommitDiffMode(value) {
|
|
7278
|
+
if (value === "head" || value === "previous") return value;
|
|
7279
|
+
return "commit";
|
|
7280
|
+
}
|
|
7281
|
+
var Route$34 = createFileRoute("/api/git-commit-diff")({ server: { handlers: { GET: async ({ request }) => {
|
|
7282
|
+
try {
|
|
7283
|
+
const url = new URL(request.url);
|
|
7284
|
+
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
7285
|
+
const commit = url.searchParams.get("commit") || "";
|
|
7286
|
+
const mode = normalizeGitCommitDiffMode(url.searchParams.get("mode"));
|
|
7287
|
+
const path = url.searchParams.get("path") || void 0;
|
|
7288
|
+
const previousPath = url.searchParams.get("previousPath") || void 0;
|
|
7289
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7290
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7291
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7292
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7293
|
+
const result = await readDirectoryGitCommitDiff(cwd, commit, mode, path, previousPath);
|
|
7294
|
+
return jsonResponse({
|
|
7295
|
+
ok: true,
|
|
7296
|
+
cwd,
|
|
7297
|
+
commit: result?.commit || commit,
|
|
7298
|
+
mode,
|
|
7299
|
+
title: result?.title || commit,
|
|
7300
|
+
...result?.path ? { path: result.path } : {},
|
|
7301
|
+
...result?.previousPath ? { previousPath: result.previousPath } : {},
|
|
7302
|
+
patch: result?.patch || "No git repository detected."
|
|
7303
|
+
});
|
|
7304
|
+
} catch (error) {
|
|
7305
|
+
return routeErrorResponse(error, "Failed to read commit diff");
|
|
7306
|
+
}
|
|
7307
|
+
} } } });
|
|
7308
|
+
var gitCommitActions = new Set([
|
|
7309
|
+
"checkout",
|
|
7310
|
+
"cherry-pick",
|
|
7311
|
+
"revert",
|
|
7312
|
+
"tag",
|
|
7313
|
+
"reset",
|
|
7314
|
+
"rebase",
|
|
7315
|
+
"drop",
|
|
7316
|
+
"squash"
|
|
7317
|
+
]);
|
|
7318
|
+
var Route$33 = createFileRoute("/api/git-commit-action")({ server: { handlers: { POST: async ({ request }) => {
|
|
7319
|
+
try {
|
|
7320
|
+
const body = await readRequestJson(request);
|
|
7321
|
+
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
7322
|
+
const action = typeof body.action === "string" ? body.action : "";
|
|
7323
|
+
const commit = typeof body.commit === "string" ? body.commit : "";
|
|
7324
|
+
if (!requestedCwd.trim()) throw new Error("cwd is required");
|
|
7325
|
+
if (!gitCommitActions.has(action)) throw new Error("action is required");
|
|
7326
|
+
if (!commit.trim()) throw new Error("commit is required");
|
|
7327
|
+
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
7328
|
+
const cwd = await resolveDirectoryPath(requestedCwd, getPicoRuntime().getBaseCwd(activeEntry, context));
|
|
7329
|
+
const result = await runDirectoryGitCommitAction(cwd, action, commit, {
|
|
7330
|
+
tagName: typeof body.tagName === "string" ? body.tagName : "",
|
|
7331
|
+
resetMode: typeof body.resetMode === "string" ? body.resetMode : "",
|
|
7332
|
+
message: typeof body.message === "string" ? body.message : ""
|
|
7333
|
+
});
|
|
7334
|
+
return jsonResponse({
|
|
7335
|
+
ok: true,
|
|
7336
|
+
cwd,
|
|
7337
|
+
stdout: result.stdout,
|
|
7338
|
+
stderr: result.stderr
|
|
7339
|
+
});
|
|
7340
|
+
} catch (error) {
|
|
7341
|
+
return routeErrorResponse(error, "Failed to run commit action");
|
|
7342
|
+
}
|
|
7343
|
+
} } } });
|
|
7344
|
+
var Route$32 = createFileRoute("/api/git-commit")({ server: { handlers: { POST: async ({ request }) => {
|
|
6781
7345
|
try {
|
|
6782
7346
|
const body = await readRequestJson(request);
|
|
6783
7347
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6802,7 +7366,7 @@ var Route$31 = createFileRoute("/api/git-commit")({ server: { handlers: { POST:
|
|
|
6802
7366
|
return routeErrorResponse(error, "Failed to commit changes");
|
|
6803
7367
|
}
|
|
6804
7368
|
} } } });
|
|
6805
|
-
var Route$
|
|
7369
|
+
var Route$31 = createFileRoute("/api/git-checkout")({ server: { handlers: { POST: async ({ request }) => {
|
|
6806
7370
|
try {
|
|
6807
7371
|
const body = await readRequestJson(request);
|
|
6808
7372
|
const requestedCwd = typeof body.cwd === "string" ? body.cwd : "";
|
|
@@ -6852,7 +7416,7 @@ function getRuntimeRequestForGitChanges(request, url) {
|
|
|
6852
7416
|
method: request.method
|
|
6853
7417
|
});
|
|
6854
7418
|
}
|
|
6855
|
-
var Route$
|
|
7419
|
+
var Route$30 = createFileRoute("/api/git-changes")({ server: { handlers: { GET: async ({ request }) => {
|
|
6856
7420
|
const url = new URL(request.url);
|
|
6857
7421
|
const requestedCwd = url.searchParams.get("cwd") || "";
|
|
6858
7422
|
const gitScope = getGitChangesScope(url);
|
|
@@ -6922,7 +7486,7 @@ var Route$29 = createFileRoute("/api/git-changes")({ server: { handlers: { GET:
|
|
|
6922
7486
|
return routeErrorResponse(error, "Failed to read git changes");
|
|
6923
7487
|
}
|
|
6924
7488
|
} } } });
|
|
6925
|
-
var Route$
|
|
7489
|
+
var Route$29 = createFileRoute("/api/file-completions")({ server: { handlers: { POST: async ({ request }) => {
|
|
6926
7490
|
try {
|
|
6927
7491
|
const body = await readRequestJson(request);
|
|
6928
7492
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -6939,7 +7503,7 @@ var Route$28 = createFileRoute("/api/file-completions")({ server: { handlers: {
|
|
|
6939
7503
|
return routeErrorResponse(error, "Failed to list file completions");
|
|
6940
7504
|
}
|
|
6941
7505
|
} } } });
|
|
6942
|
-
var Route$
|
|
7506
|
+
var Route$28 = createFileRoute("/api/directory-sessions-indexes")({ server: { handlers: { GET: async ({ request }) => {
|
|
6943
7507
|
const directories = new URL(request.url).searchParams.getAll("directory");
|
|
6944
7508
|
if (directories.length === 0) return errorResponse("at least one directory is required");
|
|
6945
7509
|
try {
|
|
@@ -6948,7 +7512,7 @@ var Route$27 = createFileRoute("/api/directory-sessions-indexes")({ server: { ha
|
|
|
6948
7512
|
return routeErrorResponse(error, "Failed to list directory session indexes");
|
|
6949
7513
|
}
|
|
6950
7514
|
} } } });
|
|
6951
|
-
var Route$
|
|
7515
|
+
var Route$27 = createFileRoute("/api/directory-sessions-index")({ server: { handlers: { GET: async ({ request }) => {
|
|
6952
7516
|
const directory = new URL(request.url).searchParams.get("directory") || "";
|
|
6953
7517
|
if (!directory.trim()) return errorResponse("directory is required");
|
|
6954
7518
|
try {
|
|
@@ -6957,7 +7521,7 @@ var Route$26 = createFileRoute("/api/directory-sessions-index")({ server: { hand
|
|
|
6957
7521
|
return routeErrorResponse(error, "Failed to list directory session index");
|
|
6958
7522
|
}
|
|
6959
7523
|
} } } });
|
|
6960
|
-
var Route$
|
|
7524
|
+
var Route$26 = createFileRoute("/api/directory-sessions")({ server: { handlers: { GET: async ({ request }) => {
|
|
6961
7525
|
const url = new URL(request.url);
|
|
6962
7526
|
const directory = url.searchParams.get("directory") || "";
|
|
6963
7527
|
const offset = Number.parseInt(url.searchParams.get("offset") || "0", 10);
|
|
@@ -6972,7 +7536,7 @@ var Route$25 = createFileRoute("/api/directory-sessions")({ server: { handlers:
|
|
|
6972
7536
|
return routeErrorResponse(error, "Failed to list directory sessions");
|
|
6973
7537
|
}
|
|
6974
7538
|
} } } });
|
|
6975
|
-
var Route$
|
|
7539
|
+
var Route$25 = createFileRoute("/api/directory-search")({ server: { handlers: { POST: async ({ request }) => {
|
|
6976
7540
|
try {
|
|
6977
7541
|
const body = await readRequestJson(request);
|
|
6978
7542
|
const { context, activeEntry } = await getPicoRuntime().resolveRequest(request);
|
|
@@ -6988,14 +7552,14 @@ var Route$24 = createFileRoute("/api/directory-search")({ server: { handlers: {
|
|
|
6988
7552
|
return routeErrorResponse(error, "Failed to search directories");
|
|
6989
7553
|
}
|
|
6990
7554
|
} } } });
|
|
6991
|
-
var Route$
|
|
7555
|
+
var Route$24 = createFileRoute("/api/abort")({ server: { handlers: { POST: async ({ request }) => {
|
|
6992
7556
|
try {
|
|
6993
7557
|
return jsonResponse(await getPicoRuntime().abort(request));
|
|
6994
7558
|
} catch (error) {
|
|
6995
7559
|
return routeErrorResponse(error, "Failed to abort session");
|
|
6996
7560
|
}
|
|
6997
7561
|
} } } });
|
|
6998
|
-
var Route$
|
|
7562
|
+
var Route$23 = createFileRoute("/api/ui/$id")({ server: { handlers: { POST: async ({ request, params }) => {
|
|
6999
7563
|
try {
|
|
7000
7564
|
const body = await readRequestJson(request);
|
|
7001
7565
|
return jsonResponse(await getPicoRuntime().resolveUiRequest(params.id, body));
|
|
@@ -7003,7 +7567,7 @@ var Route$22 = createFileRoute("/api/ui/$id")({ server: { handlers: { POST: asyn
|
|
|
7003
7567
|
return routeErrorResponse(error, "Failed to resolve UI request");
|
|
7004
7568
|
}
|
|
7005
7569
|
} } } });
|
|
7006
|
-
var Route$
|
|
7570
|
+
var Route$22 = createFileRoute("/api/settings/hide-thinking")({ server: { handlers: { POST: async ({ request }) => {
|
|
7007
7571
|
try {
|
|
7008
7572
|
const body = await readRequestJson(request);
|
|
7009
7573
|
return jsonResponse(await getPicoRuntime().setHideThinking(body));
|
|
@@ -7011,7 +7575,7 @@ var Route$21 = createFileRoute("/api/settings/hide-thinking")({ server: { handle
|
|
|
7011
7575
|
return routeErrorResponse(error, "Failed to update hide-thinking setting");
|
|
7012
7576
|
}
|
|
7013
7577
|
} } } });
|
|
7014
|
-
var Route$
|
|
7578
|
+
var Route$21 = createFileRoute("/api/sessions/delete")({ server: { handlers: { POST: async ({ request }) => {
|
|
7015
7579
|
try {
|
|
7016
7580
|
const body = await readRequestJson(request);
|
|
7017
7581
|
return jsonResponse(await getPicoRuntime().deleteSessions(request, body));
|
|
@@ -7019,7 +7583,7 @@ var Route$20 = createFileRoute("/api/sessions/delete")({ server: { handlers: { P
|
|
|
7019
7583
|
return routeErrorResponse(error, "Failed to delete sessions");
|
|
7020
7584
|
}
|
|
7021
7585
|
} } } });
|
|
7022
|
-
var Route$
|
|
7586
|
+
var Route$20 = createFileRoute("/api/session/tree")({ server: { handlers: {
|
|
7023
7587
|
GET: async ({ request }) => {
|
|
7024
7588
|
try {
|
|
7025
7589
|
return jsonResponse(await getPicoRuntime().getSessionTreeForRequest(request));
|
|
@@ -7036,14 +7600,14 @@ var Route$19 = createFileRoute("/api/session/tree")({ server: { handlers: {
|
|
|
7036
7600
|
}
|
|
7037
7601
|
}
|
|
7038
7602
|
} } });
|
|
7039
|
-
var Route$
|
|
7603
|
+
var Route$19 = createFileRoute("/api/session/select")({ server: { handlers: { POST: async ({ request }) => {
|
|
7040
7604
|
try {
|
|
7041
7605
|
return jsonResponse(await getPicoRuntime().selectSession(request));
|
|
7042
7606
|
} catch (error) {
|
|
7043
7607
|
return routeErrorResponse(error, "Failed to select session");
|
|
7044
7608
|
}
|
|
7045
7609
|
} } } });
|
|
7046
|
-
var Route$
|
|
7610
|
+
var Route$18 = createFileRoute("/api/session/rename")({ server: { handlers: { POST: async ({ request }) => {
|
|
7047
7611
|
try {
|
|
7048
7612
|
const body = await readRequestJson(request);
|
|
7049
7613
|
return jsonResponse(await getPicoRuntime().renameSession(body));
|
|
@@ -7051,6 +7615,14 @@ var Route$17 = createFileRoute("/api/session/rename")({ server: { handlers: { PO
|
|
|
7051
7615
|
return routeErrorResponse(error, "Failed to rename session");
|
|
7052
7616
|
}
|
|
7053
7617
|
} } } });
|
|
7618
|
+
var Route$17 = createFileRoute("/api/session/read-state")({ server: { handlers: { POST: async ({ request }) => {
|
|
7619
|
+
try {
|
|
7620
|
+
const body = await readRequestJson(request);
|
|
7621
|
+
return jsonResponse(await getPicoRuntime().setSessionReadState(request, body));
|
|
7622
|
+
} catch (error) {
|
|
7623
|
+
return routeErrorResponse(error, "Failed to update session read state");
|
|
7624
|
+
}
|
|
7625
|
+
} } } });
|
|
7054
7626
|
var Route$16 = createFileRoute("/api/session/new")({ server: { handlers: { POST: async ({ request }) => {
|
|
7055
7627
|
try {
|
|
7056
7628
|
const body = await readRequestJson(request);
|
|
@@ -7224,220 +7796,245 @@ var Route = createFileRoute("/api/session/tree/label")({ server: { handlers: { P
|
|
|
7224
7796
|
return routeErrorResponse(error, "Failed to update tree label");
|
|
7225
7797
|
}
|
|
7226
7798
|
} } } });
|
|
7227
|
-
var EventsRoute = Route$
|
|
7799
|
+
var EventsRoute = Route$52.update({
|
|
7228
7800
|
id: "/events",
|
|
7229
7801
|
path: "/events",
|
|
7230
|
-
getParentRoute: () => Route$
|
|
7802
|
+
getParentRoute: () => Route$53
|
|
7231
7803
|
});
|
|
7232
|
-
var IndexRoute = Route$
|
|
7804
|
+
var IndexRoute = Route$54.update({
|
|
7233
7805
|
id: "/",
|
|
7234
7806
|
path: "/",
|
|
7235
|
-
getParentRoute: () => Route$
|
|
7807
|
+
getParentRoute: () => Route$53
|
|
7236
7808
|
});
|
|
7237
|
-
var ApiThinkingRoute = Route$
|
|
7809
|
+
var ApiThinkingRoute = Route$51.update({
|
|
7238
7810
|
id: "/api/thinking",
|
|
7239
7811
|
path: "/api/thinking",
|
|
7240
|
-
getParentRoute: () => Route$
|
|
7812
|
+
getParentRoute: () => Route$53
|
|
7241
7813
|
});
|
|
7242
|
-
var ApiSlashCommandRoute = Route$
|
|
7814
|
+
var ApiSlashCommandRoute = Route$50.update({
|
|
7243
7815
|
id: "/api/slash-command",
|
|
7244
7816
|
path: "/api/slash-command",
|
|
7245
|
-
getParentRoute: () => Route$
|
|
7817
|
+
getParentRoute: () => Route$53
|
|
7246
7818
|
});
|
|
7247
|
-
var ApiProviderUsageRoute = Route$
|
|
7819
|
+
var ApiProviderUsageRoute = Route$49.update({
|
|
7248
7820
|
id: "/api/provider-usage",
|
|
7249
7821
|
path: "/api/provider-usage",
|
|
7250
|
-
getParentRoute: () => Route$
|
|
7822
|
+
getParentRoute: () => Route$53
|
|
7251
7823
|
});
|
|
7252
|
-
var ApiPromptRoute = Route$
|
|
7824
|
+
var ApiPromptRoute = Route$48.update({
|
|
7253
7825
|
id: "/api/prompt",
|
|
7254
7826
|
path: "/api/prompt",
|
|
7255
|
-
getParentRoute: () => Route$
|
|
7827
|
+
getParentRoute: () => Route$53
|
|
7256
7828
|
});
|
|
7257
|
-
var ApiPathCompletionsRoute = Route$
|
|
7829
|
+
var ApiPathCompletionsRoute = Route$47.update({
|
|
7258
7830
|
id: "/api/path-completions",
|
|
7259
7831
|
path: "/api/path-completions",
|
|
7260
|
-
getParentRoute: () => Route$
|
|
7832
|
+
getParentRoute: () => Route$53
|
|
7261
7833
|
});
|
|
7262
|
-
var ApiModelRoute = Route$
|
|
7834
|
+
var ApiModelRoute = Route$46.update({
|
|
7263
7835
|
id: "/api/model",
|
|
7264
7836
|
path: "/api/model",
|
|
7265
|
-
getParentRoute: () => Route$
|
|
7837
|
+
getParentRoute: () => Route$53
|
|
7266
7838
|
});
|
|
7267
|
-
var ApiHighlightRoute = Route$
|
|
7839
|
+
var ApiHighlightRoute = Route$45.update({
|
|
7268
7840
|
id: "/api/highlight",
|
|
7269
7841
|
path: "/api/highlight",
|
|
7270
|
-
getParentRoute: () => Route$
|
|
7842
|
+
getParentRoute: () => Route$53
|
|
7271
7843
|
});
|
|
7272
|
-
var ApiGitStatusRoute = Route$
|
|
7844
|
+
var ApiGitStatusRoute = Route$44.update({
|
|
7273
7845
|
id: "/api/git-status",
|
|
7274
7846
|
path: "/api/git-status",
|
|
7275
|
-
getParentRoute: () => Route$
|
|
7847
|
+
getParentRoute: () => Route$53
|
|
7276
7848
|
});
|
|
7277
|
-
var ApiGitStageRoute = Route$
|
|
7849
|
+
var ApiGitStageRoute = Route$43.update({
|
|
7278
7850
|
id: "/api/git-stage",
|
|
7279
7851
|
path: "/api/git-stage",
|
|
7280
|
-
getParentRoute: () => Route$
|
|
7852
|
+
getParentRoute: () => Route$53
|
|
7281
7853
|
});
|
|
7282
|
-
var ApiGitReviewRoute = Route$
|
|
7854
|
+
var ApiGitReviewRoute = Route$42.update({
|
|
7283
7855
|
id: "/api/git-review",
|
|
7284
7856
|
path: "/api/git-review",
|
|
7285
|
-
getParentRoute: () => Route$
|
|
7857
|
+
getParentRoute: () => Route$53
|
|
7286
7858
|
});
|
|
7287
|
-
var ApiGitPushRoute = Route$
|
|
7859
|
+
var ApiGitPushRoute = Route$41.update({
|
|
7288
7860
|
id: "/api/git-push",
|
|
7289
7861
|
path: "/api/git-push",
|
|
7290
|
-
getParentRoute: () => Route$
|
|
7862
|
+
getParentRoute: () => Route$53
|
|
7291
7863
|
});
|
|
7292
|
-
var ApiGitPullRoute = Route$
|
|
7864
|
+
var ApiGitPullRoute = Route$40.update({
|
|
7293
7865
|
id: "/api/git-pull",
|
|
7294
7866
|
path: "/api/git-pull",
|
|
7295
|
-
getParentRoute: () => Route$
|
|
7867
|
+
getParentRoute: () => Route$53
|
|
7296
7868
|
});
|
|
7297
|
-
var ApiGitDiscardRoute = Route$
|
|
7869
|
+
var ApiGitDiscardRoute = Route$39.update({
|
|
7298
7870
|
id: "/api/git-discard",
|
|
7299
7871
|
path: "/api/git-discard",
|
|
7300
|
-
getParentRoute: () => Route$
|
|
7872
|
+
getParentRoute: () => Route$53
|
|
7301
7873
|
});
|
|
7302
|
-
var ApiGitDiffRoute = Route$
|
|
7874
|
+
var ApiGitDiffRoute = Route$38.update({
|
|
7303
7875
|
id: "/api/git-diff",
|
|
7304
7876
|
path: "/api/git-diff",
|
|
7305
|
-
getParentRoute: () => Route$
|
|
7877
|
+
getParentRoute: () => Route$53
|
|
7878
|
+
});
|
|
7879
|
+
var ApiGitCommitRemoteUrlRoute = Route$37.update({
|
|
7880
|
+
id: "/api/git-commit-remote-url",
|
|
7881
|
+
path: "/api/git-commit-remote-url",
|
|
7882
|
+
getParentRoute: () => Route$53
|
|
7306
7883
|
});
|
|
7307
|
-
var ApiGitCommitMessageRoute = Route$
|
|
7884
|
+
var ApiGitCommitMessageRoute = Route$36.update({
|
|
7308
7885
|
id: "/api/git-commit-message",
|
|
7309
7886
|
path: "/api/git-commit-message",
|
|
7310
|
-
getParentRoute: () => Route$
|
|
7887
|
+
getParentRoute: () => Route$53
|
|
7311
7888
|
});
|
|
7312
|
-
var
|
|
7889
|
+
var ApiGitCommitFilesRoute = Route$35.update({
|
|
7890
|
+
id: "/api/git-commit-files",
|
|
7891
|
+
path: "/api/git-commit-files",
|
|
7892
|
+
getParentRoute: () => Route$53
|
|
7893
|
+
});
|
|
7894
|
+
var ApiGitCommitDiffRoute = Route$34.update({
|
|
7895
|
+
id: "/api/git-commit-diff",
|
|
7896
|
+
path: "/api/git-commit-diff",
|
|
7897
|
+
getParentRoute: () => Route$53
|
|
7898
|
+
});
|
|
7899
|
+
var ApiGitCommitActionRoute = Route$33.update({
|
|
7900
|
+
id: "/api/git-commit-action",
|
|
7901
|
+
path: "/api/git-commit-action",
|
|
7902
|
+
getParentRoute: () => Route$53
|
|
7903
|
+
});
|
|
7904
|
+
var ApiGitCommitRoute = Route$32.update({
|
|
7313
7905
|
id: "/api/git-commit",
|
|
7314
7906
|
path: "/api/git-commit",
|
|
7315
|
-
getParentRoute: () => Route$
|
|
7907
|
+
getParentRoute: () => Route$53
|
|
7316
7908
|
});
|
|
7317
|
-
var ApiGitCheckoutRoute = Route$
|
|
7909
|
+
var ApiGitCheckoutRoute = Route$31.update({
|
|
7318
7910
|
id: "/api/git-checkout",
|
|
7319
7911
|
path: "/api/git-checkout",
|
|
7320
|
-
getParentRoute: () => Route$
|
|
7912
|
+
getParentRoute: () => Route$53
|
|
7321
7913
|
});
|
|
7322
|
-
var ApiGitChangesRoute = Route$
|
|
7914
|
+
var ApiGitChangesRoute = Route$30.update({
|
|
7323
7915
|
id: "/api/git-changes",
|
|
7324
7916
|
path: "/api/git-changes",
|
|
7325
|
-
getParentRoute: () => Route$
|
|
7917
|
+
getParentRoute: () => Route$53
|
|
7326
7918
|
});
|
|
7327
|
-
var ApiFileCompletionsRoute = Route$
|
|
7919
|
+
var ApiFileCompletionsRoute = Route$29.update({
|
|
7328
7920
|
id: "/api/file-completions",
|
|
7329
7921
|
path: "/api/file-completions",
|
|
7330
|
-
getParentRoute: () => Route$
|
|
7922
|
+
getParentRoute: () => Route$53
|
|
7331
7923
|
});
|
|
7332
|
-
var ApiDirectorySessionsIndexesRoute = Route$
|
|
7924
|
+
var ApiDirectorySessionsIndexesRoute = Route$28.update({
|
|
7333
7925
|
id: "/api/directory-sessions-indexes",
|
|
7334
7926
|
path: "/api/directory-sessions-indexes",
|
|
7335
|
-
getParentRoute: () => Route$
|
|
7927
|
+
getParentRoute: () => Route$53
|
|
7336
7928
|
});
|
|
7337
|
-
var ApiDirectorySessionsIndexRoute = Route$
|
|
7929
|
+
var ApiDirectorySessionsIndexRoute = Route$27.update({
|
|
7338
7930
|
id: "/api/directory-sessions-index",
|
|
7339
7931
|
path: "/api/directory-sessions-index",
|
|
7340
|
-
getParentRoute: () => Route$
|
|
7932
|
+
getParentRoute: () => Route$53
|
|
7341
7933
|
});
|
|
7342
|
-
var ApiDirectorySessionsRoute = Route$
|
|
7934
|
+
var ApiDirectorySessionsRoute = Route$26.update({
|
|
7343
7935
|
id: "/api/directory-sessions",
|
|
7344
7936
|
path: "/api/directory-sessions",
|
|
7345
|
-
getParentRoute: () => Route$
|
|
7937
|
+
getParentRoute: () => Route$53
|
|
7346
7938
|
});
|
|
7347
|
-
var ApiDirectorySearchRoute = Route$
|
|
7939
|
+
var ApiDirectorySearchRoute = Route$25.update({
|
|
7348
7940
|
id: "/api/directory-search",
|
|
7349
7941
|
path: "/api/directory-search",
|
|
7350
|
-
getParentRoute: () => Route$
|
|
7942
|
+
getParentRoute: () => Route$53
|
|
7351
7943
|
});
|
|
7352
|
-
var ApiAbortRoute = Route$
|
|
7944
|
+
var ApiAbortRoute = Route$24.update({
|
|
7353
7945
|
id: "/api/abort",
|
|
7354
7946
|
path: "/api/abort",
|
|
7355
|
-
getParentRoute: () => Route$
|
|
7947
|
+
getParentRoute: () => Route$53
|
|
7356
7948
|
});
|
|
7357
|
-
var ApiUiIdRoute = Route$
|
|
7949
|
+
var ApiUiIdRoute = Route$23.update({
|
|
7358
7950
|
id: "/api/ui/$id",
|
|
7359
7951
|
path: "/api/ui/$id",
|
|
7360
|
-
getParentRoute: () => Route$
|
|
7952
|
+
getParentRoute: () => Route$53
|
|
7361
7953
|
});
|
|
7362
|
-
var ApiSettingsHideThinkingRoute = Route$
|
|
7954
|
+
var ApiSettingsHideThinkingRoute = Route$22.update({
|
|
7363
7955
|
id: "/api/settings/hide-thinking",
|
|
7364
7956
|
path: "/api/settings/hide-thinking",
|
|
7365
|
-
getParentRoute: () => Route$
|
|
7957
|
+
getParentRoute: () => Route$53
|
|
7366
7958
|
});
|
|
7367
|
-
var ApiSessionsDeleteRoute = Route$
|
|
7959
|
+
var ApiSessionsDeleteRoute = Route$21.update({
|
|
7368
7960
|
id: "/api/sessions/delete",
|
|
7369
7961
|
path: "/api/sessions/delete",
|
|
7370
|
-
getParentRoute: () => Route$
|
|
7962
|
+
getParentRoute: () => Route$53
|
|
7371
7963
|
});
|
|
7372
|
-
var ApiSessionTreeRoute = Route$
|
|
7964
|
+
var ApiSessionTreeRoute = Route$20.update({
|
|
7373
7965
|
id: "/api/session/tree",
|
|
7374
7966
|
path: "/api/session/tree",
|
|
7375
|
-
getParentRoute: () => Route$
|
|
7967
|
+
getParentRoute: () => Route$53
|
|
7376
7968
|
});
|
|
7377
|
-
var ApiSessionSelectRoute = Route$
|
|
7969
|
+
var ApiSessionSelectRoute = Route$19.update({
|
|
7378
7970
|
id: "/api/session/select",
|
|
7379
7971
|
path: "/api/session/select",
|
|
7380
|
-
getParentRoute: () => Route$
|
|
7972
|
+
getParentRoute: () => Route$53
|
|
7381
7973
|
});
|
|
7382
|
-
var ApiSessionRenameRoute = Route$
|
|
7974
|
+
var ApiSessionRenameRoute = Route$18.update({
|
|
7383
7975
|
id: "/api/session/rename",
|
|
7384
7976
|
path: "/api/session/rename",
|
|
7385
|
-
getParentRoute: () => Route$
|
|
7977
|
+
getParentRoute: () => Route$53
|
|
7978
|
+
});
|
|
7979
|
+
var ApiSessionReadStateRoute = Route$17.update({
|
|
7980
|
+
id: "/api/session/read-state",
|
|
7981
|
+
path: "/api/session/read-state",
|
|
7982
|
+
getParentRoute: () => Route$53
|
|
7386
7983
|
});
|
|
7387
7984
|
var ApiSessionNewRoute = Route$16.update({
|
|
7388
7985
|
id: "/api/session/new",
|
|
7389
7986
|
path: "/api/session/new",
|
|
7390
|
-
getParentRoute: () => Route$
|
|
7987
|
+
getParentRoute: () => Route$53
|
|
7391
7988
|
});
|
|
7392
7989
|
var ApiSessionMoveRoute = Route$15.update({
|
|
7393
7990
|
id: "/api/session/move",
|
|
7394
7991
|
path: "/api/session/move",
|
|
7395
|
-
getParentRoute: () => Route$
|
|
7992
|
+
getParentRoute: () => Route$53
|
|
7396
7993
|
});
|
|
7397
7994
|
var ApiSessionHistoryRoute = Route$14.update({
|
|
7398
7995
|
id: "/api/session/history",
|
|
7399
7996
|
path: "/api/session/history",
|
|
7400
|
-
getParentRoute: () => Route$
|
|
7997
|
+
getParentRoute: () => Route$53
|
|
7401
7998
|
});
|
|
7402
7999
|
var ApiSessionForkRoute = Route$13.update({
|
|
7403
8000
|
id: "/api/session/fork",
|
|
7404
8001
|
path: "/api/session/fork",
|
|
7405
|
-
getParentRoute: () => Route$
|
|
8002
|
+
getParentRoute: () => Route$53
|
|
7406
8003
|
});
|
|
7407
8004
|
var ApiSessionDeleteRoute = Route$12.update({
|
|
7408
8005
|
id: "/api/session/delete",
|
|
7409
8006
|
path: "/api/session/delete",
|
|
7410
|
-
getParentRoute: () => Route$
|
|
8007
|
+
getParentRoute: () => Route$53
|
|
7411
8008
|
});
|
|
7412
8009
|
var ApiSessionCloneRoute = Route$11.update({
|
|
7413
8010
|
id: "/api/session/clone",
|
|
7414
8011
|
path: "/api/session/clone",
|
|
7415
|
-
getParentRoute: () => Route$
|
|
8012
|
+
getParentRoute: () => Route$53
|
|
7416
8013
|
});
|
|
7417
8014
|
var ApiPendingMessagesReorderRoute = Route$10.update({
|
|
7418
8015
|
id: "/api/pending-messages/reorder",
|
|
7419
8016
|
path: "/api/pending-messages/reorder",
|
|
7420
|
-
getParentRoute: () => Route$
|
|
8017
|
+
getParentRoute: () => Route$53
|
|
7421
8018
|
});
|
|
7422
8019
|
var ApiPendingMessageRemoveRoute = Route$9.update({
|
|
7423
8020
|
id: "/api/pending-message/remove",
|
|
7424
8021
|
path: "/api/pending-message/remove",
|
|
7425
|
-
getParentRoute: () => Route$
|
|
8022
|
+
getParentRoute: () => Route$53
|
|
7426
8023
|
});
|
|
7427
8024
|
var ApiFilesTreeRoute = Route$8.update({
|
|
7428
8025
|
id: "/api/files/tree",
|
|
7429
8026
|
path: "/api/files/tree",
|
|
7430
|
-
getParentRoute: () => Route$
|
|
8027
|
+
getParentRoute: () => Route$53
|
|
7431
8028
|
});
|
|
7432
8029
|
var ApiFilesReadRoute = Route$7.update({
|
|
7433
8030
|
id: "/api/files/read",
|
|
7434
8031
|
path: "/api/files/read",
|
|
7435
|
-
getParentRoute: () => Route$
|
|
8032
|
+
getParentRoute: () => Route$53
|
|
7436
8033
|
});
|
|
7437
8034
|
var ApiDirectoryResolveRoute = Route$6.update({
|
|
7438
8035
|
id: "/api/directory/resolve",
|
|
7439
8036
|
path: "/api/directory/resolve",
|
|
7440
|
-
getParentRoute: () => Route$
|
|
8037
|
+
getParentRoute: () => Route$53
|
|
7441
8038
|
});
|
|
7442
8039
|
var ApiDirectorySessionsCleanupRoute = Route$5.update({
|
|
7443
8040
|
id: "/cleanup",
|
|
@@ -7447,22 +8044,22 @@ var ApiDirectorySessionsCleanupRoute = Route$5.update({
|
|
|
7447
8044
|
var ApiAuthProvidersRoute = Route$4.update({
|
|
7448
8045
|
id: "/api/auth/providers",
|
|
7449
8046
|
path: "/api/auth/providers",
|
|
7450
|
-
getParentRoute: () => Route$
|
|
8047
|
+
getParentRoute: () => Route$53
|
|
7451
8048
|
});
|
|
7452
8049
|
var ApiAuthOauthRoute = Route$3.update({
|
|
7453
8050
|
id: "/api/auth/oauth",
|
|
7454
8051
|
path: "/api/auth/oauth",
|
|
7455
|
-
getParentRoute: () => Route$
|
|
8052
|
+
getParentRoute: () => Route$53
|
|
7456
8053
|
});
|
|
7457
8054
|
var ApiAuthLogoutRoute = Route$2.update({
|
|
7458
8055
|
id: "/api/auth/logout",
|
|
7459
8056
|
path: "/api/auth/logout",
|
|
7460
|
-
getParentRoute: () => Route$
|
|
8057
|
+
getParentRoute: () => Route$53
|
|
7461
8058
|
});
|
|
7462
8059
|
var ApiAuthApiKeyRoute = Route$1.update({
|
|
7463
8060
|
id: "/api/auth/api-key",
|
|
7464
8061
|
path: "/api/auth/api-key",
|
|
7465
|
-
getParentRoute: () => Route$
|
|
8062
|
+
getParentRoute: () => Route$53
|
|
7466
8063
|
});
|
|
7467
8064
|
var ApiSessionTreeLabelRoute = Route.update({
|
|
7468
8065
|
id: "/label",
|
|
@@ -7484,7 +8081,11 @@ var rootRouteChildren = {
|
|
|
7484
8081
|
ApiGitChangesRoute,
|
|
7485
8082
|
ApiGitCheckoutRoute,
|
|
7486
8083
|
ApiGitCommitRoute,
|
|
8084
|
+
ApiGitCommitActionRoute,
|
|
8085
|
+
ApiGitCommitDiffRoute,
|
|
8086
|
+
ApiGitCommitFilesRoute,
|
|
7487
8087
|
ApiGitCommitMessageRoute,
|
|
8088
|
+
ApiGitCommitRemoteUrlRoute,
|
|
7488
8089
|
ApiGitDiffRoute,
|
|
7489
8090
|
ApiGitDiscardRoute,
|
|
7490
8091
|
ApiGitPullRoute,
|
|
@@ -7514,6 +8115,7 @@ var rootRouteChildren = {
|
|
|
7514
8115
|
ApiSessionHistoryRoute,
|
|
7515
8116
|
ApiSessionMoveRoute,
|
|
7516
8117
|
ApiSessionNewRoute,
|
|
8118
|
+
ApiSessionReadStateRoute,
|
|
7517
8119
|
ApiSessionRenameRoute,
|
|
7518
8120
|
ApiSessionSelectRoute,
|
|
7519
8121
|
ApiSessionTreeRoute: ApiSessionTreeRoute._addFileChildren(ApiSessionTreeRouteChildren),
|
|
@@ -7521,7 +8123,7 @@ var rootRouteChildren = {
|
|
|
7521
8123
|
ApiSettingsHideThinkingRoute,
|
|
7522
8124
|
ApiUiIdRoute
|
|
7523
8125
|
};
|
|
7524
|
-
var routeTree = Route$
|
|
8126
|
+
var routeTree = Route$53._addFileChildren(rootRouteChildren)._addFileTypes();
|
|
7525
8127
|
function getRouter() {
|
|
7526
8128
|
const queryClient = new QueryClient({ defaultOptions: { queries: {
|
|
7527
8129
|
retry: 1,
|