fleetlens 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/build-manifest.json +3 -3
- package/app/apps/web/.next/prerender-manifest.json +3 -3
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +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_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__02.51sr._.js +1 -1
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0zyh554._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0s~wd1k._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0epqfet._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0x014hn._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/00_9zw_tjem-o.js +14 -0
- package/app/apps/web/.next/static/chunks/0266xq7gs43sq.js +1 -0
- package/app/apps/web/.next/static/chunks/{0r~~~j3kmv7s_.js → 08os0c_3cdpqn.js} +1 -1
- package/app/apps/web/app/usage/page.tsx +264 -1
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/usage-data.ts +1 -1
- package/app/apps/web/lib/usage-display.test.ts +15 -0
- package/app/apps/web/lib/usage-display.ts +22 -3
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +689 -265
- package/dist/index.js +920 -284
- package/menubar/Fleetlens.app/Contents/Info.plist +2 -2
- package/menubar/Fleetlens.app/Contents/MacOS/FleetlensMenubar +0 -0
- package/menubar/Fleetlens.app/Contents/Resources/command-code.svg +4 -0
- package/menubar/Fleetlens.app/Contents/_CodeSignature/CodeResources +11 -0
- package/package.json +1 -1
- package/app/apps/web/.next/static/chunks/0lcq6isl3n79m.js +0 -1
- package/app/apps/web/.next/static/chunks/0livk1wjx5m4o.js +0 -14
- /package/app/apps/web/.next/static/{h9pB-Efqh5oayfi0_lGfY → HNG9JDuajDbJlU07fqf3C}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{h9pB-Efqh5oayfi0_lGfY → HNG9JDuajDbJlU07fqf3C}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{h9pB-Efqh5oayfi0_lGfY → HNG9JDuajDbJlU07fqf3C}/_ssgManifest.js +0 -0
package/dist/daemon-worker.js
CHANGED
|
@@ -607,7 +607,7 @@ function getAgentMetadata(kind) {
|
|
|
607
607
|
function isAgentKind(s) {
|
|
608
608
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
609
609
|
}
|
|
610
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, COPILOT_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
610
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, COPILOT_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, COMMAND_CODE_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
611
611
|
var init_agent_metadata = __esm({
|
|
612
612
|
"../parser/dist/agent-metadata.js"() {
|
|
613
613
|
"use strict";
|
|
@@ -668,6 +668,14 @@ var init_agent_metadata = __esm({
|
|
|
668
668
|
accentColor: "rgb(100, 116, 139)",
|
|
669
669
|
iconChar: "\u25C8"
|
|
670
670
|
};
|
|
671
|
+
COMMAND_CODE_METADATA = {
|
|
672
|
+
kind: "command-code",
|
|
673
|
+
displayName: "Command Code",
|
|
674
|
+
shortLabel: "Cmd",
|
|
675
|
+
// Lime — distinct from Codex teal and Claude terracotta.
|
|
676
|
+
accentColor: "rgb(132, 204, 22)",
|
|
677
|
+
iconChar: ">"
|
|
678
|
+
};
|
|
671
679
|
agentMetadata = [
|
|
672
680
|
CLAUDE_CODE_METADATA,
|
|
673
681
|
CODEX_METADATA,
|
|
@@ -676,7 +684,8 @@ var init_agent_metadata = __esm({
|
|
|
676
684
|
ANTIGRAVITY_METADATA,
|
|
677
685
|
COWORK_METADATA,
|
|
678
686
|
ZAI_METADATA,
|
|
679
|
-
GROK_METADATA
|
|
687
|
+
GROK_METADATA,
|
|
688
|
+
COMMAND_CODE_METADATA
|
|
680
689
|
];
|
|
681
690
|
KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
|
|
682
691
|
}
|
|
@@ -1418,39 +1427,39 @@ var init_parser = __esm({
|
|
|
1418
1427
|
});
|
|
1419
1428
|
|
|
1420
1429
|
// ../parser/dist/git-project.js
|
|
1421
|
-
import { existsSync, readFileSync as
|
|
1422
|
-
import { homedir as
|
|
1423
|
-
import { basename, dirname, isAbsolute, join as
|
|
1430
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, realpathSync, statSync as statSync2 } from "node:fs";
|
|
1431
|
+
import { homedir as homedir3 } from "node:os";
|
|
1432
|
+
import { basename as basename2, dirname, isAbsolute, join as join3, resolve as resolve2 } from "node:path";
|
|
1424
1433
|
function resolveGitDir(root, dotGitText) {
|
|
1425
1434
|
const m = dotGitText.match(/^gitdir:\s*(.+)\s*$/m);
|
|
1426
1435
|
if (!m)
|
|
1427
1436
|
return void 0;
|
|
1428
1437
|
const gitDir = m[1].trim();
|
|
1429
|
-
return isAbsolute(gitDir) ? gitDir :
|
|
1438
|
+
return isAbsolute(gitDir) ? gitDir : resolve2(root, gitDir);
|
|
1430
1439
|
}
|
|
1431
1440
|
function resolveCommonDir(gitDir) {
|
|
1432
|
-
const file =
|
|
1433
|
-
if (!
|
|
1441
|
+
const file = join3(gitDir, "commondir");
|
|
1442
|
+
if (!existsSync2(file))
|
|
1434
1443
|
return void 0;
|
|
1435
|
-
const common =
|
|
1444
|
+
const common = readFileSync3(file, "utf8").trim();
|
|
1436
1445
|
if (!common)
|
|
1437
1446
|
return void 0;
|
|
1438
|
-
return isAbsolute(common) ? common :
|
|
1447
|
+
return isAbsolute(common) ? common : resolve2(gitDir, common);
|
|
1439
1448
|
}
|
|
1440
1449
|
function dotGitInfoFor(root) {
|
|
1441
|
-
const dotGit =
|
|
1442
|
-
const st =
|
|
1450
|
+
const dotGit = join3(root, ".git");
|
|
1451
|
+
const st = statSync2(dotGit, { throwIfNoEntry: false });
|
|
1443
1452
|
if (!st)
|
|
1444
1453
|
return null;
|
|
1445
1454
|
if (st.isDirectory())
|
|
1446
1455
|
return { root, gitDir: dotGit, commonDir: dotGit };
|
|
1447
|
-
const gitDir = resolveGitDir(root,
|
|
1456
|
+
const gitDir = resolveGitDir(root, readFileSync3(dotGit, "utf8"));
|
|
1448
1457
|
if (!gitDir)
|
|
1449
1458
|
return { root };
|
|
1450
1459
|
return { root, gitDir, commonDir: resolveCommonDir(gitDir) };
|
|
1451
1460
|
}
|
|
1452
1461
|
function walkBoundary(start) {
|
|
1453
|
-
const home = realpathOrSelf(
|
|
1462
|
+
const home = realpathOrSelf(homedir3());
|
|
1454
1463
|
return start === home || start.startsWith(`${home}/`) ? home : void 0;
|
|
1455
1464
|
}
|
|
1456
1465
|
function nearestDotGit(start) {
|
|
@@ -1500,44 +1509,44 @@ function remoteFor(git) {
|
|
|
1500
1509
|
const dir = git.commonDir ?? git.gitDir;
|
|
1501
1510
|
if (!dir)
|
|
1502
1511
|
return void 0;
|
|
1503
|
-
const config =
|
|
1504
|
-
if (!
|
|
1512
|
+
const config = join3(dir, "config");
|
|
1513
|
+
if (!existsSync2(config))
|
|
1505
1514
|
return void 0;
|
|
1506
|
-
const url = originUrl(
|
|
1515
|
+
const url = originUrl(readFileSync3(config, "utf8"));
|
|
1507
1516
|
return url ? parseRemote(url) : void 0;
|
|
1508
1517
|
}
|
|
1509
1518
|
function headBranch(gitDir) {
|
|
1510
1519
|
if (!gitDir)
|
|
1511
1520
|
return void 0;
|
|
1512
|
-
const head =
|
|
1513
|
-
if (!
|
|
1521
|
+
const head = join3(gitDir, "HEAD");
|
|
1522
|
+
if (!existsSync2(head))
|
|
1514
1523
|
return void 0;
|
|
1515
|
-
const t =
|
|
1524
|
+
const t = readFileSync3(head, "utf8").trim();
|
|
1516
1525
|
const m = t.match(/^ref:\s*refs\/heads\/(.+)$/);
|
|
1517
1526
|
return m ? m[1] : `detached @ ${t.slice(0, 7)}`;
|
|
1518
1527
|
}
|
|
1519
1528
|
function defaultBranch(commonDir) {
|
|
1520
1529
|
if (!commonDir)
|
|
1521
1530
|
return void 0;
|
|
1522
|
-
const head =
|
|
1523
|
-
if (
|
|
1524
|
-
const m =
|
|
1531
|
+
const head = join3(commonDir, "refs", "remotes", "origin", "HEAD");
|
|
1532
|
+
if (existsSync2(head)) {
|
|
1533
|
+
const m = readFileSync3(head, "utf8").trim().match(/refs\/remotes\/origin\/(.+)$/);
|
|
1525
1534
|
if (m)
|
|
1526
1535
|
return m[1];
|
|
1527
1536
|
}
|
|
1528
|
-
const packed =
|
|
1529
|
-
if (
|
|
1530
|
-
const m =
|
|
1537
|
+
const packed = join3(commonDir, "packed-refs");
|
|
1538
|
+
if (existsSync2(packed)) {
|
|
1539
|
+
const m = readFileSync3(packed, "utf8").match(/refs\/remotes\/origin\/(\S+)/);
|
|
1531
1540
|
if (m && m[1] !== "HEAD")
|
|
1532
1541
|
return m[1];
|
|
1533
1542
|
}
|
|
1534
1543
|
return void 0;
|
|
1535
1544
|
}
|
|
1536
|
-
function readGitFolder(
|
|
1537
|
-
if (!
|
|
1545
|
+
function readGitFolder(path12) {
|
|
1546
|
+
if (!existsSync2(path12))
|
|
1538
1547
|
return { exists: false, isWorktree: false };
|
|
1539
1548
|
try {
|
|
1540
|
-
const git = nearestDotGit(realpathOrSelf(
|
|
1549
|
+
const git = nearestDotGit(realpathOrSelf(path12));
|
|
1541
1550
|
if (!git)
|
|
1542
1551
|
return { exists: true, isWorktree: false };
|
|
1543
1552
|
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
@@ -1556,7 +1565,7 @@ function readGitFolder(path11) {
|
|
|
1556
1565
|
function projectRootFromCommonDir(commonDir) {
|
|
1557
1566
|
if (!commonDir)
|
|
1558
1567
|
return void 0;
|
|
1559
|
-
return
|
|
1568
|
+
return basename2(commonDir) === ".git" ? dirname(commonDir) : void 0;
|
|
1560
1569
|
}
|
|
1561
1570
|
function realpathOrSelf(p) {
|
|
1562
1571
|
try {
|
|
@@ -1572,7 +1581,7 @@ function resolveProjectIdentity(cwd) {
|
|
|
1572
1581
|
if (git) {
|
|
1573
1582
|
const projectRoot = realpathOrSelf(projectRootFromCommonDir(git.commonDir) ?? git.root);
|
|
1574
1583
|
const gitRoot = realpathOrSelf(git.root);
|
|
1575
|
-
const wt2 = projectRoot !== gitRoot ? worktreeName(normalized) ??
|
|
1584
|
+
const wt2 = projectRoot !== gitRoot ? worktreeName(normalized) ?? basename2(git.root) : void 0;
|
|
1576
1585
|
const identity = { projectName: projectRoot };
|
|
1577
1586
|
if (wt2)
|
|
1578
1587
|
identity.worktreeName = wt2;
|
|
@@ -5703,8 +5712,8 @@ var init_grok = __esm({
|
|
|
5703
5712
|
});
|
|
5704
5713
|
|
|
5705
5714
|
// ../parser/dist/team-config.js
|
|
5706
|
-
import { readFileSync as
|
|
5707
|
-
import { join as
|
|
5715
|
+
import { readFileSync as readFileSync4, writeFileSync, unlinkSync, mkdirSync, renameSync } from "node:fs";
|
|
5716
|
+
import { join as join4 } from "node:path";
|
|
5708
5717
|
function shouldSyncProject(projectKey2, sp) {
|
|
5709
5718
|
if (!sp)
|
|
5710
5719
|
return true;
|
|
@@ -5717,7 +5726,7 @@ function shouldSyncProject(projectKey2, sp) {
|
|
|
5717
5726
|
function readTeamConfig(dir) {
|
|
5718
5727
|
const d = dir ?? cclensHome();
|
|
5719
5728
|
try {
|
|
5720
|
-
return JSON.parse(
|
|
5729
|
+
return JSON.parse(readFileSync4(join4(d, CONFIG_FILE), "utf8"));
|
|
5721
5730
|
} catch {
|
|
5722
5731
|
return null;
|
|
5723
5732
|
}
|
|
@@ -5725,14 +5734,14 @@ function readTeamConfig(dir) {
|
|
|
5725
5734
|
function writeTeamConfig(config, dir) {
|
|
5726
5735
|
const d = dir ?? cclensHome();
|
|
5727
5736
|
mkdirSync(d, { recursive: true });
|
|
5728
|
-
const tmp =
|
|
5737
|
+
const tmp = join4(d, `${CONFIG_FILE}.${process.pid}.tmp`);
|
|
5729
5738
|
writeFileSync(tmp, JSON.stringify(config, null, 2), { mode: 384 });
|
|
5730
|
-
renameSync(tmp,
|
|
5739
|
+
renameSync(tmp, join4(d, CONFIG_FILE));
|
|
5731
5740
|
}
|
|
5732
5741
|
function clearTeamConfig(dir) {
|
|
5733
5742
|
const d = dir ?? cclensHome();
|
|
5734
5743
|
try {
|
|
5735
|
-
unlinkSync(
|
|
5744
|
+
unlinkSync(join4(d, CONFIG_FILE));
|
|
5736
5745
|
} catch {
|
|
5737
5746
|
}
|
|
5738
5747
|
}
|
|
@@ -5819,7 +5828,7 @@ __export(fs_exports, {
|
|
|
5819
5828
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
5820
5829
|
writeTeamConfig: () => writeTeamConfig
|
|
5821
5830
|
});
|
|
5822
|
-
import { promises as fs8, existsSync as
|
|
5831
|
+
import { promises as fs8, existsSync as existsSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
5823
5832
|
import os8 from "node:os";
|
|
5824
5833
|
import path8 from "node:path";
|
|
5825
5834
|
function cclensHome() {
|
|
@@ -5874,9 +5883,9 @@ function appendUsageSnapshot(snapshot) {
|
|
|
5874
5883
|
}
|
|
5875
5884
|
function pruneUsageAgent(agent) {
|
|
5876
5885
|
const p = usageLogPath();
|
|
5877
|
-
if (!
|
|
5886
|
+
if (!existsSync3(p))
|
|
5878
5887
|
return;
|
|
5879
|
-
const kept =
|
|
5888
|
+
const kept = readFileSync5(p, "utf8").split("\n").filter((line) => {
|
|
5880
5889
|
if (!line.trim())
|
|
5881
5890
|
return false;
|
|
5882
5891
|
try {
|
|
@@ -6201,9 +6210,9 @@ var init_fs = __esm({
|
|
|
6201
6210
|
import {
|
|
6202
6211
|
appendFileSync as appendFileSync2,
|
|
6203
6212
|
mkdirSync as mkdirSync3,
|
|
6204
|
-
readFileSync as
|
|
6213
|
+
readFileSync as readFileSync10,
|
|
6205
6214
|
writeFileSync as writeFileSync4,
|
|
6206
|
-
existsSync as
|
|
6215
|
+
existsSync as existsSync9,
|
|
6207
6216
|
openSync,
|
|
6208
6217
|
readSync,
|
|
6209
6218
|
fstatSync,
|
|
@@ -6215,8 +6224,8 @@ function appendSnapshot(filePath, snapshot) {
|
|
|
6215
6224
|
appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
6216
6225
|
}
|
|
6217
6226
|
function readSnapshots(filePath) {
|
|
6218
|
-
if (!
|
|
6219
|
-
const content =
|
|
6227
|
+
if (!existsSync9(filePath)) return [];
|
|
6228
|
+
const content = readFileSync10(filePath, "utf8");
|
|
6220
6229
|
const snapshots = [];
|
|
6221
6230
|
for (const line of content.split("\n")) {
|
|
6222
6231
|
if (!line.trim()) continue;
|
|
@@ -6228,8 +6237,8 @@ function readSnapshots(filePath) {
|
|
|
6228
6237
|
return snapshots;
|
|
6229
6238
|
}
|
|
6230
6239
|
function pruneAgent(filePath, agent) {
|
|
6231
|
-
if (!
|
|
6232
|
-
const kept =
|
|
6240
|
+
if (!existsSync9(filePath)) return;
|
|
6241
|
+
const kept = readFileSync10(filePath, "utf8").split("\n").filter((line) => {
|
|
6233
6242
|
if (!line.trim()) return false;
|
|
6234
6243
|
try {
|
|
6235
6244
|
return JSON.parse(line).agent !== agent;
|
|
@@ -6665,6 +6674,7 @@ __export(dist_exports, {
|
|
|
6665
6674
|
ANTIGRAVITY_METADATA: () => ANTIGRAVITY_METADATA,
|
|
6666
6675
|
CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
|
|
6667
6676
|
CODEX_METADATA: () => CODEX_METADATA,
|
|
6677
|
+
COMMAND_CODE_METADATA: () => COMMAND_CODE_METADATA,
|
|
6668
6678
|
COPILOT_METADATA: () => COPILOT_METADATA,
|
|
6669
6679
|
COWORK_METADATA: () => COWORK_METADATA,
|
|
6670
6680
|
GEMINI_METADATA: () => GEMINI_METADATA,
|
|
@@ -6741,39 +6751,39 @@ __export(file_probe_exports, {
|
|
|
6741
6751
|
pathHash: () => pathHash,
|
|
6742
6752
|
probeArtifactSignals: () => probeArtifactSignals
|
|
6743
6753
|
});
|
|
6744
|
-
import { createHash } from "node:crypto";
|
|
6745
|
-
import { existsSync as
|
|
6746
|
-
import { homedir as
|
|
6747
|
-
import { join as
|
|
6754
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
6755
|
+
import { existsSync as existsSync14, readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
|
|
6756
|
+
import { homedir as homedir4 } from "node:os";
|
|
6757
|
+
import { join as join10, relative, resolve as resolve4, sep } from "node:path";
|
|
6748
6758
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
6749
6759
|
function pathHash(relPath) {
|
|
6750
|
-
return
|
|
6760
|
+
return createHash2("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
6751
6761
|
}
|
|
6752
6762
|
function defaultScanRoots(extraRoots = []) {
|
|
6753
6763
|
const roots = [];
|
|
6754
|
-
const home =
|
|
6755
|
-
if (
|
|
6764
|
+
const home = join10(homedir4(), ".claude");
|
|
6765
|
+
if (existsSync14(home)) roots.push({ root: home, label: "user" });
|
|
6756
6766
|
for (const e of extraRoots) {
|
|
6757
|
-
const r =
|
|
6758
|
-
if (
|
|
6767
|
+
const r = resolve4(e, ".claude");
|
|
6768
|
+
if (existsSync14(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
6759
6769
|
}
|
|
6760
6770
|
return roots;
|
|
6761
6771
|
}
|
|
6762
6772
|
function listMarkdownFiles(dir) {
|
|
6763
|
-
if (!
|
|
6773
|
+
if (!existsSync14(dir)) return [];
|
|
6764
6774
|
const out = [];
|
|
6765
6775
|
let entries;
|
|
6766
6776
|
try {
|
|
6767
|
-
entries =
|
|
6777
|
+
entries = readdirSync4(dir);
|
|
6768
6778
|
} catch {
|
|
6769
6779
|
return [];
|
|
6770
6780
|
}
|
|
6771
6781
|
for (const name of entries) {
|
|
6772
6782
|
if (name.startsWith(".")) continue;
|
|
6773
|
-
const full =
|
|
6783
|
+
const full = join10(dir, name);
|
|
6774
6784
|
let stat;
|
|
6775
6785
|
try {
|
|
6776
|
-
stat =
|
|
6786
|
+
stat = statSync6(full);
|
|
6777
6787
|
} catch {
|
|
6778
6788
|
continue;
|
|
6779
6789
|
}
|
|
@@ -6796,7 +6806,7 @@ function firstSeenDateOf(file) {
|
|
|
6796
6806
|
} catch {
|
|
6797
6807
|
}
|
|
6798
6808
|
try {
|
|
6799
|
-
const s =
|
|
6809
|
+
const s = statSync6(file);
|
|
6800
6810
|
return localDay(s.birthtime || s.mtime);
|
|
6801
6811
|
} catch {
|
|
6802
6812
|
return todayLocal();
|
|
@@ -6829,8 +6839,8 @@ function todayLocal() {
|
|
|
6829
6839
|
function scanAuthored(roots, subdir, day) {
|
|
6830
6840
|
const out = [];
|
|
6831
6841
|
for (const r of roots) {
|
|
6832
|
-
const dir =
|
|
6833
|
-
if (!
|
|
6842
|
+
const dir = join10(r.root, subdir);
|
|
6843
|
+
if (!existsSync14(dir)) continue;
|
|
6834
6844
|
for (const f of listMarkdownFiles(dir)) {
|
|
6835
6845
|
const firstSeen = firstSeenDateOf(f);
|
|
6836
6846
|
if (firstSeen !== day) continue;
|
|
@@ -6843,14 +6853,14 @@ function scanAuthored(roots, subdir, day) {
|
|
|
6843
6853
|
function scanEdited(roots, day) {
|
|
6844
6854
|
const out = [];
|
|
6845
6855
|
for (const r of roots) {
|
|
6846
|
-
const dir =
|
|
6847
|
-
if (!
|
|
6856
|
+
const dir = join10(r.root, "skills");
|
|
6857
|
+
if (!existsSync14(dir)) continue;
|
|
6848
6858
|
for (const f of listMarkdownFiles(dir)) {
|
|
6849
6859
|
const firstSeen = firstSeenDateOf(f);
|
|
6850
6860
|
if (firstSeen === day) continue;
|
|
6851
6861
|
let stat;
|
|
6852
6862
|
try {
|
|
6853
|
-
stat =
|
|
6863
|
+
stat = statSync6(f);
|
|
6854
6864
|
} catch {
|
|
6855
6865
|
continue;
|
|
6856
6866
|
}
|
|
@@ -6866,11 +6876,11 @@ function claudemdLineDelta(extraRoots, authorEmail, day) {
|
|
|
6866
6876
|
let delta = 0;
|
|
6867
6877
|
const candidates = [];
|
|
6868
6878
|
for (const e of extraRoots) {
|
|
6869
|
-
const f =
|
|
6870
|
-
if (
|
|
6879
|
+
const f = resolve4(e, "CLAUDE.md");
|
|
6880
|
+
if (existsSync14(f)) candidates.push(f);
|
|
6871
6881
|
}
|
|
6872
|
-
const homeClaudeMd =
|
|
6873
|
-
if (
|
|
6882
|
+
const homeClaudeMd = join10(homedir4(), "CLAUDE.md");
|
|
6883
|
+
if (existsSync14(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
6874
6884
|
for (const file of candidates) {
|
|
6875
6885
|
try {
|
|
6876
6886
|
const out = execFileSync2(
|
|
@@ -6926,7 +6936,7 @@ var init_file_probe = __esm({
|
|
|
6926
6936
|
});
|
|
6927
6937
|
|
|
6928
6938
|
// src/pid.ts
|
|
6929
|
-
import { readFileSync as
|
|
6939
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, mkdirSync as mkdirSync14, unlinkSync as unlinkSync5 } from "node:fs";
|
|
6930
6940
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
6931
6941
|
import { dirname as dirname13 } from "node:path";
|
|
6932
6942
|
function writePid(filePath, pid, port, version) {
|
|
@@ -6940,7 +6950,7 @@ function writePid(filePath, pid, port, version) {
|
|
|
6940
6950
|
}
|
|
6941
6951
|
function readPid(filePath) {
|
|
6942
6952
|
try {
|
|
6943
|
-
const content =
|
|
6953
|
+
const content = readFileSync23(filePath, "utf8").trim();
|
|
6944
6954
|
const [pidStr, portStr, versionStr] = content.split(":");
|
|
6945
6955
|
const pid = parseInt(pidStr, 10);
|
|
6946
6956
|
if (Number.isNaN(pid)) return null;
|
|
@@ -6994,13 +7004,13 @@ var init_pid = __esm({
|
|
|
6994
7004
|
|
|
6995
7005
|
// src/server.ts
|
|
6996
7006
|
import { spawn as spawn3 } from "node:child_process";
|
|
6997
|
-
import { join as
|
|
7007
|
+
import { join as join15, dirname as dirname14 } from "node:path";
|
|
6998
7008
|
import { fileURLToPath } from "node:url";
|
|
6999
|
-
import { existsSync as
|
|
7000
|
-
import { homedir as
|
|
7009
|
+
import { existsSync as existsSync22, realpathSync as realpathSync3, readFileSync as readFileSync24 } from "node:fs";
|
|
7010
|
+
import { homedir as homedir8 } from "node:os";
|
|
7001
7011
|
function appDir() {
|
|
7002
7012
|
const here = dirname14(fileURLToPath(import.meta.url));
|
|
7003
|
-
return
|
|
7013
|
+
return join15(here, "..", "app", "apps", "web");
|
|
7004
7014
|
}
|
|
7005
7015
|
function cliBinRealPath() {
|
|
7006
7016
|
const argv1 = process.argv[1] ?? "";
|
|
@@ -7013,10 +7023,10 @@ function cliBinRealPath() {
|
|
|
7013
7023
|
function onDiskVersion() {
|
|
7014
7024
|
try {
|
|
7015
7025
|
const here = dirname14(fileURLToPath(import.meta.url));
|
|
7016
|
-
const pkg = JSON.parse(
|
|
7017
|
-
return pkg.version ?? "1.0.
|
|
7026
|
+
const pkg = JSON.parse(readFileSync24(join15(here, "..", "package.json"), "utf8"));
|
|
7027
|
+
return pkg.version ?? "1.0.15";
|
|
7018
7028
|
} catch {
|
|
7019
|
-
return "1.0.
|
|
7029
|
+
return "1.0.15";
|
|
7020
7030
|
}
|
|
7021
7031
|
}
|
|
7022
7032
|
function getServerStatus() {
|
|
@@ -7029,15 +7039,15 @@ function getServerStatus() {
|
|
|
7029
7039
|
}
|
|
7030
7040
|
async function startServer(opts = {}) {
|
|
7031
7041
|
const port = opts.port ?? (parseInt(process.env.CCLENS_PORT ?? "", 10) || DEFAULT_PORT);
|
|
7032
|
-
const serverJs =
|
|
7033
|
-
if (!
|
|
7042
|
+
const serverJs = join15(appDir(), "server.js");
|
|
7043
|
+
if (!existsSync22(serverJs)) {
|
|
7034
7044
|
throw new Error(`Server not found at ${serverJs}. Reinstall with: npm install -g fleetlens`);
|
|
7035
7045
|
}
|
|
7036
7046
|
const portInUse = await checkPort(port);
|
|
7037
7047
|
if (portInUse) {
|
|
7038
7048
|
throw new Error(`Port ${port} is in use. Use --port to specify a different port.`);
|
|
7039
7049
|
}
|
|
7040
|
-
const dataDir =
|
|
7050
|
+
const dataDir = join15(homedir8(), ".claude", "projects");
|
|
7041
7051
|
const child = spawn3(process.execPath, [serverJs], {
|
|
7042
7052
|
detached: true,
|
|
7043
7053
|
stdio: "ignore",
|
|
@@ -7078,11 +7088,11 @@ async function restartWedgedServer(pid, port) {
|
|
|
7078
7088
|
}
|
|
7079
7089
|
async function checkPort(port) {
|
|
7080
7090
|
const { createServer } = await import("node:net");
|
|
7081
|
-
return new Promise((
|
|
7091
|
+
return new Promise((resolve5) => {
|
|
7082
7092
|
const server = createServer();
|
|
7083
|
-
server.once("error", () =>
|
|
7093
|
+
server.once("error", () => resolve5(true));
|
|
7084
7094
|
server.once("listening", () => {
|
|
7085
|
-
server.close(() =>
|
|
7095
|
+
server.close(() => resolve5(false));
|
|
7086
7096
|
});
|
|
7087
7097
|
server.listen(port, "localhost");
|
|
7088
7098
|
});
|
|
@@ -7120,26 +7130,33 @@ var init_server = __esm({
|
|
|
7120
7130
|
|
|
7121
7131
|
// src/daemon-worker.ts
|
|
7122
7132
|
import { spawn as spawn4 } from "node:child_process";
|
|
7123
|
-
import { closeSync as closeSync2, existsSync as
|
|
7124
|
-
import { dirname as dirname15, join as
|
|
7133
|
+
import { closeSync as closeSync2, existsSync as existsSync23, mkdirSync as mkdirSync15, openSync as openSync2, readFileSync as readFileSync25, writeFileSync as writeFileSync16 } from "node:fs";
|
|
7134
|
+
import { dirname as dirname15, join as join16 } from "node:path";
|
|
7125
7135
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7126
7136
|
|
|
7137
|
+
// src/usage/accounts.ts
|
|
7138
|
+
import { createHash } from "node:crypto";
|
|
7139
|
+
import { existsSync, readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
7140
|
+
import { homedir as homedir2, platform as platform2 } from "node:os";
|
|
7141
|
+
import { basename, join as join2, resolve } from "node:path";
|
|
7142
|
+
|
|
7127
7143
|
// src/usage/token.ts
|
|
7128
7144
|
import { execFileSync } from "node:child_process";
|
|
7129
7145
|
import { readFileSync } from "node:fs";
|
|
7130
7146
|
import { homedir, platform } from "node:os";
|
|
7131
7147
|
import { join } from "node:path";
|
|
7148
|
+
var DEFAULT_KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
7132
7149
|
function readOAuthCredentials() {
|
|
7133
7150
|
if (platform() === "darwin") {
|
|
7134
|
-
return readFromMacKeychain() ?? readFromCredentialsFile();
|
|
7151
|
+
return readFromMacKeychain(DEFAULT_KEYCHAIN_SERVICE) ?? readFromCredentialsFile();
|
|
7135
7152
|
}
|
|
7136
7153
|
return readFromCredentialsFile();
|
|
7137
7154
|
}
|
|
7138
|
-
function readFromMacKeychain() {
|
|
7155
|
+
function readFromMacKeychain(service) {
|
|
7139
7156
|
try {
|
|
7140
7157
|
const blob = execFileSync(
|
|
7141
7158
|
"security",
|
|
7142
|
-
["find-generic-password", "-s",
|
|
7159
|
+
["find-generic-password", "-s", service, "-w"],
|
|
7143
7160
|
{ stdio: ["ignore", "pipe", "ignore"], encoding: "utf8" }
|
|
7144
7161
|
);
|
|
7145
7162
|
return extractCredentials(blob);
|
|
@@ -7147,18 +7164,21 @@ function readFromMacKeychain() {
|
|
|
7147
7164
|
return null;
|
|
7148
7165
|
}
|
|
7149
7166
|
}
|
|
7167
|
+
function readCredentialsFile(path12) {
|
|
7168
|
+
try {
|
|
7169
|
+
return extractCredentials(readFileSync(path12, "utf8"));
|
|
7170
|
+
} catch {
|
|
7171
|
+
return null;
|
|
7172
|
+
}
|
|
7173
|
+
}
|
|
7150
7174
|
function readFromCredentialsFile() {
|
|
7151
7175
|
const candidates = [
|
|
7152
7176
|
join(homedir(), ".claude", ".credentials.json"),
|
|
7153
7177
|
join(homedir(), ".config", "claude", "credentials.json")
|
|
7154
7178
|
];
|
|
7155
|
-
for (const
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
const creds = extractCredentials(blob);
|
|
7159
|
-
if (creds) return creds;
|
|
7160
|
-
} catch {
|
|
7161
|
-
}
|
|
7179
|
+
for (const path12 of candidates) {
|
|
7180
|
+
const creds = readCredentialsFile(path12);
|
|
7181
|
+
if (creds) return creds;
|
|
7162
7182
|
}
|
|
7163
7183
|
return null;
|
|
7164
7184
|
}
|
|
@@ -7179,6 +7199,114 @@ function extractCredentials(blob) {
|
|
|
7179
7199
|
}
|
|
7180
7200
|
}
|
|
7181
7201
|
|
|
7202
|
+
// src/usage/accounts.ts
|
|
7203
|
+
var CLAUDE_HOME_MARKERS = [".credentials.json", ".claude.json", "settings.json", "projects"];
|
|
7204
|
+
function defaultClaudeHome(homeDir = homedir2()) {
|
|
7205
|
+
return resolve(join2(homeDir, ".claude"));
|
|
7206
|
+
}
|
|
7207
|
+
function keychainServiceForConfigDir(configDir, homeDir = homedir2()) {
|
|
7208
|
+
const resolved = resolve(configDir);
|
|
7209
|
+
if (resolved === defaultClaudeHome(homeDir)) return DEFAULT_KEYCHAIN_SERVICE;
|
|
7210
|
+
const hash = createHash("sha256").update(resolved).digest("hex").slice(0, 8);
|
|
7211
|
+
return `${DEFAULT_KEYCHAIN_SERVICE}-${hash}`;
|
|
7212
|
+
}
|
|
7213
|
+
function accountSlugForConfigDir(configDir, homeDir = homedir2()) {
|
|
7214
|
+
const resolved = resolve(configDir);
|
|
7215
|
+
if (resolved === defaultClaudeHome(homeDir)) return null;
|
|
7216
|
+
const base = basename(resolved);
|
|
7217
|
+
if (base.startsWith(".claude-")) {
|
|
7218
|
+
const slug = base.slice(".claude-".length);
|
|
7219
|
+
return slug.length > 0 ? slug : "alt";
|
|
7220
|
+
}
|
|
7221
|
+
if (base.startsWith(".claude")) {
|
|
7222
|
+
const rest = base.slice(".claude".length).replace(/^-+/, "");
|
|
7223
|
+
return rest.length > 0 ? rest : "alt";
|
|
7224
|
+
}
|
|
7225
|
+
return base || "alt";
|
|
7226
|
+
}
|
|
7227
|
+
function snapshotAgentKey(slug) {
|
|
7228
|
+
return slug ? `claude-code:${slug}` : "claude-code";
|
|
7229
|
+
}
|
|
7230
|
+
function looksLikeClaudeHome(dir) {
|
|
7231
|
+
try {
|
|
7232
|
+
if (!statSync(dir).isDirectory()) return false;
|
|
7233
|
+
} catch {
|
|
7234
|
+
return false;
|
|
7235
|
+
}
|
|
7236
|
+
return CLAUDE_HOME_MARKERS.some((name) => existsSync(join2(dir, name)));
|
|
7237
|
+
}
|
|
7238
|
+
function discoverClaudeConfigDirs(opts = {}) {
|
|
7239
|
+
const homeDir = opts.homeDir ?? homedir2();
|
|
7240
|
+
const found = [];
|
|
7241
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7242
|
+
const add = (dir) => {
|
|
7243
|
+
const resolved = resolve(dir);
|
|
7244
|
+
if (seen.has(resolved)) return;
|
|
7245
|
+
if (!looksLikeClaudeHome(resolved)) return;
|
|
7246
|
+
seen.add(resolved);
|
|
7247
|
+
found.push(resolved);
|
|
7248
|
+
};
|
|
7249
|
+
add(join2(homeDir, ".claude"));
|
|
7250
|
+
try {
|
|
7251
|
+
for (const name of readdirSync(homeDir)) {
|
|
7252
|
+
if (!name.startsWith(".claude-")) continue;
|
|
7253
|
+
add(join2(homeDir, name));
|
|
7254
|
+
}
|
|
7255
|
+
} catch {
|
|
7256
|
+
}
|
|
7257
|
+
const envDir = opts.envConfigDir ?? process.env.CLAUDE_CONFIG_DIR;
|
|
7258
|
+
if (envDir && envDir.trim()) add(envDir.trim());
|
|
7259
|
+
return found;
|
|
7260
|
+
}
|
|
7261
|
+
function readAccountCredentials(configDir, opts = {}) {
|
|
7262
|
+
const homeDir = opts.homeDir ?? homedir2();
|
|
7263
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
7264
|
+
const os12 = opts.platform ?? platform2();
|
|
7265
|
+
const keychainRead = opts.readKeychain ?? readFromMacKeychain;
|
|
7266
|
+
const usableOnly = opts.usableOnly !== false;
|
|
7267
|
+
const fileCreds = readCredentialsFile(join2(configDir, ".credentials.json"));
|
|
7268
|
+
let keychainCreds = null;
|
|
7269
|
+
if (os12 === "darwin") {
|
|
7270
|
+
keychainCreds = keychainRead(keychainServiceForConfigDir(configDir, homeDir));
|
|
7271
|
+
}
|
|
7272
|
+
const extraFile = resolve(configDir) === defaultClaudeHome(homeDir) ? readCredentialsFile(join2(homeDir, ".config", "claude", "credentials.json")) : null;
|
|
7273
|
+
const candidates = [];
|
|
7274
|
+
if (keychainCreds) candidates.push({ creds: keychainCreds, source: "keychain" });
|
|
7275
|
+
if (fileCreds) candidates.push({ creds: fileCreds, source: "file" });
|
|
7276
|
+
if (extraFile) candidates.push({ creds: extraFile, source: "file" });
|
|
7277
|
+
for (const c of candidates) {
|
|
7278
|
+
if (!usableOnly || isUsable(c.creds, nowMs)) return c;
|
|
7279
|
+
}
|
|
7280
|
+
return null;
|
|
7281
|
+
}
|
|
7282
|
+
function discoverClaudeAccounts(opts = {}) {
|
|
7283
|
+
const homeDir = opts.homeDir ?? homedir2();
|
|
7284
|
+
const dirs = discoverClaudeConfigDirs({
|
|
7285
|
+
homeDir,
|
|
7286
|
+
envConfigDir: opts.envConfigDir
|
|
7287
|
+
});
|
|
7288
|
+
const accounts = [];
|
|
7289
|
+
const seenTokens = /* @__PURE__ */ new Set();
|
|
7290
|
+
for (const configDir of dirs) {
|
|
7291
|
+
const got = readAccountCredentials(configDir, opts);
|
|
7292
|
+
if (!got) continue;
|
|
7293
|
+
if (seenTokens.has(got.creds.accessToken)) continue;
|
|
7294
|
+
seenTokens.add(got.creds.accessToken);
|
|
7295
|
+
accounts.push({
|
|
7296
|
+
configDir,
|
|
7297
|
+
slug: accountSlugForConfigDir(configDir, homeDir),
|
|
7298
|
+
creds: got.creds,
|
|
7299
|
+
source: got.source
|
|
7300
|
+
});
|
|
7301
|
+
}
|
|
7302
|
+
accounts.sort((a, b) => {
|
|
7303
|
+
if (a.slug === null) return -1;
|
|
7304
|
+
if (b.slug === null) return 1;
|
|
7305
|
+
return a.slug.localeCompare(b.slug);
|
|
7306
|
+
});
|
|
7307
|
+
return accounts;
|
|
7308
|
+
}
|
|
7309
|
+
|
|
7182
7310
|
// src/usage/api.ts
|
|
7183
7311
|
var EXPIRY_SKEW_MS = 60 * 1e3;
|
|
7184
7312
|
var USAGE_ENDPOINT = "https://api.anthropic.com/api/oauth/usage";
|
|
@@ -7189,15 +7317,9 @@ var UsageApiError = class extends Error {
|
|
|
7189
7317
|
this.code = code;
|
|
7190
7318
|
}
|
|
7191
7319
|
};
|
|
7192
|
-
async function
|
|
7193
|
-
const
|
|
7194
|
-
if (
|
|
7195
|
-
throw new UsageApiError(
|
|
7196
|
-
"No Claude Code OAuth token found. Run `claude` to log in first.",
|
|
7197
|
-
"no_token"
|
|
7198
|
-
);
|
|
7199
|
-
}
|
|
7200
|
-
if (creds.expiresAt - EXPIRY_SKEW_MS <= Date.now()) {
|
|
7320
|
+
async function fetchUsageWithCredentials(creds, opts = {}) {
|
|
7321
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
7322
|
+
if (creds.expiresAt - EXPIRY_SKEW_MS <= nowMs) {
|
|
7201
7323
|
throw new UsageApiError(
|
|
7202
7324
|
"Claude Code OAuth token expired. Open Claude Code to refresh it.",
|
|
7203
7325
|
"expired"
|
|
@@ -7230,9 +7352,10 @@ async function fetchUsage() {
|
|
|
7230
7352
|
throw new UsageApiError(`Failed to parse usage response: ${err.message}`, "parse");
|
|
7231
7353
|
}
|
|
7232
7354
|
const b = body;
|
|
7355
|
+
const account = opts.account ?? null;
|
|
7233
7356
|
return {
|
|
7234
7357
|
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7235
|
-
agent:
|
|
7358
|
+
agent: opts.agent ?? snapshotAgentKey(account),
|
|
7236
7359
|
five_hour: normalizeWindow(b.five_hour) ?? { utilization: null, resets_at: null },
|
|
7237
7360
|
seven_day: normalizeWindow(b.seven_day) ?? { utilization: null, resets_at: null },
|
|
7238
7361
|
seven_day_opus: normalizeWindow(b.seven_day_opus),
|
|
@@ -7240,9 +7363,38 @@ async function fetchUsage() {
|
|
|
7240
7363
|
seven_day_oauth_apps: normalizeWindow(b.seven_day_oauth_apps),
|
|
7241
7364
|
seven_day_cowork: normalizeWindow(b.seven_day_cowork),
|
|
7242
7365
|
extra_usage: normalizeExtra(b.extra_usage),
|
|
7243
|
-
plan_type: null
|
|
7366
|
+
plan_type: null,
|
|
7367
|
+
...account ? { account } : {}
|
|
7244
7368
|
};
|
|
7245
7369
|
}
|
|
7370
|
+
async function fetchAllClaudeUsage(opts = {}) {
|
|
7371
|
+
const accounts = opts.accounts ?? discoverClaudeAccounts({ nowMs: opts.nowMs });
|
|
7372
|
+
const fetchOne = opts.fetchOne ?? fetchUsageWithCredentials;
|
|
7373
|
+
const snapshots = [];
|
|
7374
|
+
const errors = [];
|
|
7375
|
+
for (const account of accounts) {
|
|
7376
|
+
try {
|
|
7377
|
+
snapshots.push(
|
|
7378
|
+
await fetchOne(account.creds, {
|
|
7379
|
+
agent: snapshotAgentKey(account.slug),
|
|
7380
|
+
account: account.slug,
|
|
7381
|
+
nowMs: opts.nowMs
|
|
7382
|
+
})
|
|
7383
|
+
);
|
|
7384
|
+
} catch (err) {
|
|
7385
|
+
if (err instanceof UsageApiError) {
|
|
7386
|
+
errors.push({ slug: account.slug, code: err.code, message: err.message });
|
|
7387
|
+
} else {
|
|
7388
|
+
errors.push({
|
|
7389
|
+
slug: account.slug,
|
|
7390
|
+
code: "parse",
|
|
7391
|
+
message: err.message
|
|
7392
|
+
});
|
|
7393
|
+
}
|
|
7394
|
+
}
|
|
7395
|
+
}
|
|
7396
|
+
return { snapshots, errors };
|
|
7397
|
+
}
|
|
7246
7398
|
function normalizeWindow(raw) {
|
|
7247
7399
|
if (!raw || typeof raw !== "object") return null;
|
|
7248
7400
|
const r = raw;
|
|
@@ -7264,7 +7416,7 @@ function normalizeExtra(raw) {
|
|
|
7264
7416
|
|
|
7265
7417
|
// src/usage/zai.ts
|
|
7266
7418
|
init_fs();
|
|
7267
|
-
import { existsSync as
|
|
7419
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
|
|
7268
7420
|
var ZAI_QUOTA_ENDPOINT = "https://api.z.ai/api/monitor/usage/quota/limit";
|
|
7269
7421
|
var ZAI_SUBSCRIPTION_ENDPOINT = "https://api.z.ai/api/biz/subscription/list";
|
|
7270
7422
|
var ZaiApiError = class extends Error {
|
|
@@ -7276,8 +7428,8 @@ var ZaiApiError = class extends Error {
|
|
|
7276
7428
|
function resolveApiKey() {
|
|
7277
7429
|
try {
|
|
7278
7430
|
const p = cclensPath("credentials.json");
|
|
7279
|
-
if (
|
|
7280
|
-
const store = JSON.parse(
|
|
7431
|
+
if (existsSync4(p)) {
|
|
7432
|
+
const store = JSON.parse(readFileSync6(p, "utf8"));
|
|
7281
7433
|
return store.zai?.apiKey ?? null;
|
|
7282
7434
|
}
|
|
7283
7435
|
} catch {
|
|
@@ -7367,7 +7519,7 @@ async function fetchZaiUsage() {
|
|
|
7367
7519
|
}
|
|
7368
7520
|
|
|
7369
7521
|
// src/usage/grok.ts
|
|
7370
|
-
import { existsSync as
|
|
7522
|
+
import { existsSync as existsSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
7371
7523
|
import os9 from "node:os";
|
|
7372
7524
|
import path9 from "node:path";
|
|
7373
7525
|
var CREDITS_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
|
|
@@ -7391,12 +7543,12 @@ function authPath() {
|
|
|
7391
7543
|
}
|
|
7392
7544
|
function loadAuthEntry() {
|
|
7393
7545
|
const p = authPath();
|
|
7394
|
-
if (!
|
|
7546
|
+
if (!existsSync5(p)) {
|
|
7395
7547
|
throw new GrokApiError("Grok not logged in. Run `grok login`.", "no_auth");
|
|
7396
7548
|
}
|
|
7397
7549
|
let raw;
|
|
7398
7550
|
try {
|
|
7399
|
-
raw = JSON.parse(
|
|
7551
|
+
raw = JSON.parse(readFileSync7(p, "utf8"));
|
|
7400
7552
|
} catch {
|
|
7401
7553
|
throw new GrokApiError("Grok auth.json is unreadable. Run `grok login`.", "no_auth");
|
|
7402
7554
|
}
|
|
@@ -7438,7 +7590,7 @@ async function refreshAccessToken(entry) {
|
|
|
7438
7590
|
if (typeof j.access_token !== "string" || !j.access_token) return null;
|
|
7439
7591
|
try {
|
|
7440
7592
|
const p = authPath();
|
|
7441
|
-
const raw = JSON.parse(
|
|
7593
|
+
const raw = JSON.parse(readFileSync7(p, "utf8"));
|
|
7442
7594
|
for (const key of Object.keys(raw)) {
|
|
7443
7595
|
if (raw[key]?.key === entry.key || raw[key]?.refresh_token === refresh) {
|
|
7444
7596
|
raw[key] = {
|
|
@@ -7580,8 +7732,8 @@ async function fetchGrokUsage() {
|
|
|
7580
7732
|
|
|
7581
7733
|
// src/usage/codex.ts
|
|
7582
7734
|
import {
|
|
7583
|
-
existsSync as
|
|
7584
|
-
readFileSync as
|
|
7735
|
+
existsSync as existsSync6,
|
|
7736
|
+
readFileSync as readFileSync8,
|
|
7585
7737
|
writeFileSync as writeFileSync3
|
|
7586
7738
|
} from "node:fs";
|
|
7587
7739
|
import os10 from "node:os";
|
|
@@ -7608,7 +7760,7 @@ function authPath2() {
|
|
|
7608
7760
|
}
|
|
7609
7761
|
function loadAuth() {
|
|
7610
7762
|
const p = authPath2();
|
|
7611
|
-
if (!
|
|
7763
|
+
if (!existsSync6(p)) {
|
|
7612
7764
|
throw new CodexApiError(
|
|
7613
7765
|
"Codex not logged in. Run `codex` to authenticate.",
|
|
7614
7766
|
"no_auth"
|
|
@@ -7616,7 +7768,7 @@ function loadAuth() {
|
|
|
7616
7768
|
}
|
|
7617
7769
|
let auth;
|
|
7618
7770
|
try {
|
|
7619
|
-
auth = JSON.parse(
|
|
7771
|
+
auth = JSON.parse(readFileSync8(p, "utf8"));
|
|
7620
7772
|
} catch {
|
|
7621
7773
|
throw new CodexApiError(
|
|
7622
7774
|
"Codex auth.json is unreadable. Run `codex` to log in again.",
|
|
@@ -7860,8 +8012,8 @@ async function fetchCodexUsage() {
|
|
|
7860
8012
|
|
|
7861
8013
|
// src/usage/copilot.ts
|
|
7862
8014
|
import { spawn } from "node:child_process";
|
|
7863
|
-
import { existsSync as
|
|
7864
|
-
import { dirname as dirname2, join as
|
|
8015
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
8016
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
7865
8017
|
var RPC_TIMEOUT_MS = 1e4;
|
|
7866
8018
|
var CopilotApiError = class extends Error {
|
|
7867
8019
|
constructor(message, code) {
|
|
@@ -7968,8 +8120,8 @@ function rpcFrame(message) {
|
|
|
7968
8120
|
function resolveCopilotCliPath() {
|
|
7969
8121
|
const configured = process.env.COPILOT_CLI_PATH?.trim();
|
|
7970
8122
|
if (configured) return configured;
|
|
7971
|
-
const sibling =
|
|
7972
|
-
return
|
|
8123
|
+
const sibling = join5(dirname2(process.execPath), process.platform === "win32" ? "copilot.cmd" : "copilot");
|
|
8124
|
+
return existsSync7(sibling) ? sibling : process.platform === "win32" ? "copilot.cmd" : "copilot";
|
|
7973
8125
|
}
|
|
7974
8126
|
async function requestQuota(child) {
|
|
7975
8127
|
const decoder = new ContentLengthDecoder();
|
|
@@ -8015,8 +8167,8 @@ async function requestQuota(child) {
|
|
|
8015
8167
|
});
|
|
8016
8168
|
const request = (method, params = {}) => {
|
|
8017
8169
|
const id = nextId++;
|
|
8018
|
-
const response = new Promise((
|
|
8019
|
-
pending.set(id, { resolve:
|
|
8170
|
+
const response = new Promise((resolve5, reject) => {
|
|
8171
|
+
pending.set(id, { resolve: resolve5, reject });
|
|
8020
8172
|
child.stdin.write(rpcFrame({ jsonrpc: "2.0", id, method, params }));
|
|
8021
8173
|
});
|
|
8022
8174
|
return Promise.race([response, exited]);
|
|
@@ -8060,6 +8212,248 @@ async function fetchCopilotUsage() {
|
|
|
8060
8212
|
}
|
|
8061
8213
|
}
|
|
8062
8214
|
|
|
8215
|
+
// src/usage/command-code.ts
|
|
8216
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
|
|
8217
|
+
import os11 from "node:os";
|
|
8218
|
+
import path11 from "node:path";
|
|
8219
|
+
var DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
8220
|
+
var CREDITS_PATH = "/alpha/billing/credits";
|
|
8221
|
+
var SUBSCRIPTIONS_PATH = "/alpha/billing/subscriptions";
|
|
8222
|
+
var PLAN_NAMES = {
|
|
8223
|
+
"individual-go": "Go",
|
|
8224
|
+
"individual-goat": "GOAT",
|
|
8225
|
+
"individual-pro": "Pro",
|
|
8226
|
+
"individual-pro-v1": "Pro",
|
|
8227
|
+
"individual-provider": "Provider",
|
|
8228
|
+
"individual-max": "Max",
|
|
8229
|
+
"individual-ultra": "Ultra",
|
|
8230
|
+
"teams-pro": "Teams Pro"
|
|
8231
|
+
};
|
|
8232
|
+
var PLAN_CREDITS = {
|
|
8233
|
+
"individual-go": 10,
|
|
8234
|
+
"individual-goat": 70,
|
|
8235
|
+
"individual-pro": 30,
|
|
8236
|
+
"individual-pro-v1": 80,
|
|
8237
|
+
"individual-provider": 15,
|
|
8238
|
+
"individual-max": 150,
|
|
8239
|
+
"individual-ultra": 300,
|
|
8240
|
+
"teams-pro": 40
|
|
8241
|
+
};
|
|
8242
|
+
var CommandCodeApiError = class extends Error {
|
|
8243
|
+
constructor(message, code) {
|
|
8244
|
+
super(message);
|
|
8245
|
+
this.code = code;
|
|
8246
|
+
}
|
|
8247
|
+
};
|
|
8248
|
+
function commandCodeHome() {
|
|
8249
|
+
return process.env.COMMANDCODE_HOME || path11.join(os11.homedir(), ".commandcode");
|
|
8250
|
+
}
|
|
8251
|
+
function authPath3() {
|
|
8252
|
+
return path11.join(commandCodeHome(), "auth.json");
|
|
8253
|
+
}
|
|
8254
|
+
function loadCommandCodeApiKey() {
|
|
8255
|
+
const p = authPath3();
|
|
8256
|
+
if (!existsSync8(p)) {
|
|
8257
|
+
throw new CommandCodeApiError("Command Code not logged in. Run `cmd login`.", "no_auth");
|
|
8258
|
+
}
|
|
8259
|
+
let raw;
|
|
8260
|
+
try {
|
|
8261
|
+
raw = JSON.parse(readFileSync9(p, "utf8"));
|
|
8262
|
+
} catch {
|
|
8263
|
+
throw new CommandCodeApiError("Command Code auth.json is unreadable. Run `cmd login`.", "no_auth");
|
|
8264
|
+
}
|
|
8265
|
+
const key = typeof raw.apiKey === "string" ? raw.apiKey.trim() : "";
|
|
8266
|
+
if (!key) {
|
|
8267
|
+
throw new CommandCodeApiError("Command Code auth has no API key. Run `cmd login`.", "no_auth");
|
|
8268
|
+
}
|
|
8269
|
+
return key;
|
|
8270
|
+
}
|
|
8271
|
+
function apiBase() {
|
|
8272
|
+
const custom2 = process.env.COMMANDCODE_API_URL?.trim();
|
|
8273
|
+
return custom2 && custom2.length > 0 ? custom2.replace(/\/$/, "") : DEFAULT_API_BASE;
|
|
8274
|
+
}
|
|
8275
|
+
function authHeaders3(key) {
|
|
8276
|
+
return {
|
|
8277
|
+
Authorization: `Bearer ${key}`,
|
|
8278
|
+
Accept: "application/json",
|
|
8279
|
+
"User-Agent": "fleetlens"
|
|
8280
|
+
};
|
|
8281
|
+
}
|
|
8282
|
+
function normalizePlanKey(planId) {
|
|
8283
|
+
return planId.trim().toLowerCase().replace(/_/g, "-");
|
|
8284
|
+
}
|
|
8285
|
+
function matchPlanKey(planId) {
|
|
8286
|
+
const key = normalizePlanKey(planId);
|
|
8287
|
+
if (PLAN_NAMES[key] || PLAN_CREDITS[key] !== void 0) return key;
|
|
8288
|
+
return Object.keys(PLAN_NAMES).sort((a, b) => b.length - a.length).find((p) => key.startsWith(p)) ?? null;
|
|
8289
|
+
}
|
|
8290
|
+
function planLabelFromId(planId) {
|
|
8291
|
+
if (typeof planId !== "string" || !planId.trim()) return null;
|
|
8292
|
+
const key = matchPlanKey(planId);
|
|
8293
|
+
return key ? PLAN_NAMES[key] ?? planId.trim() : planId.trim();
|
|
8294
|
+
}
|
|
8295
|
+
function planMonthlyCredits(planId) {
|
|
8296
|
+
if (typeof planId !== "string" || !planId.trim()) return null;
|
|
8297
|
+
const key = matchPlanKey(planId);
|
|
8298
|
+
if (!key) return null;
|
|
8299
|
+
const n = PLAN_CREDITS[key];
|
|
8300
|
+
return typeof n === "number" ? n : null;
|
|
8301
|
+
}
|
|
8302
|
+
function asCredit(raw) {
|
|
8303
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) return null;
|
|
8304
|
+
return raw;
|
|
8305
|
+
}
|
|
8306
|
+
function roundCredits(n) {
|
|
8307
|
+
return Math.round(n * 100) / 100;
|
|
8308
|
+
}
|
|
8309
|
+
function isoFromUnknown(raw) {
|
|
8310
|
+
if (typeof raw !== "string" || !raw.trim()) return null;
|
|
8311
|
+
const ms = Date.parse(raw);
|
|
8312
|
+
return Number.isFinite(ms) ? new Date(ms).toISOString() : null;
|
|
8313
|
+
}
|
|
8314
|
+
function parseCommandCodeCredits(body) {
|
|
8315
|
+
if (!body || typeof body !== "object") {
|
|
8316
|
+
throw new CommandCodeApiError("Command Code credits response missing body", "parse");
|
|
8317
|
+
}
|
|
8318
|
+
const credits = body.credits;
|
|
8319
|
+
if (!credits || typeof credits !== "object") {
|
|
8320
|
+
throw new CommandCodeApiError("Command Code credits response missing credits", "parse");
|
|
8321
|
+
}
|
|
8322
|
+
const c = credits;
|
|
8323
|
+
return {
|
|
8324
|
+
remaining: asCredit(c.monthlyCredits),
|
|
8325
|
+
purchased: asCredit(c.purchasedCredits) ?? 0,
|
|
8326
|
+
free: asCredit(c.freeCredits) ?? 0,
|
|
8327
|
+
planId: typeof c.planId === "string" && c.planId.trim() ? c.planId.trim() : null
|
|
8328
|
+
};
|
|
8329
|
+
}
|
|
8330
|
+
function parseCommandCodeWindow(raw) {
|
|
8331
|
+
if (!raw || typeof raw !== "object") {
|
|
8332
|
+
return { utilization: null, resets_at: null };
|
|
8333
|
+
}
|
|
8334
|
+
const w = raw;
|
|
8335
|
+
const used = Number(w.used);
|
|
8336
|
+
const cap = Number(w.cap);
|
|
8337
|
+
let utilization = null;
|
|
8338
|
+
if (Number.isFinite(used) && Number.isFinite(cap) && cap > 0) {
|
|
8339
|
+
utilization = Math.min(100, Math.max(0, used / cap * 100));
|
|
8340
|
+
}
|
|
8341
|
+
let resets_at = null;
|
|
8342
|
+
const resetAt = Number(w.resetAt);
|
|
8343
|
+
if (Number.isFinite(resetAt) && resetAt > 0) {
|
|
8344
|
+
const iso = new Date(resetAt).toISOString();
|
|
8345
|
+
if (!Number.isNaN(Date.parse(iso))) resets_at = iso;
|
|
8346
|
+
}
|
|
8347
|
+
return { utilization, resets_at };
|
|
8348
|
+
}
|
|
8349
|
+
function parseCommandCodeWindows(body) {
|
|
8350
|
+
const empty = { utilization: null, resets_at: null };
|
|
8351
|
+
if (!body || typeof body !== "object") return { five_hour: empty, seven_day: empty };
|
|
8352
|
+
const limits = body.windowLimits;
|
|
8353
|
+
if (!limits || typeof limits !== "object") return { five_hour: empty, seven_day: empty };
|
|
8354
|
+
const l = limits;
|
|
8355
|
+
return {
|
|
8356
|
+
five_hour: parseCommandCodeWindow(l.fiveHour),
|
|
8357
|
+
seven_day: parseCommandCodeWindow(l.weekly)
|
|
8358
|
+
};
|
|
8359
|
+
}
|
|
8360
|
+
function parseCommandCodeSubscription(body) {
|
|
8361
|
+
if (!body || typeof body !== "object") {
|
|
8362
|
+
return { plan_type: null, planId: null, currentPeriodEnd: null };
|
|
8363
|
+
}
|
|
8364
|
+
const data = body.data;
|
|
8365
|
+
const planId = typeof data?.planId === "string" && data.planId.trim() ? data.planId.trim() : null;
|
|
8366
|
+
return {
|
|
8367
|
+
plan_type: planLabelFromId(planId),
|
|
8368
|
+
planId,
|
|
8369
|
+
currentPeriodEnd: isoFromUnknown(data?.currentPeriodEnd)
|
|
8370
|
+
};
|
|
8371
|
+
}
|
|
8372
|
+
function parseCommandCodeMonthly(opts) {
|
|
8373
|
+
const planId = opts.subscription.planId ?? opts.credits.planId;
|
|
8374
|
+
const limit = planMonthlyCredits(planId);
|
|
8375
|
+
const remaining = opts.credits.remaining;
|
|
8376
|
+
let used = null;
|
|
8377
|
+
let utilization = null;
|
|
8378
|
+
if (limit != null && limit > 0 && remaining != null) {
|
|
8379
|
+
used = roundCredits(Math.max(0, limit - remaining));
|
|
8380
|
+
utilization = Math.min(100, Math.max(0, used / limit * 100));
|
|
8381
|
+
}
|
|
8382
|
+
return {
|
|
8383
|
+
monthly: {
|
|
8384
|
+
utilization,
|
|
8385
|
+
resets_at: opts.subscription.currentPeriodEnd
|
|
8386
|
+
},
|
|
8387
|
+
monthly_quota: {
|
|
8388
|
+
used,
|
|
8389
|
+
limit,
|
|
8390
|
+
remaining: remaining == null ? null : roundCredits(Math.max(0, remaining)),
|
|
8391
|
+
unit: "credits",
|
|
8392
|
+
unlimited: false
|
|
8393
|
+
},
|
|
8394
|
+
plan_type: opts.subscription.plan_type ?? planLabelFromId(planId)
|
|
8395
|
+
};
|
|
8396
|
+
}
|
|
8397
|
+
async function fetchJson2(url, key) {
|
|
8398
|
+
let res;
|
|
8399
|
+
try {
|
|
8400
|
+
res = await fetch(url, { headers: authHeaders3(key) });
|
|
8401
|
+
} catch (err) {
|
|
8402
|
+
throw new CommandCodeApiError(
|
|
8403
|
+
`Network error reaching Command Code billing: ${err.message}`,
|
|
8404
|
+
"network"
|
|
8405
|
+
);
|
|
8406
|
+
}
|
|
8407
|
+
let body = null;
|
|
8408
|
+
try {
|
|
8409
|
+
body = await res.json();
|
|
8410
|
+
} catch {
|
|
8411
|
+
}
|
|
8412
|
+
return { status: res.status, body };
|
|
8413
|
+
}
|
|
8414
|
+
async function fetchCommandCodeUsage() {
|
|
8415
|
+
const key = loadCommandCodeApiKey();
|
|
8416
|
+
const base = apiBase();
|
|
8417
|
+
const creditsRes = await fetchJson2(`${base}${CREDITS_PATH}`, key);
|
|
8418
|
+
if (creditsRes.status === 401 || creditsRes.status === 403) {
|
|
8419
|
+
throw new CommandCodeApiError(
|
|
8420
|
+
`Command Code credits returned HTTP ${creditsRes.status}`,
|
|
8421
|
+
"no_auth"
|
|
8422
|
+
);
|
|
8423
|
+
}
|
|
8424
|
+
if (creditsRes.status < 200 || creditsRes.status >= 300) {
|
|
8425
|
+
throw new CommandCodeApiError(
|
|
8426
|
+
`Command Code credits returned HTTP ${creditsRes.status}`,
|
|
8427
|
+
"http"
|
|
8428
|
+
);
|
|
8429
|
+
}
|
|
8430
|
+
const credits = parseCommandCodeCredits(creditsRes.body);
|
|
8431
|
+
const windows = parseCommandCodeWindows(creditsRes.body);
|
|
8432
|
+
let subscription = parseCommandCodeSubscription(null);
|
|
8433
|
+
try {
|
|
8434
|
+
const subRes = await fetchJson2(`${base}${SUBSCRIPTIONS_PATH}`, key);
|
|
8435
|
+
if (subRes.status >= 200 && subRes.status < 300) {
|
|
8436
|
+
subscription = parseCommandCodeSubscription(subRes.body);
|
|
8437
|
+
}
|
|
8438
|
+
} catch {
|
|
8439
|
+
}
|
|
8440
|
+
const monthly = parseCommandCodeMonthly({ credits, subscription });
|
|
8441
|
+
return {
|
|
8442
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8443
|
+
agent: "command-code",
|
|
8444
|
+
five_hour: windows.five_hour,
|
|
8445
|
+
seven_day: windows.seven_day,
|
|
8446
|
+
monthly: monthly.monthly,
|
|
8447
|
+
monthly_quota: monthly.monthly_quota,
|
|
8448
|
+
seven_day_opus: null,
|
|
8449
|
+
seven_day_sonnet: null,
|
|
8450
|
+
seven_day_oauth_apps: null,
|
|
8451
|
+
seven_day_cowork: null,
|
|
8452
|
+
extra_usage: null,
|
|
8453
|
+
plan_type: monthly.plan_type
|
|
8454
|
+
};
|
|
8455
|
+
}
|
|
8456
|
+
|
|
8063
8457
|
// src/daemon-worker.ts
|
|
8064
8458
|
init_storage();
|
|
8065
8459
|
init_fs();
|
|
@@ -8101,9 +8495,9 @@ import { randomUUID } from "node:crypto";
|
|
|
8101
8495
|
|
|
8102
8496
|
// ../entries/dist/fs.js
|
|
8103
8497
|
init_fs();
|
|
8104
|
-
import { readFileSync as
|
|
8498
|
+
import { readFileSync as readFileSync12, readdirSync as readdirSync3, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync11 } from "node:fs";
|
|
8105
8499
|
import { randomBytes } from "node:crypto";
|
|
8106
|
-
import { join as
|
|
8500
|
+
import { join as join7 } from "node:path";
|
|
8107
8501
|
|
|
8108
8502
|
// ../entries/dist/types.js
|
|
8109
8503
|
var CURRENT_ENTRY_SCHEMA_VERSION = 2;
|
|
@@ -8176,12 +8570,12 @@ var PROMPT_FRAME_ORIGIN = {
|
|
|
8176
8570
|
|
|
8177
8571
|
// ../entries/dist/digest-fs.js
|
|
8178
8572
|
init_fs();
|
|
8179
|
-
import { readFileSync as
|
|
8180
|
-
import { dirname as dirname4, join as
|
|
8573
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync2, writeFileSync as writeFileSync5, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync10 } from "node:fs";
|
|
8574
|
+
import { dirname as dirname4, join as join6 } from "node:path";
|
|
8181
8575
|
var digestsDirCached = null;
|
|
8182
|
-
function parseDigestFile(
|
|
8576
|
+
function parseDigestFile(path12, expectedVersion) {
|
|
8183
8577
|
try {
|
|
8184
|
-
const parsed = JSON.parse(
|
|
8578
|
+
const parsed = JSON.parse(readFileSync11(path12, "utf8"));
|
|
8185
8579
|
if (!parsed || typeof parsed !== "object")
|
|
8186
8580
|
return null;
|
|
8187
8581
|
if (parsed.version !== expectedVersion)
|
|
@@ -8201,10 +8595,10 @@ function digestsDir() {
|
|
|
8201
8595
|
return digestsDirCached;
|
|
8202
8596
|
}
|
|
8203
8597
|
function dayDigestPath(date) {
|
|
8204
|
-
return
|
|
8598
|
+
return join6(digestsDir(), "day", `${date}.json`);
|
|
8205
8599
|
}
|
|
8206
8600
|
function weekDigestPath(monday) {
|
|
8207
|
-
return
|
|
8601
|
+
return join6(digestsDir(), "week", `${monday}.json`);
|
|
8208
8602
|
}
|
|
8209
8603
|
function writeDayDigest(digest) {
|
|
8210
8604
|
const final = dayDigestPath(digest.key);
|
|
@@ -8221,7 +8615,7 @@ function writeDayDigest(digest) {
|
|
|
8221
8615
|
}
|
|
8222
8616
|
function readDayDigest(date) {
|
|
8223
8617
|
const p = dayDigestPath(date);
|
|
8224
|
-
if (!
|
|
8618
|
+
if (!existsSync10(p))
|
|
8225
8619
|
return null;
|
|
8226
8620
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
8227
8621
|
}
|
|
@@ -8254,7 +8648,7 @@ function writeWeekDigest(digest) {
|
|
|
8254
8648
|
}
|
|
8255
8649
|
function readWeekDigest(monday) {
|
|
8256
8650
|
const p = weekDigestPath(monday);
|
|
8257
|
-
if (!
|
|
8651
|
+
if (!existsSync10(p))
|
|
8258
8652
|
return null;
|
|
8259
8653
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
8260
8654
|
}
|
|
@@ -8284,7 +8678,7 @@ function entriesDir() {
|
|
|
8284
8678
|
return entriesDirCached;
|
|
8285
8679
|
}
|
|
8286
8680
|
function pathFor(sessionId, localDay2) {
|
|
8287
|
-
return
|
|
8681
|
+
return join7(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
8288
8682
|
}
|
|
8289
8683
|
function tmpPathFor(final) {
|
|
8290
8684
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
@@ -8332,19 +8726,19 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
8332
8726
|
}
|
|
8333
8727
|
function readEntry(sessionId, localDay2) {
|
|
8334
8728
|
const p = pathFor(sessionId, localDay2);
|
|
8335
|
-
if (!
|
|
8729
|
+
if (!existsSync11(p))
|
|
8336
8730
|
return null;
|
|
8337
|
-
const raw =
|
|
8731
|
+
const raw = readFileSync12(p, "utf8");
|
|
8338
8732
|
return JSON.parse(raw);
|
|
8339
8733
|
}
|
|
8340
8734
|
function entryExists(sessionId, localDay2) {
|
|
8341
|
-
return
|
|
8735
|
+
return existsSync11(pathFor(sessionId, localDay2));
|
|
8342
8736
|
}
|
|
8343
8737
|
function listEntryKeys() {
|
|
8344
8738
|
const dir = entriesDir();
|
|
8345
|
-
if (!
|
|
8739
|
+
if (!existsSync11(dir))
|
|
8346
8740
|
return [];
|
|
8347
|
-
return
|
|
8741
|
+
return readdirSync3(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
8348
8742
|
}
|
|
8349
8743
|
function listEntriesForDay(localDay2) {
|
|
8350
8744
|
const out = [];
|
|
@@ -8361,8 +8755,8 @@ function listEntriesForDay(localDay2) {
|
|
|
8361
8755
|
|
|
8362
8756
|
// src/perception/build-entries.ts
|
|
8363
8757
|
init_dist();
|
|
8364
|
-
import { statSync as
|
|
8365
|
-
import { basename as
|
|
8758
|
+
import { statSync as statSync3, readFileSync as readFileSync13 } from "node:fs";
|
|
8759
|
+
import { basename as basename3, dirname as dirname5 } from "node:path";
|
|
8366
8760
|
|
|
8367
8761
|
// ../entries/dist/signals.js
|
|
8368
8762
|
init_dist();
|
|
@@ -9102,8 +9496,8 @@ function decodeProjectDirName(projectDir) {
|
|
|
9102
9496
|
return projectDir.replace(/-/g, "/");
|
|
9103
9497
|
}
|
|
9104
9498
|
function buildEntriesForFile(filePath) {
|
|
9105
|
-
const stat =
|
|
9106
|
-
const raw =
|
|
9499
|
+
const stat = statSync3(filePath);
|
|
9500
|
+
const raw = readFileSync13(filePath, "utf8");
|
|
9107
9501
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
9108
9502
|
try {
|
|
9109
9503
|
return JSON.parse(l);
|
|
@@ -9113,8 +9507,8 @@ function buildEntriesForFile(filePath) {
|
|
|
9113
9507
|
}).filter((x) => x !== null);
|
|
9114
9508
|
if (rawLines.length === 0) return null;
|
|
9115
9509
|
const { meta, events } = parseTranscript(rawLines);
|
|
9116
|
-
const fileName =
|
|
9117
|
-
const projectDir =
|
|
9510
|
+
const fileName = basename3(filePath);
|
|
9511
|
+
const projectDir = basename3(dirname5(filePath));
|
|
9118
9512
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
9119
9513
|
const sd = {
|
|
9120
9514
|
...meta,
|
|
@@ -9369,7 +9763,7 @@ function buildIngestPayload(inputs) {
|
|
|
9369
9763
|
return {
|
|
9370
9764
|
ingestId: randomUUID(),
|
|
9371
9765
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9372
|
-
cliVersion: "1.0.
|
|
9766
|
+
cliVersion: "1.0.15",
|
|
9373
9767
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
9374
9768
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
9375
9769
|
...richRollup ? { richRollup } : {},
|
|
@@ -9396,8 +9790,8 @@ async function pushToTeamServer(config, payload) {
|
|
|
9396
9790
|
}
|
|
9397
9791
|
|
|
9398
9792
|
// src/team/git-remote.ts
|
|
9399
|
-
import { existsSync as
|
|
9400
|
-
import { dirname as dirname6, isAbsolute as isAbsolute2, join as
|
|
9793
|
+
import { existsSync as existsSync12, readFileSync as readFileSync14, statSync as statSync4 } from "node:fs";
|
|
9794
|
+
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join8, resolve as resolve3 } from "node:path";
|
|
9401
9795
|
var GITHUB_URL_RE = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/;
|
|
9402
9796
|
function parseGithubRemote(url) {
|
|
9403
9797
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
@@ -9418,19 +9812,19 @@ function originUrl2(configText) {
|
|
|
9418
9812
|
return null;
|
|
9419
9813
|
}
|
|
9420
9814
|
function gitConfigPathFor(dir) {
|
|
9421
|
-
const dotGit =
|
|
9422
|
-
const st =
|
|
9815
|
+
const dotGit = join8(dir, ".git");
|
|
9816
|
+
const st = statSync4(dotGit, { throwIfNoEntry: false });
|
|
9423
9817
|
if (!st) return null;
|
|
9424
|
-
if (st.isDirectory()) return
|
|
9425
|
-
const m =
|
|
9818
|
+
if (st.isDirectory()) return join8(dotGit, "config");
|
|
9819
|
+
const m = readFileSync14(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
9426
9820
|
if (!m) return null;
|
|
9427
|
-
const gd = isAbsolute2(m[1]) ? m[1] :
|
|
9428
|
-
const commondirFile =
|
|
9429
|
-
if (
|
|
9430
|
-
const common =
|
|
9431
|
-
return
|
|
9821
|
+
const gd = isAbsolute2(m[1]) ? m[1] : resolve3(dir, m[1]);
|
|
9822
|
+
const commondirFile = join8(gd, "commondir");
|
|
9823
|
+
if (existsSync12(commondirFile)) {
|
|
9824
|
+
const common = readFileSync14(commondirFile, "utf8").trim();
|
|
9825
|
+
return join8(isAbsolute2(common) ? common : resolve3(gd, common), "config");
|
|
9432
9826
|
}
|
|
9433
|
-
return
|
|
9827
|
+
return join8(gd, "config");
|
|
9434
9828
|
}
|
|
9435
9829
|
function createRepoResolver() {
|
|
9436
9830
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -9442,8 +9836,8 @@ function createRepoResolver() {
|
|
|
9442
9836
|
try {
|
|
9443
9837
|
for (let d = dir; ; d = dirname6(d)) {
|
|
9444
9838
|
const config = gitConfigPathFor(d);
|
|
9445
|
-
if (config &&
|
|
9446
|
-
const url = originUrl2(
|
|
9839
|
+
if (config && existsSync12(config)) {
|
|
9840
|
+
const url = originUrl2(readFileSync14(config, "utf8"));
|
|
9447
9841
|
repo = url ? parseGithubRemote(url) : null;
|
|
9448
9842
|
break;
|
|
9449
9843
|
}
|
|
@@ -9459,7 +9853,7 @@ function createRepoResolver() {
|
|
|
9459
9853
|
|
|
9460
9854
|
// src/team/queue.ts
|
|
9461
9855
|
init_fs();
|
|
9462
|
-
import { readFileSync as
|
|
9856
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync7, appendFileSync as appendFileSync4, statSync as statSync5, mkdirSync as mkdirSync6 } from "node:fs";
|
|
9463
9857
|
import { dirname as dirname7 } from "node:path";
|
|
9464
9858
|
var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
|
|
9465
9859
|
var MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
@@ -9469,7 +9863,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
9469
9863
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
9470
9864
|
appendFileSync4(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
9471
9865
|
try {
|
|
9472
|
-
const { size } =
|
|
9866
|
+
const { size } = statSync5(queuePath);
|
|
9473
9867
|
if (size > MAX_SIZE_BYTES) {
|
|
9474
9868
|
pruneOldest(queuePath);
|
|
9475
9869
|
}
|
|
@@ -9479,7 +9873,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
9479
9873
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
9480
9874
|
let lines;
|
|
9481
9875
|
try {
|
|
9482
|
-
lines =
|
|
9876
|
+
lines = readFileSync15(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
9483
9877
|
} catch {
|
|
9484
9878
|
return [];
|
|
9485
9879
|
}
|
|
@@ -9500,7 +9894,7 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
9500
9894
|
function pruneOldest(queuePath) {
|
|
9501
9895
|
let lines;
|
|
9502
9896
|
try {
|
|
9503
|
-
lines =
|
|
9897
|
+
lines = readFileSync15(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
9504
9898
|
} catch {
|
|
9505
9899
|
return;
|
|
9506
9900
|
}
|
|
@@ -9513,7 +9907,7 @@ init_storage();
|
|
|
9513
9907
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
9514
9908
|
|
|
9515
9909
|
// src/usage/profile.ts
|
|
9516
|
-
import { existsSync as
|
|
9910
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "node:fs";
|
|
9517
9911
|
import { dirname as dirname8 } from "node:path";
|
|
9518
9912
|
var PROFILE_ENDPOINT = "https://api.anthropic.com/api/oauth/profile";
|
|
9519
9913
|
var BETA_HEADER2 = "oauth-2025-04-20";
|
|
@@ -9557,9 +9951,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
9557
9951
|
};
|
|
9558
9952
|
}
|
|
9559
9953
|
function readCachedProfile(cachePath) {
|
|
9560
|
-
if (!
|
|
9954
|
+
if (!existsSync13(cachePath)) return null;
|
|
9561
9955
|
try {
|
|
9562
|
-
const raw = JSON.parse(
|
|
9956
|
+
const raw = JSON.parse(readFileSync16(cachePath, "utf8"));
|
|
9563
9957
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
9564
9958
|
return raw;
|
|
9565
9959
|
} catch {
|
|
@@ -9728,13 +10122,13 @@ async function runTeamBackfill(log3 = noopLog, filePath = USAGE_LOG, configOverr
|
|
|
9728
10122
|
|
|
9729
10123
|
// src/team/sync-log.ts
|
|
9730
10124
|
init_fs();
|
|
9731
|
-
import { readFileSync as
|
|
10125
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
9732
10126
|
var MAX_LINES = 300;
|
|
9733
10127
|
var MAX_MSG_CHARS = 1900;
|
|
9734
10128
|
function readPendingSyncLog(watermark) {
|
|
9735
10129
|
let raw;
|
|
9736
10130
|
try {
|
|
9737
|
-
raw =
|
|
10131
|
+
raw = readFileSync17(cclensPath("daemon.log"), "utf8");
|
|
9738
10132
|
} catch {
|
|
9739
10133
|
return { lines: [] };
|
|
9740
10134
|
}
|
|
@@ -9755,12 +10149,12 @@ function readPendingSyncLog(watermark) {
|
|
|
9755
10149
|
// src/team/last-push.ts
|
|
9756
10150
|
init_fs();
|
|
9757
10151
|
import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "node:fs";
|
|
9758
|
-
import { join as
|
|
10152
|
+
import { join as join9 } from "node:path";
|
|
9759
10153
|
var LAST_PUSH_FILE = "team-last-push.json";
|
|
9760
10154
|
function write(record, dir) {
|
|
9761
10155
|
const d = dir ?? cclensHome();
|
|
9762
10156
|
mkdirSync8(d, { recursive: true });
|
|
9763
|
-
writeFileSync9(
|
|
10157
|
+
writeFileSync9(join9(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
9764
10158
|
}
|
|
9765
10159
|
function writeLastPushSuccess(payload, dir) {
|
|
9766
10160
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -10355,12 +10749,12 @@ async function buildCyclePeaksForPush(planTier, loadCurve) {
|
|
|
10355
10749
|
}
|
|
10356
10750
|
|
|
10357
10751
|
// src/perception/worker.ts
|
|
10358
|
-
import { statSync as
|
|
10752
|
+
import { statSync as statSync7 } from "node:fs";
|
|
10359
10753
|
init_fs();
|
|
10360
10754
|
|
|
10361
10755
|
// src/perception/state.ts
|
|
10362
10756
|
init_fs();
|
|
10363
|
-
import { existsSync as
|
|
10757
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
|
|
10364
10758
|
import { dirname as dirname10 } from "node:path";
|
|
10365
10759
|
var STALE_MS = 15 * 60 * 1e3;
|
|
10366
10760
|
var pathCached = null;
|
|
@@ -10371,7 +10765,7 @@ function statePath() {
|
|
|
10371
10765
|
}
|
|
10372
10766
|
function readState() {
|
|
10373
10767
|
const p = statePath();
|
|
10374
|
-
if (!
|
|
10768
|
+
if (!existsSync15(p)) {
|
|
10375
10769
|
return {
|
|
10376
10770
|
sweep_in_progress: false,
|
|
10377
10771
|
last_sweep_started_at: null,
|
|
@@ -10379,7 +10773,7 @@ function readState() {
|
|
|
10379
10773
|
file_checkpoints: {}
|
|
10380
10774
|
};
|
|
10381
10775
|
}
|
|
10382
|
-
const raw =
|
|
10776
|
+
const raw = readFileSync18(p, "utf8");
|
|
10383
10777
|
return JSON.parse(raw);
|
|
10384
10778
|
}
|
|
10385
10779
|
function writeState(s) {
|
|
@@ -10415,18 +10809,18 @@ function updateCheckpoint(jsonlPath, cp) {
|
|
|
10415
10809
|
}
|
|
10416
10810
|
|
|
10417
10811
|
// src/perception/scan.ts
|
|
10418
|
-
import { readdirSync as
|
|
10419
|
-
import { join as
|
|
10420
|
-
import { homedir as
|
|
10812
|
+
import { readdirSync as readdirSync5 } from "node:fs";
|
|
10813
|
+
import { join as join11 } from "node:path";
|
|
10814
|
+
import { homedir as homedir5 } from "node:os";
|
|
10421
10815
|
async function listAllSessionJsonls(root) {
|
|
10422
|
-
const projectsRoot = root ??
|
|
10816
|
+
const projectsRoot = root ?? join11(homedir5(), ".claude", "projects");
|
|
10423
10817
|
const out = [];
|
|
10424
10818
|
try {
|
|
10425
|
-
for (const project of
|
|
10426
|
-
const dir =
|
|
10819
|
+
for (const project of readdirSync5(projectsRoot)) {
|
|
10820
|
+
const dir = join11(projectsRoot, project);
|
|
10427
10821
|
try {
|
|
10428
|
-
for (const f of
|
|
10429
|
-
if (f.endsWith(".jsonl")) out.push(
|
|
10822
|
+
for (const f of readdirSync5(dir)) {
|
|
10823
|
+
if (f.endsWith(".jsonl")) out.push(join11(dir, f));
|
|
10430
10824
|
}
|
|
10431
10825
|
} catch {
|
|
10432
10826
|
}
|
|
@@ -10453,7 +10847,7 @@ async function runPerceptionSweep(opts = {}) {
|
|
|
10453
10847
|
const files = await listAllSessionJsonls(opts.projectsRoot);
|
|
10454
10848
|
for (const f of files) {
|
|
10455
10849
|
try {
|
|
10456
|
-
const stat =
|
|
10850
|
+
const stat = statSync7(f);
|
|
10457
10851
|
const prev = state.file_checkpoints[f];
|
|
10458
10852
|
if (prev && prev.byte_offset >= stat.size) continue;
|
|
10459
10853
|
const built = buildEntriesForFile(f);
|
|
@@ -10485,7 +10879,7 @@ async function runPerceptionSweep(opts = {}) {
|
|
|
10485
10879
|
const built = buildEntries(detail);
|
|
10486
10880
|
for (const e of built) {
|
|
10487
10881
|
try {
|
|
10488
|
-
const stat =
|
|
10882
|
+
const stat = statSync7(meta.filePath);
|
|
10489
10883
|
e.source_checkpoint.byte_offset = stat.size;
|
|
10490
10884
|
} catch {
|
|
10491
10885
|
}
|
|
@@ -10987,8 +11381,8 @@ function getErrorMap() {
|
|
|
10987
11381
|
|
|
10988
11382
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
10989
11383
|
var makeIssue = (params) => {
|
|
10990
|
-
const { data, path:
|
|
10991
|
-
const fullPath = [...
|
|
11384
|
+
const { data, path: path12, errorMaps, issueData } = params;
|
|
11385
|
+
const fullPath = [...path12, ...issueData.path || []];
|
|
10992
11386
|
const fullIssue = {
|
|
10993
11387
|
...issueData,
|
|
10994
11388
|
path: fullPath
|
|
@@ -11104,11 +11498,11 @@ var errorUtil;
|
|
|
11104
11498
|
|
|
11105
11499
|
// ../../node_modules/zod/v3/types.js
|
|
11106
11500
|
var ParseInputLazyPath = class {
|
|
11107
|
-
constructor(parent, value,
|
|
11501
|
+
constructor(parent, value, path12, key) {
|
|
11108
11502
|
this._cachedPath = [];
|
|
11109
11503
|
this.parent = parent;
|
|
11110
11504
|
this.data = value;
|
|
11111
|
-
this._path =
|
|
11505
|
+
this._path = path12;
|
|
11112
11506
|
this._key = key;
|
|
11113
11507
|
}
|
|
11114
11508
|
get path() {
|
|
@@ -14642,32 +15036,32 @@ var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
|
|
|
14642
15036
|
// ../entries/dist/llm-runner.js
|
|
14643
15037
|
init_fs();
|
|
14644
15038
|
import { spawn as spawn2 } from "node:child_process";
|
|
14645
|
-
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync12, existsSync as
|
|
14646
|
-
import { join as
|
|
15039
|
+
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync12, existsSync as existsSync18 } from "node:fs";
|
|
15040
|
+
import { join as join14 } from "node:path";
|
|
14647
15041
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
14648
15042
|
|
|
14649
15043
|
// ../entries/dist/claude-bin.js
|
|
14650
|
-
import { existsSync as
|
|
14651
|
-
import { join as
|
|
14652
|
-
import { homedir as
|
|
15044
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
15045
|
+
import { join as join12, dirname as dirname11, delimiter } from "node:path";
|
|
15046
|
+
import { homedir as homedir6 } from "node:os";
|
|
14653
15047
|
function resolveClaudeBin(opts = {}) {
|
|
14654
15048
|
const env = opts.env ?? process.env;
|
|
14655
|
-
const home = opts.home ??
|
|
15049
|
+
const home = opts.home ?? homedir6();
|
|
14656
15050
|
const execPath = opts.execPath ?? process.execPath;
|
|
14657
|
-
const exists = opts.exists ??
|
|
15051
|
+
const exists = opts.exists ?? existsSync16;
|
|
14658
15052
|
for (const dir of (env.PATH ?? "").split(delimiter)) {
|
|
14659
15053
|
if (!dir)
|
|
14660
15054
|
continue;
|
|
14661
|
-
const onPath =
|
|
15055
|
+
const onPath = join12(dir, "claude");
|
|
14662
15056
|
if (exists(onPath))
|
|
14663
15057
|
return onPath;
|
|
14664
15058
|
}
|
|
14665
15059
|
return [
|
|
14666
|
-
|
|
15060
|
+
join12(home, ".local", "bin", "claude"),
|
|
14667
15061
|
// native installer
|
|
14668
|
-
|
|
15062
|
+
join12(home, ".claude", "local", "claude"),
|
|
14669
15063
|
// legacy local install
|
|
14670
|
-
|
|
15064
|
+
join12(dirname11(execPath), "claude"),
|
|
14671
15065
|
// npm -g, beside the node running us
|
|
14672
15066
|
"/opt/homebrew/bin/claude",
|
|
14673
15067
|
"/usr/local/bin/claude"
|
|
@@ -14689,9 +15083,9 @@ var ClaudeBinNotFoundError = class extends Error {
|
|
|
14689
15083
|
};
|
|
14690
15084
|
|
|
14691
15085
|
// ../entries/dist/tmux-runner.js
|
|
14692
|
-
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as
|
|
14693
|
-
import { join as
|
|
14694
|
-
import { homedir as
|
|
15086
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync17, readdirSync as readdirSync6, realpathSync as realpathSync2, readFileSync as readFileSync19, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
|
|
15087
|
+
import { join as join13 } from "node:path";
|
|
15088
|
+
import { homedir as homedir7 } from "node:os";
|
|
14695
15089
|
import { spawnSync } from "node:child_process";
|
|
14696
15090
|
var TmuxUnavailableError = class extends Error {
|
|
14697
15091
|
constructor(message) {
|
|
@@ -14719,16 +15113,16 @@ function tmuxRunnerAvailable() {
|
|
|
14719
15113
|
return { ok: true };
|
|
14720
15114
|
}
|
|
14721
15115
|
function runtimeCwd() {
|
|
14722
|
-
const dir =
|
|
14723
|
-
if (!
|
|
15116
|
+
const dir = join13(homedir7(), ".cclens", "runtime");
|
|
15117
|
+
if (!existsSync17(dir))
|
|
14724
15118
|
mkdirSync10(dir, { recursive: true });
|
|
14725
15119
|
return realpathSync2(dir);
|
|
14726
15120
|
}
|
|
14727
15121
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
14728
|
-
const cfgPath =
|
|
15122
|
+
const cfgPath = join13(homedir7(), ".claude.json");
|
|
14729
15123
|
let cfg;
|
|
14730
15124
|
try {
|
|
14731
|
-
cfg = JSON.parse(
|
|
15125
|
+
cfg = JSON.parse(readFileSync19(cfgPath, "utf8"));
|
|
14732
15126
|
} catch {
|
|
14733
15127
|
return;
|
|
14734
15128
|
}
|
|
@@ -14771,9 +15165,9 @@ async function runClaudeUnderTmuxImpl(args) {
|
|
|
14771
15165
|
ensureRuntimeCwdTrusted(cwd);
|
|
14772
15166
|
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
14773
15167
|
const sessionName = `cclens-${runId}`;
|
|
14774
|
-
const systemFile =
|
|
14775
|
-
const userFile =
|
|
14776
|
-
const wrapper =
|
|
15168
|
+
const systemFile = join13(cwd, `system-${runId}.txt`);
|
|
15169
|
+
const userFile = join13(cwd, `user-${runId}.txt`);
|
|
15170
|
+
const wrapper = join13(cwd, `run-${runId}.sh`);
|
|
14777
15171
|
writeFileSync11(systemFile, args.systemPrompt);
|
|
14778
15172
|
writeFileSync11(userFile, args.reminder ? `${args.userPrompt}
|
|
14779
15173
|
|
|
@@ -14852,35 +15246,35 @@ function num(v) {
|
|
|
14852
15246
|
function sleep(ms) {
|
|
14853
15247
|
return new Promise((r) => setTimeout(r, ms));
|
|
14854
15248
|
}
|
|
14855
|
-
var PROJECTS_ROOT = () =>
|
|
15249
|
+
var PROJECTS_ROOT = () => join13(homedir7(), ".claude", "projects");
|
|
14856
15250
|
function snapshotAllTranscripts() {
|
|
14857
15251
|
const out = /* @__PURE__ */ new Set();
|
|
14858
15252
|
const root = PROJECTS_ROOT();
|
|
14859
15253
|
let subs;
|
|
14860
15254
|
try {
|
|
14861
|
-
subs =
|
|
15255
|
+
subs = readdirSync6(root);
|
|
14862
15256
|
} catch {
|
|
14863
15257
|
return out;
|
|
14864
15258
|
}
|
|
14865
15259
|
for (const sub of subs) {
|
|
14866
|
-
const dir =
|
|
15260
|
+
const dir = join13(root, sub);
|
|
14867
15261
|
let files;
|
|
14868
15262
|
try {
|
|
14869
|
-
files =
|
|
15263
|
+
files = readdirSync6(dir);
|
|
14870
15264
|
} catch {
|
|
14871
15265
|
continue;
|
|
14872
15266
|
}
|
|
14873
15267
|
for (const f of files) {
|
|
14874
15268
|
if (f.endsWith(".jsonl"))
|
|
14875
|
-
out.add(
|
|
15269
|
+
out.add(join13(dir, f));
|
|
14876
15270
|
}
|
|
14877
15271
|
}
|
|
14878
15272
|
return out;
|
|
14879
15273
|
}
|
|
14880
|
-
function readJsonlCwd(
|
|
15274
|
+
function readJsonlCwd(path12, maxLines = 8) {
|
|
14881
15275
|
let raw;
|
|
14882
15276
|
try {
|
|
14883
|
-
raw =
|
|
15277
|
+
raw = readFileSync19(path12, "utf8");
|
|
14884
15278
|
} catch {
|
|
14885
15279
|
return void 0;
|
|
14886
15280
|
}
|
|
@@ -14908,22 +15302,22 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
14908
15302
|
const root = PROJECTS_ROOT();
|
|
14909
15303
|
let subs;
|
|
14910
15304
|
try {
|
|
14911
|
-
subs =
|
|
15305
|
+
subs = readdirSync6(root);
|
|
14912
15306
|
} catch {
|
|
14913
15307
|
subs = [];
|
|
14914
15308
|
}
|
|
14915
15309
|
for (const sub of subs) {
|
|
14916
|
-
const dir =
|
|
15310
|
+
const dir = join13(root, sub);
|
|
14917
15311
|
let files;
|
|
14918
15312
|
try {
|
|
14919
|
-
files =
|
|
15313
|
+
files = readdirSync6(dir);
|
|
14920
15314
|
} catch {
|
|
14921
15315
|
continue;
|
|
14922
15316
|
}
|
|
14923
15317
|
for (const f of files) {
|
|
14924
15318
|
if (!f.endsWith(".jsonl"))
|
|
14925
15319
|
continue;
|
|
14926
|
-
const full =
|
|
15320
|
+
const full = join13(dir, f);
|
|
14927
15321
|
if (existingBefore.has(full))
|
|
14928
15322
|
continue;
|
|
14929
15323
|
if (readJsonlCwd(full) === targetCwd)
|
|
@@ -14934,10 +15328,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
14934
15328
|
}
|
|
14935
15329
|
throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
|
|
14936
15330
|
}
|
|
14937
|
-
function parseTranscript2(
|
|
15331
|
+
function parseTranscript2(path12, defaultModel) {
|
|
14938
15332
|
let raw;
|
|
14939
15333
|
try {
|
|
14940
|
-
raw =
|
|
15334
|
+
raw = readFileSync19(path12, "utf8");
|
|
14941
15335
|
} catch {
|
|
14942
15336
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
14943
15337
|
}
|
|
@@ -14997,7 +15391,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
|
|
|
14997
15391
|
}
|
|
14998
15392
|
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
14999
15393
|
try {
|
|
15000
|
-
unlinkSync3(
|
|
15394
|
+
unlinkSync3(join13(cwd, f));
|
|
15001
15395
|
} catch {
|
|
15002
15396
|
}
|
|
15003
15397
|
}
|
|
@@ -15012,7 +15406,7 @@ function shellEscape(s) {
|
|
|
15012
15406
|
// ../entries/dist/llm-runner.js
|
|
15013
15407
|
var RUNS_DIR = cclensPath("llm-runs");
|
|
15014
15408
|
function ensureRunsDir() {
|
|
15015
|
-
if (!
|
|
15409
|
+
if (!existsSync18(RUNS_DIR)) {
|
|
15016
15410
|
try {
|
|
15017
15411
|
mkdirSync11(RUNS_DIR, { recursive: true });
|
|
15018
15412
|
} catch {
|
|
@@ -15041,17 +15435,17 @@ function newRunId(kind) {
|
|
|
15041
15435
|
return `${ts}_${kind}_${short}`;
|
|
15042
15436
|
}
|
|
15043
15437
|
function tracePath(runId) {
|
|
15044
|
-
return
|
|
15438
|
+
return join14(RUNS_DIR, `${runId}.jsonl`);
|
|
15045
15439
|
}
|
|
15046
|
-
function safeAppend(
|
|
15440
|
+
function safeAppend(path12, line) {
|
|
15047
15441
|
try {
|
|
15048
|
-
appendFileSync5(
|
|
15442
|
+
appendFileSync5(path12, line);
|
|
15049
15443
|
} catch {
|
|
15050
15444
|
}
|
|
15051
15445
|
}
|
|
15052
|
-
function safeWrite(
|
|
15446
|
+
function safeWrite(path12, line) {
|
|
15053
15447
|
try {
|
|
15054
|
-
writeFileSync12(
|
|
15448
|
+
writeFileSync12(path12, line);
|
|
15055
15449
|
} catch {
|
|
15056
15450
|
}
|
|
15057
15451
|
}
|
|
@@ -15129,7 +15523,7 @@ async function runClaudeSubprocess(args) {
|
|
|
15129
15523
|
return runClaudePrintMode(args);
|
|
15130
15524
|
}
|
|
15131
15525
|
function runClaudePrintMode(args) {
|
|
15132
|
-
return new Promise((
|
|
15526
|
+
return new Promise((resolve5, reject) => {
|
|
15133
15527
|
ensureRunsDir();
|
|
15134
15528
|
const kind = detectKindFromSystemPrompt(args.systemPrompt);
|
|
15135
15529
|
const runId = newRunId(kind);
|
|
@@ -15267,7 +15661,7 @@ ${args.reminder}` : args.userPrompt;
|
|
|
15267
15661
|
reject(new Error(`claude exited ${code}: ${stderr.trim().slice(0, 300)}`));
|
|
15268
15662
|
return;
|
|
15269
15663
|
}
|
|
15270
|
-
|
|
15664
|
+
resolve5({ content: buffer, input_tokens: inputTokens, output_tokens: outputTokens, model: modelUsed });
|
|
15271
15665
|
});
|
|
15272
15666
|
proc.on("error", (err) => {
|
|
15273
15667
|
safeAppend(trace, JSON.stringify({ _meta: { type: "spawn_error", run_id: runId, ts: (/* @__PURE__ */ new Date()).toISOString(), error: err.message } }) + "\n");
|
|
@@ -15447,7 +15841,7 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
|
|
|
15447
15841
|
|
|
15448
15842
|
// ../entries/dist/budget.js
|
|
15449
15843
|
init_fs();
|
|
15450
|
-
import { appendFileSync as appendFileSync6, readFileSync as
|
|
15844
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync20, existsSync as existsSync19, mkdirSync as mkdirSync12 } from "node:fs";
|
|
15451
15845
|
import { dirname as dirname12 } from "node:path";
|
|
15452
15846
|
var spendPathCached = null;
|
|
15453
15847
|
function spendPath() {
|
|
@@ -15463,12 +15857,12 @@ function appendSpend(record) {
|
|
|
15463
15857
|
}
|
|
15464
15858
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
15465
15859
|
const p = spendPath();
|
|
15466
|
-
if (!
|
|
15860
|
+
if (!existsSync19(p))
|
|
15467
15861
|
return 0;
|
|
15468
15862
|
const year = now.getUTCFullYear();
|
|
15469
15863
|
const month = now.getUTCMonth();
|
|
15470
15864
|
let total = 0;
|
|
15471
|
-
const raw =
|
|
15865
|
+
const raw = readFileSync20(p, "utf8");
|
|
15472
15866
|
for (const line of raw.split("\n")) {
|
|
15473
15867
|
if (!line)
|
|
15474
15868
|
continue;
|
|
@@ -15490,7 +15884,7 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
|
15490
15884
|
|
|
15491
15885
|
// ../entries/dist/pipeline-lock.js
|
|
15492
15886
|
init_fs();
|
|
15493
|
-
import { writeFileSync as writeFileSync13, unlinkSync as unlinkSync4, existsSync as
|
|
15887
|
+
import { writeFileSync as writeFileSync13, unlinkSync as unlinkSync4, existsSync as existsSync20, readFileSync as readFileSync21, statSync as statSync8 } from "node:fs";
|
|
15494
15888
|
var STALE_MS2 = 60 * 1e3;
|
|
15495
15889
|
var HEARTBEAT_MS = 30 * 1e3;
|
|
15496
15890
|
var lockPathCached = null;
|
|
@@ -15536,13 +15930,13 @@ function pidAlive(pid) {
|
|
|
15536
15930
|
}
|
|
15537
15931
|
function interactiveLockFresh(nowMs) {
|
|
15538
15932
|
const p = lockPath();
|
|
15539
|
-
if (!
|
|
15933
|
+
if (!existsSync20(p))
|
|
15540
15934
|
return false;
|
|
15541
15935
|
try {
|
|
15542
|
-
const mtime =
|
|
15936
|
+
const mtime = statSync8(p).mtimeMs;
|
|
15543
15937
|
if (nowMs - mtime > STALE_MS2)
|
|
15544
15938
|
return false;
|
|
15545
|
-
const pid = Number(
|
|
15939
|
+
const pid = Number(readFileSync21(p, "utf8").trim());
|
|
15546
15940
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
15547
15941
|
return false;
|
|
15548
15942
|
if (!pidAlive(pid))
|
|
@@ -15557,7 +15951,7 @@ function interactiveLockFresh(nowMs) {
|
|
|
15557
15951
|
var THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
15558
15952
|
|
|
15559
15953
|
// ../entries/dist/settings.js
|
|
15560
|
-
import { readFileSync as
|
|
15954
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync14, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync21 } from "node:fs";
|
|
15561
15955
|
init_fs();
|
|
15562
15956
|
var DEFAULT_SETTINGS = {
|
|
15563
15957
|
ai_features: {
|
|
@@ -15589,10 +15983,10 @@ function fromDisk(d) {
|
|
|
15589
15983
|
}
|
|
15590
15984
|
function readSettings() {
|
|
15591
15985
|
const p = settingsPath();
|
|
15592
|
-
if (!
|
|
15986
|
+
if (!existsSync21(p))
|
|
15593
15987
|
return DEFAULT_SETTINGS;
|
|
15594
15988
|
try {
|
|
15595
|
-
const raw =
|
|
15989
|
+
const raw = readFileSync22(p, "utf8");
|
|
15596
15990
|
return fromDisk(JSON.parse(raw));
|
|
15597
15991
|
} catch {
|
|
15598
15992
|
return DEFAULT_SETTINGS;
|
|
@@ -18352,14 +18746,14 @@ async function getUpdateAvailability() {
|
|
|
18352
18746
|
if (isDevMode()) return null;
|
|
18353
18747
|
const latest = await fetchLatestVersion();
|
|
18354
18748
|
if (latest === null) return {
|
|
18355
|
-
current: "1.0.
|
|
18749
|
+
current: "1.0.15",
|
|
18356
18750
|
latest: null,
|
|
18357
18751
|
updateAvailable: false
|
|
18358
18752
|
};
|
|
18359
18753
|
return {
|
|
18360
|
-
current: "1.0.
|
|
18754
|
+
current: "1.0.15",
|
|
18361
18755
|
latest,
|
|
18362
|
-
updateAvailable: shouldUpdate("1.0.
|
|
18756
|
+
updateAvailable: shouldUpdate("1.0.15", latest)
|
|
18363
18757
|
};
|
|
18364
18758
|
}
|
|
18365
18759
|
|
|
@@ -18451,7 +18845,7 @@ var perceptionHandle = setInterval(async () => {
|
|
|
18451
18845
|
}, PERCEPTION_INTERVAL_MS);
|
|
18452
18846
|
function readUpdateState() {
|
|
18453
18847
|
try {
|
|
18454
|
-
return JSON.parse(
|
|
18848
|
+
return JSON.parse(readFileSync25(UPDATE_STATE, "utf8"));
|
|
18455
18849
|
} catch {
|
|
18456
18850
|
return null;
|
|
18457
18851
|
}
|
|
@@ -18471,7 +18865,7 @@ function nextUpdateCheckFromState(nowMs) {
|
|
|
18471
18865
|
}
|
|
18472
18866
|
var nextUpdateCheckAtMs = nextUpdateCheckFromState(Date.now());
|
|
18473
18867
|
function cliEntryPath() {
|
|
18474
|
-
return
|
|
18868
|
+
return join16(dirname15(fileURLToPath2(import.meta.url)), "index.js");
|
|
18475
18869
|
}
|
|
18476
18870
|
async function runDaemonUpdateCheck() {
|
|
18477
18871
|
if (process.env.FLEETLENS_DAEMON_AUTO_UPDATE === "0") {
|
|
@@ -18503,7 +18897,7 @@ async function runDaemonUpdateCheck() {
|
|
|
18503
18897
|
return;
|
|
18504
18898
|
}
|
|
18505
18899
|
const entry = cliEntryPath();
|
|
18506
|
-
if (!
|
|
18900
|
+
if (!existsSync23(entry)) {
|
|
18507
18901
|
log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
|
|
18508
18902
|
return;
|
|
18509
18903
|
}
|
|
@@ -18663,16 +19057,43 @@ async function pollAuxiliaryUsage() {
|
|
|
18663
19057
|
log2("warn", `grok poll failed: ${err.message}`);
|
|
18664
19058
|
}
|
|
18665
19059
|
}
|
|
19060
|
+
try {
|
|
19061
|
+
const cmdSnapshot = await fetchCommandCodeUsage();
|
|
19062
|
+
appendSnapshot(USAGE_LOG3, cmdSnapshot);
|
|
19063
|
+
const monthly = cmdSnapshot.monthly?.utilization === null || cmdSnapshot.monthly?.utilization === void 0 ? "\u2014" : `${cmdSnapshot.monthly.utilization}%`;
|
|
19064
|
+
const fiveHour = cmdSnapshot.five_hour.utilization === null ? "\u2014" : `${cmdSnapshot.five_hour.utilization}%`;
|
|
19065
|
+
const sevenDay = cmdSnapshot.seven_day.utilization === null ? "\u2014" : `${cmdSnapshot.seven_day.utilization}%`;
|
|
19066
|
+
log2("info", `command-code snapshot monthly=${monthly} 5h=${fiveHour} 7d=${sevenDay}`);
|
|
19067
|
+
} catch (err) {
|
|
19068
|
+
if (err instanceof CommandCodeApiError && err.code === "no_auth") {
|
|
19069
|
+
pruneAgent(USAGE_LOG3, "command-code");
|
|
19070
|
+
} else {
|
|
19071
|
+
log2("warn", `command-code poll failed: ${err.message}`);
|
|
19072
|
+
}
|
|
19073
|
+
}
|
|
18666
19074
|
}
|
|
18667
19075
|
async function pollClaudeUsage() {
|
|
18668
19076
|
try {
|
|
18669
|
-
const
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
"
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
19077
|
+
const { snapshots, errors } = await fetchAllClaudeUsage();
|
|
19078
|
+
for (const snapshot of snapshots) {
|
|
19079
|
+
appendSnapshot(USAGE_LOG3, snapshot);
|
|
19080
|
+
const tag = snapshot.agent ?? "claude-code";
|
|
19081
|
+
log2(
|
|
19082
|
+
"info",
|
|
19083
|
+
`${tag} snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
|
|
19084
|
+
);
|
|
19085
|
+
}
|
|
19086
|
+
for (const err of errors) {
|
|
19087
|
+
const tag = err.slug ? `claude-code:${err.slug}` : "claude-code";
|
|
19088
|
+
log2("warn", `poll failed (${err.code}) ${tag}: ${err.message}`);
|
|
19089
|
+
}
|
|
19090
|
+
if (snapshots.length > 0) return "success";
|
|
19091
|
+
if (errors.length === 0) {
|
|
19092
|
+
log2("warn", "poll failed (no_token): No Claude Code OAuth token found. Run `claude` to log in first.");
|
|
19093
|
+
return "auth";
|
|
19094
|
+
}
|
|
19095
|
+
if (errors.every((e) => e.code === "network")) return "network";
|
|
19096
|
+
return "auth";
|
|
18676
19097
|
} catch (err) {
|
|
18677
19098
|
if (err instanceof UsageApiError) {
|
|
18678
19099
|
log2("warn", `poll failed (${err.code}): ${err.message}`);
|
|
@@ -18694,7 +19115,7 @@ function scheduleAfter(now, outcome) {
|
|
|
18694
19115
|
nextPollAtMs = now + currentIntervalMs;
|
|
18695
19116
|
}
|
|
18696
19117
|
function sleep2(ms) {
|
|
18697
|
-
return new Promise((
|
|
19118
|
+
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
18698
19119
|
}
|
|
18699
19120
|
async function runLoop() {
|
|
18700
19121
|
while (true) {
|
|
@@ -18710,15 +19131,18 @@ async function runLoop() {
|
|
|
18710
19131
|
`wake-from-sleep catch-up: ${Math.round((now - nextPollAtMs + currentIntervalMs) / 1e3)}s since last poll`
|
|
18711
19132
|
);
|
|
18712
19133
|
}
|
|
18713
|
-
const
|
|
18714
|
-
if (
|
|
18715
|
-
|
|
18716
|
-
|
|
18717
|
-
|
|
18718
|
-
|
|
18719
|
-
|
|
18720
|
-
|
|
19134
|
+
const accounts = discoverClaudeAccounts({ nowMs: now });
|
|
19135
|
+
if (accounts.length === 0) {
|
|
19136
|
+
const expired = discoverClaudeAccounts({ nowMs: now, usableOnly: false });
|
|
19137
|
+
if (expired.length > 0) {
|
|
19138
|
+
if (!waitingForRefresh) {
|
|
19139
|
+
log2("info", "token expired; waiting for Claude Code to refresh it");
|
|
19140
|
+
waitingForRefresh = true;
|
|
19141
|
+
}
|
|
19142
|
+
} else {
|
|
19143
|
+
log2("warn", "no Claude Code OAuth token found; waiting");
|
|
18721
19144
|
waitingForRefresh = true;
|
|
19145
|
+
nextPollAtMs = now + BASE_INTERVAL_MS;
|
|
18722
19146
|
}
|
|
18723
19147
|
} else {
|
|
18724
19148
|
if (waitingForRefresh) {
|