fleetlens 0.15.3 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/app-path-routes-manifest.json +2 -0
- 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/routes-manifest.json +12 -0
- 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 +1 -1
- package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/menubar/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/menubar/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/menubar/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/menubar/route.js +6 -0
- package/app/apps/web/.next/server/app/api/menubar/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/menubar/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/menubar/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/pdf/[key]/route.js +1 -1
- package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/credentials/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js +10 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/settings/route.js +4 -4
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/page.js +1 -1
- package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/page.js +1 -1
- package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/settings/page.js +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/team/onboarding/page.js +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app-paths-manifest.json +2 -0
- package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_settings_credentials_route_actions_04an_i2.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__05z0pcw._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_nle98._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0b5r~-1._.js +3 -0
- package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0a0~7d6._.js → [root-of-the-server]__0t7i-hy._.js} +2 -2
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_menubar_route_actions_0xep8_i.js +3 -0
- package/app/apps/web/.next/server/chunks/{node_modules_next_036my~r._.js → node_modules_next_04~_e52._.js} +5 -5
- package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +14 -14
- package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0g-tomj._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0nr2~y1._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/{_0xu2pvc._.js → _0k8yioi._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0~aj0~u._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{apps_web_components_0txtsv5._.js → apps_web_components_0x014hn._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
- package/app/apps/web/.next/server/functions-config-manifest.json +2 -0
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/0-z49mtd-zwgv.js +1 -0
- package/app/apps/web/.next/static/chunks/043slkg3juwck.js +1 -0
- package/app/apps/web/.next/static/chunks/{0_ujxc0.z66xb.js → 0g0hv.dt-de9g.js} +3 -3
- package/app/apps/web/.next/static/chunks/0t2on1dhydyb2.css +1 -0
- package/app/apps/web/app/api/menubar/route.ts +66 -0
- package/app/apps/web/app/api/settings/credentials/route.ts +45 -0
- package/app/apps/web/app/layout.tsx +2 -0
- package/app/apps/web/app/settings/page.tsx +26 -0
- package/app/apps/web/app/usage/page.tsx +80 -0
- package/app/apps/web/components/menubar-install-banner.tsx +117 -0
- package/app/apps/web/components/menubar-install.tsx +107 -0
- package/app/apps/web/components/zai-credentials-form.tsx +116 -0
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/menubar-data.ts +50 -0
- package/app/apps/web/lib/usage-data.ts +4 -0
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +321 -152
- package/dist/index.js +597 -173
- package/package.json +3 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__065lib8._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0c00i76._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0q2x4a~._.js +0 -3
- package/app/apps/web/.next/static/chunks/00a9oyw~h5i1p.js +0 -1
- package/app/apps/web/.next/static/chunks/040s42ypidk7s.css +0 -1
- package/app/apps/web/.next/static/chunks/0bhwd68o~-xc_.js +0 -1
- /package/app/apps/web/.next/static/{lIz-6F0SEIL9sgFO3XTJp → nmAGY0LiBgXuibWTKZ1RD}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{lIz-6F0SEIL9sgFO3XTJp → nmAGY0LiBgXuibWTKZ1RD}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{lIz-6F0SEIL9sgFO3XTJp → nmAGY0LiBgXuibWTKZ1RD}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -675,7 +675,7 @@ function getAgentMetadata(kind) {
|
|
|
675
675
|
function isAgentKind(s) {
|
|
676
676
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
677
677
|
}
|
|
678
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
678
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
679
679
|
var init_agent_metadata = __esm({
|
|
680
680
|
"../parser/dist/agent-metadata.js"() {
|
|
681
681
|
"use strict";
|
|
@@ -714,12 +714,20 @@ var init_agent_metadata = __esm({
|
|
|
714
714
|
accentColor: "rgb(217, 119, 87)",
|
|
715
715
|
iconChar: "\u2318"
|
|
716
716
|
};
|
|
717
|
+
ZAI_METADATA = {
|
|
718
|
+
kind: "zai",
|
|
719
|
+
displayName: "Z.ai",
|
|
720
|
+
shortLabel: "Z.ai",
|
|
721
|
+
accentColor: "rgb(59, 130, 246)",
|
|
722
|
+
iconChar: "Z"
|
|
723
|
+
};
|
|
717
724
|
agentMetadata = [
|
|
718
725
|
CLAUDE_CODE_METADATA,
|
|
719
726
|
CODEX_METADATA,
|
|
720
727
|
GEMINI_METADATA,
|
|
721
728
|
ANTIGRAVITY_METADATA,
|
|
722
|
-
COWORK_METADATA
|
|
729
|
+
COWORK_METADATA,
|
|
730
|
+
ZAI_METADATA
|
|
723
731
|
];
|
|
724
732
|
KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
|
|
725
733
|
}
|
|
@@ -3172,13 +3180,16 @@ async function getLatestCodexUsage(opts = {}) {
|
|
|
3172
3180
|
const fiveResetUnix = numberOf(primary?.resets_at);
|
|
3173
3181
|
const sevenResetUnix = numberOf(secondary?.resets_at);
|
|
3174
3182
|
const planType = typeof rl.plan_type === "string" ? rl.plan_type : null;
|
|
3183
|
+
const nowMs = Date.now();
|
|
3184
|
+
const fiveExpired = fiveResetUnix !== void 0 && nowMs > fiveResetUnix * 1e3;
|
|
3185
|
+
const sevenExpired = sevenResetUnix !== void 0 && nowMs > sevenResetUnix * 1e3;
|
|
3175
3186
|
return {
|
|
3176
3187
|
five_hour: {
|
|
3177
|
-
utilization: fivePct ?? null,
|
|
3188
|
+
utilization: fiveExpired ? 0 : fivePct ?? null,
|
|
3178
3189
|
resets_at: fiveResetUnix !== void 0 ? new Date(fiveResetUnix * 1e3).toISOString() : null
|
|
3179
3190
|
},
|
|
3180
3191
|
seven_day: {
|
|
3181
|
-
utilization: sevenPct ?? null,
|
|
3192
|
+
utilization: sevenExpired ? 0 : sevenPct ?? null,
|
|
3182
3193
|
resets_at: sevenResetUnix !== void 0 ? new Date(sevenResetUnix * 1e3).toISOString() : null
|
|
3183
3194
|
},
|
|
3184
3195
|
plan_type: planType,
|
|
@@ -4516,6 +4527,7 @@ __export(fs_exports, {
|
|
|
4516
4527
|
RICH_ROLLUP_SCHEMA_VERSION: () => RICH_ROLLUP_SCHEMA_VERSION,
|
|
4517
4528
|
agentSources: () => agentSources,
|
|
4518
4529
|
antigravitySessionLocalDay: () => antigravitySessionLocalDay,
|
|
4530
|
+
appendUsageSnapshot: () => appendUsageSnapshot,
|
|
4519
4531
|
buildCalibrationCurve: () => buildCalibrationCurve,
|
|
4520
4532
|
cacheStats: () => cacheStats,
|
|
4521
4533
|
cclensHome: () => cclensHome,
|
|
@@ -4549,6 +4561,7 @@ __export(fs_exports, {
|
|
|
4549
4561
|
loadTeamForSession: () => loadTeamForSession,
|
|
4550
4562
|
loadUsageByDay: () => loadUsageByDay,
|
|
4551
4563
|
loadWorkflowAgentDetail: () => loadWorkflowAgentDetail,
|
|
4564
|
+
pruneUsageAgent: () => pruneUsageAgent,
|
|
4552
4565
|
readGitFolder: () => readGitFolder,
|
|
4553
4566
|
readJsonlFile: () => readJsonlFile,
|
|
4554
4567
|
readTeamConfig: () => readTeamConfig,
|
|
@@ -4558,7 +4571,7 @@ __export(fs_exports, {
|
|
|
4558
4571
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
4559
4572
|
writeTeamConfig: () => writeTeamConfig
|
|
4560
4573
|
});
|
|
4561
|
-
import { promises as fs6 } from "node:fs";
|
|
4574
|
+
import { promises as fs6, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
|
|
4562
4575
|
import os6 from "node:os";
|
|
4563
4576
|
import path6 from "node:path";
|
|
4564
4577
|
function cclensHome() {
|
|
@@ -4604,6 +4617,27 @@ async function getAnySession(id) {
|
|
|
4604
4617
|
function usageLogPath() {
|
|
4605
4618
|
return cclensPath("usage.jsonl");
|
|
4606
4619
|
}
|
|
4620
|
+
function appendUsageSnapshot(snapshot) {
|
|
4621
|
+
const p = usageLogPath();
|
|
4622
|
+
mkdirSync3(path6.dirname(p), { recursive: true });
|
|
4623
|
+
appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
|
|
4624
|
+
}
|
|
4625
|
+
function pruneUsageAgent(agent) {
|
|
4626
|
+
const p = usageLogPath();
|
|
4627
|
+
if (!existsSync2(p))
|
|
4628
|
+
return;
|
|
4629
|
+
const kept = readFileSync4(p, "utf8").split("\n").filter((line) => {
|
|
4630
|
+
if (!line.trim())
|
|
4631
|
+
return false;
|
|
4632
|
+
try {
|
|
4633
|
+
return JSON.parse(line).agent !== agent;
|
|
4634
|
+
} catch {
|
|
4635
|
+
return true;
|
|
4636
|
+
}
|
|
4637
|
+
});
|
|
4638
|
+
mkdirSync3(path6.dirname(p), { recursive: true });
|
|
4639
|
+
writeFileSync3(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
4640
|
+
}
|
|
4607
4641
|
async function loadUsageByDay(start2, end) {
|
|
4608
4642
|
let raw;
|
|
4609
4643
|
try {
|
|
@@ -4909,7 +4943,7 @@ __export(server_exports, {
|
|
|
4909
4943
|
import { spawn } from "node:child_process";
|
|
4910
4944
|
import { join as join3, dirname as dirname3 } from "node:path";
|
|
4911
4945
|
import { fileURLToPath } from "node:url";
|
|
4912
|
-
import { existsSync as
|
|
4946
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
4913
4947
|
import { homedir as homedir2 } from "node:os";
|
|
4914
4948
|
function appDir() {
|
|
4915
4949
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
@@ -4924,7 +4958,7 @@ function getServerStatus() {
|
|
|
4924
4958
|
return { running: false };
|
|
4925
4959
|
}
|
|
4926
4960
|
function isServerStale(status2) {
|
|
4927
|
-
return status2.running === true && status2.version !== "0.15.
|
|
4961
|
+
return status2.running === true && status2.version !== "0.15.4";
|
|
4928
4962
|
}
|
|
4929
4963
|
async function ensureCurrentServer(opts = {}) {
|
|
4930
4964
|
const status2 = getServerStatus();
|
|
@@ -4958,7 +4992,7 @@ async function ensureCurrentServer(opts = {}) {
|
|
|
4958
4992
|
async function startServer(opts = {}) {
|
|
4959
4993
|
const port = opts.port ?? (parseInt(process.env.CCLENS_PORT ?? "", 10) || DEFAULT_PORT);
|
|
4960
4994
|
const serverJs = join3(appDir(), "server.js");
|
|
4961
|
-
if (!
|
|
4995
|
+
if (!existsSync3(serverJs)) {
|
|
4962
4996
|
throw new Error(`Server not found at ${serverJs}. Reinstall with: npm install -g fleetlens`);
|
|
4963
4997
|
}
|
|
4964
4998
|
const portInUse = await checkPort(port);
|
|
@@ -4980,7 +5014,7 @@ async function startServer(opts = {}) {
|
|
|
4980
5014
|
});
|
|
4981
5015
|
child.unref();
|
|
4982
5016
|
const pid = child.pid;
|
|
4983
|
-
writePid(PID_FILE, pid, port, "0.15.
|
|
5017
|
+
writePid(PID_FILE, pid, port, "0.15.4");
|
|
4984
5018
|
await waitForHealth(`http://localhost:${port}`, 3e4);
|
|
4985
5019
|
return { pid, port };
|
|
4986
5020
|
}
|
|
@@ -5049,17 +5083,18 @@ __export(storage_exports, {
|
|
|
5049
5083
|
appendSnapshot: () => appendSnapshot,
|
|
5050
5084
|
latestClaudeCodeSnapshot: () => latestClaudeCodeSnapshot,
|
|
5051
5085
|
latestSnapshot: () => latestSnapshot,
|
|
5086
|
+
pruneAgent: () => pruneAgent,
|
|
5052
5087
|
readSnapshots: () => readSnapshots
|
|
5053
5088
|
});
|
|
5054
|
-
import { appendFileSync, mkdirSync as
|
|
5089
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync4 } from "node:fs";
|
|
5055
5090
|
import { dirname as dirname4 } from "node:path";
|
|
5056
5091
|
function appendSnapshot(filePath, snapshot) {
|
|
5057
|
-
|
|
5058
|
-
|
|
5092
|
+
mkdirSync4(dirname4(filePath), { recursive: true });
|
|
5093
|
+
appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
5059
5094
|
}
|
|
5060
5095
|
function readSnapshots(filePath) {
|
|
5061
|
-
if (!
|
|
5062
|
-
const content =
|
|
5096
|
+
if (!existsSync4(filePath)) return [];
|
|
5097
|
+
const content = readFileSync5(filePath, "utf8");
|
|
5063
5098
|
const snapshots = [];
|
|
5064
5099
|
for (const line of content.split("\n")) {
|
|
5065
5100
|
if (!line.trim()) continue;
|
|
@@ -5074,6 +5109,19 @@ function latestSnapshot(filePath) {
|
|
|
5074
5109
|
const all = readSnapshots(filePath);
|
|
5075
5110
|
return all.length > 0 ? all[all.length - 1] : null;
|
|
5076
5111
|
}
|
|
5112
|
+
function pruneAgent(filePath, agent) {
|
|
5113
|
+
if (!existsSync4(filePath)) return;
|
|
5114
|
+
const kept = readFileSync5(filePath, "utf8").split("\n").filter((line) => {
|
|
5115
|
+
if (!line.trim()) return false;
|
|
5116
|
+
try {
|
|
5117
|
+
return JSON.parse(line).agent !== agent;
|
|
5118
|
+
} catch {
|
|
5119
|
+
return true;
|
|
5120
|
+
}
|
|
5121
|
+
});
|
|
5122
|
+
mkdirSync4(dirname4(filePath), { recursive: true });
|
|
5123
|
+
writeFileSync4(filePath, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
5124
|
+
}
|
|
5077
5125
|
function latestClaudeCodeSnapshot(filePath) {
|
|
5078
5126
|
const all = readSnapshots(filePath);
|
|
5079
5127
|
for (let i = all.length - 1; i >= 0; i--) {
|
|
@@ -5099,7 +5147,7 @@ __export(daemon_exports, {
|
|
|
5099
5147
|
import { spawn as spawn2 } from "node:child_process";
|
|
5100
5148
|
import { join as join4, dirname as dirname5 } from "node:path";
|
|
5101
5149
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
5102
|
-
import { existsSync as
|
|
5150
|
+
import { existsSync as existsSync5, statSync as statSync2, readFileSync as readFileSync6 } from "node:fs";
|
|
5103
5151
|
function startDaemonSilent() {
|
|
5104
5152
|
cleanStalePid(DAEMON_PID, DAEMON_MARKERS);
|
|
5105
5153
|
const existing = readPid(DAEMON_PID);
|
|
@@ -5107,7 +5155,7 @@ function startDaemonSilent() {
|
|
|
5107
5155
|
return { started: false, pid: existing.pid, alreadyRunning: true };
|
|
5108
5156
|
}
|
|
5109
5157
|
const script = workerPath();
|
|
5110
|
-
if (!
|
|
5158
|
+
if (!existsSync5(script)) {
|
|
5111
5159
|
return {
|
|
5112
5160
|
started: false,
|
|
5113
5161
|
pid: null,
|
|
@@ -5141,7 +5189,7 @@ function getDaemonStatusInfo() {
|
|
|
5141
5189
|
const running = entry !== null && isProcessAlive(entry.pid, DAEMON_MARKERS);
|
|
5142
5190
|
const latest = latestSnapshot(USAGE_LOG);
|
|
5143
5191
|
const lastSnapshotAgeMs = latest ? Date.now() - new Date(latest.captured_at).getTime() : null;
|
|
5144
|
-
const usageLogSize =
|
|
5192
|
+
const usageLogSize = existsSync5(USAGE_LOG) ? statSync2(USAGE_LOG).size : null;
|
|
5145
5193
|
return {
|
|
5146
5194
|
running,
|
|
5147
5195
|
pid: running ? entry.pid : null,
|
|
@@ -5217,11 +5265,11 @@ function daemonStatus() {
|
|
|
5217
5265
|
}
|
|
5218
5266
|
}
|
|
5219
5267
|
function daemonLogs() {
|
|
5220
|
-
if (!
|
|
5268
|
+
if (!existsSync5(DAEMON_LOG)) {
|
|
5221
5269
|
console.log("No daemon logs yet.");
|
|
5222
5270
|
return;
|
|
5223
5271
|
}
|
|
5224
|
-
const content =
|
|
5272
|
+
const content = readFileSync6(DAEMON_LOG, "utf8");
|
|
5225
5273
|
const lines = content.trim().split("\n").slice(-20);
|
|
5226
5274
|
for (const line of lines) process.stdout.write(line + "\n");
|
|
5227
5275
|
}
|
|
@@ -5241,7 +5289,7 @@ var init_daemon = __esm({
|
|
|
5241
5289
|
|
|
5242
5290
|
// src/updater.ts
|
|
5243
5291
|
import { execSync, spawnSync } from "node:child_process";
|
|
5244
|
-
import { existsSync as
|
|
5292
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7, realpathSync as realpathSync2 } from "node:fs";
|
|
5245
5293
|
import { dirname as dirname6, join as join5 } from "node:path";
|
|
5246
5294
|
function shouldUpdate(local, remote) {
|
|
5247
5295
|
const l = local.split(".").map(Number);
|
|
@@ -5285,7 +5333,7 @@ function verifyInstalledVersion() {
|
|
|
5285
5333
|
timeout: 5e3
|
|
5286
5334
|
}).trim();
|
|
5287
5335
|
const pkgPath = join5(globalRoot, PACKAGE_NAME, "package.json");
|
|
5288
|
-
const pkg = JSON.parse(
|
|
5336
|
+
const pkg = JSON.parse(readFileSync7(pkgPath, "utf8"));
|
|
5289
5337
|
if (!pkg.version) {
|
|
5290
5338
|
return { ok: false, reason: `no version field in ${pkgPath}` };
|
|
5291
5339
|
}
|
|
@@ -5349,9 +5397,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
5349
5397
|
console.warn(
|
|
5350
5398
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
5351
5399
|
);
|
|
5352
|
-
} else if (verify.installedVersion !== "0.15.
|
|
5400
|
+
} else if (verify.installedVersion !== "0.15.4") {
|
|
5353
5401
|
console.log(
|
|
5354
|
-
` \u2192 This process is still running ${"0.15.
|
|
5402
|
+
` \u2192 This process is still running ${"0.15.4"}. Next invocation will use ${verify.installedVersion}.`
|
|
5355
5403
|
);
|
|
5356
5404
|
}
|
|
5357
5405
|
}
|
|
@@ -5370,7 +5418,7 @@ function reExec() {
|
|
|
5370
5418
|
let script = process.argv[1] ?? "";
|
|
5371
5419
|
if (verify.ok) {
|
|
5372
5420
|
const candidate = join5(verify.installedPath, "dist", "index.js");
|
|
5373
|
-
if (
|
|
5421
|
+
if (existsSync6(candidate)) script = candidate;
|
|
5374
5422
|
}
|
|
5375
5423
|
const result = spawnSync(process.argv[0], [script, ...process.argv.slice(2)], {
|
|
5376
5424
|
stdio: "inherit",
|
|
@@ -5386,14 +5434,14 @@ async function getUpdateAvailability() {
|
|
|
5386
5434
|
if (isDevMode()) return null;
|
|
5387
5435
|
const latest = await fetchLatestVersion();
|
|
5388
5436
|
if (latest === null) return {
|
|
5389
|
-
current: "0.15.
|
|
5437
|
+
current: "0.15.4",
|
|
5390
5438
|
latest: null,
|
|
5391
5439
|
updateAvailable: false
|
|
5392
5440
|
};
|
|
5393
5441
|
return {
|
|
5394
|
-
current: "0.15.
|
|
5442
|
+
current: "0.15.4",
|
|
5395
5443
|
latest,
|
|
5396
|
-
updateAvailable: shouldUpdate("0.15.
|
|
5444
|
+
updateAvailable: shouldUpdate("0.15.4", latest)
|
|
5397
5445
|
};
|
|
5398
5446
|
}
|
|
5399
5447
|
async function checkForUpdate() {
|
|
@@ -5483,7 +5531,7 @@ async function restartServices(state) {
|
|
|
5483
5531
|
}
|
|
5484
5532
|
async function forceUpdate() {
|
|
5485
5533
|
const latest = await fetchLatestVersion();
|
|
5486
|
-
const current = "0.15.
|
|
5534
|
+
const current = "0.15.4";
|
|
5487
5535
|
if (latest === null) {
|
|
5488
5536
|
console.error("Could not reach npm registry. Check your network.");
|
|
5489
5537
|
process.exit(1);
|
|
@@ -5535,7 +5583,7 @@ __export(autostart_exports, {
|
|
|
5535
5583
|
maybePromptAutostart: () => maybePromptAutostart,
|
|
5536
5584
|
recordOptOut: () => recordOptOut
|
|
5537
5585
|
});
|
|
5538
|
-
import { existsSync as
|
|
5586
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5, rmSync, readFileSync as readFileSync8, realpathSync as realpathSync3 } from "node:fs";
|
|
5539
5587
|
import { homedir as homedir3 } from "node:os";
|
|
5540
5588
|
import { join as join6, dirname as dirname7 } from "node:path";
|
|
5541
5589
|
import { execFile } from "node:child_process";
|
|
@@ -5548,14 +5596,14 @@ function isMac() {
|
|
|
5548
5596
|
return process.platform === "darwin";
|
|
5549
5597
|
}
|
|
5550
5598
|
function isAutostartInstalled() {
|
|
5551
|
-
return isMac() &&
|
|
5599
|
+
return isMac() && existsSync7(plistPath());
|
|
5552
5600
|
}
|
|
5553
5601
|
function isStalePlistContent(content) {
|
|
5554
5602
|
return content.includes("<string>daemon</string>");
|
|
5555
5603
|
}
|
|
5556
5604
|
function installedPlistIsStale() {
|
|
5557
5605
|
try {
|
|
5558
|
-
return isStalePlistContent(
|
|
5606
|
+
return isStalePlistContent(readFileSync8(plistPath(), "utf8"));
|
|
5559
5607
|
} catch {
|
|
5560
5608
|
return false;
|
|
5561
5609
|
}
|
|
@@ -5606,8 +5654,8 @@ async function installAutostart() {
|
|
|
5606
5654
|
const scriptPath = resolveScriptPath();
|
|
5607
5655
|
const logPath = cclensPath("daemon-autostart.log");
|
|
5608
5656
|
const p = plistPath();
|
|
5609
|
-
|
|
5610
|
-
|
|
5657
|
+
mkdirSync5(dirname7(p), { recursive: true });
|
|
5658
|
+
writeFileSync5(p, buildPlist({ nodePath, scriptPath, logPath }), "utf8");
|
|
5611
5659
|
await runLaunchctl(["unload", p]).catch(() => {
|
|
5612
5660
|
});
|
|
5613
5661
|
await runLaunchctl(["load", "-w", p]);
|
|
@@ -5627,7 +5675,7 @@ async function uninstallAutostart() {
|
|
|
5627
5675
|
}
|
|
5628
5676
|
const p = plistPath();
|
|
5629
5677
|
recordOptOut();
|
|
5630
|
-
if (!
|
|
5678
|
+
if (!existsSync7(p)) {
|
|
5631
5679
|
console.log("Autostart is not installed \u2014 nothing to remove. Noted your opt-out; team join won't enable it.");
|
|
5632
5680
|
return;
|
|
5633
5681
|
}
|
|
@@ -5660,7 +5708,7 @@ async function statusAutostart() {
|
|
|
5660
5708
|
return;
|
|
5661
5709
|
}
|
|
5662
5710
|
const p = plistPath();
|
|
5663
|
-
const present =
|
|
5711
|
+
const present = existsSync7(p);
|
|
5664
5712
|
let loaded = false;
|
|
5665
5713
|
try {
|
|
5666
5714
|
const { stdout } = await execFileAsync("launchctl", ["list"]);
|
|
@@ -5675,7 +5723,7 @@ function promptFlagPath() {
|
|
|
5675
5723
|
}
|
|
5676
5724
|
function readFlags() {
|
|
5677
5725
|
try {
|
|
5678
|
-
return JSON.parse(
|
|
5726
|
+
return JSON.parse(readFileSync8(promptFlagPath(), "utf8"));
|
|
5679
5727
|
} catch {
|
|
5680
5728
|
return {};
|
|
5681
5729
|
}
|
|
@@ -5683,8 +5731,8 @@ function readFlags() {
|
|
|
5683
5731
|
function writeFlags(patch) {
|
|
5684
5732
|
const p = promptFlagPath();
|
|
5685
5733
|
try {
|
|
5686
|
-
|
|
5687
|
-
|
|
5734
|
+
mkdirSync5(dirname7(p), { recursive: true });
|
|
5735
|
+
writeFileSync5(p, JSON.stringify({ ...readFlags(), ...patch }, null, 2), "utf8");
|
|
5688
5736
|
} catch {
|
|
5689
5737
|
}
|
|
5690
5738
|
}
|
|
@@ -5896,7 +5944,7 @@ async function status() {
|
|
|
5896
5944
|
console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
|
|
5897
5945
|
if (isServerStale(server)) {
|
|
5898
5946
|
console.log(
|
|
5899
|
-
` \u26A0 serving stale ${ver} (CLI is ${"0.15.
|
|
5947
|
+
` \u26A0 serving stale ${ver} (CLI is ${"0.15.4"}) \u2014 run 'fleetlens start' to restart on the current version`
|
|
5900
5948
|
);
|
|
5901
5949
|
}
|
|
5902
5950
|
} else {
|
|
@@ -5978,7 +6026,7 @@ var init_update = __esm({
|
|
|
5978
6026
|
|
|
5979
6027
|
// src/usage/token.ts
|
|
5980
6028
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
5981
|
-
import { readFileSync as
|
|
6029
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
5982
6030
|
import { homedir as homedir4, platform } from "node:os";
|
|
5983
6031
|
import { join as join7 } from "node:path";
|
|
5984
6032
|
function readOAuthCredentials() {
|
|
@@ -6006,7 +6054,7 @@ function readFromCredentialsFile() {
|
|
|
6006
6054
|
];
|
|
6007
6055
|
for (const path7 of candidates) {
|
|
6008
6056
|
try {
|
|
6009
|
-
const blob =
|
|
6057
|
+
const blob = readFileSync9(path7, "utf8");
|
|
6010
6058
|
const creds = extractCredentials(blob);
|
|
6011
6059
|
if (creds) return creds;
|
|
6012
6060
|
} catch {
|
|
@@ -7001,6 +7049,7 @@ __export(dist_exports, {
|
|
|
7001
7049
|
RATE_PER_PCT: () => RATE_PER_PCT,
|
|
7002
7050
|
RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
|
|
7003
7051
|
RATE_PER_PCT_7D: () => RATE_PER_PCT_7D,
|
|
7052
|
+
ZAI_METADATA: () => ZAI_METADATA,
|
|
7004
7053
|
agentMetadata: () => agentMetadata,
|
|
7005
7054
|
aggregateConcurrency: () => aggregateConcurrency,
|
|
7006
7055
|
buildGanttDay: () => buildGanttDay,
|
|
@@ -7830,11 +7879,11 @@ var init_dist2 = __esm({
|
|
|
7830
7879
|
});
|
|
7831
7880
|
|
|
7832
7881
|
// ../entries/dist/digest-fs.js
|
|
7833
|
-
import { readFileSync as
|
|
7882
|
+
import { readFileSync as readFileSync10, readdirSync, writeFileSync as writeFileSync6, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync6, existsSync as existsSync8 } from "node:fs";
|
|
7834
7883
|
import { dirname as dirname8, join as join8 } from "node:path";
|
|
7835
7884
|
function parseDigestFile(path7, expectedVersion) {
|
|
7836
7885
|
try {
|
|
7837
|
-
const parsed = JSON.parse(
|
|
7886
|
+
const parsed = JSON.parse(readFileSync10(path7, "utf8"));
|
|
7838
7887
|
if (!parsed || typeof parsed !== "object")
|
|
7839
7888
|
return null;
|
|
7840
7889
|
if (parsed.version !== expectedVersion)
|
|
@@ -7855,9 +7904,9 @@ function digestsDir() {
|
|
|
7855
7904
|
}
|
|
7856
7905
|
function __setDigestsDirForTest(path7) {
|
|
7857
7906
|
digestsDirCached = path7;
|
|
7858
|
-
|
|
7859
|
-
|
|
7860
|
-
|
|
7907
|
+
mkdirSync6(join8(path7, "day"), { recursive: true });
|
|
7908
|
+
mkdirSync6(join8(path7, "week"), { recursive: true });
|
|
7909
|
+
mkdirSync6(join8(path7, "month"), { recursive: true });
|
|
7861
7910
|
}
|
|
7862
7911
|
function dayDigestPath(date) {
|
|
7863
7912
|
return join8(digestsDir(), "day", `${date}.json`);
|
|
@@ -7870,9 +7919,9 @@ function monthDigestPath(yearMonth) {
|
|
|
7870
7919
|
}
|
|
7871
7920
|
function writeDayDigest(digest2) {
|
|
7872
7921
|
const final = dayDigestPath(digest2.key);
|
|
7873
|
-
|
|
7922
|
+
mkdirSync6(dirname8(final), { recursive: true });
|
|
7874
7923
|
const tmp = `${final}.tmp`;
|
|
7875
|
-
|
|
7924
|
+
writeFileSync6(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
7876
7925
|
if (process.platform !== "win32") {
|
|
7877
7926
|
try {
|
|
7878
7927
|
chmodSync(tmp, 384);
|
|
@@ -7883,7 +7932,7 @@ function writeDayDigest(digest2) {
|
|
|
7883
7932
|
}
|
|
7884
7933
|
function readDayDigest(date) {
|
|
7885
7934
|
const p = dayDigestPath(date);
|
|
7886
|
-
if (!
|
|
7935
|
+
if (!existsSync8(p))
|
|
7887
7936
|
return null;
|
|
7888
7937
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
7889
7938
|
}
|
|
@@ -7906,9 +7955,9 @@ function __clearTodayCacheForTest() {
|
|
|
7906
7955
|
}
|
|
7907
7956
|
function writeWeekDigest(digest2) {
|
|
7908
7957
|
const final = weekDigestPath(digest2.key);
|
|
7909
|
-
|
|
7958
|
+
mkdirSync6(dirname8(final), { recursive: true });
|
|
7910
7959
|
const tmp = `${final}.tmp`;
|
|
7911
|
-
|
|
7960
|
+
writeFileSync6(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
7912
7961
|
if (process.platform !== "win32") {
|
|
7913
7962
|
try {
|
|
7914
7963
|
chmodSync(tmp, 384);
|
|
@@ -7919,13 +7968,13 @@ function writeWeekDigest(digest2) {
|
|
|
7919
7968
|
}
|
|
7920
7969
|
function readWeekDigest(monday) {
|
|
7921
7970
|
const p = weekDigestPath(monday);
|
|
7922
|
-
if (!
|
|
7971
|
+
if (!existsSync8(p))
|
|
7923
7972
|
return null;
|
|
7924
7973
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
7925
7974
|
}
|
|
7926
7975
|
function listWeekDigestKeys() {
|
|
7927
7976
|
const dir = join8(digestsDir(), "week");
|
|
7928
|
-
if (!
|
|
7977
|
+
if (!existsSync8(dir))
|
|
7929
7978
|
return [];
|
|
7930
7979
|
return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}-\d{2}$/.test(k));
|
|
7931
7980
|
}
|
|
@@ -7943,9 +7992,9 @@ function setCurrentWeekDigestInCache(monday, digest2, nowMs) {
|
|
|
7943
7992
|
}
|
|
7944
7993
|
function writeMonthDigest(digest2) {
|
|
7945
7994
|
const final = monthDigestPath(digest2.key);
|
|
7946
|
-
|
|
7995
|
+
mkdirSync6(dirname8(final), { recursive: true });
|
|
7947
7996
|
const tmp = `${final}.tmp`;
|
|
7948
|
-
|
|
7997
|
+
writeFileSync6(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
7949
7998
|
if (process.platform !== "win32") {
|
|
7950
7999
|
try {
|
|
7951
8000
|
chmodSync(tmp, 384);
|
|
@@ -7956,13 +8005,13 @@ function writeMonthDigest(digest2) {
|
|
|
7956
8005
|
}
|
|
7957
8006
|
function readMonthDigest(yearMonth) {
|
|
7958
8007
|
const p = monthDigestPath(yearMonth);
|
|
7959
|
-
if (!
|
|
8008
|
+
if (!existsSync8(p))
|
|
7960
8009
|
return null;
|
|
7961
8010
|
return parseDigestFile(p, CURRENT_MONTH_DIGEST_SCHEMA_VERSION);
|
|
7962
8011
|
}
|
|
7963
8012
|
function listMonthDigestKeys() {
|
|
7964
8013
|
const dir = join8(digestsDir(), "month");
|
|
7965
|
-
if (!
|
|
8014
|
+
if (!existsSync8(dir))
|
|
7966
8015
|
return [];
|
|
7967
8016
|
return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}$/.test(k));
|
|
7968
8017
|
}
|
|
@@ -8024,7 +8073,7 @@ __export(fs_exports2, {
|
|
|
8024
8073
|
writeMonthDigest: () => writeMonthDigest,
|
|
8025
8074
|
writeWeekDigest: () => writeWeekDigest
|
|
8026
8075
|
});
|
|
8027
|
-
import { readFileSync as
|
|
8076
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync2, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync9 } from "node:fs";
|
|
8028
8077
|
import { randomBytes } from "node:crypto";
|
|
8029
8078
|
import { join as join9 } from "node:path";
|
|
8030
8079
|
function entriesDir() {
|
|
@@ -8036,7 +8085,7 @@ function entriesDir() {
|
|
|
8036
8085
|
}
|
|
8037
8086
|
function __setEntriesDirForTest(path7) {
|
|
8038
8087
|
entriesDirCached = path7;
|
|
8039
|
-
|
|
8088
|
+
mkdirSync7(path7, { recursive: true });
|
|
8040
8089
|
}
|
|
8041
8090
|
function pathFor(sessionId, localDay2) {
|
|
8042
8091
|
return join9(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
@@ -8046,11 +8095,11 @@ function tmpPathFor(final) {
|
|
|
8046
8095
|
}
|
|
8047
8096
|
function writeEntry(entry) {
|
|
8048
8097
|
const dir = entriesDir();
|
|
8049
|
-
|
|
8098
|
+
mkdirSync7(dir, { recursive: true });
|
|
8050
8099
|
const final = pathFor(entry.session_id, entry.local_day);
|
|
8051
8100
|
const tmp = tmpPathFor(final);
|
|
8052
8101
|
const json = JSON.stringify(entry, null, 2);
|
|
8053
|
-
|
|
8102
|
+
writeFileSync7(tmp, json, { encoding: "utf8" });
|
|
8054
8103
|
renameSync3(tmp, final);
|
|
8055
8104
|
}
|
|
8056
8105
|
function enrichmentInputHash(e) {
|
|
@@ -8070,7 +8119,7 @@ function enrichmentInputHash(e) {
|
|
|
8070
8119
|
}
|
|
8071
8120
|
function writeEntryPreservingEnrichment(fresh) {
|
|
8072
8121
|
const dir = entriesDir();
|
|
8073
|
-
|
|
8122
|
+
mkdirSync7(dir, { recursive: true });
|
|
8074
8123
|
const final = pathFor(fresh.session_id, fresh.local_day);
|
|
8075
8124
|
const existing = readEntry(fresh.session_id, fresh.local_day);
|
|
8076
8125
|
let toWrite = fresh;
|
|
@@ -8078,22 +8127,22 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
8078
8127
|
toWrite = { ...fresh, enrichment: existing.enrichment };
|
|
8079
8128
|
}
|
|
8080
8129
|
const tmp = tmpPathFor(final);
|
|
8081
|
-
|
|
8130
|
+
writeFileSync7(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
|
|
8082
8131
|
renameSync3(tmp, final);
|
|
8083
8132
|
}
|
|
8084
8133
|
function readEntry(sessionId, localDay2) {
|
|
8085
8134
|
const p = pathFor(sessionId, localDay2);
|
|
8086
|
-
if (!
|
|
8135
|
+
if (!existsSync9(p))
|
|
8087
8136
|
return null;
|
|
8088
|
-
const raw =
|
|
8137
|
+
const raw = readFileSync11(p, "utf8");
|
|
8089
8138
|
return JSON.parse(raw);
|
|
8090
8139
|
}
|
|
8091
8140
|
function entryExists(sessionId, localDay2) {
|
|
8092
|
-
return
|
|
8141
|
+
return existsSync9(pathFor(sessionId, localDay2));
|
|
8093
8142
|
}
|
|
8094
8143
|
function listEntryKeys() {
|
|
8095
8144
|
const dir = entriesDir();
|
|
8096
|
-
if (!
|
|
8145
|
+
if (!existsSync9(dir))
|
|
8097
8146
|
return [];
|
|
8098
8147
|
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
8099
8148
|
}
|
|
@@ -12372,7 +12421,7 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
|
|
|
12372
12421
|
});
|
|
12373
12422
|
|
|
12374
12423
|
// ../entries/dist/tmux-runner.js
|
|
12375
|
-
import { mkdirSync as
|
|
12424
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8, existsSync as existsSync10, readdirSync as readdirSync3, realpathSync as realpathSync4, readFileSync as readFileSync12, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
12376
12425
|
import { join as join10 } from "node:path";
|
|
12377
12426
|
import { homedir as homedir5 } from "node:os";
|
|
12378
12427
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
@@ -12391,15 +12440,15 @@ function tmuxRunnerAvailable() {
|
|
|
12391
12440
|
}
|
|
12392
12441
|
function runtimeCwd() {
|
|
12393
12442
|
const dir = join10(homedir5(), ".cclens", "runtime");
|
|
12394
|
-
if (!
|
|
12395
|
-
|
|
12443
|
+
if (!existsSync10(dir))
|
|
12444
|
+
mkdirSync8(dir, { recursive: true });
|
|
12396
12445
|
return realpathSync4(dir);
|
|
12397
12446
|
}
|
|
12398
12447
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
12399
12448
|
const cfgPath = join10(homedir5(), ".claude.json");
|
|
12400
12449
|
let cfg;
|
|
12401
12450
|
try {
|
|
12402
|
-
cfg = JSON.parse(
|
|
12451
|
+
cfg = JSON.parse(readFileSync12(cfgPath, "utf8"));
|
|
12403
12452
|
} catch {
|
|
12404
12453
|
return;
|
|
12405
12454
|
}
|
|
@@ -12414,7 +12463,7 @@ function ensureRuntimeCwdTrusted(cwd) {
|
|
|
12414
12463
|
cfg.projects = projects;
|
|
12415
12464
|
const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
|
|
12416
12465
|
try {
|
|
12417
|
-
|
|
12466
|
+
writeFileSync8(tmp, JSON.stringify(cfg, null, 2));
|
|
12418
12467
|
renameSync4(tmp, cfgPath);
|
|
12419
12468
|
} catch {
|
|
12420
12469
|
try {
|
|
@@ -12444,13 +12493,13 @@ async function runClaudeUnderTmuxImpl(args2) {
|
|
|
12444
12493
|
const systemFile = join10(cwd, `system-${runId}.txt`);
|
|
12445
12494
|
const userFile = join10(cwd, `user-${runId}.txt`);
|
|
12446
12495
|
const wrapper = join10(cwd, `run-${runId}.sh`);
|
|
12447
|
-
|
|
12448
|
-
|
|
12496
|
+
writeFileSync8(systemFile, args2.systemPrompt);
|
|
12497
|
+
writeFileSync8(userFile, args2.reminder ? `${args2.userPrompt}
|
|
12449
12498
|
|
|
12450
12499
|
---
|
|
12451
12500
|
|
|
12452
12501
|
${args2.reminder}` : args2.userPrompt);
|
|
12453
|
-
|
|
12502
|
+
writeFileSync8(wrapper, `#!/bin/bash
|
|
12454
12503
|
SYS="$(cat ${shellEscape(systemFile)})"
|
|
12455
12504
|
USR="$(cat ${shellEscape(userFile)})"
|
|
12456
12505
|
exec ${shellEscape(claudeBin)} \\
|
|
@@ -12549,7 +12598,7 @@ function snapshotAllTranscripts() {
|
|
|
12549
12598
|
function readJsonlCwd(path7, maxLines = 8) {
|
|
12550
12599
|
let raw;
|
|
12551
12600
|
try {
|
|
12552
|
-
raw =
|
|
12601
|
+
raw = readFileSync12(path7, "utf8");
|
|
12553
12602
|
} catch {
|
|
12554
12603
|
return void 0;
|
|
12555
12604
|
}
|
|
@@ -12606,7 +12655,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12606
12655
|
function parseTranscript2(path7, defaultModel) {
|
|
12607
12656
|
let raw;
|
|
12608
12657
|
try {
|
|
12609
|
-
raw =
|
|
12658
|
+
raw = readFileSync12(path7, "utf8");
|
|
12610
12659
|
} catch {
|
|
12611
12660
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
12612
12661
|
}
|
|
@@ -12700,13 +12749,13 @@ var init_tmux_runner = __esm({
|
|
|
12700
12749
|
|
|
12701
12750
|
// ../entries/dist/llm-runner.js
|
|
12702
12751
|
import { spawn as spawn3 } from "node:child_process";
|
|
12703
|
-
import { mkdirSync as
|
|
12752
|
+
import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync9, existsSync as existsSync11 } from "node:fs";
|
|
12704
12753
|
import { join as join11 } from "node:path";
|
|
12705
12754
|
import { randomUUID } from "node:crypto";
|
|
12706
12755
|
function ensureRunsDir() {
|
|
12707
|
-
if (!
|
|
12756
|
+
if (!existsSync11(RUNS_DIR)) {
|
|
12708
12757
|
try {
|
|
12709
|
-
|
|
12758
|
+
mkdirSync9(RUNS_DIR, { recursive: true });
|
|
12710
12759
|
} catch {
|
|
12711
12760
|
}
|
|
12712
12761
|
}
|
|
@@ -12737,13 +12786,13 @@ function tracePath(runId) {
|
|
|
12737
12786
|
}
|
|
12738
12787
|
function safeAppend(path7, line) {
|
|
12739
12788
|
try {
|
|
12740
|
-
|
|
12789
|
+
appendFileSync3(path7, line);
|
|
12741
12790
|
} catch {
|
|
12742
12791
|
}
|
|
12743
12792
|
}
|
|
12744
12793
|
function safeWrite(path7, line) {
|
|
12745
12794
|
try {
|
|
12746
|
-
|
|
12795
|
+
writeFileSync9(path7, line);
|
|
12747
12796
|
} catch {
|
|
12748
12797
|
}
|
|
12749
12798
|
}
|
|
@@ -13149,7 +13198,7 @@ var init_enrich2 = __esm({
|
|
|
13149
13198
|
});
|
|
13150
13199
|
|
|
13151
13200
|
// ../entries/dist/budget.js
|
|
13152
|
-
import { appendFileSync as
|
|
13201
|
+
import { appendFileSync as appendFileSync4, readFileSync as readFileSync13, existsSync as existsSync12, mkdirSync as mkdirSync10 } from "node:fs";
|
|
13153
13202
|
import { dirname as dirname9 } from "node:path";
|
|
13154
13203
|
function spendPath() {
|
|
13155
13204
|
if (spendPathCached)
|
|
@@ -13162,17 +13211,17 @@ function __setSpendPathForTest(path7) {
|
|
|
13162
13211
|
}
|
|
13163
13212
|
function appendSpend(record) {
|
|
13164
13213
|
const p = spendPath();
|
|
13165
|
-
|
|
13166
|
-
|
|
13214
|
+
mkdirSync10(dirname9(p), { recursive: true });
|
|
13215
|
+
appendFileSync4(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
13167
13216
|
}
|
|
13168
13217
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
13169
13218
|
const p = spendPath();
|
|
13170
|
-
if (!
|
|
13219
|
+
if (!existsSync12(p))
|
|
13171
13220
|
return 0;
|
|
13172
13221
|
const year = now.getUTCFullYear();
|
|
13173
13222
|
const month2 = now.getUTCMonth();
|
|
13174
13223
|
let total = 0;
|
|
13175
|
-
const raw =
|
|
13224
|
+
const raw = readFileSync13(p, "utf8");
|
|
13176
13225
|
for (const line of raw.split("\n")) {
|
|
13177
13226
|
if (!line)
|
|
13178
13227
|
continue;
|
|
@@ -13201,7 +13250,7 @@ var init_budget = __esm({
|
|
|
13201
13250
|
});
|
|
13202
13251
|
|
|
13203
13252
|
// ../entries/dist/pipeline-lock.js
|
|
13204
|
-
import { writeFileSync as
|
|
13253
|
+
import { writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, existsSync as existsSync13, readFileSync as readFileSync14, statSync as statSync3 } from "node:fs";
|
|
13205
13254
|
function lockPath() {
|
|
13206
13255
|
if (lockPathCached)
|
|
13207
13256
|
return lockPathCached;
|
|
@@ -13212,7 +13261,7 @@ function __setInteractiveLockPathForTest(path7) {
|
|
|
13212
13261
|
lockPathCached = path7;
|
|
13213
13262
|
}
|
|
13214
13263
|
function touchLock() {
|
|
13215
|
-
|
|
13264
|
+
writeFileSync10(lockPath(), String(process.pid), "utf8");
|
|
13216
13265
|
}
|
|
13217
13266
|
function writeInteractiveLock() {
|
|
13218
13267
|
touchLock();
|
|
@@ -13246,13 +13295,13 @@ function pidAlive(pid) {
|
|
|
13246
13295
|
}
|
|
13247
13296
|
function interactiveLockFresh(nowMs) {
|
|
13248
13297
|
const p = lockPath();
|
|
13249
|
-
if (!
|
|
13298
|
+
if (!existsSync13(p))
|
|
13250
13299
|
return false;
|
|
13251
13300
|
try {
|
|
13252
13301
|
const mtime = statSync3(p).mtimeMs;
|
|
13253
13302
|
if (nowMs - mtime > STALE_MS)
|
|
13254
13303
|
return false;
|
|
13255
|
-
const pid = Number(
|
|
13304
|
+
const pid = Number(readFileSync14(p, "utf8").trim());
|
|
13256
13305
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
13257
13306
|
return false;
|
|
13258
13307
|
if (!pidAlive(pid))
|
|
@@ -13358,7 +13407,7 @@ var init_queue = __esm({
|
|
|
13358
13407
|
});
|
|
13359
13408
|
|
|
13360
13409
|
// ../entries/dist/settings.js
|
|
13361
|
-
import { readFileSync as
|
|
13410
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync11, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync14 } from "node:fs";
|
|
13362
13411
|
import { dirname as dirname10 } from "node:path";
|
|
13363
13412
|
function settingsPath() {
|
|
13364
13413
|
if (settingsPathCached)
|
|
@@ -13394,10 +13443,10 @@ function fromDisk(d) {
|
|
|
13394
13443
|
}
|
|
13395
13444
|
function readSettings() {
|
|
13396
13445
|
const p = settingsPath();
|
|
13397
|
-
if (!
|
|
13446
|
+
if (!existsSync14(p))
|
|
13398
13447
|
return DEFAULT_SETTINGS;
|
|
13399
13448
|
try {
|
|
13400
|
-
const raw =
|
|
13449
|
+
const raw = readFileSync15(p, "utf8");
|
|
13401
13450
|
return fromDisk(JSON.parse(raw));
|
|
13402
13451
|
} catch {
|
|
13403
13452
|
return DEFAULT_SETTINGS;
|
|
@@ -13405,9 +13454,9 @@ function readSettings() {
|
|
|
13405
13454
|
}
|
|
13406
13455
|
function writeSettings(s) {
|
|
13407
13456
|
const p = settingsPath();
|
|
13408
|
-
|
|
13457
|
+
mkdirSync11(dirname10(p), { recursive: true });
|
|
13409
13458
|
const tmp = `${p}.tmp`;
|
|
13410
|
-
|
|
13459
|
+
writeFileSync11(tmp, JSON.stringify(toDisk(s), null, 2), { encoding: "utf8" });
|
|
13411
13460
|
if (process.platform !== "win32") {
|
|
13412
13461
|
chmodSync2(tmp, 384);
|
|
13413
13462
|
}
|
|
@@ -16586,6 +16635,142 @@ var init_digest_month_pipeline = __esm({
|
|
|
16586
16635
|
}
|
|
16587
16636
|
});
|
|
16588
16637
|
|
|
16638
|
+
// ../entries/dist/credentials.js
|
|
16639
|
+
import { writeFileSync as writeFileSync12, readFileSync as readFileSync16, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync15, unlinkSync as unlinkSync5 } from "node:fs";
|
|
16640
|
+
import { dirname as dirname11 } from "node:path";
|
|
16641
|
+
async function fetchZaiUsage(candidate) {
|
|
16642
|
+
const key = candidate.trim();
|
|
16643
|
+
if (!key)
|
|
16644
|
+
throw new Error("empty key");
|
|
16645
|
+
const res = await fetch(ZAI_QUOTA_ENDPOINT, {
|
|
16646
|
+
headers: { Authorization: key, "Accept-Language": "en-US,en" }
|
|
16647
|
+
});
|
|
16648
|
+
if (!res.ok) {
|
|
16649
|
+
throw new Error(`Z.ai rejected the key (${res.status} ${res.statusText})`);
|
|
16650
|
+
}
|
|
16651
|
+
const body = await res.json().catch(() => {
|
|
16652
|
+
throw new Error("Z.ai returned an unparseable response");
|
|
16653
|
+
});
|
|
16654
|
+
if (body.code !== void 0 && body.code !== 200) {
|
|
16655
|
+
throw new Error(`Z.ai rejected the key (code ${body.code})`);
|
|
16656
|
+
}
|
|
16657
|
+
if (body.success === false) {
|
|
16658
|
+
throw new Error("Z.ai rejected the key");
|
|
16659
|
+
}
|
|
16660
|
+
const limits = body.data?.limits ?? [];
|
|
16661
|
+
let fiveHour = null;
|
|
16662
|
+
let sevenDay = null;
|
|
16663
|
+
let webSearch = null;
|
|
16664
|
+
for (const limit of limits) {
|
|
16665
|
+
const type = limit.type;
|
|
16666
|
+
if (type === "TIME_LIMIT") {
|
|
16667
|
+
const pct2 = typeof limit.percentage === "number" ? limit.percentage : null;
|
|
16668
|
+
webSearch = { used: pct2, limit: pct2 !== null ? 100 : null };
|
|
16669
|
+
continue;
|
|
16670
|
+
}
|
|
16671
|
+
if (type !== "TOKENS_LIMIT")
|
|
16672
|
+
continue;
|
|
16673
|
+
const unit = limit.unit;
|
|
16674
|
+
const pct = typeof limit.percentage === "number" ? limit.percentage : null;
|
|
16675
|
+
const resetsAt = typeof limit.nextResetTime === "number" ? new Date(limit.nextResetTime).toISOString() : null;
|
|
16676
|
+
const window = { utilization: pct, resets_at: resetsAt };
|
|
16677
|
+
if (unit === 6)
|
|
16678
|
+
sevenDay = sevenDay ?? window;
|
|
16679
|
+
else
|
|
16680
|
+
fiveHour = fiveHour ?? window;
|
|
16681
|
+
}
|
|
16682
|
+
return {
|
|
16683
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
16684
|
+
agent: "zai",
|
|
16685
|
+
five_hour: fiveHour ?? { utilization: null, resets_at: null },
|
|
16686
|
+
seven_day: sevenDay ?? { utilization: null, resets_at: null },
|
|
16687
|
+
seven_day_opus: null,
|
|
16688
|
+
seven_day_sonnet: null,
|
|
16689
|
+
seven_day_oauth_apps: null,
|
|
16690
|
+
seven_day_cowork: null,
|
|
16691
|
+
extra_usage: null,
|
|
16692
|
+
plan_type: body.data?.level ?? null,
|
|
16693
|
+
web_search_quota: webSearch ?? null
|
|
16694
|
+
};
|
|
16695
|
+
}
|
|
16696
|
+
async function validateAndSnapshotZaiKey(key) {
|
|
16697
|
+
const snap = await fetchZaiUsage(key);
|
|
16698
|
+
appendUsageSnapshot(snap);
|
|
16699
|
+
return snap;
|
|
16700
|
+
}
|
|
16701
|
+
function deleteZaiKeyAndPrune() {
|
|
16702
|
+
deleteZaiKey();
|
|
16703
|
+
pruneUsageAgent("zai");
|
|
16704
|
+
}
|
|
16705
|
+
function credentialsPath() {
|
|
16706
|
+
return cclensPath("credentials.json");
|
|
16707
|
+
}
|
|
16708
|
+
function readCredentials() {
|
|
16709
|
+
const p = credentialsPath();
|
|
16710
|
+
if (!existsSync15(p))
|
|
16711
|
+
return {};
|
|
16712
|
+
try {
|
|
16713
|
+
const raw = readFileSync16(p, "utf8");
|
|
16714
|
+
return JSON.parse(raw);
|
|
16715
|
+
} catch {
|
|
16716
|
+
return {};
|
|
16717
|
+
}
|
|
16718
|
+
}
|
|
16719
|
+
function readCredentialsMasked() {
|
|
16720
|
+
const store = readCredentials();
|
|
16721
|
+
if (!store.zai?.apiKey)
|
|
16722
|
+
return {};
|
|
16723
|
+
const key = store.zai.apiKey;
|
|
16724
|
+
const hint = key.length > 12 ? `${key.slice(0, 6)}\u2026${key.slice(-6)}` : `${key.slice(0, 6)}\u2026`;
|
|
16725
|
+
return { zai: { configured: true, hint } };
|
|
16726
|
+
}
|
|
16727
|
+
function writeZaiKey(apiKey) {
|
|
16728
|
+
apiKey = apiKey.trim();
|
|
16729
|
+
if (!apiKey) {
|
|
16730
|
+
deleteZaiKey();
|
|
16731
|
+
return;
|
|
16732
|
+
}
|
|
16733
|
+
const store = readCredentials();
|
|
16734
|
+
store.zai = { ...store.zai ?? {}, apiKey };
|
|
16735
|
+
const p = credentialsPath();
|
|
16736
|
+
mkdirSync12(dirname11(p), { recursive: true });
|
|
16737
|
+
const tmp = `${p}.tmp`;
|
|
16738
|
+
writeFileSync12(tmp, JSON.stringify(store, null, 2), { encoding: "utf8" });
|
|
16739
|
+
if (process.platform !== "win32") {
|
|
16740
|
+
chmodSync3(tmp, 384);
|
|
16741
|
+
}
|
|
16742
|
+
renameSync6(tmp, p);
|
|
16743
|
+
}
|
|
16744
|
+
function deleteZaiKey() {
|
|
16745
|
+
const store = readCredentials();
|
|
16746
|
+
delete store.zai;
|
|
16747
|
+
const p = credentialsPath();
|
|
16748
|
+
if (Object.keys(store).length === 0) {
|
|
16749
|
+
try {
|
|
16750
|
+
unlinkSync5(p);
|
|
16751
|
+
} catch {
|
|
16752
|
+
}
|
|
16753
|
+
return;
|
|
16754
|
+
}
|
|
16755
|
+
const tmp = `${p}.tmp`;
|
|
16756
|
+
writeFileSync12(tmp, JSON.stringify(store, null, 2), { encoding: "utf8" });
|
|
16757
|
+
if (process.platform !== "win32") {
|
|
16758
|
+
chmodSync3(tmp, 384);
|
|
16759
|
+
}
|
|
16760
|
+
renameSync6(tmp, p);
|
|
16761
|
+
}
|
|
16762
|
+
function hasZaiKey() {
|
|
16763
|
+
return !!readCredentials().zai?.apiKey;
|
|
16764
|
+
}
|
|
16765
|
+
var ZAI_QUOTA_ENDPOINT;
|
|
16766
|
+
var init_credentials = __esm({
|
|
16767
|
+
"../entries/dist/credentials.js"() {
|
|
16768
|
+
"use strict";
|
|
16769
|
+
init_fs();
|
|
16770
|
+
ZAI_QUOTA_ENDPOINT = "https://api.z.ai/api/monitor/usage/quota/limit";
|
|
16771
|
+
}
|
|
16772
|
+
});
|
|
16773
|
+
|
|
16589
16774
|
// ../entries/dist/node.js
|
|
16590
16775
|
var node_exports = {};
|
|
16591
16776
|
__export(node_exports, {
|
|
@@ -16616,19 +16801,25 @@ __export(node_exports, {
|
|
|
16616
16801
|
computeInteractionGrammar: () => computeInteractionGrammar,
|
|
16617
16802
|
computeInteractionModes: () => computeInteractionModes,
|
|
16618
16803
|
computeWorkingShapes: () => computeWorkingShapes,
|
|
16804
|
+
deleteZaiKey: () => deleteZaiKey,
|
|
16805
|
+
deleteZaiKeyAndPrune: () => deleteZaiKeyAndPrune,
|
|
16619
16806
|
enrichEntry: () => enrichEntry,
|
|
16807
|
+
fetchZaiUsage: () => fetchZaiUsage,
|
|
16620
16808
|
generateDayDigest: () => generateDayDigest,
|
|
16621
16809
|
generateMonthDigest: () => generateMonthDigest,
|
|
16622
16810
|
generateWeekDigest: () => generateWeekDigest,
|
|
16623
16811
|
getCurrentMonthDigestFromCache: () => getCurrentMonthDigestFromCache,
|
|
16624
16812
|
getCurrentWeekDigestFromCache: () => getCurrentWeekDigestFromCache,
|
|
16625
16813
|
getTodayDigestFromCache: () => getTodayDigestFromCache,
|
|
16814
|
+
hasZaiKey: () => hasZaiKey,
|
|
16626
16815
|
interactiveLockFresh: () => interactiveLockFresh,
|
|
16627
16816
|
listMonthDigestKeys: () => listMonthDigestKeys,
|
|
16628
16817
|
listWeekDigestKeys: () => listWeekDigestKeys,
|
|
16629
16818
|
mondayFor: () => mondayFor,
|
|
16630
16819
|
mondaysInMonth: () => mondaysInMonth,
|
|
16631
16820
|
monthToDateSpend: () => monthToDateSpend,
|
|
16821
|
+
readCredentials: () => readCredentials,
|
|
16822
|
+
readCredentialsMasked: () => readCredentialsMasked,
|
|
16632
16823
|
readDayDigest: () => readDayDigest,
|
|
16633
16824
|
readMonthDigest: () => readMonthDigest,
|
|
16634
16825
|
readSettings: () => readSettings,
|
|
@@ -16643,12 +16834,14 @@ __export(node_exports, {
|
|
|
16643
16834
|
setCurrentWeekDigestInCache: () => setCurrentWeekDigestInCache,
|
|
16644
16835
|
setTodayDigestInCache: () => setTodayDigestInCache,
|
|
16645
16836
|
tmuxRunnerAvailable: () => tmuxRunnerAvailable,
|
|
16837
|
+
validateAndSnapshotZaiKey: () => validateAndSnapshotZaiKey,
|
|
16646
16838
|
weekDates: () => weekDates,
|
|
16647
16839
|
writeDayDigest: () => writeDayDigest,
|
|
16648
16840
|
writeInteractiveLock: () => writeInteractiveLock,
|
|
16649
16841
|
writeMonthDigest: () => writeMonthDigest,
|
|
16650
16842
|
writeSettings: () => writeSettings,
|
|
16651
|
-
writeWeekDigest: () => writeWeekDigest
|
|
16843
|
+
writeWeekDigest: () => writeWeekDigest,
|
|
16844
|
+
writeZaiKey: () => writeZaiKey
|
|
16652
16845
|
});
|
|
16653
16846
|
var init_node = __esm({
|
|
16654
16847
|
"../entries/dist/node.js"() {
|
|
@@ -16670,6 +16863,7 @@ var init_node = __esm({
|
|
|
16670
16863
|
init_digest_month_pipeline();
|
|
16671
16864
|
init_tmux_runner();
|
|
16672
16865
|
init_digest_fs();
|
|
16866
|
+
init_credentials();
|
|
16673
16867
|
}
|
|
16674
16868
|
});
|
|
16675
16869
|
|
|
@@ -17139,6 +17333,230 @@ var init_digest = __esm({
|
|
|
17139
17333
|
}
|
|
17140
17334
|
});
|
|
17141
17335
|
|
|
17336
|
+
// src/commands/menubar.ts
|
|
17337
|
+
var menubar_exports = {};
|
|
17338
|
+
__export(menubar_exports, {
|
|
17339
|
+
menubar: () => menubar
|
|
17340
|
+
});
|
|
17341
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync4, writeFileSync as writeFileSync13, realpathSync as realpathSync5 } from "node:fs";
|
|
17342
|
+
import { homedir as homedir6 } from "node:os";
|
|
17343
|
+
import { join as join12, dirname as dirname12 } from "node:path";
|
|
17344
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17345
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
17346
|
+
import { promisify as promisify2 } from "node:util";
|
|
17347
|
+
function isMac2() {
|
|
17348
|
+
return process.platform === "darwin";
|
|
17349
|
+
}
|
|
17350
|
+
function bundledAppPath() {
|
|
17351
|
+
const here = dirname12(fileURLToPath3(import.meta.url));
|
|
17352
|
+
return join12(here, "..", "menubar", APP_BUNDLE);
|
|
17353
|
+
}
|
|
17354
|
+
function resolveScriptPath2() {
|
|
17355
|
+
const argv1 = process.argv[1] ?? "";
|
|
17356
|
+
try {
|
|
17357
|
+
return realpathSync5(argv1);
|
|
17358
|
+
} catch {
|
|
17359
|
+
return argv1;
|
|
17360
|
+
}
|
|
17361
|
+
}
|
|
17362
|
+
function writeCliLaunchFile() {
|
|
17363
|
+
try {
|
|
17364
|
+
writeFileSync13(
|
|
17365
|
+
cclensPath("cli-launch.json"),
|
|
17366
|
+
JSON.stringify({ node: process.execPath, script: resolveScriptPath2() }),
|
|
17367
|
+
"utf8"
|
|
17368
|
+
);
|
|
17369
|
+
} catch {
|
|
17370
|
+
}
|
|
17371
|
+
}
|
|
17372
|
+
function installedAppPath() {
|
|
17373
|
+
return join12(homedir6(), "Applications", APP_BUNDLE);
|
|
17374
|
+
}
|
|
17375
|
+
async function isRunning() {
|
|
17376
|
+
try {
|
|
17377
|
+
const { stdout } = await execFileAsync2("pgrep", ["-x", BUNDLE_EXEC]);
|
|
17378
|
+
return stdout.trim().length > 0;
|
|
17379
|
+
} catch {
|
|
17380
|
+
return false;
|
|
17381
|
+
}
|
|
17382
|
+
}
|
|
17383
|
+
async function launchApp(path7) {
|
|
17384
|
+
await execFileAsync2("open", ["-a", path7]);
|
|
17385
|
+
}
|
|
17386
|
+
async function quitApp() {
|
|
17387
|
+
await execFileAsync2("osascript", ["-e", `tell application "${BUNDLE_EXEC}" to quit`]).catch(
|
|
17388
|
+
() => {
|
|
17389
|
+
}
|
|
17390
|
+
);
|
|
17391
|
+
await execFileAsync2("pkill", ["-x", BUNDLE_EXEC]).catch(() => {
|
|
17392
|
+
});
|
|
17393
|
+
}
|
|
17394
|
+
async function setLoginItem(enabled, appPath) {
|
|
17395
|
+
const script = enabled ? `tell application "System Events" to make login item at end with properties {path:"${appPath}", hidden:false}` : `tell application "System Events" to delete login item "${APP_BUNDLE.replace(".app", "")}"`;
|
|
17396
|
+
await execFileAsync2("osascript", ["-e", script]).catch(() => {
|
|
17397
|
+
});
|
|
17398
|
+
}
|
|
17399
|
+
async function installMenubar(opts) {
|
|
17400
|
+
if (!isMac2()) {
|
|
17401
|
+
console.log(NON_MAC_MSG2);
|
|
17402
|
+
return;
|
|
17403
|
+
}
|
|
17404
|
+
const src = bundledAppPath();
|
|
17405
|
+
if (!existsSync16(src)) {
|
|
17406
|
+
console.error(
|
|
17407
|
+
`Bundled widget not found at ${src}.
|
|
17408
|
+
This install was probably built without the menubar artifact. Run \`node apps/menubar/build-app.sh && cp -R apps/menubar/dist/FleetlensMenubar.app packages/cli/menubar/\` and rebuild.`
|
|
17409
|
+
);
|
|
17410
|
+
process.exit(1);
|
|
17411
|
+
}
|
|
17412
|
+
const destDir = join12(homedir6(), "Applications");
|
|
17413
|
+
mkdirSync13(destDir, { recursive: true });
|
|
17414
|
+
const dest = installedAppPath();
|
|
17415
|
+
if (await isRunning()) {
|
|
17416
|
+
console.log("Stopping the running widget\u2026");
|
|
17417
|
+
await quitApp();
|
|
17418
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
17419
|
+
}
|
|
17420
|
+
rmSync2(dest, { recursive: true, force: true });
|
|
17421
|
+
cpSync(src, dest, { recursive: true });
|
|
17422
|
+
writeCliLaunchFile();
|
|
17423
|
+
console.log(`Installed \u2192 ${dest}`);
|
|
17424
|
+
if (opts.login) {
|
|
17425
|
+
await setLoginItem(true, dest);
|
|
17426
|
+
console.log("Login item enabled (launches at login).");
|
|
17427
|
+
}
|
|
17428
|
+
if (opts.open) {
|
|
17429
|
+
await launchApp(dest);
|
|
17430
|
+
console.log("Opened \u2014 check your menu bar (gauge icon on the right side).");
|
|
17431
|
+
} else {
|
|
17432
|
+
console.log(`Launch with: open -a "${dest}"`);
|
|
17433
|
+
}
|
|
17434
|
+
}
|
|
17435
|
+
async function uninstallMenubar() {
|
|
17436
|
+
if (!isMac2()) {
|
|
17437
|
+
console.log(NON_MAC_MSG2);
|
|
17438
|
+
return;
|
|
17439
|
+
}
|
|
17440
|
+
await setLoginItem(false, installedAppPath());
|
|
17441
|
+
if (await isRunning()) {
|
|
17442
|
+
console.log("Quitting the running widget\u2026");
|
|
17443
|
+
await quitApp();
|
|
17444
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
17445
|
+
}
|
|
17446
|
+
const dest = installedAppPath();
|
|
17447
|
+
if (existsSync16(dest)) {
|
|
17448
|
+
rmSync2(dest, { recursive: true, force: true });
|
|
17449
|
+
console.log(`Removed ${dest}`);
|
|
17450
|
+
} else {
|
|
17451
|
+
console.log("Widget is not installed \u2014 nothing to remove.");
|
|
17452
|
+
}
|
|
17453
|
+
console.log("Login item cleared (if it was set).");
|
|
17454
|
+
}
|
|
17455
|
+
async function openMenubar() {
|
|
17456
|
+
if (!isMac2()) {
|
|
17457
|
+
console.log(NON_MAC_MSG2);
|
|
17458
|
+
return;
|
|
17459
|
+
}
|
|
17460
|
+
const dest = installedAppPath();
|
|
17461
|
+
if (!existsSync16(dest)) {
|
|
17462
|
+
console.log("Widget not installed yet. Run `fleetlens menubar install` first.");
|
|
17463
|
+
return;
|
|
17464
|
+
}
|
|
17465
|
+
if (await isRunning()) {
|
|
17466
|
+
console.log("Widget is already running.");
|
|
17467
|
+
return;
|
|
17468
|
+
}
|
|
17469
|
+
await launchApp(dest);
|
|
17470
|
+
console.log("Opened \u2014 check your menu bar.");
|
|
17471
|
+
}
|
|
17472
|
+
async function statusMenubar() {
|
|
17473
|
+
if (!isMac2()) {
|
|
17474
|
+
console.log(`Menu bar widget: macOS-only (not available on ${process.platform}).`);
|
|
17475
|
+
return;
|
|
17476
|
+
}
|
|
17477
|
+
const dest = installedAppPath();
|
|
17478
|
+
const installed = existsSync16(dest);
|
|
17479
|
+
const running = await isRunning();
|
|
17480
|
+
const bundled = existsSync16(bundledAppPath());
|
|
17481
|
+
console.log(`Menu bar widget: ${installed ? "installed" : "not installed"}${installed ? ` (${dest})` : ""}`);
|
|
17482
|
+
console.log(`Running: ${running ? "yes" : "no"}`);
|
|
17483
|
+
console.log(`Bundled in CLI: ${bundled ? "yes" : "no \u2014 this build ships without the widget"}`);
|
|
17484
|
+
if (installed) {
|
|
17485
|
+
try {
|
|
17486
|
+
const apps = readdirSync4(join12(homedir6(), "Applications"));
|
|
17487
|
+
const ours = apps.find((a) => a === APP_BUNDLE);
|
|
17488
|
+
console.log(`App bundle: ${ours ? "present in ~/Applications" : "missing"}`);
|
|
17489
|
+
} catch {
|
|
17490
|
+
}
|
|
17491
|
+
}
|
|
17492
|
+
}
|
|
17493
|
+
async function menubar(args2) {
|
|
17494
|
+
const sub = args2[0] ?? "status";
|
|
17495
|
+
const flags = args2.slice(1);
|
|
17496
|
+
const noOpen = flags.includes("--no-open");
|
|
17497
|
+
const noLogin = flags.includes("--no-login");
|
|
17498
|
+
switch (sub) {
|
|
17499
|
+
case "install": {
|
|
17500
|
+
await installMenubar({ open: !noOpen, login: !noLogin });
|
|
17501
|
+
break;
|
|
17502
|
+
}
|
|
17503
|
+
case "uninstall":
|
|
17504
|
+
case "remove":
|
|
17505
|
+
await uninstallMenubar();
|
|
17506
|
+
break;
|
|
17507
|
+
case "open":
|
|
17508
|
+
case "start":
|
|
17509
|
+
await openMenubar();
|
|
17510
|
+
break;
|
|
17511
|
+
case "stop":
|
|
17512
|
+
case "quit":
|
|
17513
|
+
if (await isRunning()) {
|
|
17514
|
+
await quitApp();
|
|
17515
|
+
console.log("Stopped.");
|
|
17516
|
+
} else {
|
|
17517
|
+
console.log("Widget is not running.");
|
|
17518
|
+
}
|
|
17519
|
+
break;
|
|
17520
|
+
case "status":
|
|
17521
|
+
await statusMenubar();
|
|
17522
|
+
break;
|
|
17523
|
+
case "help":
|
|
17524
|
+
case "--help":
|
|
17525
|
+
case "-h":
|
|
17526
|
+
console.log(`Usage: fleetlens menubar <install|uninstall|open|stop|status>
|
|
17527
|
+
|
|
17528
|
+
install [--no-open] [--no-login] Copy the native macOS menu bar widget to
|
|
17529
|
+
~/Applications and launch it. Registers a
|
|
17530
|
+
login item by default.
|
|
17531
|
+
uninstall Quit + remove the widget, clear login item.
|
|
17532
|
+
open Launch the installed widget.
|
|
17533
|
+
stop Quit the running widget.
|
|
17534
|
+
status Show install/running/bundled state.
|
|
17535
|
+
|
|
17536
|
+
The widget tails ~/.cclens/usage.jsonl and shows live Claude Code / Codex
|
|
17537
|
+
plan utilization in the menu bar. Click it for a popover, or "Dashboard" to
|
|
17538
|
+
open http://localhost:3321.`);
|
|
17539
|
+
break;
|
|
17540
|
+
default:
|
|
17541
|
+
console.error(
|
|
17542
|
+
`Unknown menubar subcommand: ${sub}
|
|
17543
|
+
Usage: fleetlens menubar <install|uninstall|open|stop|status>`
|
|
17544
|
+
);
|
|
17545
|
+
process.exit(1);
|
|
17546
|
+
}
|
|
17547
|
+
}
|
|
17548
|
+
var execFileAsync2, APP_BUNDLE, BUNDLE_EXEC, NON_MAC_MSG2;
|
|
17549
|
+
var init_menubar = __esm({
|
|
17550
|
+
"src/commands/menubar.ts"() {
|
|
17551
|
+
"use strict";
|
|
17552
|
+
init_fs();
|
|
17553
|
+
execFileAsync2 = promisify2(execFile2);
|
|
17554
|
+
APP_BUNDLE = "FleetlensMenubar.app";
|
|
17555
|
+
BUNDLE_EXEC = "FleetlensMenubar";
|
|
17556
|
+
NON_MAC_MSG2 = "The Fleetlens menu bar widget is a native macOS app and is macOS-only. On Linux/Windows, keep using the dashboard at the printed URL.";
|
|
17557
|
+
}
|
|
17558
|
+
});
|
|
17559
|
+
|
|
17142
17560
|
// src/team/config.ts
|
|
17143
17561
|
var init_config = __esm({
|
|
17144
17562
|
"src/team/config.ts"() {
|
|
@@ -17148,8 +17566,8 @@ var init_config = __esm({
|
|
|
17148
17566
|
});
|
|
17149
17567
|
|
|
17150
17568
|
// src/perception/build-entries.ts
|
|
17151
|
-
import { statSync as statSync4, readFileSync as
|
|
17152
|
-
import { basename as basename2, dirname as
|
|
17569
|
+
import { statSync as statSync4, readFileSync as readFileSync17 } from "node:fs";
|
|
17570
|
+
import { basename as basename2, dirname as dirname13 } from "node:path";
|
|
17153
17571
|
function decodeProjectDirName(projectDir) {
|
|
17154
17572
|
if (projectDir.startsWith("-")) {
|
|
17155
17573
|
return "/" + projectDir.slice(1).replace(/-/g, "/");
|
|
@@ -17158,7 +17576,7 @@ function decodeProjectDirName(projectDir) {
|
|
|
17158
17576
|
}
|
|
17159
17577
|
function buildEntriesForFile(filePath) {
|
|
17160
17578
|
const stat = statSync4(filePath);
|
|
17161
|
-
const raw =
|
|
17579
|
+
const raw = readFileSync17(filePath, "utf8");
|
|
17162
17580
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
17163
17581
|
try {
|
|
17164
17582
|
return JSON.parse(l);
|
|
@@ -17169,7 +17587,7 @@ function buildEntriesForFile(filePath) {
|
|
|
17169
17587
|
if (rawLines.length === 0) return null;
|
|
17170
17588
|
const { meta, events } = parseTranscript(rawLines);
|
|
17171
17589
|
const fileName = basename2(filePath);
|
|
17172
|
-
const projectDir = basename2(
|
|
17590
|
+
const projectDir = basename2(dirname13(filePath));
|
|
17173
17591
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
17174
17592
|
const sd = {
|
|
17175
17593
|
...meta,
|
|
@@ -17423,7 +17841,7 @@ function buildIngestPayload(inputs) {
|
|
|
17423
17841
|
return {
|
|
17424
17842
|
ingestId: randomUUID2(),
|
|
17425
17843
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17426
|
-
cliVersion: "0.15.
|
|
17844
|
+
cliVersion: "0.15.4",
|
|
17427
17845
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
17428
17846
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
17429
17847
|
...richRollup ? { richRollup } : {},
|
|
@@ -17464,8 +17882,8 @@ var init_push = __esm({
|
|
|
17464
17882
|
});
|
|
17465
17883
|
|
|
17466
17884
|
// src/team/git-remote.ts
|
|
17467
|
-
import { existsSync as
|
|
17468
|
-
import { dirname as
|
|
17885
|
+
import { existsSync as existsSync17, readFileSync as readFileSync18, statSync as statSync5 } from "node:fs";
|
|
17886
|
+
import { dirname as dirname14, isAbsolute as isAbsolute2, join as join13, resolve as resolve2 } from "node:path";
|
|
17469
17887
|
function parseGithubRemote(url) {
|
|
17470
17888
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
17471
17889
|
return m ? `${m[1]}/${m[2]}`.toLowerCase() : null;
|
|
@@ -17485,19 +17903,19 @@ function originUrl2(configText) {
|
|
|
17485
17903
|
return null;
|
|
17486
17904
|
}
|
|
17487
17905
|
function gitConfigPathFor(dir) {
|
|
17488
|
-
const dotGit =
|
|
17906
|
+
const dotGit = join13(dir, ".git");
|
|
17489
17907
|
const st = statSync5(dotGit, { throwIfNoEntry: false });
|
|
17490
17908
|
if (!st) return null;
|
|
17491
|
-
if (st.isDirectory()) return
|
|
17492
|
-
const m =
|
|
17909
|
+
if (st.isDirectory()) return join13(dotGit, "config");
|
|
17910
|
+
const m = readFileSync18(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
17493
17911
|
if (!m) return null;
|
|
17494
17912
|
const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
|
|
17495
|
-
const commondirFile =
|
|
17496
|
-
if (
|
|
17497
|
-
const common =
|
|
17498
|
-
return
|
|
17913
|
+
const commondirFile = join13(gd, "commondir");
|
|
17914
|
+
if (existsSync17(commondirFile)) {
|
|
17915
|
+
const common = readFileSync18(commondirFile, "utf8").trim();
|
|
17916
|
+
return join13(isAbsolute2(common) ? common : resolve2(gd, common), "config");
|
|
17499
17917
|
}
|
|
17500
|
-
return
|
|
17918
|
+
return join13(gd, "config");
|
|
17501
17919
|
}
|
|
17502
17920
|
function createRepoResolver() {
|
|
17503
17921
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -17507,14 +17925,14 @@ function createRepoResolver() {
|
|
|
17507
17925
|
if (hit !== void 0) return hit;
|
|
17508
17926
|
let repo = null;
|
|
17509
17927
|
try {
|
|
17510
|
-
for (let d = dir; ; d =
|
|
17928
|
+
for (let d = dir; ; d = dirname14(d)) {
|
|
17511
17929
|
const config = gitConfigPathFor(d);
|
|
17512
|
-
if (config &&
|
|
17513
|
-
const url = originUrl2(
|
|
17930
|
+
if (config && existsSync17(config)) {
|
|
17931
|
+
const url = originUrl2(readFileSync18(config, "utf8"));
|
|
17514
17932
|
repo = url ? parseGithubRemote(url) : null;
|
|
17515
17933
|
break;
|
|
17516
17934
|
}
|
|
17517
|
-
if (d ===
|
|
17935
|
+
if (d === dirname14(d)) break;
|
|
17518
17936
|
}
|
|
17519
17937
|
} catch {
|
|
17520
17938
|
repo = null;
|
|
@@ -17532,12 +17950,12 @@ var init_git_remote = __esm({
|
|
|
17532
17950
|
});
|
|
17533
17951
|
|
|
17534
17952
|
// src/team/queue.ts
|
|
17535
|
-
import { readFileSync as
|
|
17536
|
-
import { dirname as
|
|
17953
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync14, appendFileSync as appendFileSync5, statSync as statSync6, mkdirSync as mkdirSync14 } from "node:fs";
|
|
17954
|
+
import { dirname as dirname15 } from "node:path";
|
|
17537
17955
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
17538
|
-
|
|
17956
|
+
mkdirSync14(dirname15(queuePath), { recursive: true });
|
|
17539
17957
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
17540
|
-
|
|
17958
|
+
appendFileSync5(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
17541
17959
|
try {
|
|
17542
17960
|
const { size } = statSync6(queuePath);
|
|
17543
17961
|
if (size > MAX_SIZE_BYTES) {
|
|
@@ -17549,7 +17967,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
17549
17967
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
17550
17968
|
let lines;
|
|
17551
17969
|
try {
|
|
17552
|
-
lines =
|
|
17970
|
+
lines = readFileSync19(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
17553
17971
|
} catch {
|
|
17554
17972
|
return [];
|
|
17555
17973
|
}
|
|
@@ -17564,18 +17982,18 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
17564
17982
|
} catch {
|
|
17565
17983
|
}
|
|
17566
17984
|
}
|
|
17567
|
-
|
|
17985
|
+
writeFileSync14(queuePath, "", "utf8");
|
|
17568
17986
|
return valid.map((e) => e.payload);
|
|
17569
17987
|
}
|
|
17570
17988
|
function pruneOldest(queuePath) {
|
|
17571
17989
|
let lines;
|
|
17572
17990
|
try {
|
|
17573
|
-
lines =
|
|
17991
|
+
lines = readFileSync19(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
17574
17992
|
} catch {
|
|
17575
17993
|
return;
|
|
17576
17994
|
}
|
|
17577
17995
|
const keep = lines.slice(Math.floor(lines.length / 2));
|
|
17578
|
-
|
|
17996
|
+
writeFileSync14(queuePath, keep.join("\n") + "\n", "utf8");
|
|
17579
17997
|
}
|
|
17580
17998
|
var QUEUE_PATH, MAX_SIZE_BYTES, MAX_AGE_MS;
|
|
17581
17999
|
var init_queue2 = __esm({
|
|
@@ -17589,8 +18007,8 @@ var init_queue2 = __esm({
|
|
|
17589
18007
|
});
|
|
17590
18008
|
|
|
17591
18009
|
// src/usage/profile.ts
|
|
17592
|
-
import { existsSync as
|
|
17593
|
-
import { dirname as
|
|
18010
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync15, readFileSync as readFileSync20, writeFileSync as writeFileSync15 } from "node:fs";
|
|
18011
|
+
import { dirname as dirname16 } from "node:path";
|
|
17594
18012
|
function mapRateLimitTier(rateLimitTier) {
|
|
17595
18013
|
switch (rateLimitTier) {
|
|
17596
18014
|
case "default_claude_pro":
|
|
@@ -17630,9 +18048,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
17630
18048
|
};
|
|
17631
18049
|
}
|
|
17632
18050
|
function readCachedProfile(cachePath) {
|
|
17633
|
-
if (!
|
|
18051
|
+
if (!existsSync18(cachePath)) return null;
|
|
17634
18052
|
try {
|
|
17635
|
-
const raw = JSON.parse(
|
|
18053
|
+
const raw = JSON.parse(readFileSync20(cachePath, "utf8"));
|
|
17636
18054
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
17637
18055
|
return raw;
|
|
17638
18056
|
} catch {
|
|
@@ -17640,8 +18058,8 @@ function readCachedProfile(cachePath) {
|
|
|
17640
18058
|
}
|
|
17641
18059
|
}
|
|
17642
18060
|
function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
|
|
17643
|
-
|
|
17644
|
-
|
|
18061
|
+
mkdirSync15(dirname16(cachePath), { recursive: true });
|
|
18062
|
+
writeFileSync15(
|
|
17645
18063
|
cachePath,
|
|
17646
18064
|
JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
|
|
17647
18065
|
{ mode: 384 }
|
|
@@ -17821,11 +18239,11 @@ var init_backfill = __esm({
|
|
|
17821
18239
|
});
|
|
17822
18240
|
|
|
17823
18241
|
// src/team/sync-log.ts
|
|
17824
|
-
import { readFileSync as
|
|
18242
|
+
import { readFileSync as readFileSync21 } from "node:fs";
|
|
17825
18243
|
function readPendingSyncLog(watermark) {
|
|
17826
18244
|
let raw;
|
|
17827
18245
|
try {
|
|
17828
|
-
raw =
|
|
18246
|
+
raw = readFileSync21(cclensPath("daemon.log"), "utf8");
|
|
17829
18247
|
} catch {
|
|
17830
18248
|
return { lines: [] };
|
|
17831
18249
|
}
|
|
@@ -17853,12 +18271,12 @@ var init_sync_log = __esm({
|
|
|
17853
18271
|
});
|
|
17854
18272
|
|
|
17855
18273
|
// src/team/last-push.ts
|
|
17856
|
-
import { writeFileSync as
|
|
17857
|
-
import { join as
|
|
18274
|
+
import { writeFileSync as writeFileSync16, unlinkSync as unlinkSync6, mkdirSync as mkdirSync16 } from "node:fs";
|
|
18275
|
+
import { join as join14 } from "node:path";
|
|
17858
18276
|
function write(record, dir) {
|
|
17859
18277
|
const d = dir ?? cclensHome();
|
|
17860
|
-
|
|
17861
|
-
|
|
18278
|
+
mkdirSync16(d, { recursive: true });
|
|
18279
|
+
writeFileSync16(join14(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
17862
18280
|
}
|
|
17863
18281
|
function writeLastPushSuccess(payload, dir) {
|
|
17864
18282
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -17869,7 +18287,7 @@ function writeLastPushFailure(payload, error, dir) {
|
|
|
17869
18287
|
function clearLastPush(dir) {
|
|
17870
18288
|
const d = dir ?? cclensHome();
|
|
17871
18289
|
try {
|
|
17872
|
-
|
|
18290
|
+
unlinkSync6(join14(d, LAST_PUSH_FILE));
|
|
17873
18291
|
} catch {
|
|
17874
18292
|
}
|
|
17875
18293
|
}
|
|
@@ -17889,35 +18307,35 @@ __export(file_probe_exports, {
|
|
|
17889
18307
|
probeArtifactSignals: () => probeArtifactSignals
|
|
17890
18308
|
});
|
|
17891
18309
|
import { createHash } from "node:crypto";
|
|
17892
|
-
import { existsSync as
|
|
17893
|
-
import { homedir as
|
|
17894
|
-
import { join as
|
|
18310
|
+
import { existsSync as existsSync19, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
|
|
18311
|
+
import { homedir as homedir7 } from "node:os";
|
|
18312
|
+
import { join as join15, relative, resolve as resolve3, sep } from "node:path";
|
|
17895
18313
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
17896
18314
|
function pathHash(relPath) {
|
|
17897
18315
|
return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
17898
18316
|
}
|
|
17899
18317
|
function defaultScanRoots(extraRoots = []) {
|
|
17900
18318
|
const roots = [];
|
|
17901
|
-
const home =
|
|
17902
|
-
if (
|
|
18319
|
+
const home = join15(homedir7(), ".claude");
|
|
18320
|
+
if (existsSync19(home)) roots.push({ root: home, label: "user" });
|
|
17903
18321
|
for (const e of extraRoots) {
|
|
17904
18322
|
const r = resolve3(e, ".claude");
|
|
17905
|
-
if (
|
|
18323
|
+
if (existsSync19(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
17906
18324
|
}
|
|
17907
18325
|
return roots;
|
|
17908
18326
|
}
|
|
17909
18327
|
function listMarkdownFiles(dir) {
|
|
17910
|
-
if (!
|
|
18328
|
+
if (!existsSync19(dir)) return [];
|
|
17911
18329
|
const out = [];
|
|
17912
18330
|
let entries2;
|
|
17913
18331
|
try {
|
|
17914
|
-
entries2 =
|
|
18332
|
+
entries2 = readdirSync5(dir);
|
|
17915
18333
|
} catch {
|
|
17916
18334
|
return [];
|
|
17917
18335
|
}
|
|
17918
18336
|
for (const name of entries2) {
|
|
17919
18337
|
if (name.startsWith(".")) continue;
|
|
17920
|
-
const full =
|
|
18338
|
+
const full = join15(dir, name);
|
|
17921
18339
|
let stat;
|
|
17922
18340
|
try {
|
|
17923
18341
|
stat = statSync7(full);
|
|
@@ -17937,7 +18355,7 @@ function firstSeenDateOf(file) {
|
|
|
17937
18355
|
const out = execFileSync3(
|
|
17938
18356
|
"git",
|
|
17939
18357
|
["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
|
|
17940
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
18358
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname17(file) }
|
|
17941
18359
|
).trim().split("\n").filter(Boolean);
|
|
17942
18360
|
if (out.length > 0) return out[out.length - 1];
|
|
17943
18361
|
} catch {
|
|
@@ -17949,7 +18367,7 @@ function firstSeenDateOf(file) {
|
|
|
17949
18367
|
return todayLocal();
|
|
17950
18368
|
}
|
|
17951
18369
|
}
|
|
17952
|
-
function
|
|
18370
|
+
function dirname17(p) {
|
|
17953
18371
|
const i = p.lastIndexOf(sep);
|
|
17954
18372
|
return i < 0 ? "." : p.slice(0, i);
|
|
17955
18373
|
}
|
|
@@ -17976,8 +18394,8 @@ function todayLocal() {
|
|
|
17976
18394
|
function scanAuthored(roots, subdir, day2) {
|
|
17977
18395
|
const out = [];
|
|
17978
18396
|
for (const r of roots) {
|
|
17979
|
-
const dir =
|
|
17980
|
-
if (!
|
|
18397
|
+
const dir = join15(r.root, subdir);
|
|
18398
|
+
if (!existsSync19(dir)) continue;
|
|
17981
18399
|
for (const f of listMarkdownFiles(dir)) {
|
|
17982
18400
|
const firstSeen = firstSeenDateOf(f);
|
|
17983
18401
|
if (firstSeen !== day2) continue;
|
|
@@ -17990,8 +18408,8 @@ function scanAuthored(roots, subdir, day2) {
|
|
|
17990
18408
|
function scanEdited(roots, day2) {
|
|
17991
18409
|
const out = [];
|
|
17992
18410
|
for (const r of roots) {
|
|
17993
|
-
const dir =
|
|
17994
|
-
if (!
|
|
18411
|
+
const dir = join15(r.root, "skills");
|
|
18412
|
+
if (!existsSync19(dir)) continue;
|
|
17995
18413
|
for (const f of listMarkdownFiles(dir)) {
|
|
17996
18414
|
const firstSeen = firstSeenDateOf(f);
|
|
17997
18415
|
if (firstSeen === day2) continue;
|
|
@@ -18014,16 +18432,16 @@ function claudemdLineDelta(extraRoots, authorEmail, day2) {
|
|
|
18014
18432
|
const candidates = [];
|
|
18015
18433
|
for (const e of extraRoots) {
|
|
18016
18434
|
const f = resolve3(e, "CLAUDE.md");
|
|
18017
|
-
if (
|
|
18435
|
+
if (existsSync19(f)) candidates.push(f);
|
|
18018
18436
|
}
|
|
18019
|
-
const homeClaudeMd =
|
|
18020
|
-
if (
|
|
18437
|
+
const homeClaudeMd = join15(homedir7(), "CLAUDE.md");
|
|
18438
|
+
if (existsSync19(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
18021
18439
|
for (const file of candidates) {
|
|
18022
18440
|
try {
|
|
18023
18441
|
const out = execFileSync3(
|
|
18024
18442
|
"git",
|
|
18025
18443
|
["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
|
|
18026
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
18444
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname17(file) }
|
|
18027
18445
|
);
|
|
18028
18446
|
let currentDate = "";
|
|
18029
18447
|
let currentEmail = "";
|
|
@@ -18674,10 +19092,10 @@ var daemon_log_exports = {};
|
|
|
18674
19092
|
__export(daemon_log_exports, {
|
|
18675
19093
|
appendDaemonLogLine: () => appendDaemonLogLine
|
|
18676
19094
|
});
|
|
18677
|
-
import { appendFileSync as
|
|
19095
|
+
import { appendFileSync as appendFileSync6 } from "node:fs";
|
|
18678
19096
|
function appendDaemonLogLine(level, msg) {
|
|
18679
19097
|
try {
|
|
18680
|
-
|
|
19098
|
+
appendFileSync6(
|
|
18681
19099
|
cclensPath("daemon.log"),
|
|
18682
19100
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${level.toUpperCase()} ${msg}
|
|
18683
19101
|
`,
|
|
@@ -18890,11 +19308,11 @@ var logs_exports = {};
|
|
|
18890
19308
|
__export(logs_exports, {
|
|
18891
19309
|
teamLogs: () => teamLogs
|
|
18892
19310
|
});
|
|
18893
|
-
import { readFileSync as
|
|
19311
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
18894
19312
|
async function teamLogs() {
|
|
18895
19313
|
const logPath = cclensPath("daemon.log");
|
|
18896
19314
|
try {
|
|
18897
|
-
const lines =
|
|
19315
|
+
const lines = readFileSync22(logPath, "utf8").trim().split("\n");
|
|
18898
19316
|
const teamLines = lines.filter((l) => l.includes("[sync] ") || l.includes("team "));
|
|
18899
19317
|
if (teamLines.length === 0) {
|
|
18900
19318
|
console.log("No team-related log entries found.");
|
|
@@ -19022,8 +19440,8 @@ __export(runs_exports, {
|
|
|
19022
19440
|
runs: () => runs
|
|
19023
19441
|
});
|
|
19024
19442
|
import { execSync as execSync2 } from "node:child_process";
|
|
19025
|
-
import { existsSync as
|
|
19026
|
-
import { join as
|
|
19443
|
+
import { existsSync as existsSync20, readFileSync as readFileSync23, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
|
|
19444
|
+
import { join as join16 } from "node:path";
|
|
19027
19445
|
async function runs(args2) {
|
|
19028
19446
|
const json = args2.includes("--json");
|
|
19029
19447
|
const watch = args2.includes("--watch");
|
|
@@ -19107,8 +19525,8 @@ function listActiveRuns() {
|
|
|
19107
19525
|
return runs2.sort((a, b) => a.elapsed_s - b.elapsed_s);
|
|
19108
19526
|
}
|
|
19109
19527
|
function readSpend(sinceMs) {
|
|
19110
|
-
if (!
|
|
19111
|
-
const lines =
|
|
19528
|
+
if (!existsSync20(SPEND_PATH)) return [];
|
|
19529
|
+
const lines = readFileSync23(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
|
|
19112
19530
|
const out = [];
|
|
19113
19531
|
for (const line of lines) {
|
|
19114
19532
|
try {
|
|
@@ -19229,23 +19647,23 @@ function ageLabel(ms) {
|
|
|
19229
19647
|
return `${Math.floor(ms / 864e5)}d`;
|
|
19230
19648
|
}
|
|
19231
19649
|
function listTraceFiles() {
|
|
19232
|
-
if (!
|
|
19233
|
-
const entries2 =
|
|
19650
|
+
if (!existsSync20(RUNS_DIR2)) return [];
|
|
19651
|
+
const entries2 = readdirSync6(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
|
|
19234
19652
|
return entries2.map((f) => {
|
|
19235
|
-
const path7 =
|
|
19653
|
+
const path7 = join16(RUNS_DIR2, f);
|
|
19236
19654
|
const st = statSync8(path7);
|
|
19237
19655
|
return { runId: f.replace(/\.jsonl$/, ""), path: path7, mtimeMs: st.mtimeMs };
|
|
19238
19656
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
19239
19657
|
}
|
|
19240
19658
|
function resolveRunId(arg) {
|
|
19241
|
-
if (!
|
|
19659
|
+
if (!existsSync20(RUNS_DIR2)) return null;
|
|
19242
19660
|
if (arg === "latest") {
|
|
19243
19661
|
const all2 = listTraceFiles();
|
|
19244
19662
|
if (all2.length === 0) return null;
|
|
19245
19663
|
return { runId: all2[0].runId, path: all2[0].path };
|
|
19246
19664
|
}
|
|
19247
|
-
const exact =
|
|
19248
|
-
if (
|
|
19665
|
+
const exact = join16(RUNS_DIR2, `${arg}.jsonl`);
|
|
19666
|
+
if (existsSync20(exact)) return { runId: arg, path: exact };
|
|
19249
19667
|
const all = listTraceFiles();
|
|
19250
19668
|
const matches = all.filter((r) => r.runId.includes(arg));
|
|
19251
19669
|
if (matches.length === 1) return { runId: matches[0].runId, path: matches[0].path };
|
|
@@ -19257,7 +19675,7 @@ function resolveRunId(arg) {
|
|
|
19257
19675
|
return null;
|
|
19258
19676
|
}
|
|
19259
19677
|
function readTrace(path7) {
|
|
19260
|
-
return
|
|
19678
|
+
return readFileSync23(path7, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
|
|
19261
19679
|
try {
|
|
19262
19680
|
return JSON.parse(l);
|
|
19263
19681
|
} catch {
|
|
@@ -19269,7 +19687,7 @@ async function inspect(arg, follow, json) {
|
|
|
19269
19687
|
const r = resolveRunId(arg);
|
|
19270
19688
|
if (!r) {
|
|
19271
19689
|
console.error(`run not found: ${arg}`);
|
|
19272
|
-
if (
|
|
19690
|
+
if (existsSync20(RUNS_DIR2)) {
|
|
19273
19691
|
const all = listTraceFiles().slice(0, 5);
|
|
19274
19692
|
if (all.length > 0) {
|
|
19275
19693
|
console.error(`
|
|
@@ -19431,6 +19849,11 @@ async function main() {
|
|
|
19431
19849
|
await autostart2(args.slice(1));
|
|
19432
19850
|
break;
|
|
19433
19851
|
}
|
|
19852
|
+
case "menubar": {
|
|
19853
|
+
const { menubar: menubar2 } = await Promise.resolve().then(() => (init_menubar(), menubar_exports));
|
|
19854
|
+
await menubar2(args.slice(1));
|
|
19855
|
+
break;
|
|
19856
|
+
}
|
|
19434
19857
|
case "team": {
|
|
19435
19858
|
const { team: team2 } = await Promise.resolve().then(() => (init_team2(), team_exports));
|
|
19436
19859
|
await team2(args.slice(1));
|
|
@@ -19444,7 +19867,7 @@ async function main() {
|
|
|
19444
19867
|
case "version":
|
|
19445
19868
|
case "--version":
|
|
19446
19869
|
case "-v":
|
|
19447
|
-
console.log(`fleetlens ${"0.15.
|
|
19870
|
+
console.log(`fleetlens ${"0.15.4"}`);
|
|
19448
19871
|
break;
|
|
19449
19872
|
case "help":
|
|
19450
19873
|
case "--help":
|
|
@@ -19471,6 +19894,7 @@ Advanced:
|
|
|
19471
19894
|
start --no-daemon Start only the web server (no daemon)
|
|
19472
19895
|
daemon <start|stop|status|logs> Manage the usage daemon by itself
|
|
19473
19896
|
autostart <install|uninstall|status> Run the usage daemon at login (macOS launchd)
|
|
19897
|
+
menubar <install|uninstall|open|status> Native macOS menu bar widget (Claude/Codex/Z.ai usage)
|
|
19474
19898
|
|
|
19475
19899
|
Team:
|
|
19476
19900
|
team join <url> <token> Pair with a team server (browser setup)
|