fleetlens 0.10.0 → 0.10.1

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.
Files changed (153) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/build-manifest.json +3 -3
  3. package/app/apps/web/.next/prerender-manifest.json +3 -3
  4. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  5. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  6. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_not-found/page.js +2 -2
  12. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/app/apps/web/.next/server/app/api/ask/route.js +4 -3
  15. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  16. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +3 -4
  17. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  18. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +3 -4
  19. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/digest/month-index/route.js +3 -3
  21. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +3 -4
  23. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  24. package/app/apps/web/.next/server/app/api/digest/week-index/route.js +3 -3
  25. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/api/events/route.js +2 -3
  27. package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/jobs/route.js +1 -1
  29. package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
  30. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js +1 -1
  31. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js +1 -1
  33. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  34. package/app/apps/web/.next/server/app/api/runs/route.js +1 -1
  35. package/app/apps/web/.next/server/app/api/runs/route.js.nft.json +1 -1
  36. package/app/apps/web/.next/server/app/api/settings/route.js +3 -4
  37. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  38. package/app/apps/web/.next/server/app/changelog/page.js +2 -2
  39. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  40. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  41. package/app/apps/web/.next/server/app/day/[date]/page.js +2 -2
  42. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  43. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  44. package/app/apps/web/.next/server/app/day/page.js +2 -2
  45. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  46. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  47. package/app/apps/web/.next/server/app/digest/[date]/page.js +2 -2
  48. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  49. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  50. package/app/apps/web/.next/server/app/digest/page.js +2 -2
  51. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  52. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  53. package/app/apps/web/.next/server/app/insights/[key]/page.js +2 -2
  54. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  55. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  56. package/app/apps/web/.next/server/app/insights/page.js +2 -2
  57. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  58. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  59. package/app/apps/web/.next/server/app/page.js +2 -2
  60. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  61. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  62. package/app/apps/web/.next/server/app/parallelism/page.js +2 -2
  63. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  64. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  65. package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -2
  66. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  67. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  68. package/app/apps/web/.next/server/app/projects/page.js +2 -2
  69. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  70. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  71. package/app/apps/web/.next/server/app/runs/page.js +2 -2
  72. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  73. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  74. package/app/apps/web/.next/server/app/sessions/[id]/page.js +2 -2
  75. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  76. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  77. package/app/apps/web/.next/server/app/sessions/page.js +2 -2
  78. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  79. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  80. package/app/apps/web/.next/server/app/settings/page.js +2 -2
  81. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  82. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  83. package/app/apps/web/.next/server/app/usage/page.js +2 -2
  84. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  85. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  86. package/app/apps/web/.next/server/chunks/[externals]__09v47rg._.js +3 -0
  87. package/app/apps/web/.next/server/chunks/[externals]__0o43ejh._.js +3 -0
  88. package/app/apps/web/.next/server/chunks/[root-of-the-server]__00n3f9y._.js +1 -1
  89. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02px2mk._.js +3 -0
  90. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02zukjw._.js +1 -1
  91. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0455vu3._.js +5 -0
  92. package/app/apps/web/.next/server/chunks/[root-of-the-server]__067~im1._.js +2 -2
  93. package/app/apps/web/.next/server/chunks/[root-of-the-server]__06b4cj-._.js +1 -1
  94. package/app/apps/web/.next/server/chunks/[root-of-the-server]__08agijy._.js +3 -0
  95. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_8zh-i._.js +9 -0
  96. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ej_p3s._.js +9 -0
  97. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i06ito._.js +3 -0
  98. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0jprdks._.js +9 -0
  99. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0vm_41a._.js +3 -0
  100. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js +4 -4
  101. package/app/apps/web/.next/server/chunks/packages_0c-sz9n._.js +3 -0
  102. package/app/apps/web/.next/server/chunks/packages_0wywuu.._.js +3 -0
  103. package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +27 -13
  104. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
  105. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0s4dg1y._.js +1 -1
  106. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +1 -1
  107. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0yv0m0q._.js +3 -0
  108. package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
  109. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +1 -1
  110. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0m67-xi._.js +1 -1
  111. package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
  112. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_12.endt._.js +3 -0
  113. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  114. package/app/apps/web/.next/server/pages/500.html +1 -1
  115. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  116. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  117. package/app/apps/web/.next/static/chunks/{09--oejbzw3q-.js → 0g8ujtb0lp._9.js} +1 -1
  118. package/app/apps/web/.next/static/chunks/0~n2a9f52wju9.js +14 -0
  119. package/app/apps/web/app/api/ask/route.ts +124 -111
  120. package/app/apps/web/app/api/events/route.ts +3 -4
  121. package/app/apps/web/app/api/runs/[runId]/route.ts +2 -2
  122. package/app/apps/web/app/api/runs/[runId]/stream/route.ts +3 -2
  123. package/app/apps/web/app/api/runs/route.ts +8 -4
  124. package/app/apps/web/app/sessions/[id]/session-view.tsx +31 -0
  125. package/app/apps/web/components/job-queue-widget.tsx +11 -8
  126. package/app/apps/web/lib/calibration-data.ts +2 -4
  127. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  128. package/app/apps/web/lib/entries-index.ts +2 -2
  129. package/app/apps/web/lib/jobs.ts +3 -5
  130. package/app/apps/web/lib/usage-data.ts +3 -4
  131. package/app/apps/web/package.json +1 -1
  132. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  133. package/dist/daemon-worker.js +476 -79
  134. package/dist/index.js +4368 -3959
  135. package/package.json +1 -1
  136. package/app/apps/web/.next/server/chunks/[root-of-the-server]__07qxzx4._.js +0 -9
  137. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0fu2xfy._.js +0 -5
  138. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0gfd42k._.js +0 -9
  139. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i.m8y0._.js +0 -3
  140. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0iy5aqy._.js +0 -9
  141. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh7-nf._.js +0 -3
  142. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nvdffv._.js +0 -3
  143. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0op9af~._.js +0 -3
  144. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s2~c3g._.js +0 -3
  145. package/app/apps/web/.next/server/chunks/packages_09wmnv.._.js +0 -3
  146. package/app/apps/web/.next/server/chunks/packages_0o6.gpk._.js +0 -3
  147. package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_122oe0-.js +0 -3
  148. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0sp6.jt._.js +0 -3
  149. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_10_oegc._.js +0 -3
  150. package/app/apps/web/.next/static/chunks/0qcu452dr~edz.js +0 -14
  151. /package/app/apps/web/.next/static/{L0Dy1hOQrZjV9l0TNulvk → sxcMbKfZ5XgVXYN4QHOHd}/_buildManifest.js +0 -0
  152. /package/app/apps/web/.next/static/{L0Dy1hOQrZjV9l0TNulvk → sxcMbKfZ5XgVXYN4QHOHd}/_clientMiddlewareManifest.js +0 -0
  153. /package/app/apps/web/.next/static/{L0Dy1hOQrZjV9l0TNulvk → sxcMbKfZ5XgVXYN4QHOHd}/_ssgManifest.js +0 -0
