fleetlens 0.15.2 → 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/apps/web/.next/BUILD_ID +1 -1
- package/app/apps/web/.next/app-path-routes-manifest.json +3 -0
- package/app/apps/web/.next/build-manifest.json +3 -3
- package/app/apps/web/.next/prerender-manifest.json +3 -3
- package/app/apps/web/.next/routes-manifest.json +18 -0
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/apps/web/.next/server/app/_not-found/page.js +1 -1
- package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/menubar/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/menubar/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/menubar/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/menubar/route.js +6 -0
- package/app/apps/web/.next/server/app/api/menubar/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/menubar/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/menubar/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/pdf/[key]/route.js +1 -1
- package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/projects/open-folder/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/projects/open-folder/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/projects/open-folder/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/projects/open-folder/route.js +7 -0
- package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/projects/open-folder/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/credentials/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route/server-reference-manifest.json +4 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js +10 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js.map +5 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/api/settings/credentials/route_client-reference-manifest.js +3 -0
- package/app/apps/web/.next/server/app/api/settings/route.js +4 -4
- package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js +1 -1
- package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js +1 -1
- package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js +1 -1
- package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/insights/page.js +1 -1
- package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/page.js +1 -1
- package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
- package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page.js +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -2
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js +1 -1
- package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page.js +1 -1
- package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/settings/page.js +2 -2
- package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page.js +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js +1 -1
- package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js +1 -1
- package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_projects_open-folder_route_actions_0m~419c.js +3 -0
- package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_settings_credentials_route_actions_04an_i2.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__05z0pcw._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_nle98._.js +3 -0
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__0b5r~-1._.js +3 -0
- package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0a0~7d6._.js → [root-of-the-server]__0t7i-hy._.js} +2 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__12iid50._.js +3 -0
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_menubar_route_actions_0xep8_i.js +3 -0
- package/app/apps/web/.next/server/chunks/{node_modules_next_036my~r._.js → node_modules_next_04~_e52._.js} +5 -5
- package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +14 -14
- package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0.zquoa._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__03svi~4._.js +8 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__04eq6z2._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__04il6m2._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__08l86e-._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__09rjz7_._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ar_8wr._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__10~b4bf._.js → [root-of-the-server]__0blm9gz._.js} +3 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0e.gxk3._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0g-tomj._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0i.q-1h._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0k1x-c9._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0lz4a~g._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0nr2~y1._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0o1_g.~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0p1x6v2._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0rvzdnx._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0stu~~r._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0tejjy_._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0u39afl._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ufi3.w._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0xy1qim._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0~.f_3z._.js +3 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__10srpu0._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__10xgshr._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_02r-a1a._.js +8 -0
- package/app/apps/web/.next/server/chunks/ssr/_0k62ejd._.js +8 -0
- package/app/apps/web/.next/server/chunks/ssr/{_0xu2pvc._.js → _0k8yioi._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{_0wj750k._.js → _0t~mx7w._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{_0kajk31._.js → _0whg~r-._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/_13jdm1g._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0~aj0~u._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_sessions-grid_tsx_0bri5x.._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0x014hn._.js +16 -0
- 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/node_modules_lucide-react_dist_esm_icons_12vc-v-._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
- package/app/apps/web/.next/server/functions-config-manifest.json +3 -0
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/0-z49mtd-zwgv.js +1 -0
- package/app/apps/web/.next/static/chunks/043slkg3juwck.js +1 -0
- package/app/apps/web/.next/static/chunks/{0~qdw1b2uz._5.js → 044mtrzh7d7va.js} +3 -3
- package/app/apps/web/.next/static/chunks/05b0dn.r00hq1.js +1 -0
- package/app/apps/web/.next/static/chunks/{14vx702c32kn6.js → 0_0~~ipv90vm3.js} +1 -1
- package/app/apps/web/.next/static/chunks/0awkd5df28gvj.js +6 -0
- package/app/apps/web/.next/static/chunks/{0m7dd-2zd9vl2.js → 0eoc4yy0s0gpe.js} +1 -1
- package/app/apps/web/.next/static/chunks/0g0hv.dt-de9g.js +14 -0
- package/app/apps/web/.next/static/chunks/0rsp61c8wb.sx.js +6 -0
- package/app/apps/web/.next/static/chunks/{03rd.3cc_t~yf.js → 0s~0-8l~_kqnf.js} +1 -1
- package/app/apps/web/.next/static/chunks/0t2on1dhydyb2.css +1 -0
- package/app/apps/web/.next/static/chunks/0y3448zrint0k.js +6 -0
- package/app/apps/web/app/api/menubar/route.ts +66 -0
- package/app/apps/web/app/api/projects/open-folder/route.ts +60 -0
- package/app/apps/web/app/api/settings/credentials/route.ts +45 -0
- package/app/apps/web/app/layout.tsx +2 -0
- package/app/apps/web/app/projects/[slug]/local-folders-button.tsx +406 -0
- package/app/apps/web/app/projects/[slug]/page.tsx +155 -20
- package/app/apps/web/app/projects/page.tsx +2 -2
- package/app/apps/web/app/sessions/[id]/page.tsx +4 -1
- package/app/apps/web/app/sessions/[id]/session-view/header-stats.tsx +81 -0
- package/app/apps/web/app/sessions/[id]/session-view.tsx +11 -0
- package/app/apps/web/app/sessions/sessions-grid.tsx +56 -25
- package/app/apps/web/app/settings/page.tsx +26 -0
- package/app/apps/web/app/usage/page.tsx +80 -0
- package/app/apps/web/components/menubar-install-banner.tsx +117 -0
- package/app/apps/web/components/menubar-install.tsx +107 -0
- package/app/apps/web/components/zai-credentials-form.tsx +116 -0
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/entries-index.ts +4 -4
- package/app/apps/web/lib/menubar-data.ts +50 -0
- package/app/apps/web/lib/usage-data.ts +4 -0
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +640 -240
- package/dist/index.js +938 -283
- package/package.json +3 -2
- package/app/apps/web/.next/server/chunks/[root-of-the-server]__065lib8._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0a7n44-._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0c00i76._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0lhwp-k._.js +0 -8
- package/app/apps/web/.next/server/chunks/ssr/_0s3n5mz._.js +0 -8
- package/app/apps/web/.next/server/chunks/ssr/_12mbgs5._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0q2x4a~._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0b-4-4j._.js +0 -8
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +0 -16
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0cepfi8._.js +0 -3
- package/app/apps/web/.next/static/chunks/00a9oyw~h5i1p.js +0 -1
- package/app/apps/web/.next/static/chunks/03gy1evbn94qu.js +0 -6
- package/app/apps/web/.next/static/chunks/040s42ypidk7s.css +0 -1
- package/app/apps/web/.next/static/chunks/0d2x-wfu.m0-z.js +0 -6
- package/app/apps/web/.next/static/chunks/0i77er85v.rj..js +0 -1
- package/app/apps/web/.next/static/chunks/0nqklmbs5s3ax.js +0 -6
- package/app/apps/web/.next/static/chunks/0tirv_vo6q8uc.js +0 -1
- package/app/apps/web/.next/static/chunks/0u6gxpqhl0gc7.js +0 -14
- /package/app/apps/web/.next/static/{mTj8nKiazosAKJec15dLe → nmAGY0LiBgXuibWTKZ1RD}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{mTj8nKiazosAKJec15dLe → nmAGY0LiBgXuibWTKZ1RD}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{mTj8nKiazosAKJec15dLe → nmAGY0LiBgXuibWTKZ1RD}/_ssgManifest.js +0 -0
package/dist/daemon-worker.js
CHANGED
|
@@ -8,40 +8,6 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
// src/usage/storage.ts
|
|
12
|
-
import { appendFileSync, mkdirSync, readFileSync as readFileSync2, existsSync } from "node:fs";
|
|
13
|
-
import { dirname } from "node:path";
|
|
14
|
-
function appendSnapshot(filePath, snapshot) {
|
|
15
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
16
|
-
appendFileSync(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
17
|
-
}
|
|
18
|
-
function readSnapshots(filePath) {
|
|
19
|
-
if (!existsSync(filePath)) return [];
|
|
20
|
-
const content = readFileSync2(filePath, "utf8");
|
|
21
|
-
const snapshots = [];
|
|
22
|
-
for (const line of content.split("\n")) {
|
|
23
|
-
if (!line.trim()) continue;
|
|
24
|
-
try {
|
|
25
|
-
snapshots.push(JSON.parse(line));
|
|
26
|
-
} catch {
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return snapshots;
|
|
30
|
-
}
|
|
31
|
-
function latestClaudeCodeSnapshot(filePath) {
|
|
32
|
-
const all = readSnapshots(filePath);
|
|
33
|
-
for (let i = all.length - 1; i >= 0; i--) {
|
|
34
|
-
const s = all[i];
|
|
35
|
-
if (!s.agent || s.agent === "claude-code") return s;
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
var init_storage = __esm({
|
|
40
|
-
"src/usage/storage.ts"() {
|
|
41
|
-
"use strict";
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
11
|
// ../parser/dist/analytics.js
|
|
46
12
|
function toLocalDay(ms) {
|
|
47
13
|
const d = new Date(ms);
|
|
@@ -114,11 +80,22 @@ function worktreeName(projectName) {
|
|
|
114
80
|
return ss.workspaceName;
|
|
115
81
|
return null;
|
|
116
82
|
}
|
|
117
|
-
function
|
|
83
|
+
function projectKey(projectName) {
|
|
118
84
|
const canonical = canonicalProjectName(projectName);
|
|
119
85
|
const segs = canonical.replace(/\/+$/, "").split("/").filter(Boolean);
|
|
120
86
|
return segs[segs.length - 1] || canonical;
|
|
121
87
|
}
|
|
88
|
+
function sessionProjectKey(s) {
|
|
89
|
+
return s.repoName ?? projectKey(s.projectName);
|
|
90
|
+
}
|
|
91
|
+
function buildProjectKeyResolver(sessions) {
|
|
92
|
+
const alias = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const s of sessions) {
|
|
94
|
+
if (s.repoName)
|
|
95
|
+
alias.set(projectKey(s.projectName), s.repoName);
|
|
96
|
+
}
|
|
97
|
+
return (s) => s.repoName ?? alias.get(projectKey(s.projectName)) ?? projectKey(s.projectName);
|
|
98
|
+
}
|
|
122
99
|
function makeDay(date) {
|
|
123
100
|
return {
|
|
124
101
|
date,
|
|
@@ -553,8 +530,9 @@ function summarizeBursts(bursts) {
|
|
|
553
530
|
}
|
|
554
531
|
function groupByProject(sessions) {
|
|
555
532
|
const map = /* @__PURE__ */ new Map();
|
|
533
|
+
const keyOf = buildProjectKeyResolver(sessions);
|
|
556
534
|
for (const s of sessions) {
|
|
557
|
-
const repo =
|
|
535
|
+
const repo = keyOf(s);
|
|
558
536
|
const key = repo;
|
|
559
537
|
let cur = map.get(key);
|
|
560
538
|
if (!cur) {
|
|
@@ -583,7 +561,7 @@ function groupByProject(sessions) {
|
|
|
583
561
|
p.metrics = highLevelMetrics(p.sessions);
|
|
584
562
|
const wtNames = /* @__PURE__ */ new Set();
|
|
585
563
|
for (const s of p.sessions) {
|
|
586
|
-
const wt = worktreeName(s.projectName);
|
|
564
|
+
const wt = s.worktreeName ?? worktreeName(s.projectName) ?? (s.cwd ? worktreeName(s.cwd) : null);
|
|
587
565
|
if (wt)
|
|
588
566
|
wtNames.add(wt);
|
|
589
567
|
}
|
|
@@ -602,7 +580,7 @@ function groupByProject(sessions) {
|
|
|
602
580
|
}
|
|
603
581
|
return Array.from(map.values()).sort((a, b) => (b.lastActiveMs ?? 0) - (a.lastActiveMs ?? 0));
|
|
604
582
|
}
|
|
605
|
-
var BLANK_USAGE, WORKTREE_MARKERS, CONDUCTOR_RE, SUPERSET_MARKER, UUID_SEG_RE, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
|
|
583
|
+
var BLANK_USAGE, WORKTREE_MARKERS, CONDUCTOR_RE, SUPERSET_MARKER, UUID_SEG_RE, projectRepoName, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
|
|
606
584
|
var init_analytics = __esm({
|
|
607
585
|
"../parser/dist/analytics.js"() {
|
|
608
586
|
"use strict";
|
|
@@ -615,6 +593,7 @@ var init_analytics = __esm({
|
|
|
615
593
|
CONDUCTOR_RE = /\/conductor\/workspaces\/[^/]+\/([^/]+)(?:\/|$)/;
|
|
616
594
|
SUPERSET_MARKER = "/.superset/worktrees/";
|
|
617
595
|
UUID_SEG_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
596
|
+
projectRepoName = projectKey;
|
|
618
597
|
PR_CREATE_RE = /gh\s+pr\s+create\b/i;
|
|
619
598
|
PR_NUMBER_RE = /#(\d+)/;
|
|
620
599
|
TITLE_FLAG_RE = /--title\s+["']([^"']+)["']/;
|
|
@@ -628,7 +607,7 @@ function getAgentMetadata(kind) {
|
|
|
628
607
|
function isAgentKind(s) {
|
|
629
608
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
630
609
|
}
|
|
631
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
610
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
632
611
|
var init_agent_metadata = __esm({
|
|
633
612
|
"../parser/dist/agent-metadata.js"() {
|
|
634
613
|
"use strict";
|
|
@@ -667,12 +646,20 @@ var init_agent_metadata = __esm({
|
|
|
667
646
|
accentColor: "rgb(217, 119, 87)",
|
|
668
647
|
iconChar: "\u2318"
|
|
669
648
|
};
|
|
649
|
+
ZAI_METADATA = {
|
|
650
|
+
kind: "zai",
|
|
651
|
+
displayName: "Z.ai",
|
|
652
|
+
shortLabel: "Z.ai",
|
|
653
|
+
accentColor: "rgb(59, 130, 246)",
|
|
654
|
+
iconChar: "Z"
|
|
655
|
+
};
|
|
670
656
|
agentMetadata = [
|
|
671
657
|
CLAUDE_CODE_METADATA,
|
|
672
658
|
CODEX_METADATA,
|
|
673
659
|
GEMINI_METADATA,
|
|
674
660
|
ANTIGRAVITY_METADATA,
|
|
675
|
-
COWORK_METADATA
|
|
661
|
+
COWORK_METADATA,
|
|
662
|
+
ZAI_METADATA
|
|
676
663
|
];
|
|
677
664
|
KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
|
|
678
665
|
}
|
|
@@ -1413,6 +1400,187 @@ var init_parser = __esm({
|
|
|
1413
1400
|
}
|
|
1414
1401
|
});
|
|
1415
1402
|
|
|
1403
|
+
// ../parser/dist/git-project.js
|
|
1404
|
+
import { existsSync, readFileSync as readFileSync2, realpathSync, statSync } from "node:fs";
|
|
1405
|
+
import { homedir as homedir2 } from "node:os";
|
|
1406
|
+
import { basename, dirname, isAbsolute, join as join2, resolve } from "node:path";
|
|
1407
|
+
function resolveGitDir(root, dotGitText) {
|
|
1408
|
+
const m = dotGitText.match(/^gitdir:\s*(.+)\s*$/m);
|
|
1409
|
+
if (!m)
|
|
1410
|
+
return void 0;
|
|
1411
|
+
const gitDir = m[1].trim();
|
|
1412
|
+
return isAbsolute(gitDir) ? gitDir : resolve(root, gitDir);
|
|
1413
|
+
}
|
|
1414
|
+
function resolveCommonDir(gitDir) {
|
|
1415
|
+
const file = join2(gitDir, "commondir");
|
|
1416
|
+
if (!existsSync(file))
|
|
1417
|
+
return void 0;
|
|
1418
|
+
const common = readFileSync2(file, "utf8").trim();
|
|
1419
|
+
if (!common)
|
|
1420
|
+
return void 0;
|
|
1421
|
+
return isAbsolute(common) ? common : resolve(gitDir, common);
|
|
1422
|
+
}
|
|
1423
|
+
function dotGitInfoFor(root) {
|
|
1424
|
+
const dotGit = join2(root, ".git");
|
|
1425
|
+
const st = statSync(dotGit, { throwIfNoEntry: false });
|
|
1426
|
+
if (!st)
|
|
1427
|
+
return null;
|
|
1428
|
+
if (st.isDirectory())
|
|
1429
|
+
return { root, gitDir: dotGit, commonDir: dotGit };
|
|
1430
|
+
const gitDir = resolveGitDir(root, readFileSync2(dotGit, "utf8"));
|
|
1431
|
+
if (!gitDir)
|
|
1432
|
+
return { root };
|
|
1433
|
+
return { root, gitDir, commonDir: resolveCommonDir(gitDir) };
|
|
1434
|
+
}
|
|
1435
|
+
function walkBoundary(start) {
|
|
1436
|
+
const home = realpathOrSelf(homedir2());
|
|
1437
|
+
return start === home || start.startsWith(`${home}/`) ? home : void 0;
|
|
1438
|
+
}
|
|
1439
|
+
function nearestDotGit(start) {
|
|
1440
|
+
if (!start || !isAbsolute(start))
|
|
1441
|
+
return null;
|
|
1442
|
+
const boundary = walkBoundary(start);
|
|
1443
|
+
for (let dir = start.replace(/\/+$/, "") || start; ; dir = dirname(dir)) {
|
|
1444
|
+
if (dir === boundary)
|
|
1445
|
+
return null;
|
|
1446
|
+
const info = dotGitInfoFor(dir);
|
|
1447
|
+
if (info)
|
|
1448
|
+
return info;
|
|
1449
|
+
const parent = dirname(dir);
|
|
1450
|
+
if (parent === dir)
|
|
1451
|
+
return null;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
function originUrl(configText) {
|
|
1455
|
+
let inOrigin = false;
|
|
1456
|
+
for (const line of configText.split("\n")) {
|
|
1457
|
+
const t = line.trim();
|
|
1458
|
+
if (t.startsWith("[")) {
|
|
1459
|
+
inOrigin = /^\[remote\s+"origin"\]/.test(t);
|
|
1460
|
+
continue;
|
|
1461
|
+
}
|
|
1462
|
+
if (!inOrigin)
|
|
1463
|
+
continue;
|
|
1464
|
+
const m = t.match(/^url\s*=\s*(.+)$/);
|
|
1465
|
+
if (m)
|
|
1466
|
+
return m[1].trim();
|
|
1467
|
+
}
|
|
1468
|
+
return void 0;
|
|
1469
|
+
}
|
|
1470
|
+
function parseRemote(url) {
|
|
1471
|
+
const m = url.match(REMOTE_URL_RE);
|
|
1472
|
+
if (!m)
|
|
1473
|
+
return void 0;
|
|
1474
|
+
const host = m[1];
|
|
1475
|
+
const segs = m[2].split("/").filter(Boolean);
|
|
1476
|
+
if (segs.length < 2)
|
|
1477
|
+
return void 0;
|
|
1478
|
+
const name = segs[segs.length - 1];
|
|
1479
|
+
const owner = segs.slice(0, -1).join("/");
|
|
1480
|
+
return { host, owner, name, url, webUrl: `https://${host}/${owner}/${name}` };
|
|
1481
|
+
}
|
|
1482
|
+
function remoteFor(git) {
|
|
1483
|
+
const dir = git.commonDir ?? git.gitDir;
|
|
1484
|
+
if (!dir)
|
|
1485
|
+
return void 0;
|
|
1486
|
+
const config = join2(dir, "config");
|
|
1487
|
+
if (!existsSync(config))
|
|
1488
|
+
return void 0;
|
|
1489
|
+
const url = originUrl(readFileSync2(config, "utf8"));
|
|
1490
|
+
return url ? parseRemote(url) : void 0;
|
|
1491
|
+
}
|
|
1492
|
+
function headBranch(gitDir) {
|
|
1493
|
+
if (!gitDir)
|
|
1494
|
+
return void 0;
|
|
1495
|
+
const head = join2(gitDir, "HEAD");
|
|
1496
|
+
if (!existsSync(head))
|
|
1497
|
+
return void 0;
|
|
1498
|
+
const t = readFileSync2(head, "utf8").trim();
|
|
1499
|
+
const m = t.match(/^ref:\s*refs\/heads\/(.+)$/);
|
|
1500
|
+
return m ? m[1] : `detached @ ${t.slice(0, 7)}`;
|
|
1501
|
+
}
|
|
1502
|
+
function defaultBranch(commonDir) {
|
|
1503
|
+
if (!commonDir)
|
|
1504
|
+
return void 0;
|
|
1505
|
+
const head = join2(commonDir, "refs", "remotes", "origin", "HEAD");
|
|
1506
|
+
if (existsSync(head)) {
|
|
1507
|
+
const m = readFileSync2(head, "utf8").trim().match(/refs\/remotes\/origin\/(.+)$/);
|
|
1508
|
+
if (m)
|
|
1509
|
+
return m[1];
|
|
1510
|
+
}
|
|
1511
|
+
const packed = join2(commonDir, "packed-refs");
|
|
1512
|
+
if (existsSync(packed)) {
|
|
1513
|
+
const m = readFileSync2(packed, "utf8").match(/refs\/remotes\/origin\/(\S+)/);
|
|
1514
|
+
if (m && m[1] !== "HEAD")
|
|
1515
|
+
return m[1];
|
|
1516
|
+
}
|
|
1517
|
+
return void 0;
|
|
1518
|
+
}
|
|
1519
|
+
function readGitFolder(path7) {
|
|
1520
|
+
if (!existsSync(path7))
|
|
1521
|
+
return { exists: false, isWorktree: false };
|
|
1522
|
+
try {
|
|
1523
|
+
const git = nearestDotGit(realpathOrSelf(path7));
|
|
1524
|
+
if (!git)
|
|
1525
|
+
return { exists: true, isWorktree: false };
|
|
1526
|
+
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
1527
|
+
const isWorktree = !!projectRoot && realpathOrSelf(projectRoot) !== realpathOrSelf(git.root);
|
|
1528
|
+
return {
|
|
1529
|
+
exists: true,
|
|
1530
|
+
isWorktree,
|
|
1531
|
+
branch: headBranch(git.gitDir),
|
|
1532
|
+
defaultBranch: defaultBranch(git.commonDir),
|
|
1533
|
+
remote: remoteFor(git)
|
|
1534
|
+
};
|
|
1535
|
+
} catch {
|
|
1536
|
+
return { exists: true, isWorktree: false };
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
function projectRootFromCommonDir(commonDir) {
|
|
1540
|
+
if (!commonDir)
|
|
1541
|
+
return void 0;
|
|
1542
|
+
return basename(commonDir) === ".git" ? dirname(commonDir) : void 0;
|
|
1543
|
+
}
|
|
1544
|
+
function realpathOrSelf(p) {
|
|
1545
|
+
try {
|
|
1546
|
+
return realpathSync(p);
|
|
1547
|
+
} catch {
|
|
1548
|
+
return p;
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
function resolveProjectIdentity(cwd) {
|
|
1552
|
+
const normalized = realpathOrSelf(cwd.replace(/\/{2,}/g, "/"));
|
|
1553
|
+
try {
|
|
1554
|
+
const git = nearestDotGit(normalized);
|
|
1555
|
+
if (git) {
|
|
1556
|
+
const projectRoot = realpathOrSelf(projectRootFromCommonDir(git.commonDir) ?? git.root);
|
|
1557
|
+
const gitRoot = realpathOrSelf(git.root);
|
|
1558
|
+
const wt2 = projectRoot !== gitRoot ? worktreeName(normalized) ?? basename(git.root) : void 0;
|
|
1559
|
+
const identity = { projectName: projectRoot };
|
|
1560
|
+
if (wt2)
|
|
1561
|
+
identity.worktreeName = wt2;
|
|
1562
|
+
const remote = remoteFor(git);
|
|
1563
|
+
if (remote) {
|
|
1564
|
+
identity.remote = remote;
|
|
1565
|
+
identity.repoName = remote.name;
|
|
1566
|
+
}
|
|
1567
|
+
return identity;
|
|
1568
|
+
}
|
|
1569
|
+
} catch {
|
|
1570
|
+
}
|
|
1571
|
+
const projectName = canonicalProjectName(normalized);
|
|
1572
|
+
const wt = worktreeName(normalized) ?? void 0;
|
|
1573
|
+
return wt ? { projectName, worktreeName: wt } : { projectName };
|
|
1574
|
+
}
|
|
1575
|
+
var REMOTE_URL_RE;
|
|
1576
|
+
var init_git_project = __esm({
|
|
1577
|
+
"../parser/dist/git-project.js"() {
|
|
1578
|
+
"use strict";
|
|
1579
|
+
init_analytics();
|
|
1580
|
+
REMOTE_URL_RE = /^(?:(?:https?|ssh|git):\/\/)?(?:[^@/]+@)?([^/:]+)[:/](.+?)(?:\.git)?\/?$/;
|
|
1581
|
+
}
|
|
1582
|
+
});
|
|
1583
|
+
|
|
1416
1584
|
// ../parser/dist/team.js
|
|
1417
1585
|
function groupByTeam(sessions, details) {
|
|
1418
1586
|
const byTeam = /* @__PURE__ */ new Map();
|
|
@@ -1881,12 +2049,16 @@ async function getCachedMeta(f) {
|
|
|
1881
2049
|
const sessionId = sessionIdFromFileName(f.fileName);
|
|
1882
2050
|
const projectDirPath = path.dirname(f.fullPath);
|
|
1883
2051
|
const wf = await scanWorkflowAggregate(projectDirPath, sessionId);
|
|
2052
|
+
const cwd = meta.cwd ?? decodeProjectName(f.projectDir);
|
|
2053
|
+
const project = resolveProjectIdentity(cwd);
|
|
1884
2054
|
const full = {
|
|
1885
2055
|
...meta,
|
|
1886
2056
|
id: sessionId,
|
|
1887
2057
|
filePath: f.fullPath,
|
|
1888
2058
|
projectDir: f.projectDir,
|
|
1889
|
-
projectName:
|
|
2059
|
+
projectName: project.projectName,
|
|
2060
|
+
worktreeName: project.worktreeName,
|
|
2061
|
+
repoName: project.repoName,
|
|
1890
2062
|
...wf.workflowCount > 0 ? { workflowCount: wf.workflowCount, spawnedAgentCount: wf.spawnedAgentCount } : {},
|
|
1891
2063
|
...foldWorkflowAgentTime(meta.activeSegments, wf.spans)
|
|
1892
2064
|
};
|
|
@@ -1907,12 +2079,16 @@ async function getCachedDetail(f) {
|
|
|
1907
2079
|
const sessionId = sessionIdFromFileName(f.fileName);
|
|
1908
2080
|
await applySubagentUsage(meta, rawLines, f);
|
|
1909
2081
|
const wf = await scanWorkflowAggregate(path.dirname(f.fullPath), sessionId);
|
|
2082
|
+
const cwd = meta.cwd ?? decodeProjectName(f.projectDir);
|
|
2083
|
+
const project = resolveProjectIdentity(cwd);
|
|
1910
2084
|
const detail = {
|
|
1911
2085
|
...meta,
|
|
1912
2086
|
id: sessionId,
|
|
1913
2087
|
filePath: f.fullPath,
|
|
1914
2088
|
projectDir: f.projectDir,
|
|
1915
|
-
projectName:
|
|
2089
|
+
projectName: project.projectName,
|
|
2090
|
+
worktreeName: project.worktreeName,
|
|
2091
|
+
repoName: project.repoName,
|
|
1916
2092
|
events,
|
|
1917
2093
|
...wf.workflowCount > 0 ? { workflowCount: wf.workflowCount, spawnedAgentCount: wf.spawnedAgentCount } : {},
|
|
1918
2094
|
...foldWorkflowAgentTime(meta.activeSegments, wf.spans)
|
|
@@ -2404,19 +2580,25 @@ async function listProjects(root = DEFAULT_ROOT) {
|
|
|
2404
2580
|
cur.lastActiveMs = f.mtimeMs;
|
|
2405
2581
|
byRawDir.set(f.projectDir, cur);
|
|
2406
2582
|
}
|
|
2407
|
-
const
|
|
2583
|
+
const cachedIdentityForProject = (dir) => {
|
|
2408
2584
|
for (const [, entry] of metaCache.entries()) {
|
|
2409
|
-
if (entry.meta.projectDir === dir
|
|
2410
|
-
return
|
|
2585
|
+
if (entry.meta.projectDir === dir) {
|
|
2586
|
+
return {
|
|
2587
|
+
cwd: entry.meta.cwd,
|
|
2588
|
+
projectName: entry.meta.projectName,
|
|
2589
|
+
worktreeName: entry.meta.worktreeName
|
|
2590
|
+
};
|
|
2411
2591
|
}
|
|
2412
2592
|
}
|
|
2413
2593
|
return void 0;
|
|
2414
2594
|
};
|
|
2415
2595
|
const canonicalMap = /* @__PURE__ */ new Map();
|
|
2416
2596
|
for (const [rawDir, { count, lastActiveMs }] of byRawDir) {
|
|
2417
|
-
const
|
|
2418
|
-
const
|
|
2419
|
-
const
|
|
2597
|
+
const cached = cachedIdentityForProject(rawDir);
|
|
2598
|
+
const cwdOrDecoded = cached?.cwd ?? decodeProjectName(rawDir);
|
|
2599
|
+
const projectName = cached?.projectName ?? canonicalProjectName(cwdOrDecoded);
|
|
2600
|
+
const wt = cached?.worktreeName ?? worktreeName(cwdOrDecoded) ?? void 0;
|
|
2601
|
+
const repo = projectKey(projectName);
|
|
2420
2602
|
const agg = canonicalMap.get(repo) ?? {
|
|
2421
2603
|
canonicalName: repo,
|
|
2422
2604
|
count: 0,
|
|
@@ -2482,6 +2664,7 @@ var init_claude_code = __esm({
|
|
|
2482
2664
|
"use strict";
|
|
2483
2665
|
init_parser();
|
|
2484
2666
|
init_analytics();
|
|
2667
|
+
init_git_project();
|
|
2485
2668
|
init_team();
|
|
2486
2669
|
init_agent_metadata();
|
|
2487
2670
|
init_calibration();
|
|
@@ -2788,13 +2971,16 @@ function parseRollout(file, lines) {
|
|
|
2788
2971
|
const activeSegments = computeActiveSegments2(tsMs);
|
|
2789
2972
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
2790
2973
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
2791
|
-
const
|
|
2974
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
2975
|
+
const projectName = project?.projectName ?? "(unknown)";
|
|
2792
2976
|
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : "(unknown)";
|
|
2793
2977
|
const meta = {
|
|
2794
2978
|
agent: "codex",
|
|
2795
2979
|
id: file.sessionId,
|
|
2796
2980
|
filePath: file.filePath,
|
|
2797
2981
|
projectName,
|
|
2982
|
+
worktreeName: project?.worktreeName,
|
|
2983
|
+
repoName: project?.repoName,
|
|
2798
2984
|
projectDir,
|
|
2799
2985
|
sessionId: file.sessionId,
|
|
2800
2986
|
firstTimestamp,
|
|
@@ -2926,13 +3112,16 @@ async function getLatestCodexUsage(opts = {}) {
|
|
|
2926
3112
|
const fiveResetUnix = numberOf(primary?.resets_at);
|
|
2927
3113
|
const sevenResetUnix = numberOf(secondary?.resets_at);
|
|
2928
3114
|
const planType = typeof rl.plan_type === "string" ? rl.plan_type : null;
|
|
3115
|
+
const nowMs = Date.now();
|
|
3116
|
+
const fiveExpired = fiveResetUnix !== void 0 && nowMs > fiveResetUnix * 1e3;
|
|
3117
|
+
const sevenExpired = sevenResetUnix !== void 0 && nowMs > sevenResetUnix * 1e3;
|
|
2929
3118
|
return {
|
|
2930
3119
|
five_hour: {
|
|
2931
|
-
utilization: fivePct ?? null,
|
|
3120
|
+
utilization: fiveExpired ? 0 : fivePct ?? null,
|
|
2932
3121
|
resets_at: fiveResetUnix !== void 0 ? new Date(fiveResetUnix * 1e3).toISOString() : null
|
|
2933
3122
|
},
|
|
2934
3123
|
seven_day: {
|
|
2935
|
-
utilization: sevenPct ?? null,
|
|
3124
|
+
utilization: sevenExpired ? 0 : sevenPct ?? null,
|
|
2936
3125
|
resets_at: sevenResetUnix !== void 0 ? new Date(sevenResetUnix * 1e3).toISOString() : null
|
|
2937
3126
|
},
|
|
2938
3127
|
plan_type: planType,
|
|
@@ -2953,6 +3142,7 @@ var init_codex = __esm({
|
|
|
2953
3142
|
"../parser/dist/codex.js"() {
|
|
2954
3143
|
"use strict";
|
|
2955
3144
|
init_analytics();
|
|
3145
|
+
init_git_project();
|
|
2956
3146
|
init_user_input();
|
|
2957
3147
|
DEFAULT_CODEX_ROOT = path2.join(os2.homedir(), ".codex", "sessions");
|
|
2958
3148
|
ROLLOUT_RE = /^rollout-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})-([0-9a-f-]+)\.jsonl$/;
|
|
@@ -3332,13 +3522,16 @@ async function parseSession(file) {
|
|
|
3332
3522
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
3333
3523
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3334
3524
|
const sessionId = metaRec.sessionId ?? file.filenameId;
|
|
3335
|
-
const
|
|
3525
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3526
|
+
const projectName = project?.projectName ?? file.slug;
|
|
3336
3527
|
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : file.slug;
|
|
3337
3528
|
const meta = {
|
|
3338
3529
|
agent: "gemini",
|
|
3339
3530
|
id: sessionId,
|
|
3340
3531
|
filePath: file.filePath,
|
|
3341
3532
|
projectName,
|
|
3533
|
+
worktreeName: project?.worktreeName,
|
|
3534
|
+
repoName: project?.repoName,
|
|
3342
3535
|
projectDir,
|
|
3343
3536
|
sessionId,
|
|
3344
3537
|
firstTimestamp,
|
|
@@ -3452,6 +3645,7 @@ var init_gemini = __esm({
|
|
|
3452
3645
|
"../parser/dist/gemini.js"() {
|
|
3453
3646
|
"use strict";
|
|
3454
3647
|
init_analytics();
|
|
3648
|
+
init_git_project();
|
|
3455
3649
|
init_user_input();
|
|
3456
3650
|
DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
|
|
3457
3651
|
GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
|
|
@@ -3725,13 +3919,16 @@ async function parseSession2(file) {
|
|
|
3725
3919
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3726
3920
|
const sessionId = file.conversationId;
|
|
3727
3921
|
const cwd = file.cwd;
|
|
3728
|
-
const
|
|
3922
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3923
|
+
const projectName = project?.projectName ?? file.conversationId;
|
|
3729
3924
|
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : file.conversationId;
|
|
3730
3925
|
const meta = {
|
|
3731
3926
|
agent: "antigravity",
|
|
3732
3927
|
id: sessionId,
|
|
3733
3928
|
filePath: file.filePath,
|
|
3734
3929
|
projectName,
|
|
3930
|
+
worktreeName: project?.worktreeName,
|
|
3931
|
+
repoName: project?.repoName,
|
|
3735
3932
|
projectDir,
|
|
3736
3933
|
sessionId,
|
|
3737
3934
|
firstTimestamp,
|
|
@@ -3838,6 +4035,7 @@ var init_antigravity = __esm({
|
|
|
3838
4035
|
"../parser/dist/antigravity.js"() {
|
|
3839
4036
|
"use strict";
|
|
3840
4037
|
init_analytics();
|
|
4038
|
+
init_git_project();
|
|
3841
4039
|
init_user_input();
|
|
3842
4040
|
DEFAULT_ANTIGRAVITY_ROOT = path4.join(os4.homedir(), ".gemini", "antigravity-cli");
|
|
3843
4041
|
IDLE_GAP_MS3 = 3 * 60 * 1e3;
|
|
@@ -3957,8 +4155,10 @@ function resolveProject(meta, spaceIdToPath) {
|
|
|
3957
4155
|
if (!projectPath) {
|
|
3958
4156
|
return { projectName: "cowork:unspaced", projectDir: "cowork-unspaced" };
|
|
3959
4157
|
}
|
|
4158
|
+
const project = resolveProjectIdentity(projectPath);
|
|
3960
4159
|
return {
|
|
3961
|
-
projectName:
|
|
4160
|
+
projectName: project.projectName,
|
|
4161
|
+
worktreeName: project.worktreeName,
|
|
3962
4162
|
projectDir: projectPath.replace(/^\//, "-").replace(/\//g, "-"),
|
|
3963
4163
|
cwd: projectPath
|
|
3964
4164
|
};
|
|
@@ -4185,8 +4385,8 @@ var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache, metaCache5, detailCache5;
|
|
|
4185
4385
|
var init_cowork = __esm({
|
|
4186
4386
|
"../parser/dist/cowork.js"() {
|
|
4187
4387
|
"use strict";
|
|
4188
|
-
init_analytics();
|
|
4189
4388
|
init_claude_code();
|
|
4389
|
+
init_git_project();
|
|
4190
4390
|
init_parser();
|
|
4191
4391
|
DEFAULT_COWORK_ROOT = defaultCoworkRoot();
|
|
4192
4392
|
SESSION_ID_RE = /^local_[0-9a-f-]+$/;
|
|
@@ -4197,36 +4397,36 @@ var init_cowork = __esm({
|
|
|
4197
4397
|
});
|
|
4198
4398
|
|
|
4199
4399
|
// ../parser/dist/team-config.js
|
|
4200
|
-
import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync
|
|
4201
|
-
import { join as
|
|
4202
|
-
function shouldSyncProject(
|
|
4400
|
+
import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync, renameSync } from "node:fs";
|
|
4401
|
+
import { join as join3 } from "node:path";
|
|
4402
|
+
function shouldSyncProject(projectKey2, sp) {
|
|
4203
4403
|
if (!sp)
|
|
4204
4404
|
return true;
|
|
4205
|
-
if (sp.excluded.includes(
|
|
4405
|
+
if (sp.excluded.includes(projectKey2))
|
|
4206
4406
|
return false;
|
|
4207
|
-
if (sp.included.includes(
|
|
4407
|
+
if (sp.included.includes(projectKey2))
|
|
4208
4408
|
return true;
|
|
4209
4409
|
return sp.autoIncludeNew;
|
|
4210
4410
|
}
|
|
4211
4411
|
function readTeamConfig(dir) {
|
|
4212
4412
|
const d = dir ?? cclensHome();
|
|
4213
4413
|
try {
|
|
4214
|
-
return JSON.parse(readFileSync3(
|
|
4414
|
+
return JSON.parse(readFileSync3(join3(d, CONFIG_FILE), "utf8"));
|
|
4215
4415
|
} catch {
|
|
4216
4416
|
return null;
|
|
4217
4417
|
}
|
|
4218
4418
|
}
|
|
4219
4419
|
function writeTeamConfig(config, dir) {
|
|
4220
4420
|
const d = dir ?? cclensHome();
|
|
4221
|
-
|
|
4222
|
-
const tmp =
|
|
4421
|
+
mkdirSync(d, { recursive: true });
|
|
4422
|
+
const tmp = join3(d, `${CONFIG_FILE}.${process.pid}.tmp`);
|
|
4223
4423
|
writeFileSync(tmp, JSON.stringify(config, null, 2), { mode: 384 });
|
|
4224
|
-
renameSync(tmp,
|
|
4424
|
+
renameSync(tmp, join3(d, CONFIG_FILE));
|
|
4225
4425
|
}
|
|
4226
4426
|
function clearTeamConfig(dir) {
|
|
4227
4427
|
const d = dir ?? cclensHome();
|
|
4228
4428
|
try {
|
|
4229
|
-
unlinkSync(
|
|
4429
|
+
unlinkSync(join3(d, CONFIG_FILE));
|
|
4230
4430
|
} catch {
|
|
4231
4431
|
}
|
|
4232
4432
|
}
|
|
@@ -4259,6 +4459,7 @@ __export(fs_exports, {
|
|
|
4259
4459
|
RICH_ROLLUP_SCHEMA_VERSION: () => RICH_ROLLUP_SCHEMA_VERSION,
|
|
4260
4460
|
agentSources: () => agentSources,
|
|
4261
4461
|
antigravitySessionLocalDay: () => antigravitySessionLocalDay,
|
|
4462
|
+
appendUsageSnapshot: () => appendUsageSnapshot,
|
|
4262
4463
|
buildCalibrationCurve: () => buildCalibrationCurve,
|
|
4263
4464
|
cacheStats: () => cacheStats,
|
|
4264
4465
|
cclensHome: () => cclensHome,
|
|
@@ -4292,14 +4493,17 @@ __export(fs_exports, {
|
|
|
4292
4493
|
loadTeamForSession: () => loadTeamForSession,
|
|
4293
4494
|
loadUsageByDay: () => loadUsageByDay,
|
|
4294
4495
|
loadWorkflowAgentDetail: () => loadWorkflowAgentDetail,
|
|
4496
|
+
pruneUsageAgent: () => pruneUsageAgent,
|
|
4497
|
+
readGitFolder: () => readGitFolder,
|
|
4295
4498
|
readJsonlFile: () => readJsonlFile,
|
|
4296
4499
|
readTeamConfig: () => readTeamConfig,
|
|
4500
|
+
resolveProjectIdentity: () => resolveProjectIdentity,
|
|
4297
4501
|
sessionIdFromFileName: () => sessionIdFromFileName,
|
|
4298
4502
|
shouldSyncProject: () => shouldSyncProject,
|
|
4299
4503
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
4300
4504
|
writeTeamConfig: () => writeTeamConfig
|
|
4301
4505
|
});
|
|
4302
|
-
import { promises as fs6 } from "node:fs";
|
|
4506
|
+
import { promises as fs6, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
4303
4507
|
import os6 from "node:os";
|
|
4304
4508
|
import path6 from "node:path";
|
|
4305
4509
|
function cclensHome() {
|
|
@@ -4345,6 +4549,27 @@ async function getAnySession(id) {
|
|
|
4345
4549
|
function usageLogPath() {
|
|
4346
4550
|
return cclensPath("usage.jsonl");
|
|
4347
4551
|
}
|
|
4552
|
+
function appendUsageSnapshot(snapshot) {
|
|
4553
|
+
const p = usageLogPath();
|
|
4554
|
+
mkdirSync2(path6.dirname(p), { recursive: true });
|
|
4555
|
+
appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
|
|
4556
|
+
}
|
|
4557
|
+
function pruneUsageAgent(agent) {
|
|
4558
|
+
const p = usageLogPath();
|
|
4559
|
+
if (!existsSync2(p))
|
|
4560
|
+
return;
|
|
4561
|
+
const kept = readFileSync4(p, "utf8").split("\n").filter((line) => {
|
|
4562
|
+
if (!line.trim())
|
|
4563
|
+
return false;
|
|
4564
|
+
try {
|
|
4565
|
+
return JSON.parse(line).agent !== agent;
|
|
4566
|
+
} catch {
|
|
4567
|
+
return true;
|
|
4568
|
+
}
|
|
4569
|
+
});
|
|
4570
|
+
mkdirSync2(path6.dirname(p), { recursive: true });
|
|
4571
|
+
writeFileSync2(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
4572
|
+
}
|
|
4348
4573
|
async function loadUsageByDay(start, end) {
|
|
4349
4574
|
let raw;
|
|
4350
4575
|
try {
|
|
@@ -4569,6 +4794,7 @@ var init_fs = __esm({
|
|
|
4569
4794
|
init_antigravity();
|
|
4570
4795
|
init_cowork();
|
|
4571
4796
|
init_claude_code();
|
|
4797
|
+
init_git_project();
|
|
4572
4798
|
init_codex();
|
|
4573
4799
|
init_gemini();
|
|
4574
4800
|
init_antigravity();
|
|
@@ -4636,6 +4862,53 @@ var init_fs = __esm({
|
|
|
4636
4862
|
}
|
|
4637
4863
|
});
|
|
4638
4864
|
|
|
4865
|
+
// src/usage/storage.ts
|
|
4866
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync4 } from "node:fs";
|
|
4867
|
+
import { dirname as dirname2 } from "node:path";
|
|
4868
|
+
function appendSnapshot(filePath, snapshot) {
|
|
4869
|
+
mkdirSync3(dirname2(filePath), { recursive: true });
|
|
4870
|
+
appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
4871
|
+
}
|
|
4872
|
+
function readSnapshots(filePath) {
|
|
4873
|
+
if (!existsSync4(filePath)) return [];
|
|
4874
|
+
const content = readFileSync6(filePath, "utf8");
|
|
4875
|
+
const snapshots = [];
|
|
4876
|
+
for (const line of content.split("\n")) {
|
|
4877
|
+
if (!line.trim()) continue;
|
|
4878
|
+
try {
|
|
4879
|
+
snapshots.push(JSON.parse(line));
|
|
4880
|
+
} catch {
|
|
4881
|
+
}
|
|
4882
|
+
}
|
|
4883
|
+
return snapshots;
|
|
4884
|
+
}
|
|
4885
|
+
function pruneAgent(filePath, agent) {
|
|
4886
|
+
if (!existsSync4(filePath)) return;
|
|
4887
|
+
const kept = readFileSync6(filePath, "utf8").split("\n").filter((line) => {
|
|
4888
|
+
if (!line.trim()) return false;
|
|
4889
|
+
try {
|
|
4890
|
+
return JSON.parse(line).agent !== agent;
|
|
4891
|
+
} catch {
|
|
4892
|
+
return true;
|
|
4893
|
+
}
|
|
4894
|
+
});
|
|
4895
|
+
mkdirSync3(dirname2(filePath), { recursive: true });
|
|
4896
|
+
writeFileSync3(filePath, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
4897
|
+
}
|
|
4898
|
+
function latestClaudeCodeSnapshot(filePath) {
|
|
4899
|
+
const all = readSnapshots(filePath);
|
|
4900
|
+
for (let i = all.length - 1; i >= 0; i--) {
|
|
4901
|
+
const s = all[i];
|
|
4902
|
+
if (!s.agent || s.agent === "claude-code") return s;
|
|
4903
|
+
}
|
|
4904
|
+
return null;
|
|
4905
|
+
}
|
|
4906
|
+
var init_storage = __esm({
|
|
4907
|
+
"src/usage/storage.ts"() {
|
|
4908
|
+
"use strict";
|
|
4909
|
+
}
|
|
4910
|
+
});
|
|
4911
|
+
|
|
4639
4912
|
// ../parser/dist/types.js
|
|
4640
4913
|
var init_types = __esm({
|
|
4641
4914
|
"../parser/dist/types.js"() {
|
|
@@ -5053,11 +5326,13 @@ __export(dist_exports, {
|
|
|
5053
5326
|
RATE_PER_PCT: () => RATE_PER_PCT,
|
|
5054
5327
|
RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
|
|
5055
5328
|
RATE_PER_PCT_7D: () => RATE_PER_PCT_7D,
|
|
5329
|
+
ZAI_METADATA: () => ZAI_METADATA,
|
|
5056
5330
|
agentMetadata: () => agentMetadata,
|
|
5057
5331
|
aggregateConcurrency: () => aggregateConcurrency,
|
|
5058
5332
|
buildGanttDay: () => buildGanttDay,
|
|
5059
5333
|
buildMegaRows: () => buildMegaRows,
|
|
5060
5334
|
buildPresentation: () => buildPresentation,
|
|
5335
|
+
buildProjectKeyResolver: () => buildProjectKeyResolver,
|
|
5061
5336
|
buildSpendIndex: () => buildSpendIndex,
|
|
5062
5337
|
calendarMonth: () => calendarMonth,
|
|
5063
5338
|
calendarWeek: () => calendarWeek,
|
|
@@ -5086,10 +5361,12 @@ __export(dist_exports, {
|
|
|
5086
5361
|
predictAnchored: () => predictAnchored,
|
|
5087
5362
|
priorCalendarMonth: () => priorCalendarMonth,
|
|
5088
5363
|
priorCalendarWeek: () => priorCalendarWeek,
|
|
5364
|
+
projectKey: () => projectKey,
|
|
5089
5365
|
projectRepoName: () => projectRepoName,
|
|
5090
5366
|
rowPrimaryIndex: () => rowPrimaryIndex,
|
|
5091
5367
|
sessionAirTimeMs: () => sessionAirTimeMs,
|
|
5092
5368
|
sessionDay: () => sessionDay,
|
|
5369
|
+
sessionProjectKey: () => sessionProjectKey,
|
|
5093
5370
|
stripFrameworkBoilerplate: () => stripFrameworkBoilerplate,
|
|
5094
5371
|
summarizeBursts: () => summarizeBursts,
|
|
5095
5372
|
toLocalDay: () => toLocalDay,
|
|
@@ -5118,25 +5395,25 @@ __export(file_probe_exports, {
|
|
|
5118
5395
|
probeArtifactSignals: () => probeArtifactSignals
|
|
5119
5396
|
});
|
|
5120
5397
|
import { createHash } from "node:crypto";
|
|
5121
|
-
import { existsSync as
|
|
5122
|
-
import { homedir as
|
|
5123
|
-
import { join as
|
|
5398
|
+
import { existsSync as existsSync9, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
|
|
5399
|
+
import { homedir as homedir3 } from "node:os";
|
|
5400
|
+
import { join as join8, relative, resolve as resolve3, sep } from "node:path";
|
|
5124
5401
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
5125
5402
|
function pathHash(relPath) {
|
|
5126
5403
|
return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
5127
5404
|
}
|
|
5128
5405
|
function defaultScanRoots(extraRoots = []) {
|
|
5129
5406
|
const roots = [];
|
|
5130
|
-
const home =
|
|
5131
|
-
if (
|
|
5407
|
+
const home = join8(homedir3(), ".claude");
|
|
5408
|
+
if (existsSync9(home)) roots.push({ root: home, label: "user" });
|
|
5132
5409
|
for (const e of extraRoots) {
|
|
5133
|
-
const r =
|
|
5134
|
-
if (
|
|
5410
|
+
const r = resolve3(e, ".claude");
|
|
5411
|
+
if (existsSync9(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
5135
5412
|
}
|
|
5136
5413
|
return roots;
|
|
5137
5414
|
}
|
|
5138
5415
|
function listMarkdownFiles(dir) {
|
|
5139
|
-
if (!
|
|
5416
|
+
if (!existsSync9(dir)) return [];
|
|
5140
5417
|
const out = [];
|
|
5141
5418
|
let entries;
|
|
5142
5419
|
try {
|
|
@@ -5146,10 +5423,10 @@ function listMarkdownFiles(dir) {
|
|
|
5146
5423
|
}
|
|
5147
5424
|
for (const name of entries) {
|
|
5148
5425
|
if (name.startsWith(".")) continue;
|
|
5149
|
-
const full =
|
|
5426
|
+
const full = join8(dir, name);
|
|
5150
5427
|
let stat;
|
|
5151
5428
|
try {
|
|
5152
|
-
stat =
|
|
5429
|
+
stat = statSync5(full);
|
|
5153
5430
|
} catch {
|
|
5154
5431
|
continue;
|
|
5155
5432
|
}
|
|
@@ -5166,19 +5443,19 @@ function firstSeenDateOf(file) {
|
|
|
5166
5443
|
const out = execFileSync2(
|
|
5167
5444
|
"git",
|
|
5168
5445
|
["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
|
|
5169
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
5446
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname8(file) }
|
|
5170
5447
|
).trim().split("\n").filter(Boolean);
|
|
5171
5448
|
if (out.length > 0) return out[out.length - 1];
|
|
5172
5449
|
} catch {
|
|
5173
5450
|
}
|
|
5174
5451
|
try {
|
|
5175
|
-
const s =
|
|
5452
|
+
const s = statSync5(file);
|
|
5176
5453
|
return localDay(s.birthtime || s.mtime);
|
|
5177
5454
|
} catch {
|
|
5178
5455
|
return todayLocal();
|
|
5179
5456
|
}
|
|
5180
5457
|
}
|
|
5181
|
-
function
|
|
5458
|
+
function dirname8(p) {
|
|
5182
5459
|
const i = p.lastIndexOf(sep);
|
|
5183
5460
|
return i < 0 ? "." : p.slice(0, i);
|
|
5184
5461
|
}
|
|
@@ -5205,8 +5482,8 @@ function todayLocal() {
|
|
|
5205
5482
|
function scanAuthored(roots, subdir, day) {
|
|
5206
5483
|
const out = [];
|
|
5207
5484
|
for (const r of roots) {
|
|
5208
|
-
const dir =
|
|
5209
|
-
if (!
|
|
5485
|
+
const dir = join8(r.root, subdir);
|
|
5486
|
+
if (!existsSync9(dir)) continue;
|
|
5210
5487
|
for (const f of listMarkdownFiles(dir)) {
|
|
5211
5488
|
const firstSeen = firstSeenDateOf(f);
|
|
5212
5489
|
if (firstSeen !== day) continue;
|
|
@@ -5219,14 +5496,14 @@ function scanAuthored(roots, subdir, day) {
|
|
|
5219
5496
|
function scanEdited(roots, day) {
|
|
5220
5497
|
const out = [];
|
|
5221
5498
|
for (const r of roots) {
|
|
5222
|
-
const dir =
|
|
5223
|
-
if (!
|
|
5499
|
+
const dir = join8(r.root, "skills");
|
|
5500
|
+
if (!existsSync9(dir)) continue;
|
|
5224
5501
|
for (const f of listMarkdownFiles(dir)) {
|
|
5225
5502
|
const firstSeen = firstSeenDateOf(f);
|
|
5226
5503
|
if (firstSeen === day) continue;
|
|
5227
5504
|
let stat;
|
|
5228
5505
|
try {
|
|
5229
|
-
stat =
|
|
5506
|
+
stat = statSync5(f);
|
|
5230
5507
|
} catch {
|
|
5231
5508
|
continue;
|
|
5232
5509
|
}
|
|
@@ -5242,17 +5519,17 @@ function claudemdLineDelta(extraRoots, authorEmail, day) {
|
|
|
5242
5519
|
let delta = 0;
|
|
5243
5520
|
const candidates = [];
|
|
5244
5521
|
for (const e of extraRoots) {
|
|
5245
|
-
const f =
|
|
5246
|
-
if (
|
|
5522
|
+
const f = resolve3(e, "CLAUDE.md");
|
|
5523
|
+
if (existsSync9(f)) candidates.push(f);
|
|
5247
5524
|
}
|
|
5248
|
-
const homeClaudeMd =
|
|
5249
|
-
if (
|
|
5525
|
+
const homeClaudeMd = join8(homedir3(), "CLAUDE.md");
|
|
5526
|
+
if (existsSync9(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
5250
5527
|
for (const file of candidates) {
|
|
5251
5528
|
try {
|
|
5252
5529
|
const out = execFileSync2(
|
|
5253
5530
|
"git",
|
|
5254
5531
|
["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
|
|
5255
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
5532
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname8(file) }
|
|
5256
5533
|
);
|
|
5257
5534
|
let currentDate = "";
|
|
5258
5535
|
let currentEmail = "";
|
|
@@ -5303,8 +5580,8 @@ var init_file_probe = __esm({
|
|
|
5303
5580
|
|
|
5304
5581
|
// src/daemon-worker.ts
|
|
5305
5582
|
import { spawn as spawn2 } from "node:child_process";
|
|
5306
|
-
import { closeSync, existsSync as
|
|
5307
|
-
import { dirname as
|
|
5583
|
+
import { closeSync, existsSync as existsSync16, mkdirSync as mkdirSync14, openSync, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
|
|
5584
|
+
import { dirname as dirname11, join as join12 } from "node:path";
|
|
5308
5585
|
import { fileURLToPath } from "node:url";
|
|
5309
5586
|
|
|
5310
5587
|
// src/usage/token.ts
|
|
@@ -5445,16 +5722,120 @@ function normalizeExtra(raw) {
|
|
|
5445
5722
|
};
|
|
5446
5723
|
}
|
|
5447
5724
|
|
|
5725
|
+
// src/usage/zai.ts
|
|
5726
|
+
init_fs();
|
|
5727
|
+
import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
|
|
5728
|
+
var ZAI_QUOTA_ENDPOINT = "https://api.z.ai/api/monitor/usage/quota/limit";
|
|
5729
|
+
var ZAI_SUBSCRIPTION_ENDPOINT = "https://api.z.ai/api/biz/subscription/list";
|
|
5730
|
+
var ZaiApiError = class extends Error {
|
|
5731
|
+
constructor(message, code) {
|
|
5732
|
+
super(message);
|
|
5733
|
+
this.code = code;
|
|
5734
|
+
}
|
|
5735
|
+
};
|
|
5736
|
+
function resolveApiKey() {
|
|
5737
|
+
try {
|
|
5738
|
+
const p = cclensPath("credentials.json");
|
|
5739
|
+
if (existsSync3(p)) {
|
|
5740
|
+
const store = JSON.parse(readFileSync5(p, "utf8"));
|
|
5741
|
+
return store.zai?.apiKey ?? null;
|
|
5742
|
+
}
|
|
5743
|
+
} catch {
|
|
5744
|
+
}
|
|
5745
|
+
return null;
|
|
5746
|
+
}
|
|
5747
|
+
function epochMsToIso(ms) {
|
|
5748
|
+
if (typeof ms !== "number" || Number.isNaN(ms)) return null;
|
|
5749
|
+
return new Date(ms).toISOString();
|
|
5750
|
+
}
|
|
5751
|
+
function windowFromLimit(limit) {
|
|
5752
|
+
return {
|
|
5753
|
+
utilization: typeof limit.percentage === "number" ? limit.percentage : null,
|
|
5754
|
+
resets_at: epochMsToIso(limit.nextResetTime)
|
|
5755
|
+
};
|
|
5756
|
+
}
|
|
5757
|
+
function zaiHeaders(key) {
|
|
5758
|
+
return { Authorization: key, "Accept-Language": "en-US,en" };
|
|
5759
|
+
}
|
|
5760
|
+
async function fetchZaiUsage() {
|
|
5761
|
+
const key = resolveApiKey();
|
|
5762
|
+
if (!key) {
|
|
5763
|
+
throw new ZaiApiError(
|
|
5764
|
+
"No Z.ai API key found. Set ZAI_API_KEY (or GLM_API_KEY), or write ~/.config/zai/key.json.",
|
|
5765
|
+
"no_key"
|
|
5766
|
+
);
|
|
5767
|
+
}
|
|
5768
|
+
let res;
|
|
5769
|
+
try {
|
|
5770
|
+
res = await fetch(ZAI_QUOTA_ENDPOINT, { headers: zaiHeaders(key) });
|
|
5771
|
+
} catch (err) {
|
|
5772
|
+
throw new ZaiApiError(`Network error reaching Z.ai: ${err.message}`, "network");
|
|
5773
|
+
}
|
|
5774
|
+
if (!res.ok) {
|
|
5775
|
+
throw new ZaiApiError(`Z.ai quota endpoint returned ${res.status} ${res.statusText}`, "http");
|
|
5776
|
+
}
|
|
5777
|
+
let body;
|
|
5778
|
+
try {
|
|
5779
|
+
body = await res.json();
|
|
5780
|
+
} catch (err) {
|
|
5781
|
+
throw new ZaiApiError(`Failed to parse Z.ai quota response: ${err.message}`, "parse");
|
|
5782
|
+
}
|
|
5783
|
+
const b = body;
|
|
5784
|
+
const limits = b.data?.limits ?? [];
|
|
5785
|
+
let fiveHour = null;
|
|
5786
|
+
let sevenDay = null;
|
|
5787
|
+
let webSearch = null;
|
|
5788
|
+
for (const limit of limits) {
|
|
5789
|
+
if (limit.type === "TIME_LIMIT") {
|
|
5790
|
+
const percentage = typeof limit.percentage === "number" ? limit.percentage : null;
|
|
5791
|
+
webSearch = {
|
|
5792
|
+
used: percentage,
|
|
5793
|
+
limit: percentage !== null ? 100 : null
|
|
5794
|
+
};
|
|
5795
|
+
continue;
|
|
5796
|
+
}
|
|
5797
|
+
const window = windowFromLimit(limit);
|
|
5798
|
+
if (limit.unit === 6) {
|
|
5799
|
+
sevenDay = sevenDay ?? window;
|
|
5800
|
+
} else {
|
|
5801
|
+
fiveHour = fiveHour ?? window;
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
let planType = null;
|
|
5805
|
+
try {
|
|
5806
|
+
const subRes = await fetch(ZAI_SUBSCRIPTION_ENDPOINT, { headers: zaiHeaders(key) });
|
|
5807
|
+
if (subRes.ok) {
|
|
5808
|
+
const sub = await subRes.json();
|
|
5809
|
+
const entry = sub.data?.[0];
|
|
5810
|
+
planType = entry?.productName || entry?.planName || entry?.name || null;
|
|
5811
|
+
}
|
|
5812
|
+
} catch {
|
|
5813
|
+
}
|
|
5814
|
+
return {
|
|
5815
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5816
|
+
agent: "zai",
|
|
5817
|
+
five_hour: fiveHour ?? { utilization: null, resets_at: null },
|
|
5818
|
+
seven_day: sevenDay ?? { utilization: null, resets_at: null },
|
|
5819
|
+
seven_day_opus: null,
|
|
5820
|
+
seven_day_sonnet: null,
|
|
5821
|
+
seven_day_oauth_apps: null,
|
|
5822
|
+
seven_day_cowork: null,
|
|
5823
|
+
extra_usage: null,
|
|
5824
|
+
plan_type: planType,
|
|
5825
|
+
web_search_quota: webSearch ?? null
|
|
5826
|
+
};
|
|
5827
|
+
}
|
|
5828
|
+
|
|
5448
5829
|
// src/daemon-worker.ts
|
|
5449
5830
|
init_storage();
|
|
5450
5831
|
init_fs();
|
|
5451
5832
|
|
|
5452
5833
|
// src/daemon-log.ts
|
|
5453
5834
|
init_fs();
|
|
5454
|
-
import { appendFileSync as
|
|
5835
|
+
import { appendFileSync as appendFileSync3 } from "node:fs";
|
|
5455
5836
|
function appendDaemonLogLine(level, msg) {
|
|
5456
5837
|
try {
|
|
5457
|
-
|
|
5838
|
+
appendFileSync3(
|
|
5458
5839
|
cclensPath("daemon.log"),
|
|
5459
5840
|
`${(/* @__PURE__ */ new Date()).toISOString()} ${level.toUpperCase()} ${msg}
|
|
5460
5841
|
`,
|
|
@@ -5486,9 +5867,9 @@ import { randomUUID } from "node:crypto";
|
|
|
5486
5867
|
|
|
5487
5868
|
// ../entries/dist/fs.js
|
|
5488
5869
|
init_fs();
|
|
5489
|
-
import { readFileSync as
|
|
5870
|
+
import { readFileSync as readFileSync8, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync6 } from "node:fs";
|
|
5490
5871
|
import { randomBytes } from "node:crypto";
|
|
5491
|
-
import { join as
|
|
5872
|
+
import { join as join5 } from "node:path";
|
|
5492
5873
|
|
|
5493
5874
|
// ../entries/dist/types.js
|
|
5494
5875
|
var CURRENT_ENTRY_SCHEMA_VERSION = 2;
|
|
@@ -5561,12 +5942,12 @@ var PROMPT_FRAME_ORIGIN = {
|
|
|
5561
5942
|
|
|
5562
5943
|
// ../entries/dist/digest-fs.js
|
|
5563
5944
|
init_fs();
|
|
5564
|
-
import { readFileSync as
|
|
5565
|
-
import { dirname as
|
|
5945
|
+
import { readFileSync as readFileSync7, readdirSync, writeFileSync as writeFileSync4, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "node:fs";
|
|
5946
|
+
import { dirname as dirname3, join as join4 } from "node:path";
|
|
5566
5947
|
var digestsDirCached = null;
|
|
5567
5948
|
function parseDigestFile(path7, expectedVersion) {
|
|
5568
5949
|
try {
|
|
5569
|
-
const parsed = JSON.parse(
|
|
5950
|
+
const parsed = JSON.parse(readFileSync7(path7, "utf8"));
|
|
5570
5951
|
if (!parsed || typeof parsed !== "object")
|
|
5571
5952
|
return null;
|
|
5572
5953
|
if (parsed.version !== expectedVersion)
|
|
@@ -5586,16 +5967,16 @@ function digestsDir() {
|
|
|
5586
5967
|
return digestsDirCached;
|
|
5587
5968
|
}
|
|
5588
5969
|
function dayDigestPath(date) {
|
|
5589
|
-
return
|
|
5970
|
+
return join4(digestsDir(), "day", `${date}.json`);
|
|
5590
5971
|
}
|
|
5591
5972
|
function weekDigestPath(monday) {
|
|
5592
|
-
return
|
|
5973
|
+
return join4(digestsDir(), "week", `${monday}.json`);
|
|
5593
5974
|
}
|
|
5594
5975
|
function writeDayDigest(digest) {
|
|
5595
5976
|
const final = dayDigestPath(digest.key);
|
|
5596
|
-
|
|
5977
|
+
mkdirSync4(dirname3(final), { recursive: true });
|
|
5597
5978
|
const tmp = `${final}.tmp`;
|
|
5598
|
-
|
|
5979
|
+
writeFileSync4(tmp, JSON.stringify(digest, null, 2), "utf8");
|
|
5599
5980
|
if (process.platform !== "win32") {
|
|
5600
5981
|
try {
|
|
5601
5982
|
chmodSync(tmp, 384);
|
|
@@ -5606,7 +5987,7 @@ function writeDayDigest(digest) {
|
|
|
5606
5987
|
}
|
|
5607
5988
|
function readDayDigest(date) {
|
|
5608
5989
|
const p = dayDigestPath(date);
|
|
5609
|
-
if (!
|
|
5990
|
+
if (!existsSync5(p))
|
|
5610
5991
|
return null;
|
|
5611
5992
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
5612
5993
|
}
|
|
@@ -5626,9 +6007,9 @@ function setTodayDigestInCache(date, digest, nowMs) {
|
|
|
5626
6007
|
}
|
|
5627
6008
|
function writeWeekDigest(digest) {
|
|
5628
6009
|
const final = weekDigestPath(digest.key);
|
|
5629
|
-
|
|
6010
|
+
mkdirSync4(dirname3(final), { recursive: true });
|
|
5630
6011
|
const tmp = `${final}.tmp`;
|
|
5631
|
-
|
|
6012
|
+
writeFileSync4(tmp, JSON.stringify(digest, null, 2), "utf8");
|
|
5632
6013
|
if (process.platform !== "win32") {
|
|
5633
6014
|
try {
|
|
5634
6015
|
chmodSync(tmp, 384);
|
|
@@ -5639,7 +6020,7 @@ function writeWeekDigest(digest) {
|
|
|
5639
6020
|
}
|
|
5640
6021
|
function readWeekDigest(monday) {
|
|
5641
6022
|
const p = weekDigestPath(monday);
|
|
5642
|
-
if (!
|
|
6023
|
+
if (!existsSync5(p))
|
|
5643
6024
|
return null;
|
|
5644
6025
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
5645
6026
|
}
|
|
@@ -5669,18 +6050,18 @@ function entriesDir() {
|
|
|
5669
6050
|
return entriesDirCached;
|
|
5670
6051
|
}
|
|
5671
6052
|
function pathFor(sessionId, localDay2) {
|
|
5672
|
-
return
|
|
6053
|
+
return join5(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
5673
6054
|
}
|
|
5674
6055
|
function tmpPathFor(final) {
|
|
5675
6056
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
5676
6057
|
}
|
|
5677
6058
|
function writeEntry(entry) {
|
|
5678
6059
|
const dir = entriesDir();
|
|
5679
|
-
|
|
6060
|
+
mkdirSync5(dir, { recursive: true });
|
|
5680
6061
|
const final = pathFor(entry.session_id, entry.local_day);
|
|
5681
6062
|
const tmp = tmpPathFor(final);
|
|
5682
6063
|
const json = JSON.stringify(entry, null, 2);
|
|
5683
|
-
|
|
6064
|
+
writeFileSync5(tmp, json, { encoding: "utf8" });
|
|
5684
6065
|
renameSync3(tmp, final);
|
|
5685
6066
|
}
|
|
5686
6067
|
var PRESERVABLE_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -5704,7 +6085,7 @@ function enrichmentInputHash(e) {
|
|
|
5704
6085
|
}
|
|
5705
6086
|
function writeEntryPreservingEnrichment(fresh) {
|
|
5706
6087
|
const dir = entriesDir();
|
|
5707
|
-
|
|
6088
|
+
mkdirSync5(dir, { recursive: true });
|
|
5708
6089
|
const final = pathFor(fresh.session_id, fresh.local_day);
|
|
5709
6090
|
const existing = readEntry(fresh.session_id, fresh.local_day);
|
|
5710
6091
|
let toWrite = fresh;
|
|
@@ -5712,22 +6093,22 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
5712
6093
|
toWrite = { ...fresh, enrichment: existing.enrichment };
|
|
5713
6094
|
}
|
|
5714
6095
|
const tmp = tmpPathFor(final);
|
|
5715
|
-
|
|
6096
|
+
writeFileSync5(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
|
|
5716
6097
|
renameSync3(tmp, final);
|
|
5717
6098
|
}
|
|
5718
6099
|
function readEntry(sessionId, localDay2) {
|
|
5719
6100
|
const p = pathFor(sessionId, localDay2);
|
|
5720
|
-
if (!
|
|
6101
|
+
if (!existsSync6(p))
|
|
5721
6102
|
return null;
|
|
5722
|
-
const raw =
|
|
6103
|
+
const raw = readFileSync8(p, "utf8");
|
|
5723
6104
|
return JSON.parse(raw);
|
|
5724
6105
|
}
|
|
5725
6106
|
function entryExists(sessionId, localDay2) {
|
|
5726
|
-
return
|
|
6107
|
+
return existsSync6(pathFor(sessionId, localDay2));
|
|
5727
6108
|
}
|
|
5728
6109
|
function listEntryKeys() {
|
|
5729
6110
|
const dir = entriesDir();
|
|
5730
|
-
if (!
|
|
6111
|
+
if (!existsSync6(dir))
|
|
5731
6112
|
return [];
|
|
5732
6113
|
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
5733
6114
|
}
|
|
@@ -5746,8 +6127,8 @@ function listEntriesForDay(localDay2) {
|
|
|
5746
6127
|
|
|
5747
6128
|
// src/perception/build-entries.ts
|
|
5748
6129
|
init_dist();
|
|
5749
|
-
import { statSync, readFileSync as
|
|
5750
|
-
import { basename, dirname as
|
|
6130
|
+
import { statSync as statSync2, readFileSync as readFileSync9 } from "node:fs";
|
|
6131
|
+
import { basename as basename2, dirname as dirname4 } from "node:path";
|
|
5751
6132
|
|
|
5752
6133
|
// ../entries/dist/signals.js
|
|
5753
6134
|
init_dist();
|
|
@@ -6338,6 +6719,7 @@ function buildEntries(sessionDetail) {
|
|
|
6338
6719
|
const entries = [];
|
|
6339
6720
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6340
6721
|
const sessionFallbackProject = canonicalProjectName(sessionDetail.projectName ?? "");
|
|
6722
|
+
const trustSessionProject = !!sessionDetail.worktreeName;
|
|
6341
6723
|
for (const [local_day, dayEvents] of byDay) {
|
|
6342
6724
|
if (dayEvents.length === 0)
|
|
6343
6725
|
continue;
|
|
@@ -6402,7 +6784,7 @@ function buildEntries(sessionDetail) {
|
|
|
6402
6784
|
const finalAgentRaw = agg.finalAgent ?? "";
|
|
6403
6785
|
const final_agent = trunc(minimizeImages(finalAgentRaw), 400);
|
|
6404
6786
|
let project = sessionFallbackProject;
|
|
6405
|
-
if (agg.cwdCounts.size > 0) {
|
|
6787
|
+
if (!trustSessionProject && agg.cwdCounts.size > 0) {
|
|
6406
6788
|
const best = [...agg.cwdCounts.entries()].sort((a, b) => b[1] - a[1])[0];
|
|
6407
6789
|
project = canonicalProjectName(best[0]);
|
|
6408
6790
|
}
|
|
@@ -6484,8 +6866,8 @@ function decodeProjectDirName(projectDir) {
|
|
|
6484
6866
|
return projectDir.replace(/-/g, "/");
|
|
6485
6867
|
}
|
|
6486
6868
|
function buildEntriesForFile(filePath) {
|
|
6487
|
-
const stat =
|
|
6488
|
-
const raw =
|
|
6869
|
+
const stat = statSync2(filePath);
|
|
6870
|
+
const raw = readFileSync9(filePath, "utf8");
|
|
6489
6871
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
6490
6872
|
try {
|
|
6491
6873
|
return JSON.parse(l);
|
|
@@ -6495,8 +6877,8 @@ function buildEntriesForFile(filePath) {
|
|
|
6495
6877
|
}).filter((x) => x !== null);
|
|
6496
6878
|
if (rawLines.length === 0) return null;
|
|
6497
6879
|
const { meta, events } = parseTranscript(rawLines);
|
|
6498
|
-
const fileName =
|
|
6499
|
-
const projectDir =
|
|
6880
|
+
const fileName = basename2(filePath);
|
|
6881
|
+
const projectDir = basename2(dirname4(filePath));
|
|
6500
6882
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
6501
6883
|
const sd = {
|
|
6502
6884
|
...meta,
|
|
@@ -6577,7 +6959,7 @@ function clipSegmentsToDay(segments, bounds) {
|
|
|
6577
6959
|
}
|
|
6578
6960
|
function filterSyncedSessions(sessions, syncProjects) {
|
|
6579
6961
|
if (!syncProjects) return sessions;
|
|
6580
|
-
return sessions.filter((s) => shouldSyncProject(
|
|
6962
|
+
return sessions.filter((s) => shouldSyncProject(projectKey(s.projectName), syncProjects));
|
|
6581
6963
|
}
|
|
6582
6964
|
function sessionTouchesDay(s, day) {
|
|
6583
6965
|
const bounds = dayBoundsMs(day);
|
|
@@ -6618,7 +7000,7 @@ function buildRichRollupBlocks(day, daySessions, entries, resolveRepo) {
|
|
|
6618
7000
|
const projects = /* @__PURE__ */ new Map();
|
|
6619
7001
|
for (const s of clippedSessions) {
|
|
6620
7002
|
const canonical = canonicalProjectName(s.projectName);
|
|
6621
|
-
const name =
|
|
7003
|
+
const name = projectKey(s.projectName);
|
|
6622
7004
|
const repo = resolveRepo?.(canonical) ?? sessionRepo.get(s.id);
|
|
6623
7005
|
const key = repo ?? name;
|
|
6624
7006
|
const ms = s.activeSegments.reduce((sum, seg) => sum + (seg.endMs - seg.startMs), 0);
|
|
@@ -6661,7 +7043,7 @@ function buildRichRollupBlocks(day, daySessions, entries, resolveRepo) {
|
|
|
6661
7043
|
commits += e.numbers.commits;
|
|
6662
7044
|
pushes += e.numbers.pushes;
|
|
6663
7045
|
if (e.github_repos?.length) {
|
|
6664
|
-
const key = sessionRepo.get(e.session_id) ??
|
|
7046
|
+
const key = sessionRepo.get(e.session_id) ?? projectKey(e.project);
|
|
6665
7047
|
const set = projectRepos.get(key) ?? /* @__PURE__ */ new Set();
|
|
6666
7048
|
for (const r of e.github_repos) set.add(r);
|
|
6667
7049
|
projectRepos.set(key, set);
|
|
@@ -6746,7 +7128,7 @@ function buildIngestPayload(inputs) {
|
|
|
6746
7128
|
return {
|
|
6747
7129
|
ingestId: randomUUID(),
|
|
6748
7130
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6749
|
-
cliVersion: "0.15.
|
|
7131
|
+
cliVersion: "0.15.4",
|
|
6750
7132
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
6751
7133
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
6752
7134
|
...richRollup ? { richRollup } : {},
|
|
@@ -6773,14 +7155,14 @@ async function pushToTeamServer(config, payload) {
|
|
|
6773
7155
|
}
|
|
6774
7156
|
|
|
6775
7157
|
// src/team/git-remote.ts
|
|
6776
|
-
import { existsSync as
|
|
6777
|
-
import { dirname as
|
|
7158
|
+
import { existsSync as existsSync7, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
|
|
7159
|
+
import { dirname as dirname5, isAbsolute as isAbsolute2, join as join6, resolve as resolve2 } from "node:path";
|
|
6778
7160
|
var GITHUB_URL_RE = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/;
|
|
6779
7161
|
function parseGithubRemote(url) {
|
|
6780
7162
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
6781
7163
|
return m ? `${m[1]}/${m[2]}`.toLowerCase() : null;
|
|
6782
7164
|
}
|
|
6783
|
-
function
|
|
7165
|
+
function originUrl2(configText) {
|
|
6784
7166
|
let inOrigin = false;
|
|
6785
7167
|
for (const line of configText.split("\n")) {
|
|
6786
7168
|
const t = line.trim();
|
|
@@ -6795,36 +7177,36 @@ function originUrl(configText) {
|
|
|
6795
7177
|
return null;
|
|
6796
7178
|
}
|
|
6797
7179
|
function gitConfigPathFor(dir) {
|
|
6798
|
-
const dotGit =
|
|
6799
|
-
const st =
|
|
7180
|
+
const dotGit = join6(dir, ".git");
|
|
7181
|
+
const st = statSync3(dotGit, { throwIfNoEntry: false });
|
|
6800
7182
|
if (!st) return null;
|
|
6801
|
-
if (st.isDirectory()) return
|
|
6802
|
-
const m =
|
|
7183
|
+
if (st.isDirectory()) return join6(dotGit, "config");
|
|
7184
|
+
const m = readFileSync10(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
6803
7185
|
if (!m) return null;
|
|
6804
|
-
const gd =
|
|
6805
|
-
const commondirFile =
|
|
6806
|
-
if (
|
|
6807
|
-
const common =
|
|
6808
|
-
return
|
|
7186
|
+
const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
|
|
7187
|
+
const commondirFile = join6(gd, "commondir");
|
|
7188
|
+
if (existsSync7(commondirFile)) {
|
|
7189
|
+
const common = readFileSync10(commondirFile, "utf8").trim();
|
|
7190
|
+
return join6(isAbsolute2(common) ? common : resolve2(gd, common), "config");
|
|
6809
7191
|
}
|
|
6810
|
-
return
|
|
7192
|
+
return join6(gd, "config");
|
|
6811
7193
|
}
|
|
6812
7194
|
function createRepoResolver() {
|
|
6813
7195
|
const cache = /* @__PURE__ */ new Map();
|
|
6814
7196
|
return (dir) => {
|
|
6815
|
-
if (!dir || !
|
|
7197
|
+
if (!dir || !isAbsolute2(dir)) return null;
|
|
6816
7198
|
const hit = cache.get(dir);
|
|
6817
7199
|
if (hit !== void 0) return hit;
|
|
6818
7200
|
let repo = null;
|
|
6819
7201
|
try {
|
|
6820
|
-
for (let d = dir; ; d =
|
|
7202
|
+
for (let d = dir; ; d = dirname5(d)) {
|
|
6821
7203
|
const config = gitConfigPathFor(d);
|
|
6822
|
-
if (config &&
|
|
6823
|
-
const url =
|
|
7204
|
+
if (config && existsSync7(config)) {
|
|
7205
|
+
const url = originUrl2(readFileSync10(config, "utf8"));
|
|
6824
7206
|
repo = url ? parseGithubRemote(url) : null;
|
|
6825
7207
|
break;
|
|
6826
7208
|
}
|
|
6827
|
-
if (d ===
|
|
7209
|
+
if (d === dirname5(d)) break;
|
|
6828
7210
|
}
|
|
6829
7211
|
} catch {
|
|
6830
7212
|
repo = null;
|
|
@@ -6836,17 +7218,17 @@ function createRepoResolver() {
|
|
|
6836
7218
|
|
|
6837
7219
|
// src/team/queue.ts
|
|
6838
7220
|
init_fs();
|
|
6839
|
-
import { readFileSync as
|
|
6840
|
-
import { dirname as
|
|
7221
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, appendFileSync as appendFileSync4, statSync as statSync4, mkdirSync as mkdirSync6 } from "node:fs";
|
|
7222
|
+
import { dirname as dirname6 } from "node:path";
|
|
6841
7223
|
var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
|
|
6842
7224
|
var MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
6843
7225
|
var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
6844
7226
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
6845
|
-
|
|
7227
|
+
mkdirSync6(dirname6(queuePath), { recursive: true });
|
|
6846
7228
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
6847
|
-
|
|
7229
|
+
appendFileSync4(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
6848
7230
|
try {
|
|
6849
|
-
const { size } =
|
|
7231
|
+
const { size } = statSync4(queuePath);
|
|
6850
7232
|
if (size > MAX_SIZE_BYTES) {
|
|
6851
7233
|
pruneOldest(queuePath);
|
|
6852
7234
|
}
|
|
@@ -6856,7 +7238,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
6856
7238
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
6857
7239
|
let lines;
|
|
6858
7240
|
try {
|
|
6859
|
-
lines =
|
|
7241
|
+
lines = readFileSync11(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
6860
7242
|
} catch {
|
|
6861
7243
|
return [];
|
|
6862
7244
|
}
|
|
@@ -6871,18 +7253,18 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
6871
7253
|
} catch {
|
|
6872
7254
|
}
|
|
6873
7255
|
}
|
|
6874
|
-
|
|
7256
|
+
writeFileSync6(queuePath, "", "utf8");
|
|
6875
7257
|
return valid.map((e) => e.payload);
|
|
6876
7258
|
}
|
|
6877
7259
|
function pruneOldest(queuePath) {
|
|
6878
7260
|
let lines;
|
|
6879
7261
|
try {
|
|
6880
|
-
lines =
|
|
7262
|
+
lines = readFileSync11(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
6881
7263
|
} catch {
|
|
6882
7264
|
return;
|
|
6883
7265
|
}
|
|
6884
7266
|
const keep = lines.slice(Math.floor(lines.length / 2));
|
|
6885
|
-
|
|
7267
|
+
writeFileSync6(queuePath, keep.join("\n") + "\n", "utf8");
|
|
6886
7268
|
}
|
|
6887
7269
|
|
|
6888
7270
|
// src/team/backfill.ts
|
|
@@ -6890,8 +7272,8 @@ init_storage();
|
|
|
6890
7272
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
6891
7273
|
|
|
6892
7274
|
// src/usage/profile.ts
|
|
6893
|
-
import { existsSync as
|
|
6894
|
-
import { dirname as
|
|
7275
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "node:fs";
|
|
7276
|
+
import { dirname as dirname7 } from "node:path";
|
|
6895
7277
|
var PROFILE_ENDPOINT = "https://api.anthropic.com/api/oauth/profile";
|
|
6896
7278
|
var BETA_HEADER2 = "oauth-2025-04-20";
|
|
6897
7279
|
var PROFILE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -6934,9 +7316,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
6934
7316
|
};
|
|
6935
7317
|
}
|
|
6936
7318
|
function readCachedProfile(cachePath) {
|
|
6937
|
-
if (!
|
|
7319
|
+
if (!existsSync8(cachePath)) return null;
|
|
6938
7320
|
try {
|
|
6939
|
-
const raw = JSON.parse(
|
|
7321
|
+
const raw = JSON.parse(readFileSync12(cachePath, "utf8"));
|
|
6940
7322
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
6941
7323
|
return raw;
|
|
6942
7324
|
} catch {
|
|
@@ -6944,8 +7326,8 @@ function readCachedProfile(cachePath) {
|
|
|
6944
7326
|
}
|
|
6945
7327
|
}
|
|
6946
7328
|
function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
|
|
6947
|
-
|
|
6948
|
-
|
|
7329
|
+
mkdirSync7(dirname7(cachePath), { recursive: true });
|
|
7330
|
+
writeFileSync7(
|
|
6949
7331
|
cachePath,
|
|
6950
7332
|
JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
|
|
6951
7333
|
{ mode: 384 }
|
|
@@ -7105,13 +7487,13 @@ async function runTeamBackfill(log3 = noopLog, filePath = USAGE_LOG, configOverr
|
|
|
7105
7487
|
|
|
7106
7488
|
// src/team/sync-log.ts
|
|
7107
7489
|
init_fs();
|
|
7108
|
-
import { readFileSync as
|
|
7490
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
7109
7491
|
var MAX_LINES = 300;
|
|
7110
7492
|
var MAX_MSG_CHARS = 1900;
|
|
7111
7493
|
function readPendingSyncLog(watermark) {
|
|
7112
7494
|
let raw;
|
|
7113
7495
|
try {
|
|
7114
|
-
raw =
|
|
7496
|
+
raw = readFileSync13(cclensPath("daemon.log"), "utf8");
|
|
7115
7497
|
} catch {
|
|
7116
7498
|
return { lines: [] };
|
|
7117
7499
|
}
|
|
@@ -7131,13 +7513,13 @@ function readPendingSyncLog(watermark) {
|
|
|
7131
7513
|
|
|
7132
7514
|
// src/team/last-push.ts
|
|
7133
7515
|
init_fs();
|
|
7134
|
-
import { writeFileSync as
|
|
7135
|
-
import { join as
|
|
7516
|
+
import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "node:fs";
|
|
7517
|
+
import { join as join7 } from "node:path";
|
|
7136
7518
|
var LAST_PUSH_FILE = "team-last-push.json";
|
|
7137
7519
|
function write(record, dir) {
|
|
7138
7520
|
const d = dir ?? cclensHome();
|
|
7139
|
-
|
|
7140
|
-
|
|
7521
|
+
mkdirSync8(d, { recursive: true });
|
|
7522
|
+
writeFileSync8(join7(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
7141
7523
|
}
|
|
7142
7524
|
function writeLastPushSuccess(payload, dir) {
|
|
7143
7525
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -7161,8 +7543,8 @@ async function dispatchCommand(command, config, log3) {
|
|
|
7161
7543
|
}
|
|
7162
7544
|
}
|
|
7163
7545
|
async function runActivityBackfill(command, config, log3) {
|
|
7164
|
-
const { listSessions: listSessions2, shouldSyncProject: shouldSyncProject2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
7165
|
-
const { toLocalDay: toLocalDay3,
|
|
7546
|
+
const { listSessions: listSessions2, resolveProjectIdentity: resolveProjectIdentity2, shouldSyncProject: shouldSyncProject2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
7547
|
+
const { toLocalDay: toLocalDay3, projectKey: projectKey2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
7166
7548
|
const { probeArtifactSignals: probeArtifactSignals2 } = await Promise.resolve().then(() => (init_file_probe(), file_probe_exports));
|
|
7167
7549
|
const days = command.params.days;
|
|
7168
7550
|
const todayMs = Date.now();
|
|
@@ -7196,7 +7578,7 @@ async function runActivityBackfill(command, config, log3) {
|
|
|
7196
7578
|
const richBlocks = buildRichBlocksForDay(rollup.day, daySessions, resolveRepo);
|
|
7197
7579
|
let artifactSignals = null;
|
|
7198
7580
|
try {
|
|
7199
|
-
const cwdAllowed = shouldSyncProject2(
|
|
7581
|
+
const cwdAllowed = shouldSyncProject2(projectKey2(resolveProjectIdentity2(process.cwd()).projectName), config.syncProjects);
|
|
7200
7582
|
artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: cwdAllowed ? [process.cwd()] : [] });
|
|
7201
7583
|
} catch {
|
|
7202
7584
|
}
|
|
@@ -7227,6 +7609,7 @@ async function runActivityBackfill(command, config, log3) {
|
|
|
7227
7609
|
}
|
|
7228
7610
|
|
|
7229
7611
|
// src/team/sync.ts
|
|
7612
|
+
init_dist();
|
|
7230
7613
|
init_fs();
|
|
7231
7614
|
var inFlightCommands = /* @__PURE__ */ new Set();
|
|
7232
7615
|
var USAGE_LOG2 = cclensPath("usage.jsonl");
|
|
@@ -7341,7 +7724,7 @@ async function runTeamSync(log3 = noopLog2, configOverride, options = {}) {
|
|
|
7341
7724
|
try {
|
|
7342
7725
|
resetEnsuredSessions();
|
|
7343
7726
|
const { listSessions: listSessions2, loadCalibrationCurve: loadCalibrationCurve2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
7344
|
-
const { toLocalDay: toLocalDay3
|
|
7727
|
+
const { toLocalDay: toLocalDay3 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
7345
7728
|
const today = toLocalDay3(Date.now());
|
|
7346
7729
|
let patches = {};
|
|
7347
7730
|
const persistConfig = (patch) => {
|
|
@@ -7528,7 +7911,7 @@ async function runTeamSync(log3 = noopLog2, configOverride, options = {}) {
|
|
|
7528
7911
|
} : void 0;
|
|
7529
7912
|
let artifactSignals = null;
|
|
7530
7913
|
try {
|
|
7531
|
-
const cwdAllowed = shouldSyncProject(
|
|
7914
|
+
const cwdAllowed = shouldSyncProject(projectKey(resolveProjectIdentity(process.cwd()).projectName), config.syncProjects);
|
|
7532
7915
|
artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: cwdAllowed ? [process.cwd()] : [] });
|
|
7533
7916
|
} catch {
|
|
7534
7917
|
}
|
|
@@ -7715,13 +8098,13 @@ async function buildCyclePeaksForPush(planTier, loadCurve) {
|
|
|
7715
8098
|
}
|
|
7716
8099
|
|
|
7717
8100
|
// src/perception/worker.ts
|
|
7718
|
-
import { statSync as
|
|
8101
|
+
import { statSync as statSync6 } from "node:fs";
|
|
7719
8102
|
init_fs();
|
|
7720
8103
|
|
|
7721
8104
|
// src/perception/state.ts
|
|
7722
8105
|
init_fs();
|
|
7723
|
-
import { existsSync as
|
|
7724
|
-
import { dirname as
|
|
8106
|
+
import { existsSync as existsSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
|
|
8107
|
+
import { dirname as dirname9 } from "node:path";
|
|
7725
8108
|
var STALE_MS = 15 * 60 * 1e3;
|
|
7726
8109
|
var pathCached = null;
|
|
7727
8110
|
function statePath() {
|
|
@@ -7731,7 +8114,7 @@ function statePath() {
|
|
|
7731
8114
|
}
|
|
7732
8115
|
function readState() {
|
|
7733
8116
|
const p = statePath();
|
|
7734
|
-
if (!
|
|
8117
|
+
if (!existsSync10(p)) {
|
|
7735
8118
|
return {
|
|
7736
8119
|
sweep_in_progress: false,
|
|
7737
8120
|
last_sweep_started_at: null,
|
|
@@ -7739,14 +8122,14 @@ function readState() {
|
|
|
7739
8122
|
file_checkpoints: {}
|
|
7740
8123
|
};
|
|
7741
8124
|
}
|
|
7742
|
-
const raw =
|
|
8125
|
+
const raw = readFileSync14(p, "utf8");
|
|
7743
8126
|
return JSON.parse(raw);
|
|
7744
8127
|
}
|
|
7745
8128
|
function writeState(s) {
|
|
7746
8129
|
const p = statePath();
|
|
7747
|
-
|
|
8130
|
+
mkdirSync9(dirname9(p), { recursive: true });
|
|
7748
8131
|
const tmp = `${p}.tmp`;
|
|
7749
|
-
|
|
8132
|
+
writeFileSync9(tmp, JSON.stringify(s, null, 2), "utf8");
|
|
7750
8133
|
renameSync4(tmp, p);
|
|
7751
8134
|
}
|
|
7752
8135
|
function markSweepStart() {
|
|
@@ -7776,17 +8159,17 @@ function updateCheckpoint(jsonlPath, cp) {
|
|
|
7776
8159
|
|
|
7777
8160
|
// src/perception/scan.ts
|
|
7778
8161
|
import { readdirSync as readdirSync4 } from "node:fs";
|
|
7779
|
-
import { join as
|
|
7780
|
-
import { homedir as
|
|
8162
|
+
import { join as join9 } from "node:path";
|
|
8163
|
+
import { homedir as homedir4 } from "node:os";
|
|
7781
8164
|
async function listAllSessionJsonls(root) {
|
|
7782
|
-
const projectsRoot = root ??
|
|
8165
|
+
const projectsRoot = root ?? join9(homedir4(), ".claude", "projects");
|
|
7783
8166
|
const out = [];
|
|
7784
8167
|
try {
|
|
7785
8168
|
for (const project of readdirSync4(projectsRoot)) {
|
|
7786
|
-
const dir =
|
|
8169
|
+
const dir = join9(projectsRoot, project);
|
|
7787
8170
|
try {
|
|
7788
8171
|
for (const f of readdirSync4(dir)) {
|
|
7789
|
-
if (f.endsWith(".jsonl")) out.push(
|
|
8172
|
+
if (f.endsWith(".jsonl")) out.push(join9(dir, f));
|
|
7790
8173
|
}
|
|
7791
8174
|
} catch {
|
|
7792
8175
|
}
|
|
@@ -7813,7 +8196,7 @@ async function runPerceptionSweep(opts = {}) {
|
|
|
7813
8196
|
const files = await listAllSessionJsonls(opts.projectsRoot);
|
|
7814
8197
|
for (const f of files) {
|
|
7815
8198
|
try {
|
|
7816
|
-
const stat =
|
|
8199
|
+
const stat = statSync6(f);
|
|
7817
8200
|
const prev = state.file_checkpoints[f];
|
|
7818
8201
|
if (prev && prev.byte_offset >= stat.size) continue;
|
|
7819
8202
|
const built = buildEntriesForFile(f);
|
|
@@ -7845,7 +8228,7 @@ async function runPerceptionSweep(opts = {}) {
|
|
|
7845
8228
|
const built = buildEntries(detail);
|
|
7846
8229
|
for (const e of built) {
|
|
7847
8230
|
try {
|
|
7848
|
-
const stat =
|
|
8231
|
+
const stat = statSync6(meta.filePath);
|
|
7849
8232
|
e.source_checkpoint.byte_offset = stat.size;
|
|
7850
8233
|
} catch {
|
|
7851
8234
|
}
|
|
@@ -12002,14 +12385,14 @@ var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
|
|
|
12002
12385
|
// ../entries/dist/llm-runner.js
|
|
12003
12386
|
init_fs();
|
|
12004
12387
|
import { spawn } from "node:child_process";
|
|
12005
|
-
import { mkdirSync as
|
|
12006
|
-
import { join as
|
|
12388
|
+
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync11, existsSync as existsSync12 } from "node:fs";
|
|
12389
|
+
import { join as join11 } from "node:path";
|
|
12007
12390
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
12008
12391
|
|
|
12009
12392
|
// ../entries/dist/tmux-runner.js
|
|
12010
|
-
import { mkdirSync as
|
|
12011
|
-
import { join as
|
|
12012
|
-
import { homedir as
|
|
12393
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10, existsSync as existsSync11, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync15, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
|
|
12394
|
+
import { join as join10 } from "node:path";
|
|
12395
|
+
import { homedir as homedir5 } from "node:os";
|
|
12013
12396
|
import { spawnSync } from "node:child_process";
|
|
12014
12397
|
var TmuxUnavailableError = class extends Error {
|
|
12015
12398
|
constructor(message) {
|
|
@@ -12037,16 +12420,16 @@ function tmuxRunnerAvailable() {
|
|
|
12037
12420
|
return { ok: true };
|
|
12038
12421
|
}
|
|
12039
12422
|
function runtimeCwd() {
|
|
12040
|
-
const dir =
|
|
12041
|
-
if (!
|
|
12042
|
-
|
|
12043
|
-
return
|
|
12423
|
+
const dir = join10(homedir5(), ".cclens", "runtime");
|
|
12424
|
+
if (!existsSync11(dir))
|
|
12425
|
+
mkdirSync10(dir, { recursive: true });
|
|
12426
|
+
return realpathSync2(dir);
|
|
12044
12427
|
}
|
|
12045
12428
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
12046
|
-
const cfgPath =
|
|
12429
|
+
const cfgPath = join10(homedir5(), ".claude.json");
|
|
12047
12430
|
let cfg;
|
|
12048
12431
|
try {
|
|
12049
|
-
cfg = JSON.parse(
|
|
12432
|
+
cfg = JSON.parse(readFileSync15(cfgPath, "utf8"));
|
|
12050
12433
|
} catch {
|
|
12051
12434
|
return;
|
|
12052
12435
|
}
|
|
@@ -12061,7 +12444,7 @@ function ensureRuntimeCwdTrusted(cwd) {
|
|
|
12061
12444
|
cfg.projects = projects;
|
|
12062
12445
|
const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
|
|
12063
12446
|
try {
|
|
12064
|
-
|
|
12447
|
+
writeFileSync10(tmp, JSON.stringify(cfg, null, 2));
|
|
12065
12448
|
renameSync5(tmp, cfgPath);
|
|
12066
12449
|
} catch {
|
|
12067
12450
|
try {
|
|
@@ -12089,16 +12472,16 @@ async function runClaudeUnderTmuxImpl(args) {
|
|
|
12089
12472
|
ensureRuntimeCwdTrusted(cwd);
|
|
12090
12473
|
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
12091
12474
|
const sessionName = `cclens-${runId}`;
|
|
12092
|
-
const systemFile =
|
|
12093
|
-
const userFile =
|
|
12094
|
-
const wrapper =
|
|
12095
|
-
|
|
12096
|
-
|
|
12475
|
+
const systemFile = join10(cwd, `system-${runId}.txt`);
|
|
12476
|
+
const userFile = join10(cwd, `user-${runId}.txt`);
|
|
12477
|
+
const wrapper = join10(cwd, `run-${runId}.sh`);
|
|
12478
|
+
writeFileSync10(systemFile, args.systemPrompt);
|
|
12479
|
+
writeFileSync10(userFile, args.reminder ? `${args.userPrompt}
|
|
12097
12480
|
|
|
12098
12481
|
---
|
|
12099
12482
|
|
|
12100
12483
|
${args.reminder}` : args.userPrompt);
|
|
12101
|
-
|
|
12484
|
+
writeFileSync10(wrapper, `#!/bin/bash
|
|
12102
12485
|
SYS="$(cat ${shellEscape(systemFile)})"
|
|
12103
12486
|
USR="$(cat ${shellEscape(userFile)})"
|
|
12104
12487
|
exec ${shellEscape(claudeBin)} \\
|
|
@@ -12170,7 +12553,7 @@ function num(v) {
|
|
|
12170
12553
|
function sleep(ms) {
|
|
12171
12554
|
return new Promise((r) => setTimeout(r, ms));
|
|
12172
12555
|
}
|
|
12173
|
-
var PROJECTS_ROOT = () =>
|
|
12556
|
+
var PROJECTS_ROOT = () => join10(homedir5(), ".claude", "projects");
|
|
12174
12557
|
function snapshotAllTranscripts() {
|
|
12175
12558
|
const out = /* @__PURE__ */ new Set();
|
|
12176
12559
|
const root = PROJECTS_ROOT();
|
|
@@ -12181,7 +12564,7 @@ function snapshotAllTranscripts() {
|
|
|
12181
12564
|
return out;
|
|
12182
12565
|
}
|
|
12183
12566
|
for (const sub of subs) {
|
|
12184
|
-
const dir =
|
|
12567
|
+
const dir = join10(root, sub);
|
|
12185
12568
|
let files;
|
|
12186
12569
|
try {
|
|
12187
12570
|
files = readdirSync5(dir);
|
|
@@ -12190,7 +12573,7 @@ function snapshotAllTranscripts() {
|
|
|
12190
12573
|
}
|
|
12191
12574
|
for (const f of files) {
|
|
12192
12575
|
if (f.endsWith(".jsonl"))
|
|
12193
|
-
out.add(
|
|
12576
|
+
out.add(join10(dir, f));
|
|
12194
12577
|
}
|
|
12195
12578
|
}
|
|
12196
12579
|
return out;
|
|
@@ -12198,7 +12581,7 @@ function snapshotAllTranscripts() {
|
|
|
12198
12581
|
function readJsonlCwd(path7, maxLines = 8) {
|
|
12199
12582
|
let raw;
|
|
12200
12583
|
try {
|
|
12201
|
-
raw =
|
|
12584
|
+
raw = readFileSync15(path7, "utf8");
|
|
12202
12585
|
} catch {
|
|
12203
12586
|
return void 0;
|
|
12204
12587
|
}
|
|
@@ -12231,7 +12614,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12231
12614
|
subs = [];
|
|
12232
12615
|
}
|
|
12233
12616
|
for (const sub of subs) {
|
|
12234
|
-
const dir =
|
|
12617
|
+
const dir = join10(root, sub);
|
|
12235
12618
|
let files;
|
|
12236
12619
|
try {
|
|
12237
12620
|
files = readdirSync5(dir);
|
|
@@ -12241,7 +12624,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12241
12624
|
for (const f of files) {
|
|
12242
12625
|
if (!f.endsWith(".jsonl"))
|
|
12243
12626
|
continue;
|
|
12244
|
-
const full =
|
|
12627
|
+
const full = join10(dir, f);
|
|
12245
12628
|
if (existingBefore.has(full))
|
|
12246
12629
|
continue;
|
|
12247
12630
|
if (readJsonlCwd(full) === targetCwd)
|
|
@@ -12255,7 +12638,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12255
12638
|
function parseTranscript2(path7, defaultModel) {
|
|
12256
12639
|
let raw;
|
|
12257
12640
|
try {
|
|
12258
|
-
raw =
|
|
12641
|
+
raw = readFileSync15(path7, "utf8");
|
|
12259
12642
|
} catch {
|
|
12260
12643
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
12261
12644
|
}
|
|
@@ -12315,7 +12698,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
|
|
|
12315
12698
|
}
|
|
12316
12699
|
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
12317
12700
|
try {
|
|
12318
|
-
unlinkSync3(
|
|
12701
|
+
unlinkSync3(join10(cwd, f));
|
|
12319
12702
|
} catch {
|
|
12320
12703
|
}
|
|
12321
12704
|
}
|
|
@@ -12330,9 +12713,9 @@ function shellEscape(s) {
|
|
|
12330
12713
|
// ../entries/dist/llm-runner.js
|
|
12331
12714
|
var RUNS_DIR = cclensPath("llm-runs");
|
|
12332
12715
|
function ensureRunsDir() {
|
|
12333
|
-
if (!
|
|
12716
|
+
if (!existsSync12(RUNS_DIR)) {
|
|
12334
12717
|
try {
|
|
12335
|
-
|
|
12718
|
+
mkdirSync11(RUNS_DIR, { recursive: true });
|
|
12336
12719
|
} catch {
|
|
12337
12720
|
}
|
|
12338
12721
|
}
|
|
@@ -12359,17 +12742,17 @@ function newRunId(kind) {
|
|
|
12359
12742
|
return `${ts}_${kind}_${short}`;
|
|
12360
12743
|
}
|
|
12361
12744
|
function tracePath(runId) {
|
|
12362
|
-
return
|
|
12745
|
+
return join11(RUNS_DIR, `${runId}.jsonl`);
|
|
12363
12746
|
}
|
|
12364
12747
|
function safeAppend(path7, line) {
|
|
12365
12748
|
try {
|
|
12366
|
-
|
|
12749
|
+
appendFileSync5(path7, line);
|
|
12367
12750
|
} catch {
|
|
12368
12751
|
}
|
|
12369
12752
|
}
|
|
12370
12753
|
function safeWrite(path7, line) {
|
|
12371
12754
|
try {
|
|
12372
|
-
|
|
12755
|
+
writeFileSync11(path7, line);
|
|
12373
12756
|
} catch {
|
|
12374
12757
|
}
|
|
12375
12758
|
}
|
|
@@ -12447,7 +12830,7 @@ async function runClaudeSubprocess(args) {
|
|
|
12447
12830
|
return runClaudePrintMode(args);
|
|
12448
12831
|
}
|
|
12449
12832
|
function runClaudePrintMode(args) {
|
|
12450
|
-
return new Promise((
|
|
12833
|
+
return new Promise((resolve4, reject) => {
|
|
12451
12834
|
ensureRunsDir();
|
|
12452
12835
|
const kind = detectKindFromSystemPrompt(args.systemPrompt);
|
|
12453
12836
|
const runId = newRunId(kind);
|
|
@@ -12578,7 +12961,7 @@ ${args.reminder}` : args.userPrompt;
|
|
|
12578
12961
|
reject(new Error(`claude exited ${code}: ${stderr.trim().slice(0, 300)}`));
|
|
12579
12962
|
return;
|
|
12580
12963
|
}
|
|
12581
|
-
|
|
12964
|
+
resolve4({ content: buffer, input_tokens: inputTokens, output_tokens: outputTokens, model: modelUsed });
|
|
12582
12965
|
});
|
|
12583
12966
|
proc.on("error", (err) => {
|
|
12584
12967
|
safeAppend(trace, JSON.stringify({ _meta: { type: "spawn_error", run_id: runId, ts: (/* @__PURE__ */ new Date()).toISOString(), error: err.message } }) + "\n");
|
|
@@ -12758,8 +13141,8 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
|
|
|
12758
13141
|
|
|
12759
13142
|
// ../entries/dist/budget.js
|
|
12760
13143
|
init_fs();
|
|
12761
|
-
import { appendFileSync as
|
|
12762
|
-
import { dirname as
|
|
13144
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync16, existsSync as existsSync13, mkdirSync as mkdirSync12 } from "node:fs";
|
|
13145
|
+
import { dirname as dirname10 } from "node:path";
|
|
12763
13146
|
var spendPathCached = null;
|
|
12764
13147
|
function spendPath() {
|
|
12765
13148
|
if (spendPathCached)
|
|
@@ -12769,17 +13152,17 @@ function spendPath() {
|
|
|
12769
13152
|
}
|
|
12770
13153
|
function appendSpend(record) {
|
|
12771
13154
|
const p = spendPath();
|
|
12772
|
-
|
|
12773
|
-
|
|
13155
|
+
mkdirSync12(dirname10(p), { recursive: true });
|
|
13156
|
+
appendFileSync6(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
12774
13157
|
}
|
|
12775
13158
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
12776
13159
|
const p = spendPath();
|
|
12777
|
-
if (!
|
|
13160
|
+
if (!existsSync13(p))
|
|
12778
13161
|
return 0;
|
|
12779
13162
|
const year = now.getUTCFullYear();
|
|
12780
13163
|
const month = now.getUTCMonth();
|
|
12781
13164
|
let total = 0;
|
|
12782
|
-
const raw =
|
|
13165
|
+
const raw = readFileSync16(p, "utf8");
|
|
12783
13166
|
for (const line of raw.split("\n")) {
|
|
12784
13167
|
if (!line)
|
|
12785
13168
|
continue;
|
|
@@ -12801,7 +13184,7 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
|
12801
13184
|
|
|
12802
13185
|
// ../entries/dist/pipeline-lock.js
|
|
12803
13186
|
init_fs();
|
|
12804
|
-
import { writeFileSync as
|
|
13187
|
+
import { writeFileSync as writeFileSync12, unlinkSync as unlinkSync4, existsSync as existsSync14, readFileSync as readFileSync17, statSync as statSync7 } from "node:fs";
|
|
12805
13188
|
var STALE_MS2 = 60 * 1e3;
|
|
12806
13189
|
var HEARTBEAT_MS = 30 * 1e3;
|
|
12807
13190
|
var lockPathCached = null;
|
|
@@ -12813,7 +13196,7 @@ function lockPath() {
|
|
|
12813
13196
|
return lockPathCached;
|
|
12814
13197
|
}
|
|
12815
13198
|
function touchLock() {
|
|
12816
|
-
|
|
13199
|
+
writeFileSync12(lockPath(), String(process.pid), "utf8");
|
|
12817
13200
|
}
|
|
12818
13201
|
function writeInteractiveLock() {
|
|
12819
13202
|
touchLock();
|
|
@@ -12847,13 +13230,13 @@ function pidAlive(pid) {
|
|
|
12847
13230
|
}
|
|
12848
13231
|
function interactiveLockFresh(nowMs) {
|
|
12849
13232
|
const p = lockPath();
|
|
12850
|
-
if (!
|
|
13233
|
+
if (!existsSync14(p))
|
|
12851
13234
|
return false;
|
|
12852
13235
|
try {
|
|
12853
|
-
const mtime =
|
|
13236
|
+
const mtime = statSync7(p).mtimeMs;
|
|
12854
13237
|
if (nowMs - mtime > STALE_MS2)
|
|
12855
13238
|
return false;
|
|
12856
|
-
const pid = Number(
|
|
13239
|
+
const pid = Number(readFileSync17(p, "utf8").trim());
|
|
12857
13240
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
12858
13241
|
return false;
|
|
12859
13242
|
if (!pidAlive(pid))
|
|
@@ -12868,7 +13251,7 @@ function interactiveLockFresh(nowMs) {
|
|
|
12868
13251
|
var THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
12869
13252
|
|
|
12870
13253
|
// ../entries/dist/settings.js
|
|
12871
|
-
import { readFileSync as
|
|
13254
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync13, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync15 } from "node:fs";
|
|
12872
13255
|
init_fs();
|
|
12873
13256
|
var DEFAULT_SETTINGS = {
|
|
12874
13257
|
ai_features: {
|
|
@@ -12900,10 +13283,10 @@ function fromDisk(d) {
|
|
|
12900
13283
|
}
|
|
12901
13284
|
function readSettings() {
|
|
12902
13285
|
const p = settingsPath();
|
|
12903
|
-
if (!
|
|
13286
|
+
if (!existsSync15(p))
|
|
12904
13287
|
return DEFAULT_SETTINGS;
|
|
12905
13288
|
try {
|
|
12906
|
-
const raw =
|
|
13289
|
+
const raw = readFileSync18(p, "utf8");
|
|
12907
13290
|
return fromDisk(JSON.parse(raw));
|
|
12908
13291
|
} catch {
|
|
12909
13292
|
return DEFAULT_SETTINGS;
|
|
@@ -15512,6 +15895,9 @@ async function* runWeekDigestPipeline(monday, opts) {
|
|
|
15512
15895
|
}
|
|
15513
15896
|
}
|
|
15514
15897
|
|
|
15898
|
+
// ../entries/dist/credentials.js
|
|
15899
|
+
init_fs();
|
|
15900
|
+
|
|
15515
15901
|
// src/perception/backfill.ts
|
|
15516
15902
|
function toLocalDay2(ms) {
|
|
15517
15903
|
const d = new Date(ms);
|
|
@@ -15660,14 +16046,14 @@ async function getUpdateAvailability() {
|
|
|
15660
16046
|
if (isDevMode()) return null;
|
|
15661
16047
|
const latest = await fetchLatestVersion();
|
|
15662
16048
|
if (latest === null) return {
|
|
15663
|
-
current: "0.15.
|
|
16049
|
+
current: "0.15.4",
|
|
15664
16050
|
latest: null,
|
|
15665
16051
|
updateAvailable: false
|
|
15666
16052
|
};
|
|
15667
16053
|
return {
|
|
15668
|
-
current: "0.15.
|
|
16054
|
+
current: "0.15.4",
|
|
15669
16055
|
latest,
|
|
15670
|
-
updateAvailable: shouldUpdate("0.15.
|
|
16056
|
+
updateAvailable: shouldUpdate("0.15.4", latest)
|
|
15671
16057
|
};
|
|
15672
16058
|
}
|
|
15673
16059
|
|
|
@@ -15677,7 +16063,7 @@ var DAEMON_LOG = cclensPath("daemon.log");
|
|
|
15677
16063
|
var UPDATE_STATE = cclensPath("daemon-update.json");
|
|
15678
16064
|
var WATCHDOG_INTERVAL_MS = 5 * 1e3;
|
|
15679
16065
|
var AUTO_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
15680
|
-
|
|
16066
|
+
mkdirSync14(dirname11(USAGE_LOG3), { recursive: true });
|
|
15681
16067
|
function log2(level, message) {
|
|
15682
16068
|
appendDaemonLogLine(level, message);
|
|
15683
16069
|
}
|
|
@@ -15715,14 +16101,14 @@ var perceptionHandle = setInterval(async () => {
|
|
|
15715
16101
|
}, PERCEPTION_INTERVAL_MS);
|
|
15716
16102
|
function readUpdateState() {
|
|
15717
16103
|
try {
|
|
15718
|
-
return JSON.parse(
|
|
16104
|
+
return JSON.parse(readFileSync19(UPDATE_STATE, "utf8"));
|
|
15719
16105
|
} catch {
|
|
15720
16106
|
return null;
|
|
15721
16107
|
}
|
|
15722
16108
|
}
|
|
15723
16109
|
function writeUpdateState(state) {
|
|
15724
16110
|
try {
|
|
15725
|
-
|
|
16111
|
+
writeFileSync14(UPDATE_STATE, JSON.stringify(state, null, 2), { mode: 384 });
|
|
15726
16112
|
} catch {
|
|
15727
16113
|
}
|
|
15728
16114
|
}
|
|
@@ -15735,7 +16121,7 @@ function nextUpdateCheckFromState(nowMs) {
|
|
|
15735
16121
|
}
|
|
15736
16122
|
var nextUpdateCheckAtMs = nextUpdateCheckFromState(Date.now());
|
|
15737
16123
|
function cliEntryPath() {
|
|
15738
|
-
return
|
|
16124
|
+
return join12(dirname11(fileURLToPath(import.meta.url)), "index.js");
|
|
15739
16125
|
}
|
|
15740
16126
|
async function runDaemonUpdateCheck() {
|
|
15741
16127
|
if (process.env.FLEETLENS_DAEMON_AUTO_UPDATE === "0") {
|
|
@@ -15767,7 +16153,7 @@ async function runDaemonUpdateCheck() {
|
|
|
15767
16153
|
return;
|
|
15768
16154
|
}
|
|
15769
16155
|
const entry = cliEntryPath();
|
|
15770
|
-
if (!
|
|
16156
|
+
if (!existsSync16(entry)) {
|
|
15771
16157
|
log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
|
|
15772
16158
|
return;
|
|
15773
16159
|
}
|
|
@@ -15830,6 +16216,20 @@ async function tick() {
|
|
|
15830
16216
|
log2("warn", `${source.kind} poll failed: ${err.message}`);
|
|
15831
16217
|
}
|
|
15832
16218
|
}
|
|
16219
|
+
try {
|
|
16220
|
+
const zaiSnapshot = await fetchZaiUsage();
|
|
16221
|
+
appendSnapshot(USAGE_LOG3, zaiSnapshot);
|
|
16222
|
+
log2(
|
|
16223
|
+
"info",
|
|
16224
|
+
`zai snapshot 5h=${zaiSnapshot.five_hour.utilization}% 7d=${zaiSnapshot.seven_day.utilization}%`
|
|
16225
|
+
);
|
|
16226
|
+
} catch (err) {
|
|
16227
|
+
if (err instanceof ZaiApiError && err.code === "no_key") {
|
|
16228
|
+
pruneAgent(USAGE_LOG3, "zai");
|
|
16229
|
+
} else {
|
|
16230
|
+
log2("warn", `zai poll failed: ${err.message}`);
|
|
16231
|
+
}
|
|
16232
|
+
}
|
|
15833
16233
|
try {
|
|
15834
16234
|
const snapshot = await fetchUsage();
|
|
15835
16235
|
appendSnapshot(USAGE_LOG3, snapshot);
|
|
@@ -15859,7 +16259,7 @@ function scheduleAfter(now, outcome) {
|
|
|
15859
16259
|
nextPollAtMs = now + currentIntervalMs;
|
|
15860
16260
|
}
|
|
15861
16261
|
function sleep2(ms) {
|
|
15862
|
-
return new Promise((
|
|
16262
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
15863
16263
|
}
|
|
15864
16264
|
async function runLoop() {
|
|
15865
16265
|
while (true) {
|