codesesh 1.0.2 → 1.0.4
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/README.md +18 -10
- package/dist/chunk-3SXCTDD6.js +326 -0
- package/dist/chunk-3SXCTDD6.js.map +1 -0
- package/dist/chunk-BYB77UAJ.js +6054 -0
- package/dist/chunk-BYB77UAJ.js.map +1 -0
- package/dist/{chunk-PROMURPM.js → chunk-G4HRD3AR.js} +13 -8
- package/dist/chunk-G4HRD3AR.js.map +1 -0
- package/dist/chunk-MBZ4VV4C.js +670 -0
- package/dist/chunk-MBZ4VV4C.js.map +1 -0
- package/dist/chunk-QH2HOXJH.js +2 -0
- package/dist/chunk-RF3EEWPH.js +17 -0
- package/dist/chunk-RF3EEWPH.js.map +1 -0
- package/dist/chunk-W4PZHL2C.js +2035 -0
- package/dist/chunk-W4PZHL2C.js.map +1 -0
- package/dist/chunk-YCUN52HA.js +8422 -0
- package/dist/chunk-YCUN52HA.js.map +1 -0
- package/dist/discovery-K3GLISI6.js +102 -0
- package/dist/discovery-K3GLISI6.js.map +1 -0
- package/dist/index.js +3016 -1392
- package/dist/index.js.map +1 -1
- package/dist/project-identity-worker.js +29 -0
- package/dist/project-identity-worker.js.map +1 -0
- package/dist/scan-refresh-worker.js +129 -139
- package/dist/scan-refresh-worker.js.map +1 -1
- package/dist/search-index-worker.js +39 -13
- package/dist/search-index-worker.js.map +1 -1
- package/dist/smart-tag-worker.js +8 -5
- package/dist/smart-tag-worker.js.map +1 -1
- package/dist/web/assets/InteractiveReceipt-Dk50TBsH.js +1 -0
- package/dist/web/assets/OverviewScreen-5hvQVp4H.js +1 -0
- package/dist/web/assets/{PrismHighlighter-BZkkX0AU.js → PrismHighlighter-B1a2dPJO.js} +2 -2
- package/dist/web/assets/Projects-Cy_v2yep.js +1 -0
- package/dist/web/assets/SearchResultsPanel-DfheEwpz.js +1 -0
- package/dist/web/assets/SessionDetail-DRI8R3st.js +53 -0
- package/dist/web/assets/api-GP9UCedC.js +1 -0
- package/dist/web/assets/contract-xJyW5u7a.js +2 -0
- package/dist/web/assets/index-Bd-YkWkZ.css +1 -0
- package/dist/web/assets/index-DEjvzumm.js +1410 -0
- package/dist/web/assets/panel-ND0J63d3.js +1 -0
- package/dist/web/assets/{session-indexes-0oT5HSS5.js → session-indexes-BsgjUoc1.js} +2 -2
- package/dist/web/assets/utils-C7BqyxxV.js +1 -0
- package/dist/web/index.html +7 -11
- package/package.json +4 -10
- package/dist/chunk-PROMURPM.js.map +0 -1
- package/dist/chunk-VAUC2W7I.js +0 -16119
- package/dist/chunk-VAUC2W7I.js.map +0 -1
- package/dist/dist-6QTGTYZT.js +0 -175
- package/dist/web/assets/ErrorBoundary-D11tWzfn.js +0 -1
- package/dist/web/assets/InteractiveReceipt-DYGyHeZd.js +0 -1
- package/dist/web/assets/OverviewScreen-DriPmCam.js +0 -1
- package/dist/web/assets/Projects-BPDIcUBK.js +0 -1
- package/dist/web/assets/SearchFilterBar-Bx73B5e9.js +0 -1
- package/dist/web/assets/SearchResultsPanel-A6_3TPhW.js +0 -1
- package/dist/web/assets/SessionDetail-BnpvDwtH.js +0 -54
- package/dist/web/assets/SmartTagChips-ux6idUGJ.js +0 -1
- package/dist/web/assets/agents-BkRP_ww3.js +0 -1
- package/dist/web/assets/code-metrics-UYFsCC7E.js +0 -1
- package/dist/web/assets/contract-V6QuD0UY.js +0 -1
- package/dist/web/assets/index-99ZxpV2y.js +0 -1410
- package/dist/web/assets/index-B2RqUgZ5.css +0 -1
- package/dist/web/assets/panel-C-gc79Gz.js +0 -1
- package/dist/web/assets/session-title-DdtlxtlR.js +0 -1
- package/dist/web/assets/utils-DgUgu15E.js +0 -1
- /package/dist/{dist-6QTGTYZT.js.map → chunk-QH2HOXJH.js.map} +0 -0
|
@@ -0,0 +1,2035 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ../core/dist/chunk-AXHUQ6MM.mjs
|
|
4
|
+
var SMART_TAGS = [
|
|
5
|
+
"bugfix",
|
|
6
|
+
"refactoring",
|
|
7
|
+
"feature-dev",
|
|
8
|
+
"testing",
|
|
9
|
+
"docs",
|
|
10
|
+
"git-ops",
|
|
11
|
+
"build-deploy",
|
|
12
|
+
"exploration",
|
|
13
|
+
"planning"
|
|
14
|
+
];
|
|
15
|
+
function isSmartTag(value) {
|
|
16
|
+
return SMART_TAGS.some((tag) => tag === value);
|
|
17
|
+
}
|
|
18
|
+
function assertIdentifiedSessionHead(session) {
|
|
19
|
+
if (session.project_identity) return;
|
|
20
|
+
throw new Error(
|
|
21
|
+
`Session ${session.reference.agentName}/${session.reference.sessionId} is missing project_identity`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
function toPublicSessionHead(session) {
|
|
25
|
+
const {
|
|
26
|
+
model_usage: _modelUsage,
|
|
27
|
+
project_identity_resolver_revision: _resolverRevision,
|
|
28
|
+
project_identity_input_signature: _identityInputSignature,
|
|
29
|
+
smart_tags_source_updated_at: _smartTagsSourceUpdatedAt,
|
|
30
|
+
smart_tags_classifier_revision: _classifierRevision,
|
|
31
|
+
...publicSession
|
|
32
|
+
} = session;
|
|
33
|
+
return publicSession;
|
|
34
|
+
}
|
|
35
|
+
function toPublicReferencedSessionHead(item) {
|
|
36
|
+
return { ...item, session: toPublicSessionHead(item.session) };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ../core/dist/chunk-EY7UDYHJ.mjs
|
|
40
|
+
var SMART_TAG_CLASSIFIER_REVISION = "smart-tags-v1";
|
|
41
|
+
var USER_RULES = [
|
|
42
|
+
["bugfix", /\b(fix|bug|error|crash|exception|fail(?:ed|ure)?)\b|修复|错误|报错|崩溃|异常/i],
|
|
43
|
+
["refactoring", /\b(refactor|rename|simplify|clean up|cleanup)\b|重构|重命名|简化|清理/i],
|
|
44
|
+
["feature-dev", /\b(add|create|implement|new|support|build)\b|新增|创建|实现|增加|开发|支持/i],
|
|
45
|
+
["docs", /\b(document|documentation|readme|docs?)\b|文档|说明/i]
|
|
46
|
+
];
|
|
47
|
+
var TESTING_COMMAND_RE = /\b(pytest|vitest|jest|mocha|pnpm\s+test|npm\s+test|yarn\s+test)\b/i;
|
|
48
|
+
var GIT_COMMAND_RE = /\bgit\s+(push|commit|merge|branch|checkout|switch|rebase|tag)\b/i;
|
|
49
|
+
var BUILD_DEPLOY_COMMAND_RE = /\b((npm|pnpm|yarn|bun)\s+(run\s+)?build|docker|pm2|deploy|vercel|netlify)\b/i;
|
|
50
|
+
var DOC_PATH_RE = /\.(md|mdx|txt|rst|adoc)$/i;
|
|
51
|
+
var READ_TOOL_RE = /\b(read|grep|glob|websearch|web_search|search|find|rg)\b/i;
|
|
52
|
+
var EDIT_TOOL_RE = /\b(edit|write|apply_patch|patch|multiedit|notebookedit)\b/i;
|
|
53
|
+
var PLAN_TOOL_RE = /\b(enterplanmode|taskcreate|update_plan|plan)\b/i;
|
|
54
|
+
function getSmartTagSourceTimestamp(session) {
|
|
55
|
+
return session.time_updated ?? session.time_created;
|
|
56
|
+
}
|
|
57
|
+
function classifySessionTags(session) {
|
|
58
|
+
const tags = /* @__PURE__ */ new Set();
|
|
59
|
+
let readToolCount = 0;
|
|
60
|
+
let editToolCount = 0;
|
|
61
|
+
for (const message of session.messages) {
|
|
62
|
+
if (message.role === "user") {
|
|
63
|
+
const text = message.parts.map(partText).join("\n");
|
|
64
|
+
for (const [tag, pattern] of USER_RULES) {
|
|
65
|
+
if (pattern.test(text)) tags.add(tag);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const part of message.parts) {
|
|
69
|
+
if (part.type === "plan") tags.add("planning");
|
|
70
|
+
if (part.type !== "tool") continue;
|
|
71
|
+
const toolName = `${part.tool} ${part.title ?? ""}`;
|
|
72
|
+
const toolPayload = stringifyToolPayload(part);
|
|
73
|
+
if (PLAN_TOOL_RE.test(toolName)) tags.add("planning");
|
|
74
|
+
if (READ_TOOL_RE.test(toolName)) readToolCount += 1;
|
|
75
|
+
if (EDIT_TOOL_RE.test(toolName)) editToolCount += 1;
|
|
76
|
+
if (TESTING_COMMAND_RE.test(toolPayload)) tags.add("testing");
|
|
77
|
+
if (GIT_COMMAND_RE.test(toolPayload)) tags.add("git-ops");
|
|
78
|
+
if (BUILD_DEPLOY_COMMAND_RE.test(toolPayload)) tags.add("build-deploy");
|
|
79
|
+
if (hasEditedDocPath(part.state.input)) {
|
|
80
|
+
tags.add("docs");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (readToolCount >= 3 && editToolCount <= 1) {
|
|
85
|
+
tags.add("exploration");
|
|
86
|
+
}
|
|
87
|
+
return SMART_TAGS.filter((tag) => tags.has(tag));
|
|
88
|
+
}
|
|
89
|
+
function partText(part) {
|
|
90
|
+
return part.type === "text" || part.type === "reasoning" || part.type === "plan" ? part.text : "";
|
|
91
|
+
}
|
|
92
|
+
function stringifyToolPayload(part) {
|
|
93
|
+
return [part.tool, part.title, valueToText(part.state)].filter(Boolean).join("\n");
|
|
94
|
+
}
|
|
95
|
+
function valueToText(value) {
|
|
96
|
+
if (value == null) return "";
|
|
97
|
+
if (typeof value === "string") return value;
|
|
98
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
99
|
+
try {
|
|
100
|
+
return JSON.stringify(value);
|
|
101
|
+
} catch {
|
|
102
|
+
return "";
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function hasEditedDocPath(value) {
|
|
106
|
+
if (value == null) return false;
|
|
107
|
+
if (typeof value === "string") return DOC_PATH_RE.test(value);
|
|
108
|
+
if (Array.isArray(value)) return value.some(hasEditedDocPath);
|
|
109
|
+
if (typeof value !== "object") return false;
|
|
110
|
+
const record = value;
|
|
111
|
+
for (const key of ["path", "file", "filePath", "file_path", "targetPath", "target_path"]) {
|
|
112
|
+
const raw = record[key];
|
|
113
|
+
if (typeof raw === "string" && DOC_PATH_RE.test(raw)) return true;
|
|
114
|
+
}
|
|
115
|
+
return Object.values(record).some(hasEditedDocPath);
|
|
116
|
+
}
|
|
117
|
+
var WORKER_LOG_MESSAGE_TYPE = "codesesh.worker-log";
|
|
118
|
+
function isRecord(value) {
|
|
119
|
+
return value != null && typeof value === "object" && !Array.isArray(value);
|
|
120
|
+
}
|
|
121
|
+
function isWorkerLogMessage(value) {
|
|
122
|
+
if (!isRecord(value) || value.type !== WORKER_LOG_MESSAGE_TYPE) return false;
|
|
123
|
+
return typeof value.ts === "string" && value.ts.length > 0 && (value.level === "debug" || value.level === "info" || value.level === "warn" || value.level === "error") && typeof value.event === "string" && value.event.length > 0 && Number.isSafeInteger(value.pid) && Number(value.pid) > 0 && Number.isSafeInteger(value.threadId) && Number(value.threadId) >= 0 && isRecord(value.data);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ../core/dist/chunk-FDGCEOYE.mjs
|
|
127
|
+
function normalizeSessionReference(reference) {
|
|
128
|
+
return {
|
|
129
|
+
agentName: reference.agentName.trim().toLowerCase(),
|
|
130
|
+
sessionId: reference.sessionId
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function formatSessionReference(reference) {
|
|
134
|
+
const normalized = normalizeSessionReference(reference);
|
|
135
|
+
return `${normalized.agentName}/${normalized.sessionId}`;
|
|
136
|
+
}
|
|
137
|
+
function getSessionReferenceKey(reference) {
|
|
138
|
+
return formatSessionReference(reference);
|
|
139
|
+
}
|
|
140
|
+
function createSessionIdentity(reference) {
|
|
141
|
+
return {
|
|
142
|
+
reference: normalizeSessionReference(reference)
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function assertSessionIdentity(identity, agentName) {
|
|
146
|
+
const normalized = normalizeSessionReference(identity.reference);
|
|
147
|
+
const expectedAgentName = agentName?.trim().toLowerCase();
|
|
148
|
+
if (identity.reference.agentName !== normalized.agentName) {
|
|
149
|
+
throw new Error("Session reference is not normalized");
|
|
150
|
+
}
|
|
151
|
+
if (expectedAgentName != null && normalized.agentName !== expectedAgentName) {
|
|
152
|
+
throw new Error(
|
|
153
|
+
`Session reference agent "${normalized.agentName}" does not match "${expectedAgentName}"`
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function getSessionAgentKey(session) {
|
|
158
|
+
return normalizeSessionReference(session.reference).agentName;
|
|
159
|
+
}
|
|
160
|
+
function agentRoutePath(agentName) {
|
|
161
|
+
return `/${encodeURIComponent(agentName.trim().toLowerCase())}`;
|
|
162
|
+
}
|
|
163
|
+
function sessionRoutePath(reference) {
|
|
164
|
+
const normalized = normalizeSessionReference(reference);
|
|
165
|
+
return `${agentRoutePath(normalized.agentName)}/${encodeURIComponent(normalized.sessionId)}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ../core/dist/chunk-GHNYETRY.mjs
|
|
169
|
+
var FILE_TOOL_KINDS = {
|
|
170
|
+
read: "read",
|
|
171
|
+
read_file: "read",
|
|
172
|
+
read_file_v2: "read",
|
|
173
|
+
read_text_file: "read",
|
|
174
|
+
readfile: "read",
|
|
175
|
+
view_image: "read",
|
|
176
|
+
apply_patch: "edit",
|
|
177
|
+
edit: "edit",
|
|
178
|
+
edit_file: "edit",
|
|
179
|
+
edit_file_v2: "edit",
|
|
180
|
+
editfile: "edit",
|
|
181
|
+
multiedit: "edit",
|
|
182
|
+
notebookedit: "edit",
|
|
183
|
+
patch: "edit",
|
|
184
|
+
search_replace: "edit",
|
|
185
|
+
str_replace: "edit",
|
|
186
|
+
create_file: "write",
|
|
187
|
+
write: "write",
|
|
188
|
+
write_file: "write",
|
|
189
|
+
writefile: "write",
|
|
190
|
+
delete: "delete",
|
|
191
|
+
delete_file: "delete"
|
|
192
|
+
};
|
|
193
|
+
var PATCH_KINDS = {
|
|
194
|
+
edit_file: "edit",
|
|
195
|
+
update_file: "edit",
|
|
196
|
+
write_file: "write",
|
|
197
|
+
delete_file: "delete",
|
|
198
|
+
move_file: "edit"
|
|
199
|
+
};
|
|
200
|
+
function toRecord(value) {
|
|
201
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
return {};
|
|
205
|
+
}
|
|
206
|
+
function looksLikeFilePath(value) {
|
|
207
|
+
const text = value.trim();
|
|
208
|
+
if (!text || text.length > 300 || text.includes("\n")) return false;
|
|
209
|
+
if (/^[a-z]+:\/\//i.test(text) || /[<>{}]/.test(text)) return false;
|
|
210
|
+
if (text.startsWith("/") || text.startsWith("./") || text.startsWith("../")) return true;
|
|
211
|
+
if (text.startsWith("~/") || text.includes("/") || text.includes("\\")) return true;
|
|
212
|
+
return /^[A-Za-z0-9_.@-]+\.[A-Za-z0-9_-]+$/.test(text);
|
|
213
|
+
}
|
|
214
|
+
function isPathKey(key) {
|
|
215
|
+
const normalized = key.trim().toLowerCase();
|
|
216
|
+
if (!normalized) return false;
|
|
217
|
+
if (normalized.includes("command") || normalized.includes("content") || normalized.includes("text") || normalized.includes("prompt") || normalized.includes("url") || normalized.includes("body") || normalized.includes("title") || normalized.includes("description") || normalized === "cwd" || normalized === "workdir" || normalized === "directory") {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
return normalized.includes("file") || normalized.includes("path");
|
|
221
|
+
}
|
|
222
|
+
function collectPaths(value, key, paths, depth = 0) {
|
|
223
|
+
if (value == null || depth > 4) return;
|
|
224
|
+
if (typeof value === "string") {
|
|
225
|
+
if (isPathKey(key) && looksLikeFilePath(value)) paths.add(value.trim());
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (Array.isArray(value)) {
|
|
229
|
+
for (const item of value) collectPaths(item, key, paths, depth + 1);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (typeof value === "object") {
|
|
233
|
+
for (const [nestedKey, nested] of Object.entries(value)) {
|
|
234
|
+
collectPaths(nested, nestedKey, paths, depth + 1);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
function extractPatchOperations(input) {
|
|
239
|
+
const record = toRecord(input);
|
|
240
|
+
const content = Array.isArray(input) ? input : Array.isArray(record.content) ? record.content : [];
|
|
241
|
+
return content.flatMap((entry) => {
|
|
242
|
+
const patch = toRecord(entry);
|
|
243
|
+
const kind = typeof patch.type === "string" ? PATCH_KINDS[patch.type] : void 0;
|
|
244
|
+
const pathValue = patch.path || patch.old_path;
|
|
245
|
+
const path = typeof pathValue === "string" ? pathValue.trim() : "";
|
|
246
|
+
return kind && path ? [{ kind, path }] : [];
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
function classifyFileTool(part) {
|
|
250
|
+
return FILE_TOOL_KINDS[part.tool.trim().toLowerCase()] ?? null;
|
|
251
|
+
}
|
|
252
|
+
function extractFileToolOperations(part) {
|
|
253
|
+
const patchOperations = extractPatchOperations(part.state.input);
|
|
254
|
+
if (patchOperations.length > 0) return patchOperations;
|
|
255
|
+
const kind = classifyFileTool(part);
|
|
256
|
+
if (!kind) return [];
|
|
257
|
+
const paths = /* @__PURE__ */ new Set();
|
|
258
|
+
collectPaths(part.state.input, "", paths);
|
|
259
|
+
return [...paths].map((path) => ({ kind, path }));
|
|
260
|
+
}
|
|
261
|
+
function mergeSessionsUpdatedEvents(previous, next) {
|
|
262
|
+
const changedSessionHeads = /* @__PURE__ */ new Map();
|
|
263
|
+
const projectionRelatedSessionHeads = /* @__PURE__ */ new Map();
|
|
264
|
+
const projectionSessionOrder = /* @__PURE__ */ new Map();
|
|
265
|
+
const newSessionRefs = /* @__PURE__ */ new Map();
|
|
266
|
+
const removedSessionRefs = /* @__PURE__ */ new Map();
|
|
267
|
+
const sessionKey2 = (agentName, sessionId) => `${agentName}\0${sessionId}`;
|
|
268
|
+
const addChanged = (item) => {
|
|
269
|
+
const key = sessionKey2(item.reference.agentName, item.reference.sessionId);
|
|
270
|
+
removedSessionRefs.delete(key);
|
|
271
|
+
projectionRelatedSessionHeads.delete(key);
|
|
272
|
+
changedSessionHeads.set(key, item);
|
|
273
|
+
};
|
|
274
|
+
const addProjectionRelated = (item) => {
|
|
275
|
+
const key = sessionKey2(item.reference.agentName, item.reference.sessionId);
|
|
276
|
+
if (changedSessionHeads.has(key) || removedSessionRefs.has(key)) return;
|
|
277
|
+
projectionRelatedSessionHeads.set(key, item);
|
|
278
|
+
};
|
|
279
|
+
const addNew = (item) => {
|
|
280
|
+
const key = sessionKey2(item.agentName, item.sessionId);
|
|
281
|
+
removedSessionRefs.delete(key);
|
|
282
|
+
newSessionRefs.set(key, item);
|
|
283
|
+
};
|
|
284
|
+
const addProjectionOrder = (item) => {
|
|
285
|
+
const key = sessionKey2(item.agentName, item.sessionId);
|
|
286
|
+
projectionSessionOrder.delete(key);
|
|
287
|
+
projectionSessionOrder.set(key, item);
|
|
288
|
+
};
|
|
289
|
+
const addRemoved = (item) => {
|
|
290
|
+
const key = sessionKey2(item.agentName, item.sessionId);
|
|
291
|
+
changedSessionHeads.delete(key);
|
|
292
|
+
projectionRelatedSessionHeads.delete(key);
|
|
293
|
+
projectionSessionOrder.delete(key);
|
|
294
|
+
newSessionRefs.delete(key);
|
|
295
|
+
removedSessionRefs.set(key, item);
|
|
296
|
+
};
|
|
297
|
+
for (const item of previous.newSessionRefs) addNew(item);
|
|
298
|
+
for (const item of previous.projectionRelatedSessionHeads ?? []) addProjectionRelated(item);
|
|
299
|
+
for (const item of previous.projectionSessionOrder ?? []) addProjectionOrder(item);
|
|
300
|
+
for (const item of previous.changedSessionHeads) addChanged(item);
|
|
301
|
+
for (const item of previous.removedSessionRefs) addRemoved(item);
|
|
302
|
+
for (const item of next.newSessionRefs) addNew(item);
|
|
303
|
+
for (const item of next.projectionRelatedSessionHeads ?? []) addProjectionRelated(item);
|
|
304
|
+
for (const item of next.projectionSessionOrder ?? []) addProjectionOrder(item);
|
|
305
|
+
for (const item of next.changedSessionHeads) addChanged(item);
|
|
306
|
+
for (const item of next.removedSessionRefs) addRemoved(item);
|
|
307
|
+
return {
|
|
308
|
+
type: "sessions-updated",
|
|
309
|
+
changedAgents: Array.from(/* @__PURE__ */ new Set([...previous.changedAgents, ...next.changedAgents])),
|
|
310
|
+
newSessionRefs: [...newSessionRefs.values()],
|
|
311
|
+
totalSessions: next.totalSessions,
|
|
312
|
+
timestamp: next.timestamp,
|
|
313
|
+
changedSessionHeads: [...changedSessionHeads.values()],
|
|
314
|
+
projectionRelatedSessionHeads: [...projectionRelatedSessionHeads.values()],
|
|
315
|
+
projectionSessionOrder: [...projectionSessionOrder.values()],
|
|
316
|
+
removedSessionRefs: [...removedSessionRefs.values()]
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function startOfCalendarDay(timestamp) {
|
|
320
|
+
const date = new Date(timestamp);
|
|
321
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
322
|
+
}
|
|
323
|
+
function addCalendarDays(timestamp, days) {
|
|
324
|
+
const date = new Date(timestamp);
|
|
325
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days).getTime();
|
|
326
|
+
}
|
|
327
|
+
function toCalendarDayNumber(timestamp) {
|
|
328
|
+
const date = new Date(timestamp);
|
|
329
|
+
return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) / 864e5;
|
|
330
|
+
}
|
|
331
|
+
function countCalendarDays(from, to) {
|
|
332
|
+
return Math.max(1, toCalendarDayNumber(to) - toCalendarDayNumber(from) + 1);
|
|
333
|
+
}
|
|
334
|
+
function toCalendarDayKey(timestamp) {
|
|
335
|
+
const date = new Date(timestamp);
|
|
336
|
+
return `${String(date.getFullYear()).padStart(4, "0")}-${String(date.getMonth() + 1).padStart(
|
|
337
|
+
2,
|
|
338
|
+
"0"
|
|
339
|
+
)}-${String(date.getDate()).padStart(2, "0")}`;
|
|
340
|
+
}
|
|
341
|
+
var PROJECT_IDENTITY_KINDS = [
|
|
342
|
+
"git_remote",
|
|
343
|
+
"git_common_dir",
|
|
344
|
+
"manifest_path",
|
|
345
|
+
"synthetic",
|
|
346
|
+
"path",
|
|
347
|
+
"loose"
|
|
348
|
+
];
|
|
349
|
+
var KIND_LOOKUP = new Set(PROJECT_IDENTITY_KINDS);
|
|
350
|
+
function isProjectIdentityKind(value) {
|
|
351
|
+
return KIND_LOOKUP.has(value);
|
|
352
|
+
}
|
|
353
|
+
function getProjectIdentityKey(identity) {
|
|
354
|
+
return `${identity.kind}:${identity.key}`;
|
|
355
|
+
}
|
|
356
|
+
function matchesProjectIdentity(identity, expected) {
|
|
357
|
+
return identity?.kind === expected.kind && identity.key === expected.key;
|
|
358
|
+
}
|
|
359
|
+
function getProjectAgentKey(projectIdentityKey, agentName) {
|
|
360
|
+
return `${projectIdentityKey}\0${agentName.toLowerCase()}`;
|
|
361
|
+
}
|
|
362
|
+
function compareSessionActivityDesc(a, b) {
|
|
363
|
+
return (b.time_updated ?? b.time_created) - (a.time_updated ?? a.time_created);
|
|
364
|
+
}
|
|
365
|
+
function sortSessionsByActivity(sessions) {
|
|
366
|
+
for (let index = 1; index < sessions.length; index += 1) {
|
|
367
|
+
if (compareSessionActivityDesc(sessions[index - 1], sessions[index]) > 0) {
|
|
368
|
+
return [...sessions].sort(compareSessionActivityDesc);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return [...sessions];
|
|
372
|
+
}
|
|
373
|
+
function mergeSortedSessions(shards) {
|
|
374
|
+
const active = shards.filter((shard) => shard.length > 0);
|
|
375
|
+
if (active.length === 0) return [];
|
|
376
|
+
if (active.length === 1) return [...active[0]];
|
|
377
|
+
const total = active.reduce((sum, shard) => sum + shard.length, 0);
|
|
378
|
+
const merged = [];
|
|
379
|
+
const cursors = Array.from({ length: active.length }, () => 0);
|
|
380
|
+
for (let position = 0; position < total; position += 1) {
|
|
381
|
+
let pick = -1;
|
|
382
|
+
for (let shard = 0; shard < active.length; shard += 1) {
|
|
383
|
+
const cursor = cursors[shard];
|
|
384
|
+
if (cursor >= active[shard].length) continue;
|
|
385
|
+
if (pick === -1 || compareSessionActivityDesc(active[shard][cursor], active[pick][cursors[pick]]) < 0) {
|
|
386
|
+
pick = shard;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
merged.push(active[pick][cursors[pick]]);
|
|
390
|
+
cursors[pick] += 1;
|
|
391
|
+
}
|
|
392
|
+
return merged;
|
|
393
|
+
}
|
|
394
|
+
function pushMapValue(map, key, value) {
|
|
395
|
+
const current = map.get(key);
|
|
396
|
+
if (current) {
|
|
397
|
+
current.push(value);
|
|
398
|
+
} else {
|
|
399
|
+
map.set(key, [value]);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function createSessionIndex(sourceSessions) {
|
|
403
|
+
const byRouteKey = /* @__PURE__ */ new Map();
|
|
404
|
+
const childrenByParentRouteKey = /* @__PURE__ */ new Map();
|
|
405
|
+
const byAgent = /* @__PURE__ */ new Map();
|
|
406
|
+
const byProjectIdentityKey = /* @__PURE__ */ new Map();
|
|
407
|
+
const byProjectAgentKey = /* @__PURE__ */ new Map();
|
|
408
|
+
for (const session of sourceSessions) {
|
|
409
|
+
const routeKey = getSessionReferenceKey(session.reference);
|
|
410
|
+
if (!byRouteKey.has(routeKey)) byRouteKey.set(routeKey, session);
|
|
411
|
+
if (session.parent_reference) {
|
|
412
|
+
pushMapValue(
|
|
413
|
+
childrenByParentRouteKey,
|
|
414
|
+
getSessionReferenceKey(session.parent_reference),
|
|
415
|
+
session
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
const sessionsByActivity = sortSessionsByActivity(sourceSessions);
|
|
420
|
+
for (const session of sessionsByActivity) {
|
|
421
|
+
const { agentName } = session.reference;
|
|
422
|
+
pushMapValue(byAgent, agentName, session);
|
|
423
|
+
const identity = session.project_identity;
|
|
424
|
+
if (!identity?.key) continue;
|
|
425
|
+
const projectIdentityKey = getProjectIdentityKey(identity);
|
|
426
|
+
pushMapValue(byProjectIdentityKey, projectIdentityKey, session);
|
|
427
|
+
pushMapValue(byProjectAgentKey, getProjectAgentKey(projectIdentityKey, agentName), session);
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
sourceSessions,
|
|
431
|
+
sessionsByActivity,
|
|
432
|
+
byRouteKey,
|
|
433
|
+
childrenByParentRouteKey,
|
|
434
|
+
byAgent,
|
|
435
|
+
byProjectIdentityKey,
|
|
436
|
+
byProjectAgentKey
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
function sessionKey(session) {
|
|
440
|
+
return getSessionReferenceKey(session.reference);
|
|
441
|
+
}
|
|
442
|
+
function parentKey(session) {
|
|
443
|
+
return session.parent_reference ? getSessionReferenceKey(session.parent_reference) : null;
|
|
444
|
+
}
|
|
445
|
+
function activityTime(session) {
|
|
446
|
+
return session.time_updated ?? session.time_created;
|
|
447
|
+
}
|
|
448
|
+
function hasActivityInWindow(session, from, to) {
|
|
449
|
+
const activity = activityTime(session);
|
|
450
|
+
return (from == null || activity >= from) && (to == null || activity <= to);
|
|
451
|
+
}
|
|
452
|
+
function ownStats(session) {
|
|
453
|
+
const stats = session.stats;
|
|
454
|
+
const cost = stats.total_cost ?? 0;
|
|
455
|
+
return {
|
|
456
|
+
messageCount: stats.message_count,
|
|
457
|
+
inputTokens: stats.total_input_tokens,
|
|
458
|
+
outputTokens: stats.total_output_tokens,
|
|
459
|
+
cacheReadTokens: stats.total_cache_read_tokens ?? 0,
|
|
460
|
+
cacheCreateTokens: stats.total_cache_create_tokens ?? 0,
|
|
461
|
+
totalTokens: stats.total_tokens ?? stats.total_input_tokens + stats.total_output_tokens,
|
|
462
|
+
cost,
|
|
463
|
+
costSource: cost > 0 ? stats.cost_source ?? "recorded" : void 0
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
function addStats(target, source) {
|
|
467
|
+
target.messageCount += source.messageCount;
|
|
468
|
+
target.inputTokens += source.inputTokens;
|
|
469
|
+
target.outputTokens += source.outputTokens;
|
|
470
|
+
target.cacheReadTokens += source.cacheReadTokens;
|
|
471
|
+
target.cacheCreateTokens += source.cacheCreateTokens;
|
|
472
|
+
target.totalTokens += source.totalTokens;
|
|
473
|
+
target.cost += source.cost;
|
|
474
|
+
if (source.costSource === "estimated") target.costSource = "estimated";
|
|
475
|
+
}
|
|
476
|
+
function rollUpSubtree(entry) {
|
|
477
|
+
const order = [];
|
|
478
|
+
const pending2 = [entry];
|
|
479
|
+
while (pending2.length > 0) {
|
|
480
|
+
const node = pending2.pop();
|
|
481
|
+
order.push(node);
|
|
482
|
+
for (const child of node.children) pending2.push(child);
|
|
483
|
+
}
|
|
484
|
+
for (let index = order.length - 1; index >= 0; index -= 1) {
|
|
485
|
+
const node = order[index];
|
|
486
|
+
const stats = node.inclusiveStats;
|
|
487
|
+
let descendants = 0;
|
|
488
|
+
for (const child of node.children) {
|
|
489
|
+
descendants += 1 + child.descendantCount;
|
|
490
|
+
addStats(stats, child.inclusiveStats);
|
|
491
|
+
}
|
|
492
|
+
if (stats.cost > 0 && stats.costSource == null) stats.costSource = "recorded";
|
|
493
|
+
node.descendantCount = descendants;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
function buildSessionTree(sessions) {
|
|
497
|
+
const byRouteKey = /* @__PURE__ */ new Map();
|
|
498
|
+
for (const session of sessions) {
|
|
499
|
+
const key = sessionKey(session);
|
|
500
|
+
if (byRouteKey.has(key)) continue;
|
|
501
|
+
byRouteKey.set(key, {
|
|
502
|
+
session,
|
|
503
|
+
children: [],
|
|
504
|
+
descendantCount: 0,
|
|
505
|
+
inclusiveStats: ownStats(session)
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
const nodes = [...byRouteKey.values()];
|
|
509
|
+
const chainTerminates = /* @__PURE__ */ new Map();
|
|
510
|
+
function reachesRoot(startKey) {
|
|
511
|
+
const path = [];
|
|
512
|
+
const onPath = /* @__PURE__ */ new Set();
|
|
513
|
+
let key = startKey;
|
|
514
|
+
let terminates = true;
|
|
515
|
+
while (key != null) {
|
|
516
|
+
const memo = chainTerminates.get(key);
|
|
517
|
+
if (memo != null) {
|
|
518
|
+
terminates = memo;
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
if (onPath.has(key)) {
|
|
522
|
+
terminates = false;
|
|
523
|
+
break;
|
|
524
|
+
}
|
|
525
|
+
onPath.add(key);
|
|
526
|
+
path.push(key);
|
|
527
|
+
const parent = parentKey(byRouteKey.get(key).session);
|
|
528
|
+
key = parent != null && byRouteKey.has(parent) ? parent : null;
|
|
529
|
+
}
|
|
530
|
+
for (const visited of path) chainTerminates.set(visited, terminates);
|
|
531
|
+
return terminates;
|
|
532
|
+
}
|
|
533
|
+
const mountStates = /* @__PURE__ */ new Map();
|
|
534
|
+
const roots = [];
|
|
535
|
+
const orphans = [];
|
|
536
|
+
const entries = [];
|
|
537
|
+
for (const node of nodes) {
|
|
538
|
+
const key = sessionKey(node.session);
|
|
539
|
+
const parent = parentKey(node.session);
|
|
540
|
+
const state = parent == null ? "root" : byRouteKey.has(parent) && reachesRoot(key) ? "mounted-child" : "orphan";
|
|
541
|
+
mountStates.set(key, state);
|
|
542
|
+
if (state === "mounted-child") {
|
|
543
|
+
byRouteKey.get(parent).children.push(node);
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
(state === "root" ? roots : orphans).push(node);
|
|
547
|
+
entries.push(node);
|
|
548
|
+
}
|
|
549
|
+
for (const entry of entries) rollUpSubtree(entry);
|
|
550
|
+
return {
|
|
551
|
+
roots,
|
|
552
|
+
orphans,
|
|
553
|
+
entries,
|
|
554
|
+
byRouteKey,
|
|
555
|
+
mountStateOf(session) {
|
|
556
|
+
return mountStates.get(sessionKey(session)) ?? (session.parent_reference ? "orphan" : "root");
|
|
557
|
+
}
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
function filterSessionTreeByActivityWindow(sessions, from, to, tree = buildSessionTree(sessions)) {
|
|
561
|
+
if (from == null && to == null) return sessions;
|
|
562
|
+
const pending2 = filterSessionTreeEntriesByActivityWindow(tree, from, to);
|
|
563
|
+
const visible = /* @__PURE__ */ new Set();
|
|
564
|
+
while (pending2.length > 0) {
|
|
565
|
+
const node = pending2.pop();
|
|
566
|
+
const key = sessionKey(node.session);
|
|
567
|
+
if (visible.has(key)) continue;
|
|
568
|
+
visible.add(key);
|
|
569
|
+
for (const child of node.children) pending2.push(child);
|
|
570
|
+
}
|
|
571
|
+
return sessions.filter((session) => visible.has(sessionKey(session)));
|
|
572
|
+
}
|
|
573
|
+
function filterSessionTreeEntriesByActivityWindow(tree, from, to) {
|
|
574
|
+
if (from == null && to == null) return tree.entries;
|
|
575
|
+
return tree.entries.filter((node) => hasActivityInWindow(node.session, from, to));
|
|
576
|
+
}
|
|
577
|
+
function createSessionHierarchyGraph(sessions) {
|
|
578
|
+
const sessionsByKey = /* @__PURE__ */ new Map();
|
|
579
|
+
for (const session of sessions) {
|
|
580
|
+
const key = sessionKey(session);
|
|
581
|
+
if (!sessionsByKey.has(key)) sessionsByKey.set(key, session);
|
|
582
|
+
}
|
|
583
|
+
const parentByKey = /* @__PURE__ */ new Map();
|
|
584
|
+
const childrenByKey = /* @__PURE__ */ new Map();
|
|
585
|
+
for (const [key, session] of sessionsByKey) {
|
|
586
|
+
const parent = parentKey(session);
|
|
587
|
+
if (!parent || !sessionsByKey.has(parent)) continue;
|
|
588
|
+
parentByKey.set(key, parent);
|
|
589
|
+
const children = childrenByKey.get(parent);
|
|
590
|
+
if (children) children.push(key);
|
|
591
|
+
else childrenByKey.set(parent, [key]);
|
|
592
|
+
}
|
|
593
|
+
return { sessionsByKey, parentByKey, childrenByKey };
|
|
594
|
+
}
|
|
595
|
+
function collectAffectedHierarchyKeys(graph, seedKeys, includeAncestors, collected) {
|
|
596
|
+
const visited = /* @__PURE__ */ new Set();
|
|
597
|
+
const pending2 = [...seedKeys].filter((key) => graph.sessionsByKey.has(key));
|
|
598
|
+
while (pending2.length > 0) {
|
|
599
|
+
const key = pending2.pop();
|
|
600
|
+
if (visited.has(key)) continue;
|
|
601
|
+
visited.add(key);
|
|
602
|
+
collected.add(key);
|
|
603
|
+
for (const child of graph.childrenByKey.get(key) ?? []) pending2.push(child);
|
|
604
|
+
}
|
|
605
|
+
if (!includeAncestors) return;
|
|
606
|
+
for (const seed of seedKeys) {
|
|
607
|
+
let key = graph.sessionsByKey.has(seed) ? seed : void 0;
|
|
608
|
+
const onPath = /* @__PURE__ */ new Set();
|
|
609
|
+
while (key && !onPath.has(key)) {
|
|
610
|
+
onPath.add(key);
|
|
611
|
+
collected.add(key);
|
|
612
|
+
key = graph.parentByKey.get(key);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
function createSessionProjectionContext(previousSessions, nextSessions, changedSessionHeads, removedSessionRefs) {
|
|
617
|
+
const changedKeys = new Set(
|
|
618
|
+
changedSessionHeads.map(({ reference }) => getSessionReferenceKey(reference))
|
|
619
|
+
);
|
|
620
|
+
const removedKeys = removedSessionRefs.map(getSessionReferenceKey);
|
|
621
|
+
const affectedKeys = /* @__PURE__ */ new Set();
|
|
622
|
+
const previousGraph = createSessionHierarchyGraph(previousSessions);
|
|
623
|
+
const nextGraph = createSessionHierarchyGraph(nextSessions);
|
|
624
|
+
collectAffectedHierarchyKeys(previousGraph, changedKeys, true, affectedKeys);
|
|
625
|
+
collectAffectedHierarchyKeys(nextGraph, changedKeys, true, affectedKeys);
|
|
626
|
+
collectAffectedHierarchyKeys(previousGraph, removedKeys, false, affectedKeys);
|
|
627
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
628
|
+
const relatedSessionHeads = nextSessions.flatMap((session) => {
|
|
629
|
+
const key = sessionKey(session);
|
|
630
|
+
if (!affectedKeys.has(key) || changedKeys.has(key) || emitted.has(key)) return [];
|
|
631
|
+
emitted.add(key);
|
|
632
|
+
return [
|
|
633
|
+
{
|
|
634
|
+
reference: session.reference,
|
|
635
|
+
session
|
|
636
|
+
}
|
|
637
|
+
];
|
|
638
|
+
});
|
|
639
|
+
const affectedActivityTimes = new Set(
|
|
640
|
+
[...changedSessionHeads, ...relatedSessionHeads].map(({ session }) => activityTime(session))
|
|
641
|
+
);
|
|
642
|
+
const sessionOrder = nextSessions.flatMap(
|
|
643
|
+
(session) => affectedActivityTimes.has(activityTime(session)) ? [session.reference] : []
|
|
644
|
+
);
|
|
645
|
+
return { relatedSessionHeads, sessionOrder };
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// ../core/dist/chunk-3ENBOS4I.mjs
|
|
649
|
+
function normalizeToolLabel(part) {
|
|
650
|
+
if (part.title?.trim()) {
|
|
651
|
+
return part.title.trim().replace(/^tool:\s*/i, "");
|
|
652
|
+
}
|
|
653
|
+
if (part.tool.trim()) return part.tool.trim();
|
|
654
|
+
return "tool";
|
|
655
|
+
}
|
|
656
|
+
function extractFileActivityOccurrences(messages) {
|
|
657
|
+
const occurrences = [];
|
|
658
|
+
messages.forEach((message, messageIndex) => {
|
|
659
|
+
let toolIndex = 0;
|
|
660
|
+
for (const part of message.parts) {
|
|
661
|
+
if (part.type !== "tool") continue;
|
|
662
|
+
const toolLabel = normalizeToolLabel(part);
|
|
663
|
+
const time = part.time_created ?? message.time_created;
|
|
664
|
+
const currentToolIndex = toolIndex;
|
|
665
|
+
toolIndex += 1;
|
|
666
|
+
for (const { kind, path } of extractFileToolOperations(part)) {
|
|
667
|
+
occurrences.push({
|
|
668
|
+
path,
|
|
669
|
+
kind,
|
|
670
|
+
time,
|
|
671
|
+
tool_label: toolLabel,
|
|
672
|
+
message_index: messageIndex,
|
|
673
|
+
tool_index: currentToolIndex
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
});
|
|
678
|
+
return occurrences;
|
|
679
|
+
}
|
|
680
|
+
function summarizeFileActivity(agentName, sessionId, projectIdentityKey, occurrences) {
|
|
681
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
682
|
+
for (const occurrence of occurrences) {
|
|
683
|
+
const key = `${occurrence.kind}\0${occurrence.path}`;
|
|
684
|
+
const current = grouped.get(key);
|
|
685
|
+
if (current) {
|
|
686
|
+
current.count += 1;
|
|
687
|
+
current.latestTime = Math.max(current.latestTime, occurrence.time);
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
grouped.set(key, {
|
|
691
|
+
reference: { agentName, sessionId },
|
|
692
|
+
projectIdentityKey,
|
|
693
|
+
path: occurrence.path,
|
|
694
|
+
kind: occurrence.kind,
|
|
695
|
+
count: 1,
|
|
696
|
+
latestTime: occurrence.time
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
return [...grouped.values()].sort((a, b) => {
|
|
700
|
+
if (b.latestTime !== a.latestTime) return b.latestTime - a.latestTime;
|
|
701
|
+
return a.path.localeCompare(b.path);
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
function extractSessionFileActivity(agentName, sessionId, projectIdentityKey, messages) {
|
|
705
|
+
return summarizeFileActivity(
|
|
706
|
+
agentName,
|
|
707
|
+
sessionId,
|
|
708
|
+
projectIdentityKey,
|
|
709
|
+
extractFileActivityOccurrences(messages)
|
|
710
|
+
);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
// ../core/dist/chunk-WABZHIV5.mjs
|
|
714
|
+
import { chmodSync, existsSync, mkdirSync, readdirSync, statSync } from "fs";
|
|
715
|
+
import { basename, dirname, join } from "path";
|
|
716
|
+
var diagnostics = null;
|
|
717
|
+
function toSafeSink(sink) {
|
|
718
|
+
return {
|
|
719
|
+
info(event, detail) {
|
|
720
|
+
try {
|
|
721
|
+
sink.info?.(event, detail);
|
|
722
|
+
} catch {
|
|
723
|
+
}
|
|
724
|
+
},
|
|
725
|
+
warn(event, detail) {
|
|
726
|
+
try {
|
|
727
|
+
sink.warn(event, detail);
|
|
728
|
+
} catch {
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
function setCoreDiagnostics(next) {
|
|
734
|
+
diagnostics = next ? toSafeSink(next) : null;
|
|
735
|
+
}
|
|
736
|
+
function getCoreDiagnostics() {
|
|
737
|
+
return diagnostics;
|
|
738
|
+
}
|
|
739
|
+
var PRIVATE_DIR_MODE = 448;
|
|
740
|
+
var PRIVATE_FILE_MODE = 384;
|
|
741
|
+
var SQLITE_SIDECAR_SUFFIXES = ["-wal", "-shm", "-journal"];
|
|
742
|
+
var isPosix = process.platform !== "win32";
|
|
743
|
+
function reportChmodFailure(path, error) {
|
|
744
|
+
getCoreDiagnostics()?.warn("storage.permissions_failed", {
|
|
745
|
+
path,
|
|
746
|
+
message: error instanceof Error ? error.message : String(error)
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
function restrict(path, mode) {
|
|
750
|
+
if (!isPosix || !existsSync(path)) return;
|
|
751
|
+
try {
|
|
752
|
+
if ((statSync(path).mode & 511) === mode) return;
|
|
753
|
+
chmodSync(path, mode);
|
|
754
|
+
} catch (error) {
|
|
755
|
+
reportChmodFailure(path, error);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
function ensurePrivateDirectory(path) {
|
|
759
|
+
mkdirSync(path, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
760
|
+
restrict(path, PRIVATE_DIR_MODE);
|
|
761
|
+
}
|
|
762
|
+
function restrictPrivateFile(path) {
|
|
763
|
+
restrict(path, PRIVATE_FILE_MODE);
|
|
764
|
+
}
|
|
765
|
+
function restrictExistingPrivateFiles(directory, owns) {
|
|
766
|
+
try {
|
|
767
|
+
for (const entry of readdirSync(directory)) {
|
|
768
|
+
if (owns(entry)) restrictPrivateFile(join(directory, entry));
|
|
769
|
+
}
|
|
770
|
+
} catch (error) {
|
|
771
|
+
reportChmodFailure(directory, error);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
var sweptBackupsFor = /* @__PURE__ */ new Set();
|
|
775
|
+
function restrictExistingBackups(dbPath) {
|
|
776
|
+
if (sweptBackupsFor.has(dbPath)) return;
|
|
777
|
+
sweptBackupsFor.add(dbPath);
|
|
778
|
+
const prefix = `${basename(dbPath)}.`;
|
|
779
|
+
restrictExistingPrivateFiles(
|
|
780
|
+
dirname(dbPath),
|
|
781
|
+
(name) => name.startsWith(prefix) && name.endsWith(".bak")
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
function restrictPrivateDatabase(dbPath) {
|
|
785
|
+
restrictPrivateFile(dbPath);
|
|
786
|
+
for (const suffix of SQLITE_SIDECAR_SUFFIXES) restrictPrivateFile(`${dbPath}${suffix}`);
|
|
787
|
+
restrictExistingBackups(dbPath);
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// ../core/dist/chunk-3JGIS7MJ.mjs
|
|
791
|
+
import { createHash } from "crypto";
|
|
792
|
+
import { existsSync as existsSync2, readFileSync, renameSync, rmSync, writeFileSync } from "fs";
|
|
793
|
+
import { homedir } from "os";
|
|
794
|
+
import { join as join2 } from "path";
|
|
795
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
796
|
+
var snapshot_default = {
|
|
797
|
+
"claude-3-5-haiku": [8e-7, 4e-6, 1e-6, 8e-8],
|
|
798
|
+
"claude-3-5-sonnet": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
799
|
+
"claude-3-7-sonnet": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
800
|
+
"claude-haiku-4-5": [1e-6, 5e-6, 125e-8, 1e-7],
|
|
801
|
+
"claude-sonnet-4": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
802
|
+
"claude-sonnet-4-5": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
803
|
+
"claude-sonnet-4-6": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
804
|
+
"claude-opus-4": [15e-6, 75e-6, 1875e-8, 15e-7],
|
|
805
|
+
"claude-opus-4-1": [15e-6, 75e-6, 1875e-8, 15e-7],
|
|
806
|
+
"claude-opus-4-5": [5e-6, 25e-6, 625e-8, 5e-7],
|
|
807
|
+
"claude-opus-4-6": [5e-6, 25e-6, 625e-8, 5e-7],
|
|
808
|
+
"claude-opus-4-7": [5e-6, 25e-6, 625e-8, 5e-7],
|
|
809
|
+
"anthropic/claude-sonnet-4-5": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
810
|
+
"anthropic/claude-sonnet-4-6": [3e-6, 15e-6, 375e-8, 3e-7],
|
|
811
|
+
"anthropic/claude-opus-4-6": [5e-6, 25e-6, 625e-8, 5e-7],
|
|
812
|
+
"gpt-4.1": [2e-6, 8e-6, null, 5e-7],
|
|
813
|
+
"gpt-4.1-mini": [4e-7, 16e-7, null, 1e-7],
|
|
814
|
+
"gpt-4.1-nano": [1e-7, 4e-7, null, 25e-9],
|
|
815
|
+
"gpt-4o": [25e-7, 1e-5, null, 125e-8],
|
|
816
|
+
"gpt-4o-mini": [15e-8, 6e-7, null, 75e-9],
|
|
817
|
+
"gpt-5": [125e-8, 1e-5, null, 125e-9],
|
|
818
|
+
"gpt-5.1": [125e-8, 1e-5, null, 125e-9],
|
|
819
|
+
"gpt-5.1-codex": [125e-8, 1e-5, null, 125e-9],
|
|
820
|
+
"gpt-5.1-codex-mini": [25e-8, 2e-6, null, 25e-9],
|
|
821
|
+
"gpt-5.2": [175e-8, 14e-6, null, 175e-9],
|
|
822
|
+
"gpt-5.2-codex": [175e-8, 14e-6, null, 175e-9],
|
|
823
|
+
"gpt-5.3-codex": [175e-8, 14e-6, null, 175e-9],
|
|
824
|
+
"gpt-5.4": [25e-7, 15e-6, null, 25e-8],
|
|
825
|
+
"gpt-5.4-mini": [75e-8, 45e-7, null, 75e-9],
|
|
826
|
+
"gpt-5.4-nano": [2e-7, 125e-8, null, 2e-8],
|
|
827
|
+
"gpt-5.5": [5e-6, 3e-5, null, 5e-7],
|
|
828
|
+
"gpt-5-mini": [25e-8, 2e-6, null, 25e-9],
|
|
829
|
+
"gpt-5-nano": [5e-8, 4e-7, null, 5e-9],
|
|
830
|
+
"moonshotai/kimi-k2-0905": [6e-7, 25e-7, null, null],
|
|
831
|
+
"moonshotai/kimi-k2-instruct": [57e-8, 23e-7, null, null],
|
|
832
|
+
"moonshotai/kimi-k2-thinking": [6e-7, 25e-7, null, null],
|
|
833
|
+
"deepseek-chat": [28e-8, 42e-8, null, 28e-9],
|
|
834
|
+
"deepseek-reasoner": [28e-8, 42e-8, null, 28e-9],
|
|
835
|
+
"qwen3-coder-480b-a35b-instruct": [3e-7, 13e-7, null, null],
|
|
836
|
+
"gemini-2.5-pro": [125e-8, 1e-5, null, 125e-9],
|
|
837
|
+
"gemini-2.5-flash": [3e-7, 25e-7, null, 3e-8]
|
|
838
|
+
};
|
|
839
|
+
var LITELLM_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
840
|
+
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
841
|
+
var WEB_SEARCH_COST = 0.01;
|
|
842
|
+
var REFRESH_TIMEOUT_MS = 1e4;
|
|
843
|
+
var published = createPricingGeneration(loadSnapshot());
|
|
844
|
+
var pending = null;
|
|
845
|
+
published = readDiskCache() ?? published;
|
|
846
|
+
function normalizeModelKey(key) {
|
|
847
|
+
return key.trim().toLowerCase().replaceAll("_", "-");
|
|
848
|
+
}
|
|
849
|
+
function createPricingGeneration(pricing) {
|
|
850
|
+
const hash = createHash("sha256");
|
|
851
|
+
const entries = [...pricing.entries()].sort(
|
|
852
|
+
([left], [right]) => left < right ? -1 : left > right ? 1 : 0
|
|
853
|
+
);
|
|
854
|
+
for (const [name, modelPricing] of entries) {
|
|
855
|
+
hash.update(name);
|
|
856
|
+
hash.update("\0");
|
|
857
|
+
hash.update(JSON.stringify(modelPricing));
|
|
858
|
+
hash.update("\n");
|
|
859
|
+
}
|
|
860
|
+
return {
|
|
861
|
+
id: Number.parseInt(hash.digest("hex").slice(0, 13), 16) || 1,
|
|
862
|
+
pricing
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
function costNumber(value, fallback) {
|
|
866
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
867
|
+
}
|
|
868
|
+
function getCacheDir() {
|
|
869
|
+
return join2(homedir(), ".cache", "codesesh");
|
|
870
|
+
}
|
|
871
|
+
function getCachePath() {
|
|
872
|
+
return join2(getCacheDir(), "litellm-pricing.json");
|
|
873
|
+
}
|
|
874
|
+
function loadSnapshot() {
|
|
875
|
+
const map = /* @__PURE__ */ new Map();
|
|
876
|
+
const snapshot = snapshot_default;
|
|
877
|
+
for (const [name, entry] of Object.entries(snapshot)) {
|
|
878
|
+
const [input, output, cacheCreate, cacheRead, reasoning, webSearch] = entry;
|
|
879
|
+
indexPricing(map, name, {
|
|
880
|
+
inputCostPerToken: input,
|
|
881
|
+
outputCostPerToken: output,
|
|
882
|
+
cacheCreateCostPerToken: cacheCreate ?? input * 1.25,
|
|
883
|
+
cacheReadCostPerToken: cacheRead ?? input * 0.1,
|
|
884
|
+
reasoningCostPerToken: reasoning ?? output,
|
|
885
|
+
webSearchCostPerRequest: webSearch ?? WEB_SEARCH_COST
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
return map;
|
|
889
|
+
}
|
|
890
|
+
function parseLiteLLMEntry(entry) {
|
|
891
|
+
const input = entry.input_cost_per_token;
|
|
892
|
+
const output = entry.output_cost_per_token;
|
|
893
|
+
if (typeof input !== "number" || typeof output !== "number") return null;
|
|
894
|
+
return {
|
|
895
|
+
inputCostPerToken: input,
|
|
896
|
+
outputCostPerToken: output,
|
|
897
|
+
cacheCreateCostPerToken: entry.cache_creation_input_token_cost ?? input * 1.25,
|
|
898
|
+
cacheReadCostPerToken: entry.cache_read_input_token_cost ?? input * 0.1,
|
|
899
|
+
reasoningCostPerToken: entry.output_reasoning_cost_per_token ?? output,
|
|
900
|
+
webSearchCostPerRequest: costNumber(
|
|
901
|
+
entry.web_search_cost_per_request ?? entry.search_context_cost_per_query,
|
|
902
|
+
WEB_SEARCH_COST
|
|
903
|
+
)
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
function normalizeCachedPricing(raw) {
|
|
907
|
+
const input = costNumber(raw["inputCostPerToken"], 0);
|
|
908
|
+
const output = costNumber(raw["outputCostPerToken"], 0);
|
|
909
|
+
if (input <= 0 || output <= 0) return null;
|
|
910
|
+
return {
|
|
911
|
+
inputCostPerToken: input,
|
|
912
|
+
outputCostPerToken: output,
|
|
913
|
+
cacheCreateCostPerToken: costNumber(raw["cacheCreateCostPerToken"], input * 1.25),
|
|
914
|
+
cacheReadCostPerToken: costNumber(raw["cacheReadCostPerToken"], input * 0.1),
|
|
915
|
+
reasoningCostPerToken: costNumber(raw["reasoningCostPerToken"], output),
|
|
916
|
+
webSearchCostPerRequest: costNumber(raw["webSearchCostPerRequest"], WEB_SEARCH_COST)
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
function indexPricing(map, name, pricing) {
|
|
920
|
+
const normalized = normalizeModelKey(name);
|
|
921
|
+
map.set(normalized, pricing);
|
|
922
|
+
const slashIndex = normalized.indexOf("/");
|
|
923
|
+
if (slashIndex >= 0) {
|
|
924
|
+
const stripped = normalized.slice(slashIndex + 1);
|
|
925
|
+
if (!map.has(stripped)) map.set(stripped, pricing);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
function parseLiteLLMData(data) {
|
|
929
|
+
const map = /* @__PURE__ */ new Map();
|
|
930
|
+
for (const [name, entry] of Object.entries(data)) {
|
|
931
|
+
const pricing = parseLiteLLMEntry(entry);
|
|
932
|
+
if (pricing) indexPricing(map, name, pricing);
|
|
933
|
+
}
|
|
934
|
+
return map;
|
|
935
|
+
}
|
|
936
|
+
function readDiskCache() {
|
|
937
|
+
const path = getCachePath();
|
|
938
|
+
if (!existsSync2(path)) return null;
|
|
939
|
+
try {
|
|
940
|
+
const cached = JSON.parse(readFileSync(path, "utf-8"));
|
|
941
|
+
if (!Number.isFinite(cached.timestamp)) return null;
|
|
942
|
+
if (cached.data == null || typeof cached.data !== "object" || Array.isArray(cached.data)) {
|
|
943
|
+
return null;
|
|
944
|
+
}
|
|
945
|
+
const next = loadSnapshot();
|
|
946
|
+
for (const [name, rawPricing] of Object.entries(cached.data)) {
|
|
947
|
+
const pricing = normalizeCachedPricing(rawPricing);
|
|
948
|
+
if (!pricing) continue;
|
|
949
|
+
indexPricing(next, name, pricing);
|
|
950
|
+
}
|
|
951
|
+
return createPricingGeneration(next);
|
|
952
|
+
} catch {
|
|
953
|
+
return null;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
function getPricingRegistry() {
|
|
957
|
+
return published.pricing;
|
|
958
|
+
}
|
|
959
|
+
function getPricingGeneration() {
|
|
960
|
+
return published;
|
|
961
|
+
}
|
|
962
|
+
function synchronizePricingGeneration(expectedId) {
|
|
963
|
+
if (!Number.isSafeInteger(expectedId) || expectedId < 1) {
|
|
964
|
+
throw new Error(`Invalid pricing generation: ${expectedId}`);
|
|
965
|
+
}
|
|
966
|
+
if (published.id === expectedId) return;
|
|
967
|
+
const cached = readDiskCache();
|
|
968
|
+
if (cached?.id !== expectedId) {
|
|
969
|
+
throw new Error(
|
|
970
|
+
`Pricing generation ${expectedId} is unavailable (current ${published.id}, cached ${cached?.id ?? "none"})`
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
published = cached;
|
|
974
|
+
getCoreDiagnostics()?.info?.("pricing.generation.synchronized", {
|
|
975
|
+
generation: published.id,
|
|
976
|
+
models: published.pricing.size
|
|
977
|
+
});
|
|
978
|
+
}
|
|
979
|
+
function publishPendingPricing() {
|
|
980
|
+
if (!pending) return false;
|
|
981
|
+
const next = createPricingGeneration(pending);
|
|
982
|
+
if (!writeDiskCacheAtomically(getCachePath(), next)) return false;
|
|
983
|
+
published = next;
|
|
984
|
+
pending = null;
|
|
985
|
+
getCoreDiagnostics()?.info?.("pricing.generation.published", {
|
|
986
|
+
generation: published.id,
|
|
987
|
+
models: published.pricing.size
|
|
988
|
+
});
|
|
989
|
+
return true;
|
|
990
|
+
}
|
|
991
|
+
function hasBillablePricing(pricing) {
|
|
992
|
+
return pricing.inputCostPerToken > 0 || pricing.outputCostPerToken > 0 || pricing.cacheReadCostPerToken > 0 || pricing.cacheCreateCostPerToken > 0;
|
|
993
|
+
}
|
|
994
|
+
function writeDiskCacheAtomically(path, generation) {
|
|
995
|
+
const temporaryPath = `${path}.${process.pid}.tmp`;
|
|
996
|
+
const payload = JSON.stringify({
|
|
997
|
+
timestamp: Date.now(),
|
|
998
|
+
data: Object.fromEntries(generation.pricing)
|
|
999
|
+
});
|
|
1000
|
+
try {
|
|
1001
|
+
ensurePrivateDirectory(getCacheDir());
|
|
1002
|
+
writeFileSync(temporaryPath, payload);
|
|
1003
|
+
restrictPrivateFile(temporaryPath);
|
|
1004
|
+
renameSync(temporaryPath, path);
|
|
1005
|
+
return true;
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
rmSync(temporaryPath, { force: true });
|
|
1008
|
+
getCoreDiagnostics()?.warn("pricing.cache_write_failed", {
|
|
1009
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1010
|
+
});
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
async function refreshPricingCache(options = {}) {
|
|
1015
|
+
const path = getCachePath();
|
|
1016
|
+
if (existsSync2(path)) {
|
|
1017
|
+
try {
|
|
1018
|
+
const cached = JSON.parse(readFileSync(path, "utf-8"));
|
|
1019
|
+
if (typeof cached.timestamp === "number" && Date.now() - cached.timestamp <= CACHE_TTL_MS) {
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
1022
|
+
} catch {
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
const timeout = AbortSignal.timeout(options.timeoutMs ?? REFRESH_TIMEOUT_MS);
|
|
1026
|
+
const signal = options.signal ? AbortSignal.any([options.signal, timeout]) : timeout;
|
|
1027
|
+
getCoreDiagnostics()?.info?.("pricing.refresh.started", { generation: published.id });
|
|
1028
|
+
try {
|
|
1029
|
+
const response = await fetch(LITELLM_URL, { signal });
|
|
1030
|
+
if (!response.ok) return false;
|
|
1031
|
+
const data = await response.json();
|
|
1032
|
+
const remote = parseLiteLLMData(data);
|
|
1033
|
+
if (remote.size === 0) return false;
|
|
1034
|
+
const next = loadSnapshot();
|
|
1035
|
+
for (const [name, pricing] of remote.entries()) {
|
|
1036
|
+
next.set(name, pricing);
|
|
1037
|
+
}
|
|
1038
|
+
pending = next;
|
|
1039
|
+
getCoreDiagnostics()?.info?.("pricing.refresh.completed", {
|
|
1040
|
+
generation: published.id,
|
|
1041
|
+
models: next.size
|
|
1042
|
+
});
|
|
1043
|
+
return true;
|
|
1044
|
+
} catch (error) {
|
|
1045
|
+
getCoreDiagnostics()?.warn("pricing.refresh.failed", {
|
|
1046
|
+
generation: published.id,
|
|
1047
|
+
aborted: signal.aborted,
|
|
1048
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1049
|
+
});
|
|
1050
|
+
return false;
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
var aliases_default = {
|
|
1054
|
+
"anthropic--claude-4.6-opus": "claude-opus-4-6",
|
|
1055
|
+
"anthropic--claude-4.6-sonnet": "claude-sonnet-4-6",
|
|
1056
|
+
"claude-4.6-sonnet": "claude-sonnet-4-6",
|
|
1057
|
+
"anthropic--claude-4.5-opus": "claude-opus-4-5",
|
|
1058
|
+
"anthropic--claude-4.5-sonnet": "claude-sonnet-4-5",
|
|
1059
|
+
"anthropic--claude-4.5-haiku": "claude-haiku-4-5",
|
|
1060
|
+
"claude-4.5-sonnet-thinking": "claude-sonnet-4-5",
|
|
1061
|
+
"claude-4-sonnet-thinking": "claude-sonnet-4-5",
|
|
1062
|
+
"claude-4-opus": "claude-opus-4-5",
|
|
1063
|
+
"cursor-auto": "claude-sonnet-4-5",
|
|
1064
|
+
"cursor-agent-auto": "claude-sonnet-4-5",
|
|
1065
|
+
"copilot-auto": "claude-sonnet-4-5",
|
|
1066
|
+
"copilot-openai-auto": "gpt-5.3-codex",
|
|
1067
|
+
"copilot-anthropic-auto": "claude-sonnet-4-5",
|
|
1068
|
+
"kimi-for-coding": "moonshotai/kimi-k2-0905",
|
|
1069
|
+
"kimi-k2.5": "moonshotai/kimi-k2-0905",
|
|
1070
|
+
"moonshot-cn/kimi-k2.5": "moonshotai/kimi-k2-0905",
|
|
1071
|
+
"gpt-5-codex": "gpt-5",
|
|
1072
|
+
"gpt-5.1-codex-high": "gpt-5.3-codex",
|
|
1073
|
+
"gpt-5.2-low": "gpt-5.2"
|
|
1074
|
+
};
|
|
1075
|
+
var BUILTIN_ALIASES = Object.fromEntries(
|
|
1076
|
+
Object.entries(aliases_default).map(([key, value]) => [
|
|
1077
|
+
normalizeModelKey(key),
|
|
1078
|
+
normalizeModelKey(value)
|
|
1079
|
+
])
|
|
1080
|
+
);
|
|
1081
|
+
function stripVersion(model) {
|
|
1082
|
+
return model.replace(/@.*$/, "").replace(/-\d{8}$/, "");
|
|
1083
|
+
}
|
|
1084
|
+
function stripProviderPrefix(model) {
|
|
1085
|
+
const parts = model.split("/");
|
|
1086
|
+
return parts[parts.length - 1] ?? model;
|
|
1087
|
+
}
|
|
1088
|
+
function resolveAlias(model) {
|
|
1089
|
+
return BUILTIN_ALIASES[model] ?? model;
|
|
1090
|
+
}
|
|
1091
|
+
function getCandidates(rawModel) {
|
|
1092
|
+
const withPrefix = stripVersion(normalizeModelKey(rawModel));
|
|
1093
|
+
const stripped = stripProviderPrefix(withPrefix);
|
|
1094
|
+
const aliased = resolveAlias(stripped);
|
|
1095
|
+
const candidates = [
|
|
1096
|
+
withPrefix,
|
|
1097
|
+
resolveAlias(withPrefix),
|
|
1098
|
+
stripped,
|
|
1099
|
+
aliased,
|
|
1100
|
+
`anthropic/${stripped}`,
|
|
1101
|
+
`openai/${stripped}`,
|
|
1102
|
+
`openrouter/openai/${stripped}`,
|
|
1103
|
+
`openrouter/anthropic/${stripped}`,
|
|
1104
|
+
`moonshotai/${stripped}`,
|
|
1105
|
+
`novita/moonshotai/${stripped}`
|
|
1106
|
+
];
|
|
1107
|
+
return [...new Set(candidates.filter(Boolean))];
|
|
1108
|
+
}
|
|
1109
|
+
function lookupCandidate(model, registry) {
|
|
1110
|
+
const direct = registry.get(model);
|
|
1111
|
+
if (direct && hasBillablePricing(direct)) return direct;
|
|
1112
|
+
const alias = resolveAlias(model);
|
|
1113
|
+
if (alias !== model) {
|
|
1114
|
+
const aliased = registry.get(alias);
|
|
1115
|
+
if (aliased && hasBillablePricing(aliased)) return aliased;
|
|
1116
|
+
}
|
|
1117
|
+
return null;
|
|
1118
|
+
}
|
|
1119
|
+
function fuzzyLookup(model, registry) {
|
|
1120
|
+
let best = null;
|
|
1121
|
+
for (const [key, pricing] of registry.entries()) {
|
|
1122
|
+
if (!hasBillablePricing(pricing)) continue;
|
|
1123
|
+
if (model.startsWith(`${key}-`) || model.startsWith(`${key}@`) || model === key) {
|
|
1124
|
+
if (!best || key.length > best[0].length) best = [key, pricing];
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return best?.[1] ?? null;
|
|
1128
|
+
}
|
|
1129
|
+
var pricingResolver = {
|
|
1130
|
+
resolve(rawModelName) {
|
|
1131
|
+
const registry = getPricingRegistry();
|
|
1132
|
+
const candidates = getCandidates(rawModelName);
|
|
1133
|
+
for (const candidate of candidates) {
|
|
1134
|
+
const pricing = lookupCandidate(candidate, registry);
|
|
1135
|
+
if (pricing) return pricing;
|
|
1136
|
+
}
|
|
1137
|
+
for (const candidate of candidates) {
|
|
1138
|
+
const pricing = fuzzyLookup(candidate, registry);
|
|
1139
|
+
if (pricing) return pricing;
|
|
1140
|
+
}
|
|
1141
|
+
return null;
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
function positive(value) {
|
|
1145
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
1146
|
+
}
|
|
1147
|
+
var pricingMissCapture = new AsyncLocalStorage();
|
|
1148
|
+
var PRICING_CAPTURE_EPOCH = "pricing-capture-v1";
|
|
1149
|
+
function pricingBecameAvailable(unpricedModels) {
|
|
1150
|
+
if (!Array.isArray(unpricedModels)) return false;
|
|
1151
|
+
return unpricedModels.some(
|
|
1152
|
+
(model) => typeof model === "string" && pricingResolver.resolve(model) !== null
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
function capturePricingMisses(run) {
|
|
1156
|
+
const capture = /* @__PURE__ */ new Set();
|
|
1157
|
+
const result = pricingMissCapture.run(capture, run);
|
|
1158
|
+
if (result instanceof Promise) {
|
|
1159
|
+
return result.then((resolved) => ({ result: resolved, unpricedModels: [...capture] }));
|
|
1160
|
+
}
|
|
1161
|
+
return { result, unpricedModels: [...capture] };
|
|
1162
|
+
}
|
|
1163
|
+
function estimateCostForTokens(model, usage) {
|
|
1164
|
+
if (!model || !usage) return null;
|
|
1165
|
+
const pricing = pricingResolver.resolve(model);
|
|
1166
|
+
if (!pricing) {
|
|
1167
|
+
pricingMissCapture.getStore()?.add(model);
|
|
1168
|
+
return null;
|
|
1169
|
+
}
|
|
1170
|
+
const cacheRead = positive(usage.cache_read);
|
|
1171
|
+
const cacheCreate = positive(usage.cache_create);
|
|
1172
|
+
const input = Math.max(0, positive(usage.input) - cacheRead - cacheCreate);
|
|
1173
|
+
const output = positive(usage.output);
|
|
1174
|
+
const reasoning = positive(usage.reasoning);
|
|
1175
|
+
const webSearchRequests = positive(usage.web_search_requests);
|
|
1176
|
+
const cost = input * pricing.inputCostPerToken + output * pricing.outputCostPerToken + reasoning * pricing.reasoningCostPerToken + cacheRead * pricing.cacheReadCostPerToken + cacheCreate * pricing.cacheCreateCostPerToken + webSearchRequests * pricing.webSearchCostPerRequest;
|
|
1177
|
+
return cost > 0 ? { cost: Number(cost.toFixed(8)), source: "estimated" } : null;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
// ../core/dist/chunk-326ZXYCY.mjs
|
|
1181
|
+
import { closeSync, openSync, readSync } from "fs";
|
|
1182
|
+
import { StringDecoder } from "string_decoder";
|
|
1183
|
+
import { basename as basename2 } from "path";
|
|
1184
|
+
var PerfTracer = class {
|
|
1185
|
+
rootMarkers = [];
|
|
1186
|
+
activeStack = [];
|
|
1187
|
+
enabled = false;
|
|
1188
|
+
enable() {
|
|
1189
|
+
this.enabled = true;
|
|
1190
|
+
}
|
|
1191
|
+
start(name) {
|
|
1192
|
+
const marker = {
|
|
1193
|
+
name,
|
|
1194
|
+
startTime: performance.now(),
|
|
1195
|
+
children: []
|
|
1196
|
+
};
|
|
1197
|
+
if (!this.enabled) return marker;
|
|
1198
|
+
const parent = this.activeStack[this.activeStack.length - 1];
|
|
1199
|
+
if (parent) {
|
|
1200
|
+
marker.parent = parent;
|
|
1201
|
+
parent.children.push(marker);
|
|
1202
|
+
} else {
|
|
1203
|
+
this.rootMarkers.push(marker);
|
|
1204
|
+
}
|
|
1205
|
+
this.activeStack.push(marker);
|
|
1206
|
+
return marker;
|
|
1207
|
+
}
|
|
1208
|
+
end(marker) {
|
|
1209
|
+
if (!this.enabled) return;
|
|
1210
|
+
const target = marker ?? this.activeStack[this.activeStack.length - 1];
|
|
1211
|
+
if (!target) return;
|
|
1212
|
+
target.endTime = performance.now();
|
|
1213
|
+
target.duration = target.endTime - target.startTime;
|
|
1214
|
+
while (this.activeStack.length > 0) {
|
|
1215
|
+
const popped = this.activeStack.pop();
|
|
1216
|
+
if (popped === target) break;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
measure(name, fn) {
|
|
1220
|
+
const marker = this.start(name);
|
|
1221
|
+
try {
|
|
1222
|
+
return fn();
|
|
1223
|
+
} finally {
|
|
1224
|
+
this.end(marker);
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
async measureAsync(name, fn) {
|
|
1228
|
+
const marker = this.start(name);
|
|
1229
|
+
try {
|
|
1230
|
+
return await fn();
|
|
1231
|
+
} finally {
|
|
1232
|
+
this.end(marker);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
getReport() {
|
|
1236
|
+
if (!this.enabled) return "Performance tracing disabled";
|
|
1237
|
+
const lines = [];
|
|
1238
|
+
lines.push("\n=== Performance Report ===\n");
|
|
1239
|
+
for (const marker of this.rootMarkers) {
|
|
1240
|
+
this.formatMarker(marker, 0, lines);
|
|
1241
|
+
}
|
|
1242
|
+
return lines.join("\n");
|
|
1243
|
+
}
|
|
1244
|
+
formatMarker(marker, depth, lines) {
|
|
1245
|
+
const indent = " ".repeat(depth);
|
|
1246
|
+
const duration = marker.duration?.toFixed(2) ?? "?";
|
|
1247
|
+
lines.push(`${indent}${marker.name}: ${duration}ms`);
|
|
1248
|
+
for (const child of marker.children) {
|
|
1249
|
+
this.formatMarker(child, depth + 1, lines);
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
reset() {
|
|
1253
|
+
this.rootMarkers = [];
|
|
1254
|
+
this.activeStack = [];
|
|
1255
|
+
}
|
|
1256
|
+
};
|
|
1257
|
+
var perf = new PerfTracer();
|
|
1258
|
+
var READ_CHUNK_BYTES = 1 << 20;
|
|
1259
|
+
function* parseJsonlLines(content) {
|
|
1260
|
+
let total = 0;
|
|
1261
|
+
let skipped = 0;
|
|
1262
|
+
for (const line of content.split("\n")) {
|
|
1263
|
+
const trimmed = line.trim();
|
|
1264
|
+
if (!trimmed) continue;
|
|
1265
|
+
total += 1;
|
|
1266
|
+
try {
|
|
1267
|
+
yield JSON.parse(trimmed);
|
|
1268
|
+
} catch {
|
|
1269
|
+
skipped += 1;
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
if (skipped > 0) {
|
|
1273
|
+
getCoreDiagnostics()?.warn("agent.jsonl_lines_skipped", { skipped, total });
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
function* readJsonlFileLines(filePath, chunkBytes = READ_CHUNK_BYTES) {
|
|
1277
|
+
const fd = openSync(filePath, "r");
|
|
1278
|
+
try {
|
|
1279
|
+
const buffer = Buffer.alloc(chunkBytes);
|
|
1280
|
+
const decoder = new StringDecoder("utf8");
|
|
1281
|
+
let pending2 = [];
|
|
1282
|
+
let bytesRead = readSync(fd, buffer, 0, chunkBytes, -1);
|
|
1283
|
+
while (bytesRead > 0) {
|
|
1284
|
+
const decoded = decoder.write(buffer.subarray(0, bytesRead));
|
|
1285
|
+
const lastBreak = decoded.lastIndexOf("\n");
|
|
1286
|
+
if (lastBreak === -1) {
|
|
1287
|
+
if (decoded) pending2.push(decoded);
|
|
1288
|
+
} else {
|
|
1289
|
+
pending2.push(decoded.slice(0, lastBreak));
|
|
1290
|
+
const complete = pending2.join("");
|
|
1291
|
+
pending2 = [decoded.slice(lastBreak + 1)];
|
|
1292
|
+
for (const line of complete.split("\n")) {
|
|
1293
|
+
const trimmed = line.trim();
|
|
1294
|
+
if (trimmed) yield trimmed;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
bytesRead = readSync(fd, buffer, 0, chunkBytes, -1);
|
|
1298
|
+
}
|
|
1299
|
+
pending2.push(decoder.end());
|
|
1300
|
+
const tail = pending2.join("").trim();
|
|
1301
|
+
if (tail) yield tail;
|
|
1302
|
+
} finally {
|
|
1303
|
+
closeSync(fd);
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
function* readJsonlFile(filePath) {
|
|
1307
|
+
let total = 0;
|
|
1308
|
+
let skipped = 0;
|
|
1309
|
+
for (const line of readJsonlFileLines(filePath)) {
|
|
1310
|
+
total += 1;
|
|
1311
|
+
try {
|
|
1312
|
+
yield JSON.parse(line);
|
|
1313
|
+
} catch {
|
|
1314
|
+
skipped += 1;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
if (skipped > 0) {
|
|
1318
|
+
getCoreDiagnostics()?.warn("agent.jsonl_lines_skipped", { skipped, total, filePath });
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
var INTERNAL_BLOCK_TAGS = [
|
|
1322
|
+
"command-message",
|
|
1323
|
+
"command-name",
|
|
1324
|
+
"local-command-caveat",
|
|
1325
|
+
"local-command-stdout",
|
|
1326
|
+
"system-reminder"
|
|
1327
|
+
];
|
|
1328
|
+
var TRANSPARENT_TAGS = ["command-args"];
|
|
1329
|
+
var INTERNAL_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
1330
|
+
"progress",
|
|
1331
|
+
"file history snapshot",
|
|
1332
|
+
"file-history snapshot",
|
|
1333
|
+
"file_history snapshot",
|
|
1334
|
+
"queue operation",
|
|
1335
|
+
"queue-operation",
|
|
1336
|
+
"queue_operation",
|
|
1337
|
+
"last prompt",
|
|
1338
|
+
"last-prompt",
|
|
1339
|
+
"last_prompt"
|
|
1340
|
+
]);
|
|
1341
|
+
function blockTagPattern(tag) {
|
|
1342
|
+
return new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi");
|
|
1343
|
+
}
|
|
1344
|
+
function blockTagLinePattern(tag) {
|
|
1345
|
+
return new RegExp(
|
|
1346
|
+
`(^|\\r?\\n)[ \\t]*<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>[ \\t]*(?:\\r?\\n|$)`,
|
|
1347
|
+
"gi"
|
|
1348
|
+
);
|
|
1349
|
+
}
|
|
1350
|
+
function openBlockTagPattern(tag) {
|
|
1351
|
+
return new RegExp(`\\n*<${tag}\\b[^>]*>[\\s\\S]*$`, "gi");
|
|
1352
|
+
}
|
|
1353
|
+
function looseTagPattern(tag) {
|
|
1354
|
+
return new RegExp(`<\\/?${tag}\\b[^>]*>`, "gi");
|
|
1355
|
+
}
|
|
1356
|
+
function isInternalEventType(value) {
|
|
1357
|
+
if (typeof value !== "string") return false;
|
|
1358
|
+
const normalized = value.trim().toLowerCase().replace(/[_-]+/g, " ");
|
|
1359
|
+
return INTERNAL_EVENT_TYPES.has(normalized);
|
|
1360
|
+
}
|
|
1361
|
+
function cleanDisplayText(text) {
|
|
1362
|
+
let cleaned = text;
|
|
1363
|
+
for (const tag of INTERNAL_BLOCK_TAGS) {
|
|
1364
|
+
cleaned = cleaned.replace(blockTagLinePattern(tag), "$1");
|
|
1365
|
+
cleaned = cleaned.replace(blockTagPattern(tag), "");
|
|
1366
|
+
cleaned = cleaned.replace(openBlockTagPattern(tag), "");
|
|
1367
|
+
}
|
|
1368
|
+
for (const tag of INTERNAL_BLOCK_TAGS) {
|
|
1369
|
+
cleaned = cleaned.replace(looseTagPattern(tag), "");
|
|
1370
|
+
}
|
|
1371
|
+
for (const tag of TRANSPARENT_TAGS) {
|
|
1372
|
+
cleaned = cleaned.replace(looseTagPattern(tag), "");
|
|
1373
|
+
}
|
|
1374
|
+
cleaned = cleaned.replace(/[ \t]+(?=\r?\n|$)/g, "").replace(/(?:\r?\n)+$/g, "");
|
|
1375
|
+
return cleaned.trim() ? cleaned : null;
|
|
1376
|
+
}
|
|
1377
|
+
var TITLE_MAX_LENGTH = 100;
|
|
1378
|
+
var UNTITLED_SESSION = "Untitled Session";
|
|
1379
|
+
function normalizeTitleText(text) {
|
|
1380
|
+
const visible = cleanDisplayText(text)?.split("\n").find((line) => line.trim())?.trim() ?? null;
|
|
1381
|
+
if (!visible) return null;
|
|
1382
|
+
const cleaned = visible.replace(/\s+/g, " ").trim();
|
|
1383
|
+
if (!cleaned) return null;
|
|
1384
|
+
return cleaned.slice(0, TITLE_MAX_LENGTH);
|
|
1385
|
+
}
|
|
1386
|
+
function basenameTitle(path) {
|
|
1387
|
+
if (!path) return null;
|
|
1388
|
+
const normalized = path.trim().replace(/[/\\]+$/, "");
|
|
1389
|
+
if (!normalized) return null;
|
|
1390
|
+
const name = basename2(normalized).trim();
|
|
1391
|
+
return name || null;
|
|
1392
|
+
}
|
|
1393
|
+
function resolveSessionTitle(explicit, message, directory) {
|
|
1394
|
+
for (const candidate of [explicit, message, directory]) {
|
|
1395
|
+
if (candidate) {
|
|
1396
|
+
const normalized = normalizeTitleText(candidate);
|
|
1397
|
+
if (normalized) return normalized;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
return UNTITLED_SESSION;
|
|
1401
|
+
}
|
|
1402
|
+
function estimateTokenCost(model, tokens) {
|
|
1403
|
+
return estimateCostForTokens(model, tokens)?.cost ?? null;
|
|
1404
|
+
}
|
|
1405
|
+
function asRecord(value) {
|
|
1406
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1407
|
+
return value;
|
|
1408
|
+
}
|
|
1409
|
+
return void 0;
|
|
1410
|
+
}
|
|
1411
|
+
function asString(value) {
|
|
1412
|
+
return typeof value === "string" ? value : void 0;
|
|
1413
|
+
}
|
|
1414
|
+
function asNumber(value) {
|
|
1415
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1416
|
+
}
|
|
1417
|
+
function asArray(value) {
|
|
1418
|
+
return Array.isArray(value) ? value : void 0;
|
|
1419
|
+
}
|
|
1420
|
+
function safeParseJsonRecord(json) {
|
|
1421
|
+
let raw;
|
|
1422
|
+
try {
|
|
1423
|
+
raw = JSON.parse(json);
|
|
1424
|
+
} catch {
|
|
1425
|
+
return void 0;
|
|
1426
|
+
}
|
|
1427
|
+
return asRecord(raw);
|
|
1428
|
+
}
|
|
1429
|
+
var reportedFieldMismatches = /* @__PURE__ */ new Set();
|
|
1430
|
+
function reportFieldMismatch(agentName, field) {
|
|
1431
|
+
const key = `${agentName}\0${field}`;
|
|
1432
|
+
if (reportedFieldMismatches.has(key)) return;
|
|
1433
|
+
reportedFieldMismatches.add(key);
|
|
1434
|
+
getCoreDiagnostics()?.warn("agent.field_shape_mismatch", { agentName, field });
|
|
1435
|
+
}
|
|
1436
|
+
function narrowField(agent, field, value, narrow) {
|
|
1437
|
+
if (value === void 0 || value === null) return void 0;
|
|
1438
|
+
const result = narrow(value);
|
|
1439
|
+
if (result === void 0) reportFieldMismatch(agent, field);
|
|
1440
|
+
return result;
|
|
1441
|
+
}
|
|
1442
|
+
function isInternalEventType2(value) {
|
|
1443
|
+
return isInternalEventType(value);
|
|
1444
|
+
}
|
|
1445
|
+
function cleanInternalText(text) {
|
|
1446
|
+
return cleanDisplayText(text) ?? "";
|
|
1447
|
+
}
|
|
1448
|
+
function cleanUnknown(value) {
|
|
1449
|
+
if (typeof value === "string") return cleanInternalText(value);
|
|
1450
|
+
if (Array.isArray(value)) return value.map(cleanUnknown);
|
|
1451
|
+
if (!value || typeof value !== "object") return value;
|
|
1452
|
+
const cleaned = {};
|
|
1453
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1454
|
+
cleaned[key] = cleanUnknown(child);
|
|
1455
|
+
}
|
|
1456
|
+
return cleaned;
|
|
1457
|
+
}
|
|
1458
|
+
function cleanMessagePart(part) {
|
|
1459
|
+
if (part.type === "text" || part.type === "reasoning" || part.type === "plan") {
|
|
1460
|
+
const text = cleanInternalText(part.text);
|
|
1461
|
+
return text ? { ...part, text } : null;
|
|
1462
|
+
}
|
|
1463
|
+
if (part.type !== "tool") return part;
|
|
1464
|
+
const title = part.title ? cleanInternalText(part.title) : "";
|
|
1465
|
+
const state = {
|
|
1466
|
+
...part.state,
|
|
1467
|
+
...part.state.input !== void 0 ? { input: cleanUnknown(part.state.input) } : {},
|
|
1468
|
+
...part.state.output !== void 0 ? { output: cleanUnknown(part.state.output) } : {},
|
|
1469
|
+
...part.state.error !== void 0 ? { error: cleanUnknown(part.state.error) } : {},
|
|
1470
|
+
...part.state.metadata !== void 0 ? { metadata: cleanUnknown(part.state.metadata) } : {}
|
|
1471
|
+
};
|
|
1472
|
+
const { title: _title, ...withoutTitle } = part;
|
|
1473
|
+
return {
|
|
1474
|
+
...withoutTitle,
|
|
1475
|
+
...title ? { title } : {},
|
|
1476
|
+
state
|
|
1477
|
+
};
|
|
1478
|
+
}
|
|
1479
|
+
function cleanMessageParts(parts) {
|
|
1480
|
+
return parts.flatMap((part) => {
|
|
1481
|
+
const cleaned = cleanMessagePart(part);
|
|
1482
|
+
return cleaned ? [cleaned] : [];
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1485
|
+
function cleanParsedMessage(message) {
|
|
1486
|
+
const parts = cleanMessageParts(message.parts);
|
|
1487
|
+
if (parts.length === 0) return null;
|
|
1488
|
+
return { ...message, parts };
|
|
1489
|
+
}
|
|
1490
|
+
function cleanParsedMessages(messages) {
|
|
1491
|
+
return messages.flatMap((message) => {
|
|
1492
|
+
const cleaned = cleanParsedMessage(message);
|
|
1493
|
+
return cleaned ? [cleaned] : [];
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1496
|
+
function firstUserMessageTitle(messages) {
|
|
1497
|
+
for (const message of messages) {
|
|
1498
|
+
if (message.role !== "user") continue;
|
|
1499
|
+
for (const part of message.parts) {
|
|
1500
|
+
if (part.type !== "text") continue;
|
|
1501
|
+
const title = normalizeTitleText(cleanInternalText(part.text));
|
|
1502
|
+
if (title) return title;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
return null;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
// ../core/dist/chunk-BAU7ZBXA.mjs
|
|
1509
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1510
|
+
import { basename as basename3, dirname as dirname2, join as join3 } from "path";
|
|
1511
|
+
import { createRequire } from "module";
|
|
1512
|
+
var SQLITE_BUSY_TIMEOUT_MS = 5e3;
|
|
1513
|
+
var DatabaseConstructor = null;
|
|
1514
|
+
var loadErrorMessage = null;
|
|
1515
|
+
try {
|
|
1516
|
+
const require2 = createRequire(import.meta.url);
|
|
1517
|
+
const mod = require2("better-sqlite3");
|
|
1518
|
+
DatabaseConstructor = typeof mod === "function" ? mod : mod.default;
|
|
1519
|
+
} catch (error) {
|
|
1520
|
+
loadErrorMessage = error instanceof Error ? error.message : String(error);
|
|
1521
|
+
}
|
|
1522
|
+
var unavailableReported = false;
|
|
1523
|
+
function reportUnavailableOnce() {
|
|
1524
|
+
if (unavailableReported) return;
|
|
1525
|
+
unavailableReported = true;
|
|
1526
|
+
getCoreDiagnostics()?.warn("sqlite.unavailable", { message: loadErrorMessage });
|
|
1527
|
+
}
|
|
1528
|
+
var SchemaMigrationPlanError = class extends Error {
|
|
1529
|
+
constructor(message) {
|
|
1530
|
+
super(message);
|
|
1531
|
+
this.name = "SchemaMigrationPlanError";
|
|
1532
|
+
}
|
|
1533
|
+
};
|
|
1534
|
+
function validateSchemaVersion(value, label) {
|
|
1535
|
+
if (Number.isSafeInteger(value) && value >= 0) return;
|
|
1536
|
+
throw new SchemaMigrationPlanError(`${label} must be a non-negative safe integer`);
|
|
1537
|
+
}
|
|
1538
|
+
function validateMigrationPlan(options) {
|
|
1539
|
+
let previousVersion = -1;
|
|
1540
|
+
let reachesTarget = false;
|
|
1541
|
+
for (const migration of options.migrations) {
|
|
1542
|
+
if (!Number.isSafeInteger(migration.version) || migration.version < 0) {
|
|
1543
|
+
throw new SchemaMigrationPlanError(
|
|
1544
|
+
`${options.backupLabel} migration version must be a non-negative safe integer`
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1547
|
+
if (migration.version <= previousVersion) {
|
|
1548
|
+
throw new SchemaMigrationPlanError(
|
|
1549
|
+
`${options.backupLabel} migrations must be ordered by strictly increasing version`
|
|
1550
|
+
);
|
|
1551
|
+
}
|
|
1552
|
+
previousVersion = migration.version;
|
|
1553
|
+
reachesTarget ||= migration.version === options.targetVersion;
|
|
1554
|
+
}
|
|
1555
|
+
if (!reachesTarget) {
|
|
1556
|
+
throw new SchemaMigrationPlanError(
|
|
1557
|
+
`${options.backupLabel} has no migration for target version ${options.targetVersion}`
|
|
1558
|
+
);
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
function quoteIdentifier(value) {
|
|
1562
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
1563
|
+
}
|
|
1564
|
+
function quoteSqlString(value) {
|
|
1565
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
1566
|
+
}
|
|
1567
|
+
function isInMemoryPath(dbPath) {
|
|
1568
|
+
return dbPath === ":memory:" || dbPath.startsWith("file::memory:") || dbPath.includes("mode=memory");
|
|
1569
|
+
}
|
|
1570
|
+
function getUserVersion(db) {
|
|
1571
|
+
const row = db.prepare("PRAGMA user_version").get();
|
|
1572
|
+
return Number(row?.user_version ?? 0);
|
|
1573
|
+
}
|
|
1574
|
+
function setUserVersion(db, version) {
|
|
1575
|
+
db.exec(`PRAGMA user_version = ${Math.trunc(version)}`);
|
|
1576
|
+
}
|
|
1577
|
+
function tableExists(db, tableName) {
|
|
1578
|
+
const row = db.prepare(
|
|
1579
|
+
`
|
|
1580
|
+
SELECT 1 AS value
|
|
1581
|
+
FROM sqlite_master
|
|
1582
|
+
WHERE name = ? AND type IN ('table', 'view')
|
|
1583
|
+
LIMIT 1
|
|
1584
|
+
`
|
|
1585
|
+
).get(tableName);
|
|
1586
|
+
return row !== void 0;
|
|
1587
|
+
}
|
|
1588
|
+
function columnExists(db, tableName, columnName) {
|
|
1589
|
+
if (!tableExists(db, tableName)) {
|
|
1590
|
+
return false;
|
|
1591
|
+
}
|
|
1592
|
+
const rows = db.prepare(`PRAGMA table_info(${quoteIdentifier(tableName)})`).all();
|
|
1593
|
+
return rows.some((row) => String(row.name) === columnName);
|
|
1594
|
+
}
|
|
1595
|
+
function tableHasRows(db, tableName) {
|
|
1596
|
+
if (!tableExists(db, tableName)) {
|
|
1597
|
+
return false;
|
|
1598
|
+
}
|
|
1599
|
+
const row = db.prepare(`SELECT 1 AS value FROM ${quoteIdentifier(tableName)} LIMIT 1`).get();
|
|
1600
|
+
return row !== void 0;
|
|
1601
|
+
}
|
|
1602
|
+
function backupDatabase(db, dbPath, label) {
|
|
1603
|
+
if (isInMemoryPath(dbPath)) {
|
|
1604
|
+
return null;
|
|
1605
|
+
}
|
|
1606
|
+
const timestamp = new Date(Date.now()).toISOString().replaceAll(":", "").replaceAll(".", "-");
|
|
1607
|
+
let backupPath = join3(dirname2(dbPath), `${basename3(dbPath)}.${timestamp}.${label}.bak`);
|
|
1608
|
+
for (let counter = 1; existsSync3(backupPath); counter += 1) {
|
|
1609
|
+
backupPath = join3(dirname2(dbPath), `${basename3(dbPath)}.${timestamp}.${label}.${counter}.bak`);
|
|
1610
|
+
}
|
|
1611
|
+
db.exec(`VACUUM INTO ${quoteSqlString(backupPath)}`);
|
|
1612
|
+
restrictPrivateFile(backupPath);
|
|
1613
|
+
return backupPath;
|
|
1614
|
+
}
|
|
1615
|
+
function backupDatabaseIfPopulated(db, dbPath, label, tables) {
|
|
1616
|
+
if (!tables.some((table) => tableHasRows(db, table))) {
|
|
1617
|
+
return null;
|
|
1618
|
+
}
|
|
1619
|
+
return backupDatabase(db, dbPath, label);
|
|
1620
|
+
}
|
|
1621
|
+
function runSchemaMigrations(db, options) {
|
|
1622
|
+
const backups = [];
|
|
1623
|
+
let currentVersion = options.currentVersion;
|
|
1624
|
+
validateSchemaVersion(currentVersion, `${options.backupLabel} current version`);
|
|
1625
|
+
validateSchemaVersion(options.targetVersion, `${options.backupLabel} target version`);
|
|
1626
|
+
if (currentVersion >= options.targetVersion) return backups;
|
|
1627
|
+
validateMigrationPlan(options);
|
|
1628
|
+
for (const migration of options.migrations) {
|
|
1629
|
+
if (migration.version <= currentVersion) {
|
|
1630
|
+
continue;
|
|
1631
|
+
}
|
|
1632
|
+
if (migration.version > options.targetVersion) {
|
|
1633
|
+
break;
|
|
1634
|
+
}
|
|
1635
|
+
const fromVersion = currentVersion;
|
|
1636
|
+
const startedAt = performance.now();
|
|
1637
|
+
getCoreDiagnostics()?.info?.("sqlite.migration.started", {
|
|
1638
|
+
label: options.backupLabel,
|
|
1639
|
+
from_version: fromVersion,
|
|
1640
|
+
to_version: migration.version,
|
|
1641
|
+
destructive: migration.destructive ?? false
|
|
1642
|
+
});
|
|
1643
|
+
try {
|
|
1644
|
+
let backupCreated = false;
|
|
1645
|
+
if (migration.destructive) {
|
|
1646
|
+
const backupPath = backupDatabaseIfPopulated(
|
|
1647
|
+
db,
|
|
1648
|
+
options.dbPath,
|
|
1649
|
+
options.backupLabel,
|
|
1650
|
+
options.backupTables
|
|
1651
|
+
);
|
|
1652
|
+
if (backupPath) {
|
|
1653
|
+
backups.push(backupPath);
|
|
1654
|
+
backupCreated = true;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
const apply = db.transaction(() => {
|
|
1658
|
+
migration.migrate(db);
|
|
1659
|
+
setUserVersion(db, migration.version);
|
|
1660
|
+
});
|
|
1661
|
+
apply.immediate();
|
|
1662
|
+
currentVersion = migration.version;
|
|
1663
|
+
getCoreDiagnostics()?.info?.("sqlite.migration.completed", {
|
|
1664
|
+
label: options.backupLabel,
|
|
1665
|
+
from_version: fromVersion,
|
|
1666
|
+
to_version: migration.version,
|
|
1667
|
+
destructive: migration.destructive ?? false,
|
|
1668
|
+
backup_created: backupCreated,
|
|
1669
|
+
duration_ms: Math.round(performance.now() - startedAt)
|
|
1670
|
+
});
|
|
1671
|
+
} catch (error) {
|
|
1672
|
+
getCoreDiagnostics()?.warn("sqlite.migration.failed", {
|
|
1673
|
+
label: options.backupLabel,
|
|
1674
|
+
from_version: fromVersion,
|
|
1675
|
+
to_version: migration.version,
|
|
1676
|
+
destructive: migration.destructive ?? false,
|
|
1677
|
+
duration_ms: Math.round(performance.now() - startedAt),
|
|
1678
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1679
|
+
});
|
|
1680
|
+
throw error;
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
if (currentVersion !== options.targetVersion) {
|
|
1684
|
+
throw new SchemaMigrationPlanError(
|
|
1685
|
+
`${options.backupLabel} stopped at version ${currentVersion}, expected ${options.targetVersion}`
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1688
|
+
return backups;
|
|
1689
|
+
}
|
|
1690
|
+
function openDbReadOnly(dbPath) {
|
|
1691
|
+
if (!DatabaseConstructor) {
|
|
1692
|
+
reportUnavailableOnce();
|
|
1693
|
+
return null;
|
|
1694
|
+
}
|
|
1695
|
+
try {
|
|
1696
|
+
const db = DatabaseConstructor(dbPath, { readonly: true });
|
|
1697
|
+
try {
|
|
1698
|
+
db.pragma(`busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);
|
|
1699
|
+
} catch {
|
|
1700
|
+
}
|
|
1701
|
+
return db;
|
|
1702
|
+
} catch (error) {
|
|
1703
|
+
getCoreDiagnostics()?.warn("sqlite.open_failed", {
|
|
1704
|
+
dbPath,
|
|
1705
|
+
readonly: true,
|
|
1706
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1707
|
+
});
|
|
1708
|
+
return null;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
function openDb(dbPath) {
|
|
1712
|
+
if (!DatabaseConstructor) {
|
|
1713
|
+
reportUnavailableOnce();
|
|
1714
|
+
return null;
|
|
1715
|
+
}
|
|
1716
|
+
try {
|
|
1717
|
+
ensurePrivateDirectory(dirname2(dbPath));
|
|
1718
|
+
if (!isInMemoryPath(dbPath)) process.env.SQLITE_TMPDIR ||= dirname2(dbPath);
|
|
1719
|
+
const db = DatabaseConstructor(dbPath);
|
|
1720
|
+
restrictPrivateDatabase(dbPath);
|
|
1721
|
+
try {
|
|
1722
|
+
db.pragma(`busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS}`);
|
|
1723
|
+
db.pragma("journal_mode = WAL");
|
|
1724
|
+
db.pragma("synchronous = NORMAL");
|
|
1725
|
+
db.pragma("foreign_keys = ON");
|
|
1726
|
+
db.pragma("temp_store = FILE");
|
|
1727
|
+
} catch {
|
|
1728
|
+
}
|
|
1729
|
+
return db;
|
|
1730
|
+
} catch (error) {
|
|
1731
|
+
getCoreDiagnostics()?.warn("sqlite.open_failed", {
|
|
1732
|
+
dbPath,
|
|
1733
|
+
readonly: false,
|
|
1734
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1735
|
+
});
|
|
1736
|
+
return null;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
function isSqliteAvailable() {
|
|
1740
|
+
return DatabaseConstructor !== null;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// ../core/dist/chunk-PIUQAREY.mjs
|
|
1744
|
+
function toRecord2(value) {
|
|
1745
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
1746
|
+
}
|
|
1747
|
+
function optionalString(value) {
|
|
1748
|
+
return typeof value === "string" && value ? value : void 0;
|
|
1749
|
+
}
|
|
1750
|
+
function optionalTime(value) {
|
|
1751
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1752
|
+
}
|
|
1753
|
+
function timeField(time_created) {
|
|
1754
|
+
return time_created === void 0 ? {} : { time_created };
|
|
1755
|
+
}
|
|
1756
|
+
function firstDefined(...values) {
|
|
1757
|
+
return values.find((value) => value !== void 0);
|
|
1758
|
+
}
|
|
1759
|
+
function normalizeStatus(state, output, error) {
|
|
1760
|
+
const status = state.status;
|
|
1761
|
+
if (status === "running" || status === "completed" || status === "error") return status;
|
|
1762
|
+
if (status === "success") return "completed";
|
|
1763
|
+
if (error != null) return "error";
|
|
1764
|
+
if (output !== void 0) return "completed";
|
|
1765
|
+
return "running";
|
|
1766
|
+
}
|
|
1767
|
+
function normalizeMetadata(state) {
|
|
1768
|
+
const rawMetadata = state.metadata ?? state.meta;
|
|
1769
|
+
const extras = Object.fromEntries(
|
|
1770
|
+
Object.entries(state).filter(
|
|
1771
|
+
([key]) => !["status", "input", "arguments", "output", "result", "error", "metadata", "meta"].includes(
|
|
1772
|
+
key
|
|
1773
|
+
)
|
|
1774
|
+
)
|
|
1775
|
+
);
|
|
1776
|
+
if (Object.keys(extras).length === 0) return rawMetadata;
|
|
1777
|
+
const metadata = toRecord2(rawMetadata);
|
|
1778
|
+
return metadata ? { ...metadata, ...extras } : extras;
|
|
1779
|
+
}
|
|
1780
|
+
function normalizeToolState(value, legacyPart) {
|
|
1781
|
+
const state = toRecord2(value) ?? {};
|
|
1782
|
+
const input = firstDefined(state.input, state.arguments, legacyPart.input);
|
|
1783
|
+
const output = firstDefined(state.output, state.result, legacyPart.output);
|
|
1784
|
+
const error = state.error;
|
|
1785
|
+
const metadata = normalizeMetadata(state);
|
|
1786
|
+
return {
|
|
1787
|
+
status: normalizeStatus(state, output, error),
|
|
1788
|
+
...input !== void 0 ? { input } : {},
|
|
1789
|
+
...output !== void 0 ? { output } : {},
|
|
1790
|
+
...error !== void 0 ? { error } : {},
|
|
1791
|
+
...metadata !== void 0 ? { metadata } : {}
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
function planText(value) {
|
|
1795
|
+
if (typeof value === "string") return value;
|
|
1796
|
+
const record = toRecord2(value);
|
|
1797
|
+
if (!record) return "";
|
|
1798
|
+
return planText(record.text ?? record.plan ?? record.content);
|
|
1799
|
+
}
|
|
1800
|
+
function normalizePlanPart(value, time_created) {
|
|
1801
|
+
const approval_status = value.approval_status === "fail" ? "fail" : "success";
|
|
1802
|
+
const text = planText(value.text ?? (approval_status === "fail" ? value.output : value.input));
|
|
1803
|
+
return text ? { type: "plan", text, approval_status, ...timeField(time_created) } : null;
|
|
1804
|
+
}
|
|
1805
|
+
function normalizeImagePart(value, time_created) {
|
|
1806
|
+
const data = optionalString(value.data);
|
|
1807
|
+
const url = optionalString(value.url);
|
|
1808
|
+
const mime_type = optionalString(value.mime_type);
|
|
1809
|
+
if (data && mime_type) {
|
|
1810
|
+
return {
|
|
1811
|
+
type: "image",
|
|
1812
|
+
data,
|
|
1813
|
+
mime_type,
|
|
1814
|
+
...url ? { url } : {},
|
|
1815
|
+
...timeField(time_created)
|
|
1816
|
+
};
|
|
1817
|
+
}
|
|
1818
|
+
if (url) {
|
|
1819
|
+
return {
|
|
1820
|
+
type: "image",
|
|
1821
|
+
url,
|
|
1822
|
+
...data ? { data } : {},
|
|
1823
|
+
...mime_type ? { mime_type } : {},
|
|
1824
|
+
...timeField(time_created)
|
|
1825
|
+
};
|
|
1826
|
+
}
|
|
1827
|
+
return null;
|
|
1828
|
+
}
|
|
1829
|
+
function normalizeToolPart(value, time_created) {
|
|
1830
|
+
const title = optionalString(value.title);
|
|
1831
|
+
const callID = optionalString(value.callID);
|
|
1832
|
+
const tool = optionalString(value.tool)?.trim() || title?.replace(/^tool:\s*/i, "").trim();
|
|
1833
|
+
if (!tool) return null;
|
|
1834
|
+
return {
|
|
1835
|
+
type: "tool",
|
|
1836
|
+
tool,
|
|
1837
|
+
...title ? { title } : {},
|
|
1838
|
+
...callID ? { callID } : {},
|
|
1839
|
+
state: normalizeToolState(value.state, value),
|
|
1840
|
+
...timeField(time_created)
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
function normalizeMessagePart(value) {
|
|
1844
|
+
const part = toRecord2(value);
|
|
1845
|
+
if (!part) return null;
|
|
1846
|
+
const time_created = optionalTime(part.time_created);
|
|
1847
|
+
if (part.type === "text" || part.type === "reasoning") {
|
|
1848
|
+
if (typeof part.text !== "string") return null;
|
|
1849
|
+
return { type: part.type, text: part.text, ...timeField(time_created) };
|
|
1850
|
+
}
|
|
1851
|
+
if (part.type === "plan") return normalizePlanPart(part, time_created);
|
|
1852
|
+
if (part.type === "image") return normalizeImagePart(part, time_created);
|
|
1853
|
+
if (part.type === "tool") return normalizeToolPart(part, time_created);
|
|
1854
|
+
return null;
|
|
1855
|
+
}
|
|
1856
|
+
function normalizeMessageParts(value) {
|
|
1857
|
+
if (!Array.isArray(value)) return [];
|
|
1858
|
+
return value.flatMap((part) => {
|
|
1859
|
+
const normalized = normalizeMessagePart(part);
|
|
1860
|
+
return normalized ? [normalized] : [];
|
|
1861
|
+
});
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
// ../core/dist/chunk-IKDMAP3N.mjs
|
|
1865
|
+
var AGENT_CATALOG = [
|
|
1866
|
+
{
|
|
1867
|
+
name: "claudecode",
|
|
1868
|
+
displayName: "Claude Code",
|
|
1869
|
+
icon: "/icon/agent/claudecode.svg",
|
|
1870
|
+
iconColored: true,
|
|
1871
|
+
sourceKind: "filesystem",
|
|
1872
|
+
resumeCommandPrefix: "claude --resume",
|
|
1873
|
+
toolStrategy: "custom"
|
|
1874
|
+
},
|
|
1875
|
+
{
|
|
1876
|
+
name: "cursor",
|
|
1877
|
+
displayName: "Cursor",
|
|
1878
|
+
icon: "/icon/agent/cursor.svg",
|
|
1879
|
+
sourceKind: "sqlite",
|
|
1880
|
+
resumeCommandPrefix: null,
|
|
1881
|
+
toolStrategy: "custom"
|
|
1882
|
+
},
|
|
1883
|
+
{
|
|
1884
|
+
name: "kimi",
|
|
1885
|
+
displayName: "Kimi-Cli",
|
|
1886
|
+
icon: "/icon/agent/kimi.svg",
|
|
1887
|
+
sourceKind: "filesystem",
|
|
1888
|
+
resumeCommandPrefix: "kimi -r",
|
|
1889
|
+
toolStrategy: "custom"
|
|
1890
|
+
},
|
|
1891
|
+
{
|
|
1892
|
+
name: "kimi-code",
|
|
1893
|
+
displayName: "Kimi-Code",
|
|
1894
|
+
icon: "/icon/agent/kimi.svg",
|
|
1895
|
+
sourceKind: "filesystem",
|
|
1896
|
+
resumeCommandPrefix: "kimi -r",
|
|
1897
|
+
toolStrategy: "custom"
|
|
1898
|
+
},
|
|
1899
|
+
{
|
|
1900
|
+
name: "codex",
|
|
1901
|
+
displayName: "Codex",
|
|
1902
|
+
icon: "/icon/agent/codex.svg",
|
|
1903
|
+
sourceKind: "filesystem",
|
|
1904
|
+
resumeCommandPrefix: "codex resume",
|
|
1905
|
+
toolStrategy: "custom"
|
|
1906
|
+
},
|
|
1907
|
+
{
|
|
1908
|
+
name: "grok",
|
|
1909
|
+
displayName: "Grok",
|
|
1910
|
+
icon: "/icon/agent/grok.svg",
|
|
1911
|
+
sourceKind: "filesystem",
|
|
1912
|
+
resumeCommandPrefix: "grok --resume",
|
|
1913
|
+
toolStrategy: "custom"
|
|
1914
|
+
},
|
|
1915
|
+
{
|
|
1916
|
+
name: "pi",
|
|
1917
|
+
displayName: "Pi",
|
|
1918
|
+
icon: "/icon/agent/pi.svg",
|
|
1919
|
+
sourceKind: "filesystem",
|
|
1920
|
+
resumeCommandPrefix: "pi --session",
|
|
1921
|
+
toolStrategy: "custom"
|
|
1922
|
+
},
|
|
1923
|
+
{
|
|
1924
|
+
name: "opencode",
|
|
1925
|
+
displayName: "OpenCode",
|
|
1926
|
+
icon: "/icon/agent/opencode.svg",
|
|
1927
|
+
sourceKind: "sqlite",
|
|
1928
|
+
resumeCommandPrefix: "opencode -s",
|
|
1929
|
+
toolStrategy: "custom"
|
|
1930
|
+
},
|
|
1931
|
+
{
|
|
1932
|
+
name: "zcode",
|
|
1933
|
+
displayName: "ZCode",
|
|
1934
|
+
icon: "/icon/agent/zcode.svg",
|
|
1935
|
+
sourceKind: "sqlite",
|
|
1936
|
+
resumeCommandPrefix: null,
|
|
1937
|
+
toolStrategy: "custom"
|
|
1938
|
+
},
|
|
1939
|
+
{
|
|
1940
|
+
name: "dsh",
|
|
1941
|
+
displayName: "DSH",
|
|
1942
|
+
icon: "/icon/agent/dsh.svg",
|
|
1943
|
+
iconColored: true,
|
|
1944
|
+
sourceKind: "filesystem",
|
|
1945
|
+
// DSH delegates launch arguments to installation-specific profiles.
|
|
1946
|
+
resumeCommandPrefix: null,
|
|
1947
|
+
toolStrategy: "custom"
|
|
1948
|
+
}
|
|
1949
|
+
];
|
|
1950
|
+
function getAgentCatalogEntry(name) {
|
|
1951
|
+
const entry = AGENT_CATALOG.find((candidate) => candidate.name === name);
|
|
1952
|
+
if (!entry) throw new Error(`Unknown agent catalog entry: ${name}`);
|
|
1953
|
+
return entry;
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
export {
|
|
1957
|
+
SMART_TAGS,
|
|
1958
|
+
isSmartTag,
|
|
1959
|
+
assertIdentifiedSessionHead,
|
|
1960
|
+
toPublicSessionHead,
|
|
1961
|
+
toPublicReferencedSessionHead,
|
|
1962
|
+
SMART_TAG_CLASSIFIER_REVISION,
|
|
1963
|
+
getSmartTagSourceTimestamp,
|
|
1964
|
+
classifySessionTags,
|
|
1965
|
+
WORKER_LOG_MESSAGE_TYPE,
|
|
1966
|
+
isWorkerLogMessage,
|
|
1967
|
+
normalizeSessionReference,
|
|
1968
|
+
formatSessionReference,
|
|
1969
|
+
getSessionReferenceKey,
|
|
1970
|
+
createSessionIdentity,
|
|
1971
|
+
assertSessionIdentity,
|
|
1972
|
+
getSessionAgentKey,
|
|
1973
|
+
sessionRoutePath,
|
|
1974
|
+
mergeSessionsUpdatedEvents,
|
|
1975
|
+
startOfCalendarDay,
|
|
1976
|
+
addCalendarDays,
|
|
1977
|
+
countCalendarDays,
|
|
1978
|
+
toCalendarDayKey,
|
|
1979
|
+
isProjectIdentityKind,
|
|
1980
|
+
getProjectIdentityKey,
|
|
1981
|
+
matchesProjectIdentity,
|
|
1982
|
+
sortSessionsByActivity,
|
|
1983
|
+
mergeSortedSessions,
|
|
1984
|
+
createSessionIndex,
|
|
1985
|
+
buildSessionTree,
|
|
1986
|
+
filterSessionTreeByActivityWindow,
|
|
1987
|
+
filterSessionTreeEntriesByActivityWindow,
|
|
1988
|
+
createSessionProjectionContext,
|
|
1989
|
+
extractSessionFileActivity,
|
|
1990
|
+
setCoreDiagnostics,
|
|
1991
|
+
getCoreDiagnostics,
|
|
1992
|
+
ensurePrivateDirectory,
|
|
1993
|
+
restrictPrivateFile,
|
|
1994
|
+
restrictExistingPrivateFiles,
|
|
1995
|
+
getPricingGeneration,
|
|
1996
|
+
synchronizePricingGeneration,
|
|
1997
|
+
publishPendingPricing,
|
|
1998
|
+
refreshPricingCache,
|
|
1999
|
+
PRICING_CAPTURE_EPOCH,
|
|
2000
|
+
pricingBecameAvailable,
|
|
2001
|
+
capturePricingMisses,
|
|
2002
|
+
perf,
|
|
2003
|
+
parseJsonlLines,
|
|
2004
|
+
readJsonlFileLines,
|
|
2005
|
+
readJsonlFile,
|
|
2006
|
+
isInternalEventType,
|
|
2007
|
+
normalizeTitleText,
|
|
2008
|
+
basenameTitle,
|
|
2009
|
+
resolveSessionTitle,
|
|
2010
|
+
estimateTokenCost,
|
|
2011
|
+
asRecord,
|
|
2012
|
+
asString,
|
|
2013
|
+
asNumber,
|
|
2014
|
+
asArray,
|
|
2015
|
+
safeParseJsonRecord,
|
|
2016
|
+
reportFieldMismatch,
|
|
2017
|
+
narrowField,
|
|
2018
|
+
isInternalEventType2,
|
|
2019
|
+
cleanInternalText,
|
|
2020
|
+
cleanMessagePart,
|
|
2021
|
+
cleanParsedMessages,
|
|
2022
|
+
firstUserMessageTitle,
|
|
2023
|
+
getUserVersion,
|
|
2024
|
+
setUserVersion,
|
|
2025
|
+
tableExists,
|
|
2026
|
+
columnExists,
|
|
2027
|
+
runSchemaMigrations,
|
|
2028
|
+
openDbReadOnly,
|
|
2029
|
+
openDb,
|
|
2030
|
+
isSqliteAvailable,
|
|
2031
|
+
normalizeMessageParts,
|
|
2032
|
+
AGENT_CATALOG,
|
|
2033
|
+
getAgentCatalogEntry
|
|
2034
|
+
};
|
|
2035
|
+
//# sourceMappingURL=chunk-W4PZHL2C.js.map
|