@@ -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(USAGE_LOG, "utf8");
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(USAGE_LOG, "utf8");
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, USAGE_LOG;
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
 
@@ -3725,9 +3739,8 @@ var init_dist = __esm({
3725
3739
  });
3726
3740
 
3727
3741
  // src/daemon-worker.ts
3728
- import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync11 } from "node:fs";
3729
- import { dirname as dirname9, join as join13 } from "node:path";
3730
- import { homedir as homedir13 } from "node:os";
3742
+ import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync12 } from "node:fs";
3743
+ import { dirname as dirname8 } from "node:path";
3731
3744
 
3732
3745
  // src/usage/token.ts
3733
3746
  import { execFileSync } from "node:child_process";
@@ -3908,26 +3921,23 @@ function nextIntervalMs(current, outcome) {
3908
3921
  return Math.min(Math.max(current, BASE_INTERVAL_MS) * 2, MAX_INTERVAL_MS);
3909
3922
  }
3910
3923
 
3911
- // src/team/sync.ts
3912
- import { homedir as homedir4 } from "node:os";
3913
- import { join as join4 } from "node:path";
3914
-
3915
3924
  // src/team/config.ts
3925
+ init_fs();
3916
3926
  import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync as mkdirSync2 } from "node:fs";
3917
3927
  import { join as join2 } from "node:path";
3918
- import { homedir as homedir2 } from "node:os";
3919
- var DEFAULT_DIR = join2(homedir2(), ".cclens");
3920
3928
  var CONFIG_FILE = "team.json";
