fleetlens 0.7.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/build-manifest.json +3 -3
- package/app/apps/web/.next/prerender-manifest.json +3 -3
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +3 -3
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +3 -3
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js +2 -2
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +3 -3
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week-index/route.js +2 -2
- package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/events/route.js +1 -1
- package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/route.js +4 -4
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__07qxzx4._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0fu2xfy._.js +5 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0gfd42k._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i.m8y0._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0iy5aqy._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh7-nf._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nvdffv._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s2~c3g._.js +3 -0
- package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js +3 -3
- package/app/apps/web/.next/server/chunks/packages_09wmnv.._.js +3 -0
- package/app/apps/web/.next/server/chunks/packages_0o6.gpk._.js +3 -0
- package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +13 -13
- package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_122oe0-.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0d~2~le._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0s4dg1y._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0tejjy_._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +3 -3
- package/app/apps/web/.next/server/chunks/ssr/_0jw2sm7._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0ly1xes._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0m67-xi._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_10_oegc._.js +1 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/04a36uhu~p_z-.css +1 -0
- package/app/apps/web/.next/static/chunks/{0q2vd~aj.1hpz.js → 09--oejbzw3q-.js} +3 -3
- package/app/apps/web/.next/static/chunks/0l3ck.awv~4t7.js +1 -0
- package/app/apps/web/.next/static/chunks/{171za22fv684..js → 0lxuac2v0_gdl.js} +2 -2
- package/app/apps/web/.next/static/chunks/0n0n.0279ot6c.js +1 -0
- package/app/apps/web/.next/static/chunks/0qcu452dr~edz.js +14 -0
- package/app/apps/web/.next/static/chunks/0uev~g~qvbjv9.js +4 -0
- package/app/apps/web/components/previous-cycles-trend.tsx +26 -11
- package/app/apps/web/components/usage-chart.tsx +35 -37
- package/app/apps/web/components/usage-gauges.tsx +18 -12
- package/app/apps/web/components/usage-sidebar.tsx +23 -12
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/utilization-tone.ts +74 -0
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +694 -67
- package/dist/index.js +1449 -823
- package/package.json +1 -1
- package/app/apps/web/.next/server/chunks/[externals]__0fpbr8-._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0-vgrh1._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.z48ue._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_8zh-i._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0dctov1._.js +0 -5
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0e8n_x4._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ej_p3s._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0jprdks._.js +0 -9
- package/app/apps/web/.next/server/chunks/packages_09hmrqx._.js +0 -3
- package/app/apps/web/.next/server/chunks/packages_118y1lp._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ytdqxt._.js +0 -3
- package/app/apps/web/.next/static/chunks/05m.oz3kmf1p7.js +0 -1
- package/app/apps/web/.next/static/chunks/07-fq4im3pmjp.js +0 -4
- package/app/apps/web/.next/static/chunks/0o9ayt8sknubd.js +0 -1
- package/app/apps/web/.next/static/chunks/0wfbj5zr~az.z.css +0 -1
- package/app/apps/web/.next/static/chunks/179_t_igg8ghh.js +0 -14
- /package/app/apps/web/.next/static/{tiK9aMHXkgnKLNmxj9J1P → L0Dy1hOQrZjV9l0TNulvk}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{tiK9aMHXkgnKLNmxj9J1P → L0Dy1hOQrZjV9l0TNulvk}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{tiK9aMHXkgnKLNmxj9J1P → L0Dy1hOQrZjV9l0TNulvk}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -187,6 +187,14 @@ function latestSnapshot(filePath) {
|
|
|
187
187
|
const all = readSnapshots(filePath);
|
|
188
188
|
return all.length > 0 ? all[all.length - 1] : null;
|
|
189
189
|
}
|
|
190
|
+
function latestClaudeCodeSnapshot(filePath) {
|
|
191
|
+
const all = readSnapshots(filePath);
|
|
192
|
+
for (let i = all.length - 1; i >= 0; i--) {
|
|
193
|
+
const s = all[i];
|
|
194
|
+
if (!s.agent || s.agent === "claude-code") return s;
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
190
198
|
var init_storage = __esm({
|
|
191
199
|
"src/usage/storage.ts"() {
|
|
192
200
|
"use strict";
|
|
@@ -454,9 +462,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
454
462
|
console.warn(
|
|
455
463
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
456
464
|
);
|
|
457
|
-
} else if (verify.installedVersion !== "0.
|
|
465
|
+
} else if (verify.installedVersion !== "0.10.0") {
|
|
458
466
|
console.log(
|
|
459
|
-
` \u2192 This process is still running ${"0.
|
|
467
|
+
` \u2192 This process is still running ${"0.10.0"}. Next invocation will use ${verify.installedVersion}.`
|
|
460
468
|
);
|
|
461
469
|
}
|
|
462
470
|
}
|
|
@@ -492,7 +500,7 @@ async function checkForUpdate() {
|
|
|
492
500
|
if (process.env.__FLEETLENS_UPDATED === "1" || process.env.__CCLENS_UPDATED === "1") return;
|
|
493
501
|
const latest = await fetchLatestVersion();
|
|
494
502
|
if (latest === null) return;
|
|
495
|
-
const current = "0.
|
|
503
|
+
const current = "0.10.0";
|
|
496
504
|
if (!shouldUpdate(current, latest)) return;
|
|
497
505
|
console.log(`Updating ${PACKAGE_NAME} ${current} \u2192 ${latest}...`);
|
|
498
506
|
await stopRunningServices();
|
|
@@ -574,7 +582,7 @@ async function restartServices(state) {
|
|
|
574
582
|
}
|
|
575
583
|
async function forceUpdate() {
|
|
576
584
|
const latest = await fetchLatestVersion();
|
|
577
|
-
const current = "0.
|
|
585
|
+
const current = "0.10.0";
|
|
578
586
|
if (latest === null) {
|
|
579
587
|
console.error("Could not reach npm registry. Check your network.");
|
|
580
588
|
process.exit(1);
|
|
@@ -747,10 +755,10 @@ async function web(args2) {
|
|
|
747
755
|
const noOpen = args2.includes("--no-open");
|
|
748
756
|
const positional = args2.filter((a) => !a.startsWith("--"));
|
|
749
757
|
const rawPath = positional[0] ?? "";
|
|
750
|
-
const
|
|
758
|
+
const path5 = rawPath.startsWith("/") ? rawPath : rawPath ? `/${rawPath}` : "";
|
|
751
759
|
const status2 = getServerStatus();
|
|
752
760
|
if (status2.running) {
|
|
753
|
-
const url = `http://localhost:${status2.port}${
|
|
761
|
+
const url = `http://localhost:${status2.port}${path5}`;
|
|
754
762
|
console.log(noOpen ? `Server running at ${url}` : `Opening ${url}`);
|
|
755
763
|
if (!noOpen) openBrowser(url);
|
|
756
764
|
return;
|
|
@@ -758,7 +766,7 @@ async function web(args2) {
|
|
|
758
766
|
console.log("fleetlens is not running. Starting server...");
|
|
759
767
|
try {
|
|
760
768
|
const result = await startServer({});
|
|
761
|
-
const url = `http://localhost:${result.port}${
|
|
769
|
+
const url = `http://localhost:${result.port}${path5}`;
|
|
762
770
|
console.log(`fleetlens running on ${url} (PID ${result.pid})`);
|
|
763
771
|
if (!noOpen) openBrowser(url);
|
|
764
772
|
} catch (err) {
|
|
@@ -816,9 +824,9 @@ function readFromCredentialsFile() {
|
|
|
816
824
|
join4(homedir3(), ".claude", ".credentials.json"),
|
|
817
825
|
join4(homedir3(), ".config", "claude", "credentials.json")
|
|
818
826
|
];
|
|
819
|
-
for (const
|
|
827
|
+
for (const path5 of candidates) {
|
|
820
828
|
try {
|
|
821
|
-
const blob = readFileSync5(
|
|
829
|
+
const blob = readFileSync5(path5, "utf8");
|
|
822
830
|
const creds = extractCredentials(blob);
|
|
823
831
|
if (creds) return creds;
|
|
824
832
|
} catch {
|
|
@@ -1050,21 +1058,37 @@ function findWorktreeMarker(projectName) {
|
|
|
1050
1058
|
}
|
|
1051
1059
|
return null;
|
|
1052
1060
|
}
|
|
1061
|
+
function findConductorWorkspace(projectName) {
|
|
1062
|
+
const m = CONDUCTOR_RE.exec(projectName);
|
|
1063
|
+
if (!m)
|
|
1064
|
+
return null;
|
|
1065
|
+
const workspaceName = m[1];
|
|
1066
|
+
const trailingSlash = m[0].endsWith("/") ? 1 : 0;
|
|
1067
|
+
const canonicalEndIdx = m.index + m[0].length - workspaceName.length - 1 - trailingSlash;
|
|
1068
|
+
return { canonicalEndIdx, workspaceName };
|
|
1069
|
+
}
|
|
1053
1070
|
function canonicalProjectName(projectName) {
|
|
1054
1071
|
const normalized = projectName.replace(/\/{2,}/g, "/");
|
|
1055
|
-
const
|
|
1056
|
-
if (
|
|
1057
|
-
return normalized.slice(0,
|
|
1072
|
+
const wt = findWorktreeMarker(normalized);
|
|
1073
|
+
if (wt)
|
|
1074
|
+
return normalized.slice(0, wt.idx);
|
|
1075
|
+
const cd = findConductorWorkspace(normalized);
|
|
1076
|
+
if (cd)
|
|
1077
|
+
return normalized.slice(0, cd.canonicalEndIdx);
|
|
1058
1078
|
return normalized;
|
|
1059
1079
|
}
|
|
1060
1080
|
function worktreeName(projectName) {
|
|
1061
1081
|
const normalized = projectName.replace(/\/{2,}/g, "/");
|
|
1062
|
-
const
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1082
|
+
const wt = findWorktreeMarker(normalized);
|
|
1083
|
+
if (wt) {
|
|
1084
|
+
const tail = normalized.slice(wt.idx + wt.marker.length);
|
|
1085
|
+
const slash = tail.indexOf("/");
|
|
1086
|
+
return slash >= 0 ? tail.slice(0, slash) : tail;
|
|
1087
|
+
}
|
|
1088
|
+
const cd = findConductorWorkspace(normalized);
|
|
1089
|
+
if (cd)
|
|
1090
|
+
return cd.workspaceName;
|
|
1091
|
+
return null;
|
|
1068
1092
|
}
|
|
1069
1093
|
function makeDay(date) {
|
|
1070
1094
|
return {
|
|
@@ -1533,7 +1557,7 @@ function groupByProject(sessions) {
|
|
|
1533
1557
|
}
|
|
1534
1558
|
return Array.from(map.values()).sort((a, b) => (b.lastActiveMs ?? 0) - (a.lastActiveMs ?? 0));
|
|
1535
1559
|
}
|
|
1536
|
-
var BLANK_USAGE, WORKTREE_MARKERS, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
|
|
1560
|
+
var BLANK_USAGE, WORKTREE_MARKERS, CONDUCTOR_RE, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
|
|
1537
1561
|
var init_analytics = __esm({
|
|
1538
1562
|
"../parser/dist/analytics.js"() {
|
|
1539
1563
|
"use strict";
|
|
@@ -1543,6 +1567,7 @@ var init_analytics = __esm({
|
|
|
1543
1567
|
"/.worktrees/",
|
|
1544
1568
|
"/claude/worktrees/"
|
|
1545
1569
|
];
|
|
1570
|
+
CONDUCTOR_RE = /\/conductor\/workspaces\/[^/]+\/([^/]+)(?:\/|$)/;
|
|
1546
1571
|
PR_CREATE_RE = /gh\s+pr\s+create\b/i;
|
|
1547
1572
|
PR_NUMBER_RE = /#(\d+)/;
|
|
1548
1573
|
TITLE_FLAG_RE = /--title\s+["']([^"']+)["']/;
|
|
@@ -1556,7 +1581,7 @@ function getAgentMetadata(kind) {
|
|
|
1556
1581
|
function isAgentKind(s) {
|
|
1557
1582
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
1558
1583
|
}
|
|
1559
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
1584
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
1560
1585
|
var init_agent_metadata = __esm({
|
|
1561
1586
|
"../parser/dist/agent-metadata.js"() {
|
|
1562
1587
|
"use strict";
|
|
@@ -1574,9 +1599,17 @@ var init_agent_metadata = __esm({
|
|
|
1574
1599
|
accentColor: "rgb(16, 163, 127)",
|
|
1575
1600
|
iconChar: "\u25C6"
|
|
1576
1601
|
};
|
|
1602
|
+
GEMINI_METADATA = {
|
|
1603
|
+
kind: "gemini",
|
|
1604
|
+
displayName: "Gemini CLI",
|
|
1605
|
+
shortLabel: "Gemini",
|
|
1606
|
+
accentColor: "rgb(124, 92, 246)",
|
|
1607
|
+
iconChar: "\u273A"
|
|
1608
|
+
};
|
|
1577
1609
|
agentMetadata = [
|
|
1578
1610
|
CLAUDE_CODE_METADATA,
|
|
1579
|
-
CODEX_METADATA
|
|
1611
|
+
CODEX_METADATA,
|
|
1612
|
+
GEMINI_METADATA
|
|
1580
1613
|
];
|
|
1581
1614
|
KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
|
|
1582
1615
|
}
|
|
@@ -1767,10 +1800,64 @@ var init_calibration = __esm({
|
|
|
1767
1800
|
}
|
|
1768
1801
|
});
|
|
1769
1802
|
|
|
1803
|
+
// ../parser/dist/user-input.js
|
|
1804
|
+
function stripFrameworkBoilerplate(rawText) {
|
|
1805
|
+
if (!rawText)
|
|
1806
|
+
return rawText;
|
|
1807
|
+
let out = rawText;
|
|
1808
|
+
for (const re of STRIPPABLE_WRAPPERS) {
|
|
1809
|
+
out = out.replace(re, "");
|
|
1810
|
+
}
|
|
1811
|
+
return out.trim();
|
|
1812
|
+
}
|
|
1813
|
+
function isFrameworkInjectedUserInput(rawText) {
|
|
1814
|
+
if (!rawText)
|
|
1815
|
+
return false;
|
|
1816
|
+
const stripped = stripFrameworkBoilerplate(rawText);
|
|
1817
|
+
if (!stripped)
|
|
1818
|
+
return true;
|
|
1819
|
+
for (const prefix of ENTIRELY_INJECTED_PREFIXES) {
|
|
1820
|
+
if (stripped.startsWith(prefix))
|
|
1821
|
+
return true;
|
|
1822
|
+
}
|
|
1823
|
+
return false;
|
|
1824
|
+
}
|
|
1825
|
+
var STRIPPABLE_WRAPPERS, ENTIRELY_INJECTED_PREFIXES;
|
|
1826
|
+
var init_user_input = __esm({
|
|
1827
|
+
"../parser/dist/user-input.js"() {
|
|
1828
|
+
"use strict";
|
|
1829
|
+
STRIPPABLE_WRAPPERS = [
|
|
1830
|
+
/<system_instruction\b[^>]*>[\s\S]*?<\/system_instruction>\s*/gi
|
|
1831
|
+
];
|
|
1832
|
+
ENTIRELY_INJECTED_PREFIXES = [
|
|
1833
|
+
"<command-name>",
|
|
1834
|
+
"<local-command-stdout>",
|
|
1835
|
+
"<local-command-caveat>",
|
|
1836
|
+
"<task-notification>",
|
|
1837
|
+
"Base directory for this skill:"
|
|
1838
|
+
];
|
|
1839
|
+
}
|
|
1840
|
+
});
|
|
1841
|
+
|
|
1770
1842
|
// ../parser/dist/parser.js
|
|
1771
1843
|
function cleanText(s) {
|
|
1772
1844
|
return s.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
|
|
1773
1845
|
}
|
|
1846
|
+
function extractRawUserText(rawMsg) {
|
|
1847
|
+
const c = rawMsg?.content;
|
|
1848
|
+
if (typeof c === "string")
|
|
1849
|
+
return c;
|
|
1850
|
+
if (Array.isArray(c)) {
|
|
1851
|
+
for (const block of c) {
|
|
1852
|
+
if (block && typeof block === "object") {
|
|
1853
|
+
const b = block;
|
|
1854
|
+
if (b.type === "text" && typeof b.text === "string")
|
|
1855
|
+
return b.text;
|
|
1856
|
+
}
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
return "";
|
|
1860
|
+
}
|
|
1774
1861
|
function truncate(s, n = 200) {
|
|
1775
1862
|
const one = cleanText(s);
|
|
1776
1863
|
return one.length > n ? one.slice(0, n - 1) + "\u2026" : one;
|
|
@@ -1869,7 +1956,8 @@ function toEvent(raw, index) {
|
|
|
1869
1956
|
const msg = r.message ?? {};
|
|
1870
1957
|
const c = msg.content;
|
|
1871
1958
|
if (typeof c === "string") {
|
|
1872
|
-
const
|
|
1959
|
+
const cleaned = stripFrameworkBoilerplate(c);
|
|
1960
|
+
const tm = classifyTeammateMessage(cleaned);
|
|
1873
1961
|
return {
|
|
1874
1962
|
index,
|
|
1875
1963
|
uuid,
|
|
@@ -1877,8 +1965,8 @@ function toEvent(raw, index) {
|
|
|
1877
1965
|
timestamp,
|
|
1878
1966
|
role: "user",
|
|
1879
1967
|
rawType,
|
|
1880
|
-
preview: truncate(
|
|
1881
|
-
blocks: [{ type: "text", text:
|
|
1968
|
+
preview: truncate(cleaned, 200),
|
|
1969
|
+
blocks: cleaned ? [{ type: "text", text: cleaned }] : [],
|
|
1882
1970
|
raw,
|
|
1883
1971
|
teammateMessage: tm
|
|
1884
1972
|
};
|
|
@@ -1902,7 +1990,9 @@ function toEvent(raw, index) {
|
|
|
1902
1990
|
};
|
|
1903
1991
|
}
|
|
1904
1992
|
const textBlock = c.find((b) => b?.type === "text");
|
|
1905
|
-
const
|
|
1993
|
+
const cleanedText = textBlock ? stripFrameworkBoilerplate(textBlock.text) : "";
|
|
1994
|
+
const cleanedBlocks = textBlock ? c.map((b) => b === textBlock ? { type: "text", text: cleanedText } : b) : c;
|
|
1995
|
+
const tm = cleanedText ? classifyTeammateMessage(cleanedText) : void 0;
|
|
1906
1996
|
return {
|
|
1907
1997
|
index,
|
|
1908
1998
|
uuid,
|
|
@@ -1910,8 +2000,8 @@ function toEvent(raw, index) {
|
|
|
1910
2000
|
timestamp,
|
|
1911
2001
|
role: "user",
|
|
1912
2002
|
rawType,
|
|
1913
|
-
preview:
|
|
1914
|
-
blocks:
|
|
2003
|
+
preview: cleanedText ? truncate(cleanedText, 200) : truncate(JSON.stringify(c), 200),
|
|
2004
|
+
blocks: cleanedBlocks,
|
|
1915
2005
|
raw,
|
|
1916
2006
|
teammateMessage: tm
|
|
1917
2007
|
};
|
|
@@ -2131,8 +2221,8 @@ function parseTranscript(rawLines) {
|
|
|
2131
2221
|
}
|
|
2132
2222
|
if (e.role === "user") {
|
|
2133
2223
|
const rawMsg = e.raw?.message;
|
|
2134
|
-
const rawContent =
|
|
2135
|
-
const isHidden =
|
|
2224
|
+
const rawContent = extractRawUserText(rawMsg);
|
|
2225
|
+
const isHidden = isFrameworkInjectedUserInput(rawContent);
|
|
2136
2226
|
const isTeamNoise = e.teammateMessage !== void 0 && !agentName;
|
|
2137
2227
|
if (!isHidden && !isTeamNoise) {
|
|
2138
2228
|
if (!firstUserPreview) {
|
|
@@ -2217,6 +2307,7 @@ var BLANK_USAGE2, TEAMMATE_MSG_RE;
|
|
|
2217
2307
|
var init_parser = __esm({
|
|
2218
2308
|
"../parser/dist/parser.js"() {
|
|
2219
2309
|
"use strict";
|
|
2310
|
+
init_user_input();
|
|
2220
2311
|
BLANK_USAGE2 = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
2221
2312
|
TEAMMATE_MSG_RE = /^\s*<teammate-message\s+teammate_id="([^"]+)"[^>]*>([\s\S]*?)<\/teammate-message>/;
|
|
2222
2313
|
}
|
|
@@ -3035,7 +3126,8 @@ function parseRollout(file, lines) {
|
|
|
3035
3126
|
if (type === "event_msg" && subtype === "user_message") {
|
|
3036
3127
|
const text = typeof payload.message === "string" ? payload.message : "";
|
|
3037
3128
|
const preview = previewOf(text);
|
|
3038
|
-
|
|
3129
|
+
const isHidden = isFrameworkInjectedUserInput(text);
|
|
3130
|
+
if (text && !isHidden) {
|
|
3039
3131
|
if (!firstUserPreview)
|
|
3040
3132
|
firstUserPreview = preview;
|
|
3041
3133
|
lastUserPreview = preview;
|
|
@@ -3352,6 +3444,7 @@ var init_codex = __esm({
|
|
|
3352
3444
|
"../parser/dist/codex.js"() {
|
|
3353
3445
|
"use strict";
|
|
3354
3446
|
init_analytics();
|
|
3447
|
+
init_user_input();
|
|
3355
3448
|
DEFAULT_CODEX_ROOT = path2.join(os2.homedir(), ".codex", "sessions");
|
|
3356
3449
|
ROLLOUT_RE = /^rollout-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})-([0-9a-f-]+)\.jsonl$/;
|
|
3357
3450
|
IDLE_GAP_MS = 3 * 60 * 1e3;
|
|
@@ -3360,10 +3453,512 @@ var init_codex = __esm({
|
|
|
3360
3453
|
}
|
|
3361
3454
|
});
|
|
3362
3455
|
|
|
3456
|
+
// ../parser/dist/gemini.js
|
|
3457
|
+
import { promises as fs3 } from "node:fs";
|
|
3458
|
+
import os3 from "node:os";
|
|
3459
|
+
import path3 from "node:path";
|
|
3460
|
+
async function safeReaddir2(p) {
|
|
3461
|
+
return fs3.readdir(p).catch(() => []);
|
|
3462
|
+
}
|
|
3463
|
+
async function listSessionFiles(root) {
|
|
3464
|
+
const out = [];
|
|
3465
|
+
const slugs = await safeReaddir2(root);
|
|
3466
|
+
for (const slug of slugs) {
|
|
3467
|
+
const chatsDir = path3.join(root, slug, "chats");
|
|
3468
|
+
const entries2 = await safeReaddir2(chatsDir);
|
|
3469
|
+
for (const entry of entries2) {
|
|
3470
|
+
if (!SESSION_FILE_RE.test(entry))
|
|
3471
|
+
continue;
|
|
3472
|
+
const full = path3.join(chatsDir, entry);
|
|
3473
|
+
const stat = await fs3.stat(full).catch(() => null);
|
|
3474
|
+
if (!stat || !stat.isFile())
|
|
3475
|
+
continue;
|
|
3476
|
+
const filenameId = entry.replace(/\.(jsonl|json)$/, "").split("-").pop() ?? entry;
|
|
3477
|
+
out.push({
|
|
3478
|
+
filePath: full,
|
|
3479
|
+
slug,
|
|
3480
|
+
filenameId,
|
|
3481
|
+
format: entry.endsWith(".jsonl") ? "jsonl" : "legacy-json",
|
|
3482
|
+
mtimeMs: stat.mtimeMs,
|
|
3483
|
+
sizeBytes: stat.size
|
|
3484
|
+
});
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
return out;
|
|
3488
|
+
}
|
|
3489
|
+
async function loadSlugToCwd() {
|
|
3490
|
+
const stat = await fs3.stat(GEMINI_PROJECTS_FILE).catch(() => null);
|
|
3491
|
+
if (!stat)
|
|
3492
|
+
return /* @__PURE__ */ new Map();
|
|
3493
|
+
if (projectsCache && projectsCache.mtimeMs === stat.mtimeMs) {
|
|
3494
|
+
return projectsCache.slugToCwd;
|
|
3495
|
+
}
|
|
3496
|
+
const raw = await fs3.readFile(GEMINI_PROJECTS_FILE, "utf8").catch(() => "");
|
|
3497
|
+
let parsed;
|
|
3498
|
+
try {
|
|
3499
|
+
parsed = JSON.parse(raw);
|
|
3500
|
+
} catch {
|
|
3501
|
+
parsed = {};
|
|
3502
|
+
}
|
|
3503
|
+
const slugToCwd = /* @__PURE__ */ new Map();
|
|
3504
|
+
for (const [cwd, slug] of Object.entries(parsed.projects ?? {})) {
|
|
3505
|
+
if (typeof slug === "string")
|
|
3506
|
+
slugToCwd.set(slug, cwd);
|
|
3507
|
+
}
|
|
3508
|
+
projectsCache = { mtimeMs: stat.mtimeMs, slugToCwd };
|
|
3509
|
+
return slugToCwd;
|
|
3510
|
+
}
|
|
3511
|
+
function isRewindMarker(o) {
|
|
3512
|
+
return !!o && typeof o === "object" && "$rewindTo" in o;
|
|
3513
|
+
}
|
|
3514
|
+
function isSetMarker(o) {
|
|
3515
|
+
return !!o && typeof o === "object" && "$set" in o;
|
|
3516
|
+
}
|
|
3517
|
+
function isMessageRecord(o) {
|
|
3518
|
+
return !!o && typeof o === "object" && typeof o.id === "string" && typeof o.type === "string";
|
|
3519
|
+
}
|
|
3520
|
+
async function readAndReplay(file) {
|
|
3521
|
+
const raw = await fs3.readFile(file.filePath, "utf8");
|
|
3522
|
+
if (file.format === "legacy-json") {
|
|
3523
|
+
let blob;
|
|
3524
|
+
try {
|
|
3525
|
+
blob = JSON.parse(raw);
|
|
3526
|
+
} catch {
|
|
3527
|
+
return { meta: {}, messages: [] };
|
|
3528
|
+
}
|
|
3529
|
+
const meta2 = {
|
|
3530
|
+
sessionId: typeof blob.sessionId === "string" ? blob.sessionId : void 0,
|
|
3531
|
+
projectHash: typeof blob.projectHash === "string" ? blob.projectHash : void 0,
|
|
3532
|
+
startTime: typeof blob.startTime === "string" ? blob.startTime : void 0,
|
|
3533
|
+
lastUpdated: typeof blob.lastUpdated === "string" ? blob.lastUpdated : void 0,
|
|
3534
|
+
summary: typeof blob.summary === "string" ? blob.summary : void 0
|
|
3535
|
+
};
|
|
3536
|
+
const msgs = Array.isArray(blob.messages) ? blob.messages : [];
|
|
3537
|
+
const messages2 = msgs.filter(isMessageRecord);
|
|
3538
|
+
return { meta: meta2, messages: messages2 };
|
|
3539
|
+
}
|
|
3540
|
+
const meta = {};
|
|
3541
|
+
const byId = /* @__PURE__ */ new Map();
|
|
3542
|
+
const order = [];
|
|
3543
|
+
for (const line of raw.split("\n")) {
|
|
3544
|
+
const trimmed = line.trim();
|
|
3545
|
+
if (!trimmed)
|
|
3546
|
+
continue;
|
|
3547
|
+
let obj;
|
|
3548
|
+
try {
|
|
3549
|
+
obj = JSON.parse(trimmed);
|
|
3550
|
+
} catch {
|
|
3551
|
+
continue;
|
|
3552
|
+
}
|
|
3553
|
+
if (isRewindMarker(obj)) {
|
|
3554
|
+
const target = obj.$rewindTo;
|
|
3555
|
+
const idx = order.indexOf(target);
|
|
3556
|
+
if (idx >= 0) {
|
|
3557
|
+
for (const id of order.slice(idx))
|
|
3558
|
+
byId.delete(id);
|
|
3559
|
+
order.length = idx;
|
|
3560
|
+
}
|
|
3561
|
+
continue;
|
|
3562
|
+
}
|
|
3563
|
+
if (isSetMarker(obj)) {
|
|
3564
|
+
Object.assign(meta, obj.$set);
|
|
3565
|
+
continue;
|
|
3566
|
+
}
|
|
3567
|
+
if (isMessageRecord(obj)) {
|
|
3568
|
+
if (!byId.has(obj.id))
|
|
3569
|
+
order.push(obj.id);
|
|
3570
|
+
byId.set(obj.id, obj);
|
|
3571
|
+
continue;
|
|
3572
|
+
}
|
|
3573
|
+
if (typeof obj === "object" && obj !== null) {
|
|
3574
|
+
const m = obj;
|
|
3575
|
+
if (typeof m.sessionId === "string" && !meta.sessionId) {
|
|
3576
|
+
meta.sessionId = m.sessionId;
|
|
3577
|
+
if (typeof m.projectHash === "string")
|
|
3578
|
+
meta.projectHash = m.projectHash;
|
|
3579
|
+
if (typeof m.startTime === "string")
|
|
3580
|
+
meta.startTime = m.startTime;
|
|
3581
|
+
if (typeof m.lastUpdated === "string")
|
|
3582
|
+
meta.lastUpdated = m.lastUpdated;
|
|
3583
|
+
if (typeof m.summary === "string")
|
|
3584
|
+
meta.summary = m.summary;
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
const messages = [];
|
|
3589
|
+
for (const id of order) {
|
|
3590
|
+
const m = byId.get(id);
|
|
3591
|
+
if (m)
|
|
3592
|
+
messages.push(m);
|
|
3593
|
+
}
|
|
3594
|
+
return { meta, messages };
|
|
3595
|
+
}
|
|
3596
|
+
function emptyUsage2() {
|
|
3597
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3598
|
+
}
|
|
3599
|
+
function previewOf2(text) {
|
|
3600
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3601
|
+
}
|
|
3602
|
+
function flattenContent(c) {
|
|
3603
|
+
if (!c)
|
|
3604
|
+
return "";
|
|
3605
|
+
if (typeof c === "string")
|
|
3606
|
+
return c;
|
|
3607
|
+
const parts = Array.isArray(c) ? c : [c];
|
|
3608
|
+
const out = [];
|
|
3609
|
+
for (const p of parts) {
|
|
3610
|
+
if (!p || typeof p !== "object")
|
|
3611
|
+
continue;
|
|
3612
|
+
const part = p;
|
|
3613
|
+
if (typeof part.text === "string") {
|
|
3614
|
+
out.push(part.text);
|
|
3615
|
+
continue;
|
|
3616
|
+
}
|
|
3617
|
+
const fr = part.functionResponse;
|
|
3618
|
+
if (fr) {
|
|
3619
|
+
const resp = fr.response;
|
|
3620
|
+
if (typeof resp === "string") {
|
|
3621
|
+
out.push(resp);
|
|
3622
|
+
} else if (resp && typeof resp === "object") {
|
|
3623
|
+
const r = resp;
|
|
3624
|
+
if (typeof r.output === "string")
|
|
3625
|
+
out.push(r.output);
|
|
3626
|
+
else if (typeof r.error === "string")
|
|
3627
|
+
out.push(`error: ${r.error}`);
|
|
3628
|
+
else
|
|
3629
|
+
out.push(JSON.stringify(r));
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
}
|
|
3633
|
+
return out.join("\n");
|
|
3634
|
+
}
|
|
3635
|
+
function truncate3(s, n) {
|
|
3636
|
+
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
3637
|
+
}
|
|
3638
|
+
async function parseSession(file) {
|
|
3639
|
+
const { meta: metaRec, messages } = await readAndReplay(file);
|
|
3640
|
+
const slugToCwd = await loadSlugToCwd();
|
|
3641
|
+
const cwd = slugToCwd.get(file.slug);
|
|
3642
|
+
const events = [];
|
|
3643
|
+
const totalUsage = emptyUsage2();
|
|
3644
|
+
let firstTimestamp;
|
|
3645
|
+
let lastTimestamp;
|
|
3646
|
+
let model;
|
|
3647
|
+
let toolCallCount = 0;
|
|
3648
|
+
let turnCount = 0;
|
|
3649
|
+
let firstUserPreview;
|
|
3650
|
+
let lastUserPreview;
|
|
3651
|
+
let lastAgentPreview;
|
|
3652
|
+
const tsMs = [];
|
|
3653
|
+
let idx = 0;
|
|
3654
|
+
function pushEvent(e) {
|
|
3655
|
+
events.push(e);
|
|
3656
|
+
if (e.timestamp && e.role !== "meta") {
|
|
3657
|
+
if (!firstTimestamp)
|
|
3658
|
+
firstTimestamp = e.timestamp;
|
|
3659
|
+
lastTimestamp = e.timestamp;
|
|
3660
|
+
const ms = Date.parse(e.timestamp);
|
|
3661
|
+
if (Number.isFinite(ms))
|
|
3662
|
+
tsMs.push(ms);
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
for (const msg of messages) {
|
|
3666
|
+
const ts = msg.timestamp;
|
|
3667
|
+
if (msg.type === "user") {
|
|
3668
|
+
const text = flattenContent(msg.displayContent ?? msg.content);
|
|
3669
|
+
const preview = previewOf2(text);
|
|
3670
|
+
const isHidden = isFrameworkInjectedUserInput(text);
|
|
3671
|
+
if (text && !isHidden) {
|
|
3672
|
+
if (!firstUserPreview)
|
|
3673
|
+
firstUserPreview = preview;
|
|
3674
|
+
lastUserPreview = preview;
|
|
3675
|
+
turnCount += 1;
|
|
3676
|
+
}
|
|
3677
|
+
pushEvent({
|
|
3678
|
+
index: idx++,
|
|
3679
|
+
timestamp: ts,
|
|
3680
|
+
role: "user",
|
|
3681
|
+
rawType: "gemini/user",
|
|
3682
|
+
preview,
|
|
3683
|
+
blocks: text ? [{ type: "text", text }] : [],
|
|
3684
|
+
messageId: msg.id,
|
|
3685
|
+
raw: msg
|
|
3686
|
+
});
|
|
3687
|
+
continue;
|
|
3688
|
+
}
|
|
3689
|
+
if (msg.type === "gemini") {
|
|
3690
|
+
if (typeof msg.model === "string")
|
|
3691
|
+
model = msg.model;
|
|
3692
|
+
const text = flattenContent(msg.content);
|
|
3693
|
+
const preview = previewOf2(text);
|
|
3694
|
+
if (text)
|
|
3695
|
+
lastAgentPreview = preview;
|
|
3696
|
+
let usage2;
|
|
3697
|
+
if (msg.tokens) {
|
|
3698
|
+
const t = msg.tokens;
|
|
3699
|
+
const u = {
|
|
3700
|
+
input: t.input ?? 0,
|
|
3701
|
+
output: t.output ?? 0,
|
|
3702
|
+
cacheRead: t.cached ?? 0,
|
|
3703
|
+
cacheWrite: 0
|
|
3704
|
+
};
|
|
3705
|
+
usage2 = u;
|
|
3706
|
+
totalUsage.input += u.input;
|
|
3707
|
+
totalUsage.output += u.output;
|
|
3708
|
+
totalUsage.cacheRead += u.cacheRead;
|
|
3709
|
+
}
|
|
3710
|
+
for (const th of msg.thoughts ?? []) {
|
|
3711
|
+
const thText = [th.subject, th.description].filter(Boolean).join(": ");
|
|
3712
|
+
if (!thText)
|
|
3713
|
+
continue;
|
|
3714
|
+
pushEvent({
|
|
3715
|
+
index: idx++,
|
|
3716
|
+
timestamp: th.timestamp ?? ts,
|
|
3717
|
+
role: "agent-thinking",
|
|
3718
|
+
rawType: "gemini/thought",
|
|
3719
|
+
preview: previewOf2(thText),
|
|
3720
|
+
blocks: [{ type: "thinking", thinking: thText }],
|
|
3721
|
+
model,
|
|
3722
|
+
raw: th
|
|
3723
|
+
});
|
|
3724
|
+
}
|
|
3725
|
+
if (text) {
|
|
3726
|
+
pushEvent({
|
|
3727
|
+
index: idx++,
|
|
3728
|
+
timestamp: ts,
|
|
3729
|
+
role: "agent",
|
|
3730
|
+
rawType: "gemini/agent",
|
|
3731
|
+
preview,
|
|
3732
|
+
blocks: [{ type: "text", text }],
|
|
3733
|
+
messageId: msg.id,
|
|
3734
|
+
model,
|
|
3735
|
+
usage: usage2,
|
|
3736
|
+
raw: msg
|
|
3737
|
+
});
|
|
3738
|
+
} else if (usage2) {
|
|
3739
|
+
pushEvent({
|
|
3740
|
+
index: idx++,
|
|
3741
|
+
timestamp: ts,
|
|
3742
|
+
role: "agent",
|
|
3743
|
+
rawType: "gemini/agent",
|
|
3744
|
+
preview: "",
|
|
3745
|
+
blocks: [],
|
|
3746
|
+
messageId: msg.id,
|
|
3747
|
+
model,
|
|
3748
|
+
usage: usage2,
|
|
3749
|
+
raw: msg
|
|
3750
|
+
});
|
|
3751
|
+
}
|
|
3752
|
+
for (const tc of msg.toolCalls ?? []) {
|
|
3753
|
+
toolCallCount += 1;
|
|
3754
|
+
const argsStr = tc.args ? JSON.stringify(tc.args) : "";
|
|
3755
|
+
pushEvent({
|
|
3756
|
+
index: idx++,
|
|
3757
|
+
timestamp: tc.timestamp ?? ts,
|
|
3758
|
+
role: "tool-call",
|
|
3759
|
+
rawType: "gemini/tool_call",
|
|
3760
|
+
preview: `${tc.name}(${truncate3(argsStr, 80)})`,
|
|
3761
|
+
blocks: [{ type: "tool_use", id: tc.id, name: tc.name, input: tc.args ?? {} }],
|
|
3762
|
+
toolName: tc.name,
|
|
3763
|
+
toolUseId: tc.id,
|
|
3764
|
+
model,
|
|
3765
|
+
raw: tc
|
|
3766
|
+
});
|
|
3767
|
+
const status2 = (tc.status ?? "").toLowerCase();
|
|
3768
|
+
const isTerminal = status2 === "success" || status2 === "error" || status2 === "cancelled";
|
|
3769
|
+
if (isTerminal) {
|
|
3770
|
+
const resultText = flattenContent(tc.result);
|
|
3771
|
+
pushEvent({
|
|
3772
|
+
index: idx++,
|
|
3773
|
+
timestamp: tc.timestamp ?? ts,
|
|
3774
|
+
role: "tool-result",
|
|
3775
|
+
rawType: "gemini/tool_result",
|
|
3776
|
+
preview: previewOf2(resultText),
|
|
3777
|
+
blocks: [
|
|
3778
|
+
{
|
|
3779
|
+
type: "tool_result",
|
|
3780
|
+
tool_use_id: tc.id,
|
|
3781
|
+
content: resultText,
|
|
3782
|
+
is_error: status2 === "error" || status2 === "cancelled"
|
|
3783
|
+
}
|
|
3784
|
+
],
|
|
3785
|
+
toolUseId: tc.id,
|
|
3786
|
+
toolResult: resultText,
|
|
3787
|
+
raw: tc
|
|
3788
|
+
});
|
|
3789
|
+
}
|
|
3790
|
+
}
|
|
3791
|
+
continue;
|
|
3792
|
+
}
|
|
3793
|
+
if (msg.type === "info" || msg.type === "warning" || msg.type === "error") {
|
|
3794
|
+
const text = flattenContent(msg.content);
|
|
3795
|
+
pushEvent({
|
|
3796
|
+
index: idx++,
|
|
3797
|
+
timestamp: ts,
|
|
3798
|
+
role: "meta",
|
|
3799
|
+
rawType: `gemini/${msg.type}`,
|
|
3800
|
+
preview: previewOf2(text),
|
|
3801
|
+
blocks: text ? [{ type: "text", text }] : [],
|
|
3802
|
+
raw: msg
|
|
3803
|
+
});
|
|
3804
|
+
continue;
|
|
3805
|
+
}
|
|
3806
|
+
}
|
|
3807
|
+
const startMs = firstTimestamp ? Date.parse(firstTimestamp) : void 0;
|
|
3808
|
+
if (startMs !== void 0 && Number.isFinite(startMs)) {
|
|
3809
|
+
let prevMs;
|
|
3810
|
+
for (const ev of events) {
|
|
3811
|
+
if (!ev.timestamp)
|
|
3812
|
+
continue;
|
|
3813
|
+
const ms = Date.parse(ev.timestamp);
|
|
3814
|
+
if (!Number.isFinite(ms))
|
|
3815
|
+
continue;
|
|
3816
|
+
ev.tOffsetMs = Math.max(0, ms - startMs);
|
|
3817
|
+
if (prevMs !== void 0)
|
|
3818
|
+
ev.gapMs = Math.max(0, ms - prevMs);
|
|
3819
|
+
prevMs = ms;
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
const activeSegments = computeActiveSegments3(tsMs);
|
|
3823
|
+
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
3824
|
+
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3825
|
+
const sessionId = metaRec.sessionId ?? file.filenameId;
|
|
3826
|
+
const projectName = cwd ? canonicalProjectName(cwd) : file.slug;
|
|
3827
|
+
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : file.slug;
|
|
3828
|
+
const meta = {
|
|
3829
|
+
agent: "gemini",
|
|
3830
|
+
id: sessionId,
|
|
3831
|
+
filePath: file.filePath,
|
|
3832
|
+
projectName,
|
|
3833
|
+
projectDir,
|
|
3834
|
+
sessionId,
|
|
3835
|
+
firstTimestamp,
|
|
3836
|
+
lastTimestamp,
|
|
3837
|
+
durationMs: durationMs && Number.isFinite(durationMs) ? durationMs : void 0,
|
|
3838
|
+
eventCount: events.length,
|
|
3839
|
+
model,
|
|
3840
|
+
cwd,
|
|
3841
|
+
totalUsage,
|
|
3842
|
+
status: "idle",
|
|
3843
|
+
firstUserPreview,
|
|
3844
|
+
lastUserPreview,
|
|
3845
|
+
lastAgentPreview,
|
|
3846
|
+
toolCallCount,
|
|
3847
|
+
turnCount,
|
|
3848
|
+
airTimeMs,
|
|
3849
|
+
activeSegments
|
|
3850
|
+
};
|
|
3851
|
+
return { meta, events };
|
|
3852
|
+
}
|
|
3853
|
+
function computeActiveSegments3(tsMs) {
|
|
3854
|
+
if (tsMs.length === 0)
|
|
3855
|
+
return [];
|
|
3856
|
+
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
3857
|
+
const out = [];
|
|
3858
|
+
let segStart = sorted[0];
|
|
3859
|
+
let segEnd = sorted[0];
|
|
3860
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
3861
|
+
if (sorted[i] - segEnd > IDLE_GAP_MS2) {
|
|
3862
|
+
out.push({ startMs: segStart, endMs: segEnd });
|
|
3863
|
+
segStart = sorted[i];
|
|
3864
|
+
}
|
|
3865
|
+
segEnd = sorted[i];
|
|
3866
|
+
}
|
|
3867
|
+
out.push({ startMs: segStart, endMs: segEnd });
|
|
3868
|
+
return out;
|
|
3869
|
+
}
|
|
3870
|
+
function clearGeminiCaches() {
|
|
3871
|
+
metaCache3.clear();
|
|
3872
|
+
detailCache3.clear();
|
|
3873
|
+
projectsCache = null;
|
|
3874
|
+
}
|
|
3875
|
+
async function listGeminiSessions(opts = {}) {
|
|
3876
|
+
const root = opts.root ?? DEFAULT_GEMINI_ROOT;
|
|
3877
|
+
const files = await listSessionFiles(root);
|
|
3878
|
+
const out = [];
|
|
3879
|
+
for (const file of files) {
|
|
3880
|
+
const cached = metaCache3.get(file.filePath);
|
|
3881
|
+
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3882
|
+
out.push(cached.meta);
|
|
3883
|
+
continue;
|
|
3884
|
+
}
|
|
3885
|
+
try {
|
|
3886
|
+
const { meta } = await parseSession(file);
|
|
3887
|
+
metaCache3.set(file.filePath, {
|
|
3888
|
+
meta,
|
|
3889
|
+
mtimeMs: file.mtimeMs,
|
|
3890
|
+
sizeBytes: file.sizeBytes
|
|
3891
|
+
});
|
|
3892
|
+
out.push(meta);
|
|
3893
|
+
} catch {
|
|
3894
|
+
}
|
|
3895
|
+
}
|
|
3896
|
+
out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
|
|
3897
|
+
if (opts.limit !== void 0)
|
|
3898
|
+
return out.slice(0, opts.limit);
|
|
3899
|
+
return out;
|
|
3900
|
+
}
|
|
3901
|
+
async function getGeminiSession(id, opts = {}) {
|
|
3902
|
+
const root = opts.root ?? DEFAULT_GEMINI_ROOT;
|
|
3903
|
+
const files = await listSessionFiles(root);
|
|
3904
|
+
let chosen;
|
|
3905
|
+
for (const file of files) {
|
|
3906
|
+
if (file.filenameId === id || id.startsWith(file.filenameId)) {
|
|
3907
|
+
chosen = file;
|
|
3908
|
+
break;
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
if (!chosen) {
|
|
3912
|
+
for (const file of files) {
|
|
3913
|
+
const { meta: meta2 } = await parseSession(file).catch(() => ({ meta: { id: "" } }));
|
|
3914
|
+
if (meta2.id === id) {
|
|
3915
|
+
chosen = file;
|
|
3916
|
+
break;
|
|
3917
|
+
}
|
|
3918
|
+
}
|
|
3919
|
+
}
|
|
3920
|
+
if (!chosen)
|
|
3921
|
+
return null;
|
|
3922
|
+
const cached = detailCache3.get(chosen.filePath);
|
|
3923
|
+
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
|
|
3924
|
+
return cached.detail;
|
|
3925
|
+
}
|
|
3926
|
+
const { meta, events } = await parseSession(chosen);
|
|
3927
|
+
const detail = { ...meta, events };
|
|
3928
|
+
detailCache3.set(chosen.filePath, {
|
|
3929
|
+
detail,
|
|
3930
|
+
mtimeMs: chosen.mtimeMs,
|
|
3931
|
+
sizeBytes: chosen.sizeBytes
|
|
3932
|
+
});
|
|
3933
|
+
return detail;
|
|
3934
|
+
}
|
|
3935
|
+
function geminiSessionLocalDay(meta) {
|
|
3936
|
+
if (!meta.firstTimestamp)
|
|
3937
|
+
return void 0;
|
|
3938
|
+
const ms = Date.parse(meta.firstTimestamp);
|
|
3939
|
+
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
3940
|
+
}
|
|
3941
|
+
var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE, IDLE_GAP_MS2, projectsCache, metaCache3, detailCache3;
|
|
3942
|
+
var init_gemini = __esm({
|
|
3943
|
+
"../parser/dist/gemini.js"() {
|
|
3944
|
+
"use strict";
|
|
3945
|
+
init_analytics();
|
|
3946
|
+
init_user_input();
|
|
3947
|
+
DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
|
|
3948
|
+
GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
|
|
3949
|
+
SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
|
|
3950
|
+
IDLE_GAP_MS2 = 3 * 60 * 1e3;
|
|
3951
|
+
projectsCache = null;
|
|
3952
|
+
metaCache3 = /* @__PURE__ */ new Map();
|
|
3953
|
+
detailCache3 = /* @__PURE__ */ new Map();
|
|
3954
|
+
}
|
|
3955
|
+
});
|
|
3956
|
+
|
|
3363
3957
|
// ../parser/dist/fs.js
|
|
3364
3958
|
var fs_exports = {};
|
|
3365
3959
|
__export(fs_exports, {
|
|
3366
3960
|
DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
|
|
3961
|
+
DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
|
|
3367
3962
|
DEFAULT_ROOT: () => DEFAULT_ROOT,
|
|
3368
3963
|
agentSources: () => agentSources,
|
|
3369
3964
|
buildCalibrationCurve: () => buildCalibrationCurve,
|
|
@@ -3372,14 +3967,17 @@ __export(fs_exports, {
|
|
|
3372
3967
|
codexSessionLocalDay: () => codexSessionLocalDay,
|
|
3373
3968
|
decodeProjectName: () => decodeProjectName,
|
|
3374
3969
|
findTeamLead: () => findTeamLead,
|
|
3970
|
+
geminiSessionLocalDay: () => geminiSessionLocalDay,
|
|
3375
3971
|
getAgentSource: () => getAgentSource,
|
|
3376
3972
|
getAnySession: () => getAnySession,
|
|
3377
3973
|
getCodexSession: () => getCodexSession,
|
|
3974
|
+
getGeminiSession: () => getGeminiSession,
|
|
3378
3975
|
getLatestCodexUsage: () => getLatestCodexUsage,
|
|
3379
3976
|
getSession: () => getSession,
|
|
3380
3977
|
invalidateFile: () => invalidateFile,
|
|
3381
3978
|
listAllSessions: () => listAllSessions,
|
|
3382
3979
|
listCodexSessions: () => listCodexSessions,
|
|
3980
|
+
listGeminiSessions: () => listGeminiSessions,
|
|
3383
3981
|
listProjects: () => listProjects,
|
|
3384
3982
|
listSessions: () => listSessions,
|
|
3385
3983
|
loadCalibrationCurve: () => loadCalibrationCurve,
|
|
@@ -3391,15 +3989,16 @@ __export(fs_exports, {
|
|
|
3391
3989
|
sessionIdFromFileName: () => sessionIdFromFileName,
|
|
3392
3990
|
walkJsonlFiles: () => walkJsonlFiles
|
|
3393
3991
|
});
|
|
3394
|
-
import { promises as
|
|
3395
|
-
import
|
|
3396
|
-
import
|
|
3992
|
+
import { promises as fs4 } from "node:fs";
|
|
3993
|
+
import os4 from "node:os";
|
|
3994
|
+
import path4 from "node:path";
|
|
3397
3995
|
function cacheStats() {
|
|
3398
3996
|
return claudeCodeCacheStats();
|
|
3399
3997
|
}
|
|
3400
3998
|
function clearCaches() {
|
|
3401
3999
|
clearClaudeCodeCaches();
|
|
3402
4000
|
clearCodexCaches();
|
|
4001
|
+
clearGeminiCaches();
|
|
3403
4002
|
}
|
|
3404
4003
|
function invalidateFile(fullPath) {
|
|
3405
4004
|
invalidateClaudeCodeFile(fullPath);
|
|
@@ -3428,7 +4027,7 @@ async function getAnySession(id) {
|
|
|
3428
4027
|
async function loadUsageByDay(start2, end) {
|
|
3429
4028
|
let raw;
|
|
3430
4029
|
try {
|
|
3431
|
-
raw = await
|
|
4030
|
+
raw = await fs4.readFile(USAGE_LOG2, "utf8");
|
|
3432
4031
|
} catch {
|
|
3433
4032
|
return { by_day: [] };
|
|
3434
4033
|
}
|
|
@@ -3473,7 +4072,7 @@ async function loadUsageByDay(start2, end) {
|
|
|
3473
4072
|
async function loadCalibrationSnapshots() {
|
|
3474
4073
|
let raw;
|
|
3475
4074
|
try {
|
|
3476
|
-
raw = await
|
|
4075
|
+
raw = await fs4.readFile(USAGE_LOG2, "utf8");
|
|
3477
4076
|
} catch {
|
|
3478
4077
|
return [];
|
|
3479
4078
|
}
|
|
@@ -3631,7 +4230,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
|
|
|
3631
4230
|
]);
|
|
3632
4231
|
return buildCalibrationCurve(events, snapshots, tier, granularityMin);
|
|
3633
4232
|
}
|
|
3634
|
-
var codexSource, agentSources, USAGE_LOG2;
|
|
4233
|
+
var codexSource, geminiSource, agentSources, USAGE_LOG2;
|
|
3635
4234
|
var init_fs = __esm({
|
|
3636
4235
|
"../parser/dist/fs.js"() {
|
|
3637
4236
|
"use strict";
|
|
@@ -3640,8 +4239,10 @@ var init_fs = __esm({
|
|
|
3640
4239
|
init_calibration();
|
|
3641
4240
|
init_claude_code();
|
|
3642
4241
|
init_codex();
|
|
4242
|
+
init_gemini();
|
|
3643
4243
|
init_claude_code();
|
|
3644
4244
|
init_codex();
|
|
4245
|
+
init_gemini();
|
|
3645
4246
|
codexSource = {
|
|
3646
4247
|
...CODEX_METADATA,
|
|
3647
4248
|
defaultRoot: DEFAULT_CODEX_ROOT,
|
|
@@ -3663,8 +4264,18 @@ var init_fs = __esm({
|
|
|
3663
4264
|
};
|
|
3664
4265
|
}
|
|
3665
4266
|
};
|
|
3666
|
-
|
|
3667
|
-
|
|
4267
|
+
geminiSource = {
|
|
4268
|
+
...GEMINI_METADATA,
|
|
4269
|
+
defaultRoot: DEFAULT_GEMINI_ROOT,
|
|
4270
|
+
async listSessions(opts) {
|
|
4271
|
+
return listGeminiSessions(opts);
|
|
4272
|
+
},
|
|
4273
|
+
async getSession(id) {
|
|
4274
|
+
return getGeminiSession(id);
|
|
4275
|
+
}
|
|
4276
|
+
};
|
|
4277
|
+
agentSources = [claudeCodeSource, codexSource, geminiSource];
|
|
4278
|
+
USAGE_LOG2 = path4.join(os4.homedir(), ".cclens", "usage.jsonl");
|
|
3668
4279
|
}
|
|
3669
4280
|
});
|
|
3670
4281
|
|
|
@@ -3986,15 +4597,489 @@ var init_types = __esm({
|
|
|
3986
4597
|
}
|
|
3987
4598
|
});
|
|
3988
4599
|
|
|
4600
|
+
// ../parser/dist/types.js
|
|
4601
|
+
var init_types2 = __esm({
|
|
4602
|
+
"../parser/dist/types.js"() {
|
|
4603
|
+
"use strict";
|
|
4604
|
+
}
|
|
4605
|
+
});
|
|
4606
|
+
|
|
4607
|
+
// ../parser/dist/presentation.js
|
|
4608
|
+
function rowPrimaryIndex(r) {
|
|
4609
|
+
if (r.kind === "tool-group")
|
|
4610
|
+
return r.events[0].index;
|
|
4611
|
+
return r.event.index;
|
|
4612
|
+
}
|
|
4613
|
+
function buildMegaRows(rows) {
|
|
4614
|
+
const out = [];
|
|
4615
|
+
let buffer = [];
|
|
4616
|
+
const flush = () => {
|
|
4617
|
+
if (buffer.length === 0)
|
|
4618
|
+
return;
|
|
4619
|
+
let agentMessages = 0;
|
|
4620
|
+
let toolCalls = 0;
|
|
4621
|
+
let errors = 0;
|
|
4622
|
+
let firstAgentIndex;
|
|
4623
|
+
const toolMap = /* @__PURE__ */ new Map();
|
|
4624
|
+
const seenMsgIds = /* @__PURE__ */ new Set();
|
|
4625
|
+
const tokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
4626
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
4627
|
+
const r = buffer[i];
|
|
4628
|
+
if (r.kind === "agent") {
|
|
4629
|
+
agentMessages++;
|
|
4630
|
+
if (firstAgentIndex === void 0)
|
|
4631
|
+
firstAgentIndex = i;
|
|
4632
|
+
const msgId = r.event.messageId;
|
|
4633
|
+
const usage2 = r.event.usage;
|
|
4634
|
+
if (msgId && !seenMsgIds.has(msgId) && usage2) {
|
|
4635
|
+
seenMsgIds.add(msgId);
|
|
4636
|
+
tokens.input += usage2.input;
|
|
4637
|
+
tokens.output += usage2.output;
|
|
4638
|
+
tokens.cacheRead += usage2.cacheRead;
|
|
4639
|
+
tokens.cacheWrite += usage2.cacheWrite;
|
|
4640
|
+
}
|
|
4641
|
+
} else if (r.kind === "tool-group") {
|
|
4642
|
+
toolCalls += r.count;
|
|
4643
|
+
for (const t of r.toolNames) {
|
|
4644
|
+
toolMap.set(t.name, (toolMap.get(t.name) ?? 0) + t.count);
|
|
4645
|
+
}
|
|
4646
|
+
} else if (r.kind === "error") {
|
|
4647
|
+
errors++;
|
|
4648
|
+
}
|
|
4649
|
+
}
|
|
4650
|
+
let finalAgentIndex;
|
|
4651
|
+
for (let i = buffer.length - 1; i >= 0; i--) {
|
|
4652
|
+
const r = buffer[i];
|
|
4653
|
+
if (r.kind !== "agent")
|
|
4654
|
+
continue;
|
|
4655
|
+
const prev = buffer[i - 1];
|
|
4656
|
+
if (prev?.kind === "task-notification")
|
|
4657
|
+
continue;
|
|
4658
|
+
finalAgentIndex = i;
|
|
4659
|
+
break;
|
|
4660
|
+
}
|
|
4661
|
+
if (finalAgentIndex === void 0) {
|
|
4662
|
+
for (let i = buffer.length - 1; i >= 0; i--) {
|
|
4663
|
+
if (buffer[i].kind === "agent") {
|
|
4664
|
+
finalAgentIndex = i;
|
|
4665
|
+
break;
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
const firstAgentPreview = firstAgentIndex !== void 0 && buffer[firstAgentIndex].kind === "agent" ? buffer[firstAgentIndex].event.preview : void 0;
|
|
4670
|
+
const finalAgentPreview = finalAgentIndex !== void 0 && buffer[finalAgentIndex].kind === "agent" ? buffer[finalAgentIndex].event.preview : void 0;
|
|
4671
|
+
const toolNames = Array.from(toolMap.entries()).sort((a, b) => b[1] - a[1]).map(([name, count]) => ({ name, count }));
|
|
4672
|
+
const first = buffer[0];
|
|
4673
|
+
const last = buffer[buffer.length - 1];
|
|
4674
|
+
const start2 = first.tOffsetMs;
|
|
4675
|
+
const end = last.tOffsetMs;
|
|
4676
|
+
const durationMs = start2 !== void 0 && end !== void 0 ? end - start2 : void 0;
|
|
4677
|
+
out.push({
|
|
4678
|
+
kind: "turn",
|
|
4679
|
+
rows: buffer,
|
|
4680
|
+
firstPrimaryIndex: rowPrimaryIndex(first),
|
|
4681
|
+
tOffsetMs: start2,
|
|
4682
|
+
durationMs,
|
|
4683
|
+
summary: {
|
|
4684
|
+
agentMessages,
|
|
4685
|
+
toolCalls,
|
|
4686
|
+
errors,
|
|
4687
|
+
firstAgentPreview,
|
|
4688
|
+
finalAgentPreview,
|
|
4689
|
+
firstAgentIndex,
|
|
4690
|
+
finalAgentIndex,
|
|
4691
|
+
toolNames,
|
|
4692
|
+
totalTokens: tokens
|
|
4693
|
+
}
|
|
4694
|
+
});
|
|
4695
|
+
buffer = [];
|
|
4696
|
+
};
|
|
4697
|
+
for (const r of rows) {
|
|
4698
|
+
if (r.kind === "user" || r.kind === "interrupt") {
|
|
4699
|
+
flush();
|
|
4700
|
+
out.push(r);
|
|
4701
|
+
} else {
|
|
4702
|
+
buffer.push(r);
|
|
4703
|
+
}
|
|
4704
|
+
}
|
|
4705
|
+
flush();
|
|
4706
|
+
return out;
|
|
4707
|
+
}
|
|
4708
|
+
function parseTaskNotification(text) {
|
|
4709
|
+
if (!TASK_NOTIFICATION_RE.test(text))
|
|
4710
|
+
return null;
|
|
4711
|
+
const pick = (tag) => {
|
|
4712
|
+
const m = text.match(new RegExp(`<${tag}>([\\s\\S]*?)<\\/${tag}>`));
|
|
4713
|
+
return m ? m[1].trim() : void 0;
|
|
4714
|
+
};
|
|
4715
|
+
const statusRaw = (pick("status") ?? "").toLowerCase();
|
|
4716
|
+
let status2 = "unknown";
|
|
4717
|
+
if (statusRaw === "success" || statusRaw === "ok" || statusRaw === "done" || statusRaw === "completed")
|
|
4718
|
+
status2 = "success";
|
|
4719
|
+
else if (statusRaw === "failed" || statusRaw === "error" || statusRaw === "fail")
|
|
4720
|
+
status2 = "failed";
|
|
4721
|
+
else if (statusRaw === "running" || statusRaw === "in_progress")
|
|
4722
|
+
status2 = "running";
|
|
4723
|
+
return {
|
|
4724
|
+
status: status2,
|
|
4725
|
+
summary: pick("summary") ?? "Background task notification",
|
|
4726
|
+
taskId: pick("task-id"),
|
|
4727
|
+
toolUseId: pick("tool-use-id"),
|
|
4728
|
+
outputFile: pick("output-file")
|
|
4729
|
+
};
|
|
4730
|
+
}
|
|
4731
|
+
function isAttachmentOrMeta(e) {
|
|
4732
|
+
return e.role === "system" || e.role === "meta";
|
|
4733
|
+
}
|
|
4734
|
+
function firstTextOfBlocks(blocks) {
|
|
4735
|
+
for (const b of blocks) {
|
|
4736
|
+
if (b?.type === "text")
|
|
4737
|
+
return b.text;
|
|
4738
|
+
}
|
|
4739
|
+
return void 0;
|
|
4740
|
+
}
|
|
4741
|
+
function hasZeroUsage(e) {
|
|
4742
|
+
if (!e.usage)
|
|
4743
|
+
return false;
|
|
4744
|
+
const u = e.usage;
|
|
4745
|
+
return u.input === 0 && u.output === 0 && u.cacheRead === 0 && u.cacheWrite === 0;
|
|
4746
|
+
}
|
|
4747
|
+
function buildPresentation(events) {
|
|
4748
|
+
const byMessageId = /* @__PURE__ */ new Map();
|
|
4749
|
+
for (const e of events) {
|
|
4750
|
+
if (!e.messageId)
|
|
4751
|
+
continue;
|
|
4752
|
+
const list = byMessageId.get(e.messageId) ?? [];
|
|
4753
|
+
list.push(e);
|
|
4754
|
+
byMessageId.set(e.messageId, list);
|
|
4755
|
+
}
|
|
4756
|
+
const visible = events.filter((e) => {
|
|
4757
|
+
if (isAttachmentOrMeta(e))
|
|
4758
|
+
return false;
|
|
4759
|
+
if (e.role === "tool-result")
|
|
4760
|
+
return false;
|
|
4761
|
+
if (e.role === "agent-thinking")
|
|
4762
|
+
return false;
|
|
4763
|
+
if (e.role === "user") {
|
|
4764
|
+
const txt = firstTextOfBlocks(e.blocks) ?? "";
|
|
4765
|
+
if (e.blocks.length === 0 || !txt.trim())
|
|
4766
|
+
return false;
|
|
4767
|
+
if (SLASH_COMMAND_RE.test(txt))
|
|
4768
|
+
return true;
|
|
4769
|
+
if (TASK_NOTIFICATION_RE.test(txt))
|
|
4770
|
+
return true;
|
|
4771
|
+
if (isFrameworkInjectedUserInput(txt))
|
|
4772
|
+
return false;
|
|
4773
|
+
}
|
|
4774
|
+
return true;
|
|
4775
|
+
});
|
|
4776
|
+
const rows = [];
|
|
4777
|
+
for (let i = 0; i < visible.length; i++) {
|
|
4778
|
+
const e = visible[i];
|
|
4779
|
+
if (e.role === "tool-call") {
|
|
4780
|
+
const start2 = i;
|
|
4781
|
+
while (i + 1 < visible.length && visible[i + 1].role === "tool-call") {
|
|
4782
|
+
i++;
|
|
4783
|
+
}
|
|
4784
|
+
const group = visible.slice(start2, i + 1);
|
|
4785
|
+
const order = [];
|
|
4786
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4787
|
+
for (const ev of group) {
|
|
4788
|
+
const name = ev.toolName ?? "tool";
|
|
4789
|
+
if (!counts.has(name))
|
|
4790
|
+
order.push(name);
|
|
4791
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
4792
|
+
}
|
|
4793
|
+
const toolNames = order.map((name) => ({
|
|
4794
|
+
name,
|
|
4795
|
+
count: counts.get(name) ?? 1
|
|
4796
|
+
}));
|
|
4797
|
+
rows.push({
|
|
4798
|
+
kind: "tool-group",
|
|
4799
|
+
toolNames,
|
|
4800
|
+
count: group.length,
|
|
4801
|
+
events: group,
|
|
4802
|
+
tOffsetMs: group[0].tOffsetMs,
|
|
4803
|
+
gapMs: group[0].gapMs
|
|
4804
|
+
});
|
|
4805
|
+
continue;
|
|
4806
|
+
}
|
|
4807
|
+
if (e.role === "user") {
|
|
4808
|
+
const txt = firstTextOfBlocks(e.blocks) ?? "";
|
|
4809
|
+
const taskNotif = parseTaskNotification(txt);
|
|
4810
|
+
if (taskNotif) {
|
|
4811
|
+
rows.push({
|
|
4812
|
+
kind: "task-notification",
|
|
4813
|
+
event: e,
|
|
4814
|
+
status: taskNotif.status,
|
|
4815
|
+
summary: taskNotif.summary,
|
|
4816
|
+
taskId: taskNotif.taskId,
|
|
4817
|
+
toolUseId: taskNotif.toolUseId,
|
|
4818
|
+
outputFile: taskNotif.outputFile,
|
|
4819
|
+
tOffsetMs: e.tOffsetMs,
|
|
4820
|
+
gapMs: e.gapMs
|
|
4821
|
+
});
|
|
4822
|
+
continue;
|
|
4823
|
+
}
|
|
4824
|
+
if (INTERRUPT_RE.test(txt)) {
|
|
4825
|
+
rows.push({
|
|
4826
|
+
kind: "interrupt",
|
|
4827
|
+
event: e,
|
|
4828
|
+
tOffsetMs: e.tOffsetMs,
|
|
4829
|
+
gapMs: e.gapMs
|
|
4830
|
+
});
|
|
4831
|
+
continue;
|
|
4832
|
+
}
|
|
4833
|
+
const slashMatch = txt.match(SLASH_COMMAND_RE);
|
|
4834
|
+
if (slashMatch) {
|
|
4835
|
+
const cmd = slashMatch[1];
|
|
4836
|
+
const args2 = (slashMatch[2] ?? "").trim();
|
|
4837
|
+
const pretty = args2 ? `${cmd} ${args2}` : cmd;
|
|
4838
|
+
rows.push({
|
|
4839
|
+
kind: "user",
|
|
4840
|
+
event: e,
|
|
4841
|
+
displayPreview: pretty,
|
|
4842
|
+
displayBlocks: [{ type: "text", text: pretty }],
|
|
4843
|
+
tOffsetMs: e.tOffsetMs,
|
|
4844
|
+
gapMs: e.gapMs
|
|
4845
|
+
});
|
|
4846
|
+
continue;
|
|
4847
|
+
}
|
|
4848
|
+
rows.push({
|
|
4849
|
+
kind: "user",
|
|
4850
|
+
event: e,
|
|
4851
|
+
tOffsetMs: e.tOffsetMs,
|
|
4852
|
+
gapMs: e.gapMs
|
|
4853
|
+
});
|
|
4854
|
+
continue;
|
|
4855
|
+
}
|
|
4856
|
+
if (e.role === "agent") {
|
|
4857
|
+
const txt = firstTextOfBlocks(e.blocks) ?? "";
|
|
4858
|
+
if (hasZeroUsage(e)) {
|
|
4859
|
+
rows.push({
|
|
4860
|
+
kind: "model",
|
|
4861
|
+
event: e,
|
|
4862
|
+
tOffsetMs: e.tOffsetMs,
|
|
4863
|
+
gapMs: e.gapMs
|
|
4864
|
+
});
|
|
4865
|
+
if (RATE_LIMIT_RE.test(txt) && txt.length < 500) {
|
|
4866
|
+
rows.push({
|
|
4867
|
+
kind: "error",
|
|
4868
|
+
event: e,
|
|
4869
|
+
message: txt,
|
|
4870
|
+
tOffsetMs: e.tOffsetMs,
|
|
4871
|
+
gapMs: 0
|
|
4872
|
+
});
|
|
4873
|
+
}
|
|
4874
|
+
continue;
|
|
4875
|
+
}
|
|
4876
|
+
if (RATE_LIMIT_RE.test(txt) && txt.length < 500) {
|
|
4877
|
+
rows.push({
|
|
4878
|
+
kind: "error",
|
|
4879
|
+
event: e,
|
|
4880
|
+
message: txt,
|
|
4881
|
+
tOffsetMs: e.tOffsetMs,
|
|
4882
|
+
gapMs: e.gapMs
|
|
4883
|
+
});
|
|
4884
|
+
continue;
|
|
4885
|
+
}
|
|
4886
|
+
const grouped = e.messageId ? byMessageId.get(e.messageId) ?? [e] : [e];
|
|
4887
|
+
rows.push({
|
|
4888
|
+
kind: "agent",
|
|
4889
|
+
event: e,
|
|
4890
|
+
groupedEvents: grouped,
|
|
4891
|
+
tOffsetMs: e.tOffsetMs,
|
|
4892
|
+
gapMs: e.gapMs
|
|
4893
|
+
});
|
|
4894
|
+
continue;
|
|
4895
|
+
}
|
|
4896
|
+
}
|
|
4897
|
+
return rows;
|
|
4898
|
+
}
|
|
4899
|
+
var INTERRUPT_RE, RATE_LIMIT_RE, SLASH_COMMAND_RE, TASK_NOTIFICATION_RE;
|
|
4900
|
+
var init_presentation = __esm({
|
|
4901
|
+
"../parser/dist/presentation.js"() {
|
|
4902
|
+
"use strict";
|
|
4903
|
+
init_user_input();
|
|
4904
|
+
INTERRUPT_RE = /\[request interrupted|interrupted by user/i;
|
|
4905
|
+
RATE_LIMIT_RE = /rate.?limit|overloaded_error|api error|Error sending message/i;
|
|
4906
|
+
SLASH_COMMAND_RE = /<command-name>(\/[^<\s]+)<\/command-name>(?:[\s\S]*?<command-args>([\s\S]*?)<\/command-args>)?/;
|
|
4907
|
+
TASK_NOTIFICATION_RE = /<task-notification>/;
|
|
4908
|
+
}
|
|
4909
|
+
});
|
|
4910
|
+
|
|
4911
|
+
// ../parser/dist/aggregate.js
|
|
4912
|
+
function isoDay(d) {
|
|
4913
|
+
return toLocalDay(d.getTime());
|
|
4914
|
+
}
|
|
4915
|
+
function rangeDays(start2, end) {
|
|
4916
|
+
const out = [];
|
|
4917
|
+
const cur = new Date(start2.getFullYear(), start2.getMonth(), start2.getDate());
|
|
4918
|
+
const stop2 = new Date(end.getFullYear(), end.getMonth(), end.getDate());
|
|
4919
|
+
while (cur.getTime() <= stop2.getTime()) {
|
|
4920
|
+
out.push(new Date(cur));
|
|
4921
|
+
cur.setDate(cur.getDate() + 1);
|
|
4922
|
+
}
|
|
4923
|
+
return out;
|
|
4924
|
+
}
|
|
4925
|
+
function calendarWeek(ref = /* @__PURE__ */ new Date()) {
|
|
4926
|
+
const d = new Date(ref.getFullYear(), ref.getMonth(), ref.getDate());
|
|
4927
|
+
const dow = d.getDay();
|
|
4928
|
+
const daysSinceMon = (dow + 6) % 7;
|
|
4929
|
+
const monday = new Date(d);
|
|
4930
|
+
monday.setDate(d.getDate() - daysSinceMon);
|
|
4931
|
+
const sunday = new Date(monday);
|
|
4932
|
+
sunday.setDate(monday.getDate() + 6);
|
|
4933
|
+
return { start: monday, end: sunday };
|
|
4934
|
+
}
|
|
4935
|
+
function priorCalendarWeek(ref = /* @__PURE__ */ new Date()) {
|
|
4936
|
+
const cur = calendarWeek(ref);
|
|
4937
|
+
const prevEnd = new Date(cur.start);
|
|
4938
|
+
prevEnd.setDate(cur.start.getDate() - 1);
|
|
4939
|
+
const prevStart = new Date(prevEnd);
|
|
4940
|
+
prevStart.setDate(prevEnd.getDate() - 6);
|
|
4941
|
+
return { start: prevStart, end: prevEnd };
|
|
4942
|
+
}
|
|
4943
|
+
function last4CompletedWeeks(ref = /* @__PURE__ */ new Date()) {
|
|
4944
|
+
const { end } = priorCalendarWeek(ref);
|
|
4945
|
+
const start2 = new Date(end);
|
|
4946
|
+
start2.setDate(end.getDate() - 27);
|
|
4947
|
+
return { start: start2, end };
|
|
4948
|
+
}
|
|
4949
|
+
function calendarMonth(ref = /* @__PURE__ */ new Date()) {
|
|
4950
|
+
const start2 = new Date(ref.getFullYear(), ref.getMonth(), 1);
|
|
4951
|
+
const end = new Date(ref.getFullYear(), ref.getMonth() + 1, 0);
|
|
4952
|
+
return { start: start2, end };
|
|
4953
|
+
}
|
|
4954
|
+
function priorCalendarMonth(ref = /* @__PURE__ */ new Date()) {
|
|
4955
|
+
const start2 = new Date(ref.getFullYear(), ref.getMonth() - 1, 1);
|
|
4956
|
+
const end = new Date(ref.getFullYear(), ref.getMonth(), 0);
|
|
4957
|
+
return { start: start2, end };
|
|
4958
|
+
}
|
|
4959
|
+
function aggregateConcurrency(bursts, period) {
|
|
4960
|
+
const days = rangeDays(period.start, period.end);
|
|
4961
|
+
const byDayKey = /* @__PURE__ */ new Map();
|
|
4962
|
+
for (const d of days)
|
|
4963
|
+
byDayKey.set(isoDay(d), { peak: 0, has_cross_project: false });
|
|
4964
|
+
for (const b of bursts) {
|
|
4965
|
+
const dayKey = isoDay(new Date(b.startMs));
|
|
4966
|
+
const cur = byDayKey.get(dayKey);
|
|
4967
|
+
if (!cur)
|
|
4968
|
+
continue;
|
|
4969
|
+
if (b.peak > cur.peak)
|
|
4970
|
+
cur.peak = b.peak;
|
|
4971
|
+
if (b.crossProject)
|
|
4972
|
+
cur.has_cross_project = true;
|
|
4973
|
+
}
|
|
4974
|
+
const by_day = days.map((d) => {
|
|
4975
|
+
const k = isoDay(d);
|
|
4976
|
+
const v = byDayKey.get(k);
|
|
4977
|
+
return { date: k, peak: v.peak, has_cross_project: v.has_cross_project };
|
|
4978
|
+
});
|
|
4979
|
+
let peak = 0;
|
|
4980
|
+
let peak_day;
|
|
4981
|
+
let multi_agent_days = 0;
|
|
4982
|
+
let cross_project_days = 0;
|
|
4983
|
+
for (const d of by_day) {
|
|
4984
|
+
if (d.peak > peak) {
|
|
4985
|
+
peak = d.peak;
|
|
4986
|
+
peak_day = d.date;
|
|
4987
|
+
}
|
|
4988
|
+
if (d.peak >= 3)
|
|
4989
|
+
multi_agent_days++;
|
|
4990
|
+
if (d.has_cross_project)
|
|
4991
|
+
cross_project_days++;
|
|
4992
|
+
}
|
|
4993
|
+
return { by_day, peak, peak_day, multi_agent_days, cross_project_days };
|
|
4994
|
+
}
|
|
4995
|
+
var init_aggregate = __esm({
|
|
4996
|
+
"../parser/dist/aggregate.js"() {
|
|
4997
|
+
"use strict";
|
|
4998
|
+
init_analytics();
|
|
4999
|
+
}
|
|
5000
|
+
});
|
|
5001
|
+
|
|
5002
|
+
// ../parser/dist/index.js
|
|
5003
|
+
var dist_exports = {};
|
|
5004
|
+
__export(dist_exports, {
|
|
5005
|
+
CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
|
|
5006
|
+
CODEX_METADATA: () => CODEX_METADATA,
|
|
5007
|
+
GEMINI_METADATA: () => GEMINI_METADATA,
|
|
5008
|
+
PRICES: () => PRICES,
|
|
5009
|
+
RATE_PER_PCT: () => RATE_PER_PCT,
|
|
5010
|
+
RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
|
|
5011
|
+
RATE_PER_PCT_7D: () => RATE_PER_PCT_7D,
|
|
5012
|
+
agentMetadata: () => agentMetadata,
|
|
5013
|
+
aggregateConcurrency: () => aggregateConcurrency,
|
|
5014
|
+
buildGanttDay: () => buildGanttDay,
|
|
5015
|
+
buildMegaRows: () => buildMegaRows,
|
|
5016
|
+
buildPresentation: () => buildPresentation,
|
|
5017
|
+
buildSpendIndex: () => buildSpendIndex,
|
|
5018
|
+
calendarMonth: () => calendarMonth,
|
|
5019
|
+
calendarWeek: () => calendarWeek,
|
|
5020
|
+
canonicalProjectName: () => canonicalProjectName,
|
|
5021
|
+
collectSnapPairRates: () => collectSnapPairRates,
|
|
5022
|
+
computeActiveSegments: () => computeActiveSegments,
|
|
5023
|
+
computeBurstsFromSessions: () => computeBurstsFromSessions,
|
|
5024
|
+
computeParallelism: () => computeParallelism,
|
|
5025
|
+
computeParallelismBursts: () => computeParallelismBursts,
|
|
5026
|
+
dailyActivity: () => dailyActivity,
|
|
5027
|
+
daysBetween: () => daysBetween,
|
|
5028
|
+
detectParallelRuns: () => detectParallelRuns,
|
|
5029
|
+
detectPrMarkers: () => detectPrMarkers,
|
|
5030
|
+
dollarsInRange: () => dollarsInRange,
|
|
5031
|
+
dollarsInWindow: () => dollarsInWindow,
|
|
5032
|
+
eventDollars: () => eventDollars,
|
|
5033
|
+
getAgentMetadata: () => getAgentMetadata,
|
|
5034
|
+
groupByProject: () => groupByProject,
|
|
5035
|
+
groupByTeam: () => groupByTeam,
|
|
5036
|
+
groupSnapsByCycle: () => groupSnapsByCycle,
|
|
5037
|
+
highLevelMetrics: () => highLevelMetrics,
|
|
5038
|
+
isAgentKind: () => isAgentKind,
|
|
5039
|
+
isFrameworkInjectedUserInput: () => isFrameworkInjectedUserInput,
|
|
5040
|
+
last4CompletedWeeks: () => last4CompletedWeeks,
|
|
5041
|
+
modelFamily: () => modelFamily,
|
|
5042
|
+
parseTranscript: () => parseTranscript,
|
|
5043
|
+
predictAnchored: () => predictAnchored,
|
|
5044
|
+
predictUtilization: () => predictUtilization,
|
|
5045
|
+
priorCalendarMonth: () => priorCalendarMonth,
|
|
5046
|
+
priorCalendarWeek: () => priorCalendarWeek,
|
|
5047
|
+
rowPrimaryIndex: () => rowPrimaryIndex,
|
|
5048
|
+
sessionAirTimeMs: () => sessionAirTimeMs,
|
|
5049
|
+
sessionDay: () => sessionDay,
|
|
5050
|
+
stripFrameworkBoilerplate: () => stripFrameworkBoilerplate,
|
|
5051
|
+
summarizeBursts: () => summarizeBursts,
|
|
5052
|
+
toLocalDay: () => toLocalDay,
|
|
5053
|
+
userSoloRate: () => userSoloRate,
|
|
5054
|
+
worktreeName: () => worktreeName
|
|
5055
|
+
});
|
|
5056
|
+
var init_dist = __esm({
|
|
5057
|
+
"../parser/dist/index.js"() {
|
|
5058
|
+
"use strict";
|
|
5059
|
+
init_types2();
|
|
5060
|
+
init_parser();
|
|
5061
|
+
init_user_input();
|
|
5062
|
+
init_presentation();
|
|
5063
|
+
init_analytics();
|
|
5064
|
+
init_aggregate();
|
|
5065
|
+
init_calibration();
|
|
5066
|
+
init_agent_metadata();
|
|
5067
|
+
init_team();
|
|
5068
|
+
}
|
|
5069
|
+
});
|
|
5070
|
+
|
|
3989
5071
|
// ../entries/dist/signals.js
|
|
3990
5072
|
function classifyUserInputSource(text) {
|
|
3991
5073
|
if (!text)
|
|
3992
5074
|
return "human";
|
|
3993
|
-
|
|
5075
|
+
const stripped = stripFrameworkBoilerplate(text);
|
|
5076
|
+
if (!stripped)
|
|
5077
|
+
return "system_instruction";
|
|
5078
|
+
if (TEAMMATE_RE.test(stripped))
|
|
3994
5079
|
return "teammate";
|
|
3995
|
-
if (SKILL_LOAD_RE.test(
|
|
5080
|
+
if (SKILL_LOAD_RE.test(stripped))
|
|
3996
5081
|
return "skill_load";
|
|
3997
|
-
if (
|
|
5082
|
+
if (SLASH_COMMAND_RE2.test(stripped))
|
|
3998
5083
|
return "slash_command";
|
|
3999
5084
|
return "human";
|
|
4000
5085
|
}
|
|
@@ -4135,13 +5220,14 @@ function computeEntrySignals(entry) {
|
|
|
4135
5220
|
continuation_kind
|
|
4136
5221
|
};
|
|
4137
5222
|
}
|
|
4138
|
-
var TEAMMATE_RE, SKILL_LOAD_RE,
|
|
5223
|
+
var TEAMMATE_RE, SKILL_LOAD_RE, SLASH_COMMAND_RE2, STOCK_SUBAGENT_PREFIXES, STOCK_SKILL_PREFIXES, EXTERNAL_REF_PATTERNS;
|
|
4139
5224
|
var init_signals = __esm({
|
|
4140
5225
|
"../entries/dist/signals.js"() {
|
|
4141
5226
|
"use strict";
|
|
5227
|
+
init_dist();
|
|
4142
5228
|
TEAMMATE_RE = /^<teammate-message\b/;
|
|
4143
5229
|
SKILL_LOAD_RE = /^Base directory for this skill:/;
|
|
4144
|
-
|
|
5230
|
+
SLASH_COMMAND_RE2 = /^<command-name>|^<local-command-stdout>/;
|
|
4145
5231
|
STOCK_SUBAGENT_PREFIXES = /^(general-purpose|Explore|Plan|claude-code-guide|playwright-qa-verifier|statusline-setup|frontend-design:|code-review:|code-simplifier:|codex:|superpowers:)/;
|
|
4146
5232
|
STOCK_SKILL_PREFIXES = /^(superpowers|mcp__|frontend-design|code-review|codex|claude-code-guide|claude-api):/i;
|
|
4147
5233
|
EXTERNAL_REF_PATTERNS = [
|
|
@@ -4161,7 +5247,7 @@ var init_trivial = __esm({
|
|
|
4161
5247
|
});
|
|
4162
5248
|
|
|
4163
5249
|
// ../entries/dist/build.js
|
|
4164
|
-
var
|
|
5250
|
+
var IDLE_GAP_MS3;
|
|
4165
5251
|
var init_build = __esm({
|
|
4166
5252
|
"../entries/dist/build.js"() {
|
|
4167
5253
|
"use strict";
|
|
@@ -4169,7 +5255,7 @@ var init_build = __esm({
|
|
|
4169
5255
|
init_types();
|
|
4170
5256
|
init_signals();
|
|
4171
5257
|
init_trivial();
|
|
4172
|
-
|
|
5258
|
+
IDLE_GAP_MS3 = 3 * 60 * 1e3;
|
|
4173
5259
|
}
|
|
4174
5260
|
});
|
|
4175
5261
|
|
|
@@ -4181,7 +5267,7 @@ var init_flag_glossary = __esm({
|
|
|
4181
5267
|
});
|
|
4182
5268
|
|
|
4183
5269
|
// ../entries/dist/index.js
|
|
4184
|
-
var
|
|
5270
|
+
var init_dist2 = __esm({
|
|
4185
5271
|
"../entries/dist/index.js"() {
|
|
4186
5272
|
"use strict";
|
|
4187
5273
|
init_types();
|
|
@@ -4203,11 +5289,11 @@ function digestsDir() {
|
|
|
4203
5289
|
digestsDirCached = envOverride ?? join6(homedir5(), ".cclens", "digests");
|
|
4204
5290
|
return digestsDirCached;
|
|
4205
5291
|
}
|
|
4206
|
-
function __setDigestsDirForTest(
|
|
4207
|
-
digestsDirCached =
|
|
4208
|
-
mkdirSync3(join6(
|
|
4209
|
-
mkdirSync3(join6(
|
|
4210
|
-
mkdirSync3(join6(
|
|
5292
|
+
function __setDigestsDirForTest(path5) {
|
|
5293
|
+
digestsDirCached = path5;
|
|
5294
|
+
mkdirSync3(join6(path5, "day"), { recursive: true });
|
|
5295
|
+
mkdirSync3(join6(path5, "week"), { recursive: true });
|
|
5296
|
+
mkdirSync3(join6(path5, "month"), { recursive: true });
|
|
4211
5297
|
}
|
|
4212
5298
|
function dayDigestPath(date) {
|
|
4213
5299
|
return join6(digestsDir(), "day", `${date}.json`);
|
|
@@ -4394,9 +5480,9 @@ function entriesDir() {
|
|
|
4394
5480
|
entriesDirCached = envOverride ?? join7(homedir6(), ".cclens", "entries");
|
|
4395
5481
|
return entriesDirCached;
|
|
4396
5482
|
}
|
|
4397
|
-
function __setEntriesDirForTest(
|
|
4398
|
-
entriesDirCached =
|
|
4399
|
-
mkdirSync4(
|
|
5483
|
+
function __setEntriesDirForTest(path5) {
|
|
5484
|
+
entriesDirCached = path5;
|
|
5485
|
+
mkdirSync4(path5, { recursive: true });
|
|
4400
5486
|
}
|
|
4401
5487
|
function pathFor(sessionId, localDay) {
|
|
4402
5488
|
return join7(entriesDir(), `${entryKey(sessionId, localDay)}.json`);
|
|
@@ -4931,8 +6017,8 @@ var init_parseUtil = __esm({
|
|
|
4931
6017
|
init_errors();
|
|
4932
6018
|
init_en();
|
|
4933
6019
|
makeIssue = (params) => {
|
|
4934
|
-
const { data, path:
|
|
4935
|
-
const fullPath = [...
|
|
6020
|
+
const { data, path: path5, errorMaps, issueData } = params;
|
|
6021
|
+
const fullPath = [...path5, ...issueData.path || []];
|
|
4936
6022
|
const fullIssue = {
|
|
4937
6023
|
...issueData,
|
|
4938
6024
|
path: fullPath
|
|
@@ -5232,7 +6318,7 @@ function custom(check, _params = {}, fatal) {
|
|
|
5232
6318
|
return ZodAny.create();
|
|
5233
6319
|
}
|
|
5234
6320
|
var ParseInputLazyPath, handleResult, ZodType, cuidRegex, cuid2Regex, ulidRegex, uuidRegex, nanoidRegex, jwtRegex, durationRegex, emailRegex, _emojiRegex, emojiRegex, ipv4Regex, ipv4CidrRegex, ipv6Regex, ipv6CidrRegex, base64Regex, base64urlRegex, dateRegexSource, dateRegex, ZodString, ZodNumber, ZodBigInt, ZodBoolean, ZodDate, ZodSymbol, ZodUndefined, ZodNull, ZodAny, ZodUnknown, ZodNever, ZodVoid, ZodArray, ZodObject, ZodUnion, getDiscriminator, ZodDiscriminatedUnion, ZodIntersection, ZodTuple, ZodRecord, ZodMap, ZodSet, ZodFunction, ZodLazy, ZodLiteral, ZodEnum, ZodNativeEnum, ZodPromise, ZodEffects, ZodOptional, ZodNullable, ZodDefault, ZodCatch, ZodNaN, BRAND, ZodBranded, ZodPipeline, ZodReadonly, late, ZodFirstPartyTypeKind, instanceOfType, stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType, ostring, onumber, oboolean, coerce, NEVER;
|
|
5235
|
-
var
|
|
6321
|
+
var init_types3 = __esm({
|
|
5236
6322
|
"../../node_modules/zod/v3/types.js"() {
|
|
5237
6323
|
init_ZodError();
|
|
5238
6324
|
init_errors();
|
|
@@ -5240,11 +6326,11 @@ var init_types2 = __esm({
|
|
|
5240
6326
|
init_parseUtil();
|
|
5241
6327
|
init_util();
|
|
5242
6328
|
ParseInputLazyPath = class {
|
|
5243
|
-
constructor(parent, value,
|
|
6329
|
+
constructor(parent, value, path5, key) {
|
|
5244
6330
|
this._cachedPath = [];
|
|
5245
6331
|
this.parent = parent;
|
|
5246
6332
|
this.data = value;
|
|
5247
|
-
this._path =
|
|
6333
|
+
this._path = path5;
|
|
5248
6334
|
this._key = key;
|
|
5249
6335
|
}
|
|
5250
6336
|
get path() {
|
|
@@ -8612,7 +9698,7 @@ var init_external = __esm({
|
|
|
8612
9698
|
init_parseUtil();
|
|
8613
9699
|
init_typeAliases();
|
|
8614
9700
|
init_util();
|
|
8615
|
-
|
|
9701
|
+
init_types3();
|
|
8616
9702
|
init_ZodError();
|
|
8617
9703
|
}
|
|
8618
9704
|
});
|
|
@@ -8765,15 +9851,15 @@ function newRunId(kind) {
|
|
|
8765
9851
|
function tracePath(runId) {
|
|
8766
9852
|
return join8(RUNS_DIR, `${runId}.jsonl`);
|
|
8767
9853
|
}
|
|
8768
|
-
function safeAppend(
|
|
9854
|
+
function safeAppend(path5, line) {
|
|
8769
9855
|
try {
|
|
8770
|
-
appendFileSync2(
|
|
9856
|
+
appendFileSync2(path5, line);
|
|
8771
9857
|
} catch {
|
|
8772
9858
|
}
|
|
8773
9859
|
}
|
|
8774
|
-
function safeWrite(
|
|
9860
|
+
function safeWrite(path5, line) {
|
|
8775
9861
|
try {
|
|
8776
|
-
writeFileSync4(
|
|
9862
|
+
writeFileSync4(path5, line);
|
|
8777
9863
|
} catch {
|
|
8778
9864
|
}
|
|
8779
9865
|
}
|
|
@@ -9068,783 +10154,322 @@ function applyEnrichmentSuccess(entry, resp, model, costUsd, generatedAt) {
|
|
|
9068
10154
|
};
|
|
9069
10155
|
return { ...entry, enrichment };
|
|
9070
10156
|
}
|
|
9071
|
-
function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt, rateLimited = false) {
|
|
9072
|
-
if (rateLimited) {
|
|
9073
|
-
const enrichment2 = {
|
|
9074
|
-
...entry.enrichment,
|
|
9075
|
-
status: "pending",
|
|
9076
|
-
generated_at: generatedAt,
|
|
9077
|
-
model,
|
|
9078
|
-
cost_usd: costUsd,
|
|
9079
|
-
error: errorMessage
|
|
9080
|
-
// retry_count NOT incremented on rate-limit.
|
|
9081
|
-
};
|
|
9082
|
-
return { ...entry, enrichment: enrichment2 };
|
|
9083
|
-
}
|
|
9084
|
-
const enrichment = {
|
|
9085
|
-
...entry.enrichment,
|
|
9086
|
-
status: "error",
|
|
9087
|
-
generated_at: generatedAt,
|
|
9088
|
-
model,
|
|
9089
|
-
cost_usd: costUsd,
|
|
9090
|
-
error: errorMessage,
|
|
9091
|
-
retry_count: (entry.enrichment.retry_count ?? 0) + 1
|
|
9092
|
-
};
|
|
9093
|
-
return { ...entry, enrichment };
|
|
9094
|
-
}
|
|
9095
|
-
var DEFAULT_MODEL;
|
|
9096
|
-
var init_enrich2 = __esm({
|
|
9097
|
-
"../entries/dist/enrich.js"() {
|
|
9098
|
-
"use strict";
|
|
9099
|
-
init_signals();
|
|
9100
|
-
init_enrich();
|
|
9101
|
-
init_llm_runner();
|
|
9102
|
-
DEFAULT_MODEL = "sonnet";
|
|
9103
|
-
}
|
|
9104
|
-
});
|
|
9105
|
-
|
|
9106
|
-
// ../entries/dist/budget.js
|
|
9107
|
-
import { appendFileSync as appendFileSync3, readFileSync as readFileSync8, existsSync as existsSync8, mkdirSync as mkdirSync6 } from "node:fs";
|
|
9108
|
-
import { dirname as dirname7, join as join9 } from "node:path";
|
|
9109
|
-
import { homedir as homedir8 } from "node:os";
|
|
9110
|
-
function spendPath() {
|
|
9111
|
-
if (spendPathCached)
|
|
9112
|
-
return spendPathCached;
|
|
9113
|
-
spendPathCached = join9(homedir8(), ".cclens", "llm-spend.jsonl");
|
|
9114
|
-
return spendPathCached;
|
|
9115
|
-
}
|
|
9116
|
-
function __setSpendPathForTest(path4) {
|
|
9117
|
-
spendPathCached = path4;
|
|
9118
|
-
}
|
|
9119
|
-
function appendSpend(record) {
|
|
9120
|
-
const p = spendPath();
|
|
9121
|
-
mkdirSync6(dirname7(p), { recursive: true });
|
|
9122
|
-
appendFileSync3(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
9123
|
-
}
|
|
9124
|
-
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
9125
|
-
const p = spendPath();
|
|
9126
|
-
if (!existsSync8(p))
|
|
9127
|
-
return 0;
|
|
9128
|
-
const year = now.getUTCFullYear();
|
|
9129
|
-
const month2 = now.getUTCMonth();
|
|
9130
|
-
let total = 0;
|
|
9131
|
-
const raw = readFileSync8(p, "utf8");
|
|
9132
|
-
for (const line of raw.split("\n")) {
|
|
9133
|
-
if (!line)
|
|
9134
|
-
continue;
|
|
9135
|
-
let rec;
|
|
9136
|
-
try {
|
|
9137
|
-
rec = JSON.parse(line);
|
|
9138
|
-
} catch {
|
|
9139
|
-
continue;
|
|
9140
|
-
}
|
|
9141
|
-
const ts = new Date(rec.ts);
|
|
9142
|
-
if (Number.isNaN(ts.getTime()))
|
|
9143
|
-
continue;
|
|
9144
|
-
if (ts.getUTCFullYear() !== year || ts.getUTCMonth() !== month2)
|
|
9145
|
-
continue;
|
|
9146
|
-
total += rec.cost_usd;
|
|
9147
|
-
}
|
|
9148
|
-
return total;
|
|
9149
|
-
}
|
|
9150
|
-
var spendPathCached;
|
|
9151
|
-
var init_budget = __esm({
|
|
9152
|
-
"../entries/dist/budget.js"() {
|
|
9153
|
-
"use strict";
|
|
9154
|
-
spendPathCached = null;
|
|
9155
|
-
}
|
|
9156
|
-
});
|
|
9157
|
-
|
|
9158
|
-
// ../entries/dist/pipeline-lock.js
|
|
9159
|
-
import { writeFileSync as writeFileSync5, unlinkSync as unlinkSync2, existsSync as existsSync9, readFileSync as readFileSync9, statSync as statSync2 } from "node:fs";
|
|
9160
|
-
import { join as join10 } from "node:path";
|
|
9161
|
-
import { homedir as homedir9 } from "node:os";
|
|
9162
|
-
function lockPath() {
|
|
9163
|
-
if (lockPathCached)
|
|
9164
|
-
return lockPathCached;
|
|
9165
|
-
lockPathCached = join10(homedir9(), ".cclens", "llm-interactive.lock");
|
|
9166
|
-
return lockPathCached;
|
|
9167
|
-
}
|
|
9168
|
-
function __setInteractiveLockPathForTest(path4) {
|
|
9169
|
-
lockPathCached = path4;
|
|
9170
|
-
}
|
|
9171
|
-
function touchLock() {
|
|
9172
|
-
writeFileSync5(lockPath(), String(process.pid), "utf8");
|
|
9173
|
-
}
|
|
9174
|
-
function writeInteractiveLock() {
|
|
9175
|
-
touchLock();
|
|
9176
|
-
if (heartbeat)
|
|
9177
|
-
clearInterval(heartbeat);
|
|
9178
|
-
heartbeat = setInterval(() => {
|
|
9179
|
-
try {
|
|
9180
|
-
touchLock();
|
|
9181
|
-
} catch {
|
|
9182
|
-
}
|
|
9183
|
-
}, HEARTBEAT_MS);
|
|
9184
|
-
heartbeat.unref?.();
|
|
9185
|
-
}
|
|
9186
|
-
function removeInteractiveLock() {
|
|
9187
|
-
if (heartbeat) {
|
|
9188
|
-
clearInterval(heartbeat);
|
|
9189
|
-
heartbeat = null;
|
|
9190
|
-
}
|
|
9191
|
-
try {
|
|
9192
|
-
unlinkSync2(lockPath());
|
|
9193
|
-
} catch {
|
|
9194
|
-
}
|
|
9195
|
-
}
|
|
9196
|
-
function pidAlive(pid) {
|
|
9197
|
-
try {
|
|
9198
|
-
process.kill(pid, 0);
|
|
9199
|
-
return true;
|
|
9200
|
-
} catch {
|
|
9201
|
-
return false;
|
|
9202
|
-
}
|
|
9203
|
-
}
|
|
9204
|
-
function interactiveLockFresh(nowMs) {
|
|
9205
|
-
const p = lockPath();
|
|
9206
|
-
if (!existsSync9(p))
|
|
9207
|
-
return false;
|
|
9208
|
-
try {
|
|
9209
|
-
const mtime = statSync2(p).mtimeMs;
|
|
9210
|
-
if (nowMs - mtime > STALE_MS)
|
|
9211
|
-
return false;
|
|
9212
|
-
const pid = Number(readFileSync9(p, "utf8").trim());
|
|
9213
|
-
if (!Number.isFinite(pid) || pid <= 0)
|
|
9214
|
-
return false;
|
|
9215
|
-
if (!pidAlive(pid))
|
|
9216
|
-
return false;
|
|
9217
|
-
return true;
|
|
9218
|
-
} catch {
|
|
9219
|
-
return false;
|
|
9220
|
-
}
|
|
9221
|
-
}
|
|
9222
|
-
var STALE_MS, HEARTBEAT_MS, lockPathCached, heartbeat;
|
|
9223
|
-
var init_pipeline_lock = __esm({
|
|
9224
|
-
"../entries/dist/pipeline-lock.js"() {
|
|
9225
|
-
"use strict";
|
|
9226
|
-
STALE_MS = 60 * 1e3;
|
|
9227
|
-
HEARTBEAT_MS = 30 * 1e3;
|
|
9228
|
-
lockPathCached = null;
|
|
9229
|
-
heartbeat = null;
|
|
9230
|
-
}
|
|
9231
|
-
});
|
|
9232
|
-
|
|
9233
|
-
// ../entries/dist/queue.js
|
|
9234
|
-
function toLocalDay2(ms) {
|
|
9235
|
-
const d = new Date(ms);
|
|
9236
|
-
const y = d.getFullYear();
|
|
9237
|
-
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
9238
|
-
const day2 = String(d.getDate()).padStart(2, "0");
|
|
9239
|
-
return `${y}-${m}-${day2}`;
|
|
9240
|
-
}
|
|
9241
|
-
async function runEnrichmentQueue(settings, opts = {}) {
|
|
9242
|
-
if (!settings.enabled)
|
|
9243
|
-
return { skipped: "disabled" };
|
|
9244
|
-
const now = opts.now ?? (() => Date.now());
|
|
9245
|
-
if (interactiveLockFresh(now()))
|
|
9246
|
-
return { skipped: "interactive_in_progress" };
|
|
9247
|
-
const budget = settings.monthlyBudgetUsd ?? Infinity;
|
|
9248
|
-
if (monthToDateSpend() >= budget)
|
|
9249
|
-
return { skipped: "budget_cap_reached" };
|
|
9250
|
-
const queue = listEntriesWithStatus(["pending", "error"]).filter((e) => (e.enrichment.retry_count ?? 0) < MAX_RETRY_COUNT);
|
|
9251
|
-
const todayLocal = toLocalDay2(now());
|
|
9252
|
-
let enriched = 0, errors = 0, skipped = 0;
|
|
9253
|
-
for (const entry of queue) {
|
|
9254
|
-
if (entry.local_day === todayLocal) {
|
|
9255
|
-
skipped++;
|
|
9256
|
-
continue;
|
|
9257
|
-
}
|
|
9258
|
-
const endMs = Date.parse(entry.end_iso);
|
|
9259
|
-
if (!Number.isNaN(endMs) && now() - endMs < THIRTY_MIN_MS) {
|
|
9260
|
-
skipped++;
|
|
9261
|
-
continue;
|
|
9262
|
-
}
|
|
9263
|
-
if (monthToDateSpend() >= budget)
|
|
9264
|
-
break;
|
|
9265
|
-
try {
|
|
9266
|
-
const { entry: result, usage: usage2 } = await enrichEntry(entry, {
|
|
9267
|
-
model: settings.model,
|
|
9268
|
-
callLLM: opts.callLLM
|
|
9269
|
-
});
|
|
9270
|
-
writeEntry(result);
|
|
9271
|
-
if (result.enrichment.status === "done") {
|
|
9272
|
-
enriched++;
|
|
9273
|
-
appendSpend({
|
|
9274
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9275
|
-
caller: "daemon",
|
|
9276
|
-
model: result.enrichment.model ?? settings.model,
|
|
9277
|
-
input_tokens: usage2?.input_tokens ?? 0,
|
|
9278
|
-
output_tokens: usage2?.output_tokens ?? 0,
|
|
9279
|
-
cost_usd: result.enrichment.cost_usd ?? 0,
|
|
9280
|
-
kind: "entry_enrich",
|
|
9281
|
-
ref: `${result.session_id}__${result.local_day}`
|
|
9282
|
-
});
|
|
9283
|
-
} else {
|
|
9284
|
-
errors++;
|
|
9285
|
-
}
|
|
9286
|
-
} catch (err) {
|
|
9287
|
-
errors++;
|
|
9288
|
-
const failed = {
|
|
9289
|
-
...entry,
|
|
9290
|
-
enrichment: {
|
|
9291
|
-
...entry.enrichment,
|
|
9292
|
-
status: "error",
|
|
9293
|
-
retry_count: (entry.enrichment.retry_count ?? 0) + 1,
|
|
9294
|
-
error: err.message,
|
|
9295
|
-
generated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
9296
|
-
}
|
|
9297
|
-
};
|
|
9298
|
-
writeEntry(failed);
|
|
9299
|
-
}
|
|
10157
|
+
function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt, rateLimited = false) {
|
|
10158
|
+
if (rateLimited) {
|
|
10159
|
+
const enrichment2 = {
|
|
10160
|
+
...entry.enrichment,
|
|
10161
|
+
status: "pending",
|
|
10162
|
+
generated_at: generatedAt,
|
|
10163
|
+
model,
|
|
10164
|
+
cost_usd: costUsd,
|
|
10165
|
+
error: errorMessage
|
|
10166
|
+
// retry_count NOT incremented on rate-limit.
|
|
10167
|
+
};
|
|
10168
|
+
return { ...entry, enrichment: enrichment2 };
|
|
9300
10169
|
}
|
|
9301
|
-
|
|
10170
|
+
const enrichment = {
|
|
10171
|
+
...entry.enrichment,
|
|
10172
|
+
status: "error",
|
|
10173
|
+
generated_at: generatedAt,
|
|
10174
|
+
model,
|
|
10175
|
+
cost_usd: costUsd,
|
|
10176
|
+
error: errorMessage,
|
|
10177
|
+
retry_count: (entry.enrichment.retry_count ?? 0) + 1
|
|
10178
|
+
};
|
|
10179
|
+
return { ...entry, enrichment };
|
|
9302
10180
|
}
|
|
9303
|
-
var
|
|
9304
|
-
var
|
|
9305
|
-
"../entries/dist/
|
|
10181
|
+
var DEFAULT_MODEL;
|
|
10182
|
+
var init_enrich2 = __esm({
|
|
10183
|
+
"../entries/dist/enrich.js"() {
|
|
9306
10184
|
"use strict";
|
|
9307
|
-
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
9312
|
-
MAX_RETRY_COUNT = 3;
|
|
10185
|
+
init_signals();
|
|
10186
|
+
init_enrich();
|
|
10187
|
+
init_llm_runner();
|
|
10188
|
+
DEFAULT_MODEL = "sonnet";
|
|
9313
10189
|
}
|
|
9314
10190
|
});
|
|
9315
10191
|
|
|
9316
|
-
// ../entries/dist/
|
|
9317
|
-
import {
|
|
9318
|
-
import { dirname as
|
|
9319
|
-
import { homedir as
|
|
9320
|
-
function
|
|
9321
|
-
if (
|
|
9322
|
-
return
|
|
9323
|
-
|
|
9324
|
-
return
|
|
10192
|
+
// ../entries/dist/budget.js
|
|
10193
|
+
import { appendFileSync as appendFileSync3, readFileSync as readFileSync8, existsSync as existsSync8, mkdirSync as mkdirSync6 } from "node:fs";
|
|
10194
|
+
import { dirname as dirname7, join as join9 } from "node:path";
|
|
10195
|
+
import { homedir as homedir8 } from "node:os";
|
|
10196
|
+
function spendPath() {
|
|
10197
|
+
if (spendPathCached)
|
|
10198
|
+
return spendPathCached;
|
|
10199
|
+
spendPathCached = join9(homedir8(), ".cclens", "llm-spend.jsonl");
|
|
10200
|
+
return spendPathCached;
|
|
9325
10201
|
}
|
|
9326
|
-
function
|
|
9327
|
-
|
|
10202
|
+
function __setSpendPathForTest(path5) {
|
|
10203
|
+
spendPathCached = path5;
|
|
9328
10204
|
}
|
|
9329
|
-
function
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
model: s.ai_features.model,
|
|
9334
|
-
monthly_budget_usd: s.ai_features.monthlyBudgetUsd,
|
|
9335
|
-
auto_backfill_last_week: s.ai_features.autoBackfillLastWeek,
|
|
9336
|
-
auto_backfill_yesterday: s.ai_features.autoBackfillYesterday
|
|
9337
|
-
}
|
|
9338
|
-
};
|
|
10205
|
+
function appendSpend(record) {
|
|
10206
|
+
const p = spendPath();
|
|
10207
|
+
mkdirSync6(dirname7(p), { recursive: true });
|
|
10208
|
+
appendFileSync3(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
9339
10209
|
}
|
|
9340
|
-
function
|
|
9341
|
-
const
|
|
9342
|
-
|
|
9343
|
-
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
10210
|
+
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
10211
|
+
const p = spendPath();
|
|
10212
|
+
if (!existsSync8(p))
|
|
10213
|
+
return 0;
|
|
10214
|
+
const year = now.getUTCFullYear();
|
|
10215
|
+
const month2 = now.getUTCMonth();
|
|
10216
|
+
let total = 0;
|
|
10217
|
+
const raw = readFileSync8(p, "utf8");
|
|
10218
|
+
for (const line of raw.split("\n")) {
|
|
10219
|
+
if (!line)
|
|
10220
|
+
continue;
|
|
10221
|
+
let rec;
|
|
10222
|
+
try {
|
|
10223
|
+
rec = JSON.parse(line);
|
|
10224
|
+
} catch {
|
|
10225
|
+
continue;
|
|
9349
10226
|
}
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
try {
|
|
9357
|
-
const raw = readFileSync10(p, "utf8");
|
|
9358
|
-
return fromDisk(JSON.parse(raw));
|
|
9359
|
-
} catch {
|
|
9360
|
-
return DEFAULT_SETTINGS;
|
|
9361
|
-
}
|
|
9362
|
-
}
|
|
9363
|
-
function writeSettings(s) {
|
|
9364
|
-
const p = settingsPath();
|
|
9365
|
-
mkdirSync7(dirname8(p), { recursive: true });
|
|
9366
|
-
const tmp = `${p}.tmp`;
|
|
9367
|
-
writeFileSync6(tmp, JSON.stringify(toDisk(s), null, 2), { encoding: "utf8" });
|
|
9368
|
-
if (process.platform !== "win32") {
|
|
9369
|
-
chmodSync2(tmp, 384);
|
|
10227
|
+
const ts = new Date(rec.ts);
|
|
10228
|
+
if (Number.isNaN(ts.getTime()))
|
|
10229
|
+
continue;
|
|
10230
|
+
if (ts.getUTCFullYear() !== year || ts.getUTCMonth() !== month2)
|
|
10231
|
+
continue;
|
|
10232
|
+
total += rec.cost_usd;
|
|
9370
10233
|
}
|
|
9371
|
-
|
|
10234
|
+
return total;
|
|
9372
10235
|
}
|
|
9373
|
-
var
|
|
9374
|
-
var
|
|
9375
|
-
"../entries/dist/
|
|
9376
|
-
"use strict";
|
|
9377
|
-
DEFAULT_SETTINGS = {
|
|
9378
|
-
ai_features: {
|
|
9379
|
-
enabled: true,
|
|
9380
|
-
model: "sonnet",
|
|
9381
|
-
monthlyBudgetUsd: null,
|
|
9382
|
-
autoBackfillLastWeek: true,
|
|
9383
|
-
autoBackfillYesterday: true
|
|
9384
|
-
}
|
|
9385
|
-
};
|
|
9386
|
-
settingsPathCached = null;
|
|
9387
|
-
}
|
|
9388
|
-
});
|
|
9389
|
-
|
|
9390
|
-
// ../parser/dist/types.js
|
|
9391
|
-
var init_types3 = __esm({
|
|
9392
|
-
"../parser/dist/types.js"() {
|
|
10236
|
+
var spendPathCached;
|
|
10237
|
+
var init_budget = __esm({
|
|
10238
|
+
"../entries/dist/budget.js"() {
|
|
9393
10239
|
"use strict";
|
|
10240
|
+
spendPathCached = null;
|
|
9394
10241
|
}
|
|
9395
10242
|
});
|
|
9396
10243
|
|
|
9397
|
-
// ../
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
|
|
9401
|
-
|
|
10244
|
+
// ../entries/dist/pipeline-lock.js
|
|
10245
|
+
import { writeFileSync as writeFileSync5, unlinkSync as unlinkSync2, existsSync as existsSync9, readFileSync as readFileSync9, statSync as statSync2 } from "node:fs";
|
|
10246
|
+
import { join as join10 } from "node:path";
|
|
10247
|
+
import { homedir as homedir9 } from "node:os";
|
|
10248
|
+
function lockPath() {
|
|
10249
|
+
if (lockPathCached)
|
|
10250
|
+
return lockPathCached;
|
|
10251
|
+
lockPathCached = join10(homedir9(), ".cclens", "llm-interactive.lock");
|
|
10252
|
+
return lockPathCached;
|
|
9402
10253
|
}
|
|
9403
|
-
function
|
|
9404
|
-
|
|
9405
|
-
let buffer = [];
|
|
9406
|
-
const flush = () => {
|
|
9407
|
-
if (buffer.length === 0)
|
|
9408
|
-
return;
|
|
9409
|
-
let agentMessages = 0;
|
|
9410
|
-
let toolCalls = 0;
|
|
9411
|
-
let errors = 0;
|
|
9412
|
-
let firstAgentIndex;
|
|
9413
|
-
const toolMap = /* @__PURE__ */ new Map();
|
|
9414
|
-
const seenMsgIds = /* @__PURE__ */ new Set();
|
|
9415
|
-
const tokens = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
9416
|
-
for (let i = 0; i < buffer.length; i++) {
|
|
9417
|
-
const r = buffer[i];
|
|
9418
|
-
if (r.kind === "agent") {
|
|
9419
|
-
agentMessages++;
|
|
9420
|
-
if (firstAgentIndex === void 0)
|
|
9421
|
-
firstAgentIndex = i;
|
|
9422
|
-
const msgId = r.event.messageId;
|
|
9423
|
-
const usage2 = r.event.usage;
|
|
9424
|
-
if (msgId && !seenMsgIds.has(msgId) && usage2) {
|
|
9425
|
-
seenMsgIds.add(msgId);
|
|
9426
|
-
tokens.input += usage2.input;
|
|
9427
|
-
tokens.output += usage2.output;
|
|
9428
|
-
tokens.cacheRead += usage2.cacheRead;
|
|
9429
|
-
tokens.cacheWrite += usage2.cacheWrite;
|
|
9430
|
-
}
|
|
9431
|
-
} else if (r.kind === "tool-group") {
|
|
9432
|
-
toolCalls += r.count;
|
|
9433
|
-
for (const t of r.toolNames) {
|
|
9434
|
-
toolMap.set(t.name, (toolMap.get(t.name) ?? 0) + t.count);
|
|
9435
|
-
}
|
|
9436
|
-
} else if (r.kind === "error") {
|
|
9437
|
-
errors++;
|
|
9438
|
-
}
|
|
9439
|
-
}
|
|
9440
|
-
let finalAgentIndex;
|
|
9441
|
-
for (let i = buffer.length - 1; i >= 0; i--) {
|
|
9442
|
-
const r = buffer[i];
|
|
9443
|
-
if (r.kind !== "agent")
|
|
9444
|
-
continue;
|
|
9445
|
-
const prev = buffer[i - 1];
|
|
9446
|
-
if (prev?.kind === "task-notification")
|
|
9447
|
-
continue;
|
|
9448
|
-
finalAgentIndex = i;
|
|
9449
|
-
break;
|
|
9450
|
-
}
|
|
9451
|
-
if (finalAgentIndex === void 0) {
|
|
9452
|
-
for (let i = buffer.length - 1; i >= 0; i--) {
|
|
9453
|
-
if (buffer[i].kind === "agent") {
|
|
9454
|
-
finalAgentIndex = i;
|
|
9455
|
-
break;
|
|
9456
|
-
}
|
|
9457
|
-
}
|
|
9458
|
-
}
|
|
9459
|
-
const firstAgentPreview = firstAgentIndex !== void 0 && buffer[firstAgentIndex].kind === "agent" ? buffer[firstAgentIndex].event.preview : void 0;
|
|
9460
|
-
const finalAgentPreview = finalAgentIndex !== void 0 && buffer[finalAgentIndex].kind === "agent" ? buffer[finalAgentIndex].event.preview : void 0;
|
|
9461
|
-
const toolNames = Array.from(toolMap.entries()).sort((a, b) => b[1] - a[1]).map(([name, count]) => ({ name, count }));
|
|
9462
|
-
const first = buffer[0];
|
|
9463
|
-
const last = buffer[buffer.length - 1];
|
|
9464
|
-
const start2 = first.tOffsetMs;
|
|
9465
|
-
const end = last.tOffsetMs;
|
|
9466
|
-
const durationMs = start2 !== void 0 && end !== void 0 ? end - start2 : void 0;
|
|
9467
|
-
out.push({
|
|
9468
|
-
kind: "turn",
|
|
9469
|
-
rows: buffer,
|
|
9470
|
-
firstPrimaryIndex: rowPrimaryIndex(first),
|
|
9471
|
-
tOffsetMs: start2,
|
|
9472
|
-
durationMs,
|
|
9473
|
-
summary: {
|
|
9474
|
-
agentMessages,
|
|
9475
|
-
toolCalls,
|
|
9476
|
-
errors,
|
|
9477
|
-
firstAgentPreview,
|
|
9478
|
-
finalAgentPreview,
|
|
9479
|
-
firstAgentIndex,
|
|
9480
|
-
finalAgentIndex,
|
|
9481
|
-
toolNames,
|
|
9482
|
-
totalTokens: tokens
|
|
9483
|
-
}
|
|
9484
|
-
});
|
|
9485
|
-
buffer = [];
|
|
9486
|
-
};
|
|
9487
|
-
for (const r of rows) {
|
|
9488
|
-
if (r.kind === "user" || r.kind === "interrupt") {
|
|
9489
|
-
flush();
|
|
9490
|
-
out.push(r);
|
|
9491
|
-
} else {
|
|
9492
|
-
buffer.push(r);
|
|
9493
|
-
}
|
|
9494
|
-
}
|
|
9495
|
-
flush();
|
|
9496
|
-
return out;
|
|
10254
|
+
function __setInteractiveLockPathForTest(path5) {
|
|
10255
|
+
lockPathCached = path5;
|
|
9497
10256
|
}
|
|
9498
|
-
function
|
|
9499
|
-
|
|
9500
|
-
return null;
|
|
9501
|
-
const pick = (tag) => {
|
|
9502
|
-
const m = text.match(new RegExp(`<${tag}>([\\s\\S]*?)<\\/${tag}>`));
|
|
9503
|
-
return m ? m[1].trim() : void 0;
|
|
9504
|
-
};
|
|
9505
|
-
const statusRaw = (pick("status") ?? "").toLowerCase();
|
|
9506
|
-
let status2 = "unknown";
|
|
9507
|
-
if (statusRaw === "success" || statusRaw === "ok" || statusRaw === "done" || statusRaw === "completed")
|
|
9508
|
-
status2 = "success";
|
|
9509
|
-
else if (statusRaw === "failed" || statusRaw === "error" || statusRaw === "fail")
|
|
9510
|
-
status2 = "failed";
|
|
9511
|
-
else if (statusRaw === "running" || statusRaw === "in_progress")
|
|
9512
|
-
status2 = "running";
|
|
9513
|
-
return {
|
|
9514
|
-
status: status2,
|
|
9515
|
-
summary: pick("summary") ?? "Background task notification",
|
|
9516
|
-
taskId: pick("task-id"),
|
|
9517
|
-
toolUseId: pick("tool-use-id"),
|
|
9518
|
-
outputFile: pick("output-file")
|
|
9519
|
-
};
|
|
10257
|
+
function touchLock() {
|
|
10258
|
+
writeFileSync5(lockPath(), String(process.pid), "utf8");
|
|
9520
10259
|
}
|
|
9521
|
-
function
|
|
9522
|
-
|
|
10260
|
+
function writeInteractiveLock() {
|
|
10261
|
+
touchLock();
|
|
10262
|
+
if (heartbeat)
|
|
10263
|
+
clearInterval(heartbeat);
|
|
10264
|
+
heartbeat = setInterval(() => {
|
|
10265
|
+
try {
|
|
10266
|
+
touchLock();
|
|
10267
|
+
} catch {
|
|
10268
|
+
}
|
|
10269
|
+
}, HEARTBEAT_MS);
|
|
10270
|
+
heartbeat.unref?.();
|
|
9523
10271
|
}
|
|
9524
|
-
function
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
10272
|
+
function removeInteractiveLock() {
|
|
10273
|
+
if (heartbeat) {
|
|
10274
|
+
clearInterval(heartbeat);
|
|
10275
|
+
heartbeat = null;
|
|
10276
|
+
}
|
|
10277
|
+
try {
|
|
10278
|
+
unlinkSync2(lockPath());
|
|
10279
|
+
} catch {
|
|
9528
10280
|
}
|
|
9529
|
-
return void 0;
|
|
9530
10281
|
}
|
|
9531
|
-
function
|
|
9532
|
-
|
|
10282
|
+
function pidAlive(pid) {
|
|
10283
|
+
try {
|
|
10284
|
+
process.kill(pid, 0);
|
|
10285
|
+
return true;
|
|
10286
|
+
} catch {
|
|
9533
10287
|
return false;
|
|
9534
|
-
const u = e.usage;
|
|
9535
|
-
return u.input === 0 && u.output === 0 && u.cacheRead === 0 && u.cacheWrite === 0;
|
|
9536
|
-
}
|
|
9537
|
-
function buildPresentation(events) {
|
|
9538
|
-
const byMessageId = /* @__PURE__ */ new Map();
|
|
9539
|
-
for (const e of events) {
|
|
9540
|
-
if (!e.messageId)
|
|
9541
|
-
continue;
|
|
9542
|
-
const list = byMessageId.get(e.messageId) ?? [];
|
|
9543
|
-
list.push(e);
|
|
9544
|
-
byMessageId.set(e.messageId, list);
|
|
9545
10288
|
}
|
|
9546
|
-
|
|
9547
|
-
|
|
10289
|
+
}
|
|
10290
|
+
function interactiveLockFresh(nowMs) {
|
|
10291
|
+
const p = lockPath();
|
|
10292
|
+
if (!existsSync9(p))
|
|
10293
|
+
return false;
|
|
10294
|
+
try {
|
|
10295
|
+
const mtime = statSync2(p).mtimeMs;
|
|
10296
|
+
if (nowMs - mtime > STALE_MS)
|
|
9548
10297
|
return false;
|
|
9549
|
-
|
|
10298
|
+
const pid = Number(readFileSync9(p, "utf8").trim());
|
|
10299
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
9550
10300
|
return false;
|
|
9551
|
-
if (
|
|
10301
|
+
if (!pidAlive(pid))
|
|
9552
10302
|
return false;
|
|
9553
|
-
if (e.role === "user") {
|
|
9554
|
-
const txt = firstTextOfBlocks(e.blocks) ?? "";
|
|
9555
|
-
if (SKILL_CONTENT_RE.test(txt))
|
|
9556
|
-
return false;
|
|
9557
|
-
}
|
|
9558
10303
|
return true;
|
|
9559
|
-
}
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
|
|
10304
|
+
} catch {
|
|
10305
|
+
return false;
|
|
10306
|
+
}
|
|
10307
|
+
}
|
|
10308
|
+
var STALE_MS, HEARTBEAT_MS, lockPathCached, heartbeat;
|
|
10309
|
+
var init_pipeline_lock = __esm({
|
|
10310
|
+
"../entries/dist/pipeline-lock.js"() {
|
|
10311
|
+
"use strict";
|
|
10312
|
+
STALE_MS = 60 * 1e3;
|
|
10313
|
+
HEARTBEAT_MS = 30 * 1e3;
|
|
10314
|
+
lockPathCached = null;
|
|
10315
|
+
heartbeat = null;
|
|
10316
|
+
}
|
|
10317
|
+
});
|
|
10318
|
+
|
|
10319
|
+
// ../entries/dist/queue.js
|
|
10320
|
+
function toLocalDay2(ms) {
|
|
10321
|
+
const d = new Date(ms);
|
|
10322
|
+
const y = d.getFullYear();
|
|
10323
|
+
const m = String(d.getMonth() + 1).padStart(2, "0");
|
|
10324
|
+
const day2 = String(d.getDate()).padStart(2, "0");
|
|
10325
|
+
return `${y}-${m}-${day2}`;
|
|
10326
|
+
}
|
|
10327
|
+
async function runEnrichmentQueue(settings, opts = {}) {
|
|
10328
|
+
if (!settings.enabled)
|
|
10329
|
+
return { skipped: "disabled" };
|
|
10330
|
+
const now = opts.now ?? (() => Date.now());
|
|
10331
|
+
if (interactiveLockFresh(now()))
|
|
10332
|
+
return { skipped: "interactive_in_progress" };
|
|
10333
|
+
const budget = settings.monthlyBudgetUsd ?? Infinity;
|
|
10334
|
+
if (monthToDateSpend() >= budget)
|
|
10335
|
+
return { skipped: "budget_cap_reached" };
|
|
10336
|
+
const queue = listEntriesWithStatus(["pending", "error"]).filter((e) => (e.enrichment.retry_count ?? 0) < MAX_RETRY_COUNT);
|
|
10337
|
+
const todayLocal = toLocalDay2(now());
|
|
10338
|
+
let enriched = 0, errors = 0, skipped = 0;
|
|
10339
|
+
for (const entry of queue) {
|
|
10340
|
+
if (entry.local_day === todayLocal) {
|
|
10341
|
+
skipped++;
|
|
9589
10342
|
continue;
|
|
9590
10343
|
}
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
if (taskNotif) {
|
|
9595
|
-
rows.push({
|
|
9596
|
-
kind: "task-notification",
|
|
9597
|
-
event: e,
|
|
9598
|
-
status: taskNotif.status,
|
|
9599
|
-
summary: taskNotif.summary,
|
|
9600
|
-
taskId: taskNotif.taskId,
|
|
9601
|
-
toolUseId: taskNotif.toolUseId,
|
|
9602
|
-
outputFile: taskNotif.outputFile,
|
|
9603
|
-
tOffsetMs: e.tOffsetMs,
|
|
9604
|
-
gapMs: e.gapMs
|
|
9605
|
-
});
|
|
9606
|
-
continue;
|
|
9607
|
-
}
|
|
9608
|
-
if (INTERRUPT_RE.test(txt)) {
|
|
9609
|
-
rows.push({
|
|
9610
|
-
kind: "interrupt",
|
|
9611
|
-
event: e,
|
|
9612
|
-
tOffsetMs: e.tOffsetMs,
|
|
9613
|
-
gapMs: e.gapMs
|
|
9614
|
-
});
|
|
9615
|
-
continue;
|
|
9616
|
-
}
|
|
9617
|
-
const slashMatch = txt.match(SLASH_COMMAND_RE2);
|
|
9618
|
-
if (slashMatch) {
|
|
9619
|
-
const cmd = slashMatch[1];
|
|
9620
|
-
const args2 = (slashMatch[2] ?? "").trim();
|
|
9621
|
-
const pretty = args2 ? `${cmd} ${args2}` : cmd;
|
|
9622
|
-
rows.push({
|
|
9623
|
-
kind: "user",
|
|
9624
|
-
event: e,
|
|
9625
|
-
displayPreview: pretty,
|
|
9626
|
-
displayBlocks: [{ type: "text", text: pretty }],
|
|
9627
|
-
tOffsetMs: e.tOffsetMs,
|
|
9628
|
-
gapMs: e.gapMs
|
|
9629
|
-
});
|
|
9630
|
-
continue;
|
|
9631
|
-
}
|
|
9632
|
-
rows.push({
|
|
9633
|
-
kind: "user",
|
|
9634
|
-
event: e,
|
|
9635
|
-
tOffsetMs: e.tOffsetMs,
|
|
9636
|
-
gapMs: e.gapMs
|
|
9637
|
-
});
|
|
10344
|
+
const endMs = Date.parse(entry.end_iso);
|
|
10345
|
+
if (!Number.isNaN(endMs) && now() - endMs < THIRTY_MIN_MS) {
|
|
10346
|
+
skipped++;
|
|
9638
10347
|
continue;
|
|
9639
10348
|
}
|
|
9640
|
-
if (
|
|
9641
|
-
|
|
9642
|
-
|
|
9643
|
-
|
|
9644
|
-
|
|
9645
|
-
|
|
9646
|
-
tOffsetMs: e.tOffsetMs,
|
|
9647
|
-
gapMs: e.gapMs
|
|
9648
|
-
});
|
|
9649
|
-
if (RATE_LIMIT_RE.test(txt) && txt.length < 500) {
|
|
9650
|
-
rows.push({
|
|
9651
|
-
kind: "error",
|
|
9652
|
-
event: e,
|
|
9653
|
-
message: txt,
|
|
9654
|
-
tOffsetMs: e.tOffsetMs,
|
|
9655
|
-
gapMs: 0
|
|
9656
|
-
});
|
|
9657
|
-
}
|
|
9658
|
-
continue;
|
|
9659
|
-
}
|
|
9660
|
-
if (RATE_LIMIT_RE.test(txt) && txt.length < 500) {
|
|
9661
|
-
rows.push({
|
|
9662
|
-
kind: "error",
|
|
9663
|
-
event: e,
|
|
9664
|
-
message: txt,
|
|
9665
|
-
tOffsetMs: e.tOffsetMs,
|
|
9666
|
-
gapMs: e.gapMs
|
|
9667
|
-
});
|
|
9668
|
-
continue;
|
|
9669
|
-
}
|
|
9670
|
-
const grouped = e.messageId ? byMessageId.get(e.messageId) ?? [e] : [e];
|
|
9671
|
-
rows.push({
|
|
9672
|
-
kind: "agent",
|
|
9673
|
-
event: e,
|
|
9674
|
-
groupedEvents: grouped,
|
|
9675
|
-
tOffsetMs: e.tOffsetMs,
|
|
9676
|
-
gapMs: e.gapMs
|
|
10349
|
+
if (monthToDateSpend() >= budget)
|
|
10350
|
+
break;
|
|
10351
|
+
try {
|
|
10352
|
+
const { entry: result, usage: usage2 } = await enrichEntry(entry, {
|
|
10353
|
+
model: settings.model,
|
|
10354
|
+
callLLM: opts.callLLM
|
|
9677
10355
|
});
|
|
9678
|
-
|
|
10356
|
+
writeEntry(result);
|
|
10357
|
+
if (result.enrichment.status === "done") {
|
|
10358
|
+
enriched++;
|
|
10359
|
+
appendSpend({
|
|
10360
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10361
|
+
caller: "daemon",
|
|
10362
|
+
model: result.enrichment.model ?? settings.model,
|
|
10363
|
+
input_tokens: usage2?.input_tokens ?? 0,
|
|
10364
|
+
output_tokens: usage2?.output_tokens ?? 0,
|
|
10365
|
+
cost_usd: result.enrichment.cost_usd ?? 0,
|
|
10366
|
+
kind: "entry_enrich",
|
|
10367
|
+
ref: `${result.session_id}__${result.local_day}`
|
|
10368
|
+
});
|
|
10369
|
+
} else {
|
|
10370
|
+
errors++;
|
|
10371
|
+
}
|
|
10372
|
+
} catch (err) {
|
|
10373
|
+
errors++;
|
|
10374
|
+
const failed = {
|
|
10375
|
+
...entry,
|
|
10376
|
+
enrichment: {
|
|
10377
|
+
...entry.enrichment,
|
|
10378
|
+
status: "error",
|
|
10379
|
+
retry_count: (entry.enrichment.retry_count ?? 0) + 1,
|
|
10380
|
+
error: err.message,
|
|
10381
|
+
generated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
10382
|
+
}
|
|
10383
|
+
};
|
|
10384
|
+
writeEntry(failed);
|
|
9679
10385
|
}
|
|
9680
10386
|
}
|
|
9681
|
-
return
|
|
10387
|
+
return { enriched, errors, skipped };
|
|
9682
10388
|
}
|
|
9683
|
-
var
|
|
9684
|
-
var
|
|
9685
|
-
"../
|
|
10389
|
+
var THIRTY_MIN_MS, MAX_RETRY_COUNT;
|
|
10390
|
+
var init_queue = __esm({
|
|
10391
|
+
"../entries/dist/queue.js"() {
|
|
9686
10392
|
"use strict";
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
10393
|
+
init_fs2();
|
|
10394
|
+
init_enrich2();
|
|
10395
|
+
init_budget();
|
|
10396
|
+
init_pipeline_lock();
|
|
10397
|
+
THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
10398
|
+
MAX_RETRY_COUNT = 3;
|
|
9692
10399
|
}
|
|
9693
10400
|
});
|
|
9694
10401
|
|
|
9695
|
-
// ../
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
}
|
|
9699
|
-
function
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
out.push(new Date(cur));
|
|
9705
|
-
cur.setDate(cur.getDate() + 1);
|
|
9706
|
-
}
|
|
9707
|
-
return out;
|
|
9708
|
-
}
|
|
9709
|
-
function calendarWeek(ref = /* @__PURE__ */ new Date()) {
|
|
9710
|
-
const d = new Date(ref.getFullYear(), ref.getMonth(), ref.getDate());
|
|
9711
|
-
const dow = d.getDay();
|
|
9712
|
-
const daysSinceMon = (dow + 6) % 7;
|
|
9713
|
-
const monday = new Date(d);
|
|
9714
|
-
monday.setDate(d.getDate() - daysSinceMon);
|
|
9715
|
-
const sunday = new Date(monday);
|
|
9716
|
-
sunday.setDate(monday.getDate() + 6);
|
|
9717
|
-
return { start: monday, end: sunday };
|
|
9718
|
-
}
|
|
9719
|
-
function priorCalendarWeek(ref = /* @__PURE__ */ new Date()) {
|
|
9720
|
-
const cur = calendarWeek(ref);
|
|
9721
|
-
const prevEnd = new Date(cur.start);
|
|
9722
|
-
prevEnd.setDate(cur.start.getDate() - 1);
|
|
9723
|
-
const prevStart = new Date(prevEnd);
|
|
9724
|
-
prevStart.setDate(prevEnd.getDate() - 6);
|
|
9725
|
-
return { start: prevStart, end: prevEnd };
|
|
9726
|
-
}
|
|
9727
|
-
function last4CompletedWeeks(ref = /* @__PURE__ */ new Date()) {
|
|
9728
|
-
const { end } = priorCalendarWeek(ref);
|
|
9729
|
-
const start2 = new Date(end);
|
|
9730
|
-
start2.setDate(end.getDate() - 27);
|
|
9731
|
-
return { start: start2, end };
|
|
10402
|
+
// ../entries/dist/settings.js
|
|
10403
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, renameSync as renameSync3, chmodSync as chmodSync2, mkdirSync as mkdirSync7, existsSync as existsSync10 } from "node:fs";
|
|
10404
|
+
import { dirname as dirname8, join as join11 } from "node:path";
|
|
10405
|
+
import { homedir as homedir10 } from "node:os";
|
|
10406
|
+
function settingsPath() {
|
|
10407
|
+
if (settingsPathCached)
|
|
10408
|
+
return settingsPathCached;
|
|
10409
|
+
settingsPathCached = join11(homedir10(), ".cclens", "settings.json");
|
|
10410
|
+
return settingsPathCached;
|
|
9732
10411
|
}
|
|
9733
|
-
function
|
|
9734
|
-
|
|
9735
|
-
const end = new Date(ref.getFullYear(), ref.getMonth() + 1, 0);
|
|
9736
|
-
return { start: start2, end };
|
|
10412
|
+
function __setSettingsPathForTest(path5) {
|
|
10413
|
+
settingsPathCached = path5;
|
|
9737
10414
|
}
|
|
9738
|
-
function
|
|
9739
|
-
|
|
9740
|
-
|
|
9741
|
-
|
|
10415
|
+
function toDisk(s) {
|
|
10416
|
+
return {
|
|
10417
|
+
ai_features: {
|
|
10418
|
+
enabled: s.ai_features.enabled,
|
|
10419
|
+
model: s.ai_features.model,
|
|
10420
|
+
monthly_budget_usd: s.ai_features.monthlyBudgetUsd,
|
|
10421
|
+
auto_backfill_last_week: s.ai_features.autoBackfillLastWeek,
|
|
10422
|
+
auto_backfill_yesterday: s.ai_features.autoBackfillYesterday
|
|
10423
|
+
}
|
|
10424
|
+
};
|
|
9742
10425
|
}
|
|
9743
|
-
function
|
|
9744
|
-
const
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
|
|
9751
|
-
|
|
9752
|
-
continue;
|
|
9753
|
-
if (b.peak > cur.peak)
|
|
9754
|
-
cur.peak = b.peak;
|
|
9755
|
-
if (b.crossProject)
|
|
9756
|
-
cur.has_cross_project = true;
|
|
9757
|
-
}
|
|
9758
|
-
const by_day = days.map((d) => {
|
|
9759
|
-
const k = isoDay(d);
|
|
9760
|
-
const v = byDayKey.get(k);
|
|
9761
|
-
return { date: k, peak: v.peak, has_cross_project: v.has_cross_project };
|
|
9762
|
-
});
|
|
9763
|
-
let peak = 0;
|
|
9764
|
-
let peak_day;
|
|
9765
|
-
let multi_agent_days = 0;
|
|
9766
|
-
let cross_project_days = 0;
|
|
9767
|
-
for (const d of by_day) {
|
|
9768
|
-
if (d.peak > peak) {
|
|
9769
|
-
peak = d.peak;
|
|
9770
|
-
peak_day = d.date;
|
|
10426
|
+
function fromDisk(d) {
|
|
10427
|
+
const af = d.ai_features ?? {};
|
|
10428
|
+
return {
|
|
10429
|
+
ai_features: {
|
|
10430
|
+
enabled: af.enabled ?? DEFAULT_SETTINGS.ai_features.enabled,
|
|
10431
|
+
model: af.model ?? DEFAULT_SETTINGS.ai_features.model,
|
|
10432
|
+
monthlyBudgetUsd: af.monthly_budget_usd ?? null,
|
|
10433
|
+
autoBackfillLastWeek: af.auto_backfill_last_week ?? DEFAULT_SETTINGS.ai_features.autoBackfillLastWeek,
|
|
10434
|
+
autoBackfillYesterday: af.auto_backfill_yesterday ?? DEFAULT_SETTINGS.ai_features.autoBackfillYesterday
|
|
9771
10435
|
}
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
|
|
10436
|
+
};
|
|
10437
|
+
}
|
|
10438
|
+
function readSettings() {
|
|
10439
|
+
const p = settingsPath();
|
|
10440
|
+
if (!existsSync10(p))
|
|
10441
|
+
return DEFAULT_SETTINGS;
|
|
10442
|
+
try {
|
|
10443
|
+
const raw = readFileSync10(p, "utf8");
|
|
10444
|
+
return fromDisk(JSON.parse(raw));
|
|
10445
|
+
} catch {
|
|
10446
|
+
return DEFAULT_SETTINGS;
|
|
9776
10447
|
}
|
|
9777
|
-
return { by_day, peak, peak_day, multi_agent_days, cross_project_days };
|
|
9778
10448
|
}
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
10449
|
+
function writeSettings(s) {
|
|
10450
|
+
const p = settingsPath();
|
|
10451
|
+
mkdirSync7(dirname8(p), { recursive: true });
|
|
10452
|
+
const tmp = `${p}.tmp`;
|
|
10453
|
+
writeFileSync6(tmp, JSON.stringify(toDisk(s), null, 2), { encoding: "utf8" });
|
|
10454
|
+
if (process.platform !== "win32") {
|
|
10455
|
+
chmodSync2(tmp, 384);
|
|
9783
10456
|
}
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
var
|
|
9788
|
-
|
|
9789
|
-
CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
|
|
9790
|
-
CODEX_METADATA: () => CODEX_METADATA,
|
|
9791
|
-
PRICES: () => PRICES,
|
|
9792
|
-
RATE_PER_PCT: () => RATE_PER_PCT,
|
|
9793
|
-
RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
|
|
9794
|
-
RATE_PER_PCT_7D: () => RATE_PER_PCT_7D,
|
|
9795
|
-
agentMetadata: () => agentMetadata,
|
|
9796
|
-
aggregateConcurrency: () => aggregateConcurrency,
|
|
9797
|
-
buildGanttDay: () => buildGanttDay,
|
|
9798
|
-
buildMegaRows: () => buildMegaRows,
|
|
9799
|
-
buildPresentation: () => buildPresentation,
|
|
9800
|
-
buildSpendIndex: () => buildSpendIndex,
|
|
9801
|
-
calendarMonth: () => calendarMonth,
|
|
9802
|
-
calendarWeek: () => calendarWeek,
|
|
9803
|
-
canonicalProjectName: () => canonicalProjectName,
|
|
9804
|
-
collectSnapPairRates: () => collectSnapPairRates,
|
|
9805
|
-
computeActiveSegments: () => computeActiveSegments,
|
|
9806
|
-
computeBurstsFromSessions: () => computeBurstsFromSessions,
|
|
9807
|
-
computeParallelism: () => computeParallelism,
|
|
9808
|
-
computeParallelismBursts: () => computeParallelismBursts,
|
|
9809
|
-
dailyActivity: () => dailyActivity,
|
|
9810
|
-
daysBetween: () => daysBetween,
|
|
9811
|
-
detectParallelRuns: () => detectParallelRuns,
|
|
9812
|
-
detectPrMarkers: () => detectPrMarkers,
|
|
9813
|
-
dollarsInRange: () => dollarsInRange,
|
|
9814
|
-
dollarsInWindow: () => dollarsInWindow,
|
|
9815
|
-
eventDollars: () => eventDollars,
|
|
9816
|
-
getAgentMetadata: () => getAgentMetadata,
|
|
9817
|
-
groupByProject: () => groupByProject,
|
|
9818
|
-
groupByTeam: () => groupByTeam,
|
|
9819
|
-
groupSnapsByCycle: () => groupSnapsByCycle,
|
|
9820
|
-
highLevelMetrics: () => highLevelMetrics,
|
|
9821
|
-
isAgentKind: () => isAgentKind,
|
|
9822
|
-
last4CompletedWeeks: () => last4CompletedWeeks,
|
|
9823
|
-
modelFamily: () => modelFamily,
|
|
9824
|
-
parseTranscript: () => parseTranscript,
|
|
9825
|
-
predictAnchored: () => predictAnchored,
|
|
9826
|
-
predictUtilization: () => predictUtilization,
|
|
9827
|
-
priorCalendarMonth: () => priorCalendarMonth,
|
|
9828
|
-
priorCalendarWeek: () => priorCalendarWeek,
|
|
9829
|
-
rowPrimaryIndex: () => rowPrimaryIndex,
|
|
9830
|
-
sessionAirTimeMs: () => sessionAirTimeMs,
|
|
9831
|
-
sessionDay: () => sessionDay,
|
|
9832
|
-
summarizeBursts: () => summarizeBursts,
|
|
9833
|
-
toLocalDay: () => toLocalDay,
|
|
9834
|
-
userSoloRate: () => userSoloRate,
|
|
9835
|
-
worktreeName: () => worktreeName
|
|
9836
|
-
});
|
|
9837
|
-
var init_dist2 = __esm({
|
|
9838
|
-
"../parser/dist/index.js"() {
|
|
10457
|
+
renameSync3(tmp, p);
|
|
10458
|
+
}
|
|
10459
|
+
var DEFAULT_SETTINGS, settingsPathCached;
|
|
10460
|
+
var init_settings = __esm({
|
|
10461
|
+
"../entries/dist/settings.js"() {
|
|
9839
10462
|
"use strict";
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
10463
|
+
DEFAULT_SETTINGS = {
|
|
10464
|
+
ai_features: {
|
|
10465
|
+
enabled: true,
|
|
10466
|
+
model: "sonnet",
|
|
10467
|
+
monthlyBudgetUsd: null,
|
|
10468
|
+
autoBackfillLastWeek: true,
|
|
10469
|
+
autoBackfillYesterday: true
|
|
10470
|
+
}
|
|
10471
|
+
};
|
|
10472
|
+
settingsPathCached = null;
|
|
9848
10473
|
}
|
|
9849
10474
|
});
|
|
9850
10475
|
|
|
@@ -9911,7 +10536,7 @@ var init_digest_day = __esm({
|
|
|
9911
10536
|
"../entries/dist/prompts/digest-day.js"() {
|
|
9912
10537
|
"use strict";
|
|
9913
10538
|
init_zod();
|
|
9914
|
-
|
|
10539
|
+
init_dist();
|
|
9915
10540
|
AGENT_NAMING_TABLE = agentMetadata.map((m) => ` - agent="${m.kind}" \u2192 render as "${m.displayName}"`).join("\n");
|
|
9916
10541
|
SuggestionSchema = external_exports.object({
|
|
9917
10542
|
headline: external_exports.string().min(1).max(80),
|
|
@@ -10021,7 +10646,7 @@ function rollupOutcomeDay(entries2) {
|
|
|
10021
10646
|
return "exploratory";
|
|
10022
10647
|
return "trivial";
|
|
10023
10648
|
}
|
|
10024
|
-
function
|
|
10649
|
+
function truncate4(s, max) {
|
|
10025
10650
|
if (s.length <= max)
|
|
10026
10651
|
return s;
|
|
10027
10652
|
return s.slice(0, max - 1).trimEnd() + "\u2026";
|
|
@@ -10077,7 +10702,7 @@ function computeDaySignals(entries2) {
|
|
|
10077
10702
|
type,
|
|
10078
10703
|
count: v.count,
|
|
10079
10704
|
sample_description: v.sample_description,
|
|
10080
|
-
sample_prompt_preview:
|
|
10705
|
+
sample_prompt_preview: truncate4(v.sample_prompt_preview, 200)
|
|
10081
10706
|
}));
|
|
10082
10707
|
const frameCounts = /* @__PURE__ */ new Map();
|
|
10083
10708
|
for (const s of signalsList) {
|
|
@@ -10096,7 +10721,7 @@ function computeDaySignals(entries2) {
|
|
|
10096
10721
|
if ((e.first_user ?? "").length > 0)
|
|
10097
10722
|
verbosity_distribution[s.verbosity] += 1;
|
|
10098
10723
|
for (const ref of s.external_refs) {
|
|
10099
|
-
external_refs.push({ session_id: e.session_id, kind: ref.kind, preview:
|
|
10724
|
+
external_refs.push({ session_id: e.session_id, kind: ref.kind, preview: truncate4(ref.preview, 200) });
|
|
10100
10725
|
}
|
|
10101
10726
|
const ints = e.numbers.interrupts ?? 0;
|
|
10102
10727
|
interrupts += ints;
|
|
@@ -10502,7 +11127,7 @@ var init_digest_day_pipeline = __esm({
|
|
|
10502
11127
|
init_budget();
|
|
10503
11128
|
init_pipeline_lock();
|
|
10504
11129
|
init_fs();
|
|
10505
|
-
|
|
11130
|
+
init_dist();
|
|
10506
11131
|
THIRTY_MIN_MS2 = 30 * 60 * 1e3;
|
|
10507
11132
|
MAX_RETRY_COUNT2 = 3;
|
|
10508
11133
|
}
|
|
@@ -10698,7 +11323,7 @@ var init_digest_week = __esm({
|
|
|
10698
11323
|
"../entries/dist/prompts/digest-week.js"() {
|
|
10699
11324
|
"use strict";
|
|
10700
11325
|
init_zod();
|
|
10701
|
-
|
|
11326
|
+
init_dist();
|
|
10702
11327
|
AGENT_NAMING_TABLE2 = agentMetadata.map((m) => ` - agent="${m.kind}" \u2192 render as "${m.displayName}"`).join("\n");
|
|
10703
11328
|
DateRegex = /^\d{4}-\d{2}-\d{2}$/;
|
|
10704
11329
|
ProjectAreaResponseSchema = external_exports.object({
|
|
@@ -10969,7 +11594,7 @@ function computeInteractionModes(entries2) {
|
|
|
10969
11594
|
date: entry.local_day,
|
|
10970
11595
|
project_display: prettyProject3(entry.project),
|
|
10971
11596
|
type: sa.type,
|
|
10972
|
-
prompt_preview:
|
|
11597
|
+
prompt_preview: truncate5(sa.prompt_preview, 200)
|
|
10973
11598
|
});
|
|
10974
11599
|
}
|
|
10975
11600
|
const skillExamples = [];
|
|
@@ -10986,7 +11611,7 @@ function computeInteractionModes(entries2) {
|
|
|
10986
11611
|
skillExamples.push({
|
|
10987
11612
|
date: e.local_day,
|
|
10988
11613
|
skill,
|
|
10989
|
-
first_user_preview:
|
|
11614
|
+
first_user_preview: truncate5(e.first_user, 200)
|
|
10990
11615
|
});
|
|
10991
11616
|
}
|
|
10992
11617
|
}
|
|
@@ -11003,7 +11628,7 @@ function computeInteractionModes(entries2) {
|
|
|
11003
11628
|
project_display: prettyProject3(longestTurnEntry.project),
|
|
11004
11629
|
active_min: longestTurnEntry.numbers.active_min,
|
|
11005
11630
|
top_tools: longestTurnEntry.top_tools.slice(0, 5),
|
|
11006
|
-
first_user_preview:
|
|
11631
|
+
first_user_preview: truncate5(longestTurnEntry.first_user, 200)
|
|
11007
11632
|
} : null;
|
|
11008
11633
|
const tools_per_turn = turn_count > 0 ? tools_total / turn_count : 0;
|
|
11009
11634
|
const label = tools_per_turn < 5 ? "rapid" : tools_per_turn < 15 ? "mixed" : "batch";
|
|
@@ -11034,7 +11659,7 @@ function computeInteractionModes(entries2) {
|
|
|
11034
11659
|
}
|
|
11035
11660
|
};
|
|
11036
11661
|
}
|
|
11037
|
-
function
|
|
11662
|
+
function truncate5(s, max) {
|
|
11038
11663
|
if (s.length <= max)
|
|
11039
11664
|
return s;
|
|
11040
11665
|
return s.slice(0, max - 1).trimEnd() + "\u2026";
|
|
@@ -11081,7 +11706,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
|
|
|
11081
11706
|
evidence_subagent = {
|
|
11082
11707
|
type: sa.type,
|
|
11083
11708
|
description: sa.description,
|
|
11084
|
-
prompt_preview:
|
|
11709
|
+
prompt_preview: truncate5(sa.prompt_preview, 200)
|
|
11085
11710
|
};
|
|
11086
11711
|
}
|
|
11087
11712
|
const project_display = repEntry ? prettyProject3(repEntry.project) : dd.projects[0]?.display_name ?? "";
|
|
@@ -11092,7 +11717,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
|
|
|
11092
11717
|
outcome: dayOutcome.get(dd.key) ?? null,
|
|
11093
11718
|
helpfulness: dayHelp.get(dd.key) ?? null,
|
|
11094
11719
|
evidence_subagent,
|
|
11095
|
-
evidence_first_user: repEntry?.first_user ?
|
|
11720
|
+
evidence_first_user: repEntry?.first_user ? truncate5(repEntry.first_user, 200) : null,
|
|
11096
11721
|
day_signature: dd.day_signature ?? null
|
|
11097
11722
|
};
|
|
11098
11723
|
});
|
|
@@ -11167,7 +11792,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
|
|
|
11167
11792
|
date: day2,
|
|
11168
11793
|
session_id: ref.session_id,
|
|
11169
11794
|
ref_kind: ref.kind,
|
|
11170
|
-
preview:
|
|
11795
|
+
preview: truncate5(ref.preview, 200)
|
|
11171
11796
|
});
|
|
11172
11797
|
}
|
|
11173
11798
|
total_interrupts += signals.comm_style.steering.interrupts;
|
|
@@ -11239,7 +11864,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
|
|
|
11239
11864
|
count: v.count,
|
|
11240
11865
|
days: [...v.days].sort(),
|
|
11241
11866
|
sample_description: v.sample_description,
|
|
11242
|
-
sample_prompt_preview:
|
|
11867
|
+
sample_prompt_preview: truncate5(v.sample_prompt_preview, 200)
|
|
11243
11868
|
})),
|
|
11244
11869
|
threads,
|
|
11245
11870
|
communication_style: {
|
|
@@ -11887,7 +12512,7 @@ function activeMs(timestamps) {
|
|
|
11887
12512
|
let active = 0;
|
|
11888
12513
|
for (let i = 1; i < ts.length; i++) {
|
|
11889
12514
|
const dt = ts[i] - ts[i - 1];
|
|
11890
|
-
if (dt <
|
|
12515
|
+
if (dt < IDLE_GAP_MS4)
|
|
11891
12516
|
active += dt;
|
|
11892
12517
|
}
|
|
11893
12518
|
return active;
|
|
@@ -12058,7 +12683,7 @@ function buildSessionSlice(entry, events, daySignature) {
|
|
|
12058
12683
|
let intEnd = sortedTs[0];
|
|
12059
12684
|
for (let i = 1; i < sortedTs.length; i++) {
|
|
12060
12685
|
const dt = sortedTs[i] - intEnd;
|
|
12061
|
-
if (dt >=
|
|
12686
|
+
if (dt >= IDLE_GAP_MS4) {
|
|
12062
12687
|
intervals.push({
|
|
12063
12688
|
start_min: fmtMin(intStart - sliceStartMs),
|
|
12064
12689
|
end_min: fmtMin(intEnd - sliceStartMs)
|
|
@@ -12455,14 +13080,14 @@ async function generateTopSession(slice, opts = {}) {
|
|
|
12455
13080
|
void lastModel;
|
|
12456
13081
|
}
|
|
12457
13082
|
}
|
|
12458
|
-
var
|
|
13083
|
+
var IDLE_GAP_MS4, LONG_AUTONOMOUS_MIN, N_USER, N_FIRST_AGENT, N_LAST_AGENT, N_USER_TURN1, N_SUBAGENT, SHELL_NOISE, INTERRUPT_RE2, PR_TITLE_RE, PinResponseSchema, TopSessionResponseSchema, SYSTEM_PROMPT5, TOP_SESSION_SYSTEM_PROMPT, DEFAULT_MODEL5, defaultCallLLMTopSession, validateTopSession;
|
|
12459
13084
|
var init_top_sessions = __esm({
|
|
12460
13085
|
"../entries/dist/top-sessions.js"() {
|
|
12461
13086
|
"use strict";
|
|
12462
13087
|
init_zod();
|
|
12463
13088
|
init_signals();
|
|
12464
13089
|
init_llm_runner();
|
|
12465
|
-
|
|
13090
|
+
IDLE_GAP_MS4 = 3 * 60 * 1e3;
|
|
12466
13091
|
LONG_AUTONOMOUS_MIN = 20;
|
|
12467
13092
|
N_USER = 150;
|
|
12468
13093
|
N_FIRST_AGENT = 150;
|
|
@@ -13215,7 +13840,7 @@ Exit codes:
|
|
|
13215
13840
|
var init_entries = __esm({
|
|
13216
13841
|
"src/commands/entries.ts"() {
|
|
13217
13842
|
"use strict";
|
|
13218
|
-
|
|
13843
|
+
init_dist2();
|
|
13219
13844
|
init_fs2();
|
|
13220
13845
|
init_args();
|
|
13221
13846
|
}
|
|
@@ -13716,11 +14341,12 @@ async function runTeamBackfill(log = noopLog, filePath = USAGE_LOG4, configOverr
|
|
|
13716
14341
|
return { paired: false, sentSnapshots: 0, insertedSnapshots: 0, skippedSnapshots: 0, batches: 0 };
|
|
13717
14342
|
}
|
|
13718
14343
|
const raw = readSnapshots(filePath);
|
|
13719
|
-
|
|
14344
|
+
const claudeOnly = raw.filter((s) => !s.agent || s.agent === "claude-code");
|
|
14345
|
+
if (claudeOnly.length === 0) {
|
|
13720
14346
|
log("info", "team backfill: no usage snapshots to send");
|
|
13721
14347
|
return { paired: true, sentSnapshots: 0, insertedSnapshots: 0, skippedSnapshots: 0, batches: 0 };
|
|
13722
14348
|
}
|
|
13723
|
-
const wire =
|
|
14349
|
+
const wire = claudeOnly.map(rawToWire);
|
|
13724
14350
|
const batches = chunk(wire, BATCH_SIZE);
|
|
13725
14351
|
const planTier = await getPlanTier(PROFILE_CACHE).catch(() => null) ?? void 0;
|
|
13726
14352
|
let inserted = 0;
|
|
@@ -13784,7 +14410,7 @@ var init_backfill = __esm({
|
|
|
13784
14410
|
// src/team/push.ts
|
|
13785
14411
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
13786
14412
|
function readLatestUsageSnapshotForWire(filePath, nowMs = Date.now()) {
|
|
13787
|
-
const raw =
|
|
14413
|
+
const raw = latestClaudeCodeSnapshot(filePath);
|
|
13788
14414
|
if (!raw) return null;
|
|
13789
14415
|
const capturedMs = Date.parse(raw.captured_at);
|
|
13790
14416
|
if (Number.isNaN(capturedMs)) return null;
|
|
@@ -13854,7 +14480,7 @@ var SNAPSHOT_FRESHNESS_MS;
|
|
|
13854
14480
|
var init_push = __esm({
|
|
13855
14481
|
"src/team/push.ts"() {
|
|
13856
14482
|
"use strict";
|
|
13857
|
-
|
|
14483
|
+
init_dist();
|
|
13858
14484
|
init_storage();
|
|
13859
14485
|
SNAPSHOT_FRESHNESS_MS = 10 * 60 * 1e3;
|
|
13860
14486
|
}
|
|
@@ -13929,7 +14555,7 @@ async function runTeamSync(log = noopLog2, configOverride) {
|
|
|
13929
14555
|
if (!config) return { paired: false, pushed: 0, queued: 0, queuedDrained: 0 };
|
|
13930
14556
|
try {
|
|
13931
14557
|
const { listSessions: listSessions2, loadCalibrationCurve: loadCalibrationCurve2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
13932
|
-
const { toLocalDay: toLocalDay4 } = await Promise.resolve().then(() => (
|
|
14558
|
+
const { toLocalDay: toLocalDay4 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
13933
14559
|
const today = toLocalDay4(Date.now());
|
|
13934
14560
|
const sessions = await listSessions2({ limit: 1e4 });
|
|
13935
14561
|
const rollups = buildRollupsForRange(sessions, config.lastSyncedDay);
|
|
@@ -14537,9 +15163,9 @@ function listTraceFiles() {
|
|
|
14537
15163
|
if (!existsSync12(RUNS_DIR2)) return [];
|
|
14538
15164
|
const entries2 = readdirSync3(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
|
|
14539
15165
|
return entries2.map((f) => {
|
|
14540
|
-
const
|
|
14541
|
-
const st = statSync4(
|
|
14542
|
-
return { runId: f.replace(/\.jsonl$/, ""), path:
|
|
15166
|
+
const path5 = join17(RUNS_DIR2, f);
|
|
15167
|
+
const st = statSync4(path5);
|
|
15168
|
+
return { runId: f.replace(/\.jsonl$/, ""), path: path5, mtimeMs: st.mtimeMs };
|
|
14543
15169
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
14544
15170
|
}
|
|
14545
15171
|
function resolveRunId(arg) {
|
|
@@ -14561,8 +15187,8 @@ function resolveRunId(arg) {
|
|
|
14561
15187
|
}
|
|
14562
15188
|
return null;
|
|
14563
15189
|
}
|
|
14564
|
-
function readTrace(
|
|
14565
|
-
return readFileSync15(
|
|
15190
|
+
function readTrace(path5) {
|
|
15191
|
+
return readFileSync15(path5, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
|
|
14566
15192
|
try {
|
|
14567
15193
|
return JSON.parse(l);
|
|
14568
15194
|
} catch {
|
|
@@ -14743,7 +15369,7 @@ async function main() {
|
|
|
14743
15369
|
case "version":
|
|
14744
15370
|
case "--version":
|
|
14745
15371
|
case "-v":
|
|
14746
|
-
console.log(`fleetlens ${"0.
|
|
15372
|
+
console.log(`fleetlens ${"0.10.0"}`);
|
|
14747
15373
|
break;
|
|
14748
15374
|
case "help":
|
|
14749
15375
|
case "--help":
|