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/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, COPILOT_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
678
|
+
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;
|
|
679
679
|
var init_agent_metadata = __esm({
|
|
680
680
|
"../parser/dist/agent-metadata.js"() {
|
|
681
681
|
"use strict";
|
|
@@ -736,6 +736,14 @@ var init_agent_metadata = __esm({
|
|
|
736
736
|
accentColor: "rgb(100, 116, 139)",
|
|
737
737
|
iconChar: "\u25C8"
|
|
738
738
|
};
|
|
739
|
+
COMMAND_CODE_METADATA = {
|
|
740
|
+
kind: "command-code",
|
|
741
|
+
displayName: "Command Code",
|
|
742
|
+
shortLabel: "Cmd",
|
|
743
|
+
// Lime — distinct from Codex teal and Claude terracotta.
|
|
744
|
+
accentColor: "rgb(132, 204, 22)",
|
|
745
|
+
iconChar: ">"
|
|
746
|
+
};
|
|
739
747
|
agentMetadata = [
|
|
740
748
|
CLAUDE_CODE_METADATA,
|
|
741
749
|
CODEX_METADATA,
|
|
@@ -744,7 +752,8 @@ var init_agent_metadata = __esm({
|
|
|
744
752
|
ANTIGRAVITY_METADATA,
|
|
745
753
|
COWORK_METADATA,
|
|
746
754
|
ZAI_METADATA,
|
|
747
|
-
GROK_METADATA
|
|
755
|
+
GROK_METADATA,
|
|
756
|
+
COMMAND_CODE_METADATA
|
|
748
757
|
];
|
|
749
758
|
KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
|
|
750
759
|
}
|
|
@@ -1601,11 +1610,11 @@ function defaultBranch(commonDir) {
|
|
|
1601
1610
|
}
|
|
1602
1611
|
return void 0;
|
|
1603
1612
|
}
|
|
1604
|
-
function readGitFolder(
|
|
1605
|
-
if (!existsSync(
|
|
1613
|
+
function readGitFolder(path12) {
|
|
1614
|
+
if (!existsSync(path12))
|
|
1606
1615
|
return { exists: false, isWorktree: false };
|
|
1607
1616
|
try {
|
|
1608
|
-
const git = nearestDotGit(realpathOrSelf(
|
|
1617
|
+
const git = nearestDotGit(realpathOrSelf(path12));
|
|
1609
1618
|
if (!git)
|
|
1610
1619
|
return { exists: true, isWorktree: false };
|
|
1611
1620
|
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
@@ -6298,9 +6307,9 @@ function onDiskVersion() {
|
|
|
6298
6307
|
try {
|
|
6299
6308
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
6300
6309
|
const pkg = JSON.parse(readFileSync5(join3(here, "..", "package.json"), "utf8"));
|
|
6301
|
-
return pkg.version ?? "1.0.
|
|
6310
|
+
return pkg.version ?? "1.0.15";
|
|
6302
6311
|
} catch {
|
|
6303
|
-
return "1.0.
|
|
6312
|
+
return "1.0.15";
|
|
6304
6313
|
}
|
|
6305
6314
|
}
|
|
6306
6315
|
function getServerStatus() {
|
|
@@ -6312,7 +6321,7 @@ function getServerStatus() {
|
|
|
6312
6321
|
return { running: false };
|
|
6313
6322
|
}
|
|
6314
6323
|
function isServerStale(status2) {
|
|
6315
|
-
return status2.running === true && status2.version !== "1.0.
|
|
6324
|
+
return status2.running === true && status2.version !== "1.0.15";
|
|
6316
6325
|
}
|
|
6317
6326
|
async function ensureCurrentServer(opts = {}) {
|
|
6318
6327
|
const status2 = getServerStatus();
|
|
@@ -6407,11 +6416,11 @@ function stopServer() {
|
|
|
6407
6416
|
}
|
|
6408
6417
|
async function checkPort(port) {
|
|
6409
6418
|
const { createServer } = await import("node:net");
|
|
6410
|
-
return new Promise((
|
|
6419
|
+
return new Promise((resolve5) => {
|
|
6411
6420
|
const server = createServer();
|
|
6412
|
-
server.once("error", () =>
|
|
6421
|
+
server.once("error", () => resolve5(true));
|
|
6413
6422
|
server.once("listening", () => {
|
|
6414
|
-
server.close(() =>
|
|
6423
|
+
server.close(() => resolve5(false));
|
|
6415
6424
|
});
|
|
6416
6425
|
server.listen(port, "localhost");
|
|
6417
6426
|
});
|
|
@@ -6828,9 +6837,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
6828
6837
|
console.warn(
|
|
6829
6838
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
6830
6839
|
);
|
|
6831
|
-
} else if (verify.installedVersion !== "1.0.
|
|
6840
|
+
} else if (verify.installedVersion !== "1.0.15") {
|
|
6832
6841
|
console.log(
|
|
6833
|
-
` \u2192 This process is still running ${"1.0.
|
|
6842
|
+
` \u2192 This process is still running ${"1.0.15"}. Next invocation will use ${verify.installedVersion}.`
|
|
6834
6843
|
);
|
|
6835
6844
|
}
|
|
6836
6845
|
}
|
|
@@ -6865,14 +6874,14 @@ async function getUpdateAvailability() {
|
|
|
6865
6874
|
if (isDevMode()) return null;
|
|
6866
6875
|
const latest = await fetchLatestVersion();
|
|
6867
6876
|
if (latest === null) return {
|
|
6868
|
-
current: "1.0.
|
|
6877
|
+
current: "1.0.15",
|
|
6869
6878
|
latest: null,
|
|
6870
6879
|
updateAvailable: false
|
|
6871
6880
|
};
|
|
6872
6881
|
return {
|
|
6873
|
-
current: "1.0.
|
|
6882
|
+
current: "1.0.15",
|
|
6874
6883
|
latest,
|
|
6875
|
-
updateAvailable: shouldUpdate("1.0.
|
|
6884
|
+
updateAvailable: shouldUpdate("1.0.15", latest)
|
|
6876
6885
|
};
|
|
6877
6886
|
}
|
|
6878
6887
|
async function checkForUpdate() {
|
|
@@ -6962,7 +6971,7 @@ async function restartServices(state) {
|
|
|
6962
6971
|
}
|
|
6963
6972
|
async function forceUpdate() {
|
|
6964
6973
|
const latest = await fetchLatestVersion();
|
|
6965
|
-
const current = "1.0.
|
|
6974
|
+
const current = "1.0.15";
|
|
6966
6975
|
if (latest === null) {
|
|
6967
6976
|
console.error("Could not reach npm registry. Check your network.");
|
|
6968
6977
|
process.exit(1);
|
|
@@ -7180,13 +7189,13 @@ function recordOptOut() {
|
|
|
7180
7189
|
writeFlags({ optedOut: true });
|
|
7181
7190
|
}
|
|
7182
7191
|
function promptYesNo(question, defaultYes) {
|
|
7183
|
-
return new Promise((
|
|
7192
|
+
return new Promise((resolve5) => {
|
|
7184
7193
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
7185
7194
|
rl.question(question, (answer) => {
|
|
7186
7195
|
rl.close();
|
|
7187
7196
|
const a = answer.trim().toLowerCase();
|
|
7188
|
-
if (a === "") return
|
|
7189
|
-
|
|
7197
|
+
if (a === "") return resolve5(defaultYes);
|
|
7198
|
+
resolve5(a === "y" || a === "yes");
|
|
7190
7199
|
});
|
|
7191
7200
|
});
|
|
7192
7201
|
}
|
|
@@ -7383,7 +7392,7 @@ async function status() {
|
|
|
7383
7392
|
}
|
|
7384
7393
|
if (isServerStale(server)) {
|
|
7385
7394
|
console.log(
|
|
7386
|
-
` \u26A0 serving stale ${ver} (CLI is ${"1.0.
|
|
7395
|
+
` \u26A0 serving stale ${ver} (CLI is ${"1.0.15"}) \u2014 run 'fleetlens start' to restart on the current version`
|
|
7387
7396
|
);
|
|
7388
7397
|
}
|
|
7389
7398
|
} else {
|
|
@@ -7422,7 +7431,7 @@ async function web(args2) {
|
|
|
7422
7431
|
const open = args2.includes("--open");
|
|
7423
7432
|
const positional = args2.filter((a) => !a.startsWith("--"));
|
|
7424
7433
|
const rawPath = positional[0] ?? "";
|
|
7425
|
-
const
|
|
7434
|
+
const path12 = rawPath.startsWith("/") ? rawPath : rawPath ? `/${rawPath}` : "";
|
|
7426
7435
|
let result;
|
|
7427
7436
|
try {
|
|
7428
7437
|
result = await ensureCurrentServer({});
|
|
@@ -7430,7 +7439,7 @@ async function web(args2) {
|
|
|
7430
7439
|
console.error(`Failed to start: ${err.message}`);
|
|
7431
7440
|
process.exit(1);
|
|
7432
7441
|
}
|
|
7433
|
-
const url = `http://localhost:${result.port}${
|
|
7442
|
+
const url = `http://localhost:${result.port}${path12}`;
|
|
7434
7443
|
if (result.restarted) {
|
|
7435
7444
|
console.log(`fleetlens restarted on http://localhost:${result.port} (PID ${result.pid}) \u2014 replaced stale ${result.previousVersion ?? "unknown"} server`);
|
|
7436
7445
|
}
|
|
@@ -7874,6 +7883,7 @@ __export(dist_exports, {
|
|
|
7874
7883
|
ANTIGRAVITY_METADATA: () => ANTIGRAVITY_METADATA,
|
|
7875
7884
|
CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
|
|
7876
7885
|
CODEX_METADATA: () => CODEX_METADATA,
|
|
7886
|
+
COMMAND_CODE_METADATA: () => COMMAND_CODE_METADATA,
|
|
7877
7887
|
COPILOT_METADATA: () => COPILOT_METADATA,
|
|
7878
7888
|
COWORK_METADATA: () => COWORK_METADATA,
|
|
7879
7889
|
GEMINI_METADATA: () => GEMINI_METADATA,
|
|
@@ -7962,15 +7972,15 @@ import { homedir as homedir4, platform } from "node:os";
|
|
|
7962
7972
|
import { join as join7 } from "node:path";
|
|
7963
7973
|
function readOAuthCredentials() {
|
|
7964
7974
|
if (platform() === "darwin") {
|
|
7965
|
-
return readFromMacKeychain() ?? readFromCredentialsFile();
|
|
7975
|
+
return readFromMacKeychain(DEFAULT_KEYCHAIN_SERVICE) ?? readFromCredentialsFile();
|
|
7966
7976
|
}
|
|
7967
7977
|
return readFromCredentialsFile();
|
|
7968
7978
|
}
|
|
7969
|
-
function readFromMacKeychain() {
|
|
7979
|
+
function readFromMacKeychain(service) {
|
|
7970
7980
|
try {
|
|
7971
7981
|
const blob = execFileSync2(
|
|
7972
7982
|
"security",
|
|
7973
|
-
["find-generic-password", "-s",
|
|
7983
|
+
["find-generic-password", "-s", service, "-w"],
|
|
7974
7984
|
{ stdio: ["ignore", "pipe", "ignore"], encoding: "utf8" }
|
|
7975
7985
|
);
|
|
7976
7986
|
return extractCredentials(blob);
|
|
@@ -7978,21 +7988,27 @@ function readFromMacKeychain() {
|
|
|
7978
7988
|
return null;
|
|
7979
7989
|
}
|
|
7980
7990
|
}
|
|
7991
|
+
function readCredentialsFile(path12) {
|
|
7992
|
+
try {
|
|
7993
|
+
return extractCredentials(readFileSync10(path12, "utf8"));
|
|
7994
|
+
} catch {
|
|
7995
|
+
return null;
|
|
7996
|
+
}
|
|
7997
|
+
}
|
|
7981
7998
|
function readFromCredentialsFile() {
|
|
7982
7999
|
const candidates = [
|
|
7983
8000
|
join7(homedir4(), ".claude", ".credentials.json"),
|
|
7984
8001
|
join7(homedir4(), ".config", "claude", "credentials.json")
|
|
7985
8002
|
];
|
|
7986
|
-
for (const
|
|
7987
|
-
|
|
7988
|
-
|
|
7989
|
-
const creds = extractCredentials(blob);
|
|
7990
|
-
if (creds) return creds;
|
|
7991
|
-
} catch {
|
|
7992
|
-
}
|
|
8003
|
+
for (const path12 of candidates) {
|
|
8004
|
+
const creds = readCredentialsFile(path12);
|
|
8005
|
+
if (creds) return creds;
|
|
7993
8006
|
}
|
|
7994
8007
|
return null;
|
|
7995
8008
|
}
|
|
8009
|
+
function isUsable(creds, now, skewMs = 6e4) {
|
|
8010
|
+
return creds.expiresAt - skewMs > now;
|
|
8011
|
+
}
|
|
7996
8012
|
function extractCredentials(blob) {
|
|
7997
8013
|
try {
|
|
7998
8014
|
const parsed = JSON.parse(blob);
|
|
@@ -8006,9 +8022,130 @@ function extractCredentials(blob) {
|
|
|
8006
8022
|
return null;
|
|
8007
8023
|
}
|
|
8008
8024
|
}
|
|
8025
|
+
var DEFAULT_KEYCHAIN_SERVICE;
|
|
8009
8026
|
var init_token = __esm({
|
|
8010
8027
|
"src/usage/token.ts"() {
|
|
8011
8028
|
"use strict";
|
|
8029
|
+
DEFAULT_KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
8030
|
+
}
|
|
8031
|
+
});
|
|
8032
|
+
|
|
8033
|
+
// src/usage/accounts.ts
|
|
8034
|
+
import { createHash } from "node:crypto";
|
|
8035
|
+
import { existsSync as existsSync8, readdirSync, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
|
|
8036
|
+
import { homedir as homedir5, platform as platform2 } from "node:os";
|
|
8037
|
+
import { basename as basename2, join as join8, resolve as resolve2 } from "node:path";
|
|
8038
|
+
function defaultClaudeHome(homeDir = homedir5()) {
|
|
8039
|
+
return resolve2(join8(homeDir, ".claude"));
|
|
8040
|
+
}
|
|
8041
|
+
function keychainServiceForConfigDir(configDir, homeDir = homedir5()) {
|
|
8042
|
+
const resolved = resolve2(configDir);
|
|
8043
|
+
if (resolved === defaultClaudeHome(homeDir)) return DEFAULT_KEYCHAIN_SERVICE;
|
|
8044
|
+
const hash = createHash("sha256").update(resolved).digest("hex").slice(0, 8);
|
|
8045
|
+
return `${DEFAULT_KEYCHAIN_SERVICE}-${hash}`;
|
|
8046
|
+
}
|
|
8047
|
+
function accountSlugForConfigDir(configDir, homeDir = homedir5()) {
|
|
8048
|
+
const resolved = resolve2(configDir);
|
|
8049
|
+
if (resolved === defaultClaudeHome(homeDir)) return null;
|
|
8050
|
+
const base = basename2(resolved);
|
|
8051
|
+
if (base.startsWith(".claude-")) {
|
|
8052
|
+
const slug = base.slice(".claude-".length);
|
|
8053
|
+
return slug.length > 0 ? slug : "alt";
|
|
8054
|
+
}
|
|
8055
|
+
if (base.startsWith(".claude")) {
|
|
8056
|
+
const rest = base.slice(".claude".length).replace(/^-+/, "");
|
|
8057
|
+
return rest.length > 0 ? rest : "alt";
|
|
8058
|
+
}
|
|
8059
|
+
return base || "alt";
|
|
8060
|
+
}
|
|
8061
|
+
function snapshotAgentKey(slug) {
|
|
8062
|
+
return slug ? `claude-code:${slug}` : "claude-code";
|
|
8063
|
+
}
|
|
8064
|
+
function looksLikeClaudeHome(dir) {
|
|
8065
|
+
try {
|
|
8066
|
+
if (!statSync3(dir).isDirectory()) return false;
|
|
8067
|
+
} catch {
|
|
8068
|
+
return false;
|
|
8069
|
+
}
|
|
8070
|
+
return CLAUDE_HOME_MARKERS.some((name) => existsSync8(join8(dir, name)));
|
|
8071
|
+
}
|
|
8072
|
+
function discoverClaudeConfigDirs(opts = {}) {
|
|
8073
|
+
const homeDir = opts.homeDir ?? homedir5();
|
|
8074
|
+
const found = [];
|
|
8075
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8076
|
+
const add = (dir) => {
|
|
8077
|
+
const resolved = resolve2(dir);
|
|
8078
|
+
if (seen.has(resolved)) return;
|
|
8079
|
+
if (!looksLikeClaudeHome(resolved)) return;
|
|
8080
|
+
seen.add(resolved);
|
|
8081
|
+
found.push(resolved);
|
|
8082
|
+
};
|
|
8083
|
+
add(join8(homeDir, ".claude"));
|
|
8084
|
+
try {
|
|
8085
|
+
for (const name of readdirSync(homeDir)) {
|
|
8086
|
+
if (!name.startsWith(".claude-")) continue;
|
|
8087
|
+
add(join8(homeDir, name));
|
|
8088
|
+
}
|
|
8089
|
+
} catch {
|
|
8090
|
+
}
|
|
8091
|
+
const envDir = opts.envConfigDir ?? process.env.CLAUDE_CONFIG_DIR;
|
|
8092
|
+
if (envDir && envDir.trim()) add(envDir.trim());
|
|
8093
|
+
return found;
|
|
8094
|
+
}
|
|
8095
|
+
function readAccountCredentials(configDir, opts = {}) {
|
|
8096
|
+
const homeDir = opts.homeDir ?? homedir5();
|
|
8097
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
8098
|
+
const os12 = opts.platform ?? platform2();
|
|
8099
|
+
const keychainRead = opts.readKeychain ?? readFromMacKeychain;
|
|
8100
|
+
const usableOnly = opts.usableOnly !== false;
|
|
8101
|
+
const fileCreds = readCredentialsFile(join8(configDir, ".credentials.json"));
|
|
8102
|
+
let keychainCreds = null;
|
|
8103
|
+
if (os12 === "darwin") {
|
|
8104
|
+
keychainCreds = keychainRead(keychainServiceForConfigDir(configDir, homeDir));
|
|
8105
|
+
}
|
|
8106
|
+
const extraFile = resolve2(configDir) === defaultClaudeHome(homeDir) ? readCredentialsFile(join8(homeDir, ".config", "claude", "credentials.json")) : null;
|
|
8107
|
+
const candidates = [];
|
|
8108
|
+
if (keychainCreds) candidates.push({ creds: keychainCreds, source: "keychain" });
|
|
8109
|
+
if (fileCreds) candidates.push({ creds: fileCreds, source: "file" });
|
|
8110
|
+
if (extraFile) candidates.push({ creds: extraFile, source: "file" });
|
|
8111
|
+
for (const c of candidates) {
|
|
8112
|
+
if (!usableOnly || isUsable(c.creds, nowMs)) return c;
|
|
8113
|
+
}
|
|
8114
|
+
return null;
|
|
8115
|
+
}
|
|
8116
|
+
function discoverClaudeAccounts(opts = {}) {
|
|
8117
|
+
const homeDir = opts.homeDir ?? homedir5();
|
|
8118
|
+
const dirs = discoverClaudeConfigDirs({
|
|
8119
|
+
homeDir,
|
|
8120
|
+
envConfigDir: opts.envConfigDir
|
|
8121
|
+
});
|
|
8122
|
+
const accounts = [];
|
|
8123
|
+
const seenTokens = /* @__PURE__ */ new Set();
|
|
8124
|
+
for (const configDir of dirs) {
|
|
8125
|
+
const got = readAccountCredentials(configDir, opts);
|
|
8126
|
+
if (!got) continue;
|
|
8127
|
+
if (seenTokens.has(got.creds.accessToken)) continue;
|
|
8128
|
+
seenTokens.add(got.creds.accessToken);
|
|
8129
|
+
accounts.push({
|
|
8130
|
+
configDir,
|
|
8131
|
+
slug: accountSlugForConfigDir(configDir, homeDir),
|
|
8132
|
+
creds: got.creds,
|
|
8133
|
+
source: got.source
|
|
8134
|
+
});
|
|
8135
|
+
}
|
|
8136
|
+
accounts.sort((a, b) => {
|
|
8137
|
+
if (a.slug === null) return -1;
|
|
8138
|
+
if (b.slug === null) return 1;
|
|
8139
|
+
return a.slug.localeCompare(b.slug);
|
|
8140
|
+
});
|
|
8141
|
+
return accounts;
|
|
8142
|
+
}
|
|
8143
|
+
var CLAUDE_HOME_MARKERS;
|
|
8144
|
+
var init_accounts = __esm({
|
|
8145
|
+
"src/usage/accounts.ts"() {
|
|
8146
|
+
"use strict";
|
|
8147
|
+
init_token();
|
|
8148
|
+
CLAUDE_HOME_MARKERS = [".credentials.json", ".claude.json", "settings.json", "projects"];
|
|
8012
8149
|
}
|
|
8013
8150
|
});
|
|
8014
8151
|
|
|
@@ -8016,7 +8153,9 @@ var init_token = __esm({
|
|
|
8016
8153
|
var api_exports = {};
|
|
8017
8154
|
__export(api_exports, {
|
|
8018
8155
|
UsageApiError: () => UsageApiError,
|
|
8019
|
-
|
|
8156
|
+
fetchAllClaudeUsage: () => fetchAllClaudeUsage,
|
|
8157
|
+
fetchUsage: () => fetchUsage,
|
|
8158
|
+
fetchUsageWithCredentials: () => fetchUsageWithCredentials
|
|
8020
8159
|
});
|
|
8021
8160
|
async function fetchUsage() {
|
|
8022
8161
|
const creds = readOAuthCredentials();
|
|
@@ -8026,7 +8165,11 @@ async function fetchUsage() {
|
|
|
8026
8165
|
"no_token"
|
|
8027
8166
|
);
|
|
8028
8167
|
}
|
|
8029
|
-
|
|
8168
|
+
return fetchUsageWithCredentials(creds, { agent: "claude-code" });
|
|
8169
|
+
}
|
|
8170
|
+
async function fetchUsageWithCredentials(creds, opts = {}) {
|
|
8171
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
8172
|
+
if (creds.expiresAt - EXPIRY_SKEW_MS <= nowMs) {
|
|
8030
8173
|
throw new UsageApiError(
|
|
8031
8174
|
"Claude Code OAuth token expired. Open Claude Code to refresh it.",
|
|
8032
8175
|
"expired"
|
|
@@ -8059,9 +8202,10 @@ async function fetchUsage() {
|
|
|
8059
8202
|
throw new UsageApiError(`Failed to parse usage response: ${err.message}`, "parse");
|
|
8060
8203
|
}
|
|
8061
8204
|
const b = body;
|
|
8205
|
+
const account = opts.account ?? null;
|
|
8062
8206
|
return {
|
|
8063
8207
|
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8064
|
-
agent:
|
|
8208
|
+
agent: opts.agent ?? snapshotAgentKey(account),
|
|
8065
8209
|
five_hour: normalizeWindow(b.five_hour) ?? { utilization: null, resets_at: null },
|
|
8066
8210
|
seven_day: normalizeWindow(b.seven_day) ?? { utilization: null, resets_at: null },
|
|
8067
8211
|
seven_day_opus: normalizeWindow(b.seven_day_opus),
|
|
@@ -8069,9 +8213,38 @@ async function fetchUsage() {
|
|
|
8069
8213
|
seven_day_oauth_apps: normalizeWindow(b.seven_day_oauth_apps),
|
|
8070
8214
|
seven_day_cowork: normalizeWindow(b.seven_day_cowork),
|
|
8071
8215
|
extra_usage: normalizeExtra(b.extra_usage),
|
|
8072
|
-
plan_type: null
|
|
8216
|
+
plan_type: null,
|
|
8217
|
+
...account ? { account } : {}
|
|
8073
8218
|
};
|
|
8074
8219
|
}
|
|
8220
|
+
async function fetchAllClaudeUsage(opts = {}) {
|
|
8221
|
+
const accounts = opts.accounts ?? discoverClaudeAccounts({ nowMs: opts.nowMs });
|
|
8222
|
+
const fetchOne = opts.fetchOne ?? fetchUsageWithCredentials;
|
|
8223
|
+
const snapshots = [];
|
|
8224
|
+
const errors = [];
|
|
8225
|
+
for (const account of accounts) {
|
|
8226
|
+
try {
|
|
8227
|
+
snapshots.push(
|
|
8228
|
+
await fetchOne(account.creds, {
|
|
8229
|
+
agent: snapshotAgentKey(account.slug),
|
|
8230
|
+
account: account.slug,
|
|
8231
|
+
nowMs: opts.nowMs
|
|
8232
|
+
})
|
|
8233
|
+
);
|
|
8234
|
+
} catch (err) {
|
|
8235
|
+
if (err instanceof UsageApiError) {
|
|
8236
|
+
errors.push({ slug: account.slug, code: err.code, message: err.message });
|
|
8237
|
+
} else {
|
|
8238
|
+
errors.push({
|
|
8239
|
+
slug: account.slug,
|
|
8240
|
+
code: "parse",
|
|
8241
|
+
message: err.message
|
|
8242
|
+
});
|
|
8243
|
+
}
|
|
8244
|
+
}
|
|
8245
|
+
}
|
|
8246
|
+
return { snapshots, errors };
|
|
8247
|
+
}
|
|
8075
8248
|
function normalizeWindow(raw) {
|
|
8076
8249
|
if (!raw || typeof raw !== "object") return null;
|
|
8077
8250
|
const r = raw;
|
|
@@ -8094,6 +8267,7 @@ var EXPIRY_SKEW_MS, USAGE_ENDPOINT, BETA_HEADER, UsageApiError;
|
|
|
8094
8267
|
var init_api = __esm({
|
|
8095
8268
|
"src/usage/api.ts"() {
|
|
8096
8269
|
"use strict";
|
|
8270
|
+
init_accounts();
|
|
8097
8271
|
init_token();
|
|
8098
8272
|
EXPIRY_SKEW_MS = 60 * 1e3;
|
|
8099
8273
|
USAGE_ENDPOINT = "https://api.anthropic.com/api/oauth/usage";
|
|
@@ -8108,7 +8282,7 @@ var init_api = __esm({
|
|
|
8108
8282
|
});
|
|
8109
8283
|
|
|
8110
8284
|
// src/usage/grok.ts
|
|
8111
|
-
import { existsSync as
|
|
8285
|
+
import { existsSync as existsSync9, readFileSync as readFileSync12 } from "node:fs";
|
|
8112
8286
|
import os9 from "node:os";
|
|
8113
8287
|
import path9 from "node:path";
|
|
8114
8288
|
function grokHome() {
|
|
@@ -8119,12 +8293,12 @@ function authPath() {
|
|
|
8119
8293
|
}
|
|
8120
8294
|
function loadAuthEntry() {
|
|
8121
8295
|
const p = authPath();
|
|
8122
|
-
if (!
|
|
8296
|
+
if (!existsSync9(p)) {
|
|
8123
8297
|
throw new GrokApiError("Grok not logged in. Run `grok login`.", "no_auth");
|
|
8124
8298
|
}
|
|
8125
8299
|
let raw;
|
|
8126
8300
|
try {
|
|
8127
|
-
raw = JSON.parse(
|
|
8301
|
+
raw = JSON.parse(readFileSync12(p, "utf8"));
|
|
8128
8302
|
} catch {
|
|
8129
8303
|
throw new GrokApiError("Grok auth.json is unreadable. Run `grok login`.", "no_auth");
|
|
8130
8304
|
}
|
|
@@ -8166,7 +8340,7 @@ async function refreshAccessToken(entry) {
|
|
|
8166
8340
|
if (typeof j.access_token !== "string" || !j.access_token) return null;
|
|
8167
8341
|
try {
|
|
8168
8342
|
const p = authPath();
|
|
8169
|
-
const raw = JSON.parse(
|
|
8343
|
+
const raw = JSON.parse(readFileSync12(p, "utf8"));
|
|
8170
8344
|
for (const key of Object.keys(raw)) {
|
|
8171
8345
|
if (raw[key]?.key === entry.key || raw[key]?.refresh_token === refresh) {
|
|
8172
8346
|
raw[key] = {
|
|
@@ -8327,8 +8501,8 @@ var init_grok2 = __esm({
|
|
|
8327
8501
|
|
|
8328
8502
|
// src/usage/codex.ts
|
|
8329
8503
|
import {
|
|
8330
|
-
existsSync as
|
|
8331
|
-
readFileSync as
|
|
8504
|
+
existsSync as existsSync10,
|
|
8505
|
+
readFileSync as readFileSync13,
|
|
8332
8506
|
writeFileSync as writeFileSync6
|
|
8333
8507
|
} from "node:fs";
|
|
8334
8508
|
import os10 from "node:os";
|
|
@@ -8343,7 +8517,7 @@ function authPath2() {
|
|
|
8343
8517
|
}
|
|
8344
8518
|
function loadAuth() {
|
|
8345
8519
|
const p = authPath2();
|
|
8346
|
-
if (!
|
|
8520
|
+
if (!existsSync10(p)) {
|
|
8347
8521
|
throw new CodexApiError(
|
|
8348
8522
|
"Codex not logged in. Run `codex` to authenticate.",
|
|
8349
8523
|
"no_auth"
|
|
@@ -8351,7 +8525,7 @@ function loadAuth() {
|
|
|
8351
8525
|
}
|
|
8352
8526
|
let auth;
|
|
8353
8527
|
try {
|
|
8354
|
-
auth = JSON.parse(
|
|
8528
|
+
auth = JSON.parse(readFileSync13(p, "utf8"));
|
|
8355
8529
|
} catch {
|
|
8356
8530
|
throw new CodexApiError(
|
|
8357
8531
|
"Codex auth.json is unreadable. Run `codex` to log in again.",
|
|
@@ -8613,8 +8787,8 @@ var init_codex2 = __esm({
|
|
|
8613
8787
|
|
|
8614
8788
|
// src/usage/copilot.ts
|
|
8615
8789
|
import { spawn as spawn3 } from "node:child_process";
|
|
8616
|
-
import { existsSync as
|
|
8617
|
-
import { dirname as dirname8, join as
|
|
8790
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
8791
|
+
import { dirname as dirname8, join as join9 } from "node:path";
|
|
8618
8792
|
function recordOf2(value) {
|
|
8619
8793
|
return typeof value === "object" && value !== null ? value : void 0;
|
|
8620
8794
|
}
|
|
@@ -8687,8 +8861,8 @@ function rpcFrame(message) {
|
|
|
8687
8861
|
function resolveCopilotCliPath() {
|
|
8688
8862
|
const configured = process.env.COPILOT_CLI_PATH?.trim();
|
|
8689
8863
|
if (configured) return configured;
|
|
8690
|
-
const sibling =
|
|
8691
|
-
return
|
|
8864
|
+
const sibling = join9(dirname8(process.execPath), process.platform === "win32" ? "copilot.cmd" : "copilot");
|
|
8865
|
+
return existsSync11(sibling) ? sibling : process.platform === "win32" ? "copilot.cmd" : "copilot";
|
|
8692
8866
|
}
|
|
8693
8867
|
async function requestQuota(child) {
|
|
8694
8868
|
const decoder = new ContentLengthDecoder();
|
|
@@ -8734,8 +8908,8 @@ async function requestQuota(child) {
|
|
|
8734
8908
|
});
|
|
8735
8909
|
const request = (method, params = {}) => {
|
|
8736
8910
|
const id = nextId++;
|
|
8737
|
-
const response = new Promise((
|
|
8738
|
-
pending.set(id, { resolve:
|
|
8911
|
+
const response = new Promise((resolve5, reject) => {
|
|
8912
|
+
pending.set(id, { resolve: resolve5, reject });
|
|
8739
8913
|
child.stdin.write(rpcFrame({ jsonrpc: "2.0", id, method, params }));
|
|
8740
8914
|
});
|
|
8741
8915
|
return Promise.race([response, exited]);
|
|
@@ -8820,12 +8994,12 @@ var init_copilot2 = __esm({
|
|
|
8820
8994
|
});
|
|
8821
8995
|
|
|
8822
8996
|
// src/usage/zai.ts
|
|
8823
|
-
import { existsSync as
|
|
8997
|
+
import { existsSync as existsSync12, readFileSync as readFileSync14 } from "node:fs";
|
|
8824
8998
|
function resolveApiKey() {
|
|
8825
8999
|
try {
|
|
8826
9000
|
const p = cclensPath("credentials.json");
|
|
8827
|
-
if (
|
|
8828
|
-
const store = JSON.parse(
|
|
9001
|
+
if (existsSync12(p)) {
|
|
9002
|
+
const store = JSON.parse(readFileSync14(p, "utf8"));
|
|
8829
9003
|
return store.zai?.apiKey ?? null;
|
|
8830
9004
|
}
|
|
8831
9005
|
} catch {
|
|
@@ -8929,7 +9103,336 @@ var init_zai = __esm({
|
|
|
8929
9103
|
}
|
|
8930
9104
|
});
|
|
8931
9105
|
|
|
9106
|
+
// src/usage/command-code.ts
|
|
9107
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15 } from "node:fs";
|
|
9108
|
+
import os11 from "node:os";
|
|
9109
|
+
import path11 from "node:path";
|
|
9110
|
+
function commandCodeHome() {
|
|
9111
|
+
return process.env.COMMANDCODE_HOME || path11.join(os11.homedir(), ".commandcode");
|
|
9112
|
+
}
|
|
9113
|
+
function authPath3() {
|
|
9114
|
+
return path11.join(commandCodeHome(), "auth.json");
|
|
9115
|
+
}
|
|
9116
|
+
function loadCommandCodeApiKey() {
|
|
9117
|
+
const p = authPath3();
|
|
9118
|
+
if (!existsSync13(p)) {
|
|
9119
|
+
throw new CommandCodeApiError("Command Code not logged in. Run `cmd login`.", "no_auth");
|
|
9120
|
+
}
|
|
9121
|
+
let raw;
|
|
9122
|
+
try {
|
|
9123
|
+
raw = JSON.parse(readFileSync15(p, "utf8"));
|
|
9124
|
+
} catch {
|
|
9125
|
+
throw new CommandCodeApiError("Command Code auth.json is unreadable. Run `cmd login`.", "no_auth");
|
|
9126
|
+
}
|
|
9127
|
+
const key = typeof raw.apiKey === "string" ? raw.apiKey.trim() : "";
|
|
9128
|
+
if (!key) {
|
|
9129
|
+
throw new CommandCodeApiError("Command Code auth has no API key. Run `cmd login`.", "no_auth");
|
|
9130
|
+
}
|
|
9131
|
+
return key;
|
|
9132
|
+
}
|
|
9133
|
+
function apiBase() {
|
|
9134
|
+
const custom2 = process.env.COMMANDCODE_API_URL?.trim();
|
|
9135
|
+
return custom2 && custom2.length > 0 ? custom2.replace(/\/$/, "") : DEFAULT_API_BASE;
|
|
9136
|
+
}
|
|
9137
|
+
function authHeaders3(key) {
|
|
9138
|
+
return {
|
|
9139
|
+
Authorization: `Bearer ${key}`,
|
|
9140
|
+
Accept: "application/json",
|
|
9141
|
+
"User-Agent": "fleetlens"
|
|
9142
|
+
};
|
|
9143
|
+
}
|
|
9144
|
+
function normalizePlanKey(planId) {
|
|
9145
|
+
return planId.trim().toLowerCase().replace(/_/g, "-");
|
|
9146
|
+
}
|
|
9147
|
+
function matchPlanKey(planId) {
|
|
9148
|
+
const key = normalizePlanKey(planId);
|
|
9149
|
+
if (PLAN_NAMES[key] || PLAN_CREDITS[key] !== void 0) return key;
|
|
9150
|
+
return Object.keys(PLAN_NAMES).sort((a, b) => b.length - a.length).find((p) => key.startsWith(p)) ?? null;
|
|
9151
|
+
}
|
|
9152
|
+
function planLabelFromId(planId) {
|
|
9153
|
+
if (typeof planId !== "string" || !planId.trim()) return null;
|
|
9154
|
+
const key = matchPlanKey(planId);
|
|
9155
|
+
return key ? PLAN_NAMES[key] ?? planId.trim() : planId.trim();
|
|
9156
|
+
}
|
|
9157
|
+
function planMonthlyCredits(planId) {
|
|
9158
|
+
if (typeof planId !== "string" || !planId.trim()) return null;
|
|
9159
|
+
const key = matchPlanKey(planId);
|
|
9160
|
+
if (!key) return null;
|
|
9161
|
+
const n = PLAN_CREDITS[key];
|
|
9162
|
+
return typeof n === "number" ? n : null;
|
|
9163
|
+
}
|
|
9164
|
+
function asCredit(raw) {
|
|
9165
|
+
if (typeof raw !== "number" || !Number.isFinite(raw)) return null;
|
|
9166
|
+
return raw;
|
|
9167
|
+
}
|
|
9168
|
+
function roundCredits(n) {
|
|
9169
|
+
return Math.round(n * 100) / 100;
|
|
9170
|
+
}
|
|
9171
|
+
function isoFromUnknown(raw) {
|
|
9172
|
+
if (typeof raw !== "string" || !raw.trim()) return null;
|
|
9173
|
+
const ms = Date.parse(raw);
|
|
9174
|
+
return Number.isFinite(ms) ? new Date(ms).toISOString() : null;
|
|
9175
|
+
}
|
|
9176
|
+
function parseCommandCodeCredits(body) {
|
|
9177
|
+
if (!body || typeof body !== "object") {
|
|
9178
|
+
throw new CommandCodeApiError("Command Code credits response missing body", "parse");
|
|
9179
|
+
}
|
|
9180
|
+
const credits = body.credits;
|
|
9181
|
+
if (!credits || typeof credits !== "object") {
|
|
9182
|
+
throw new CommandCodeApiError("Command Code credits response missing credits", "parse");
|
|
9183
|
+
}
|
|
9184
|
+
const c = credits;
|
|
9185
|
+
return {
|
|
9186
|
+
remaining: asCredit(c.monthlyCredits),
|
|
9187
|
+
purchased: asCredit(c.purchasedCredits) ?? 0,
|
|
9188
|
+
free: asCredit(c.freeCredits) ?? 0,
|
|
9189
|
+
planId: typeof c.planId === "string" && c.planId.trim() ? c.planId.trim() : null
|
|
9190
|
+
};
|
|
9191
|
+
}
|
|
9192
|
+
function parseCommandCodeWindow(raw) {
|
|
9193
|
+
if (!raw || typeof raw !== "object") {
|
|
9194
|
+
return { utilization: null, resets_at: null };
|
|
9195
|
+
}
|
|
9196
|
+
const w = raw;
|
|
9197
|
+
const used = Number(w.used);
|
|
9198
|
+
const cap = Number(w.cap);
|
|
9199
|
+
let utilization = null;
|
|
9200
|
+
if (Number.isFinite(used) && Number.isFinite(cap) && cap > 0) {
|
|
9201
|
+
utilization = Math.min(100, Math.max(0, used / cap * 100));
|
|
9202
|
+
}
|
|
9203
|
+
let resets_at = null;
|
|
9204
|
+
const resetAt = Number(w.resetAt);
|
|
9205
|
+
if (Number.isFinite(resetAt) && resetAt > 0) {
|
|
9206
|
+
const iso = new Date(resetAt).toISOString();
|
|
9207
|
+
if (!Number.isNaN(Date.parse(iso))) resets_at = iso;
|
|
9208
|
+
}
|
|
9209
|
+
return { utilization, resets_at };
|
|
9210
|
+
}
|
|
9211
|
+
function parseCommandCodeWindows(body) {
|
|
9212
|
+
const empty = { utilization: null, resets_at: null };
|
|
9213
|
+
if (!body || typeof body !== "object") return { five_hour: empty, seven_day: empty };
|
|
9214
|
+
const limits = body.windowLimits;
|
|
9215
|
+
if (!limits || typeof limits !== "object") return { five_hour: empty, seven_day: empty };
|
|
9216
|
+
const l = limits;
|
|
9217
|
+
return {
|
|
9218
|
+
five_hour: parseCommandCodeWindow(l.fiveHour),
|
|
9219
|
+
seven_day: parseCommandCodeWindow(l.weekly)
|
|
9220
|
+
};
|
|
9221
|
+
}
|
|
9222
|
+
function parseCommandCodeSubscription(body) {
|
|
9223
|
+
if (!body || typeof body !== "object") {
|
|
9224
|
+
return { plan_type: null, planId: null, currentPeriodEnd: null };
|
|
9225
|
+
}
|
|
9226
|
+
const data = body.data;
|
|
9227
|
+
const planId = typeof data?.planId === "string" && data.planId.trim() ? data.planId.trim() : null;
|
|
9228
|
+
return {
|
|
9229
|
+
plan_type: planLabelFromId(planId),
|
|
9230
|
+
planId,
|
|
9231
|
+
currentPeriodEnd: isoFromUnknown(data?.currentPeriodEnd)
|
|
9232
|
+
};
|
|
9233
|
+
}
|
|
9234
|
+
function parseCommandCodeMonthly(opts) {
|
|
9235
|
+
const planId = opts.subscription.planId ?? opts.credits.planId;
|
|
9236
|
+
const limit = planMonthlyCredits(planId);
|
|
9237
|
+
const remaining = opts.credits.remaining;
|
|
9238
|
+
let used = null;
|
|
9239
|
+
let utilization = null;
|
|
9240
|
+
if (limit != null && limit > 0 && remaining != null) {
|
|
9241
|
+
used = roundCredits(Math.max(0, limit - remaining));
|
|
9242
|
+
utilization = Math.min(100, Math.max(0, used / limit * 100));
|
|
9243
|
+
}
|
|
9244
|
+
return {
|
|
9245
|
+
monthly: {
|
|
9246
|
+
utilization,
|
|
9247
|
+
resets_at: opts.subscription.currentPeriodEnd
|
|
9248
|
+
},
|
|
9249
|
+
monthly_quota: {
|
|
9250
|
+
used,
|
|
9251
|
+
limit,
|
|
9252
|
+
remaining: remaining == null ? null : roundCredits(Math.max(0, remaining)),
|
|
9253
|
+
unit: "credits",
|
|
9254
|
+
unlimited: false
|
|
9255
|
+
},
|
|
9256
|
+
plan_type: opts.subscription.plan_type ?? planLabelFromId(planId)
|
|
9257
|
+
};
|
|
9258
|
+
}
|
|
9259
|
+
async function fetchJson2(url, key) {
|
|
9260
|
+
let res;
|
|
9261
|
+
try {
|
|
9262
|
+
res = await fetch(url, { headers: authHeaders3(key) });
|
|
9263
|
+
} catch (err) {
|
|
9264
|
+
throw new CommandCodeApiError(
|
|
9265
|
+
`Network error reaching Command Code billing: ${err.message}`,
|
|
9266
|
+
"network"
|
|
9267
|
+
);
|
|
9268
|
+
}
|
|
9269
|
+
let body = null;
|
|
9270
|
+
try {
|
|
9271
|
+
body = await res.json();
|
|
9272
|
+
} catch {
|
|
9273
|
+
}
|
|
9274
|
+
return { status: res.status, body };
|
|
9275
|
+
}
|
|
9276
|
+
async function fetchCommandCodeUsage() {
|
|
9277
|
+
const key = loadCommandCodeApiKey();
|
|
9278
|
+
const base = apiBase();
|
|
9279
|
+
const creditsRes = await fetchJson2(`${base}${CREDITS_PATH}`, key);
|
|
9280
|
+
if (creditsRes.status === 401 || creditsRes.status === 403) {
|
|
9281
|
+
throw new CommandCodeApiError(
|
|
9282
|
+
`Command Code credits returned HTTP ${creditsRes.status}`,
|
|
9283
|
+
"no_auth"
|
|
9284
|
+
);
|
|
9285
|
+
}
|
|
9286
|
+
if (creditsRes.status < 200 || creditsRes.status >= 300) {
|
|
9287
|
+
throw new CommandCodeApiError(
|
|
9288
|
+
`Command Code credits returned HTTP ${creditsRes.status}`,
|
|
9289
|
+
"http"
|
|
9290
|
+
);
|
|
9291
|
+
}
|
|
9292
|
+
const credits = parseCommandCodeCredits(creditsRes.body);
|
|
9293
|
+
const windows = parseCommandCodeWindows(creditsRes.body);
|
|
9294
|
+
let subscription = parseCommandCodeSubscription(null);
|
|
9295
|
+
try {
|
|
9296
|
+
const subRes = await fetchJson2(`${base}${SUBSCRIPTIONS_PATH}`, key);
|
|
9297
|
+
if (subRes.status >= 200 && subRes.status < 300) {
|
|
9298
|
+
subscription = parseCommandCodeSubscription(subRes.body);
|
|
9299
|
+
}
|
|
9300
|
+
} catch {
|
|
9301
|
+
}
|
|
9302
|
+
const monthly = parseCommandCodeMonthly({ credits, subscription });
|
|
9303
|
+
return {
|
|
9304
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9305
|
+
agent: "command-code",
|
|
9306
|
+
five_hour: windows.five_hour,
|
|
9307
|
+
seven_day: windows.seven_day,
|
|
9308
|
+
monthly: monthly.monthly,
|
|
9309
|
+
monthly_quota: monthly.monthly_quota,
|
|
9310
|
+
seven_day_opus: null,
|
|
9311
|
+
seven_day_sonnet: null,
|
|
9312
|
+
seven_day_oauth_apps: null,
|
|
9313
|
+
seven_day_cowork: null,
|
|
9314
|
+
extra_usage: null,
|
|
9315
|
+
plan_type: monthly.plan_type
|
|
9316
|
+
};
|
|
9317
|
+
}
|
|
9318
|
+
var DEFAULT_API_BASE, CREDITS_PATH, SUBSCRIPTIONS_PATH, PLAN_NAMES, PLAN_CREDITS, CommandCodeApiError;
|
|
9319
|
+
var init_command_code = __esm({
|
|
9320
|
+
"src/usage/command-code.ts"() {
|
|
9321
|
+
"use strict";
|
|
9322
|
+
DEFAULT_API_BASE = "https://api.commandcode.ai";
|
|
9323
|
+
CREDITS_PATH = "/alpha/billing/credits";
|
|
9324
|
+
SUBSCRIPTIONS_PATH = "/alpha/billing/subscriptions";
|
|
9325
|
+
PLAN_NAMES = {
|
|
9326
|
+
"individual-go": "Go",
|
|
9327
|
+
"individual-goat": "GOAT",
|
|
9328
|
+
"individual-pro": "Pro",
|
|
9329
|
+
"individual-pro-v1": "Pro",
|
|
9330
|
+
"individual-provider": "Provider",
|
|
9331
|
+
"individual-max": "Max",
|
|
9332
|
+
"individual-ultra": "Ultra",
|
|
9333
|
+
"teams-pro": "Teams Pro"
|
|
9334
|
+
};
|
|
9335
|
+
PLAN_CREDITS = {
|
|
9336
|
+
"individual-go": 10,
|
|
9337
|
+
"individual-goat": 70,
|
|
9338
|
+
"individual-pro": 30,
|
|
9339
|
+
"individual-pro-v1": 80,
|
|
9340
|
+
"individual-provider": 15,
|
|
9341
|
+
"individual-max": 150,
|
|
9342
|
+
"individual-ultra": 300,
|
|
9343
|
+
"teams-pro": 40
|
|
9344
|
+
};
|
|
9345
|
+
CommandCodeApiError = class extends Error {
|
|
9346
|
+
constructor(message, code) {
|
|
9347
|
+
super(message);
|
|
9348
|
+
this.code = code;
|
|
9349
|
+
}
|
|
9350
|
+
};
|
|
9351
|
+
}
|
|
9352
|
+
});
|
|
9353
|
+
|
|
9354
|
+
// src/usage/pace.ts
|
|
9355
|
+
function round1(n) {
|
|
9356
|
+
return Math.round(n * 10) / 10;
|
|
9357
|
+
}
|
|
9358
|
+
function paceVerdict(deltaPp) {
|
|
9359
|
+
if (deltaPp < -PACE_BAND_PP) return "fast";
|
|
9360
|
+
if (deltaPp > PACE_BAND_PP) return "slow";
|
|
9361
|
+
return "on_track";
|
|
9362
|
+
}
|
|
9363
|
+
function monthlyWindowMs(resetsAt) {
|
|
9364
|
+
const start2 = addUtcMonths(resetsAt, -1);
|
|
9365
|
+
return Math.max(HOUR_MS2, resetsAt.getTime() - start2.getTime());
|
|
9366
|
+
}
|
|
9367
|
+
function addUtcMonths(date, months) {
|
|
9368
|
+
const y = date.getUTCFullYear();
|
|
9369
|
+
const m = date.getUTCMonth() + months;
|
|
9370
|
+
const targetMonth = (m % 12 + 12) % 12;
|
|
9371
|
+
const targetYear = y + Math.floor(m / 12);
|
|
9372
|
+
const day2 = date.getUTCDate();
|
|
9373
|
+
const lastDay = new Date(Date.UTC(targetYear, targetMonth + 1, 0)).getUTCDate();
|
|
9374
|
+
return new Date(
|
|
9375
|
+
Date.UTC(
|
|
9376
|
+
targetYear,
|
|
9377
|
+
targetMonth,
|
|
9378
|
+
Math.min(day2, lastDay),
|
|
9379
|
+
date.getUTCHours(),
|
|
9380
|
+
date.getUTCMinutes(),
|
|
9381
|
+
date.getUTCSeconds(),
|
|
9382
|
+
date.getUTCMilliseconds()
|
|
9383
|
+
)
|
|
9384
|
+
);
|
|
9385
|
+
}
|
|
9386
|
+
function windowPace(opts) {
|
|
9387
|
+
const { usedPct, resetsAtMs, windowMs } = opts;
|
|
9388
|
+
if (!Number.isFinite(usedPct) || !Number.isFinite(resetsAtMs) || !Number.isFinite(windowMs) || windowMs <= 0) {
|
|
9389
|
+
return null;
|
|
9390
|
+
}
|
|
9391
|
+
const nowMs = opts.nowMs ?? Date.now();
|
|
9392
|
+
const startMs = resetsAtMs - windowMs;
|
|
9393
|
+
const elapsedPct = Math.max(0, Math.min(100, (nowMs - startMs) / windowMs * 100));
|
|
9394
|
+
const used = Math.max(0, Math.min(100, usedPct));
|
|
9395
|
+
const deltaPp = round1(elapsedPct - used);
|
|
9396
|
+
return {
|
|
9397
|
+
used_pct: round1(used),
|
|
9398
|
+
elapsed_pct: round1(elapsedPct),
|
|
9399
|
+
delta_pp: deltaPp,
|
|
9400
|
+
verdict: paceVerdict(deltaPp)
|
|
9401
|
+
};
|
|
9402
|
+
}
|
|
9403
|
+
function paceForWindow(window, kind, nowMs) {
|
|
9404
|
+
if (!window || window.utilization === null || !window.resets_at) return null;
|
|
9405
|
+
const resetsAtMs = Date.parse(window.resets_at);
|
|
9406
|
+
if (!Number.isFinite(resetsAtMs)) return null;
|
|
9407
|
+
const windowMs = kind === "monthly" ? monthlyWindowMs(new Date(resetsAtMs)) : SEVEN_DAYS_MS;
|
|
9408
|
+
return windowPace({
|
|
9409
|
+
usedPct: window.utilization,
|
|
9410
|
+
resetsAtMs,
|
|
9411
|
+
windowMs,
|
|
9412
|
+
nowMs
|
|
9413
|
+
});
|
|
9414
|
+
}
|
|
9415
|
+
function paceForSnapshot(snapshot, nowMs) {
|
|
9416
|
+
const seven_day = paceForWindow(snapshot.seven_day, "seven_day", nowMs) ?? void 0;
|
|
9417
|
+
const monthly = paceForWindow(snapshot.monthly, "monthly", nowMs) ?? void 0;
|
|
9418
|
+
if (!seven_day && !monthly) return void 0;
|
|
9419
|
+
return { ...seven_day ? { seven_day } : {}, ...monthly ? { monthly } : {} };
|
|
9420
|
+
}
|
|
9421
|
+
var PACE_BAND_PP, SEVEN_DAYS_MS, HOUR_MS2, PACE_LEGEND;
|
|
9422
|
+
var init_pace = __esm({
|
|
9423
|
+
"src/usage/pace.ts"() {
|
|
9424
|
+
"use strict";
|
|
9425
|
+
PACE_BAND_PP = 15;
|
|
9426
|
+
SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
9427
|
+
HOUR_MS2 = 60 * 60 * 1e3;
|
|
9428
|
+
PACE_LEGEND = "pace.delta_pp=elapsed_pct-used_pct of 7d/30d (+slow quota-expires / -fast may-exhaust; |delta_pp|<=15 on_track)";
|
|
9429
|
+
}
|
|
9430
|
+
});
|
|
9431
|
+
|
|
8932
9432
|
// src/usage/format.ts
|
|
9433
|
+
function isClaudeAgent(kind) {
|
|
9434
|
+
return kind === "claude-code" || kind.startsWith("claude-code:") || !kind;
|
|
9435
|
+
}
|
|
8933
9436
|
function barWidthFor(columns, labelWidth) {
|
|
8934
9437
|
return Math.max(4, columns - labelWidth - 12);
|
|
8935
9438
|
}
|
|
@@ -8999,16 +9502,21 @@ function formatMultiAgentUsage(byAgent, opts = {}) {
|
|
|
8999
9502
|
}
|
|
9000
9503
|
function formatAgentBlock(kind, snapshot, layout) {
|
|
9001
9504
|
const lines = [];
|
|
9002
|
-
const title = layout.shortLabels
|
|
9505
|
+
const title = layout.shortLabels ? kind.startsWith("claude-code:") ? `Claude (${kind.slice("claude-code:".length)})` : isAgentKind(kind) ? getAgentMetadata(kind)?.shortLabel ?? agentTitle(kind) : agentTitle(kind) : agentTitle(kind);
|
|
9003
9506
|
const plan = snapshot.plan_type && layout.mode !== "narrow" ? ` ${DIM}${snapshot.plan_type}${RESET}` : "";
|
|
9004
9507
|
lines.push(` ${BOLD}${title}${RESET}${plan}`);
|
|
9005
9508
|
let renderedMeter = false;
|
|
9006
|
-
for (const
|
|
9007
|
-
if (!window || window.utilization === null) continue;
|
|
9509
|
+
for (const meter of agentWindows(kind, snapshot, layout.shortLabels)) {
|
|
9510
|
+
if (!meter.window || meter.window.utilization === null) continue;
|
|
9008
9511
|
renderedMeter = true;
|
|
9009
|
-
|
|
9512
|
+
const pace = meter.paceKind ? paceForWindow(meter.window, meter.paceKind) : null;
|
|
9513
|
+
lines.push(
|
|
9514
|
+
...formatMeterRow(meter.label, meter.window.utilization, meter.window.resets_at, layout, {
|
|
9515
|
+
pace
|
|
9516
|
+
})
|
|
9517
|
+
);
|
|
9010
9518
|
}
|
|
9011
|
-
if ((kind
|
|
9519
|
+
if (isClaudeAgent(kind) && snapshot.extra_usage?.is_enabled) {
|
|
9012
9520
|
renderedMeter = true;
|
|
9013
9521
|
const extra = snapshot.extra_usage;
|
|
9014
9522
|
if (extra.utilization !== null) {
|
|
@@ -9030,9 +9538,9 @@ function formatAgentBlock(kind, snapshot, layout) {
|
|
|
9030
9538
|
lines.push(...formatMeterRow(label, used, null, layout, { wholePct: true }));
|
|
9031
9539
|
}
|
|
9032
9540
|
}
|
|
9033
|
-
if (kind === "copilot" && snapshot.monthly_quota) {
|
|
9541
|
+
if ((kind === "copilot" || kind === "command-code") && snapshot.monthly_quota) {
|
|
9034
9542
|
const q = snapshot.monthly_quota;
|
|
9035
|
-
const unit = q.unit === "premium-requests" ? "premium requests" : "AI credits";
|
|
9543
|
+
const unit = q.unit === "premium-requests" ? "premium requests" : q.unit === "credits" ? "credits" : "AI credits";
|
|
9036
9544
|
const pad2 = layout.mode === "narrow" ? 2 : layout.labelWidth + 2;
|
|
9037
9545
|
if (q.unlimited) {
|
|
9038
9546
|
renderedMeter = true;
|
|
@@ -9061,19 +9569,40 @@ function formatAgentBlock(kind, snapshot, layout) {
|
|
|
9061
9569
|
function formatMeterRow(label, utilization, resetsAt, layout, opts = {}) {
|
|
9062
9570
|
const pctStr = opts.wholePct ? `${utilization.toFixed(0)}%`.padStart(5) : `${utilization.toFixed(1)}%`.padStart(6);
|
|
9063
9571
|
const labelStr = label.padEnd(layout.labelWidth);
|
|
9572
|
+
const pace = opts.pace ?? null;
|
|
9064
9573
|
if (layout.mode === "narrow" && layout.barWidth <= 0) {
|
|
9065
9574
|
const reset = resetsAt ? ` ${DIM}r${formatRelativeShort(resetsAt)}${RESET}` : "";
|
|
9066
|
-
|
|
9575
|
+
const paceBit = pace ? ` ${paceColor(pace.verdict)}${formatPace(pace, layout)}${RESET}` : "";
|
|
9576
|
+
return [` ${labelStr}${BOLD}${pctStr}${RESET}${reset}${paceBit}`];
|
|
9067
9577
|
}
|
|
9068
9578
|
const bar = renderBar(utilization, layout.barWidth);
|
|
9069
9579
|
const lines = [` ${labelStr}${bar} ${BOLD}${pctStr}${RESET} `];
|
|
9070
9580
|
if (resetsAt) {
|
|
9581
|
+
const paceBit = pace ? `${DIM} \xB7 ${RESET}${paceColor(pace.verdict)}${formatPace(pace, layout)}${RESET}` : "";
|
|
9071
9582
|
lines.push(
|
|
9072
|
-
` ${" ".repeat(layout.labelWidth)}${DIM}resets ${formatRelative(resetsAt)}${RESET}`
|
|
9583
|
+
` ${" ".repeat(layout.labelWidth)}${DIM}resets ${formatRelative(resetsAt)}${RESET}${paceBit}`
|
|
9073
9584
|
);
|
|
9074
9585
|
}
|
|
9075
9586
|
return lines;
|
|
9076
9587
|
}
|
|
9588
|
+
function paceColor(verdict) {
|
|
9589
|
+
if (verdict === "fast") return RED;
|
|
9590
|
+
if (verdict === "slow") return YELLOW;
|
|
9591
|
+
return GREEN;
|
|
9592
|
+
}
|
|
9593
|
+
function formatPace(pace, layout) {
|
|
9594
|
+
const n = Math.round(pace.delta_pp);
|
|
9595
|
+
const signed = n > 0 ? `+${n}pp` : `${n}pp`;
|
|
9596
|
+
if (layout.mode === "narrow") {
|
|
9597
|
+
if (pace.verdict === "slow") return `slow${n > 0 ? `+${n}` : String(n)}`;
|
|
9598
|
+
if (pace.verdict === "fast") return `fast${n > 0 ? `+${n}` : String(n)}`;
|
|
9599
|
+
return `ok${n > 0 ? `+${n}` : String(n)}`;
|
|
9600
|
+
}
|
|
9601
|
+
const vsEven = layout.mode === "wide" ? " vs even" : "";
|
|
9602
|
+
if (pace.verdict === "slow") return `slow ${signed}${vsEven}`;
|
|
9603
|
+
if (pace.verdict === "fast") return `fast ${signed}${vsEven}`;
|
|
9604
|
+
return `on track ${signed}${vsEven}`;
|
|
9605
|
+
}
|
|
9077
9606
|
function agentWindows(kind, snapshot, shortLabels) {
|
|
9078
9607
|
const L = shortLabels ? { five: "5h", seven: "7d", monthly: "mo", opus: "opus", sonnet: "son", oauth: "oath", cowork: "cowk" } : {
|
|
9079
9608
|
five: "5 hour",
|
|
@@ -9085,41 +9614,65 @@ function agentWindows(kind, snapshot, shortLabels) {
|
|
|
9085
9614
|
cowork: "7 day (Cowork)"
|
|
9086
9615
|
};
|
|
9087
9616
|
if (kind === "copilot") {
|
|
9088
|
-
return [
|
|
9617
|
+
return [{ label: L.monthly, window: snapshot.monthly, paceKind: "monthly" }];
|
|
9618
|
+
}
|
|
9619
|
+
if (kind === "command-code") {
|
|
9620
|
+
return [
|
|
9621
|
+
{ label: L.five, window: snapshot.five_hour },
|
|
9622
|
+
{
|
|
9623
|
+
label: shortLabels ? "wk" : "weekly",
|
|
9624
|
+
window: snapshot.seven_day,
|
|
9625
|
+
paceKind: "seven_day"
|
|
9626
|
+
},
|
|
9627
|
+
{ label: L.monthly, window: snapshot.monthly, paceKind: "monthly" }
|
|
9628
|
+
];
|
|
9089
9629
|
}
|
|
9090
9630
|
if (kind === "grok") {
|
|
9091
|
-
return [
|
|
9631
|
+
return [{ label: L.seven, window: snapshot.seven_day, paceKind: "seven_day" }];
|
|
9092
9632
|
}
|
|
9093
9633
|
if (kind === "codex" && snapshot.five_hour?.utilization == null) {
|
|
9094
|
-
return [
|
|
9634
|
+
return [{ label: L.seven, window: snapshot.seven_day, paceKind: "seven_day" }];
|
|
9095
9635
|
}
|
|
9096
9636
|
const rows = [
|
|
9097
|
-
|
|
9098
|
-
|
|
9637
|
+
{ label: L.five, window: snapshot.five_hour },
|
|
9638
|
+
{ label: L.seven, window: snapshot.seven_day, paceKind: "seven_day" }
|
|
9099
9639
|
];
|
|
9100
|
-
if (kind
|
|
9640
|
+
if (isClaudeAgent(kind) || !snapshot.agent) {
|
|
9101
9641
|
if (snapshot.seven_day_opus?.utilization != null) {
|
|
9102
|
-
rows.push(
|
|
9642
|
+
rows.push({ label: L.opus, window: snapshot.seven_day_opus, paceKind: "seven_day" });
|
|
9103
9643
|
}
|
|
9104
9644
|
if (snapshot.seven_day_sonnet?.utilization != null) {
|
|
9105
|
-
rows.push(
|
|
9645
|
+
rows.push({ label: L.sonnet, window: snapshot.seven_day_sonnet, paceKind: "seven_day" });
|
|
9106
9646
|
}
|
|
9107
9647
|
if (snapshot.seven_day_oauth_apps?.utilization != null) {
|
|
9108
|
-
rows.push(
|
|
9648
|
+
rows.push({ label: L.oauth, window: snapshot.seven_day_oauth_apps, paceKind: "seven_day" });
|
|
9109
9649
|
}
|
|
9110
9650
|
if (snapshot.seven_day_cowork?.utilization != null) {
|
|
9111
|
-
rows.push(
|
|
9651
|
+
rows.push({ label: L.cowork, window: snapshot.seven_day_cowork, paceKind: "seven_day" });
|
|
9112
9652
|
}
|
|
9113
9653
|
}
|
|
9114
9654
|
return rows;
|
|
9115
9655
|
}
|
|
9116
9656
|
function agentTitle(kind) {
|
|
9657
|
+
if (kind.startsWith("claude-code:")) {
|
|
9658
|
+
return `Claude Code (${kind.slice("claude-code:".length)})`;
|
|
9659
|
+
}
|
|
9117
9660
|
if (isAgentKind(kind)) {
|
|
9118
9661
|
return getAgentMetadata(kind)?.displayName ?? kind;
|
|
9119
9662
|
}
|
|
9120
9663
|
return kind;
|
|
9121
9664
|
}
|
|
9122
9665
|
function compareAgents(a, b) {
|
|
9666
|
+
const aClaude = isClaudeAgent(a);
|
|
9667
|
+
const bClaude = isClaudeAgent(b);
|
|
9668
|
+
if (aClaude || bClaude) {
|
|
9669
|
+
if (aClaude && bClaude) {
|
|
9670
|
+
if (a === "claude-code") return -1;
|
|
9671
|
+
if (b === "claude-code") return 1;
|
|
9672
|
+
return a.localeCompare(b);
|
|
9673
|
+
}
|
|
9674
|
+
return aClaude ? -1 : 1;
|
|
9675
|
+
}
|
|
9123
9676
|
const ia = AGENT_PRIORITY.indexOf(a);
|
|
9124
9677
|
const ib = AGENT_PRIORITY.indexOf(b);
|
|
9125
9678
|
if (ia !== -1 || ib !== -1) {
|
|
@@ -9179,6 +9732,7 @@ var init_format = __esm({
|
|
|
9179
9732
|
"src/usage/format.ts"() {
|
|
9180
9733
|
"use strict";
|
|
9181
9734
|
init_dist();
|
|
9735
|
+
init_pace();
|
|
9182
9736
|
DIM = "\x1B[2m";
|
|
9183
9737
|
BOLD = "\x1B[1m";
|
|
9184
9738
|
RESET = "\x1B[0m";
|
|
@@ -9186,7 +9740,7 @@ var init_format = __esm({
|
|
|
9186
9740
|
YELLOW = "\x1B[33m";
|
|
9187
9741
|
RED = "\x1B[31m";
|
|
9188
9742
|
EIGHTHS = ["", "\u258F", "\u258E", "\u258D", "\u258C", "\u258B", "\u258A", "\u2589"];
|
|
9189
|
-
AGENT_PRIORITY = ["claude-code", "codex", "copilot", "zai", "grok"];
|
|
9743
|
+
AGENT_PRIORITY = ["claude-code", "codex", "copilot", "zai", "grok", "command-code"];
|
|
9190
9744
|
}
|
|
9191
9745
|
});
|
|
9192
9746
|
|
|
@@ -9493,6 +10047,14 @@ async function saveAuxiliarySnapshots() {
|
|
|
9493
10047
|
console.warn(`zai usage: ${err.message}`);
|
|
9494
10048
|
}
|
|
9495
10049
|
}
|
|
10050
|
+
try {
|
|
10051
|
+
appendSnapshot(USAGE_LOG2, await fetchCommandCodeUsage());
|
|
10052
|
+
saved += 1;
|
|
10053
|
+
} catch (err) {
|
|
10054
|
+
if (!(err instanceof CommandCodeApiError) || err.code !== "no_auth") {
|
|
10055
|
+
console.warn(`command-code usage: ${err.message}`);
|
|
10056
|
+
}
|
|
10057
|
+
}
|
|
9496
10058
|
return saved;
|
|
9497
10059
|
}
|
|
9498
10060
|
function parseAgentFilter(args2) {
|
|
@@ -9506,22 +10068,51 @@ function parseAgentFilter(args2) {
|
|
|
9506
10068
|
copilot: "copilot",
|
|
9507
10069
|
zai: "zai",
|
|
9508
10070
|
"z.ai": "zai",
|
|
9509
|
-
grok: "grok"
|
|
10071
|
+
grok: "grok",
|
|
10072
|
+
"command-code": "command-code",
|
|
10073
|
+
commandcode: "command-code",
|
|
10074
|
+
cmd: "command-code"
|
|
9510
10075
|
};
|
|
9511
|
-
|
|
10076
|
+
if (aliases[kind]) return aliases[kind];
|
|
10077
|
+
if (kind.startsWith("claude-") && kind !== "claude-code") {
|
|
10078
|
+
return `claude-code:${kind.slice("claude-".length)}`;
|
|
10079
|
+
}
|
|
10080
|
+
return kind;
|
|
10081
|
+
}
|
|
10082
|
+
function isKnownUsageAgent(kind) {
|
|
10083
|
+
if (kind.startsWith("claude-code:")) return true;
|
|
10084
|
+
return isAgentKind(kind);
|
|
9512
10085
|
}
|
|
9513
10086
|
function filterAgents(byAgent, agentFilter) {
|
|
9514
10087
|
if (!agentFilter) return byAgent;
|
|
10088
|
+
if (agentFilter === "claude-code") {
|
|
10089
|
+
const hits = {};
|
|
10090
|
+
for (const [key, snap] of Object.entries(byAgent)) {
|
|
10091
|
+
if (key === "claude-code" || key.startsWith("claude-code:")) hits[key] = snap;
|
|
10092
|
+
}
|
|
10093
|
+
return hits;
|
|
10094
|
+
}
|
|
9515
10095
|
const hit = byAgent[agentFilter];
|
|
9516
10096
|
return hit ? { [agentFilter]: hit } : {};
|
|
9517
10097
|
}
|
|
10098
|
+
function applyLiveClaudeSnapshots(byAgent, snapshots) {
|
|
10099
|
+
if (snapshots.length === 0) return;
|
|
10100
|
+
for (const key of Object.keys(byAgent)) {
|
|
10101
|
+
if (key === "claude-code" || key.startsWith("claude-code:")) delete byAgent[key];
|
|
10102
|
+
}
|
|
10103
|
+
for (const snapshot of snapshots) {
|
|
10104
|
+
byAgent[snapshot.agent ?? "claude-code"] = snapshot;
|
|
10105
|
+
}
|
|
10106
|
+
}
|
|
9518
10107
|
async function collectSnapshots(opts) {
|
|
9519
10108
|
let saved = 0;
|
|
9520
10109
|
if (opts.save) {
|
|
9521
10110
|
try {
|
|
9522
|
-
const
|
|
9523
|
-
|
|
9524
|
-
|
|
10111
|
+
const { snapshots } = await fetchAllClaudeUsage();
|
|
10112
|
+
for (const snapshot of snapshots) {
|
|
10113
|
+
appendSnapshot(USAGE_LOG2, snapshot);
|
|
10114
|
+
saved += 1;
|
|
10115
|
+
}
|
|
9525
10116
|
} catch (err) {
|
|
9526
10117
|
if (!(err instanceof UsageApiError)) throw err;
|
|
9527
10118
|
}
|
|
@@ -9530,23 +10121,35 @@ async function collectSnapshots(opts) {
|
|
|
9530
10121
|
const byAgent = latestSnapshotsByAgent(USAGE_LOG2);
|
|
9531
10122
|
if (opts.preferLiveClaude && !opts.save) {
|
|
9532
10123
|
try {
|
|
9533
|
-
const
|
|
9534
|
-
byAgent
|
|
10124
|
+
const { snapshots } = await fetchAllClaudeUsage();
|
|
10125
|
+
applyLiveClaudeSnapshots(byAgent, snapshots);
|
|
9535
10126
|
} catch {
|
|
9536
10127
|
}
|
|
9537
10128
|
}
|
|
9538
10129
|
return { byAgent, saved };
|
|
9539
10130
|
}
|
|
9540
|
-
function usageJsonPayload(byAgent) {
|
|
10131
|
+
function usageJsonPayload(byAgent, opts) {
|
|
9541
10132
|
const keys = Object.keys(byAgent).sort(compareAgentKeys);
|
|
9542
10133
|
return {
|
|
10134
|
+
legend: PACE_LEGEND,
|
|
9543
10135
|
agents: keys.map((k) => {
|
|
9544
10136
|
const s = byAgent[k];
|
|
9545
|
-
|
|
10137
|
+
const pace = paceForSnapshot(s, opts?.nowMs);
|
|
10138
|
+
return { ...s, agent: s.agent ?? k, ...pace ? { pace } : {} };
|
|
9546
10139
|
})
|
|
9547
10140
|
};
|
|
9548
10141
|
}
|
|
9549
10142
|
function compareAgentKeys(a, b) {
|
|
10143
|
+
const aClaude = a === "claude-code" || a.startsWith("claude-code:");
|
|
10144
|
+
const bClaude = b === "claude-code" || b.startsWith("claude-code:");
|
|
10145
|
+
if (aClaude || bClaude) {
|
|
10146
|
+
if (aClaude && bClaude) {
|
|
10147
|
+
if (a === "claude-code") return -1;
|
|
10148
|
+
if (b === "claude-code") return 1;
|
|
10149
|
+
return a.localeCompare(b);
|
|
10150
|
+
}
|
|
10151
|
+
return aClaude ? -1 : 1;
|
|
10152
|
+
}
|
|
9550
10153
|
const ia = JSON_AGENT_ORDER.indexOf(a);
|
|
9551
10154
|
const ib = JSON_AGENT_ORDER.indexOf(b);
|
|
9552
10155
|
if (ia !== -1 || ib !== -1) {
|
|
@@ -9575,15 +10178,17 @@ function omitNulls(value) {
|
|
|
9575
10178
|
return value;
|
|
9576
10179
|
}
|
|
9577
10180
|
function shortAgentId(agent) {
|
|
9578
|
-
|
|
10181
|
+
if (agent === "claude-code") return "claude";
|
|
10182
|
+
if (agent.startsWith("claude-code:")) return `claude-${agent.slice("claude-code:".length)}`;
|
|
10183
|
+
if (agent === "command-code") return "cmd";
|
|
10184
|
+
return agent;
|
|
9579
10185
|
}
|
|
9580
10186
|
function shortIso(iso) {
|
|
9581
10187
|
const m = iso.match(/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2})/);
|
|
9582
10188
|
return m ? m[1] : iso.slice(0, 16);
|
|
9583
10189
|
}
|
|
9584
|
-
function usageCompactText(byAgent) {
|
|
9585
|
-
const agents = usageJsonPayload(byAgent).agents;
|
|
9586
|
-
const cell = (v) => v === null || v === void 0 ? "-" : String(v);
|
|
10190
|
+
function usageCompactText(byAgent, opts) {
|
|
10191
|
+
const agents = usageJsonPayload(byAgent, opts).agents;
|
|
9587
10192
|
const rows = agents.map((a) => {
|
|
9588
10193
|
const id = shortAgentId(a.agent);
|
|
9589
10194
|
const fh = a.five_hour?.utilization;
|
|
@@ -9591,14 +10196,33 @@ function usageCompactText(byAgent) {
|
|
|
9591
10196
|
const mo = a.monthly?.utilization;
|
|
9592
10197
|
const plan = (a.plan_type ?? "-").replace(/\s+/g, "_");
|
|
9593
10198
|
const at = a.captured_at ? shortIso(a.captured_at) : "-";
|
|
9594
|
-
return
|
|
10199
|
+
return [
|
|
10200
|
+
id,
|
|
10201
|
+
cellPct(fh),
|
|
10202
|
+
cellPct(sd),
|
|
10203
|
+
cellPct(mo),
|
|
10204
|
+
cellPace(a.pace?.seven_day),
|
|
10205
|
+
cellPace(a.pace?.monthly),
|
|
10206
|
+
plan,
|
|
10207
|
+
at
|
|
10208
|
+
].join(",");
|
|
9595
10209
|
});
|
|
9596
|
-
const legend = "# % of plan quota used \u2191busier | 5h/7d/mo
|
|
10210
|
+
const legend = "# % of plan quota used \u2191busier | 5h/7d/mo | 7d_pace/mo_pace=elapsed%-used% (+slow/-fast; |15|=on_track) | -=n/a";
|
|
9597
10211
|
return `${legend}
|
|
9598
|
-
agents[${rows.length}]{agent,5h,7d,mo,plan,sampled}:
|
|
10212
|
+
agents[${rows.length}]{agent,5h,7d,mo,7d_pace,mo_pace,plan,sampled}:
|
|
9599
10213
|
${rows.join("\n")}
|
|
9600
10214
|
`;
|
|
9601
10215
|
}
|
|
10216
|
+
function cellPct(v) {
|
|
10217
|
+
if (v === null || v === void 0) return "-";
|
|
10218
|
+
const r = Math.round(v * 10) / 10;
|
|
10219
|
+
return Number.isInteger(r) ? String(r) : r.toFixed(1);
|
|
10220
|
+
}
|
|
10221
|
+
function cellPace(p) {
|
|
10222
|
+
if (!p) return "-";
|
|
10223
|
+
const n = Math.round(p.delta_pp);
|
|
10224
|
+
return n > 0 ? `+${n}` : String(n);
|
|
10225
|
+
}
|
|
9602
10226
|
function emitJson(payload) {
|
|
9603
10227
|
process.stdout.write(JSON.stringify(omitNulls(payload)) + "\n");
|
|
9604
10228
|
}
|
|
@@ -9623,7 +10247,8 @@ Usage:
|
|
|
9623
10247
|
|
|
9624
10248
|
--compact Ultra-dense columnar text (recommended for agents / LLM context)
|
|
9625
10249
|
--json Machine JSON (minified, nulls stripped; exclusive with --watch/--compact)
|
|
9626
|
-
--agent / -a Filter to one provider (claude | codex | copilot | zai | grok)
|
|
10250
|
+
--agent / -a Filter to one provider (claude | claude-<slug> | codex | copilot | zai | grok | cmd).
|
|
10251
|
+
\`claude\` includes every discovered Claude Code login.
|
|
9627
10252
|
|
|
9628
10253
|
Watch options:
|
|
9629
10254
|
--interval N Redraw every N seconds (default 2; reads ~/.cclens/usage.jsonl)
|
|
@@ -9643,8 +10268,8 @@ stays fresh without hammering provider APIs.`);
|
|
|
9643
10268
|
const compact = args2.includes("--compact");
|
|
9644
10269
|
const machineMode = json ? "json" : compact ? "compact" : "text";
|
|
9645
10270
|
const agentFilter = parseAgentFilter(args2);
|
|
9646
|
-
if (agentFilter && !
|
|
9647
|
-
const msg = `unknown agent "${agentFilter}". Use claude, codex, copilot, zai, or
|
|
10271
|
+
if (agentFilter && !isKnownUsageAgent(agentFilter)) {
|
|
10272
|
+
const msg = `unknown agent "${agentFilter}". Use claude, claude-<slug>, codex, copilot, zai, grok, or cmd.`;
|
|
9648
10273
|
emitMachineError(machineMode, msg);
|
|
9649
10274
|
process.exitCode = 1;
|
|
9650
10275
|
return;
|
|
@@ -9713,8 +10338,17 @@ stays fresh without hammering provider APIs.`);
|
|
|
9713
10338
|
}
|
|
9714
10339
|
}
|
|
9715
10340
|
async function runWatch(opts) {
|
|
10341
|
+
let saved = 0;
|
|
10342
|
+
try {
|
|
10343
|
+
const { snapshots } = await fetchAllClaudeUsage();
|
|
10344
|
+
for (const snapshot of snapshots) {
|
|
10345
|
+
appendSnapshot(USAGE_LOG2, snapshot);
|
|
10346
|
+
saved += 1;
|
|
10347
|
+
}
|
|
10348
|
+
} catch {
|
|
10349
|
+
}
|
|
9716
10350
|
if (opts.saveOnce) {
|
|
9717
|
-
|
|
10351
|
+
saved += await saveAuxiliarySnapshots();
|
|
9718
10352
|
if (saved === 0 && Object.keys(latestSnapshotsByAgent(USAGE_LOG2)).length === 0) {
|
|
9719
10353
|
console.error(
|
|
9720
10354
|
"Error: could not poll any provider and no samples are on disk."
|
|
@@ -9790,10 +10424,12 @@ var init_usage = __esm({
|
|
|
9790
10424
|
init_codex2();
|
|
9791
10425
|
init_copilot2();
|
|
9792
10426
|
init_zai();
|
|
10427
|
+
init_command_code();
|
|
9793
10428
|
init_format();
|
|
10429
|
+
init_pace();
|
|
9794
10430
|
init_storage();
|
|
9795
10431
|
USAGE_LOG2 = cclensPath("usage.jsonl");
|
|
9796
|
-
JSON_AGENT_ORDER = ["claude-code", "codex", "copilot", "zai", "grok"];
|
|
10432
|
+
JSON_AGENT_ORDER = ["claude-code", "codex", "copilot", "zai", "grok", "command-code"];
|
|
9797
10433
|
}
|
|
9798
10434
|
});
|
|
9799
10435
|
|
|
@@ -10643,11 +11279,11 @@ var init_dist2 = __esm({
|
|
|
10643
11279
|
});
|
|
10644
11280
|
|
|
10645
11281
|
// ../entries/dist/digest-fs.js
|
|
10646
|
-
import { readFileSync as
|
|
10647
|
-
import { dirname as dirname9, join as
|
|
10648
|
-
function parseDigestFile(
|
|
11282
|
+
import { readFileSync as readFileSync16, readdirSync as readdirSync2, writeFileSync as writeFileSync7, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync6, existsSync as existsSync14 } from "node:fs";
|
|
11283
|
+
import { dirname as dirname9, join as join10 } from "node:path";
|
|
11284
|
+
function parseDigestFile(path12, expectedVersion) {
|
|
10649
11285
|
try {
|
|
10650
|
-
const parsed = JSON.parse(
|
|
11286
|
+
const parsed = JSON.parse(readFileSync16(path12, "utf8"));
|
|
10651
11287
|
if (!parsed || typeof parsed !== "object")
|
|
10652
11288
|
return null;
|
|
10653
11289
|
if (parsed.version !== expectedVersion)
|
|
@@ -10666,20 +11302,20 @@ function digestsDir() {
|
|
|
10666
11302
|
digestsDirCached = envOverride ?? cclensPath("digests");
|
|
10667
11303
|
return digestsDirCached;
|
|
10668
11304
|
}
|
|
10669
|
-
function __setDigestsDirForTest(
|
|
10670
|
-
digestsDirCached =
|
|
10671
|
-
mkdirSync6(
|
|
10672
|
-
mkdirSync6(
|
|
10673
|
-
mkdirSync6(
|
|
11305
|
+
function __setDigestsDirForTest(path12) {
|
|
11306
|
+
digestsDirCached = path12;
|
|
11307
|
+
mkdirSync6(join10(path12, "day"), { recursive: true });
|
|
11308
|
+
mkdirSync6(join10(path12, "week"), { recursive: true });
|
|
11309
|
+
mkdirSync6(join10(path12, "month"), { recursive: true });
|
|
10674
11310
|
}
|
|
10675
11311
|
function dayDigestPath(date) {
|
|
10676
|
-
return
|
|
11312
|
+
return join10(digestsDir(), "day", `${date}.json`);
|
|
10677
11313
|
}
|
|
10678
11314
|
function weekDigestPath(monday) {
|
|
10679
|
-
return
|
|
11315
|
+
return join10(digestsDir(), "week", `${monday}.json`);
|
|
10680
11316
|
}
|
|
10681
11317
|
function monthDigestPath(yearMonth) {
|
|
10682
|
-
return
|
|
11318
|
+
return join10(digestsDir(), "month", `${yearMonth}.json`);
|
|
10683
11319
|
}
|
|
10684
11320
|
function writeDayDigest(digest2) {
|
|
10685
11321
|
const final = dayDigestPath(digest2.key);
|
|
@@ -10696,7 +11332,7 @@ function writeDayDigest(digest2) {
|
|
|
10696
11332
|
}
|
|
10697
11333
|
function readDayDigest(date) {
|
|
10698
11334
|
const p = dayDigestPath(date);
|
|
10699
|
-
if (!
|
|
11335
|
+
if (!existsSync14(p))
|
|
10700
11336
|
return null;
|
|
10701
11337
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
10702
11338
|
}
|
|
@@ -10732,15 +11368,15 @@ function writeWeekDigest(digest2) {
|
|
|
10732
11368
|
}
|
|
10733
11369
|
function readWeekDigest(monday) {
|
|
10734
11370
|
const p = weekDigestPath(monday);
|
|
10735
|
-
if (!
|
|
11371
|
+
if (!existsSync14(p))
|
|
10736
11372
|
return null;
|
|
10737
11373
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
10738
11374
|
}
|
|
10739
11375
|
function listWeekDigestKeys() {
|
|
10740
|
-
const dir =
|
|
10741
|
-
if (!
|
|
11376
|
+
const dir = join10(digestsDir(), "week");
|
|
11377
|
+
if (!existsSync14(dir))
|
|
10742
11378
|
return [];
|
|
10743
|
-
return
|
|
11379
|
+
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}-\d{2}$/.test(k));
|
|
10744
11380
|
}
|
|
10745
11381
|
function getCurrentWeekDigestFromCache(monday, nowMs) {
|
|
10746
11382
|
if (!currentWeekCache)
|
|
@@ -10769,15 +11405,15 @@ function writeMonthDigest(digest2) {
|
|
|
10769
11405
|
}
|
|
10770
11406
|
function readMonthDigest(yearMonth) {
|
|
10771
11407
|
const p = monthDigestPath(yearMonth);
|
|
10772
|
-
if (!
|
|
11408
|
+
if (!existsSync14(p))
|
|
10773
11409
|
return null;
|
|
10774
11410
|
return parseDigestFile(p, CURRENT_MONTH_DIGEST_SCHEMA_VERSION);
|
|
10775
11411
|
}
|
|
10776
11412
|
function listMonthDigestKeys() {
|
|
10777
|
-
const dir =
|
|
10778
|
-
if (!
|
|
11413
|
+
const dir = join10(digestsDir(), "month");
|
|
11414
|
+
if (!existsSync14(dir))
|
|
10779
11415
|
return [];
|
|
10780
|
-
return
|
|
11416
|
+
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}$/.test(k));
|
|
10781
11417
|
}
|
|
10782
11418
|
function getCurrentMonthDigestFromCache(yearMonth, nowMs) {
|
|
10783
11419
|
if (!currentMonthCache)
|
|
@@ -10837,9 +11473,9 @@ __export(fs_exports2, {
|
|
|
10837
11473
|
writeMonthDigest: () => writeMonthDigest,
|
|
10838
11474
|
writeWeekDigest: () => writeWeekDigest
|
|
10839
11475
|
});
|
|
10840
|
-
import { readFileSync as
|
|
11476
|
+
import { readFileSync as readFileSync17, readdirSync as readdirSync3, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync15 } from "node:fs";
|
|
10841
11477
|
import { randomBytes } from "node:crypto";
|
|
10842
|
-
import { join as
|
|
11478
|
+
import { join as join11 } from "node:path";
|
|
10843
11479
|
function entriesDir() {
|
|
10844
11480
|
if (entriesDirCached)
|
|
10845
11481
|
return entriesDirCached;
|
|
@@ -10847,12 +11483,12 @@ function entriesDir() {
|
|
|
10847
11483
|
entriesDirCached = envOverride ?? cclensPath("entries");
|
|
10848
11484
|
return entriesDirCached;
|
|
10849
11485
|
}
|
|
10850
|
-
function __setEntriesDirForTest(
|
|
10851
|
-
entriesDirCached =
|
|
10852
|
-
mkdirSync7(
|
|
11486
|
+
function __setEntriesDirForTest(path12) {
|
|
11487
|
+
entriesDirCached = path12;
|
|
11488
|
+
mkdirSync7(path12, { recursive: true });
|
|
10853
11489
|
}
|
|
10854
11490
|
function pathFor(sessionId, localDay2) {
|
|
10855
|
-
return
|
|
11491
|
+
return join11(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
10856
11492
|
}
|
|
10857
11493
|
function tmpPathFor(final) {
|
|
10858
11494
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
@@ -10896,19 +11532,19 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
10896
11532
|
}
|
|
10897
11533
|
function readEntry(sessionId, localDay2) {
|
|
10898
11534
|
const p = pathFor(sessionId, localDay2);
|
|
10899
|
-
if (!
|
|
11535
|
+
if (!existsSync15(p))
|
|
10900
11536
|
return null;
|
|
10901
|
-
const raw =
|
|
11537
|
+
const raw = readFileSync17(p, "utf8");
|
|
10902
11538
|
return JSON.parse(raw);
|
|
10903
11539
|
}
|
|
10904
11540
|
function entryExists(sessionId, localDay2) {
|
|
10905
|
-
return
|
|
11541
|
+
return existsSync15(pathFor(sessionId, localDay2));
|
|
10906
11542
|
}
|
|
10907
11543
|
function listEntryKeys() {
|
|
10908
11544
|
const dir = entriesDir();
|
|
10909
|
-
if (!
|
|
11545
|
+
if (!existsSync15(dir))
|
|
10910
11546
|
return [];
|
|
10911
|
-
return
|
|
11547
|
+
return readdirSync3(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
10912
11548
|
}
|
|
10913
11549
|
function listEntriesForDay(localDay2) {
|
|
10914
11550
|
const out = [];
|
|
@@ -11377,8 +12013,8 @@ var init_parseUtil = __esm({
|
|
|
11377
12013
|
init_errors();
|
|
11378
12014
|
init_en();
|
|
11379
12015
|
makeIssue = (params) => {
|
|
11380
|
-
const { data, path:
|
|
11381
|
-
const fullPath = [...
|
|
12016
|
+
const { data, path: path12, errorMaps, issueData } = params;
|
|
12017
|
+
const fullPath = [...path12, ...issueData.path || []];
|
|
11382
12018
|
const fullIssue = {
|
|
11383
12019
|
...issueData,
|
|
11384
12020
|
path: fullPath
|
|
@@ -11686,11 +12322,11 @@ var init_types3 = __esm({
|
|
|
11686
12322
|
init_parseUtil();
|
|
11687
12323
|
init_util();
|
|
11688
12324
|
ParseInputLazyPath = class {
|
|
11689
|
-
constructor(parent, value,
|
|
12325
|
+
constructor(parent, value, path12, key) {
|
|
11690
12326
|
this._cachedPath = [];
|
|
11691
12327
|
this.parent = parent;
|
|
11692
12328
|
this.data = value;
|
|
11693
|
-
this._path =
|
|
12329
|
+
this._path = path12;
|
|
11694
12330
|
this._key = key;
|
|
11695
12331
|
}
|
|
11696
12332
|
get path() {
|
|
@@ -15174,27 +15810,27 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
|
|
|
15174
15810
|
});
|
|
15175
15811
|
|
|
15176
15812
|
// ../entries/dist/claude-bin.js
|
|
15177
|
-
import { existsSync as
|
|
15178
|
-
import { join as
|
|
15179
|
-
import { homedir as
|
|
15813
|
+
import { existsSync as existsSync16 } from "node:fs";
|
|
15814
|
+
import { join as join12, dirname as dirname10, delimiter } from "node:path";
|
|
15815
|
+
import { homedir as homedir6 } from "node:os";
|
|
15180
15816
|
function resolveClaudeBin(opts = {}) {
|
|
15181
15817
|
const env = opts.env ?? process.env;
|
|
15182
|
-
const home = opts.home ??
|
|
15818
|
+
const home = opts.home ?? homedir6();
|
|
15183
15819
|
const execPath = opts.execPath ?? process.execPath;
|
|
15184
|
-
const exists = opts.exists ??
|
|
15820
|
+
const exists = opts.exists ?? existsSync16;
|
|
15185
15821
|
for (const dir of (env.PATH ?? "").split(delimiter)) {
|
|
15186
15822
|
if (!dir)
|
|
15187
15823
|
continue;
|
|
15188
|
-
const onPath =
|
|
15824
|
+
const onPath = join12(dir, "claude");
|
|
15189
15825
|
if (exists(onPath))
|
|
15190
15826
|
return onPath;
|
|
15191
15827
|
}
|
|
15192
15828
|
return [
|
|
15193
|
-
|
|
15829
|
+
join12(home, ".local", "bin", "claude"),
|
|
15194
15830
|
// native installer
|
|
15195
|
-
|
|
15831
|
+
join12(home, ".claude", "local", "claude"),
|
|
15196
15832
|
// legacy local install
|
|
15197
|
-
|
|
15833
|
+
join12(dirname10(execPath), "claude"),
|
|
15198
15834
|
// npm -g, beside the node running us
|
|
15199
15835
|
"/opt/homebrew/bin/claude",
|
|
15200
15836
|
"/usr/local/bin/claude"
|
|
@@ -15222,9 +15858,9 @@ var init_claude_bin = __esm({
|
|
|
15222
15858
|
});
|
|
15223
15859
|
|
|
15224
15860
|
// ../entries/dist/tmux-runner.js
|
|
15225
|
-
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, existsSync as
|
|
15226
|
-
import { join as
|
|
15227
|
-
import { homedir as
|
|
15861
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, existsSync as existsSync17, readdirSync as readdirSync4, realpathSync as realpathSync5, readFileSync as readFileSync18, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
15862
|
+
import { join as join13 } from "node:path";
|
|
15863
|
+
import { homedir as homedir7 } from "node:os";
|
|
15228
15864
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
15229
15865
|
function which(bin) {
|
|
15230
15866
|
const r = spawnSync2("/usr/bin/env", ["which", bin], { encoding: "utf8" });
|
|
@@ -15240,16 +15876,16 @@ function tmuxRunnerAvailable() {
|
|
|
15240
15876
|
return { ok: true };
|
|
15241
15877
|
}
|
|
15242
15878
|
function runtimeCwd() {
|
|
15243
|
-
const dir =
|
|
15244
|
-
if (!
|
|
15879
|
+
const dir = join13(homedir7(), ".cclens", "runtime");
|
|
15880
|
+
if (!existsSync17(dir))
|
|
15245
15881
|
mkdirSync8(dir, { recursive: true });
|
|
15246
15882
|
return realpathSync5(dir);
|
|
15247
15883
|
}
|
|
15248
15884
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
15249
|
-
const cfgPath =
|
|
15885
|
+
const cfgPath = join13(homedir7(), ".claude.json");
|
|
15250
15886
|
let cfg;
|
|
15251
15887
|
try {
|
|
15252
|
-
cfg = JSON.parse(
|
|
15888
|
+
cfg = JSON.parse(readFileSync18(cfgPath, "utf8"));
|
|
15253
15889
|
} catch {
|
|
15254
15890
|
return;
|
|
15255
15891
|
}
|
|
@@ -15291,9 +15927,9 @@ async function runClaudeUnderTmuxImpl(args2) {
|
|
|
15291
15927
|
ensureRuntimeCwdTrusted(cwd);
|
|
15292
15928
|
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
15293
15929
|
const sessionName = `cclens-${runId}`;
|
|
15294
|
-
const systemFile =
|
|
15295
|
-
const userFile =
|
|
15296
|
-
const wrapper =
|
|
15930
|
+
const systemFile = join13(cwd, `system-${runId}.txt`);
|
|
15931
|
+
const userFile = join13(cwd, `user-${runId}.txt`);
|
|
15932
|
+
const wrapper = join13(cwd, `run-${runId}.sh`);
|
|
15297
15933
|
writeFileSync9(systemFile, args2.systemPrompt);
|
|
15298
15934
|
writeFileSync9(userFile, args2.reminder ? `${args2.userPrompt}
|
|
15299
15935
|
|
|
@@ -15377,29 +16013,29 @@ function snapshotAllTranscripts() {
|
|
|
15377
16013
|
const root = PROJECTS_ROOT();
|
|
15378
16014
|
let subs;
|
|
15379
16015
|
try {
|
|
15380
|
-
subs =
|
|
16016
|
+
subs = readdirSync4(root);
|
|
15381
16017
|
} catch {
|
|
15382
16018
|
return out;
|
|
15383
16019
|
}
|
|
15384
16020
|
for (const sub of subs) {
|
|
15385
|
-
const dir =
|
|
16021
|
+
const dir = join13(root, sub);
|
|
15386
16022
|
let files;
|
|
15387
16023
|
try {
|
|
15388
|
-
files =
|
|
16024
|
+
files = readdirSync4(dir);
|
|
15389
16025
|
} catch {
|
|
15390
16026
|
continue;
|
|
15391
16027
|
}
|
|
15392
16028
|
for (const f of files) {
|
|
15393
16029
|
if (f.endsWith(".jsonl"))
|
|
15394
|
-
out.add(
|
|
16030
|
+
out.add(join13(dir, f));
|
|
15395
16031
|
}
|
|
15396
16032
|
}
|
|
15397
16033
|
return out;
|
|
15398
16034
|
}
|
|
15399
|
-
function readJsonlCwd(
|
|
16035
|
+
function readJsonlCwd(path12, maxLines = 8) {
|
|
15400
16036
|
let raw;
|
|
15401
16037
|
try {
|
|
15402
|
-
raw =
|
|
16038
|
+
raw = readFileSync18(path12, "utf8");
|
|
15403
16039
|
} catch {
|
|
15404
16040
|
return void 0;
|
|
15405
16041
|
}
|
|
@@ -15427,22 +16063,22 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
15427
16063
|
const root = PROJECTS_ROOT();
|
|
15428
16064
|
let subs;
|
|
15429
16065
|
try {
|
|
15430
|
-
subs =
|
|
16066
|
+
subs = readdirSync4(root);
|
|
15431
16067
|
} catch {
|
|
15432
16068
|
subs = [];
|
|
15433
16069
|
}
|
|
15434
16070
|
for (const sub of subs) {
|
|
15435
|
-
const dir =
|
|
16071
|
+
const dir = join13(root, sub);
|
|
15436
16072
|
let files;
|
|
15437
16073
|
try {
|
|
15438
|
-
files =
|
|
16074
|
+
files = readdirSync4(dir);
|
|
15439
16075
|
} catch {
|
|
15440
16076
|
continue;
|
|
15441
16077
|
}
|
|
15442
16078
|
for (const f of files) {
|
|
15443
16079
|
if (!f.endsWith(".jsonl"))
|
|
15444
16080
|
continue;
|
|
15445
|
-
const full =
|
|
16081
|
+
const full = join13(dir, f);
|
|
15446
16082
|
if (existingBefore.has(full))
|
|
15447
16083
|
continue;
|
|
15448
16084
|
if (readJsonlCwd(full) === targetCwd)
|
|
@@ -15453,10 +16089,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
15453
16089
|
}
|
|
15454
16090
|
throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
|
|
15455
16091
|
}
|
|
15456
|
-
function parseTranscript2(
|
|
16092
|
+
function parseTranscript2(path12, defaultModel) {
|
|
15457
16093
|
let raw;
|
|
15458
16094
|
try {
|
|
15459
|
-
raw =
|
|
16095
|
+
raw = readFileSync18(path12, "utf8");
|
|
15460
16096
|
} catch {
|
|
15461
16097
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
15462
16098
|
}
|
|
@@ -15516,7 +16152,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
|
|
|
15516
16152
|
}
|
|
15517
16153
|
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
15518
16154
|
try {
|
|
15519
|
-
unlinkSync3(
|
|
16155
|
+
unlinkSync3(join13(cwd, f));
|
|
15520
16156
|
} catch {
|
|
15521
16157
|
}
|
|
15522
16158
|
}
|
|
@@ -15545,17 +16181,17 @@ var init_tmux_runner = __esm({
|
|
|
15545
16181
|
}
|
|
15546
16182
|
};
|
|
15547
16183
|
mutex = Promise.resolve();
|
|
15548
|
-
PROJECTS_ROOT = () =>
|
|
16184
|
+
PROJECTS_ROOT = () => join13(homedir7(), ".claude", "projects");
|
|
15549
16185
|
}
|
|
15550
16186
|
});
|
|
15551
16187
|
|
|
15552
16188
|
// ../entries/dist/llm-runner.js
|
|
15553
16189
|
import { spawn as spawn4 } from "node:child_process";
|
|
15554
|
-
import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync10, existsSync as
|
|
15555
|
-
import { join as
|
|
16190
|
+
import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync10, existsSync as existsSync18 } from "node:fs";
|
|
16191
|
+
import { join as join14 } from "node:path";
|
|
15556
16192
|
import { randomUUID } from "node:crypto";
|
|
15557
16193
|
function ensureRunsDir() {
|
|
15558
|
-
if (!
|
|
16194
|
+
if (!existsSync18(RUNS_DIR)) {
|
|
15559
16195
|
try {
|
|
15560
16196
|
mkdirSync9(RUNS_DIR, { recursive: true });
|
|
15561
16197
|
} catch {
|
|
@@ -15584,17 +16220,17 @@ function newRunId(kind) {
|
|
|
15584
16220
|
return `${ts}_${kind}_${short}`;
|
|
15585
16221
|
}
|
|
15586
16222
|
function tracePath(runId) {
|
|
15587
|
-
return
|
|
16223
|
+
return join14(RUNS_DIR, `${runId}.jsonl`);
|
|
15588
16224
|
}
|
|
15589
|
-
function safeAppend(
|
|
16225
|
+
function safeAppend(path12, line) {
|
|
15590
16226
|
try {
|
|
15591
|
-
appendFileSync3(
|
|
16227
|
+
appendFileSync3(path12, line);
|
|
15592
16228
|
} catch {
|
|
15593
16229
|
}
|
|
15594
16230
|
}
|
|
15595
|
-
function safeWrite(
|
|
16231
|
+
function safeWrite(path12, line) {
|
|
15596
16232
|
try {
|
|
15597
|
-
writeFileSync10(
|
|
16233
|
+
writeFileSync10(path12, line);
|
|
15598
16234
|
} catch {
|
|
15599
16235
|
}
|
|
15600
16236
|
}
|
|
@@ -15672,7 +16308,7 @@ async function runClaudeSubprocess(args2) {
|
|
|
15672
16308
|
return runClaudePrintMode(args2);
|
|
15673
16309
|
}
|
|
15674
16310
|
function runClaudePrintMode(args2) {
|
|
15675
|
-
return new Promise((
|
|
16311
|
+
return new Promise((resolve5, reject) => {
|
|
15676
16312
|
ensureRunsDir();
|
|
15677
16313
|
const kind = detectKindFromSystemPrompt(args2.systemPrompt);
|
|
15678
16314
|
const runId = newRunId(kind);
|
|
@@ -15810,7 +16446,7 @@ ${args2.reminder}` : args2.userPrompt;
|
|
|
15810
16446
|
reject(new Error(`claude exited ${code}: ${stderr.trim().slice(0, 300)}`));
|
|
15811
16447
|
return;
|
|
15812
16448
|
}
|
|
15813
|
-
|
|
16449
|
+
resolve5({ content: buffer, input_tokens: inputTokens, output_tokens: outputTokens, model: modelUsed });
|
|
15814
16450
|
});
|
|
15815
16451
|
proc.on("error", (err) => {
|
|
15816
16452
|
safeAppend(trace, JSON.stringify({ _meta: { type: "spawn_error", run_id: runId, ts: (/* @__PURE__ */ new Date()).toISOString(), error: err.message } }) + "\n");
|
|
@@ -16008,7 +16644,7 @@ var init_enrich2 = __esm({
|
|
|
16008
16644
|
});
|
|
16009
16645
|
|
|
16010
16646
|
// ../entries/dist/budget.js
|
|
16011
|
-
import { appendFileSync as appendFileSync4, readFileSync as
|
|
16647
|
+
import { appendFileSync as appendFileSync4, readFileSync as readFileSync19, existsSync as existsSync19, mkdirSync as mkdirSync10 } from "node:fs";
|
|
16012
16648
|
import { dirname as dirname11 } from "node:path";
|
|
16013
16649
|
function spendPath() {
|
|
16014
16650
|
if (spendPathCached)
|
|
@@ -16016,8 +16652,8 @@ function spendPath() {
|
|
|
16016
16652
|
spendPathCached = cclensPath("llm-spend.jsonl");
|
|
16017
16653
|
return spendPathCached;
|
|
16018
16654
|
}
|
|
16019
|
-
function __setSpendPathForTest(
|
|
16020
|
-
spendPathCached =
|
|
16655
|
+
function __setSpendPathForTest(path12) {
|
|
16656
|
+
spendPathCached = path12;
|
|
16021
16657
|
}
|
|
16022
16658
|
function appendSpend(record) {
|
|
16023
16659
|
const p = spendPath();
|
|
@@ -16026,12 +16662,12 @@ function appendSpend(record) {
|
|
|
16026
16662
|
}
|
|
16027
16663
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
16028
16664
|
const p = spendPath();
|
|
16029
|
-
if (!
|
|
16665
|
+
if (!existsSync19(p))
|
|
16030
16666
|
return 0;
|
|
16031
16667
|
const year = now.getUTCFullYear();
|
|
16032
16668
|
const month2 = now.getUTCMonth();
|
|
16033
16669
|
let total = 0;
|
|
16034
|
-
const raw =
|
|
16670
|
+
const raw = readFileSync19(p, "utf8");
|
|
16035
16671
|
for (const line of raw.split("\n")) {
|
|
16036
16672
|
if (!line)
|
|
16037
16673
|
continue;
|
|
@@ -16060,15 +16696,15 @@ var init_budget = __esm({
|
|
|
16060
16696
|
});
|
|
16061
16697
|
|
|
16062
16698
|
// ../entries/dist/pipeline-lock.js
|
|
16063
|
-
import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync4, existsSync as
|
|
16699
|
+
import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync4, existsSync as existsSync20, readFileSync as readFileSync20, statSync as statSync4 } from "node:fs";
|
|
16064
16700
|
function lockPath() {
|
|
16065
16701
|
if (lockPathCached)
|
|
16066
16702
|
return lockPathCached;
|
|
16067
16703
|
lockPathCached = cclensPath("llm-interactive.lock");
|
|
16068
16704
|
return lockPathCached;
|
|
16069
16705
|
}
|
|
16070
|
-
function __setInteractiveLockPathForTest(
|
|
16071
|
-
lockPathCached =
|
|
16706
|
+
function __setInteractiveLockPathForTest(path12) {
|
|
16707
|
+
lockPathCached = path12;
|
|
16072
16708
|
}
|
|
16073
16709
|
function touchLock() {
|
|
16074
16710
|
writeFileSync11(lockPath(), String(process.pid), "utf8");
|
|
@@ -16105,13 +16741,13 @@ function pidAlive(pid) {
|
|
|
16105
16741
|
}
|
|
16106
16742
|
function interactiveLockFresh(nowMs) {
|
|
16107
16743
|
const p = lockPath();
|
|
16108
|
-
if (!
|
|
16744
|
+
if (!existsSync20(p))
|
|
16109
16745
|
return false;
|
|
16110
16746
|
try {
|
|
16111
|
-
const mtime =
|
|
16747
|
+
const mtime = statSync4(p).mtimeMs;
|
|
16112
16748
|
if (nowMs - mtime > STALE_MS)
|
|
16113
16749
|
return false;
|
|
16114
|
-
const pid = Number(
|
|
16750
|
+
const pid = Number(readFileSync20(p, "utf8").trim());
|
|
16115
16751
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
16116
16752
|
return false;
|
|
16117
16753
|
if (!pidAlive(pid))
|
|
@@ -16217,7 +16853,7 @@ var init_queue = __esm({
|
|
|
16217
16853
|
});
|
|
16218
16854
|
|
|
16219
16855
|
// ../entries/dist/settings.js
|
|
16220
|
-
import { readFileSync as
|
|
16856
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync12, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync21 } from "node:fs";
|
|
16221
16857
|
import { dirname as dirname12 } from "node:path";
|
|
16222
16858
|
function settingsPath() {
|
|
16223
16859
|
if (settingsPathCached)
|
|
@@ -16225,8 +16861,8 @@ function settingsPath() {
|
|
|
16225
16861
|
settingsPathCached = cclensPath("settings.json");
|
|
16226
16862
|
return settingsPathCached;
|
|
16227
16863
|
}
|
|
16228
|
-
function __setSettingsPathForTest(
|
|
16229
|
-
settingsPathCached =
|
|
16864
|
+
function __setSettingsPathForTest(path12) {
|
|
16865
|
+
settingsPathCached = path12;
|
|
16230
16866
|
}
|
|
16231
16867
|
function toDisk(s) {
|
|
16232
16868
|
return {
|
|
@@ -16253,10 +16889,10 @@ function fromDisk(d) {
|
|
|
16253
16889
|
}
|
|
16254
16890
|
function readSettings() {
|
|
16255
16891
|
const p = settingsPath();
|
|
16256
|
-
if (!
|
|
16892
|
+
if (!existsSync21(p))
|
|
16257
16893
|
return DEFAULT_SETTINGS;
|
|
16258
16894
|
try {
|
|
16259
|
-
const raw =
|
|
16895
|
+
const raw = readFileSync21(p, "utf8");
|
|
16260
16896
|
return fromDisk(JSON.parse(raw));
|
|
16261
16897
|
} catch {
|
|
16262
16898
|
return DEFAULT_SETTINGS;
|
|
@@ -19446,7 +20082,7 @@ var init_digest_month_pipeline = __esm({
|
|
|
19446
20082
|
});
|
|
19447
20083
|
|
|
19448
20084
|
// ../entries/dist/credentials.js
|
|
19449
|
-
import { writeFileSync as writeFileSync13, readFileSync as
|
|
20085
|
+
import { writeFileSync as writeFileSync13, readFileSync as readFileSync22, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync22, unlinkSync as unlinkSync5 } from "node:fs";
|
|
19450
20086
|
import { dirname as dirname13 } from "node:path";
|
|
19451
20087
|
async function fetchZaiUsage2(candidate) {
|
|
19452
20088
|
const key = candidate.trim();
|
|
@@ -19517,10 +20153,10 @@ function credentialsPath() {
|
|
|
19517
20153
|
}
|
|
19518
20154
|
function readCredentials() {
|
|
19519
20155
|
const p = credentialsPath();
|
|
19520
|
-
if (!
|
|
20156
|
+
if (!existsSync22(p))
|
|
19521
20157
|
return {};
|
|
19522
20158
|
try {
|
|
19523
|
-
const raw =
|
|
20159
|
+
const raw = readFileSync22(p, "utf8");
|
|
19524
20160
|
return JSON.parse(raw);
|
|
19525
20161
|
} catch {
|
|
19526
20162
|
return {};
|
|
@@ -20154,9 +20790,9 @@ var menubar_exports = {};
|
|
|
20154
20790
|
__export(menubar_exports, {
|
|
20155
20791
|
menubar: () => menubar
|
|
20156
20792
|
});
|
|
20157
|
-
import { existsSync as
|
|
20158
|
-
import { homedir as
|
|
20159
|
-
import { join as
|
|
20793
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync5, writeFileSync as writeFileSync14, realpathSync as realpathSync6 } from "node:fs";
|
|
20794
|
+
import { homedir as homedir8 } from "node:os";
|
|
20795
|
+
import { join as join15, dirname as dirname14 } from "node:path";
|
|
20160
20796
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
20161
20797
|
import { execFile as execFile2 } from "node:child_process";
|
|
20162
20798
|
import { promisify as promisify2 } from "node:util";
|
|
@@ -20165,7 +20801,7 @@ function isMac2() {
|
|
|
20165
20801
|
}
|
|
20166
20802
|
function bundledAppPath() {
|
|
20167
20803
|
const here = dirname14(fileURLToPath3(import.meta.url));
|
|
20168
|
-
return
|
|
20804
|
+
return join15(here, "..", "menubar", APP_BUNDLE);
|
|
20169
20805
|
}
|
|
20170
20806
|
function resolveScriptPath2() {
|
|
20171
20807
|
const argv1 = process.argv[1] ?? "";
|
|
@@ -20186,10 +20822,10 @@ function writeCliLaunchFile() {
|
|
|
20186
20822
|
}
|
|
20187
20823
|
}
|
|
20188
20824
|
function installedAppPath() {
|
|
20189
|
-
return
|
|
20825
|
+
return join15(homedir8(), "Applications", APP_BUNDLE);
|
|
20190
20826
|
}
|
|
20191
20827
|
function legacyInstalledAppPath() {
|
|
20192
|
-
return
|
|
20828
|
+
return join15(homedir8(), "Applications", LEGACY_APP_BUNDLE);
|
|
20193
20829
|
}
|
|
20194
20830
|
async function isRunning() {
|
|
20195
20831
|
try {
|
|
@@ -20199,8 +20835,8 @@ async function isRunning() {
|
|
|
20199
20835
|
return false;
|
|
20200
20836
|
}
|
|
20201
20837
|
}
|
|
20202
|
-
async function launchApp(
|
|
20203
|
-
await execFileAsync2("open", ["-a",
|
|
20838
|
+
async function launchApp(path12) {
|
|
20839
|
+
await execFileAsync2("open", ["-a", path12]);
|
|
20204
20840
|
}
|
|
20205
20841
|
async function quitApp() {
|
|
20206
20842
|
await execFileAsync2("osascript", ["-e", `tell application "${BUNDLE_EXEC}" to quit`]).catch(
|
|
@@ -20228,14 +20864,14 @@ async function installMenubar(opts) {
|
|
|
20228
20864
|
return;
|
|
20229
20865
|
}
|
|
20230
20866
|
const src = bundledAppPath();
|
|
20231
|
-
if (!
|
|
20867
|
+
if (!existsSync23(src)) {
|
|
20232
20868
|
console.error(
|
|
20233
20869
|
`Bundled widget not found at ${src}.
|
|
20234
20870
|
This install was probably built without the menubar artifact. Run \`bash apps/menubar/build-app.sh && cp -R apps/menubar/dist/Fleetlens.app packages/cli/menubar/\` and rebuild.`
|
|
20235
20871
|
);
|
|
20236
20872
|
process.exit(1);
|
|
20237
20873
|
}
|
|
20238
|
-
const destDir =
|
|
20874
|
+
const destDir = join15(homedir8(), "Applications");
|
|
20239
20875
|
mkdirSync13(destDir, { recursive: true });
|
|
20240
20876
|
const dest = installedAppPath();
|
|
20241
20877
|
if (await isRunning()) {
|
|
@@ -20274,7 +20910,7 @@ async function uninstallMenubar() {
|
|
|
20274
20910
|
await new Promise((r) => setTimeout(r, 300));
|
|
20275
20911
|
}
|
|
20276
20912
|
const dest = installedAppPath();
|
|
20277
|
-
if (
|
|
20913
|
+
if (existsSync23(dest)) {
|
|
20278
20914
|
rmSync2(dest, { recursive: true, force: true });
|
|
20279
20915
|
console.log(`Removed ${dest}`);
|
|
20280
20916
|
} else {
|
|
@@ -20289,7 +20925,7 @@ async function openMenubar() {
|
|
|
20289
20925
|
return;
|
|
20290
20926
|
}
|
|
20291
20927
|
const dest = installedAppPath();
|
|
20292
|
-
if (!
|
|
20928
|
+
if (!existsSync23(dest)) {
|
|
20293
20929
|
console.log("Widget not installed yet. Run `fleetlens menubar install` first.");
|
|
20294
20930
|
return;
|
|
20295
20931
|
}
|
|
@@ -20306,15 +20942,15 @@ async function statusMenubar() {
|
|
|
20306
20942
|
return;
|
|
20307
20943
|
}
|
|
20308
20944
|
const dest = installedAppPath();
|
|
20309
|
-
const installed =
|
|
20945
|
+
const installed = existsSync23(dest);
|
|
20310
20946
|
const running = await isRunning();
|
|
20311
|
-
const bundled =
|
|
20947
|
+
const bundled = existsSync23(bundledAppPath());
|
|
20312
20948
|
console.log(`Menu bar widget: ${installed ? "installed" : "not installed"}${installed ? ` (${dest})` : ""}`);
|
|
20313
20949
|
console.log(`Running: ${running ? "yes" : "no"}`);
|
|
20314
20950
|
console.log(`Bundled in CLI: ${bundled ? "yes" : "no \u2014 this build ships without the widget"}`);
|
|
20315
20951
|
if (installed) {
|
|
20316
20952
|
try {
|
|
20317
|
-
const apps =
|
|
20953
|
+
const apps = readdirSync5(join15(homedir8(), "Applications"));
|
|
20318
20954
|
const ours = apps.find((a) => a === APP_BUNDLE);
|
|
20319
20955
|
console.log(`App bundle: ${ours ? "present in ~/Applications" : "missing"}`);
|
|
20320
20956
|
} catch {
|
|
@@ -20399,8 +21035,8 @@ var init_config = __esm({
|
|
|
20399
21035
|
});
|
|
20400
21036
|
|
|
20401
21037
|
// src/perception/build-entries.ts
|
|
20402
|
-
import { statSync as
|
|
20403
|
-
import { basename as
|
|
21038
|
+
import { statSync as statSync5, readFileSync as readFileSync23 } from "node:fs";
|
|
21039
|
+
import { basename as basename3, dirname as dirname15 } from "node:path";
|
|
20404
21040
|
function decodeProjectDirName(projectDir) {
|
|
20405
21041
|
if (projectDir.startsWith("-")) {
|
|
20406
21042
|
return "/" + projectDir.slice(1).replace(/-/g, "/");
|
|
@@ -20408,8 +21044,8 @@ function decodeProjectDirName(projectDir) {
|
|
|
20408
21044
|
return projectDir.replace(/-/g, "/");
|
|
20409
21045
|
}
|
|
20410
21046
|
function buildEntriesForFile(filePath) {
|
|
20411
|
-
const stat =
|
|
20412
|
-
const raw =
|
|
21047
|
+
const stat = statSync5(filePath);
|
|
21048
|
+
const raw = readFileSync23(filePath, "utf8");
|
|
20413
21049
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
20414
21050
|
try {
|
|
20415
21051
|
return JSON.parse(l);
|
|
@@ -20419,8 +21055,8 @@ function buildEntriesForFile(filePath) {
|
|
|
20419
21055
|
}).filter((x) => x !== null);
|
|
20420
21056
|
if (rawLines.length === 0) return null;
|
|
20421
21057
|
const { meta, events } = parseTranscript(rawLines);
|
|
20422
|
-
const fileName =
|
|
20423
|
-
const projectDir =
|
|
21058
|
+
const fileName = basename3(filePath);
|
|
21059
|
+
const projectDir = basename3(dirname15(filePath));
|
|
20424
21060
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
20425
21061
|
const sd = {
|
|
20426
21062
|
...meta,
|
|
@@ -20678,7 +21314,7 @@ function buildIngestPayload(inputs) {
|
|
|
20678
21314
|
return {
|
|
20679
21315
|
ingestId: randomUUID2(),
|
|
20680
21316
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20681
|
-
cliVersion: "1.0.
|
|
21317
|
+
cliVersion: "1.0.15",
|
|
20682
21318
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
20683
21319
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
20684
21320
|
...richRollup ? { richRollup } : {},
|
|
@@ -20720,8 +21356,8 @@ var init_push = __esm({
|
|
|
20720
21356
|
});
|
|
20721
21357
|
|
|
20722
21358
|
// src/team/git-remote.ts
|
|
20723
|
-
import { existsSync as
|
|
20724
|
-
import { dirname as dirname16, isAbsolute as isAbsolute2, join as
|
|
21359
|
+
import { existsSync as existsSync24, readFileSync as readFileSync24, statSync as statSync6 } from "node:fs";
|
|
21360
|
+
import { dirname as dirname16, isAbsolute as isAbsolute2, join as join16, resolve as resolve3 } from "node:path";
|
|
20725
21361
|
function parseGithubRemote(url) {
|
|
20726
21362
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
20727
21363
|
return m ? `${m[1]}/${m[2]}`.toLowerCase() : null;
|
|
@@ -20741,19 +21377,19 @@ function originUrl2(configText) {
|
|
|
20741
21377
|
return null;
|
|
20742
21378
|
}
|
|
20743
21379
|
function gitConfigPathFor(dir) {
|
|
20744
|
-
const dotGit =
|
|
20745
|
-
const st =
|
|
21380
|
+
const dotGit = join16(dir, ".git");
|
|
21381
|
+
const st = statSync6(dotGit, { throwIfNoEntry: false });
|
|
20746
21382
|
if (!st) return null;
|
|
20747
|
-
if (st.isDirectory()) return
|
|
20748
|
-
const m =
|
|
21383
|
+
if (st.isDirectory()) return join16(dotGit, "config");
|
|
21384
|
+
const m = readFileSync24(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
20749
21385
|
if (!m) return null;
|
|
20750
|
-
const gd = isAbsolute2(m[1]) ? m[1] :
|
|
20751
|
-
const commondirFile =
|
|
20752
|
-
if (
|
|
20753
|
-
const common =
|
|
20754
|
-
return
|
|
21386
|
+
const gd = isAbsolute2(m[1]) ? m[1] : resolve3(dir, m[1]);
|
|
21387
|
+
const commondirFile = join16(gd, "commondir");
|
|
21388
|
+
if (existsSync24(commondirFile)) {
|
|
21389
|
+
const common = readFileSync24(commondirFile, "utf8").trim();
|
|
21390
|
+
return join16(isAbsolute2(common) ? common : resolve3(gd, common), "config");
|
|
20755
21391
|
}
|
|
20756
|
-
return
|
|
21392
|
+
return join16(gd, "config");
|
|
20757
21393
|
}
|
|
20758
21394
|
function createRepoResolver() {
|
|
20759
21395
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -20765,8 +21401,8 @@ function createRepoResolver() {
|
|
|
20765
21401
|
try {
|
|
20766
21402
|
for (let d = dir; ; d = dirname16(d)) {
|
|
20767
21403
|
const config = gitConfigPathFor(d);
|
|
20768
|
-
if (config &&
|
|
20769
|
-
const url = originUrl2(
|
|
21404
|
+
if (config && existsSync24(config)) {
|
|
21405
|
+
const url = originUrl2(readFileSync24(config, "utf8"));
|
|
20770
21406
|
repo = url ? parseGithubRemote(url) : null;
|
|
20771
21407
|
break;
|
|
20772
21408
|
}
|
|
@@ -20788,14 +21424,14 @@ var init_git_remote = __esm({
|
|
|
20788
21424
|
});
|
|
20789
21425
|
|
|
20790
21426
|
// src/team/queue.ts
|
|
20791
|
-
import { readFileSync as
|
|
21427
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync15, appendFileSync as appendFileSync5, statSync as statSync7, mkdirSync as mkdirSync14 } from "node:fs";
|
|
20792
21428
|
import { dirname as dirname17 } from "node:path";
|
|
20793
21429
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
20794
21430
|
mkdirSync14(dirname17(queuePath), { recursive: true });
|
|
20795
21431
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
20796
21432
|
appendFileSync5(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
20797
21433
|
try {
|
|
20798
|
-
const { size } =
|
|
21434
|
+
const { size } = statSync7(queuePath);
|
|
20799
21435
|
if (size > MAX_SIZE_BYTES) {
|
|
20800
21436
|
pruneOldest(queuePath);
|
|
20801
21437
|
}
|
|
@@ -20805,7 +21441,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
20805
21441
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
20806
21442
|
let lines;
|
|
20807
21443
|
try {
|
|
20808
|
-
lines =
|
|
21444
|
+
lines = readFileSync25(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
20809
21445
|
} catch {
|
|
20810
21446
|
return [];
|
|
20811
21447
|
}
|
|
@@ -20826,7 +21462,7 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
20826
21462
|
function pruneOldest(queuePath) {
|
|
20827
21463
|
let lines;
|
|
20828
21464
|
try {
|
|
20829
|
-
lines =
|
|
21465
|
+
lines = readFileSync25(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
20830
21466
|
} catch {
|
|
20831
21467
|
return;
|
|
20832
21468
|
}
|
|
@@ -20845,7 +21481,7 @@ var init_queue2 = __esm({
|
|
|
20845
21481
|
});
|
|
20846
21482
|
|
|
20847
21483
|
// src/usage/profile.ts
|
|
20848
|
-
import { existsSync as
|
|
21484
|
+
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync26, writeFileSync as writeFileSync16 } from "node:fs";
|
|
20849
21485
|
import { dirname as dirname18 } from "node:path";
|
|
20850
21486
|
function mapRateLimitTier(rateLimitTier) {
|
|
20851
21487
|
switch (rateLimitTier) {
|
|
@@ -20886,9 +21522,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
20886
21522
|
};
|
|
20887
21523
|
}
|
|
20888
21524
|
function readCachedProfile(cachePath) {
|
|
20889
|
-
if (!
|
|
21525
|
+
if (!existsSync25(cachePath)) return null;
|
|
20890
21526
|
try {
|
|
20891
|
-
const raw = JSON.parse(
|
|
21527
|
+
const raw = JSON.parse(readFileSync26(cachePath, "utf8"));
|
|
20892
21528
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
20893
21529
|
return raw;
|
|
20894
21530
|
} catch {
|
|
@@ -21077,11 +21713,11 @@ var init_backfill = __esm({
|
|
|
21077
21713
|
});
|
|
21078
21714
|
|
|
21079
21715
|
// src/team/sync-log.ts
|
|
21080
|
-
import { readFileSync as
|
|
21716
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
21081
21717
|
function readPendingSyncLog(watermark) {
|
|
21082
21718
|
let raw;
|
|
21083
21719
|
try {
|
|
21084
|
-
raw =
|
|
21720
|
+
raw = readFileSync27(cclensPath("daemon.log"), "utf8");
|
|
21085
21721
|
} catch {
|
|
21086
21722
|
return { lines: [] };
|
|
21087
21723
|
}
|
|
@@ -21110,11 +21746,11 @@ var init_sync_log = __esm({
|
|
|
21110
21746
|
|
|
21111
21747
|
// src/team/last-push.ts
|
|
21112
21748
|
import { writeFileSync as writeFileSync17, unlinkSync as unlinkSync6, mkdirSync as mkdirSync16 } from "node:fs";
|
|
21113
|
-
import { join as
|
|
21749
|
+
import { join as join17 } from "node:path";
|
|
21114
21750
|
function write(record, dir) {
|
|
21115
21751
|
const d = dir ?? cclensHome();
|
|
21116
21752
|
mkdirSync16(d, { recursive: true });
|
|
21117
|
-
writeFileSync17(
|
|
21753
|
+
writeFileSync17(join17(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
21118
21754
|
}
|
|
21119
21755
|
function writeLastPushSuccess(payload, dir) {
|
|
21120
21756
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -21125,7 +21761,7 @@ function writeLastPushFailure(payload, error, dir) {
|
|
|
21125
21761
|
function clearLastPush(dir) {
|
|
21126
21762
|
const d = dir ?? cclensHome();
|
|
21127
21763
|
try {
|
|
21128
|
-
unlinkSync6(
|
|
21764
|
+
unlinkSync6(join17(d, LAST_PUSH_FILE));
|
|
21129
21765
|
} catch {
|
|
21130
21766
|
}
|
|
21131
21767
|
}
|
|
@@ -21144,39 +21780,39 @@ __export(file_probe_exports, {
|
|
|
21144
21780
|
pathHash: () => pathHash,
|
|
21145
21781
|
probeArtifactSignals: () => probeArtifactSignals
|
|
21146
21782
|
});
|
|
21147
|
-
import { createHash } from "node:crypto";
|
|
21148
|
-
import { existsSync as
|
|
21149
|
-
import { homedir as
|
|
21150
|
-
import { join as
|
|
21783
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
21784
|
+
import { existsSync as existsSync26, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
|
|
21785
|
+
import { homedir as homedir9 } from "node:os";
|
|
21786
|
+
import { join as join18, relative, resolve as resolve4, sep } from "node:path";
|
|
21151
21787
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
21152
21788
|
function pathHash(relPath) {
|
|
21153
|
-
return
|
|
21789
|
+
return createHash2("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
21154
21790
|
}
|
|
21155
21791
|
function defaultScanRoots(extraRoots = []) {
|
|
21156
21792
|
const roots = [];
|
|
21157
|
-
const home =
|
|
21158
|
-
if (
|
|
21793
|
+
const home = join18(homedir9(), ".claude");
|
|
21794
|
+
if (existsSync26(home)) roots.push({ root: home, label: "user" });
|
|
21159
21795
|
for (const e of extraRoots) {
|
|
21160
|
-
const r =
|
|
21161
|
-
if (
|
|
21796
|
+
const r = resolve4(e, ".claude");
|
|
21797
|
+
if (existsSync26(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
21162
21798
|
}
|
|
21163
21799
|
return roots;
|
|
21164
21800
|
}
|
|
21165
21801
|
function listMarkdownFiles(dir) {
|
|
21166
|
-
if (!
|
|
21802
|
+
if (!existsSync26(dir)) return [];
|
|
21167
21803
|
const out = [];
|
|
21168
21804
|
let entries2;
|
|
21169
21805
|
try {
|
|
21170
|
-
entries2 =
|
|
21806
|
+
entries2 = readdirSync6(dir);
|
|
21171
21807
|
} catch {
|
|
21172
21808
|
return [];
|
|
21173
21809
|
}
|
|
21174
21810
|
for (const name of entries2) {
|
|
21175
21811
|
if (name.startsWith(".")) continue;
|
|
21176
|
-
const full =
|
|
21812
|
+
const full = join18(dir, name);
|
|
21177
21813
|
let stat;
|
|
21178
21814
|
try {
|
|
21179
|
-
stat =
|
|
21815
|
+
stat = statSync8(full);
|
|
21180
21816
|
} catch {
|
|
21181
21817
|
continue;
|
|
21182
21818
|
}
|
|
@@ -21199,7 +21835,7 @@ function firstSeenDateOf(file) {
|
|
|
21199
21835
|
} catch {
|
|
21200
21836
|
}
|
|
21201
21837
|
try {
|
|
21202
|
-
const s =
|
|
21838
|
+
const s = statSync8(file);
|
|
21203
21839
|
return localDay(s.birthtime || s.mtime);
|
|
21204
21840
|
} catch {
|
|
21205
21841
|
return todayLocal();
|
|
@@ -21232,8 +21868,8 @@ function todayLocal() {
|
|
|
21232
21868
|
function scanAuthored(roots, subdir, day2) {
|
|
21233
21869
|
const out = [];
|
|
21234
21870
|
for (const r of roots) {
|
|
21235
|
-
const dir =
|
|
21236
|
-
if (!
|
|
21871
|
+
const dir = join18(r.root, subdir);
|
|
21872
|
+
if (!existsSync26(dir)) continue;
|
|
21237
21873
|
for (const f of listMarkdownFiles(dir)) {
|
|
21238
21874
|
const firstSeen = firstSeenDateOf(f);
|
|
21239
21875
|
if (firstSeen !== day2) continue;
|
|
@@ -21246,14 +21882,14 @@ function scanAuthored(roots, subdir, day2) {
|
|
|
21246
21882
|
function scanEdited(roots, day2) {
|
|
21247
21883
|
const out = [];
|
|
21248
21884
|
for (const r of roots) {
|
|
21249
|
-
const dir =
|
|
21250
|
-
if (!
|
|
21885
|
+
const dir = join18(r.root, "skills");
|
|
21886
|
+
if (!existsSync26(dir)) continue;
|
|
21251
21887
|
for (const f of listMarkdownFiles(dir)) {
|
|
21252
21888
|
const firstSeen = firstSeenDateOf(f);
|
|
21253
21889
|
if (firstSeen === day2) continue;
|
|
21254
21890
|
let stat;
|
|
21255
21891
|
try {
|
|
21256
|
-
stat =
|
|
21892
|
+
stat = statSync8(f);
|
|
21257
21893
|
} catch {
|
|
21258
21894
|
continue;
|
|
21259
21895
|
}
|
|
@@ -21269,11 +21905,11 @@ function claudemdLineDelta(extraRoots, authorEmail, day2) {
|
|
|
21269
21905
|
let delta = 0;
|
|
21270
21906
|
const candidates = [];
|
|
21271
21907
|
for (const e of extraRoots) {
|
|
21272
|
-
const f =
|
|
21273
|
-
if (
|
|
21908
|
+
const f = resolve4(e, "CLAUDE.md");
|
|
21909
|
+
if (existsSync26(f)) candidates.push(f);
|
|
21274
21910
|
}
|
|
21275
|
-
const homeClaudeMd =
|
|
21276
|
-
if (
|
|
21911
|
+
const homeClaudeMd = join18(homedir9(), "CLAUDE.md");
|
|
21912
|
+
if (existsSync26(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
21277
21913
|
for (const file of candidates) {
|
|
21278
21914
|
try {
|
|
21279
21915
|
const out = execFileSync3(
|
|
@@ -22163,11 +22799,11 @@ var logs_exports = {};
|
|
|
22163
22799
|
__export(logs_exports, {
|
|
22164
22800
|
teamLogs: () => teamLogs
|
|
22165
22801
|
});
|
|
22166
|
-
import { readFileSync as
|
|
22802
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
22167
22803
|
async function teamLogs() {
|
|
22168
22804
|
const logPath = cclensPath("daemon.log");
|
|
22169
22805
|
try {
|
|
22170
|
-
const lines =
|
|
22806
|
+
const lines = readFileSync28(logPath, "utf8").trim().split("\n");
|
|
22171
22807
|
const teamLines = lines.filter((l) => l.includes("[sync] ") || l.includes("team "));
|
|
22172
22808
|
if (teamLines.length === 0) {
|
|
22173
22809
|
console.log("No team-related log entries found.");
|
|
@@ -22295,8 +22931,8 @@ __export(runs_exports, {
|
|
|
22295
22931
|
runs: () => runs
|
|
22296
22932
|
});
|
|
22297
22933
|
import { execSync as execSync2 } from "node:child_process";
|
|
22298
|
-
import { existsSync as
|
|
22299
|
-
import { join as
|
|
22934
|
+
import { existsSync as existsSync27, readFileSync as readFileSync29, readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
|
|
22935
|
+
import { join as join19 } from "node:path";
|
|
22300
22936
|
async function runs(args2) {
|
|
22301
22937
|
const json = args2.includes("--json");
|
|
22302
22938
|
const watch = args2.includes("--watch");
|
|
@@ -22380,8 +23016,8 @@ function listActiveRuns() {
|
|
|
22380
23016
|
return runs2.sort((a, b) => a.elapsed_s - b.elapsed_s);
|
|
22381
23017
|
}
|
|
22382
23018
|
function readSpend(sinceMs) {
|
|
22383
|
-
if (!
|
|
22384
|
-
const lines =
|
|
23019
|
+
if (!existsSync27(SPEND_PATH)) return [];
|
|
23020
|
+
const lines = readFileSync29(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
|
|
22385
23021
|
const out = [];
|
|
22386
23022
|
for (const line of lines) {
|
|
22387
23023
|
try {
|
|
@@ -22502,23 +23138,23 @@ function ageLabel(ms) {
|
|
|
22502
23138
|
return `${Math.floor(ms / 864e5)}d`;
|
|
22503
23139
|
}
|
|
22504
23140
|
function listTraceFiles() {
|
|
22505
|
-
if (!
|
|
22506
|
-
const entries2 =
|
|
23141
|
+
if (!existsSync27(RUNS_DIR2)) return [];
|
|
23142
|
+
const entries2 = readdirSync7(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
|
|
22507
23143
|
return entries2.map((f) => {
|
|
22508
|
-
const
|
|
22509
|
-
const st =
|
|
22510
|
-
return { runId: f.replace(/\.jsonl$/, ""), path:
|
|
23144
|
+
const path12 = join19(RUNS_DIR2, f);
|
|
23145
|
+
const st = statSync9(path12);
|
|
23146
|
+
return { runId: f.replace(/\.jsonl$/, ""), path: path12, mtimeMs: st.mtimeMs };
|
|
22511
23147
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
22512
23148
|
}
|
|
22513
23149
|
function resolveRunId(arg) {
|
|
22514
|
-
if (!
|
|
23150
|
+
if (!existsSync27(RUNS_DIR2)) return null;
|
|
22515
23151
|
if (arg === "latest") {
|
|
22516
23152
|
const all2 = listTraceFiles();
|
|
22517
23153
|
if (all2.length === 0) return null;
|
|
22518
23154
|
return { runId: all2[0].runId, path: all2[0].path };
|
|
22519
23155
|
}
|
|
22520
|
-
const exact =
|
|
22521
|
-
if (
|
|
23156
|
+
const exact = join19(RUNS_DIR2, `${arg}.jsonl`);
|
|
23157
|
+
if (existsSync27(exact)) return { runId: arg, path: exact };
|
|
22522
23158
|
const all = listTraceFiles();
|
|
22523
23159
|
const matches = all.filter((r) => r.runId.includes(arg));
|
|
22524
23160
|
if (matches.length === 1) return { runId: matches[0].runId, path: matches[0].path };
|
|
@@ -22529,8 +23165,8 @@ function resolveRunId(arg) {
|
|
|
22529
23165
|
}
|
|
22530
23166
|
return null;
|
|
22531
23167
|
}
|
|
22532
|
-
function readTrace(
|
|
22533
|
-
return
|
|
23168
|
+
function readTrace(path12) {
|
|
23169
|
+
return readFileSync29(path12, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
|
|
22534
23170
|
try {
|
|
22535
23171
|
return JSON.parse(l);
|
|
22536
23172
|
} catch {
|
|
@@ -22542,7 +23178,7 @@ async function inspect(arg, follow, json) {
|
|
|
22542
23178
|
const r = resolveRunId(arg);
|
|
22543
23179
|
if (!r) {
|
|
22544
23180
|
console.error(`run not found: ${arg}`);
|
|
22545
|
-
if (
|
|
23181
|
+
if (existsSync27(RUNS_DIR2)) {
|
|
22546
23182
|
const all = listTraceFiles().slice(0, 5);
|
|
22547
23183
|
if (all.length > 0) {
|
|
22548
23184
|
console.error(`
|
|
@@ -22562,13 +23198,13 @@ recent runs:`);
|
|
|
22562
23198
|
const events = readTrace(r.path);
|
|
22563
23199
|
printTrace(r.runId, events);
|
|
22564
23200
|
if (!follow) return;
|
|
22565
|
-
let lastSize =
|
|
23201
|
+
let lastSize = statSync9(r.path).size;
|
|
22566
23202
|
let lastIdx = events.length;
|
|
22567
23203
|
console.log("\n \u27F6 following \xB7 ^C to quit\n");
|
|
22568
23204
|
process.on("SIGINT", () => process.exit(0));
|
|
22569
23205
|
while (true) {
|
|
22570
23206
|
await new Promise((res) => setTimeout(res, 500));
|
|
22571
|
-
const st =
|
|
23207
|
+
const st = statSync9(r.path);
|
|
22572
23208
|
if (st.size === lastSize) continue;
|
|
22573
23209
|
lastSize = st.size;
|
|
22574
23210
|
const all = readTrace(r.path);
|
|
@@ -22722,7 +23358,7 @@ async function main() {
|
|
|
22722
23358
|
case "version":
|
|
22723
23359
|
case "--version":
|
|
22724
23360
|
case "-v":
|
|
22725
|
-
console.log(`fleetlens ${"1.0.
|
|
23361
|
+
console.log(`fleetlens ${"1.0.15"}`);
|
|
22726
23362
|
break;
|
|
22727
23363
|
case "help":
|
|
22728
23364
|
case "--help":
|