3921
- function readTeamConfig(dir = DEFAULT_DIR) {
3929
+ function readTeamConfig(dir) {
3930
+ const d = dir ?? cclensHome();
3922
3931
  try {
3923
- return JSON.parse(readFileSync3(join2(dir, CONFIG_FILE), "utf8"));
3932
+ return JSON.parse(readFileSync3(join2(d, CONFIG_FILE), "utf8"));
3924
3933
  } catch {
3925
3934
  return null;
3926
3935
  }
3927
3936
  }
3928
- function writeTeamConfig(config, dir = DEFAULT_DIR) {
3929
- mkdirSync2(dir, { recursive: true });
3930
- writeFileSync(join2(dir, CONFIG_FILE), JSON.stringify(config, null, 2), { mode: 384 });
3937
+ function writeTeamConfig(config, dir) {
3938
+ const d = dir ?? cclensHome();
3939
+ mkdirSync2(d, { recursive: true });
3940
+ writeFileSync(join2(d, CONFIG_FILE), JSON.stringify(config, null, 2), { mode: 384 });
3931
3941
  }
3932
3942
 
3933
3943
  // src/team/push.ts
@@ -4003,10 +4013,10 @@ async function pushToTeamServer(config, payload) {
4003
4013
  }
4004
4014
 
4005
4015
  // src/team/queue.ts
4016
+ init_fs();
4006
4017
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync as appendFileSync2, statSync, mkdirSync as mkdirSync3 } from "node:fs";
4007
- import { join as join3, dirname as dirname2 } from "node:path";
4008
- import { homedir as homedir3 } from "node:os";
4009
- var QUEUE_PATH = join3(homedir3(), ".cclens", "ingest-queue.jsonl");
4018
+ import { dirname as dirname2 } from "node:path";
4019
+ var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
4010
4020
  var MAX_SIZE_BYTES = 10 * 1024 * 1024;
4011
4021
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
4012
4022
  function enqueuePayload(payload, queuePath = QUEUE_PATH) {
@@ -4129,8 +4139,9 @@ async function getPlanTier(cachePath, nowMs = Date.now(), fetcher = fetchProfile
4129
4139
  }
4130
4140
 
4131
4141
  // src/team/sync.ts
4132
- var USAGE_LOG2 = join4(homedir4(), ".cclens", "usage.jsonl");
4133
- var PROFILE_CACHE = join4(homedir4(), ".cclens", "profile.json");
4142
+ init_fs();
4143
+ var USAGE_LOG = cclensPath("usage.jsonl");
4144
+ var PROFILE_CACHE = cclensPath("profile.json");
4134
4145
  var noopLog = () => {
4135
4146
  };
4136
4147
  async function runTeamSync(log3 = noopLog, configOverride) {
@@ -4142,7 +4153,7 @@ async function runTeamSync(log3 = noopLog, configOverride) {
4142
4153
  const today = toLocalDay3(Date.now());
4143
4154
  const sessions = await listSessions2({ limit: 1e4 });
4144
4155
  const rollups = buildRollupsForRange(sessions, config.lastSyncedDay);
4145
- const usageSnapshot = readLatestUsageSnapshotForWire(USAGE_LOG2) ?? void 0;
4156
+ const usageSnapshot = readLatestUsageSnapshotForWire(USAGE_LOG) ?? void 0;
4146
4157
  const planTier = await getPlanTier(PROFILE_CACHE).catch(() => null) ?? void 0;
4147
4158
  const cyclePeaks = await buildCyclePeaksForPush(planTier, loadCalibrationCurve2);
4148
4159
  if (rollups.length === 0) {
@@ -5057,28 +5068,28 @@ function buildEntries(sessionDetail) {
5057
5068
  }
5058
5069
 
5059
5070
  // ../entries/dist/fs.js
5071
+ init_fs();
5060
5072
  import { readFileSync as readFileSync7, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, renameSync as renameSync2, existsSync as existsSync4 } from "node:fs";
5061
5073
  import { randomBytes } from "node:crypto";
5062
- import { join as join6 } from "node:path";
5063
- import { homedir as homedir6 } from "node:os";
5074
+ import { join as join4 } from "node:path";
5064
5075
 
5065
5076
  // ../entries/dist/digest-fs.js
5077
+ init_fs();
5066
5078
  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 join5 } from "node:path";
5068
- import { homedir as homedir5 } from "node:os";
5079
+ import { dirname as dirname4, join as join3 } from "node:path";
5069
5080
  var digestsDirCached = null;
5070
5081
  function digestsDir() {
5071
5082
  if (digestsDirCached)
5072
5083
  return digestsDirCached;
5073
5084
  const envOverride = process.env.CCLENS_DIGESTS_DIR;
5074
- digestsDirCached = envOverride ?? join5(homedir5(), ".cclens", "digests");
5085
+ digestsDirCached = envOverride ?? cclensPath("digests");
5075
5086
  return digestsDirCached;
5076
5087
  }
5077
5088
  function dayDigestPath(date) {
5078
- return join5(digestsDir(), "day", `${date}.json`);
5089
+ return join3(digestsDir(), "day", `${date}.json`);
5079
5090
  }
5080
5091
  function weekDigestPath(monday) {
5081
- return join5(digestsDir(), "week", `${monday}.json`);
5092
+ return join3(digestsDir(), "week", `${monday}.json`);
5082
5093
  }
5083
5094
  function writeDayDigest(digest) {
5084
5095
  const final = dayDigestPath(digest.key);
@@ -5162,11 +5173,11 @@ function entriesDir() {
5162
5173
  if (entriesDirCached)
5163
5174
  return entriesDirCached;
5164
5175
  const envOverride = process.env.CCLENS_ENTRIES_DIR;
5165
- entriesDirCached = envOverride ?? join6(homedir6(), ".cclens", "entries");
5176
+ entriesDirCached = envOverride ?? cclensPath("entries");
5166
5177
  return entriesDirCached;
5167
5178
  }
5168
5179
  function pathFor(sessionId, localDay) {
5169
- return join6(entriesDir(), `${entryKey(sessionId, localDay)}.json`);
5180
+ return join4(entriesDir(), `${entryKey(sessionId, localDay)}.json`);
5170
5181
  }
5171
5182
  function tmpPathFor(final) {
5172
5183
  return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
@@ -5239,14 +5250,14 @@ function listEntriesForDay(localDay) {
5239
5250
  }
5240
5251
 
5241
5252
  // src/perception/state.ts
5253
+ init_fs();
5242
5254
  import { existsSync as existsSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, renameSync as renameSync3 } from "node:fs";
5243
- import { dirname as dirname5, join as join7 } from "node:path";
5244
- import { homedir as homedir7 } from "node:os";
5255
+ import { dirname as dirname5 } from "node:path";
5245
5256
  var STALE_MS = 15 * 60 * 1e3;
5246
5257
  var pathCached = null;
5247
5258
  function statePath() {
5248
5259
  if (pathCached) return pathCached;
5249
- pathCached = join7(homedir7(), ".cclens", "perception-state.json");
5260
+ pathCached = cclensPath("perception-state.json");
5250
5261
  return pathCached;
5251
5262
  }
5252
5263
  function readState() {
@@ -5296,17 +5307,17 @@ function updateCheckpoint(jsonlPath, cp) {
5296
5307
 
5297
5308
  // src/perception/scan.ts
5298
5309
  import { readdirSync as readdirSync3 } from "node:fs";
5299
- import { join as join8 } from "node:path";
5300
- import { homedir as homedir8 } from "node:os";
5310
+ import { join as join5 } from "node:path";
5311
+ import { homedir as homedir2 } from "node:os";
5301
5312
  async function listAllSessionJsonls(root) {
5302
- const projectsRoot = root ?? join8(homedir8(), ".claude", "projects");
5313
+ const projectsRoot = root ?? join5(homedir2(), ".claude", "projects");
5303
5314
  const out = [];
5304
5315
  try {
5305
5316
  for (const project of readdirSync3(projectsRoot)) {
5306
- const dir = join8(projectsRoot, project);
5317
+ const dir = join5(projectsRoot, project);
5307
5318
  try {
5308
5319
  for (const f of readdirSync3(dir)) {
5309
- if (f.endsWith(".jsonl")) out.push(join8(dir, f));
5320
+ if (f.endsWith(".jsonl")) out.push(join5(dir, f));
5310
5321
  }
5311
5322
  } catch {
5312
5323
  }
@@ -9547,16 +9558,332 @@ ${turns || "(none \u2014 the user text was filtered out as non-human)"}`;
9547
9558
  var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
9548
9559
 
9549
9560
  // ../entries/dist/llm-runner.js
9561
+ init_fs();
9550
9562
  import { spawn } from "node:child_process";
9551
- import { mkdirSync as mkdirSync8, appendFileSync as appendFileSync3, writeFileSync as writeFileSync7, existsSync as existsSync6 } from "node:fs";
9552
- import { homedir as homedir9 } from "node:os";
9553
- import { join as join9 } from "node:path";
9563
+ import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync8, existsSync as existsSync7 } from "node:fs";
9564
+ import { join as join7 } from "node:path";
9554
9565
  import { randomUUID as randomUUID2 } from "node:crypto";
9555
- var RUNS_DIR = join9(homedir9(), ".cclens", "llm-runs");
9566
+
9567
+ // ../entries/dist/tmux-runner.js
9568
+ 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";
9569
+ import { join as join6 } from "node:path";
9570
+ import { homedir as homedir3 } from "node:os";
9571
+ import { spawnSync } from "node:child_process";
9572
+ var TmuxUnavailableError = class extends Error {
9573
+ constructor(message) {
9574
+ super(message);
9575
+ this.name = "TmuxUnavailableError";
9576
+ }
9577
+ };
9578
+ var TmuxRunError = class extends Error {
9579
+ constructor(message) {
9580
+ super(message);
9581
+ this.name = "TmuxRunError";
9582
+ }
9583
+ };
9584
+ function which(bin) {
9585
+ const r = spawnSync("/usr/bin/env", ["which", bin], { encoding: "utf8" });
9586
+ if (r.status === 0)
9587
+ return r.stdout.trim() || void 0;
9588
+ return void 0;
9589
+ }
9590
+ function tmuxRunnerAvailable() {
9591
+ if (!which("tmux"))
9592
+ return { ok: false, reason: "tmux not on PATH" };
9593
+ if (!which("claude"))
9594
+ return { ok: false, reason: "claude not on PATH" };
9595
+ return { ok: true };
9596
+ }
9597
+ function runtimeCwd() {
9598
+ const dir = join6(homedir3(), ".cclens", "runtime");
9599
+ if (!existsSync6(dir))
9600
+ mkdirSync8(dir, { recursive: true });
9601
+ return realpathSync(dir);
9602
+ }
9603
+ function ensureRuntimeCwdTrusted(cwd) {
9604
+ const cfgPath = join6(homedir3(), ".claude.json");
9605
+ let cfg;
9606
+ try {
9607
+ cfg = JSON.parse(readFileSync10(cfgPath, "utf8"));
9608
+ } catch {
9609
+ return;
9610
+ }
9611
+ const projects = cfg.projects ?? {};
9612
+ const cur = projects[cwd];
9613
+ if (cur && cur.hasTrustDialogAccepted === true)
9614
+ return;
9615
+ projects[cwd] = {
9616
+ ...cur ?? {},
9617
+ hasTrustDialogAccepted: true
9618
+ };
9619
+ cfg.projects = projects;
9620
+ const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
9621
+ try {
9622
+ writeFileSync7(tmp, JSON.stringify(cfg, null, 2));
9623
+ renameSync4(tmp, cfgPath);
9624
+ } catch {
9625
+ try {
9626
+ unlinkSync2(tmp);
9627
+ } catch {
9628
+ }
9629
+ }
9630
+ }
9631
+ var mutex = Promise.resolve();
9632
+ function runClaudeUnderTmux(args) {
9633
+ const next = mutex.then(() => runClaudeUnderTmuxImpl(args));
9634
+ mutex = next.catch(() => void 0);
9635
+ return next;
9636
+ }
9637
+ async function runClaudeUnderTmuxImpl(args) {
9638
+ const tmuxBin = args.tmuxBin ?? which("tmux");
9639
+ if (!tmuxBin)
9640
+ throw new TmuxUnavailableError("tmux not on PATH");
9641
+ const claudeBin = args.claudeBin ?? which("claude");
9642
+ if (!claudeBin)
9643
+ throw new TmuxUnavailableError("claude not on PATH");
9644
+ if (args.signal?.aborted)
9645
+ throw new TmuxRunError("aborted before spawn");
9646
+ const cwd = runtimeCwd();
9647
+ ensureRuntimeCwdTrusted(cwd);
9648
+ const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
9649
+ const sessionName = `cclens-${runId}`;
9650
+ const systemFile = join6(cwd, `system-${runId}.txt`);
9651
+ const userFile = join6(cwd, `user-${runId}.txt`);
9652
+ const wrapper = join6(cwd, `run-${runId}.sh`);
9653
+ writeFileSync7(systemFile, args.systemPrompt);
9654
+ writeFileSync7(userFile, args.reminder ? `${args.userPrompt}
9655
+
9656
+ ---
9657
+
9658
+ ${args.reminder}` : args.userPrompt);
9659
+ writeFileSync7(wrapper, `#!/bin/bash
9660
+ SYS="$(cat ${shellEscape(systemFile)})"
9661
+ USR="$(cat ${shellEscape(userFile)})"
9662
+ exec ${shellEscape(claudeBin)} \\
9663
+ --model ${shellEscape(args.model)} \\
9664
+ --strict-mcp-config --mcp-config '{"mcpServers":{}}' \\
9665
+ --disable-slash-commands \\
9666
+ --effort medium \\
9667
+ --append-system-prompt "$SYS" \\
9668
+ "$USR"
9669
+ `, { mode: 493 });
9670
+ const existingBefore = snapshotAllTranscripts();
9671
+ const spawn2 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
9672
+ if (spawn2.status !== 0) {
9673
+ cleanup(cwd, runId, tmuxBin, sessionName);
9674
+ throw new TmuxRunError(`tmux new-session failed: ${spawn2.stderr.trim()}`);
9675
+ }
9676
+ const onAbort = () => {
9677
+ try {
9678
+ spawnSync(tmuxBin, ["kill-session", "-t", sessionName], { stdio: "ignore" });
9679
+ } catch {
9680
+ }
9681
+ };
9682
+ args.signal?.addEventListener("abort", onAbort, { once: true });
9683
+ const startMs = Date.now();
9684
+ const timeoutMs = args.timeoutMs ?? 12e4;
9685
+ let lastReportedKb = -1;
9686
+ let lastEmittedLength = 0;
9687
+ try {
9688
+ const transcriptPath = await discoverTranscript(cwd, existingBefore, startMs, timeoutMs, args.signal);
9689
+ while (Date.now() - startMs < timeoutMs) {
9690
+ if (args.signal?.aborted)
9691
+ throw new TmuxRunError("aborted");
9692
+ const { assembled, inputTokens, outputTokens, modelUsed, done } = parseTranscript2(transcriptPath, args.model);
9693
+ if (args.onProgress) {
9694
+ const kb = Math.floor(assembled.length / 1024);
9695
+ if (kb > lastReportedKb) {
9696
+ lastReportedKb = kb;
9697
+ args.onProgress({ bytes: assembled.length, elapsedMs: Date.now() - startMs });
9698
+ }
9699
+ }
9700
+ if (args.onDelta && assembled.length > lastEmittedLength) {
9701
+ const chunk = assembled.slice(lastEmittedLength);
9702
+ lastEmittedLength = assembled.length;
9703
+ try {
9704
+ args.onDelta(chunk);
9705
+ } catch {
9706
+ }
9707
+ }
9708
+ if (done && assembled.length > 0) {
9709
+ return {
9710
+ content: assembled,
9711
+ input_tokens: inputTokens,
9712
+ output_tokens: outputTokens,
9713
+ model: modelUsed
9714
+ };
9715
+ }
9716
+ await sleep(500);
9717
+ }
9718
+ throw new TmuxRunError(`timeout after ${timeoutMs}ms waiting for assistant turn`);
9719
+ } finally {
9720
+ args.signal?.removeEventListener("abort", onAbort);
9721
+ cleanup(cwd, runId, tmuxBin, sessionName);
9722
+ }
9723
+ }
9724
+ function num(v) {
9725
+ return typeof v === "number" ? v : 0;
9726
+ }
9727
+ function sleep(ms) {
9728
+ return new Promise((r) => setTimeout(r, ms));
9729
+ }
9730
+ var PROJECTS_ROOT = () => join6(homedir3(), ".claude", "projects");
9731
+ function snapshotAllTranscripts() {
9732
+ const out = /* @__PURE__ */ new Set();
9733
+ const root = PROJECTS_ROOT();
9734
+ let subs;
9735
+ try {
9736
+ subs = readdirSync4(root);
9737
+ } catch {
9738
+ return out;
9739
+ }
9740
+ for (const sub of subs) {
9741
+ const dir = join6(root, sub);
9742
+ let files;
9743
+ try {
9744
+ files = readdirSync4(dir);
9745
+ } catch {
9746
+ continue;
9747
+ }
9748
+ for (const f of files) {
9749
+ if (f.endsWith(".jsonl"))
9750
+ out.add(join6(dir, f));
9751
+ }
9752
+ }
9753
+ return out;
9754
+ }
9755
+ function readJsonlCwd(path5, maxLines = 8) {
9756
+ let raw;
9757
+ try {
9758
+ raw = readFileSync10(path5, "utf8");
9759
+ } catch {
9760
+ return void 0;
9761
+ }
9762
+ let count = 0;
9763
+ for (const line of raw.split("\n")) {
9764
+ const t = line.trim();
9765
+ if (!t)
9766
+ continue;
9767
+ count++;
9768
+ try {
9769
+ const o = JSON.parse(t);
9770
+ if (typeof o.cwd === "string")
9771
+ return o.cwd;
9772
+ } catch {
9773
+ }
9774
+ if (count >= maxLines)
9775
+ break;
9776
+ }
9777
+ return void 0;
9778
+ }
9779
+ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs, signal) {
9780
+ while (Date.now() - startMs < timeoutMs) {
9781
+ if (signal?.aborted)
9782
+ throw new TmuxRunError("aborted");
9783
+ const root = PROJECTS_ROOT();
9784
+ let subs;
9785
+ try {
9786
+ subs = readdirSync4(root);
9787
+ } catch {
9788
+ subs = [];
9789
+ }
9790
+ for (const sub of subs) {
9791
+ const dir = join6(root, sub);
9792
+ let files;
9793
+ try {
9794
+ files = readdirSync4(dir);
9795
+ } catch {
9796
+ continue;
9797
+ }
9798
+ for (const f of files) {
9799
+ if (!f.endsWith(".jsonl"))
9800
+ continue;
9801
+ const full = join6(dir, f);
9802
+ if (existingBefore.has(full))
9803
+ continue;
9804
+ if (readJsonlCwd(full) === targetCwd)
9805
+ return full;
9806
+ }
9807
+ }
9808
+ await sleep(300);
9809
+ }
9810
+ throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
9811
+ }
9812
+ function parseTranscript2(path5, defaultModel) {
9813
+ let raw;
9814
+ try {
9815
+ raw = readFileSync10(path5, "utf8");
9816
+ } catch {
9817
+ return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
9818
+ }
9819
+ let assembled = "";
9820
+ let inputTokens = 0;
9821
+ let outputTokens = 0;
9822
+ let modelUsed = defaultModel;
9823
+ let done = false;
9824
+ for (const line of raw.split("\n")) {
9825
+ const t = line.trim();
9826
+ if (!t)
9827
+ continue;
9828
+ let o;
9829
+ try {
9830
+ o = JSON.parse(t);
9831
+ } catch {
9832
+ continue;
9833
+ }
9834
+ if (o.type !== "assistant")
9835
+ continue;
9836
+ const m = o.message;
9837
+ if (!m)
9838
+ continue;
9839
+ const mm = m.model;
9840
+ if (mm)
9841
+ modelUsed = mm;
9842
+ const content = m.content;
9843
+ if (Array.isArray(content)) {
9844
+ for (const block of content) {
9845
+ if (block.type === "text" && typeof block.text === "string") {
9846
+ assembled += block.text;
9847
+ }
9848
+ }
9849
+ }
9850
+ const usage = m.usage;
9851
+ if (usage) {
9852
+ inputTokens = num(usage.input_tokens) + num(usage.cache_creation_input_tokens) + num(usage.cache_read_input_tokens);
9853
+ outputTokens = num(usage.output_tokens);
9854
+ }
9855
+ if (m.stop_reason === "end_turn") {
9856
+ done = true;
9857
+ }
9858
+ }
9859
+ return { assembled, inputTokens, outputTokens, modelUsed, done };
9860
+ }
9861
+ function cleanup(cwd, runId, tmuxBin, sessionName) {
9862
+ try {
9863
+ spawnSync(tmuxBin, ["kill-session", "-t", sessionName], { stdio: "ignore" });
9864
+ } catch {
9865
+ }
9866
+ if (process.env.FLEETLENS_TMUX_KEEP_WRAPPER !== "1") {
9867
+ for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
9868
+ try {
9869
+ unlinkSync2(join6(cwd, f));
9870
+ } catch {
9871
+ }
9872
+ }
9873
+ }
9874
+ }
9875
+ function shellEscape(s) {
9876
+ if (/^[A-Za-z0-9_./-]+$/.test(s))
9877
+ return s;
9878
+ return `'${s.replace(/'/g, `'"'"'`)}'`;
9879
+ }
9880
+
9881
+ // ../entries/dist/llm-runner.js
9882
+ var RUNS_DIR = cclensPath("llm-runs");
9556
9883
  function ensureRunsDir() {
9557
- if (!existsSync6(RUNS_DIR)) {
9884
+ if (!existsSync7(RUNS_DIR)) {
9558
9885
  try {
9559
- mkdirSync8(RUNS_DIR, { recursive: true });
9886
+ mkdirSync9(RUNS_DIR, { recursive: true });
9560
9887
  } catch {
9561
9888
  }
9562
9889
  }
@@ -9583,7 +9910,7 @@ function newRunId(kind) {
9583
9910
  return `${ts}_${kind}_${short}`;
9584
9911
  }
9585
9912
  function tracePath(runId) {
9586
- return join9(RUNS_DIR, `${runId}.jsonl`);
9913
+ return join7(RUNS_DIR, `${runId}.jsonl`);
9587
9914
  }
9588
9915
  function safeAppend(path5, line) {
9589
9916
  try {
@@ -9593,11 +9920,84 @@ function safeAppend(path5, line) {
9593
9920
  }
9594
9921
  function safeWrite(path5, line) {
9595
9922
  try {
9596
- writeFileSync7(path5, line);
9923
+ writeFileSync8(path5, line);
9597
9924
  } catch {
9598
9925
  }
9599
9926
  }
9600
- function runClaudeSubprocess(args) {
9927
+ async function runClaudeSubprocess(args) {
9928
+ if (process.env.FLEETLENS_FORCE_PRINT_MODE !== "1") {
9929
+ const avail = tmuxRunnerAvailable();
9930
+ if (avail.ok) {
9931
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
9932
+ const kind = detectKindFromSystemPrompt(args.systemPrompt);
9933
+ const runId = newRunId(kind);
9934
+ const trace = tracePath(runId);
9935
+ ensureRunsDir();
9936
+ safeWrite(trace, JSON.stringify({
9937
+ _meta: {
9938
+ type: "start",
9939
+ run_id: runId,
9940
+ kind,
9941
+ model: args.model,
9942
+ ts: startedAt,
9943
+ runtime: "tmux",
9944
+ user_prompt_chars: args.userPrompt.length,
9945
+ reminder_chars: args.reminder?.length ?? 0
9946
+ }
9947
+ }) + "\n");
9948
+ safeAppend(trace, JSON.stringify({
9949
+ _meta: {
9950
+ type: "payload",
9951
+ run_id: runId,
9952
+ system_prompt: args.systemPrompt,
9953
+ user_prompt: args.userPrompt,
9954
+ reminder: args.reminder ?? null
9955
+ }
9956
+ }) + "\n");
9957
+ try {
9958
+ const startMs = Date.now();
9959
+ const res = await runClaudeUnderTmux({
9960
+ systemPrompt: args.systemPrompt,
9961
+ model: args.model,
9962
+ userPrompt: args.userPrompt,
9963
+ reminder: args.reminder,
9964
+ onProgress: args.onProgress
9965
+ });
9966
+ safeAppend(trace, JSON.stringify({
9967
+ _meta: {
9968
+ type: "end",
9969
+ run_id: runId,
9970
+ runtime: "tmux",
9971
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
9972
+ elapsed_ms: Date.now() - startMs,
9973
+ // tmux runs have no subprocess exit code (the session is killed
9974
+ // by cleanup). Stamp 0 on success so /api/runs renders them
9975
+ // as `ok` rather than `error`.
9976
+ exit_code: 0,
9977
+ content_chars: res.content.length,
9978
+ input_tokens: res.input_tokens,
9979
+ output_tokens: res.output_tokens,
9980
+ model_used: res.model
9981
+ }
9982
+ }) + "\n");
9983
+ return res;
9984
+ } catch (err) {
9985
+ const isExpected = err instanceof TmuxUnavailableError || err instanceof TmuxRunError;
9986
+ safeAppend(trace, JSON.stringify({
9987
+ _meta: {
9988
+ type: "tmux_fallback",
9989
+ run_id: runId,
9990
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
9991
+ error: err.message,
9992
+ expected: isExpected
9993
+ }
9994
+ }) + "\n");
9995
+ }
9996
+ }
9997
+ }
9998
+ return runClaudePrintMode(args);
9999
+ }
10000
+ function runClaudePrintMode(args) {
9601
10001
  return new Promise((resolve, reject) => {
9602
10002
  ensureRunsDir();
9603
10003
  const kind = detectKindFromSystemPrompt(args.systemPrompt);
@@ -9908,29 +10308,29 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
9908
10308
  }
9909
10309
 
9910
10310
  // ../entries/dist/budget.js
9911
- import { appendFileSync as appendFileSync4, readFileSync as readFileSync10, existsSync as existsSync7, mkdirSync as mkdirSync9 } from "node:fs";
9912
- import { dirname as dirname7, join as join10 } from "node:path";
9913
- import { homedir as homedir10 } from "node:os";
10311
+ init_fs();
10312
+ import { appendFileSync as appendFileSync4, readFileSync as readFileSync11, existsSync as existsSync8, mkdirSync as mkdirSync10 } from "node:fs";
10313
+ import { dirname as dirname7 } from "node:path";
9914
10314
  var spendPathCached = null;
9915
10315
  function spendPath() {
9916
10316
  if (spendPathCached)
9917
10317
  return spendPathCached;
9918
- spendPathCached = join10(homedir10(), ".cclens", "llm-spend.jsonl");
10318
+ spendPathCached = cclensPath("llm-spend.jsonl");
9919
10319
  return spendPathCached;
9920
10320
  }
9921
10321
  function appendSpend(record) {
9922
10322
  const p = spendPath();
9923
- mkdirSync9(dirname7(p), { recursive: true });
10323
+ mkdirSync10(dirname7(p), { recursive: true });
9924
10324
  appendFileSync4(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
9925
10325
  }
9926
10326
  function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
9927
10327
  const p = spendPath();
9928
- if (!existsSync7(p))
10328
+ if (!existsSync8(p))
9929
10329
  return 0;
9930
10330
  const year = now.getUTCFullYear();
9931
10331
  const month = now.getUTCMonth();
9932
10332
  let total = 0;
9933
- const raw = readFileSync10(p, "utf8");
10333
+ const raw = readFileSync11(p, "utf8");
9934
10334
  for (const line of raw.split("\n")) {
9935
10335
  if (!line)
9936
10336
  continue;
@@ -9951,9 +10351,8 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
9951
10351
  }
9952
10352
 
9953
10353
  // ../entries/dist/pipeline-lock.js
9954
- import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync2, existsSync as existsSync8, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
9955
- import { join as join11 } from "node:path";
9956
- import { homedir as homedir11 } from "node:os";
10354
+ init_fs();
10355
+ import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, existsSync as existsSync9, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
9957
10356
  var STALE_MS2 = 60 * 1e3;
9958
10357
  var HEARTBEAT_MS = 30 * 1e3;
9959
10358
  var lockPathCached = null;
@@ -9961,11 +10360,11 @@ var heartbeat = null;
9961
10360
  function lockPath() {
9962
10361
  if (lockPathCached)
9963
10362
  return lockPathCached;
9964
- lockPathCached = join11(homedir11(), ".cclens", "llm-interactive.lock");
10363
+ lockPathCached = cclensPath("llm-interactive.lock");
9965
10364
  return lockPathCached;
9966
10365
  }
9967
10366
  function touchLock() {
9968
- writeFileSync8(lockPath(), String(process.pid), "utf8");
10367
+ writeFileSync9(lockPath(), String(process.pid), "utf8");
9969
10368
  }
9970
10369
  function writeInteractiveLock() {
9971
10370
  touchLock();
@@ -9985,7 +10384,7 @@ function removeInteractiveLock() {
9985
10384
  heartbeat = null;
9986
10385
  }
9987
10386
  try {
9988
- unlinkSync2(lockPath());
10387
+ unlinkSync3(lockPath());
9989
10388
  } catch {
9990
10389
  }
9991
10390
  }
@@ -9999,13 +10398,13 @@ function pidAlive(pid) {
9999
10398
  }
10000
10399
  function interactiveLockFresh(nowMs) {
10001
10400
  const p = lockPath();
10002
- if (!existsSync8(p))
10401
+ if (!existsSync9(p))
10003
10402
  return false;
10004
10403
  try {
10005
10404
  const mtime = statSync3(p).mtimeMs;
10006
10405
  if (nowMs - mtime > STALE_MS2)
10007
10406
  return false;
10008
- const pid = Number(readFileSync11(p, "utf8").trim());
10407
+ const pid = Number(readFileSync12(p, "utf8").trim());
10009
10408
  if (!Number.isFinite(pid) || pid <= 0)
10010
10409
  return false;
10011
10410
  if (!pidAlive(pid))
@@ -10020,9 +10419,8 @@ function interactiveLockFresh(nowMs) {
10020
10419
  var THIRTY_MIN_MS = 30 * 60 * 1e3;
10021
10420
 
10022
10421
  // ../entries/dist/settings.js
10023
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, renameSync as renameSync4, chmodSync as chmodSync2, mkdirSync as mkdirSync10, existsSync as existsSync9 } from "node:fs";
10024
- import { dirname as dirname8, join as join12 } from "node:path";
10025
- import { homedir as homedir12 } from "node:os";
10422
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync10 } from "node:fs";
10423
+ init_fs();
10026
10424
  var DEFAULT_SETTINGS = {
10027
10425
  ai_features: {
10028
10426
  enabled: true,
@@ -10036,7 +10434,7 @@ var settingsPathCached = null;
10036
10434
  function settingsPath() {
10037
10435
  if (settingsPathCached)
10038
10436
  return settingsPathCached;
10039
- settingsPathCached = join12(homedir12(), ".cclens", "settings.json");
10437
+ settingsPathCached = cclensPath("settings.json");
10040
10438
  return settingsPathCached;
10041
10439
  }
10042
10440
  function fromDisk(d) {
@@ -10053,10 +10451,10 @@ function fromDisk(d) {
10053
10451
  }
10054
10452
  function readSettings() {
10055
10453
  const p = settingsPath();
10056
- if (!existsSync9(p))
10454
+ if (!existsSync10(p))
10057
10455
  return DEFAULT_SETTINGS;
10058
10456
  try {
10059
- const raw = readFileSync12(p, "utf8");
10457
+ const raw = readFileSync13(p, "utf8");
10060
10458
  return fromDisk(JSON.parse(raw));
10061
10459
  } catch {
10062
10460
  return DEFAULT_SETTINGS;
@@ -12779,11 +13177,10 @@ async function backfillYesterdayDigest(opts = {}) {
12779
13177
  }
12780
13178
 
12781
13179
  // src/daemon-worker.ts
12782
- var STATE_DIR = join13(homedir13(), ".cclens");
12783
- var USAGE_LOG3 = join13(STATE_DIR, "usage.jsonl");
12784
- var DAEMON_LOG = join13(STATE_DIR, "daemon.log");
13180
+ var USAGE_LOG2 = cclensPath("usage.jsonl");
13181
+ var DAEMON_LOG = cclensPath("daemon.log");
12785
13182
  var WATCHDOG_INTERVAL_MS = 5 * 1e3;
12786
- mkdirSync11(dirname9(USAGE_LOG3), { recursive: true });
13183
+ mkdirSync12(dirname8(USAGE_LOG2), { recursive: true });
12787
13184
  function log2(level, message) {
12788
13185
  const line = `${(/* @__PURE__ */ new Date()).toISOString()} ${level.toUpperCase()} ${message}
12789
13186
  `;
@@ -12836,7 +13233,7 @@ async function tick() {
12836
13233
  seven_day_cowork: null,
12837
13234
  extra_usage: null
12838
13235
  };
12839
- appendSnapshot(USAGE_LOG3, snapshot);
13236
+ appendSnapshot(USAGE_LOG2, snapshot);
12840
13237
  log2(
12841
13238
  "info",
12842
13239
  `${source.kind} snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
@@ -12847,7 +13244,7 @@ async function tick() {
12847
13244
  }
12848
13245
  try {
12849
13246
  const snapshot = await fetchUsage();
12850
- appendSnapshot(USAGE_LOG3, snapshot);
13247
+ appendSnapshot(USAGE_LOG2, snapshot);
12851
13248
  log2(
12852
13249
  "info",
12853
13250
  `claude-code snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
@@ -12873,7 +13270,7 @@ function scheduleAfter(now, outcome) {
12873
13270
  }
12874
13271
  nextPollAtMs = now + currentIntervalMs;
12875
13272
  }
12876
- function sleep(ms) {
13273
+ function sleep2(ms) {
12877
13274
  return new Promise((resolve) => setTimeout(resolve, ms));
12878
13275
  }
12879
13276
  async function runLoop() {
@@ -12906,7 +13303,7 @@ async function runLoop() {
12906
13303
  }
12907
13304
  await runTeamSync(log2);
12908
13305
  }
12909
- await sleep(WATCHDOG_INTERVAL_MS);
13306
+ await sleep2(WATCHDOG_INTERVAL_MS);
12910
13307
  }
12911
13308
  }
12912
13309
  log2(