fleetlens 0.16.0 → 0.16.2
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/agent/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/[id]/events/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/[id]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/[id]/stop/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/mcp/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/suggestions/route.js.nft.json +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.nft.json +1 -1
- 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.nft.json +1 -1
- 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.nft.json +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/pdf/[key]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/projects/open-folder/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/runs/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/team/autostart/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/team/sync-projects/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/workflow-agent/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/print/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/print/[key]/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/team/onboarding/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js +2 -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]__02faosk._.js +3 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__09cgmam._.js +2 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0tk8p3d._.js +2 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0u6pamj._.js +2 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__12jomao._.js +2 -2
- package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0f3q8gt._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__11xp-1u._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0epqfet._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_[id]_session-view_tsx_0-9t5~.._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_sessions-grid_tsx_0bri5x.._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0x014hn._.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_changelog_ts_0n7_p1d._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- 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/0jes0m38a9ib_.js +14 -0
- package/app/apps/web/.next/static/chunks/{07bzlfv97o1ig.js → 0p5ee8wje3zi~.js} +1 -1
- package/app/apps/web/.next/static/chunks/{0_0~~ipv90vm3.js → 0rrcj195v1nd..js} +1 -1
- package/app/apps/web/.next/static/chunks/{0awkd5df28gvj.js → 0~uugvb4izjd2.js} +1 -1
- package/app/apps/web/app/sessions/[id]/session-view.tsx +6 -2
- package/app/apps/web/app/sessions/sessions-grid.tsx +5 -1
- package/app/apps/web/app/usage/page.tsx +166 -2
- package/app/apps/web/components/agent-badge.tsx +3 -0
- package/app/apps/web/components/agent-icon.tsx +42 -4
- package/app/apps/web/components/menubar-install-banner.tsx +2 -1
- package/app/apps/web/components/usage-charts-dashboard.tsx +9 -1
- package/app/apps/web/lib/agent/run.ts +24 -5
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/public/agent-icons/grok.svg +8 -0
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +1173 -123
- package/dist/index.js +1230 -167
- package/menubar/FleetlensMenubar.app/Contents/Info.plist +2 -2
- package/menubar/FleetlensMenubar.app/Contents/MacOS/FleetlensMenubar +0 -0
- package/menubar/FleetlensMenubar.app/Contents/Resources/grok.svg +8 -0
- package/menubar/FleetlensMenubar.app/Contents/_CodeSignature/CodeResources +11 -0
- package/package.json +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ns6ydi._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +0 -3
- package/app/apps/web/.next/static/chunks/0mry~475v0fa3.js +0 -14
- /package/app/apps/web/.next/static/{bTww6lPxII4wde65VQDrF → q_fQaCe85j7F9VawBRe81}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{bTww6lPxII4wde65VQDrF → q_fQaCe85j7F9VawBRe81}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{bTww6lPxII4wde65VQDrF → q_fQaCe85j7F9VawBRe81}/_ssgManifest.js +0 -0
package/dist/daemon-worker.js
CHANGED
|
@@ -607,7 +607,7 @@ function getAgentMetadata(kind) {
|
|
|
607
607
|
function isAgentKind(s) {
|
|
608
608
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
609
609
|
}
|
|
610
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
610
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
611
611
|
var init_agent_metadata = __esm({
|
|
612
612
|
"../parser/dist/agent-metadata.js"() {
|
|
613
613
|
"use strict";
|
|
@@ -653,13 +653,22 @@ var init_agent_metadata = __esm({
|
|
|
653
653
|
accentColor: "rgb(59, 130, 246)",
|
|
654
654
|
iconChar: "Z"
|
|
655
655
|
};
|
|
656
|
+
GROK_METADATA = {
|
|
657
|
+
kind: "grok",
|
|
658
|
+
displayName: "Grok Build",
|
|
659
|
+
shortLabel: "Grok",
|
|
660
|
+
// Slate-400 — visible on dark Fleetlens chrome and still fine on light.
|
|
661
|
+
accentColor: "rgb(100, 116, 139)",
|
|
662
|
+
iconChar: "\u25C8"
|
|
663
|
+
};
|
|
656
664
|
agentMetadata = [
|
|
657
665
|
CLAUDE_CODE_METADATA,
|
|
658
666
|
CODEX_METADATA,
|
|
659
667
|
GEMINI_METADATA,
|
|
660
668
|
ANTIGRAVITY_METADATA,
|
|
661
669
|
COWORK_METADATA,
|
|
662
|
-
ZAI_METADATA
|
|
670
|
+
ZAI_METADATA,
|
|
671
|
+
GROK_METADATA
|
|
663
672
|
];
|
|
664
673
|
KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
|
|
665
674
|
}
|
|
@@ -1516,11 +1525,11 @@ function defaultBranch(commonDir) {
|
|
|
1516
1525
|
}
|
|
1517
1526
|
return void 0;
|
|
1518
1527
|
}
|
|
1519
|
-
function readGitFolder(
|
|
1520
|
-
if (!existsSync(
|
|
1528
|
+
function readGitFolder(path9) {
|
|
1529
|
+
if (!existsSync(path9))
|
|
1521
1530
|
return { exists: false, isWorktree: false };
|
|
1522
1531
|
try {
|
|
1523
|
-
const git = nearestDotGit(realpathOrSelf(
|
|
1532
|
+
const git = nearestDotGit(realpathOrSelf(path9));
|
|
1524
1533
|
if (!git)
|
|
1525
1534
|
return { exists: true, isWorktree: false };
|
|
1526
1535
|
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
@@ -2776,6 +2785,11 @@ function parseRollout(file, lines) {
|
|
|
2776
2785
|
let lastUserPreview;
|
|
2777
2786
|
let lastAgentPreview;
|
|
2778
2787
|
const tsMs = [];
|
|
2788
|
+
let threadSource;
|
|
2789
|
+
let rootSessionId;
|
|
2790
|
+
let parentThreadId;
|
|
2791
|
+
let agentNickname;
|
|
2792
|
+
let agentPath;
|
|
2779
2793
|
let idx = 0;
|
|
2780
2794
|
for (const line of lines) {
|
|
2781
2795
|
if (typeof line !== "object" || line === null)
|
|
@@ -2796,6 +2810,16 @@ function parseRollout(file, lines) {
|
|
|
2796
2810
|
if (type === "session_meta") {
|
|
2797
2811
|
if (typeof payload.cwd === "string")
|
|
2798
2812
|
cwd = payload.cwd;
|
|
2813
|
+
if (threadSource === void 0 && typeof payload.thread_source === "string")
|
|
2814
|
+
threadSource = payload.thread_source;
|
|
2815
|
+
if (rootSessionId === void 0 && typeof payload.session_id === "string")
|
|
2816
|
+
rootSessionId = payload.session_id;
|
|
2817
|
+
if (parentThreadId === void 0 && typeof payload.parent_thread_id === "string")
|
|
2818
|
+
parentThreadId = payload.parent_thread_id;
|
|
2819
|
+
if (agentNickname === void 0 && typeof payload.agent_nickname === "string")
|
|
2820
|
+
agentNickname = payload.agent_nickname;
|
|
2821
|
+
if (agentPath === void 0 && typeof payload.agent_path === "string")
|
|
2822
|
+
agentPath = payload.agent_path;
|
|
2799
2823
|
continue;
|
|
2800
2824
|
}
|
|
2801
2825
|
if (type === "turn_context") {
|
|
@@ -2999,7 +3023,7 @@ function parseRollout(file, lines) {
|
|
|
2999
3023
|
airTimeMs,
|
|
3000
3024
|
activeSegments
|
|
3001
3025
|
};
|
|
3002
|
-
return { meta, events };
|
|
3026
|
+
return { meta, events, threadSource, rootSessionId, parentThreadId, agentNickname, agentPath };
|
|
3003
3027
|
}
|
|
3004
3028
|
function numberOf(v) {
|
|
3005
3029
|
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
@@ -3037,28 +3061,112 @@ function clearCodexCaches() {
|
|
|
3037
3061
|
metaCache2.clear();
|
|
3038
3062
|
detailCache2.clear();
|
|
3039
3063
|
}
|
|
3040
|
-
async function
|
|
3041
|
-
const root = opts.root ?? DEFAULT_CODEX_ROOT;
|
|
3064
|
+
async function scanAllCodex(root) {
|
|
3042
3065
|
const files = await listRolloutFiles(root);
|
|
3043
3066
|
const out = [];
|
|
3044
3067
|
for (const file of files) {
|
|
3045
3068
|
const cached = metaCache2.get(file.filePath);
|
|
3046
3069
|
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3047
|
-
out.push(
|
|
3070
|
+
out.push({
|
|
3071
|
+
file,
|
|
3072
|
+
meta: cached.meta,
|
|
3073
|
+
threadSource: cached.threadSource,
|
|
3074
|
+
rootSessionId: cached.rootSessionId,
|
|
3075
|
+
parentThreadId: cached.parentThreadId,
|
|
3076
|
+
agentNickname: cached.agentNickname,
|
|
3077
|
+
agentPath: cached.agentPath
|
|
3078
|
+
});
|
|
3048
3079
|
continue;
|
|
3049
3080
|
}
|
|
3050
3081
|
try {
|
|
3051
3082
|
const lines = await readJsonl(file.filePath);
|
|
3052
|
-
const
|
|
3083
|
+
const parsed = parseRollout(file, lines);
|
|
3053
3084
|
metaCache2.set(file.filePath, {
|
|
3054
|
-
meta,
|
|
3085
|
+
meta: parsed.meta,
|
|
3055
3086
|
mtimeMs: file.mtimeMs,
|
|
3056
|
-
sizeBytes: file.sizeBytes
|
|
3087
|
+
sizeBytes: file.sizeBytes,
|
|
3088
|
+
threadSource: parsed.threadSource,
|
|
3089
|
+
rootSessionId: parsed.rootSessionId,
|
|
3090
|
+
parentThreadId: parsed.parentThreadId,
|
|
3091
|
+
agentNickname: parsed.agentNickname,
|
|
3092
|
+
agentPath: parsed.agentPath
|
|
3093
|
+
});
|
|
3094
|
+
out.push({
|
|
3095
|
+
file,
|
|
3096
|
+
meta: parsed.meta,
|
|
3097
|
+
threadSource: parsed.threadSource,
|
|
3098
|
+
rootSessionId: parsed.rootSessionId,
|
|
3099
|
+
parentThreadId: parsed.parentThreadId,
|
|
3100
|
+
agentNickname: parsed.agentNickname,
|
|
3101
|
+
agentPath: parsed.agentPath
|
|
3057
3102
|
});
|
|
3058
|
-
out.push(meta);
|
|
3059
3103
|
} catch {
|
|
3060
3104
|
}
|
|
3061
3105
|
}
|
|
3106
|
+
return out;
|
|
3107
|
+
}
|
|
3108
|
+
function buildSubagentRun(entry, parentStartMs) {
|
|
3109
|
+
const meta = entry.meta;
|
|
3110
|
+
const startMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
|
|
3111
|
+
const endMs = meta.lastTimestamp ? Date.parse(meta.lastTimestamp) : void 0;
|
|
3112
|
+
const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
|
|
3113
|
+
const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
|
|
3114
|
+
return {
|
|
3115
|
+
agentId: meta.id,
|
|
3116
|
+
agentType: entry.agentNickname ?? entry.agentPath ?? "subagent",
|
|
3117
|
+
description: entry.agentPath ?? entry.agentNickname ?? meta.id,
|
|
3118
|
+
startMs: startOk,
|
|
3119
|
+
endMs: endOk,
|
|
3120
|
+
durationMs: meta.durationMs,
|
|
3121
|
+
startTOffsetMs: parentStartMs !== void 0 && startOk !== void 0 ? Math.max(0, startOk - parentStartMs) : void 0,
|
|
3122
|
+
endTOffsetMs: parentStartMs !== void 0 && endOk !== void 0 ? Math.max(0, endOk - parentStartMs) : void 0,
|
|
3123
|
+
eventCount: meta.eventCount,
|
|
3124
|
+
totalUsage: meta.totalUsage,
|
|
3125
|
+
model: meta.model,
|
|
3126
|
+
toolCallCount: meta.toolCallCount,
|
|
3127
|
+
finalPreview: meta.lastAgentPreview
|
|
3128
|
+
};
|
|
3129
|
+
}
|
|
3130
|
+
async function listCodexSessions(opts = {}) {
|
|
3131
|
+
const root = opts.root ?? DEFAULT_CODEX_ROOT;
|
|
3132
|
+
const all = await scanAllCodex(root);
|
|
3133
|
+
const subagentsByRoot = /* @__PURE__ */ new Map();
|
|
3134
|
+
for (const entry of all) {
|
|
3135
|
+
if (entry.threadSource !== "subagent" || !entry.rootSessionId)
|
|
3136
|
+
continue;
|
|
3137
|
+
const list = subagentsByRoot.get(entry.rootSessionId);
|
|
3138
|
+
if (list)
|
|
3139
|
+
list.push(entry);
|
|
3140
|
+
else
|
|
3141
|
+
subagentsByRoot.set(entry.rootSessionId, [entry]);
|
|
3142
|
+
}
|
|
3143
|
+
const out = [];
|
|
3144
|
+
for (const entry of all) {
|
|
3145
|
+
if (entry.threadSource === "subagent")
|
|
3146
|
+
continue;
|
|
3147
|
+
const children = subagentsByRoot.get(entry.meta.id);
|
|
3148
|
+
if (!children || children.length === 0) {
|
|
3149
|
+
out.push(entry.meta);
|
|
3150
|
+
continue;
|
|
3151
|
+
}
|
|
3152
|
+
const merged = {
|
|
3153
|
+
...entry.meta,
|
|
3154
|
+
spawnedAgentCount: children.length,
|
|
3155
|
+
totalUsage: {
|
|
3156
|
+
input: entry.meta.totalUsage.input + children.reduce((s, c) => s + c.meta.totalUsage.input, 0),
|
|
3157
|
+
output: entry.meta.totalUsage.output + children.reduce((s, c) => s + c.meta.totalUsage.output, 0),
|
|
3158
|
+
cacheRead: entry.meta.totalUsage.cacheRead + children.reduce((s, c) => s + c.meta.totalUsage.cacheRead, 0),
|
|
3159
|
+
cacheWrite: entry.meta.totalUsage.cacheWrite + children.reduce((s, c) => s + c.meta.totalUsage.cacheWrite, 0)
|
|
3160
|
+
},
|
|
3161
|
+
toolCallCount: (entry.meta.toolCallCount ?? 0) + children.reduce((s, c) => s + (c.meta.toolCallCount ?? 0), 0)
|
|
3162
|
+
};
|
|
3163
|
+
for (const c of children) {
|
|
3164
|
+
if (c.meta.lastTimestamp && (!merged.lastTimestamp || c.meta.lastTimestamp > merged.lastTimestamp)) {
|
|
3165
|
+
merged.lastTimestamp = c.meta.lastTimestamp;
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
out.push(merged);
|
|
3169
|
+
}
|
|
3062
3170
|
out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
|
|
3063
3171
|
if (opts.limit !== void 0)
|
|
3064
3172
|
return out.slice(0, opts.limit);
|
|
@@ -3066,17 +3174,41 @@ async function listCodexSessions(opts = {}) {
|
|
|
3066
3174
|
}
|
|
3067
3175
|
async function getCodexSession(id, opts = {}) {
|
|
3068
3176
|
const root = opts.root ?? DEFAULT_CODEX_ROOT;
|
|
3069
|
-
const
|
|
3070
|
-
const
|
|
3071
|
-
if (!
|
|
3072
|
-
|
|
3177
|
+
const all = await scanAllCodex(root);
|
|
3178
|
+
const rootEntry = all.find((a) => a.meta.id === id && a.threadSource !== "subagent");
|
|
3179
|
+
if (!rootEntry) {
|
|
3180
|
+
const direct = all.find((a) => a.meta.id === id);
|
|
3181
|
+
if (!direct)
|
|
3182
|
+
return null;
|
|
3183
|
+
const cached2 = detailCache2.get(direct.file.filePath);
|
|
3184
|
+
if (cached2 && cached2.mtimeMs === direct.file.mtimeMs && cached2.sizeBytes === direct.file.sizeBytes) {
|
|
3185
|
+
return cached2.detail;
|
|
3186
|
+
}
|
|
3187
|
+
const lines2 = await readJsonl(direct.file.filePath);
|
|
3188
|
+
const { meta: meta2, events: events2 } = parseRollout(direct.file, lines2);
|
|
3189
|
+
const detail2 = { ...meta2, events: events2 };
|
|
3190
|
+
detailCache2.set(direct.file.filePath, {
|
|
3191
|
+
detail: detail2,
|
|
3192
|
+
mtimeMs: direct.file.mtimeMs,
|
|
3193
|
+
sizeBytes: direct.file.sizeBytes
|
|
3194
|
+
});
|
|
3195
|
+
return detail2;
|
|
3196
|
+
}
|
|
3197
|
+
const file = rootEntry.file;
|
|
3073
3198
|
const cached = detailCache2.get(file.filePath);
|
|
3074
3199
|
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3075
3200
|
return cached.detail;
|
|
3076
3201
|
}
|
|
3077
3202
|
const lines = await readJsonl(file.filePath);
|
|
3078
3203
|
const { meta, events } = parseRollout(file, lines);
|
|
3079
|
-
const
|
|
3204
|
+
const children = all.filter((a) => a.threadSource === "subagent" && a.rootSessionId === id);
|
|
3205
|
+
const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
|
|
3206
|
+
const subagents = children.map((c) => buildSubagentRun(c, parentStartMs)).sort((a, b) => (a.startMs ?? 0) - (b.startMs ?? 0));
|
|
3207
|
+
const detail = {
|
|
3208
|
+
...meta,
|
|
3209
|
+
events,
|
|
3210
|
+
...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
|
|
3211
|
+
};
|
|
3080
3212
|
detailCache2.set(file.filePath, {
|
|
3081
3213
|
detail,
|
|
3082
3214
|
mtimeMs: file.mtimeMs,
|
|
@@ -4401,6 +4533,672 @@ var init_cowork = __esm({
|
|
|
4401
4533
|
}
|
|
4402
4534
|
});
|
|
4403
4535
|
|
|
4536
|
+
// ../parser/dist/grok.js
|
|
4537
|
+
import { promises as fs6 } from "node:fs";
|
|
4538
|
+
import os6 from "node:os";
|
|
4539
|
+
import path6 from "node:path";
|
|
4540
|
+
function resolveDefaultGrokRoot() {
|
|
4541
|
+
const home = process.env.GROK_HOME || path6.join(os6.homedir(), ".grok");
|
|
4542
|
+
return path6.join(home, "sessions");
|
|
4543
|
+
}
|
|
4544
|
+
async function safeReaddir5(p) {
|
|
4545
|
+
return fs6.readdir(p).catch(() => []);
|
|
4546
|
+
}
|
|
4547
|
+
async function safeReadJson(p) {
|
|
4548
|
+
const raw = await fs6.readFile(p, "utf8").catch(() => null);
|
|
4549
|
+
if (raw == null)
|
|
4550
|
+
return null;
|
|
4551
|
+
try {
|
|
4552
|
+
return JSON.parse(raw);
|
|
4553
|
+
} catch {
|
|
4554
|
+
return null;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
async function resolveEncodedCwd(groupDir, encoded) {
|
|
4558
|
+
const cwdFile = path6.join(groupDir, ".cwd");
|
|
4559
|
+
const fromFile = await fs6.readFile(cwdFile, "utf8").catch(() => null);
|
|
4560
|
+
if (fromFile && fromFile.trim())
|
|
4561
|
+
return fromFile.trim();
|
|
4562
|
+
try {
|
|
4563
|
+
return decodeURIComponent(encoded);
|
|
4564
|
+
} catch {
|
|
4565
|
+
return encoded;
|
|
4566
|
+
}
|
|
4567
|
+
}
|
|
4568
|
+
async function listSessionDirs(root) {
|
|
4569
|
+
const out = [];
|
|
4570
|
+
const groups = await safeReaddir5(root);
|
|
4571
|
+
for (const group of groups) {
|
|
4572
|
+
if (group === "session_search.sqlite" || group.startsWith("."))
|
|
4573
|
+
continue;
|
|
4574
|
+
const groupDir = path6.join(root, group);
|
|
4575
|
+
const groupStat = await fs6.stat(groupDir).catch(() => null);
|
|
4576
|
+
if (!groupStat?.isDirectory())
|
|
4577
|
+
continue;
|
|
4578
|
+
const decodedCwd = await resolveEncodedCwd(groupDir, group);
|
|
4579
|
+
const entries = await safeReaddir5(groupDir);
|
|
4580
|
+
for (const entry of entries) {
|
|
4581
|
+
if (entry === "prompt_history.jsonl" || entry.startsWith("."))
|
|
4582
|
+
continue;
|
|
4583
|
+
const dirPath = path6.join(groupDir, entry);
|
|
4584
|
+
const summaryPath = path6.join(dirPath, "summary.json");
|
|
4585
|
+
const updatesPath = path6.join(dirPath, "updates.jsonl");
|
|
4586
|
+
const signalsCandidate = path6.join(dirPath, "signals.json");
|
|
4587
|
+
const [summaryStat, updatesStat, signalsStat] = await Promise.all([
|
|
4588
|
+
fs6.stat(summaryPath).catch(() => null),
|
|
4589
|
+
fs6.stat(updatesPath).catch(() => null),
|
|
4590
|
+
fs6.stat(signalsCandidate).catch(() => null)
|
|
4591
|
+
]);
|
|
4592
|
+
if (!summaryStat?.isFile())
|
|
4593
|
+
continue;
|
|
4594
|
+
const mtimeMs = Math.max(summaryStat.mtimeMs, updatesStat?.mtimeMs ?? 0);
|
|
4595
|
+
const sizeBytes = (updatesStat?.size ?? 0) + summaryStat.size;
|
|
4596
|
+
out.push({
|
|
4597
|
+
dirPath,
|
|
4598
|
+
updatesPath,
|
|
4599
|
+
summaryPath,
|
|
4600
|
+
signalsPath: signalsStat?.isFile() ? signalsCandidate : null,
|
|
4601
|
+
sessionId: entry,
|
|
4602
|
+
groupName: group,
|
|
4603
|
+
decodedCwd,
|
|
4604
|
+
mtimeMs,
|
|
4605
|
+
sizeBytes
|
|
4606
|
+
});
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
return out;
|
|
4610
|
+
}
|
|
4611
|
+
function emptyUsage4() {
|
|
4612
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
4613
|
+
}
|
|
4614
|
+
function previewOf4(text) {
|
|
4615
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
4616
|
+
}
|
|
4617
|
+
function truncate5(s, n) {
|
|
4618
|
+
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
4619
|
+
}
|
|
4620
|
+
function textFromContent2(content) {
|
|
4621
|
+
if (!content)
|
|
4622
|
+
return "";
|
|
4623
|
+
if (typeof content === "string")
|
|
4624
|
+
return content;
|
|
4625
|
+
if (typeof content.text === "string")
|
|
4626
|
+
return content.text;
|
|
4627
|
+
return "";
|
|
4628
|
+
}
|
|
4629
|
+
function toolResultText(update) {
|
|
4630
|
+
const items = update.content;
|
|
4631
|
+
if (Array.isArray(items)) {
|
|
4632
|
+
const parts = [];
|
|
4633
|
+
for (const item of items) {
|
|
4634
|
+
if (!item || typeof item !== "object")
|
|
4635
|
+
continue;
|
|
4636
|
+
if (typeof item.text === "string" && item.text) {
|
|
4637
|
+
parts.push(item.text);
|
|
4638
|
+
continue;
|
|
4639
|
+
}
|
|
4640
|
+
const inner = item.content;
|
|
4641
|
+
if (typeof inner === "string" && inner)
|
|
4642
|
+
parts.push(inner);
|
|
4643
|
+
else if (inner && typeof inner === "object" && typeof inner.text === "string") {
|
|
4644
|
+
parts.push(inner.text);
|
|
4645
|
+
}
|
|
4646
|
+
}
|
|
4647
|
+
if (parts.length)
|
|
4648
|
+
return parts.join("\n");
|
|
4649
|
+
}
|
|
4650
|
+
const raw = update.rawOutput;
|
|
4651
|
+
if (raw == null)
|
|
4652
|
+
return "";
|
|
4653
|
+
if (typeof raw === "string")
|
|
4654
|
+
return raw;
|
|
4655
|
+
if (typeof raw === "object") {
|
|
4656
|
+
const r = raw;
|
|
4657
|
+
if (typeof r.output_for_prompt === "string")
|
|
4658
|
+
return r.output_for_prompt;
|
|
4659
|
+
if (typeof r.summary_for_prompt === "string")
|
|
4660
|
+
return r.summary_for_prompt;
|
|
4661
|
+
if (r.Content && typeof r.Content === "object") {
|
|
4662
|
+
const c = r.Content;
|
|
4663
|
+
if (typeof c.content === "string")
|
|
4664
|
+
return c.content;
|
|
4665
|
+
}
|
|
4666
|
+
if (r.TodosUpdated && typeof r.TodosUpdated === "object") {
|
|
4667
|
+
const t = r.TodosUpdated;
|
|
4668
|
+
if (typeof t.summary_for_prompt === "string")
|
|
4669
|
+
return t.summary_for_prompt;
|
|
4670
|
+
}
|
|
4671
|
+
if (Array.isArray(r.stdout) || Array.isArray(r.output)) {
|
|
4672
|
+
try {
|
|
4673
|
+
return JSON.stringify({
|
|
4674
|
+
type: r.type,
|
|
4675
|
+
exit_code: r.exit_code,
|
|
4676
|
+
note: "binary/stdout omitted"
|
|
4677
|
+
});
|
|
4678
|
+
} catch {
|
|
4679
|
+
return "";
|
|
4680
|
+
}
|
|
4681
|
+
}
|
|
4682
|
+
try {
|
|
4683
|
+
return JSON.stringify(raw);
|
|
4684
|
+
} catch {
|
|
4685
|
+
return "";
|
|
4686
|
+
}
|
|
4687
|
+
}
|
|
4688
|
+
return String(raw);
|
|
4689
|
+
}
|
|
4690
|
+
function toolNameOf(update) {
|
|
4691
|
+
const meta = update._meta;
|
|
4692
|
+
if (meta && typeof meta === "object") {
|
|
4693
|
+
const xai = meta["x.ai/tool"];
|
|
4694
|
+
if (xai && typeof xai === "object") {
|
|
4695
|
+
const name = xai.name;
|
|
4696
|
+
if (typeof name === "string" && name)
|
|
4697
|
+
return name;
|
|
4698
|
+
}
|
|
4699
|
+
}
|
|
4700
|
+
if (typeof update.title === "string" && update.title) {
|
|
4701
|
+
if (!update.title.includes(" ") && !update.title.includes("`"))
|
|
4702
|
+
return update.title;
|
|
4703
|
+
return update.title;
|
|
4704
|
+
}
|
|
4705
|
+
return "tool";
|
|
4706
|
+
}
|
|
4707
|
+
function statusOf(update) {
|
|
4708
|
+
const s = update.status;
|
|
4709
|
+
if (typeof s === "string")
|
|
4710
|
+
return s;
|
|
4711
|
+
if (s && typeof s === "object" && typeof s.status === "string")
|
|
4712
|
+
return s.status;
|
|
4713
|
+
return void 0;
|
|
4714
|
+
}
|
|
4715
|
+
function lineTimestampIso(line) {
|
|
4716
|
+
const meta = line.params?._meta;
|
|
4717
|
+
const agentMs = meta && typeof meta.agentTimestampMs === "number" ? meta.agentTimestampMs : void 0;
|
|
4718
|
+
if (agentMs != null && Number.isFinite(agentMs)) {
|
|
4719
|
+
return new Date(agentMs).toISOString();
|
|
4720
|
+
}
|
|
4721
|
+
const ts = line.timestamp;
|
|
4722
|
+
if (typeof ts === "number" && Number.isFinite(ts)) {
|
|
4723
|
+
const ms = ts > 1e12 ? ts : ts * 1e3;
|
|
4724
|
+
return new Date(ms).toISOString();
|
|
4725
|
+
}
|
|
4726
|
+
return void 0;
|
|
4727
|
+
}
|
|
4728
|
+
function computeActiveSegments5(tsMs) {
|
|
4729
|
+
if (tsMs.length === 0)
|
|
4730
|
+
return [];
|
|
4731
|
+
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
4732
|
+
const out = [];
|
|
4733
|
+
let segStart = sorted[0];
|
|
4734
|
+
let segEnd = sorted[0];
|
|
4735
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
4736
|
+
const t = sorted[i];
|
|
4737
|
+
if (t - segEnd > IDLE_GAP_MS4) {
|
|
4738
|
+
out.push({ startMs: segStart, endMs: segEnd });
|
|
4739
|
+
segStart = t;
|
|
4740
|
+
}
|
|
4741
|
+
segEnd = t;
|
|
4742
|
+
}
|
|
4743
|
+
out.push({ startMs: segStart, endMs: segEnd });
|
|
4744
|
+
return out;
|
|
4745
|
+
}
|
|
4746
|
+
async function parseSession3(dir) {
|
|
4747
|
+
const [summary, signals, updatesRaw] = await Promise.all([
|
|
4748
|
+
safeReadJson(dir.summaryPath),
|
|
4749
|
+
dir.signalsPath ? safeReadJson(dir.signalsPath) : Promise.resolve(null),
|
|
4750
|
+
fs6.readFile(dir.updatesPath, "utf8").catch(() => "")
|
|
4751
|
+
]);
|
|
4752
|
+
const sessionId = summary?.info?.id ?? dir.sessionId;
|
|
4753
|
+
const cwd = summary?.info?.cwd ?? dir.decodedCwd;
|
|
4754
|
+
let model = summary?.current_model_id ?? signals?.primaryModelId ?? signals?.modelsUsed?.[0];
|
|
4755
|
+
const events = [];
|
|
4756
|
+
const totalUsage = emptyUsage4();
|
|
4757
|
+
if (signals?.contextTokensUsed && signals.contextTokensUsed > 0) {
|
|
4758
|
+
totalUsage.input = signals.contextTokensUsed;
|
|
4759
|
+
}
|
|
4760
|
+
let firstTimestamp;
|
|
4761
|
+
let lastTimestamp;
|
|
4762
|
+
let toolCallCount = 0;
|
|
4763
|
+
let turnCount = 0;
|
|
4764
|
+
let firstUserPreview;
|
|
4765
|
+
let lastUserPreview;
|
|
4766
|
+
let lastAgentPreview;
|
|
4767
|
+
const tsMs = [];
|
|
4768
|
+
let idx = 0;
|
|
4769
|
+
const completedToolResults = /* @__PURE__ */ new Set();
|
|
4770
|
+
let maxTotalTokens = 0;
|
|
4771
|
+
function noteTs(ts, role) {
|
|
4772
|
+
if (!ts || role === "meta")
|
|
4773
|
+
return;
|
|
4774
|
+
if (!firstTimestamp)
|
|
4775
|
+
firstTimestamp = ts;
|
|
4776
|
+
lastTimestamp = ts;
|
|
4777
|
+
const ms = Date.parse(ts);
|
|
4778
|
+
if (Number.isFinite(ms))
|
|
4779
|
+
tsMs.push(ms);
|
|
4780
|
+
}
|
|
4781
|
+
function pushEvent(e) {
|
|
4782
|
+
events.push(e);
|
|
4783
|
+
noteTs(e.timestamp, e.role);
|
|
4784
|
+
}
|
|
4785
|
+
let buf = null;
|
|
4786
|
+
function flushBuf() {
|
|
4787
|
+
if (!buf)
|
|
4788
|
+
return;
|
|
4789
|
+
const text = buf.texts.join("");
|
|
4790
|
+
const preview = previewOf4(text);
|
|
4791
|
+
if (buf.kind === "user") {
|
|
4792
|
+
const isHidden = !text || isFrameworkInjectedUserInput(text);
|
|
4793
|
+
if (text && !isHidden) {
|
|
4794
|
+
if (!firstUserPreview)
|
|
4795
|
+
firstUserPreview = preview;
|
|
4796
|
+
lastUserPreview = preview;
|
|
4797
|
+
turnCount += 1;
|
|
4798
|
+
}
|
|
4799
|
+
if (text) {
|
|
4800
|
+
pushEvent({
|
|
4801
|
+
index: idx++,
|
|
4802
|
+
timestamp: buf.firstTs,
|
|
4803
|
+
role: "user",
|
|
4804
|
+
rawType: "grok/user_message",
|
|
4805
|
+
preview,
|
|
4806
|
+
blocks: [{ type: "text", text }],
|
|
4807
|
+
messageId: buf.promptId,
|
|
4808
|
+
raw: buf.raw.length === 1 ? buf.raw[0] : buf.raw
|
|
4809
|
+
});
|
|
4810
|
+
}
|
|
4811
|
+
} else if (buf.kind === "agent") {
|
|
4812
|
+
if (text)
|
|
4813
|
+
lastAgentPreview = preview;
|
|
4814
|
+
if (text) {
|
|
4815
|
+
pushEvent({
|
|
4816
|
+
index: idx++,
|
|
4817
|
+
timestamp: buf.firstTs,
|
|
4818
|
+
role: "agent",
|
|
4819
|
+
rawType: "grok/agent_message",
|
|
4820
|
+
preview,
|
|
4821
|
+
blocks: [{ type: "text", text }],
|
|
4822
|
+
messageId: buf.promptId,
|
|
4823
|
+
model: buf.model ?? model,
|
|
4824
|
+
raw: buf.raw.length === 1 ? buf.raw[0] : buf.raw
|
|
4825
|
+
});
|
|
4826
|
+
}
|
|
4827
|
+
} else if (buf.kind === "thought") {
|
|
4828
|
+
if (text) {
|
|
4829
|
+
pushEvent({
|
|
4830
|
+
index: idx++,
|
|
4831
|
+
timestamp: buf.firstTs,
|
|
4832
|
+
role: "agent-thinking",
|
|
4833
|
+
rawType: "grok/agent_thought",
|
|
4834
|
+
preview,
|
|
4835
|
+
blocks: [{ type: "thinking", thinking: text }],
|
|
4836
|
+
messageId: buf.promptId,
|
|
4837
|
+
model: buf.model ?? model,
|
|
4838
|
+
raw: buf.raw.length === 1 ? buf.raw[0] : buf.raw
|
|
4839
|
+
});
|
|
4840
|
+
}
|
|
4841
|
+
}
|
|
4842
|
+
buf = null;
|
|
4843
|
+
}
|
|
4844
|
+
function appendChunk(kind, text, ts, promptId, modelId, raw) {
|
|
4845
|
+
if (!text && kind === "user")
|
|
4846
|
+
return;
|
|
4847
|
+
if (buf && buf.kind !== kind)
|
|
4848
|
+
flushBuf();
|
|
4849
|
+
if (!buf) {
|
|
4850
|
+
buf = {
|
|
4851
|
+
kind,
|
|
4852
|
+
texts: [],
|
|
4853
|
+
firstTs: ts,
|
|
4854
|
+
lastTs: ts,
|
|
4855
|
+
model: modelId,
|
|
4856
|
+
promptId,
|
|
4857
|
+
raw: []
|
|
4858
|
+
};
|
|
4859
|
+
}
|
|
4860
|
+
if (text)
|
|
4861
|
+
buf.texts.push(text);
|
|
4862
|
+
buf.lastTs = ts ?? buf.lastTs;
|
|
4863
|
+
if (modelId)
|
|
4864
|
+
buf.model = modelId;
|
|
4865
|
+
if (promptId)
|
|
4866
|
+
buf.promptId = promptId;
|
|
4867
|
+
buf.raw.push(raw);
|
|
4868
|
+
}
|
|
4869
|
+
const lines = updatesRaw.split("\n");
|
|
4870
|
+
for (const line of lines) {
|
|
4871
|
+
const trimmed = line.trim();
|
|
4872
|
+
if (!trimmed)
|
|
4873
|
+
continue;
|
|
4874
|
+
let obj;
|
|
4875
|
+
try {
|
|
4876
|
+
obj = JSON.parse(trimmed);
|
|
4877
|
+
} catch {
|
|
4878
|
+
continue;
|
|
4879
|
+
}
|
|
4880
|
+
const update = obj.params?.update;
|
|
4881
|
+
if (!update || typeof update !== "object")
|
|
4882
|
+
continue;
|
|
4883
|
+
const st = update.sessionUpdate;
|
|
4884
|
+
if (!st)
|
|
4885
|
+
continue;
|
|
4886
|
+
const ts = lineTimestampIso(obj);
|
|
4887
|
+
const lineMeta = obj.params?._meta ?? {};
|
|
4888
|
+
const updateMeta = update._meta ?? {};
|
|
4889
|
+
const promptId = typeof lineMeta.promptId === "string" && lineMeta.promptId || typeof updateMeta.promptId === "string" && updateMeta.promptId || void 0;
|
|
4890
|
+
const modelId = typeof updateMeta.modelId === "string" && updateMeta.modelId || typeof lineMeta.modelId === "string" && lineMeta.modelId || void 0;
|
|
4891
|
+
if (modelId)
|
|
4892
|
+
model = modelId;
|
|
4893
|
+
const totalTok = lineMeta.totalTokens;
|
|
4894
|
+
if (typeof totalTok === "number" && totalTok > maxTotalTokens) {
|
|
4895
|
+
maxTotalTokens = totalTok;
|
|
4896
|
+
}
|
|
4897
|
+
if (st === "user_message_chunk") {
|
|
4898
|
+
const text = textFromContent2(update.content);
|
|
4899
|
+
appendChunk("user", text, ts, promptId, modelId, obj);
|
|
4900
|
+
continue;
|
|
4901
|
+
}
|
|
4902
|
+
if (st === "agent_message_chunk") {
|
|
4903
|
+
const text = textFromContent2(update.content);
|
|
4904
|
+
appendChunk("agent", text, ts, promptId, modelId, obj);
|
|
4905
|
+
continue;
|
|
4906
|
+
}
|
|
4907
|
+
if (st === "agent_thought_chunk") {
|
|
4908
|
+
const text = textFromContent2(update.content);
|
|
4909
|
+
appendChunk("thought", text, ts, promptId, modelId, obj);
|
|
4910
|
+
continue;
|
|
4911
|
+
}
|
|
4912
|
+
flushBuf();
|
|
4913
|
+
if (st === "tool_call") {
|
|
4914
|
+
const toolCallId = typeof update.toolCallId === "string" ? update.toolCallId : `grok-${idx}`;
|
|
4915
|
+
const name = toolNameOf(update);
|
|
4916
|
+
const input = update.rawInput ?? {};
|
|
4917
|
+
const argsStr = input ? JSON.stringify(input) : "";
|
|
4918
|
+
toolCallCount += 1;
|
|
4919
|
+
pushEvent({
|
|
4920
|
+
index: idx++,
|
|
4921
|
+
timestamp: ts,
|
|
4922
|
+
role: "tool-call",
|
|
4923
|
+
rawType: "grok/tool_call",
|
|
4924
|
+
preview: `${name}(${truncate5(argsStr, 80)})`,
|
|
4925
|
+
blocks: [{ type: "tool_use", id: toolCallId, name, input }],
|
|
4926
|
+
toolName: name,
|
|
4927
|
+
toolUseId: toolCallId,
|
|
4928
|
+
model,
|
|
4929
|
+
raw: obj
|
|
4930
|
+
});
|
|
4931
|
+
continue;
|
|
4932
|
+
}
|
|
4933
|
+
if (st === "tool_call_update") {
|
|
4934
|
+
const status = statusOf(update);
|
|
4935
|
+
if (status !== "completed" && status !== "failed" && status !== "error" && status !== "cancelled") {
|
|
4936
|
+
continue;
|
|
4937
|
+
}
|
|
4938
|
+
const toolCallId = typeof update.toolCallId === "string" ? update.toolCallId : "";
|
|
4939
|
+
if (toolCallId && completedToolResults.has(toolCallId))
|
|
4940
|
+
continue;
|
|
4941
|
+
if (toolCallId)
|
|
4942
|
+
completedToolResults.add(toolCallId);
|
|
4943
|
+
const resultText = toolResultText(update);
|
|
4944
|
+
const isError = status === "failed" || status === "error" || status === "cancelled";
|
|
4945
|
+
pushEvent({
|
|
4946
|
+
index: idx++,
|
|
4947
|
+
timestamp: ts,
|
|
4948
|
+
role: "tool-result",
|
|
4949
|
+
rawType: "grok/tool_result",
|
|
4950
|
+
preview: previewOf4(resultText),
|
|
4951
|
+
blocks: [
|
|
4952
|
+
{
|
|
4953
|
+
type: "tool_result",
|
|
4954
|
+
tool_use_id: toolCallId,
|
|
4955
|
+
content: resultText,
|
|
4956
|
+
is_error: isError || void 0
|
|
4957
|
+
}
|
|
4958
|
+
],
|
|
4959
|
+
toolUseId: toolCallId || void 0,
|
|
4960
|
+
toolResult: resultText,
|
|
4961
|
+
raw: obj
|
|
4962
|
+
});
|
|
4963
|
+
continue;
|
|
4964
|
+
}
|
|
4965
|
+
if (st === "turn_completed") {
|
|
4966
|
+
continue;
|
|
4967
|
+
}
|
|
4968
|
+
}
|
|
4969
|
+
flushBuf();
|
|
4970
|
+
if (totalUsage.input === 0 && maxTotalTokens > 0) {
|
|
4971
|
+
totalUsage.input = maxTotalTokens;
|
|
4972
|
+
}
|
|
4973
|
+
if (!firstTimestamp && summary?.created_at)
|
|
4974
|
+
firstTimestamp = summary.created_at;
|
|
4975
|
+
if (!lastTimestamp) {
|
|
4976
|
+
lastTimestamp = summary?.last_active_at ?? summary?.updated_at ?? firstTimestamp;
|
|
4977
|
+
}
|
|
4978
|
+
if (signals?.toolCallCount != null && signals.toolCallCount > toolCallCount) {
|
|
4979
|
+
toolCallCount = signals.toolCallCount;
|
|
4980
|
+
}
|
|
4981
|
+
if (signals?.turnCount != null && signals.turnCount > turnCount) {
|
|
4982
|
+
turnCount = signals.turnCount;
|
|
4983
|
+
}
|
|
4984
|
+
const startMs = firstTimestamp ? Date.parse(firstTimestamp) : void 0;
|
|
4985
|
+
if (startMs !== void 0 && Number.isFinite(startMs)) {
|
|
4986
|
+
let prevMs;
|
|
4987
|
+
for (const ev of events) {
|
|
4988
|
+
if (!ev.timestamp)
|
|
4989
|
+
continue;
|
|
4990
|
+
const ms = Date.parse(ev.timestamp);
|
|
4991
|
+
if (!Number.isFinite(ms))
|
|
4992
|
+
continue;
|
|
4993
|
+
ev.tOffsetMs = Math.max(0, ms - startMs);
|
|
4994
|
+
if (prevMs !== void 0)
|
|
4995
|
+
ev.gapMs = Math.max(0, ms - prevMs);
|
|
4996
|
+
prevMs = ms;
|
|
4997
|
+
}
|
|
4998
|
+
}
|
|
4999
|
+
const activeSegments = computeActiveSegments5(tsMs);
|
|
5000
|
+
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
5001
|
+
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
5002
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
5003
|
+
const projectName = project?.projectName ?? cwd ?? dir.decodedCwd;
|
|
5004
|
+
const projectDir = dir.groupName || (cwd ? encodeURIComponent(cwd) : "(unknown)");
|
|
5005
|
+
if (!firstUserPreview) {
|
|
5006
|
+
const title = summary?.generated_title || summary?.session_summary;
|
|
5007
|
+
if (title)
|
|
5008
|
+
firstUserPreview = previewOf4(title);
|
|
5009
|
+
}
|
|
5010
|
+
const spawnedAgentCount = await countSubagentChildren(dir.dirPath);
|
|
5011
|
+
const meta = {
|
|
5012
|
+
agent: "grok",
|
|
5013
|
+
id: sessionId,
|
|
5014
|
+
filePath: dir.updatesPath,
|
|
5015
|
+
projectName,
|
|
5016
|
+
worktreeName: project?.worktreeName,
|
|
5017
|
+
repoName: project?.repoName,
|
|
5018
|
+
projectDir,
|
|
5019
|
+
sessionId,
|
|
5020
|
+
firstTimestamp,
|
|
5021
|
+
lastTimestamp,
|
|
5022
|
+
lastActivityMs: lastTimestamp ? Date.parse(lastTimestamp) : void 0,
|
|
5023
|
+
durationMs: durationMs && Number.isFinite(durationMs) ? durationMs : void 0,
|
|
5024
|
+
eventCount: events.length,
|
|
5025
|
+
model,
|
|
5026
|
+
cwd,
|
|
5027
|
+
gitBranch: summary?.head_branch,
|
|
5028
|
+
agentName: summary?.agent_name,
|
|
5029
|
+
totalUsage,
|
|
5030
|
+
status: "idle",
|
|
5031
|
+
firstUserPreview,
|
|
5032
|
+
lastUserPreview,
|
|
5033
|
+
lastAgentPreview,
|
|
5034
|
+
toolCallCount,
|
|
5035
|
+
turnCount,
|
|
5036
|
+
linesAdded: signals?.agentLinesAdded,
|
|
5037
|
+
linesRemoved: signals?.agentLinesRemoved,
|
|
5038
|
+
airTimeMs,
|
|
5039
|
+
activeSegments,
|
|
5040
|
+
...spawnedAgentCount > 0 ? { spawnedAgentCount } : {}
|
|
5041
|
+
};
|
|
5042
|
+
return { meta, events, sessionKind: summary?.session_kind };
|
|
5043
|
+
}
|
|
5044
|
+
async function countSubagentChildren(dirPath) {
|
|
5045
|
+
const subRoot = path6.join(dirPath, "subagents");
|
|
5046
|
+
const entries = await safeReaddir5(subRoot);
|
|
5047
|
+
let n = 0;
|
|
5048
|
+
for (const e of entries) {
|
|
5049
|
+
const st = await fs6.stat(path6.join(subRoot, e)).catch(() => null);
|
|
5050
|
+
if (st?.isDirectory())
|
|
5051
|
+
n += 1;
|
|
5052
|
+
}
|
|
5053
|
+
return n;
|
|
5054
|
+
}
|
|
5055
|
+
async function loadGrokSubagents(parentDir, parentStartMs) {
|
|
5056
|
+
const subRoot = path6.join(parentDir.dirPath, "subagents");
|
|
5057
|
+
const entries = await safeReaddir5(subRoot);
|
|
5058
|
+
const groupDir = path6.dirname(parentDir.dirPath);
|
|
5059
|
+
const runs = [];
|
|
5060
|
+
for (const entry of entries) {
|
|
5061
|
+
const metaPath = path6.join(subRoot, entry, "meta.json");
|
|
5062
|
+
const meta = await safeReadJson(metaPath);
|
|
5063
|
+
if (!meta)
|
|
5064
|
+
continue;
|
|
5065
|
+
const childId = meta.child_session_id ?? meta.subagent_id ?? entry;
|
|
5066
|
+
const childDir = path6.join(groupDir, childId);
|
|
5067
|
+
const [childSummary, childSignals] = await Promise.all([
|
|
5068
|
+
safeReadJson(path6.join(childDir, "summary.json")),
|
|
5069
|
+
safeReadJson(path6.join(childDir, "signals.json"))
|
|
5070
|
+
]);
|
|
5071
|
+
const startMs = childSummary?.created_at ? Date.parse(childSummary.created_at) : void 0;
|
|
5072
|
+
const endIso = childSummary?.last_active_at ?? childSummary?.updated_at;
|
|
5073
|
+
const endMs = endIso ? Date.parse(endIso) : void 0;
|
|
5074
|
+
const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
|
|
5075
|
+
const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
|
|
5076
|
+
const usage = emptyUsage4();
|
|
5077
|
+
if (childSignals?.contextTokensUsed)
|
|
5078
|
+
usage.input = childSignals.contextTokensUsed;
|
|
5079
|
+
runs.push({
|
|
5080
|
+
agentId: childId,
|
|
5081
|
+
agentType: meta.subagent_type ?? childSummary?.agent_name ?? "subagent",
|
|
5082
|
+
description: meta.description && meta.description.trim() || childSummary?.generated_title || childSummary?.session_summary || childId,
|
|
5083
|
+
startMs: startOk,
|
|
5084
|
+
endMs: endOk,
|
|
5085
|
+
durationMs: startOk !== void 0 && endOk !== void 0 ? Math.max(0, endOk - startOk) : void 0,
|
|
5086
|
+
startTOffsetMs: parentStartMs !== void 0 && startOk !== void 0 ? Math.max(0, startOk - parentStartMs) : void 0,
|
|
5087
|
+
endTOffsetMs: parentStartMs !== void 0 && endOk !== void 0 ? Math.max(0, endOk - parentStartMs) : void 0,
|
|
5088
|
+
eventCount: childSummary?.num_messages ?? childSummary?.num_chat_messages ?? 0,
|
|
5089
|
+
totalUsage: usage,
|
|
5090
|
+
prompt: typeof meta.prompt === "string" ? meta.prompt : void 0,
|
|
5091
|
+
model: childSummary?.current_model_id ?? childSignals?.primaryModelId,
|
|
5092
|
+
toolCallCount: childSignals?.toolCallCount
|
|
5093
|
+
});
|
|
5094
|
+
}
|
|
5095
|
+
runs.sort((a, b) => (a.startMs ?? 0) - (b.startMs ?? 0));
|
|
5096
|
+
return runs;
|
|
5097
|
+
}
|
|
5098
|
+
function clearGrokCaches() {
|
|
5099
|
+
metaCache6.clear();
|
|
5100
|
+
detailCache6.clear();
|
|
5101
|
+
}
|
|
5102
|
+
async function listGrokSessions(opts = {}) {
|
|
5103
|
+
const root = opts.root ?? resolveDefaultGrokRoot();
|
|
5104
|
+
const dirs = await listSessionDirs(root);
|
|
5105
|
+
const out = [];
|
|
5106
|
+
for (const dir of dirs) {
|
|
5107
|
+
const summaryPeek = await safeReadJson(dir.summaryPath);
|
|
5108
|
+
if (summaryPeek?.session_kind === "subagent")
|
|
5109
|
+
continue;
|
|
5110
|
+
const cached = metaCache6.get(dir.dirPath);
|
|
5111
|
+
if (cached && cached.mtimeMs === dir.mtimeMs && cached.sizeBytes === dir.sizeBytes) {
|
|
5112
|
+
out.push(cached.meta);
|
|
5113
|
+
continue;
|
|
5114
|
+
}
|
|
5115
|
+
try {
|
|
5116
|
+
const { meta, sessionKind } = await parseSession3(dir);
|
|
5117
|
+
if (sessionKind === "subagent")
|
|
5118
|
+
continue;
|
|
5119
|
+
metaCache6.set(dir.dirPath, {
|
|
5120
|
+
meta,
|
|
5121
|
+
mtimeMs: dir.mtimeMs,
|
|
5122
|
+
sizeBytes: dir.sizeBytes
|
|
5123
|
+
});
|
|
5124
|
+
out.push(meta);
|
|
5125
|
+
} catch {
|
|
5126
|
+
}
|
|
5127
|
+
}
|
|
5128
|
+
out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
|
|
5129
|
+
if (opts.limit !== void 0)
|
|
5130
|
+
return out.slice(0, opts.limit);
|
|
5131
|
+
return out;
|
|
5132
|
+
}
|
|
5133
|
+
async function getGrokSession(id, opts = {}) {
|
|
5134
|
+
const root = opts.root ?? resolveDefaultGrokRoot();
|
|
5135
|
+
const dirs = await listSessionDirs(root);
|
|
5136
|
+
const chosen = dirs.find((d) => d.sessionId === id);
|
|
5137
|
+
if (!chosen) {
|
|
5138
|
+
for (const dir of dirs) {
|
|
5139
|
+
try {
|
|
5140
|
+
const { meta: meta2, events: events2 } = await parseSession3(dir);
|
|
5141
|
+
if (meta2.id === id) {
|
|
5142
|
+
const detail2 = { ...meta2, events: events2 };
|
|
5143
|
+
detailCache6.set(dir.dirPath, {
|
|
5144
|
+
detail: detail2,
|
|
5145
|
+
mtimeMs: dir.mtimeMs,
|
|
5146
|
+
sizeBytes: dir.sizeBytes
|
|
5147
|
+
});
|
|
5148
|
+
return detail2;
|
|
5149
|
+
}
|
|
5150
|
+
} catch {
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5153
|
+
return null;
|
|
5154
|
+
}
|
|
5155
|
+
const cached = detailCache6.get(chosen.dirPath);
|
|
5156
|
+
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
|
|
5157
|
+
return cached.detail;
|
|
5158
|
+
}
|
|
5159
|
+
const { meta, events } = await parseSession3(chosen);
|
|
5160
|
+
const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
|
|
5161
|
+
const subagents = await loadGrokSubagents(chosen, parentStartMs !== void 0 && Number.isFinite(parentStartMs) ? parentStartMs : void 0);
|
|
5162
|
+
const detail = {
|
|
5163
|
+
...meta,
|
|
5164
|
+
events,
|
|
5165
|
+
...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
|
|
5166
|
+
};
|
|
5167
|
+
detailCache6.set(chosen.dirPath, {
|
|
5168
|
+
detail,
|
|
5169
|
+
mtimeMs: chosen.mtimeMs,
|
|
5170
|
+
sizeBytes: chosen.sizeBytes
|
|
5171
|
+
});
|
|
5172
|
+
metaCache6.set(chosen.dirPath, {
|
|
5173
|
+
meta: {
|
|
5174
|
+
...meta,
|
|
5175
|
+
...subagents.length > 0 ? { spawnedAgentCount: subagents.length } : {}
|
|
5176
|
+
},
|
|
5177
|
+
mtimeMs: chosen.mtimeMs,
|
|
5178
|
+
sizeBytes: chosen.sizeBytes
|
|
5179
|
+
});
|
|
5180
|
+
return detail;
|
|
5181
|
+
}
|
|
5182
|
+
function grokSessionLocalDay(meta) {
|
|
5183
|
+
if (!meta.firstTimestamp)
|
|
5184
|
+
return void 0;
|
|
5185
|
+
const ms = Date.parse(meta.firstTimestamp);
|
|
5186
|
+
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
5187
|
+
}
|
|
5188
|
+
var DEFAULT_GROK_ROOT, IDLE_GAP_MS4, metaCache6, detailCache6;
|
|
5189
|
+
var init_grok = __esm({
|
|
5190
|
+
"../parser/dist/grok.js"() {
|
|
5191
|
+
"use strict";
|
|
5192
|
+
init_analytics();
|
|
5193
|
+
init_git_project();
|
|
5194
|
+
init_user_input();
|
|
5195
|
+
DEFAULT_GROK_ROOT = path6.join(os6.homedir(), ".grok", "sessions");
|
|
5196
|
+
IDLE_GAP_MS4 = 3 * 60 * 1e3;
|
|
5197
|
+
metaCache6 = /* @__PURE__ */ new Map();
|
|
5198
|
+
detailCache6 = /* @__PURE__ */ new Map();
|
|
5199
|
+
}
|
|
5200
|
+
});
|
|
5201
|
+
|
|
4404
5202
|
// ../parser/dist/team-config.js
|
|
4405
5203
|
import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync, renameSync } from "node:fs";
|
|
4406
5204
|
import { join as join3 } from "node:path";
|
|
@@ -4460,6 +5258,7 @@ __export(fs_exports, {
|
|
|
4460
5258
|
DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
|
|
4461
5259
|
DEFAULT_COWORK_ROOT: () => DEFAULT_COWORK_ROOT,
|
|
4462
5260
|
DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
|
|
5261
|
+
DEFAULT_GROK_ROOT: () => DEFAULT_GROK_ROOT,
|
|
4463
5262
|
DEFAULT_ROOT: () => DEFAULT_ROOT,
|
|
4464
5263
|
RICH_ROLLUP_SCHEMA_VERSION: () => RICH_ROLLUP_SCHEMA_VERSION,
|
|
4465
5264
|
agentSources: () => agentSources,
|
|
@@ -4470,6 +5269,7 @@ __export(fs_exports, {
|
|
|
4470
5269
|
cclensHome: () => cclensHome,
|
|
4471
5270
|
cclensPath: () => cclensPath,
|
|
4472
5271
|
clearCaches: () => clearCaches,
|
|
5272
|
+
clearGrokCaches: () => clearGrokCaches,
|
|
4473
5273
|
clearTeamConfig: () => clearTeamConfig,
|
|
4474
5274
|
codexSessionLocalDay: () => codexSessionLocalDay,
|
|
4475
5275
|
decodeProjectName: () => decodeProjectName,
|
|
@@ -4481,8 +5281,10 @@ __export(fs_exports, {
|
|
|
4481
5281
|
getCodexSession: () => getCodexSession,
|
|
4482
5282
|
getCoworkSession: () => getCoworkSession,
|
|
4483
5283
|
getGeminiSession: () => getGeminiSession,
|
|
5284
|
+
getGrokSession: () => getGrokSession,
|
|
4484
5285
|
getLatestCodexUsage: () => getLatestCodexUsage,
|
|
4485
5286
|
getSession: () => getSession,
|
|
5287
|
+
grokSessionLocalDay: () => grokSessionLocalDay,
|
|
4486
5288
|
invalidateFile: () => invalidateFile,
|
|
4487
5289
|
isFleetlensRuntimeDir: () => isFleetlensRuntimeDir,
|
|
4488
5290
|
listAllSessions: () => listAllSessions,
|
|
@@ -4490,6 +5292,7 @@ __export(fs_exports, {
|
|
|
4490
5292
|
listCodexSessions: () => listCodexSessions,
|
|
4491
5293
|
listCoworkSessions: () => listCoworkSessions,
|
|
4492
5294
|
listGeminiSessions: () => listGeminiSessions,
|
|
5295
|
+
listGrokSessions: () => listGrokSessions,
|
|
4493
5296
|
listProjects: () => listProjects,
|
|
4494
5297
|
listSessions: () => listSessions,
|
|
4495
5298
|
loadCalibrationCurve: () => loadCalibrationCurve,
|
|
@@ -4502,20 +5305,21 @@ __export(fs_exports, {
|
|
|
4502
5305
|
readGitFolder: () => readGitFolder,
|
|
4503
5306
|
readJsonlFile: () => readJsonlFile,
|
|
4504
5307
|
readTeamConfig: () => readTeamConfig,
|
|
5308
|
+
resolveDefaultGrokRoot: () => resolveDefaultGrokRoot,
|
|
4505
5309
|
resolveProjectIdentity: () => resolveProjectIdentity,
|
|
4506
5310
|
sessionIdFromFileName: () => sessionIdFromFileName,
|
|
4507
5311
|
shouldSyncProject: () => shouldSyncProject,
|
|
4508
5312
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
4509
5313
|
writeTeamConfig: () => writeTeamConfig
|
|
4510
5314
|
});
|
|
4511
|
-
import { promises as
|
|
4512
|
-
import
|
|
4513
|
-
import
|
|
5315
|
+
import { promises as fs7, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
5316
|
+
import os7 from "node:os";
|
|
5317
|
+
import path7 from "node:path";
|
|
4514
5318
|
function cclensHome() {
|
|
4515
|
-
return process.env.CCLENS_HOME ||
|
|
5319
|
+
return process.env.CCLENS_HOME || path7.join(os7.homedir(), ".cclens");
|
|
4516
5320
|
}
|
|
4517
5321
|
function cclensPath(...parts) {
|
|
4518
|
-
return
|
|
5322
|
+
return path7.join(cclensHome(), ...parts);
|
|
4519
5323
|
}
|
|
4520
5324
|
function cacheStats() {
|
|
4521
5325
|
return claudeCodeCacheStats();
|
|
@@ -4526,6 +5330,7 @@ function clearCaches() {
|
|
|
4526
5330
|
clearGeminiCaches();
|
|
4527
5331
|
clearAntigravityCaches();
|
|
4528
5332
|
clearCoworkCaches();
|
|
5333
|
+
clearGrokCaches();
|
|
4529
5334
|
}
|
|
4530
5335
|
function invalidateFile(fullPath) {
|
|
4531
5336
|
invalidateClaudeCodeFile(fullPath);
|
|
@@ -4556,7 +5361,7 @@ function usageLogPath() {
|
|
|
4556
5361
|
}
|
|
4557
5362
|
function appendUsageSnapshot(snapshot) {
|
|
4558
5363
|
const p = usageLogPath();
|
|
4559
|
-
mkdirSync2(
|
|
5364
|
+
mkdirSync2(path7.dirname(p), { recursive: true });
|
|
4560
5365
|
appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
|
|
4561
5366
|
}
|
|
4562
5367
|
function pruneUsageAgent(agent) {
|
|
@@ -4572,13 +5377,13 @@ function pruneUsageAgent(agent) {
|
|
|
4572
5377
|
return true;
|
|
4573
5378
|
}
|
|
4574
5379
|
});
|
|
4575
|
-
mkdirSync2(
|
|
5380
|
+
mkdirSync2(path7.dirname(p), { recursive: true });
|
|
4576
5381
|
writeFileSync2(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
4577
5382
|
}
|
|
4578
5383
|
async function loadUsageByDay(start, end) {
|
|
4579
5384
|
let raw;
|
|
4580
5385
|
try {
|
|
4581
|
-
raw = await
|
|
5386
|
+
raw = await fs7.readFile(usageLogPath(), "utf8");
|
|
4582
5387
|
} catch {
|
|
4583
5388
|
return { by_day: [] };
|
|
4584
5389
|
}
|
|
@@ -4623,7 +5428,7 @@ async function loadUsageByDay(start, end) {
|
|
|
4623
5428
|
async function loadCalibrationSnapshots() {
|
|
4624
5429
|
let raw;
|
|
4625
5430
|
try {
|
|
4626
|
-
raw = await
|
|
5431
|
+
raw = await fs7.readFile(usageLogPath(), "utf8");
|
|
4627
5432
|
} catch {
|
|
4628
5433
|
return [];
|
|
4629
5434
|
}
|
|
@@ -4787,7 +5592,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
|
|
|
4787
5592
|
]);
|
|
4788
5593
|
return buildCalibrationCurve(events, snapshots, tier, granularityMin);
|
|
4789
5594
|
}
|
|
4790
|
-
var codexSource, geminiSource, antigravitySource, coworkSource, agentSources;
|
|
5595
|
+
var codexSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
|
|
4791
5596
|
var init_fs = __esm({
|
|
4792
5597
|
"../parser/dist/fs.js"() {
|
|
4793
5598
|
"use strict";
|
|
@@ -4799,12 +5604,14 @@ var init_fs = __esm({
|
|
|
4799
5604
|
init_gemini();
|
|
4800
5605
|
init_antigravity();
|
|
4801
5606
|
init_cowork();
|
|
5607
|
+
init_grok();
|
|
4802
5608
|
init_claude_code();
|
|
4803
5609
|
init_git_project();
|
|
4804
5610
|
init_codex();
|
|
4805
5611
|
init_gemini();
|
|
4806
5612
|
init_antigravity();
|
|
4807
5613
|
init_cowork();
|
|
5614
|
+
init_grok();
|
|
4808
5615
|
init_team_config();
|
|
4809
5616
|
init_team_wire();
|
|
4810
5617
|
codexSource = {
|
|
@@ -4858,26 +5665,38 @@ var init_fs = __esm({
|
|
|
4858
5665
|
return getCoworkSession(id);
|
|
4859
5666
|
}
|
|
4860
5667
|
};
|
|
5668
|
+
grokSource = {
|
|
5669
|
+
...GROK_METADATA,
|
|
5670
|
+
// Display default; list/get re-resolve GROK_HOME at call time internally.
|
|
5671
|
+
defaultRoot: DEFAULT_GROK_ROOT,
|
|
5672
|
+
async listSessions(opts) {
|
|
5673
|
+
return listGrokSessions(opts);
|
|
5674
|
+
},
|
|
5675
|
+
async getSession(id, opts) {
|
|
5676
|
+
return getGrokSession(id, opts);
|
|
5677
|
+
}
|
|
5678
|
+
};
|
|
4861
5679
|
agentSources = [
|
|
4862
5680
|
claudeCodeSource,
|
|
4863
5681
|
codexSource,
|
|
4864
5682
|
geminiSource,
|
|
4865
5683
|
antigravitySource,
|
|
4866
|
-
coworkSource
|
|
5684
|
+
coworkSource,
|
|
5685
|
+
grokSource
|
|
4867
5686
|
];
|
|
4868
5687
|
}
|
|
4869
5688
|
});
|
|
4870
5689
|
|
|
4871
5690
|
// src/usage/storage.ts
|
|
4872
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as
|
|
5691
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync5 } from "node:fs";
|
|
4873
5692
|
import { dirname as dirname2 } from "node:path";
|
|
4874
5693
|
function appendSnapshot(filePath, snapshot) {
|
|
4875
5694
|
mkdirSync3(dirname2(filePath), { recursive: true });
|
|
4876
5695
|
appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
4877
5696
|
}
|
|
4878
5697
|
function readSnapshots(filePath) {
|
|
4879
|
-
if (!
|
|
4880
|
-
const content =
|
|
5698
|
+
if (!existsSync5(filePath)) return [];
|
|
5699
|
+
const content = readFileSync7(filePath, "utf8");
|
|
4881
5700
|
const snapshots = [];
|
|
4882
5701
|
for (const line of content.split("\n")) {
|
|
4883
5702
|
if (!line.trim()) continue;
|
|
@@ -4889,8 +5708,8 @@ function readSnapshots(filePath) {
|
|
|
4889
5708
|
return snapshots;
|
|
4890
5709
|
}
|
|
4891
5710
|
function pruneAgent(filePath, agent) {
|
|
4892
|
-
if (!
|
|
4893
|
-
const kept =
|
|
5711
|
+
if (!existsSync5(filePath)) return;
|
|
5712
|
+
const kept = readFileSync7(filePath, "utf8").split("\n").filter((line) => {
|
|
4894
5713
|
if (!line.trim()) return false;
|
|
4895
5714
|
try {
|
|
4896
5715
|
return JSON.parse(line).agent !== agent;
|
|
@@ -5328,6 +6147,7 @@ __export(dist_exports, {
|
|
|
5328
6147
|
CODEX_METADATA: () => CODEX_METADATA,
|
|
5329
6148
|
COWORK_METADATA: () => COWORK_METADATA,
|
|
5330
6149
|
GEMINI_METADATA: () => GEMINI_METADATA,
|
|
6150
|
+
GROK_METADATA: () => GROK_METADATA,
|
|
5331
6151
|
PRICES: () => PRICES,
|
|
5332
6152
|
RATE_PER_PCT: () => RATE_PER_PCT,
|
|
5333
6153
|
RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
|
|
@@ -5401,7 +6221,7 @@ __export(file_probe_exports, {
|
|
|
5401
6221
|
probeArtifactSignals: () => probeArtifactSignals
|
|
5402
6222
|
});
|
|
5403
6223
|
import { createHash } from "node:crypto";
|
|
5404
|
-
import { existsSync as
|
|
6224
|
+
import { existsSync as existsSync10, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
|
|
5405
6225
|
import { homedir as homedir3 } from "node:os";
|
|
5406
6226
|
import { join as join8, relative, resolve as resolve3, sep } from "node:path";
|
|
5407
6227
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
@@ -5411,15 +6231,15 @@ function pathHash(relPath) {
|
|
|
5411
6231
|
function defaultScanRoots(extraRoots = []) {
|
|
5412
6232
|
const roots = [];
|
|
5413
6233
|
const home = join8(homedir3(), ".claude");
|
|
5414
|
-
if (
|
|
6234
|
+
if (existsSync10(home)) roots.push({ root: home, label: "user" });
|
|
5415
6235
|
for (const e of extraRoots) {
|
|
5416
6236
|
const r = resolve3(e, ".claude");
|
|
5417
|
-
if (
|
|
6237
|
+
if (existsSync10(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
5418
6238
|
}
|
|
5419
6239
|
return roots;
|
|
5420
6240
|
}
|
|
5421
6241
|
function listMarkdownFiles(dir) {
|
|
5422
|
-
if (!
|
|
6242
|
+
if (!existsSync10(dir)) return [];
|
|
5423
6243
|
const out = [];
|
|
5424
6244
|
let entries;
|
|
5425
6245
|
try {
|
|
@@ -5489,7 +6309,7 @@ function scanAuthored(roots, subdir, day) {
|
|
|
5489
6309
|
const out = [];
|
|
5490
6310
|
for (const r of roots) {
|
|
5491
6311
|
const dir = join8(r.root, subdir);
|
|
5492
|
-
if (!
|
|
6312
|
+
if (!existsSync10(dir)) continue;
|
|
5493
6313
|
for (const f of listMarkdownFiles(dir)) {
|
|
5494
6314
|
const firstSeen = firstSeenDateOf(f);
|
|
5495
6315
|
if (firstSeen !== day) continue;
|
|
@@ -5503,7 +6323,7 @@ function scanEdited(roots, day) {
|
|
|
5503
6323
|
const out = [];
|
|
5504
6324
|
for (const r of roots) {
|
|
5505
6325
|
const dir = join8(r.root, "skills");
|
|
5506
|
-
if (!
|
|
6326
|
+
if (!existsSync10(dir)) continue;
|
|
5507
6327
|
for (const f of listMarkdownFiles(dir)) {
|
|
5508
6328
|
const firstSeen = firstSeenDateOf(f);
|
|
5509
6329
|
if (firstSeen === day) continue;
|
|
@@ -5526,10 +6346,10 @@ function claudemdLineDelta(extraRoots, authorEmail, day) {
|
|
|
5526
6346
|
const candidates = [];
|
|
5527
6347
|
for (const e of extraRoots) {
|
|
5528
6348
|
const f = resolve3(e, "CLAUDE.md");
|
|
5529
|
-
if (
|
|
6349
|
+
if (existsSync10(f)) candidates.push(f);
|
|
5530
6350
|
}
|
|
5531
6351
|
const homeClaudeMd = join8(homedir3(), "CLAUDE.md");
|
|
5532
|
-
if (
|
|
6352
|
+
if (existsSync10(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
5533
6353
|
for (const file of candidates) {
|
|
5534
6354
|
try {
|
|
5535
6355
|
const out = execFileSync2(
|
|
@@ -5586,7 +6406,7 @@ var init_file_probe = __esm({
|
|
|
5586
6406
|
|
|
5587
6407
|
// src/daemon-worker.ts
|
|
5588
6408
|
import { spawn as spawn2 } from "node:child_process";
|
|
5589
|
-
import { closeSync, existsSync as
|
|
6409
|
+
import { closeSync, existsSync as existsSync17, mkdirSync as mkdirSync14, openSync, readFileSync as readFileSync20, writeFileSync as writeFileSync14 } from "node:fs";
|
|
5590
6410
|
import { dirname as dirname11, join as join12 } from "node:path";
|
|
5591
6411
|
import { fileURLToPath } from "node:url";
|
|
5592
6412
|
|
|
@@ -5618,9 +6438,9 @@ function readFromCredentialsFile() {
|
|
|
5618
6438
|
join(homedir(), ".claude", ".credentials.json"),
|
|
5619
6439
|
join(homedir(), ".config", "claude", "credentials.json")
|
|
5620
6440
|
];
|
|
5621
|
-
for (const
|
|
6441
|
+
for (const path9 of candidates) {
|
|
5622
6442
|
try {
|
|
5623
|
-
const blob = readFileSync(
|
|
6443
|
+
const blob = readFileSync(path9, "utf8");
|
|
5624
6444
|
const creds = extractCredentials(blob);
|
|
5625
6445
|
if (creds) return creds;
|
|
5626
6446
|
} catch {
|
|
@@ -5832,6 +6652,218 @@ async function fetchZaiUsage() {
|
|
|
5832
6652
|
};
|
|
5833
6653
|
}
|
|
5834
6654
|
|
|
6655
|
+
// src/usage/grok.ts
|
|
6656
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
|
|
6657
|
+
import os8 from "node:os";
|
|
6658
|
+
import path8 from "node:path";
|
|
6659
|
+
var CREDITS_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
|
|
6660
|
+
var SETTINGS_URL = "https://cli-chat-proxy.grok.com/v1/settings";
|
|
6661
|
+
var REFRESH_URL = "https://auth.x.ai/oauth2/token";
|
|
6662
|
+
var TOKEN_AUTH = "xai-grok-cli";
|
|
6663
|
+
var DEFAULT_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
|
|
6664
|
+
var WEEKLY_PERIOD = "USAGE_PERIOD_TYPE_WEEKLY";
|
|
6665
|
+
var REFRESH_BUFFER_MS = 5 * 60 * 1e3;
|
|
6666
|
+
var GrokApiError = class extends Error {
|
|
6667
|
+
constructor(message, code) {
|
|
6668
|
+
super(message);
|
|
6669
|
+
this.code = code;
|
|
6670
|
+
}
|
|
6671
|
+
};
|
|
6672
|
+
function grokHome() {
|
|
6673
|
+
return process.env.GROK_HOME || path8.join(os8.homedir(), ".grok");
|
|
6674
|
+
}
|
|
6675
|
+
function authPath() {
|
|
6676
|
+
return path8.join(grokHome(), "auth.json");
|
|
6677
|
+
}
|
|
6678
|
+
function loadAuthEntry() {
|
|
6679
|
+
const p = authPath();
|
|
6680
|
+
if (!existsSync4(p)) {
|
|
6681
|
+
throw new GrokApiError("Grok not logged in. Run `grok login`.", "no_auth");
|
|
6682
|
+
}
|
|
6683
|
+
let raw;
|
|
6684
|
+
try {
|
|
6685
|
+
raw = JSON.parse(readFileSync6(p, "utf8"));
|
|
6686
|
+
} catch {
|
|
6687
|
+
throw new GrokApiError("Grok auth.json is unreadable. Run `grok login`.", "no_auth");
|
|
6688
|
+
}
|
|
6689
|
+
for (const [entryKey2, entry] of Object.entries(raw)) {
|
|
6690
|
+
const token = typeof entry?.key === "string" ? entry.key.trim() : "";
|
|
6691
|
+
if (token) return { token, entry, entryKey: entryKey2 };
|
|
6692
|
+
}
|
|
6693
|
+
throw new GrokApiError("Grok auth has no access token. Run `grok login`.", "no_auth");
|
|
6694
|
+
}
|
|
6695
|
+
function needsRefresh(entry) {
|
|
6696
|
+
const exp = entry.expires_at;
|
|
6697
|
+
if (!exp) return false;
|
|
6698
|
+
const ms = Date.parse(exp);
|
|
6699
|
+
if (!Number.isFinite(ms)) return false;
|
|
6700
|
+
return Date.now() >= ms - REFRESH_BUFFER_MS;
|
|
6701
|
+
}
|
|
6702
|
+
async function refreshAccessToken(entry) {
|
|
6703
|
+
const refresh = entry.refresh_token?.trim();
|
|
6704
|
+
if (!refresh) return null;
|
|
6705
|
+
const clientId = entry.oidc_client_id?.trim() || DEFAULT_CLIENT_ID;
|
|
6706
|
+
const body = new URLSearchParams({
|
|
6707
|
+
grant_type: "refresh_token",
|
|
6708
|
+
client_id: clientId,
|
|
6709
|
+
refresh_token: refresh
|
|
6710
|
+
});
|
|
6711
|
+
let res;
|
|
6712
|
+
try {
|
|
6713
|
+
res = await fetch(REFRESH_URL, {
|
|
6714
|
+
method: "POST",
|
|
6715
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
6716
|
+
body: body.toString()
|
|
6717
|
+
});
|
|
6718
|
+
} catch {
|
|
6719
|
+
return null;
|
|
6720
|
+
}
|
|
6721
|
+
if (!res.ok) return null;
|
|
6722
|
+
try {
|
|
6723
|
+
const j = await res.json();
|
|
6724
|
+
if (typeof j.access_token !== "string" || !j.access_token) return null;
|
|
6725
|
+
try {
|
|
6726
|
+
const p = authPath();
|
|
6727
|
+
const raw = JSON.parse(readFileSync6(p, "utf8"));
|
|
6728
|
+
for (const key of Object.keys(raw)) {
|
|
6729
|
+
if (raw[key]?.key === entry.key || raw[key]?.refresh_token === refresh) {
|
|
6730
|
+
raw[key] = {
|
|
6731
|
+
...raw[key],
|
|
6732
|
+
key: j.access_token,
|
|
6733
|
+
refresh_token: j.refresh_token ?? raw[key].refresh_token,
|
|
6734
|
+
expires_at: typeof j.expires_in === "number" ? new Date(Date.now() + j.expires_in * 1e3).toISOString() : raw[key].expires_at
|
|
6735
|
+
};
|
|
6736
|
+
break;
|
|
6737
|
+
}
|
|
6738
|
+
}
|
|
6739
|
+
const { writeFileSync: writeFileSync15 } = await import("node:fs");
|
|
6740
|
+
writeFileSync15(p, JSON.stringify(raw, null, 2), "utf8");
|
|
6741
|
+
} catch {
|
|
6742
|
+
}
|
|
6743
|
+
return j.access_token;
|
|
6744
|
+
} catch {
|
|
6745
|
+
return null;
|
|
6746
|
+
}
|
|
6747
|
+
}
|
|
6748
|
+
function authHeaders(token) {
|
|
6749
|
+
return {
|
|
6750
|
+
Authorization: `Bearer ${token.trim()}`,
|
|
6751
|
+
"X-XAI-Token-Auth": TOKEN_AUTH,
|
|
6752
|
+
Accept: "application/json",
|
|
6753
|
+
"User-Agent": "fleetlens"
|
|
6754
|
+
};
|
|
6755
|
+
}
|
|
6756
|
+
function parseGrokCreditsConfig(body) {
|
|
6757
|
+
if (!body || typeof body !== "object") {
|
|
6758
|
+
throw new GrokApiError("Grok billing response missing body", "parse");
|
|
6759
|
+
}
|
|
6760
|
+
const config = body.config;
|
|
6761
|
+
if (!config || typeof config !== "object") {
|
|
6762
|
+
throw new GrokApiError("Grok billing response missing config", "parse");
|
|
6763
|
+
}
|
|
6764
|
+
const period = config.currentPeriod;
|
|
6765
|
+
if (!period || typeof period !== "object") {
|
|
6766
|
+
throw new GrokApiError("Grok billing response missing currentPeriod", "parse");
|
|
6767
|
+
}
|
|
6768
|
+
const periodType = typeof period.type === "string" ? period.type.trim() : "";
|
|
6769
|
+
if (!periodType) {
|
|
6770
|
+
throw new GrokApiError("Grok billing period type missing", "parse");
|
|
6771
|
+
}
|
|
6772
|
+
let utilization = 0;
|
|
6773
|
+
if (config.creditUsagePercent !== void 0 && config.creditUsagePercent !== null) {
|
|
6774
|
+
const n = Number(config.creditUsagePercent);
|
|
6775
|
+
if (!Number.isFinite(n)) {
|
|
6776
|
+
throw new GrokApiError("Grok creditUsagePercent is not a number", "parse");
|
|
6777
|
+
}
|
|
6778
|
+
utilization = Math.min(100, Math.max(0, n));
|
|
6779
|
+
}
|
|
6780
|
+
const end = typeof period.end === "string" && period.end ? new Date(period.end).toISOString() : null;
|
|
6781
|
+
let onDemandCap = 0;
|
|
6782
|
+
const cap = config.onDemandCap;
|
|
6783
|
+
if (cap && typeof cap === "object" && "val" in cap) {
|
|
6784
|
+
const v = Number(cap.val);
|
|
6785
|
+
if (Number.isFinite(v)) onDemandCap = v;
|
|
6786
|
+
}
|
|
6787
|
+
return {
|
|
6788
|
+
utilization,
|
|
6789
|
+
resets_at: end && !Number.isNaN(Date.parse(end)) ? end : null,
|
|
6790
|
+
period_type: periodType,
|
|
6791
|
+
on_demand_cap: onDemandCap
|
|
6792
|
+
};
|
|
6793
|
+
}
|
|
6794
|
+
async function fetchJson(url, token) {
|
|
6795
|
+
let res;
|
|
6796
|
+
try {
|
|
6797
|
+
res = await fetch(url, { headers: authHeaders(token) });
|
|
6798
|
+
} catch (err) {
|
|
6799
|
+
throw new GrokApiError(
|
|
6800
|
+
`Network error reaching Grok billing: ${err.message}`,
|
|
6801
|
+
"network"
|
|
6802
|
+
);
|
|
6803
|
+
}
|
|
6804
|
+
let body = null;
|
|
6805
|
+
try {
|
|
6806
|
+
body = await res.json();
|
|
6807
|
+
} catch {
|
|
6808
|
+
}
|
|
6809
|
+
return { status: res.status, body };
|
|
6810
|
+
}
|
|
6811
|
+
async function fetchGrokUsage() {
|
|
6812
|
+
const loaded = loadAuthEntry();
|
|
6813
|
+
const entry = loaded.entry;
|
|
6814
|
+
let token = loaded.token;
|
|
6815
|
+
if (needsRefresh(entry)) {
|
|
6816
|
+
const refreshed = await refreshAccessToken(entry);
|
|
6817
|
+
if (refreshed) token = refreshed;
|
|
6818
|
+
}
|
|
6819
|
+
let { status, body } = await fetchJson(CREDITS_URL, token);
|
|
6820
|
+
if (status === 401 || status === 403) {
|
|
6821
|
+
const refreshed = await refreshAccessToken(entry);
|
|
6822
|
+
if (refreshed) {
|
|
6823
|
+
token = refreshed;
|
|
6824
|
+
({ status, body } = await fetchJson(CREDITS_URL, token));
|
|
6825
|
+
}
|
|
6826
|
+
}
|
|
6827
|
+
if (status < 200 || status >= 300) {
|
|
6828
|
+
throw new GrokApiError(
|
|
6829
|
+
`Grok billing returned HTTP ${status}`,
|
|
6830
|
+
status === 401 || status === 403 ? "no_auth" : "http"
|
|
6831
|
+
);
|
|
6832
|
+
}
|
|
6833
|
+
const credits = parseGrokCreditsConfig(body);
|
|
6834
|
+
if (credits.period_type !== WEEKLY_PERIOD) {
|
|
6835
|
+
throw new GrokApiError(
|
|
6836
|
+
`Grok period is ${credits.period_type}, not weekly`,
|
|
6837
|
+
"not_weekly"
|
|
6838
|
+
);
|
|
6839
|
+
}
|
|
6840
|
+
let planType = null;
|
|
6841
|
+
try {
|
|
6842
|
+
const settings = await fetchJson(SETTINGS_URL, token);
|
|
6843
|
+
if (settings.status >= 200 && settings.status < 300 && settings.body && typeof settings.body === "object") {
|
|
6844
|
+
const tier = settings.body.subscription_tier_display;
|
|
6845
|
+
if (typeof tier === "string" && tier.trim()) planType = tier.trim();
|
|
6846
|
+
}
|
|
6847
|
+
} catch {
|
|
6848
|
+
}
|
|
6849
|
+
return {
|
|
6850
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6851
|
+
agent: "grok",
|
|
6852
|
+
// No 5-hour window — menubar / strip show "—" on the top line.
|
|
6853
|
+
five_hour: { utilization: null, resets_at: null },
|
|
6854
|
+
seven_day: {
|
|
6855
|
+
utilization: credits.utilization,
|
|
6856
|
+
resets_at: credits.resets_at
|
|
6857
|
+
},
|
|
6858
|
+
seven_day_opus: null,
|
|
6859
|
+
seven_day_sonnet: null,
|
|
6860
|
+
seven_day_oauth_apps: null,
|
|
6861
|
+
seven_day_cowork: null,
|
|
6862
|
+
extra_usage: null,
|
|
6863
|
+
plan_type: planType
|
|
6864
|
+
};
|
|
6865
|
+
}
|
|
6866
|
+
|
|
5835
6867
|
// src/daemon-worker.ts
|
|
5836
6868
|
init_storage();
|
|
5837
6869
|
init_fs();
|
|
@@ -5873,7 +6905,7 @@ import { randomUUID } from "node:crypto";
|
|
|
5873
6905
|
|
|
5874
6906
|
// ../entries/dist/fs.js
|
|
5875
6907
|
init_fs();
|
|
5876
|
-
import { readFileSync as
|
|
6908
|
+
import { readFileSync as readFileSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync7 } from "node:fs";
|
|
5877
6909
|
import { randomBytes } from "node:crypto";
|
|
5878
6910
|
import { join as join5 } from "node:path";
|
|
5879
6911
|
|
|
@@ -5948,12 +6980,12 @@ var PROMPT_FRAME_ORIGIN = {
|
|
|
5948
6980
|
|
|
5949
6981
|
// ../entries/dist/digest-fs.js
|
|
5950
6982
|
init_fs();
|
|
5951
|
-
import { readFileSync as
|
|
6983
|
+
import { readFileSync as readFileSync8, readdirSync, writeFileSync as writeFileSync4, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync6 } from "node:fs";
|
|
5952
6984
|
import { dirname as dirname3, join as join4 } from "node:path";
|
|
5953
6985
|
var digestsDirCached = null;
|
|
5954
|
-
function parseDigestFile(
|
|
6986
|
+
function parseDigestFile(path9, expectedVersion) {
|
|
5955
6987
|
try {
|
|
5956
|
-
const parsed = JSON.parse(
|
|
6988
|
+
const parsed = JSON.parse(readFileSync8(path9, "utf8"));
|
|
5957
6989
|
if (!parsed || typeof parsed !== "object")
|
|
5958
6990
|
return null;
|
|
5959
6991
|
if (parsed.version !== expectedVersion)
|
|
@@ -5993,7 +7025,7 @@ function writeDayDigest(digest) {
|
|
|
5993
7025
|
}
|
|
5994
7026
|
function readDayDigest(date) {
|
|
5995
7027
|
const p = dayDigestPath(date);
|
|
5996
|
-
if (!
|
|
7028
|
+
if (!existsSync6(p))
|
|
5997
7029
|
return null;
|
|
5998
7030
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
5999
7031
|
}
|
|
@@ -6026,7 +7058,7 @@ function writeWeekDigest(digest) {
|
|
|
6026
7058
|
}
|
|
6027
7059
|
function readWeekDigest(monday) {
|
|
6028
7060
|
const p = weekDigestPath(monday);
|
|
6029
|
-
if (!
|
|
7061
|
+
if (!existsSync6(p))
|
|
6030
7062
|
return null;
|
|
6031
7063
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
6032
7064
|
}
|
|
@@ -6104,17 +7136,17 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
6104
7136
|
}
|
|
6105
7137
|
function readEntry(sessionId, localDay2) {
|
|
6106
7138
|
const p = pathFor(sessionId, localDay2);
|
|
6107
|
-
if (!
|
|
7139
|
+
if (!existsSync7(p))
|
|
6108
7140
|
return null;
|
|
6109
|
-
const raw =
|
|
7141
|
+
const raw = readFileSync9(p, "utf8");
|
|
6110
7142
|
return JSON.parse(raw);
|
|
6111
7143
|
}
|
|
6112
7144
|
function entryExists(sessionId, localDay2) {
|
|
6113
|
-
return
|
|
7145
|
+
return existsSync7(pathFor(sessionId, localDay2));
|
|
6114
7146
|
}
|
|
6115
7147
|
function listEntryKeys() {
|
|
6116
7148
|
const dir = entriesDir();
|
|
6117
|
-
if (!
|
|
7149
|
+
if (!existsSync7(dir))
|
|
6118
7150
|
return [];
|
|
6119
7151
|
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
6120
7152
|
}
|
|
@@ -6133,7 +7165,7 @@ function listEntriesForDay(localDay2) {
|
|
|
6133
7165
|
|
|
6134
7166
|
// src/perception/build-entries.ts
|
|
6135
7167
|
init_dist();
|
|
6136
|
-
import { statSync as statSync2, readFileSync as
|
|
7168
|
+
import { statSync as statSync2, readFileSync as readFileSync10 } from "node:fs";
|
|
6137
7169
|
import { basename as basename2, dirname as dirname4 } from "node:path";
|
|
6138
7170
|
|
|
6139
7171
|
// ../entries/dist/signals.js
|
|
@@ -6367,7 +7399,7 @@ function viewEvent(ev) {
|
|
|
6367
7399
|
cwd: rawCwd
|
|
6368
7400
|
};
|
|
6369
7401
|
}
|
|
6370
|
-
var
|
|
7402
|
+
var IDLE_GAP_MS5 = 3 * 60 * 1e3;
|
|
6371
7403
|
var INTERRUPT_RE2 = /\[request interrupted|interrupted by user/i;
|
|
6372
7404
|
var PR_TITLE_RE = /--title\s+["']([^"']+)["']/;
|
|
6373
7405
|
var BASH_CHAIN_SPLIT_RE = /\|\||&&|;|\|/;
|
|
@@ -6479,7 +7511,7 @@ function closeTurn(t, closed, cwd) {
|
|
|
6479
7511
|
let active = 0;
|
|
6480
7512
|
for (let i = 1; i < ts.length; i++) {
|
|
6481
7513
|
const dt = ts[i] - ts[i - 1];
|
|
6482
|
-
if (dt <
|
|
7514
|
+
if (dt < IDLE_GAP_MS5)
|
|
6483
7515
|
active += dt;
|
|
6484
7516
|
}
|
|
6485
7517
|
closed.push({
|
|
@@ -6676,7 +7708,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
|
|
|
6676
7708
|
let activeMs2 = 0;
|
|
6677
7709
|
for (let i = 1; i < tsSorted.length; i++) {
|
|
6678
7710
|
const dt = tsSorted[i] - tsSorted[i - 1];
|
|
6679
|
-
if (dt <
|
|
7711
|
+
if (dt < IDLE_GAP_MS5)
|
|
6680
7712
|
activeMs2 += dt;
|
|
6681
7713
|
}
|
|
6682
7714
|
const tsSortedStrings = dayEvents.map((e) => e.timestamp).filter((t) => !!t).sort();
|
|
@@ -6873,7 +7905,7 @@ function decodeProjectDirName(projectDir) {
|
|
|
6873
7905
|
}
|
|
6874
7906
|
function buildEntriesForFile(filePath) {
|
|
6875
7907
|
const stat = statSync2(filePath);
|
|
6876
|
-
const raw =
|
|
7908
|
+
const raw = readFileSync10(filePath, "utf8");
|
|
6877
7909
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
6878
7910
|
try {
|
|
6879
7911
|
return JSON.parse(l);
|
|
@@ -7134,7 +8166,7 @@ function buildIngestPayload(inputs) {
|
|
|
7134
8166
|
return {
|
|
7135
8167
|
ingestId: randomUUID(),
|
|
7136
8168
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7137
|
-
cliVersion: "0.16.
|
|
8169
|
+
cliVersion: "0.16.2",
|
|
7138
8170
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
7139
8171
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
7140
8172
|
...richRollup ? { richRollup } : {},
|
|
@@ -7161,7 +8193,7 @@ async function pushToTeamServer(config, payload) {
|
|
|
7161
8193
|
}
|
|
7162
8194
|
|
|
7163
8195
|
// src/team/git-remote.ts
|
|
7164
|
-
import { existsSync as
|
|
8196
|
+
import { existsSync as existsSync8, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
|
|
7165
8197
|
import { dirname as dirname5, isAbsolute as isAbsolute2, join as join6, resolve as resolve2 } from "node:path";
|
|
7166
8198
|
var GITHUB_URL_RE = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/;
|
|
7167
8199
|
function parseGithubRemote(url) {
|
|
@@ -7187,12 +8219,12 @@ function gitConfigPathFor(dir) {
|
|
|
7187
8219
|
const st = statSync3(dotGit, { throwIfNoEntry: false });
|
|
7188
8220
|
if (!st) return null;
|
|
7189
8221
|
if (st.isDirectory()) return join6(dotGit, "config");
|
|
7190
|
-
const m =
|
|
8222
|
+
const m = readFileSync11(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
7191
8223
|
if (!m) return null;
|
|
7192
8224
|
const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
|
|
7193
8225
|
const commondirFile = join6(gd, "commondir");
|
|
7194
|
-
if (
|
|
7195
|
-
const common =
|
|
8226
|
+
if (existsSync8(commondirFile)) {
|
|
8227
|
+
const common = readFileSync11(commondirFile, "utf8").trim();
|
|
7196
8228
|
return join6(isAbsolute2(common) ? common : resolve2(gd, common), "config");
|
|
7197
8229
|
}
|
|
7198
8230
|
return join6(gd, "config");
|
|
@@ -7207,8 +8239,8 @@ function createRepoResolver() {
|
|
|
7207
8239
|
try {
|
|
7208
8240
|
for (let d = dir; ; d = dirname5(d)) {
|
|
7209
8241
|
const config = gitConfigPathFor(d);
|
|
7210
|
-
if (config &&
|
|
7211
|
-
const url = originUrl2(
|
|
8242
|
+
if (config && existsSync8(config)) {
|
|
8243
|
+
const url = originUrl2(readFileSync11(config, "utf8"));
|
|
7212
8244
|
repo = url ? parseGithubRemote(url) : null;
|
|
7213
8245
|
break;
|
|
7214
8246
|
}
|
|
@@ -7224,7 +8256,7 @@ function createRepoResolver() {
|
|
|
7224
8256
|
|
|
7225
8257
|
// src/team/queue.ts
|
|
7226
8258
|
init_fs();
|
|
7227
|
-
import { readFileSync as
|
|
8259
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, appendFileSync as appendFileSync4, statSync as statSync4, mkdirSync as mkdirSync6 } from "node:fs";
|
|
7228
8260
|
import { dirname as dirname6 } from "node:path";
|
|
7229
8261
|
var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
|
|
7230
8262
|
var MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -7244,7 +8276,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
7244
8276
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
7245
8277
|
let lines;
|
|
7246
8278
|
try {
|
|
7247
|
-
lines =
|
|
8279
|
+
lines = readFileSync12(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
7248
8280
|
} catch {
|
|
7249
8281
|
return [];
|
|
7250
8282
|
}
|
|
@@ -7265,7 +8297,7 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
7265
8297
|
function pruneOldest(queuePath) {
|
|
7266
8298
|
let lines;
|
|
7267
8299
|
try {
|
|
7268
|
-
lines =
|
|
8300
|
+
lines = readFileSync12(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
7269
8301
|
} catch {
|
|
7270
8302
|
return;
|
|
7271
8303
|
}
|
|
@@ -7278,7 +8310,7 @@ init_storage();
|
|
|
7278
8310
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
7279
8311
|
|
|
7280
8312
|
// src/usage/profile.ts
|
|
7281
|
-
import { existsSync as
|
|
8313
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "node:fs";
|
|
7282
8314
|
import { dirname as dirname7 } from "node:path";
|
|
7283
8315
|
var PROFILE_ENDPOINT = "https://api.anthropic.com/api/oauth/profile";
|
|
7284
8316
|
var BETA_HEADER2 = "oauth-2025-04-20";
|
|
@@ -7322,9 +8354,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
7322
8354
|
};
|
|
7323
8355
|
}
|
|
7324
8356
|
function readCachedProfile(cachePath) {
|
|
7325
|
-
if (!
|
|
8357
|
+
if (!existsSync9(cachePath)) return null;
|
|
7326
8358
|
try {
|
|
7327
|
-
const raw = JSON.parse(
|
|
8359
|
+
const raw = JSON.parse(readFileSync13(cachePath, "utf8"));
|
|
7328
8360
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
7329
8361
|
return raw;
|
|
7330
8362
|
} catch {
|
|
@@ -7493,13 +8525,13 @@ async function runTeamBackfill(log3 = noopLog, filePath = USAGE_LOG, configOverr
|
|
|
7493
8525
|
|
|
7494
8526
|
// src/team/sync-log.ts
|
|
7495
8527
|
init_fs();
|
|
7496
|
-
import { readFileSync as
|
|
8528
|
+
import { readFileSync as readFileSync14 } from "node:fs";
|
|
7497
8529
|
var MAX_LINES = 300;
|
|
7498
8530
|
var MAX_MSG_CHARS = 1900;
|
|
7499
8531
|
function readPendingSyncLog(watermark) {
|
|
7500
8532
|
let raw;
|
|
7501
8533
|
try {
|
|
7502
|
-
raw =
|
|
8534
|
+
raw = readFileSync14(cclensPath("daemon.log"), "utf8");
|
|
7503
8535
|
} catch {
|
|
7504
8536
|
return { lines: [] };
|
|
7505
8537
|
}
|
|
@@ -8125,7 +9157,7 @@ init_fs();
|
|
|
8125
9157
|
|
|
8126
9158
|
// src/perception/state.ts
|
|
8127
9159
|
init_fs();
|
|
8128
|
-
import { existsSync as
|
|
9160
|
+
import { existsSync as existsSync11, readFileSync as readFileSync15, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
|
|
8129
9161
|
import { dirname as dirname9 } from "node:path";
|
|
8130
9162
|
var STALE_MS = 15 * 60 * 1e3;
|
|
8131
9163
|
var pathCached = null;
|
|
@@ -8136,7 +9168,7 @@ function statePath() {
|
|
|
8136
9168
|
}
|
|
8137
9169
|
function readState() {
|
|
8138
9170
|
const p = statePath();
|
|
8139
|
-
if (!
|
|
9171
|
+
if (!existsSync11(p)) {
|
|
8140
9172
|
return {
|
|
8141
9173
|
sweep_in_progress: false,
|
|
8142
9174
|
last_sweep_started_at: null,
|
|
@@ -8144,7 +9176,7 @@ function readState() {
|
|
|
8144
9176
|
file_checkpoints: {}
|
|
8145
9177
|
};
|
|
8146
9178
|
}
|
|
8147
|
-
const raw =
|
|
9179
|
+
const raw = readFileSync15(p, "utf8");
|
|
8148
9180
|
return JSON.parse(raw);
|
|
8149
9181
|
}
|
|
8150
9182
|
function writeState(s) {
|
|
@@ -8752,8 +9784,8 @@ function getErrorMap() {
|
|
|
8752
9784
|
|
|
8753
9785
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
8754
9786
|
var makeIssue = (params) => {
|
|
8755
|
-
const { data, path:
|
|
8756
|
-
const fullPath = [...
|
|
9787
|
+
const { data, path: path9, errorMaps, issueData } = params;
|
|
9788
|
+
const fullPath = [...path9, ...issueData.path || []];
|
|
8757
9789
|
const fullIssue = {
|
|
8758
9790
|
...issueData,
|
|
8759
9791
|
path: fullPath
|
|
@@ -8869,11 +9901,11 @@ var errorUtil;
|
|
|
8869
9901
|
|
|
8870
9902
|
// ../../node_modules/zod/v3/types.js
|
|
8871
9903
|
var ParseInputLazyPath = class {
|
|
8872
|
-
constructor(parent, value,
|
|
9904
|
+
constructor(parent, value, path9, key) {
|
|
8873
9905
|
this._cachedPath = [];
|
|
8874
9906
|
this.parent = parent;
|
|
8875
9907
|
this.data = value;
|
|
8876
|
-
this._path =
|
|
9908
|
+
this._path = path9;
|
|
8877
9909
|
this._key = key;
|
|
8878
9910
|
}
|
|
8879
9911
|
get path() {
|
|
@@ -12407,12 +13439,12 @@ var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
|
|
|
12407
13439
|
// ../entries/dist/llm-runner.js
|
|
12408
13440
|
init_fs();
|
|
12409
13441
|
import { spawn } from "node:child_process";
|
|
12410
|
-
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync11, existsSync as
|
|
13442
|
+
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync11, existsSync as existsSync13 } from "node:fs";
|
|
12411
13443
|
import { join as join11 } from "node:path";
|
|
12412
13444
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
12413
13445
|
|
|
12414
13446
|
// ../entries/dist/tmux-runner.js
|
|
12415
|
-
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10, existsSync as
|
|
13447
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10, existsSync as existsSync12, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync16, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
|
|
12416
13448
|
import { join as join10 } from "node:path";
|
|
12417
13449
|
import { homedir as homedir5 } from "node:os";
|
|
12418
13450
|
import { spawnSync } from "node:child_process";
|
|
@@ -12443,7 +13475,7 @@ function tmuxRunnerAvailable() {
|
|
|
12443
13475
|
}
|
|
12444
13476
|
function runtimeCwd() {
|
|
12445
13477
|
const dir = join10(homedir5(), ".cclens", "runtime");
|
|
12446
|
-
if (!
|
|
13478
|
+
if (!existsSync12(dir))
|
|
12447
13479
|
mkdirSync10(dir, { recursive: true });
|
|
12448
13480
|
return realpathSync2(dir);
|
|
12449
13481
|
}
|
|
@@ -12451,7 +13483,7 @@ function ensureRuntimeCwdTrusted(cwd) {
|
|
|
12451
13483
|
const cfgPath = join10(homedir5(), ".claude.json");
|
|
12452
13484
|
let cfg;
|
|
12453
13485
|
try {
|
|
12454
|
-
cfg = JSON.parse(
|
|
13486
|
+
cfg = JSON.parse(readFileSync16(cfgPath, "utf8"));
|
|
12455
13487
|
} catch {
|
|
12456
13488
|
return;
|
|
12457
13489
|
}
|
|
@@ -12600,10 +13632,10 @@ function snapshotAllTranscripts() {
|
|
|
12600
13632
|
}
|
|
12601
13633
|
return out;
|
|
12602
13634
|
}
|
|
12603
|
-
function readJsonlCwd(
|
|
13635
|
+
function readJsonlCwd(path9, maxLines = 8) {
|
|
12604
13636
|
let raw;
|
|
12605
13637
|
try {
|
|
12606
|
-
raw =
|
|
13638
|
+
raw = readFileSync16(path9, "utf8");
|
|
12607
13639
|
} catch {
|
|
12608
13640
|
return void 0;
|
|
12609
13641
|
}
|
|
@@ -12657,10 +13689,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12657
13689
|
}
|
|
12658
13690
|
throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
|
|
12659
13691
|
}
|
|
12660
|
-
function parseTranscript2(
|
|
13692
|
+
function parseTranscript2(path9, defaultModel) {
|
|
12661
13693
|
let raw;
|
|
12662
13694
|
try {
|
|
12663
|
-
raw =
|
|
13695
|
+
raw = readFileSync16(path9, "utf8");
|
|
12664
13696
|
} catch {
|
|
12665
13697
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
12666
13698
|
}
|
|
@@ -12735,7 +13767,7 @@ function shellEscape(s) {
|
|
|
12735
13767
|
// ../entries/dist/llm-runner.js
|
|
12736
13768
|
var RUNS_DIR = cclensPath("llm-runs");
|
|
12737
13769
|
function ensureRunsDir() {
|
|
12738
|
-
if (!
|
|
13770
|
+
if (!existsSync13(RUNS_DIR)) {
|
|
12739
13771
|
try {
|
|
12740
13772
|
mkdirSync11(RUNS_DIR, { recursive: true });
|
|
12741
13773
|
} catch {
|
|
@@ -12766,15 +13798,15 @@ function newRunId(kind) {
|
|
|
12766
13798
|
function tracePath(runId) {
|
|
12767
13799
|
return join11(RUNS_DIR, `${runId}.jsonl`);
|
|
12768
13800
|
}
|
|
12769
|
-
function safeAppend(
|
|
13801
|
+
function safeAppend(path9, line) {
|
|
12770
13802
|
try {
|
|
12771
|
-
appendFileSync5(
|
|
13803
|
+
appendFileSync5(path9, line);
|
|
12772
13804
|
} catch {
|
|
12773
13805
|
}
|
|
12774
13806
|
}
|
|
12775
|
-
function safeWrite(
|
|
13807
|
+
function safeWrite(path9, line) {
|
|
12776
13808
|
try {
|
|
12777
|
-
writeFileSync11(
|
|
13809
|
+
writeFileSync11(path9, line);
|
|
12778
13810
|
} catch {
|
|
12779
13811
|
}
|
|
12780
13812
|
}
|
|
@@ -13163,7 +14195,7 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
|
|
|
13163
14195
|
|
|
13164
14196
|
// ../entries/dist/budget.js
|
|
13165
14197
|
init_fs();
|
|
13166
|
-
import { appendFileSync as appendFileSync6, readFileSync as
|
|
14198
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync17, existsSync as existsSync14, mkdirSync as mkdirSync12 } from "node:fs";
|
|
13167
14199
|
import { dirname as dirname10 } from "node:path";
|
|
13168
14200
|
var spendPathCached = null;
|
|
13169
14201
|
function spendPath() {
|
|
@@ -13179,12 +14211,12 @@ function appendSpend(record) {
|
|
|
13179
14211
|
}
|
|
13180
14212
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
13181
14213
|
const p = spendPath();
|
|
13182
|
-
if (!
|
|
14214
|
+
if (!existsSync14(p))
|
|
13183
14215
|
return 0;
|
|
13184
14216
|
const year = now.getUTCFullYear();
|
|
13185
14217
|
const month = now.getUTCMonth();
|
|
13186
14218
|
let total = 0;
|
|
13187
|
-
const raw =
|
|
14219
|
+
const raw = readFileSync17(p, "utf8");
|
|
13188
14220
|
for (const line of raw.split("\n")) {
|
|
13189
14221
|
if (!line)
|
|
13190
14222
|
continue;
|
|
@@ -13206,7 +14238,7 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
|
13206
14238
|
|
|
13207
14239
|
// ../entries/dist/pipeline-lock.js
|
|
13208
14240
|
init_fs();
|
|
13209
|
-
import { writeFileSync as writeFileSync12, unlinkSync as unlinkSync4, existsSync as
|
|
14241
|
+
import { writeFileSync as writeFileSync12, unlinkSync as unlinkSync4, existsSync as existsSync15, readFileSync as readFileSync18, statSync as statSync7 } from "node:fs";
|
|
13210
14242
|
var STALE_MS2 = 60 * 1e3;
|
|
13211
14243
|
var HEARTBEAT_MS = 30 * 1e3;
|
|
13212
14244
|
var lockPathCached = null;
|
|
@@ -13252,13 +14284,13 @@ function pidAlive(pid) {
|
|
|
13252
14284
|
}
|
|
13253
14285
|
function interactiveLockFresh(nowMs) {
|
|
13254
14286
|
const p = lockPath();
|
|
13255
|
-
if (!
|
|
14287
|
+
if (!existsSync15(p))
|
|
13256
14288
|
return false;
|
|
13257
14289
|
try {
|
|
13258
14290
|
const mtime = statSync7(p).mtimeMs;
|
|
13259
14291
|
if (nowMs - mtime > STALE_MS2)
|
|
13260
14292
|
return false;
|
|
13261
|
-
const pid = Number(
|
|
14293
|
+
const pid = Number(readFileSync18(p, "utf8").trim());
|
|
13262
14294
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
13263
14295
|
return false;
|
|
13264
14296
|
if (!pidAlive(pid))
|
|
@@ -13273,7 +14305,7 @@ function interactiveLockFresh(nowMs) {
|
|
|
13273
14305
|
var THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
13274
14306
|
|
|
13275
14307
|
// ../entries/dist/settings.js
|
|
13276
|
-
import { readFileSync as
|
|
14308
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync13, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync16 } from "node:fs";
|
|
13277
14309
|
init_fs();
|
|
13278
14310
|
var DEFAULT_SETTINGS = {
|
|
13279
14311
|
ai_features: {
|
|
@@ -13305,10 +14337,10 @@ function fromDisk(d) {
|
|
|
13305
14337
|
}
|
|
13306
14338
|
function readSettings() {
|
|
13307
14339
|
const p = settingsPath();
|
|
13308
|
-
if (!
|
|
14340
|
+
if (!existsSync16(p))
|
|
13309
14341
|
return DEFAULT_SETTINGS;
|
|
13310
14342
|
try {
|
|
13311
|
-
const raw =
|
|
14343
|
+
const raw = readFileSync19(p, "utf8");
|
|
13312
14344
|
return fromDisk(JSON.parse(raw));
|
|
13313
14345
|
} catch {
|
|
13314
14346
|
return DEFAULT_SETTINGS;
|
|
@@ -13481,7 +14513,7 @@ function rollupOutcomeDay(entries) {
|
|
|
13481
14513
|
return "exploratory";
|
|
13482
14514
|
return "trivial";
|
|
13483
14515
|
}
|
|
13484
|
-
function
|
|
14516
|
+
function truncate6(s, max) {
|
|
13485
14517
|
if (s.length <= max)
|
|
13486
14518
|
return s;
|
|
13487
14519
|
return s.slice(0, max - 1).trimEnd() + "\u2026";
|
|
@@ -13537,7 +14569,7 @@ function computeDaySignals(entries) {
|
|
|
13537
14569
|
type,
|
|
13538
14570
|
count: v.count,
|
|
13539
14571
|
sample_description: v.sample_description,
|
|
13540
|
-
sample_prompt_preview:
|
|
14572
|
+
sample_prompt_preview: truncate6(v.sample_prompt_preview, 200)
|
|
13541
14573
|
}));
|
|
13542
14574
|
const frameCounts = /* @__PURE__ */ new Map();
|
|
13543
14575
|
for (const s of signalsList) {
|
|
@@ -13556,7 +14588,7 @@ function computeDaySignals(entries) {
|
|
|
13556
14588
|
if ((e.first_user ?? "").length > 0)
|
|
13557
14589
|
verbosity_distribution[s.verbosity] += 1;
|
|
13558
14590
|
for (const ref of s.external_refs) {
|
|
13559
|
-
external_refs.push({ session_id: e.session_id, kind: ref.kind, preview:
|
|
14591
|
+
external_refs.push({ session_id: e.session_id, kind: ref.kind, preview: truncate6(ref.preview, 200) });
|
|
13560
14592
|
}
|
|
13561
14593
|
const ints = e.numbers.interrupts ?? 0;
|
|
13562
14594
|
interrupts += ints;
|
|
@@ -14399,7 +15431,7 @@ function computeInteractionModes(entries) {
|
|
|
14399
15431
|
date: entry.local_day,
|
|
14400
15432
|
project_display: prettyProject3(entry.project),
|
|
14401
15433
|
type: sa.type,
|
|
14402
|
-
prompt_preview:
|
|
15434
|
+
prompt_preview: truncate7(sa.prompt_preview, 200)
|
|
14403
15435
|
});
|
|
14404
15436
|
}
|
|
14405
15437
|
const skillExamples = [];
|
|
@@ -14416,7 +15448,7 @@ function computeInteractionModes(entries) {
|
|
|
14416
15448
|
skillExamples.push({
|
|
14417
15449
|
date: e.local_day,
|
|
14418
15450
|
skill,
|
|
14419
|
-
first_user_preview:
|
|
15451
|
+
first_user_preview: truncate7(e.first_user, 200)
|
|
14420
15452
|
});
|
|
14421
15453
|
}
|
|
14422
15454
|
}
|
|
@@ -14433,7 +15465,7 @@ function computeInteractionModes(entries) {
|
|
|
14433
15465
|
project_display: prettyProject3(longestTurnEntry.project),
|
|
14434
15466
|
active_min: longestTurnEntry.numbers.active_min,
|
|
14435
15467
|
top_tools: longestTurnEntry.top_tools.slice(0, 5),
|
|
14436
|
-
first_user_preview:
|
|
15468
|
+
first_user_preview: truncate7(longestTurnEntry.first_user, 200)
|
|
14437
15469
|
} : null;
|
|
14438
15470
|
const tools_per_turn = turn_count > 0 ? tools_total / turn_count : 0;
|
|
14439
15471
|
const label = tools_per_turn < 5 ? "rapid" : tools_per_turn < 15 ? "mixed" : "batch";
|
|
@@ -14464,7 +15496,7 @@ function computeInteractionModes(entries) {
|
|
|
14464
15496
|
}
|
|
14465
15497
|
};
|
|
14466
15498
|
}
|
|
14467
|
-
function
|
|
15499
|
+
function truncate7(s, max) {
|
|
14468
15500
|
if (s.length <= max)
|
|
14469
15501
|
return s;
|
|
14470
15502
|
return s.slice(0, max - 1).trimEnd() + "\u2026";
|
|
@@ -14521,7 +15553,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
|
|
|
14521
15553
|
evidence_subagent = {
|
|
14522
15554
|
type: sa.type,
|
|
14523
15555
|
description: sa.description,
|
|
14524
|
-
prompt_preview:
|
|
15556
|
+
prompt_preview: truncate7(sa.prompt_preview, 200)
|
|
14525
15557
|
};
|
|
14526
15558
|
}
|
|
14527
15559
|
const project_display = repEntry ? prettyProject3(repEntry.project) : dd.projects[0]?.display_name ?? "";
|
|
@@ -14532,7 +15564,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
|
|
|
14532
15564
|
outcome: dayOutcome.get(dd.key) ?? null,
|
|
14533
15565
|
helpfulness: dayHelp.get(dd.key) ?? null,
|
|
14534
15566
|
evidence_subagent,
|
|
14535
|
-
evidence_first_user: repEntry?.first_user ?
|
|
15567
|
+
evidence_first_user: repEntry?.first_user ? truncate7(repEntry.first_user, 200) : null,
|
|
14536
15568
|
day_signature: dd.day_signature ?? null
|
|
14537
15569
|
};
|
|
14538
15570
|
});
|
|
@@ -14607,7 +15639,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
|
|
|
14607
15639
|
date: day,
|
|
14608
15640
|
session_id: ref.session_id,
|
|
14609
15641
|
ref_kind: ref.kind,
|
|
14610
|
-
preview:
|
|
15642
|
+
preview: truncate7(ref.preview, 200)
|
|
14611
15643
|
});
|
|
14612
15644
|
}
|
|
14613
15645
|
total_interrupts += signals.comm_style.steering.interrupts;
|
|
@@ -14679,7 +15711,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
|
|
|
14679
15711
|
count: v.count,
|
|
14680
15712
|
days: [...v.days].sort(),
|
|
14681
15713
|
sample_description: v.sample_description,
|
|
14682
|
-
sample_prompt_preview:
|
|
15714
|
+
sample_prompt_preview: truncate7(v.sample_prompt_preview, 200)
|
|
14683
15715
|
})),
|
|
14684
15716
|
threads,
|
|
14685
15717
|
communication_style: {
|
|
@@ -14979,7 +16011,7 @@ var MonthDigestResponseSchema = external_exports.object({
|
|
|
14979
16011
|
}).passthrough();
|
|
14980
16012
|
|
|
14981
16013
|
// ../entries/dist/top-sessions.js
|
|
14982
|
-
var
|
|
16014
|
+
var IDLE_GAP_MS6 = 3 * 60 * 1e3;
|
|
14983
16015
|
var LONG_AUTONOMOUS_MIN = 20;
|
|
14984
16016
|
var N_USER = 150;
|
|
14985
16017
|
var N_FIRST_AGENT = 150;
|
|
@@ -15010,7 +16042,7 @@ function activeMs(timestamps) {
|
|
|
15010
16042
|
let active = 0;
|
|
15011
16043
|
for (let i = 1; i < ts.length; i++) {
|
|
15012
16044
|
const dt = ts[i] - ts[i - 1];
|
|
15013
|
-
if (dt <
|
|
16045
|
+
if (dt < IDLE_GAP_MS6)
|
|
15014
16046
|
active += dt;
|
|
15015
16047
|
}
|
|
15016
16048
|
return active;
|
|
@@ -15184,7 +16216,7 @@ function buildSessionSlice(entry, events, daySignature) {
|
|
|
15184
16216
|
let intEnd = sortedTs[0];
|
|
15185
16217
|
for (let i = 1; i < sortedTs.length; i++) {
|
|
15186
16218
|
const dt = sortedTs[i] - intEnd;
|
|
15187
|
-
if (dt >=
|
|
16219
|
+
if (dt >= IDLE_GAP_MS6) {
|
|
15188
16220
|
intervals.push({
|
|
15189
16221
|
start_min: fmtMin(intStart - sliceStartMs),
|
|
15190
16222
|
end_min: fmtMin(intEnd - sliceStartMs)
|
|
@@ -16068,14 +17100,14 @@ async function getUpdateAvailability() {
|
|
|
16068
17100
|
if (isDevMode()) return null;
|
|
16069
17101
|
const latest = await fetchLatestVersion();
|
|
16070
17102
|
if (latest === null) return {
|
|
16071
|
-
current: "0.16.
|
|
17103
|
+
current: "0.16.2",
|
|
16072
17104
|
latest: null,
|
|
16073
17105
|
updateAvailable: false
|
|
16074
17106
|
};
|
|
16075
17107
|
return {
|
|
16076
|
-
current: "0.16.
|
|
17108
|
+
current: "0.16.2",
|
|
16077
17109
|
latest,
|
|
16078
|
-
updateAvailable: shouldUpdate("0.16.
|
|
17110
|
+
updateAvailable: shouldUpdate("0.16.2", latest)
|
|
16079
17111
|
};
|
|
16080
17112
|
}
|
|
16081
17113
|
|
|
@@ -16123,7 +17155,7 @@ var perceptionHandle = setInterval(async () => {
|
|
|
16123
17155
|
}, PERCEPTION_INTERVAL_MS);
|
|
16124
17156
|
function readUpdateState() {
|
|
16125
17157
|
try {
|
|
16126
|
-
return JSON.parse(
|
|
17158
|
+
return JSON.parse(readFileSync20(UPDATE_STATE, "utf8"));
|
|
16127
17159
|
} catch {
|
|
16128
17160
|
return null;
|
|
16129
17161
|
}
|
|
@@ -16175,7 +17207,7 @@ async function runDaemonUpdateCheck() {
|
|
|
16175
17207
|
return;
|
|
16176
17208
|
}
|
|
16177
17209
|
const entry = cliEntryPath();
|
|
16178
|
-
if (!
|
|
17210
|
+
if (!existsSync17(entry)) {
|
|
16179
17211
|
log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
|
|
16180
17212
|
return;
|
|
16181
17213
|
}
|
|
@@ -16252,6 +17284,24 @@ async function tick() {
|
|
|
16252
17284
|
log2("warn", `zai poll failed: ${err.message}`);
|
|
16253
17285
|
}
|
|
16254
17286
|
}
|
|
17287
|
+
try {
|
|
17288
|
+
const grokSnapshot = await fetchGrokUsage();
|
|
17289
|
+
appendSnapshot(USAGE_LOG3, grokSnapshot);
|
|
17290
|
+
log2(
|
|
17291
|
+
"info",
|
|
17292
|
+
`grok snapshot 5h=\u2014 7d=${grokSnapshot.seven_day.utilization}%`
|
|
17293
|
+
);
|
|
17294
|
+
} catch (err) {
|
|
17295
|
+
if (err instanceof GrokApiError && (err.code === "no_auth" || err.code === "not_weekly")) {
|
|
17296
|
+
pruneAgent(USAGE_LOG3, "grok");
|
|
17297
|
+
if (err.code === "no_auth") {
|
|
17298
|
+
} else {
|
|
17299
|
+
log2("warn", `grok poll skipped: ${err.message}`);
|
|
17300
|
+
}
|
|
17301
|
+
} else {
|
|
17302
|
+
log2("warn", `grok poll failed: ${err.message}`);
|
|
17303
|
+
}
|
|
17304
|
+
}
|
|
16255
17305
|
try {
|
|
16256
17306
|
const snapshot = await fetchUsage();
|
|
16257
17307
|
appendSnapshot(USAGE_LOG3, snapshot);
|