fleetlens 0.10.0 → 0.10.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 +2 -2
- package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js +4 -3
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +3 -4
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +3 -4
- 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 +3 -3
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +3 -4
- 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 +3 -3
- 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 +2 -3
- 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 +1 -1
- package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js +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 +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 +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/route.js +3 -4
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js +2 -2
- 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/[externals]__09v47rg._.js +3 -0
- package/app/apps/web/.next/server/chunks/[externals]__0o43ejh._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__00n3f9y._.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__02px2mk._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__02zukjw._.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0455vu3._.js +5 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__067~im1._.js +2 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__06b4cj-._.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__08agijy._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_8zh-i._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ej_p3s._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i06ito._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0jprdks._.js +9 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0vm_41a._.js +3 -0
- package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js +4 -4
- package/app/apps/web/.next/server/chunks/packages_0c-sz9n._.js +3 -0
- package/app/apps/web/.next/server/chunks/packages_0wywuu.._.js +3 -0
- package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +27 -13
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0s4dg1y._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0tejjy_._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0yv0m0q._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0m67-xi._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_12.endt._.js +3 -0
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/063r4x2.9csh8.js +14 -0
- package/app/apps/web/.next/static/chunks/{09--oejbzw3q-.js → 0rtba0saz74e1.js} +2 -2
- package/app/apps/web/app/api/ask/route.ts +124 -111
- package/app/apps/web/app/api/events/route.ts +3 -4
- package/app/apps/web/app/api/runs/[runId]/route.ts +2 -2
- package/app/apps/web/app/api/runs/[runId]/stream/route.ts +3 -2
- package/app/apps/web/app/api/runs/route.ts +8 -4
- package/app/apps/web/app/sessions/[id]/session-view.tsx +164 -49
- package/app/apps/web/components/job-queue-widget.tsx +11 -8
- package/app/apps/web/lib/calibration-data.ts +2 -4
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/entries-index.ts +2 -2
- package/app/apps/web/lib/jobs.ts +3 -5
- package/app/apps/web/lib/usage-data.ts +3 -4
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +481 -81
- package/dist/index.js +4373 -3961
- package/package.json +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__07qxzx4._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0fu2xfy._.js +0 -5
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0gfd42k._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i.m8y0._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0iy5aqy._.js +0 -9
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh7-nf._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nvdffv._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0op9af~._.js +0 -3
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s2~c3g._.js +0 -3
- package/app/apps/web/.next/server/chunks/packages_09wmnv.._.js +0 -3
- package/app/apps/web/.next/server/chunks/packages_0o6.gpk._.js +0 -3
- package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_122oe0-.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0sp6.jt._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_10_oegc._.js +0 -3
- package/app/apps/web/.next/static/chunks/0qcu452dr~edz.js +0 -14
- /package/app/apps/web/.next/static/{L0Dy1hOQrZjV9l0TNulvk → XTns3Y6jHWmb7EYKzQi55}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{L0Dy1hOQrZjV9l0TNulvk → XTns3Y6jHWmb7EYKzQi55}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{L0Dy1hOQrZjV9l0TNulvk → XTns3Y6jHWmb7EYKzQi55}/_ssgManifest.js +0 -0
package/dist/daemon-worker.js
CHANGED
|
@@ -1152,6 +1152,7 @@ function parseTranscript(rawLines) {
|
|
|
1152
1152
|
let sessionId = "";
|
|
1153
1153
|
let cwd;
|
|
1154
1154
|
let gitBranch;
|
|
1155
|
+
let entrypoint;
|
|
1155
1156
|
let teamName;
|
|
1156
1157
|
let agentName;
|
|
1157
1158
|
let hasTeamCreate = false;
|
|
@@ -1220,6 +1221,8 @@ function parseTranscript(rawLines) {
|
|
|
1220
1221
|
cwd = o.cwd;
|
|
1221
1222
|
if (typeof o.gitBranch === "string" && !gitBranch)
|
|
1222
1223
|
gitBranch = o.gitBranch;
|
|
1224
|
+
if (typeof o.entrypoint === "string" && !entrypoint)
|
|
1225
|
+
entrypoint = o.entrypoint;
|
|
1223
1226
|
if (typeof o.teamName === "string" && !teamName)
|
|
1224
1227
|
teamName = o.teamName;
|
|
1225
1228
|
if (typeof o.agentName === "string" && !agentName)
|
|
@@ -1257,6 +1260,7 @@ function parseTranscript(rawLines) {
|
|
|
1257
1260
|
model,
|
|
1258
1261
|
cwd,
|
|
1259
1262
|
gitBranch,
|
|
1263
|
+
entrypoint,
|
|
1260
1264
|
totalUsage,
|
|
1261
1265
|
status: "idle",
|
|
1262
1266
|
firstUserPreview,
|
|
@@ -2937,6 +2941,8 @@ __export(fs_exports, {
|
|
|
2937
2941
|
agentSources: () => agentSources,
|
|
2938
2942
|
buildCalibrationCurve: () => buildCalibrationCurve,
|
|
2939
2943
|
cacheStats: () => cacheStats,
|
|
2944
|
+
cclensHome: () => cclensHome,
|
|
2945
|
+
cclensPath: () => cclensPath,
|
|
2940
2946
|
clearCaches: () => clearCaches,
|
|
2941
2947
|
codexSessionLocalDay: () => codexSessionLocalDay,
|
|
2942
2948
|
decodeProjectName: () => decodeProjectName,
|
|
@@ -2966,6 +2972,12 @@ __export(fs_exports, {
|
|
|
2966
2972
|
import { promises as fs4 } from "node:fs";
|
|
2967
2973
|
import os4 from "node:os";
|
|
2968
2974
|
import path4 from "node:path";
|
|
2975
|
+
function cclensHome() {
|
|
2976
|
+
return process.env.CCLENS_HOME || path4.join(os4.homedir(), ".cclens");
|
|
2977
|
+
}
|
|
2978
|
+
function cclensPath(...parts) {
|
|
2979
|
+
return path4.join(cclensHome(), ...parts);
|
|
2980
|
+
}
|
|
2969
2981
|
function cacheStats() {
|
|
2970
2982
|
return claudeCodeCacheStats();
|
|
2971
2983
|
}
|
|
@@ -2998,10 +3010,13 @@ async function getAnySession(id) {
|
|
|
2998
3010
|
}
|
|
2999
3011
|
return null;
|
|
3000
3012
|
}
|
|
3013
|
+
function usageLogPath() {
|
|
3014
|
+
return cclensPath("usage.jsonl");
|
|
3015
|
+
}
|
|
3001
3016
|
async function loadUsageByDay(start, end) {
|
|
3002
3017
|
let raw;
|
|
3003
3018
|
try {
|
|
3004
|
-
raw = await fs4.readFile(
|
|
3019
|
+
raw = await fs4.readFile(usageLogPath(), "utf8");
|
|
3005
3020
|
} catch {
|
|
3006
3021
|
return { by_day: [] };
|
|
3007
3022
|
}
|
|
@@ -3046,7 +3061,7 @@ async function loadUsageByDay(start, end) {
|
|
|
3046
3061
|
async function loadCalibrationSnapshots() {
|
|
3047
3062
|
let raw;
|
|
3048
3063
|
try {
|
|
3049
|
-
raw = await fs4.readFile(
|
|
3064
|
+
raw = await fs4.readFile(usageLogPath(), "utf8");
|
|
3050
3065
|
} catch {
|
|
3051
3066
|
return [];
|
|
3052
3067
|
}
|
|
@@ -3204,7 +3219,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
|
|
|
3204
3219
|
]);
|
|
3205
3220
|
return buildCalibrationCurve(events, snapshots, tier, granularityMin);
|
|
3206
3221
|
}
|
|
3207
|
-
var codexSource, geminiSource, agentSources
|
|
3222
|
+
var codexSource, geminiSource, agentSources;
|
|
3208
3223
|
var init_fs = __esm({
|
|
3209
3224
|
"../parser/dist/fs.js"() {
|
|
3210
3225
|
"use strict";
|
|
@@ -3249,7 +3264,6 @@ var init_fs = __esm({
|
|
|
3249
3264
|
}
|
|
3250
3265
|
};
|
|
3251
3266
|
agentSources = [claudeCodeSource, codexSource, geminiSource];
|
|
3252
|
-
USAGE_LOG = path4.join(os4.homedir(), ".cclens", "usage.jsonl");
|
|
3253
3267
|
}
|
|
3254
3268
|
});
|
|
3255
3269
|
|
|
@@ -3269,6 +3283,7 @@ function rowPrimaryIndex(r) {
|
|
|
3269
3283
|
function buildMegaRows(rows) {
|
|
3270
3284
|
const out = [];
|
|
3271
3285
|
let buffer = [];
|
|
3286
|
+
let turnAnchor = null;
|
|
3272
3287
|
const flush = () => {
|
|
3273
3288
|
if (buffer.length === 0)
|
|
3274
3289
|
return;
|
|
@@ -3327,9 +3342,10 @@ function buildMegaRows(rows) {
|
|
|
3327
3342
|
const toolNames = Array.from(toolMap.entries()).sort((a, b) => b[1] - a[1]).map(([name, count]) => ({ name, count }));
|
|
3328
3343
|
const first = buffer[0];
|
|
3329
3344
|
const last = buffer[buffer.length - 1];
|
|
3330
|
-
const
|
|
3345
|
+
const anchorOffset = turnAnchor?.tOffsetMs;
|
|
3346
|
+
const start = anchorOffset ?? first.tOffsetMs;
|
|
3331
3347
|
const end = last.tOffsetMs;
|
|
3332
|
-
const durationMs = start !== void 0 && end !== void 0 ? end - start : void 0;
|
|
3348
|
+
const durationMs = start !== void 0 && end !== void 0 && end >= start ? end - start : void 0;
|
|
3333
3349
|
out.push({
|
|
3334
3350
|
kind: "turn",
|
|
3335
3351
|
rows: buffer,
|
|
@@ -3354,6 +3370,7 @@ function buildMegaRows(rows) {
|
|
|
3354
3370
|
if (r.kind === "user" || r.kind === "interrupt") {
|
|
3355
3371
|
flush();
|
|
3356
3372
|
out.push(r);
|
|
3373
|
+
turnAnchor = r;
|
|
3357
3374
|
} else {
|
|
3358
3375
|
buffer.push(r);
|
|
3359
3376
|
}
|
|
@@ -3725,9 +3742,8 @@ var init_dist = __esm({
|
|
|
3725
3742
|
});
|
|
3726
3743
|
|
|
3727
3744
|
// src/daemon-worker.ts
|
|
3728
|
-
import { appendFileSync as appendFileSync5, mkdirSync as
|
|
3729
|
-
import { dirname as
|
|
3730
|
-
import { homedir as homedir13 } from "node:os";
|
|
3745
|
+
import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync12 } from "node:fs";
|
|
3746
|
+
import { dirname as dirname8 } from "node:path";
|
|
3731
3747
|
|
|
3732
3748
|
// src/usage/token.ts
|
|
3733
3749
|
import { execFileSync } from "node:child_process";
|
|
@@ -3908,26 +3924,23 @@ function nextIntervalMs(current, outcome) {
|
|
|
3908
3924
|
return Math.min(Math.max(current, BASE_INTERVAL_MS) * 2, MAX_INTERVAL_MS);
|
|
3909
3925
|
}
|
|
3910
3926
|
|
|
3911
|
-
// src/team/sync.ts
|
|
3912
|
-
import { homedir as homedir4 } from "node:os";
|
|
3913
|
-
import { join as join4 } from "node:path";
|
|
3914
|
-
|
|
3915
3927
|
// src/team/config.ts
|
|
3928
|
+
init_fs();
|
|
3916
3929
|
import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
3917
3930
|
import { join as join2 } from "node:path";
|
|
3918
|
-
import { homedir as homedir2 } from "node:os";
|
|
3919
|
-
var DEFAULT_DIR = join2(homedir2(), ".cclens");
|
|
3920
3931
|
var CONFIG_FILE = "team.json";
|
|
3921
|
-
function readTeamConfig(dir
|
|
3932
|
+
function readTeamConfig(dir) {
|
|
3933
|
+
const d = dir ?? cclensHome();
|
|
3922
3934
|
try {
|
|
3923
|
-
return JSON.parse(readFileSync3(join2(
|
|
3935
|
+
return JSON.parse(readFileSync3(join2(d, CONFIG_FILE), "utf8"));
|
|
3924
3936
|
} catch {
|
|
3925
3937
|
return null;
|
|
3926
3938
|
}
|
|
3927
3939
|
}
|
|
3928
|
-
function writeTeamConfig(config, dir
|
|
3929
|
-
|
|
3930
|
-
|
|
3940
|
+
function writeTeamConfig(config, dir) {
|
|
3941
|
+
const d = dir ?? cclensHome();
|
|
3942
|
+
mkdirSync2(d, { recursive: true });
|
|
3943
|
+
writeFileSync(join2(d, CONFIG_FILE), JSON.stringify(config, null, 2), { mode: 384 });
|
|
3931
3944
|
}
|
|
3932
3945
|
|
|
3933
3946
|
// src/team/push.ts
|
|
@@ -4003,10 +4016,10 @@ async function pushToTeamServer(config, payload) {
|
|
|
4003
4016
|
}
|
|
4004
4017
|
|
|
4005
4018
|
// src/team/queue.ts
|
|
4019
|
+
init_fs();
|
|
4006
4020
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync as appendFileSync2, statSync, mkdirSync as mkdirSync3 } from "node:fs";
|
|
4007
|
-
import {
|
|
4008
|
-
|
|
4009
|
-
var QUEUE_PATH = join3(homedir3(), ".cclens", "ingest-queue.jsonl");
|
|
4021
|
+
import { dirname as dirname2 } from "node:path";
|
|
4022
|
+
var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
|
|
4010
4023
|
var MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
4011
4024
|
var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
4012
4025
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
@@ -4129,8 +4142,9 @@ async function getPlanTier(cachePath, nowMs = Date.now(), fetcher = fetchProfile
|
|
|
4129
4142
|
}
|
|
4130
4143
|
|
|
4131
4144
|
// src/team/sync.ts
|
|
4132
|
-
|
|
4133
|
-
var
|
|
4145
|
+
init_fs();
|
|
4146
|
+
var USAGE_LOG = cclensPath("usage.jsonl");
|
|
4147
|
+
var PROFILE_CACHE = cclensPath("profile.json");
|
|
4134
4148
|
var noopLog = () => {
|
|
4135
4149
|
};
|
|
4136
4150
|
async function runTeamSync(log3 = noopLog, configOverride) {
|
|
@@ -4142,7 +4156,7 @@ async function runTeamSync(log3 = noopLog, configOverride) {
|
|
|
4142
4156
|
const today = toLocalDay3(Date.now());
|
|
4143
4157
|
const sessions = await listSessions2({ limit: 1e4 });
|
|
4144
4158
|
const rollups = buildRollupsForRange(sessions, config.lastSyncedDay);
|
|
4145
|
-
const usageSnapshot = readLatestUsageSnapshotForWire(
|
|
4159
|
+
const usageSnapshot = readLatestUsageSnapshotForWire(USAGE_LOG) ?? void 0;
|
|
4146
4160
|
const planTier = await getPlanTier(PROFILE_CACHE).catch(() => null) ?? void 0;
|
|
4147
4161
|
const cyclePeaks = await buildCyclePeaksForPush(planTier, loadCalibrationCurve2);
|
|
4148
4162
|
if (rollups.length === 0) {
|
|
@@ -5057,28 +5071,28 @@ function buildEntries(sessionDetail) {
|
|
|
5057
5071
|
}
|
|
5058
5072
|
|
|
5059
5073
|
// ../entries/dist/fs.js
|
|
5074
|
+
init_fs();
|
|
5060
5075
|
import { readFileSync as readFileSync7, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, renameSync as renameSync2, existsSync as existsSync4 } from "node:fs";
|
|
5061
5076
|
import { randomBytes } from "node:crypto";
|
|
5062
|
-
import { join as
|
|
5063
|
-
import { homedir as homedir6 } from "node:os";
|
|
5077
|
+
import { join as join4 } from "node:path";
|
|
5064
5078
|
|
|
5065
5079
|
// ../entries/dist/digest-fs.js
|
|
5080
|
+
init_fs();
|
|
5066
5081
|
import { readFileSync as readFileSync6, readdirSync, writeFileSync as writeFileSync4, renameSync, chmodSync, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "node:fs";
|
|
5067
|
-
import { dirname as dirname4, join as
|
|
5068
|
-
import { homedir as homedir5 } from "node:os";
|
|
5082
|
+
import { dirname as dirname4, join as join3 } from "node:path";
|
|
5069
5083
|
var digestsDirCached = null;
|
|
5070
5084
|
function digestsDir() {
|
|
5071
5085
|
if (digestsDirCached)
|
|
5072
5086
|
return digestsDirCached;
|
|
5073
5087
|
const envOverride = process.env.CCLENS_DIGESTS_DIR;
|
|
5074
|
-
digestsDirCached = envOverride ??
|
|
5088
|
+
digestsDirCached = envOverride ?? cclensPath("digests");
|
|
5075
5089
|
return digestsDirCached;
|
|
5076
5090
|
}
|
|
5077
5091
|
function dayDigestPath(date) {
|
|
5078
|
-
return
|
|
5092
|
+
return join3(digestsDir(), "day", `${date}.json`);
|
|
5079
5093
|
}
|
|
5080
5094
|
function weekDigestPath(monday) {
|
|
5081
|
-
return
|
|
5095
|
+
return join3(digestsDir(), "week", `${monday}.json`);
|
|
5082
5096
|
}
|
|
5083
5097
|
function writeDayDigest(digest) {
|
|
5084
5098
|
const final = dayDigestPath(digest.key);
|
|
@@ -5162,11 +5176,11 @@ function entriesDir() {
|
|
|
5162
5176
|
if (entriesDirCached)
|
|
5163
5177
|
return entriesDirCached;
|
|
5164
5178
|
const envOverride = process.env.CCLENS_ENTRIES_DIR;
|
|
5165
|
-
entriesDirCached = envOverride ??
|
|
5179
|
+
entriesDirCached = envOverride ?? cclensPath("entries");
|
|
5166
5180
|
return entriesDirCached;
|
|
5167
5181
|
}
|
|
5168
5182
|
function pathFor(sessionId, localDay) {
|
|
5169
|
-
return
|
|
5183
|
+
return join4(entriesDir(), `${entryKey(sessionId, localDay)}.json`);
|
|
5170
5184
|
}
|
|
5171
5185
|
function tmpPathFor(final) {
|
|
5172
5186
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
@@ -5239,14 +5253,14 @@ function listEntriesForDay(localDay) {
|
|
|
5239
5253
|
}
|
|
5240
5254
|
|
|
5241
5255
|
// src/perception/state.ts
|
|
5256
|
+
init_fs();
|
|
5242
5257
|
import { existsSync as existsSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, renameSync as renameSync3 } from "node:fs";
|
|
5243
|
-
import { dirname as dirname5
|
|
5244
|
-
import { homedir as homedir7 } from "node:os";
|
|
5258
|
+
import { dirname as dirname5 } from "node:path";
|
|
5245
5259
|
var STALE_MS = 15 * 60 * 1e3;
|
|
5246
5260
|
var pathCached = null;
|
|
5247
5261
|
function statePath() {
|
|
5248
5262
|
if (pathCached) return pathCached;
|
|
5249
|
-
pathCached =
|
|
5263
|
+
pathCached = cclensPath("perception-state.json");
|
|
5250
5264
|
return pathCached;
|
|
5251
5265
|
}
|
|
5252
5266
|
function readState() {
|
|
@@ -5296,17 +5310,17 @@ function updateCheckpoint(jsonlPath, cp) {
|
|
|
5296
5310
|
|
|
5297
5311
|
// src/perception/scan.ts
|
|
5298
5312
|
import { readdirSync as readdirSync3 } from "node:fs";
|
|
5299
|
-
import { join as
|
|
5300
|
-
import { homedir as
|
|
5313
|
+
import { join as join5 } from "node:path";
|
|
5314
|
+
import { homedir as homedir2 } from "node:os";
|
|
5301
5315
|
async function listAllSessionJsonls(root) {
|
|
5302
|
-
const projectsRoot = root ??
|
|
5316
|
+
const projectsRoot = root ?? join5(homedir2(), ".claude", "projects");
|
|
5303
5317
|
const out = [];
|
|
5304
5318
|
try {
|
|
5305
5319
|
for (const project of readdirSync3(projectsRoot)) {
|
|
5306
|
-
const dir =
|
|
5320
|
+
const dir = join5(projectsRoot, project);
|
|
5307
5321
|
try {
|
|
5308
5322
|
for (const f of readdirSync3(dir)) {
|
|
5309
|
-
if (f.endsWith(".jsonl")) out.push(
|
|
5323
|
+
if (f.endsWith(".jsonl")) out.push(join5(dir, f));
|
|
5310
5324
|
}
|
|
5311
5325
|
} catch {
|
|
5312
5326
|
}
|
|
@@ -9547,16 +9561,332 @@ ${turns || "(none \u2014 the user text was filtered out as non-human)"}`;
|
|
|
9547
9561
|
var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
|
|
9548
9562
|
|
|
9549
9563
|
// ../entries/dist/llm-runner.js
|
|
9564
|
+
init_fs();
|
|
9550
9565
|
import { spawn } from "node:child_process";
|
|
9551
|
-
import { mkdirSync as
|
|
9552
|
-
import {
|
|
9553
|
-
import { join as join9 } from "node:path";
|
|
9566
|
+
import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync8, existsSync as existsSync7 } from "node:fs";
|
|
9567
|
+
import { join as join7 } from "node:path";
|
|
9554
9568
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
9555
|
-
|
|
9569
|
+
|
|
9570
|
+
// ../entries/dist/tmux-runner.js
|
|
9571
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, existsSync as existsSync6, readdirSync as readdirSync4, realpathSync, readFileSync as readFileSync10, unlinkSync as unlinkSync2, renameSync as renameSync4 } from "node:fs";
|
|
9572
|
+
import { join as join6 } from "node:path";
|
|
9573
|
+
import { homedir as homedir3 } from "node:os";
|
|
9574
|
+
import { spawnSync } from "node:child_process";
|
|
9575
|
+
var TmuxUnavailableError = class extends Error {
|
|
9576
|
+
constructor(message) {
|
|
9577
|
+
super(message);
|
|
9578
|
+
this.name = "TmuxUnavailableError";
|
|
9579
|
+
}
|
|
9580
|
+
};
|
|
9581
|
+
var TmuxRunError = class extends Error {
|
|
9582
|
+
constructor(message) {
|
|
9583
|
+
super(message);
|
|
9584
|
+
this.name = "TmuxRunError";
|
|
9585
|
+
}
|
|
9586
|
+
};
|
|
9587
|
+
function which(bin) {
|
|
9588
|
+
const r = spawnSync("/usr/bin/env", ["which", bin], { encoding: "utf8" });
|
|
9589
|
+
if (r.status === 0)
|
|
9590
|
+
return r.stdout.trim() || void 0;
|
|
9591
|
+
return void 0;
|
|
9592
|
+
}
|
|
9593
|
+
function tmuxRunnerAvailable() {
|
|
9594
|
+
if (!which("tmux"))
|
|
9595
|
+
return { ok: false, reason: "tmux not on PATH" };
|
|
9596
|
+
if (!which("claude"))
|
|
9597
|
+
return { ok: false, reason: "claude not on PATH" };
|
|
9598
|
+
return { ok: true };
|
|
9599
|
+
}
|
|
9600
|
+
function runtimeCwd() {
|
|
9601
|
+
const dir = join6(homedir3(), ".cclens", "runtime");
|
|
9602
|
+
if (!existsSync6(dir))
|
|
9603
|
+
mkdirSync8(dir, { recursive: true });
|
|
9604
|
+
return realpathSync(dir);
|
|
9605
|
+
}
|
|
9606
|
+
function ensureRuntimeCwdTrusted(cwd) {
|
|
9607
|
+
const cfgPath = join6(homedir3(), ".claude.json");
|
|
9608
|
+
let cfg;
|
|
9609
|
+
try {
|
|
9610
|
+
cfg = JSON.parse(readFileSync10(cfgPath, "utf8"));
|
|
9611
|
+
} catch {
|
|
9612
|
+
return;
|
|
9613
|
+
}
|
|
9614
|
+
const projects = cfg.projects ?? {};
|
|
9615
|
+
const cur = projects[cwd];
|
|
9616
|
+
if (cur && cur.hasTrustDialogAccepted === true)
|
|
9617
|
+
return;
|
|
9618
|
+
projects[cwd] = {
|
|
9619
|
+
...cur ?? {},
|
|
9620
|
+
hasTrustDialogAccepted: true
|
|
9621
|
+
};
|
|
9622
|
+
cfg.projects = projects;
|
|
9623
|
+
const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
|
|
9624
|
+
try {
|
|
9625
|
+
writeFileSync7(tmp, JSON.stringify(cfg, null, 2));
|
|
9626
|
+
renameSync4(tmp, cfgPath);
|
|
9627
|
+
} catch {
|
|
9628
|
+
try {
|
|
9629
|
+
unlinkSync2(tmp);
|
|
9630
|
+
} catch {
|
|
9631
|
+
}
|
|
9632
|
+
}
|
|
9633
|
+
}
|
|
9634
|
+
var mutex = Promise.resolve();
|
|
9635
|
+
function runClaudeUnderTmux(args) {
|
|
9636
|
+
const next = mutex.then(() => runClaudeUnderTmuxImpl(args));
|
|
9637
|
+
mutex = next.catch(() => void 0);
|
|
9638
|
+
return next;
|
|
9639
|
+
}
|
|
9640
|
+
async function runClaudeUnderTmuxImpl(args) {
|
|
9641
|
+
const tmuxBin = args.tmuxBin ?? which("tmux");
|
|
9642
|
+
if (!tmuxBin)
|
|
9643
|
+
throw new TmuxUnavailableError("tmux not on PATH");
|
|
9644
|
+
const claudeBin = args.claudeBin ?? which("claude");
|
|
9645
|
+
if (!claudeBin)
|
|
9646
|
+
throw new TmuxUnavailableError("claude not on PATH");
|
|
9647
|
+
if (args.signal?.aborted)
|
|
9648
|
+
throw new TmuxRunError("aborted before spawn");
|
|
9649
|
+
const cwd = runtimeCwd();
|
|
9650
|
+
ensureRuntimeCwdTrusted(cwd);
|
|
9651
|
+
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
9652
|
+
const sessionName = `cclens-${runId}`;
|
|
9653
|
+
const systemFile = join6(cwd, `system-${runId}.txt`);
|
|
9654
|
+
const userFile = join6(cwd, `user-${runId}.txt`);
|
|
9655
|
+
const wrapper = join6(cwd, `run-${runId}.sh`);
|
|
9656
|
+
writeFileSync7(systemFile, args.systemPrompt);
|
|
9657
|
+
writeFileSync7(userFile, args.reminder ? `${args.userPrompt}
|
|
9658
|
+
|
|
9659
|
+
---
|
|
9660
|
+
|
|
9661
|
+
${args.reminder}` : args.userPrompt);
|
|
9662
|
+
writeFileSync7(wrapper, `#!/bin/bash
|
|
9663
|
+
SYS="$(cat ${shellEscape(systemFile)})"
|
|
9664
|
+
USR="$(cat ${shellEscape(userFile)})"
|
|
9665
|
+
exec ${shellEscape(claudeBin)} \\
|
|
9666
|
+
--model ${shellEscape(args.model)} \\
|
|
9667
|
+
--strict-mcp-config --mcp-config '{"mcpServers":{}}' \\
|
|
9668
|
+
--disable-slash-commands \\
|
|
9669
|
+
--effort medium \\
|
|
9670
|
+
--append-system-prompt "$SYS" \\
|
|
9671
|
+
"$USR"
|
|
9672
|
+
`, { mode: 493 });
|
|
9673
|
+
const existingBefore = snapshotAllTranscripts();
|
|
9674
|
+
const spawn2 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
|
|
9675
|
+
if (spawn2.status !== 0) {
|
|
9676
|
+
cleanup(cwd, runId, tmuxBin, sessionName);
|
|
9677
|
+
throw new TmuxRunError(`tmux new-session failed: ${spawn2.stderr.trim()}`);
|
|
9678
|
+
}
|
|
9679
|
+
const onAbort = () => {
|
|
9680
|
+
try {
|
|
9681
|
+
spawnSync(tmuxBin, ["kill-session", "-t", sessionName], { stdio: "ignore" });
|
|
9682
|
+
} catch {
|
|
9683
|
+
}
|
|
9684
|
+
};
|
|
9685
|
+
args.signal?.addEventListener("abort", onAbort, { once: true });
|
|
9686
|
+
const startMs = Date.now();
|
|
9687
|
+
const timeoutMs = args.timeoutMs ?? 12e4;
|
|
9688
|
+
let lastReportedKb = -1;
|
|
9689
|
+
let lastEmittedLength = 0;
|
|
9690
|
+
try {
|
|
9691
|
+
const transcriptPath = await discoverTranscript(cwd, existingBefore, startMs, timeoutMs, args.signal);
|
|
9692
|
+
while (Date.now() - startMs < timeoutMs) {
|
|
9693
|
+
if (args.signal?.aborted)
|
|
9694
|
+
throw new TmuxRunError("aborted");
|
|
9695
|
+
const { assembled, inputTokens, outputTokens, modelUsed, done } = parseTranscript2(transcriptPath, args.model);
|
|
9696
|
+
if (args.onProgress) {
|
|
9697
|
+
const kb = Math.floor(assembled.length / 1024);
|
|
9698
|
+
if (kb > lastReportedKb) {
|
|
9699
|
+
lastReportedKb = kb;
|
|
9700
|
+
args.onProgress({ bytes: assembled.length, elapsedMs: Date.now() - startMs });
|
|
9701
|
+
}
|
|
9702
|
+
}
|
|
9703
|
+
if (args.onDelta && assembled.length > lastEmittedLength) {
|
|
9704
|
+
const chunk = assembled.slice(lastEmittedLength);
|
|
9705
|
+
lastEmittedLength = assembled.length;
|
|
9706
|
+
try {
|
|
9707
|
+
args.onDelta(chunk);
|
|
9708
|
+
} catch {
|
|
9709
|
+
}
|
|
9710
|
+
}
|
|
9711
|
+
if (done && assembled.length > 0) {
|
|
9712
|
+
return {
|
|
9713
|
+
content: assembled,
|
|
9714
|
+
input_tokens: inputTokens,
|
|
9715
|
+
output_tokens: outputTokens,
|
|
9716
|
+
model: modelUsed
|
|
9717
|
+
};
|
|
9718
|
+
}
|
|
9719
|
+
await sleep(500);
|
|
9720
|
+
}
|
|
9721
|
+
throw new TmuxRunError(`timeout after ${timeoutMs}ms waiting for assistant turn`);
|
|
9722
|
+
} finally {
|
|
9723
|
+
args.signal?.removeEventListener("abort", onAbort);
|
|
9724
|
+
cleanup(cwd, runId, tmuxBin, sessionName);
|
|
9725
|
+
}
|
|
9726
|
+
}
|
|
9727
|
+
function num(v) {
|
|
9728
|
+
return typeof v === "number" ? v : 0;
|
|
9729
|
+
}
|
|
9730
|
+
function sleep(ms) {
|
|
9731
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
9732
|
+
}
|
|
9733
|
+
var PROJECTS_ROOT = () => join6(homedir3(), ".claude", "projects");
|
|
9734
|
+
function snapshotAllTranscripts() {
|
|
9735
|
+
const out = /* @__PURE__ */ new Set();
|
|
9736
|
+
const root = PROJECTS_ROOT();
|
|
9737
|
+
let subs;
|
|
9738
|
+
try {
|
|
9739
|
+
subs = readdirSync4(root);
|
|
9740
|
+
} catch {
|
|
9741
|
+
return out;
|
|
9742
|
+
}
|
|
9743
|
+
for (const sub of subs) {
|
|
9744
|
+
const dir = join6(root, sub);
|
|
9745
|
+
let files;
|
|
9746
|
+
try {
|
|
9747
|
+
files = readdirSync4(dir);
|
|
9748
|
+
} catch {
|
|
9749
|
+
continue;
|
|
9750
|
+
}
|
|
9751
|
+
for (const f of files) {
|
|
9752
|
+
if (f.endsWith(".jsonl"))
|
|
9753
|
+
out.add(join6(dir, f));
|
|
9754
|
+
}
|
|
9755
|
+
}
|
|
9756
|
+
return out;
|
|
9757
|
+
}
|
|
9758
|
+
function readJsonlCwd(path5, maxLines = 8) {
|
|
9759
|
+
let raw;
|
|
9760
|
+
try {
|
|
9761
|
+
raw = readFileSync10(path5, "utf8");
|
|
9762
|
+
} catch {
|
|
9763
|
+
return void 0;
|
|
9764
|
+
}
|
|
9765
|
+
let count = 0;
|
|
9766
|
+
for (const line of raw.split("\n")) {
|
|
9767
|
+
const t = line.trim();
|
|
9768
|
+
if (!t)
|
|
9769
|
+
continue;
|
|
9770
|
+
count++;
|
|
9771
|
+
try {
|
|
9772
|
+
const o = JSON.parse(t);
|
|
9773
|
+
if (typeof o.cwd === "string")
|
|
9774
|
+
return o.cwd;
|
|
9775
|
+
} catch {
|
|
9776
|
+
}
|
|
9777
|
+
if (count >= maxLines)
|
|
9778
|
+
break;
|
|
9779
|
+
}
|
|
9780
|
+
return void 0;
|
|
9781
|
+
}
|
|
9782
|
+
async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs, signal) {
|
|
9783
|
+
while (Date.now() - startMs < timeoutMs) {
|
|
9784
|
+
if (signal?.aborted)
|
|
9785
|
+
throw new TmuxRunError("aborted");
|
|
9786
|
+
const root = PROJECTS_ROOT();
|
|
9787
|
+
let subs;
|
|
9788
|
+
try {
|
|
9789
|
+
subs = readdirSync4(root);
|
|
9790
|
+
} catch {
|
|
9791
|
+
subs = [];
|
|
9792
|
+
}
|
|
9793
|
+
for (const sub of subs) {
|
|
9794
|
+
const dir = join6(root, sub);
|
|
9795
|
+
let files;
|
|
9796
|
+
try {
|
|
9797
|
+
files = readdirSync4(dir);
|
|
9798
|
+
} catch {
|
|
9799
|
+
continue;
|
|
9800
|
+
}
|
|
9801
|
+
for (const f of files) {
|
|
9802
|
+
if (!f.endsWith(".jsonl"))
|
|
9803
|
+
continue;
|
|
9804
|
+
const full = join6(dir, f);
|
|
9805
|
+
if (existingBefore.has(full))
|
|
9806
|
+
continue;
|
|
9807
|
+
if (readJsonlCwd(full) === targetCwd)
|
|
9808
|
+
return full;
|
|
9809
|
+
}
|
|
9810
|
+
}
|
|
9811
|
+
await sleep(300);
|
|
9812
|
+
}
|
|
9813
|
+
throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
|
|
9814
|
+
}
|
|
9815
|
+
function parseTranscript2(path5, defaultModel) {
|
|
9816
|
+
let raw;
|
|
9817
|
+
try {
|
|
9818
|
+
raw = readFileSync10(path5, "utf8");
|
|
9819
|
+
} catch {
|
|
9820
|
+
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
9821
|
+
}
|
|
9822
|
+
let assembled = "";
|
|
9823
|
+
let inputTokens = 0;
|
|
9824
|
+
let outputTokens = 0;
|
|
9825
|
+
let modelUsed = defaultModel;
|
|
9826
|
+
let done = false;
|
|
9827
|
+
for (const line of raw.split("\n")) {
|
|
9828
|
+
const t = line.trim();
|
|
9829
|
+
if (!t)
|
|
9830
|
+
continue;
|
|
9831
|
+
let o;
|
|
9832
|
+
try {
|
|
9833
|
+
o = JSON.parse(t);
|
|
9834
|
+
} catch {
|
|
9835
|
+
continue;
|
|
9836
|
+
}
|
|
9837
|
+
if (o.type !== "assistant")
|
|
9838
|
+
continue;
|
|
9839
|
+
const m = o.message;
|
|
9840
|
+
if (!m)
|
|
9841
|
+
continue;
|
|
9842
|
+
const mm = m.model;
|
|
9843
|
+
if (mm)
|
|
9844
|
+
modelUsed = mm;
|
|
9845
|
+
const content = m.content;
|
|
9846
|
+
if (Array.isArray(content)) {
|
|
9847
|
+
for (const block of content) {
|
|
9848
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
9849
|
+
assembled += block.text;
|
|
9850
|
+
}
|
|
9851
|
+
}
|
|
9852
|
+
}
|
|
9853
|
+
const usage = m.usage;
|
|
9854
|
+
if (usage) {
|
|
9855
|
+
inputTokens = num(usage.input_tokens) + num(usage.cache_creation_input_tokens) + num(usage.cache_read_input_tokens);
|
|
9856
|
+
outputTokens = num(usage.output_tokens);
|
|
9857
|
+
}
|
|
9858
|
+
if (m.stop_reason === "end_turn") {
|
|
9859
|
+
done = true;
|
|
9860
|
+
}
|
|
9861
|
+
}
|
|
9862
|
+
return { assembled, inputTokens, outputTokens, modelUsed, done };
|
|
9863
|
+
}
|
|
9864
|
+
function cleanup(cwd, runId, tmuxBin, sessionName) {
|
|
9865
|
+
try {
|
|
9866
|
+
spawnSync(tmuxBin, ["kill-session", "-t", sessionName], { stdio: "ignore" });
|
|
9867
|
+
} catch {
|
|
9868
|
+
}
|
|
9869
|
+
if (process.env.FLEETLENS_TMUX_KEEP_WRAPPER !== "1") {
|
|
9870
|
+
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
9871
|
+
try {
|
|
9872
|
+
unlinkSync2(join6(cwd, f));
|
|
9873
|
+
} catch {
|
|
9874
|
+
}
|
|
9875
|
+
}
|
|
9876
|
+
}
|
|
9877
|
+
}
|
|
9878
|
+
function shellEscape(s) {
|
|
9879
|
+
if (/^[A-Za-z0-9_./-]+$/.test(s))
|
|
9880
|
+
return s;
|
|
9881
|
+
return `'${s.replace(/'/g, `'"'"'`)}'`;
|
|
9882
|
+
}
|
|
9883
|
+
|
|
9884
|
+
// ../entries/dist/llm-runner.js
|
|
9885
|
+
var RUNS_DIR = cclensPath("llm-runs");
|
|
9556
9886
|
function ensureRunsDir() {
|
|
9557
|
-
if (!
|
|
9887
|
+
if (!existsSync7(RUNS_DIR)) {
|
|
9558
9888
|
try {
|
|
9559
|
-
|
|
9889
|
+
mkdirSync9(RUNS_DIR, { recursive: true });
|
|
9560
9890
|
} catch {
|
|
9561
9891
|
}
|
|
9562
9892
|
}
|
|
@@ -9583,7 +9913,7 @@ function newRunId(kind) {
|
|
|
9583
9913
|
return `${ts}_${kind}_${short}`;
|
|
9584
9914
|
}
|
|
9585
9915
|
function tracePath(runId) {
|
|
9586
|
-
return
|
|
9916
|
+
return join7(RUNS_DIR, `${runId}.jsonl`);
|
|
9587
9917
|
}
|
|
9588
9918
|
function safeAppend(path5, line) {
|
|
9589
9919
|
try {
|
|
@@ -9593,11 +9923,84 @@ function safeAppend(path5, line) {
|
|
|
9593
9923
|
}
|
|
9594
9924
|
function safeWrite(path5, line) {
|
|
9595
9925
|
try {
|
|
9596
|
-
|
|
9926
|
+
writeFileSync8(path5, line);
|
|
9597
9927
|
} catch {
|
|
9598
9928
|
}
|
|
9599
9929
|
}
|
|
9600
|
-
function runClaudeSubprocess(args) {
|
|
9930
|
+
async function runClaudeSubprocess(args) {
|
|
9931
|
+
if (process.env.FLEETLENS_FORCE_PRINT_MODE !== "1") {
|
|
9932
|
+
const avail = tmuxRunnerAvailable();
|
|
9933
|
+
if (avail.ok) {
|
|
9934
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9935
|
+
const kind = detectKindFromSystemPrompt(args.systemPrompt);
|
|
9936
|
+
const runId = newRunId(kind);
|
|
9937
|
+
const trace = tracePath(runId);
|
|
9938
|
+
ensureRunsDir();
|
|
9939
|
+
safeWrite(trace, JSON.stringify({
|
|
9940
|
+
_meta: {
|
|
9941
|
+
type: "start",
|
|
9942
|
+
run_id: runId,
|
|
9943
|
+
kind,
|
|
9944
|
+
model: args.model,
|
|
9945
|
+
ts: startedAt,
|
|
9946
|
+
runtime: "tmux",
|
|
9947
|
+
user_prompt_chars: args.userPrompt.length,
|
|
9948
|
+
reminder_chars: args.reminder?.length ?? 0
|
|
9949
|
+
}
|
|
9950
|
+
}) + "\n");
|
|
9951
|
+
safeAppend(trace, JSON.stringify({
|
|
9952
|
+
_meta: {
|
|
9953
|
+
type: "payload",
|
|
9954
|
+
run_id: runId,
|
|
9955
|
+
system_prompt: args.systemPrompt,
|
|
9956
|
+
user_prompt: args.userPrompt,
|
|
9957
|
+
reminder: args.reminder ?? null
|
|
9958
|
+
}
|
|
9959
|
+
}) + "\n");
|
|
9960
|
+
try {
|
|
9961
|
+
const startMs = Date.now();
|
|
9962
|
+
const res = await runClaudeUnderTmux({
|
|
9963
|
+
systemPrompt: args.systemPrompt,
|
|
9964
|
+
model: args.model,
|
|
9965
|
+
userPrompt: args.userPrompt,
|
|
9966
|
+
reminder: args.reminder,
|
|
9967
|
+
onProgress: args.onProgress
|
|
9968
|
+
});
|
|
9969
|
+
safeAppend(trace, JSON.stringify({
|
|
9970
|
+
_meta: {
|
|
9971
|
+
type: "end",
|
|
9972
|
+
run_id: runId,
|
|
9973
|
+
runtime: "tmux",
|
|
9974
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9975
|
+
elapsed_ms: Date.now() - startMs,
|
|
9976
|
+
// tmux runs have no subprocess exit code (the session is killed
|
|
9977
|
+
// by cleanup). Stamp 0 on success so /api/runs renders them
|
|
9978
|
+
// as `ok` rather than `error`.
|
|
9979
|
+
exit_code: 0,
|
|
9980
|
+
content_chars: res.content.length,
|
|
9981
|
+
input_tokens: res.input_tokens,
|
|
9982
|
+
output_tokens: res.output_tokens,
|
|
9983
|
+
model_used: res.model
|
|
9984
|
+
}
|
|
9985
|
+
}) + "\n");
|
|
9986
|
+
return res;
|
|
9987
|
+
} catch (err) {
|
|
9988
|
+
const isExpected = err instanceof TmuxUnavailableError || err instanceof TmuxRunError;
|
|
9989
|
+
safeAppend(trace, JSON.stringify({
|
|
9990
|
+
_meta: {
|
|
9991
|
+
type: "tmux_fallback",
|
|
9992
|
+
run_id: runId,
|
|
9993
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9994
|
+
error: err.message,
|
|
9995
|
+
expected: isExpected
|
|
9996
|
+
}
|
|
9997
|
+
}) + "\n");
|
|
9998
|
+
}
|
|
9999
|
+
}
|
|
10000
|
+
}
|
|
10001
|
+
return runClaudePrintMode(args);
|
|
10002
|
+
}
|
|
10003
|
+
function runClaudePrintMode(args) {
|
|
9601
10004
|
return new Promise((resolve, reject) => {
|
|
9602
10005
|
ensureRunsDir();
|
|
9603
10006
|
const kind = detectKindFromSystemPrompt(args.systemPrompt);
|
|
@@ -9908,29 +10311,29 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
|
|
|
9908
10311
|
}
|
|
9909
10312
|
|
|
9910
10313
|
// ../entries/dist/budget.js
|
|
9911
|
-
|
|
9912
|
-
import {
|
|
9913
|
-
import {
|
|
10314
|
+
init_fs();
|
|
10315
|
+
import { appendFileSync as appendFileSync4, readFileSync as readFileSync11, existsSync as existsSync8, mkdirSync as mkdirSync10 } from "node:fs";
|
|
10316
|
+
import { dirname as dirname7 } from "node:path";
|
|
9914
10317
|
var spendPathCached = null;
|
|
9915
10318
|
function spendPath() {
|
|
9916
10319
|
if (spendPathCached)
|
|
9917
10320
|
return spendPathCached;
|
|
9918
|
-
spendPathCached =
|
|
10321
|
+
spendPathCached = cclensPath("llm-spend.jsonl");
|
|
9919
10322
|
return spendPathCached;
|
|
9920
10323
|
}
|
|
9921
10324
|
function appendSpend(record) {
|
|
9922
10325
|
const p = spendPath();
|
|
9923
|
-
|
|
10326
|
+
mkdirSync10(dirname7(p), { recursive: true });
|
|
9924
10327
|
appendFileSync4(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
9925
10328
|
}
|
|
9926
10329
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
9927
10330
|
const p = spendPath();
|
|
9928
|
-
if (!
|
|
10331
|
+
if (!existsSync8(p))
|
|
9929
10332
|
return 0;
|
|
9930
10333
|
const year = now.getUTCFullYear();
|
|
9931
10334
|
const month = now.getUTCMonth();
|
|
9932
10335
|
let total = 0;
|
|
9933
|
-
const raw =
|
|
10336
|
+
const raw = readFileSync11(p, "utf8");
|
|
9934
10337
|
for (const line of raw.split("\n")) {
|
|
9935
10338
|
if (!line)
|
|
9936
10339
|
continue;
|
|
@@ -9951,9 +10354,8 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
|
9951
10354
|
}
|
|
9952
10355
|
|
|
9953
10356
|
// ../entries/dist/pipeline-lock.js
|
|
9954
|
-
|
|
9955
|
-
import {
|
|
9956
|
-
import { homedir as homedir11 } from "node:os";
|
|
10357
|
+
init_fs();
|
|
10358
|
+
import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, existsSync as existsSync9, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
|
|
9957
10359
|
var STALE_MS2 = 60 * 1e3;
|
|
9958
10360
|
var HEARTBEAT_MS = 30 * 1e3;
|
|
9959
10361
|
var lockPathCached = null;
|
|
@@ -9961,11 +10363,11 @@ var heartbeat = null;
|
|
|
9961
10363
|
function lockPath() {
|
|
9962
10364
|
if (lockPathCached)
|
|
9963
10365
|
return lockPathCached;
|
|
9964
|
-
lockPathCached =
|
|
10366
|
+
lockPathCached = cclensPath("llm-interactive.lock");
|
|
9965
10367
|
return lockPathCached;
|
|
9966
10368
|
}
|
|
9967
10369
|
function touchLock() {
|
|
9968
|
-
|
|
10370
|
+
writeFileSync9(lockPath(), String(process.pid), "utf8");
|
|
9969
10371
|
}
|
|
9970
10372
|
function writeInteractiveLock() {
|
|
9971
10373
|
touchLock();
|
|
@@ -9985,7 +10387,7 @@ function removeInteractiveLock() {
|
|
|
9985
10387
|
heartbeat = null;
|
|
9986
10388
|
}
|
|
9987
10389
|
try {
|
|
9988
|
-
|
|
10390
|
+
unlinkSync3(lockPath());
|
|
9989
10391
|
} catch {
|
|
9990
10392
|
}
|
|
9991
10393
|
}
|
|
@@ -9999,13 +10401,13 @@ function pidAlive(pid) {
|
|
|
9999
10401
|
}
|
|
10000
10402
|
function interactiveLockFresh(nowMs) {
|
|
10001
10403
|
const p = lockPath();
|
|
10002
|
-
if (!
|
|
10404
|
+
if (!existsSync9(p))
|
|
10003
10405
|
return false;
|
|
10004
10406
|
try {
|
|
10005
10407
|
const mtime = statSync3(p).mtimeMs;
|
|
10006
10408
|
if (nowMs - mtime > STALE_MS2)
|
|
10007
10409
|
return false;
|
|
10008
|
-
const pid = Number(
|
|
10410
|
+
const pid = Number(readFileSync12(p, "utf8").trim());
|
|
10009
10411
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
10010
10412
|
return false;
|
|
10011
10413
|
if (!pidAlive(pid))
|
|
@@ -10020,9 +10422,8 @@ function interactiveLockFresh(nowMs) {
|
|
|
10020
10422
|
var THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
10021
10423
|
|
|
10022
10424
|
// ../entries/dist/settings.js
|
|
10023
|
-
import { readFileSync as
|
|
10024
|
-
|
|
10025
|
-
import { homedir as homedir12 } from "node:os";
|
|
10425
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync10 } from "node:fs";
|
|
10426
|
+
init_fs();
|
|
10026
10427
|
var DEFAULT_SETTINGS = {
|
|
10027
10428
|
ai_features: {
|
|
10028
10429
|
enabled: true,
|
|
@@ -10036,7 +10437,7 @@ var settingsPathCached = null;
|
|
|
10036
10437
|
function settingsPath() {
|
|
10037
10438
|
if (settingsPathCached)
|
|
10038
10439
|
return settingsPathCached;
|
|
10039
|
-
settingsPathCached =
|
|
10440
|
+
settingsPathCached = cclensPath("settings.json");
|
|
10040
10441
|
return settingsPathCached;
|
|
10041
10442
|
}
|
|
10042
10443
|
function fromDisk(d) {
|
|
@@ -10053,10 +10454,10 @@ function fromDisk(d) {
|
|
|
10053
10454
|
}
|
|
10054
10455
|
function readSettings() {
|
|
10055
10456
|
const p = settingsPath();
|
|
10056
|
-
if (!
|
|
10457
|
+
if (!existsSync10(p))
|
|
10057
10458
|
return DEFAULT_SETTINGS;
|
|
10058
10459
|
try {
|
|
10059
|
-
const raw =
|
|
10460
|
+
const raw = readFileSync13(p, "utf8");
|
|
10060
10461
|
return fromDisk(JSON.parse(raw));
|
|
10061
10462
|
} catch {
|
|
10062
10463
|
return DEFAULT_SETTINGS;
|
|
@@ -12779,11 +13180,10 @@ async function backfillYesterdayDigest(opts = {}) {
|
|
|
12779
13180
|
}
|
|
12780
13181
|
|
|
12781
13182
|
// src/daemon-worker.ts
|
|
12782
|
-
var
|
|
12783
|
-
var
|
|
12784
|
-
var DAEMON_LOG = join13(STATE_DIR, "daemon.log");
|
|
13183
|
+
var USAGE_LOG2 = cclensPath("usage.jsonl");
|
|
13184
|
+
var DAEMON_LOG = cclensPath("daemon.log");
|
|
12785
13185
|
var WATCHDOG_INTERVAL_MS = 5 * 1e3;
|
|
12786
|
-
|
|
13186
|
+
mkdirSync12(dirname8(USAGE_LOG2), { recursive: true });
|
|
12787
13187
|
function log2(level, message) {
|
|
12788
13188
|
const line = `${(/* @__PURE__ */ new Date()).toISOString()} ${level.toUpperCase()} ${message}
|
|
12789
13189
|
`;
|
|
@@ -12836,7 +13236,7 @@ async function tick() {
|
|
|
12836
13236
|
seven_day_cowork: null,
|
|
12837
13237
|
extra_usage: null
|
|
12838
13238
|
};
|
|
12839
|
-
appendSnapshot(
|
|
13239
|
+
appendSnapshot(USAGE_LOG2, snapshot);
|
|
12840
13240
|
log2(
|
|
12841
13241
|
"info",
|
|
12842
13242
|
`${source.kind} snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
|
|
@@ -12847,7 +13247,7 @@ async function tick() {
|
|
|
12847
13247
|
}
|
|
12848
13248
|
try {
|
|
12849
13249
|
const snapshot = await fetchUsage();
|
|
12850
|
-
appendSnapshot(
|
|
13250
|
+
appendSnapshot(USAGE_LOG2, snapshot);
|
|
12851
13251
|
log2(
|
|
12852
13252
|
"info",
|
|
12853
13253
|
`claude-code snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
|
|
@@ -12873,7 +13273,7 @@ function scheduleAfter(now, outcome) {
|
|
|
12873
13273
|
}
|
|
12874
13274
|
nextPollAtMs = now + currentIntervalMs;
|
|
12875
13275
|
}
|
|
12876
|
-
function
|
|
13276
|
+
function sleep2(ms) {
|
|
12877
13277
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
12878
13278
|
}
|
|
12879
13279
|
async function runLoop() {
|
|
@@ -12906,7 +13306,7 @@ async function runLoop() {
|
|
|
12906
13306
|
}
|
|
12907
13307
|
await runTeamSync(log2);
|
|
12908
13308
|
}
|
|
12909
|
-
await
|
|
13309
|
+
await sleep2(WATCHDOG_INTERVAL_MS);
|
|
12910
13310
|
}
|
|
12911
13311
|
}
|
|
12912
13312
|
log2(
|