fleetlens 0.15.2 → 0.15.3
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 +1 -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 +6 -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.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/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/route.js.nft.json +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.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.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.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.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.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.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.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.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.nft.json +1 -1
- package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/projects/page.js.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.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.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.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.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.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.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.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 +1 -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/[root-of-the-server]__12iid50._.js +3 -0
- 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]__0c00i76._.js +1 -1
- 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]__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/{_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/_0xu2pvc._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_13jdm1g._.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_0txtsv5._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_12vc-v-._.js +3 -0
- 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 +1 -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~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/0_ujxc0.z66xb.js +14 -0
- package/app/apps/web/.next/static/chunks/0awkd5df28gvj.js +6 -0
- package/app/apps/web/.next/static/chunks/0bhwd68o~-xc_.js +1 -0
- package/app/apps/web/.next/static/chunks/{0m7dd-2zd9vl2.js → 0eoc4yy0s0gpe.js} +1 -1
- 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/0y3448zrint0k.js +6 -0
- package/app/apps/web/app/api/projects/open-folder/route.ts +60 -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/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/entries-index.ts +4 -4
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +405 -174
- package/dist/index.js +476 -245
- package/package.json +1 -1
- 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]__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_components_0b-4-4j._.js +0 -8
- 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/03gy1evbn94qu.js +0 -6
- 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 → lIz-6F0SEIL9sgFO3XTJp}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{mTj8nKiazosAKJec15dLe → lIz-6F0SEIL9sgFO3XTJp}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{mTj8nKiazosAKJec15dLe → lIz-6F0SEIL9sgFO3XTJp}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -148,11 +148,22 @@ function worktreeName(projectName) {
|
|
|
148
148
|
return ss.workspaceName;
|
|
149
149
|
return null;
|
|
150
150
|
}
|
|
151
|
-
function
|
|
151
|
+
function projectKey(projectName) {
|
|
152
152
|
const canonical = canonicalProjectName(projectName);
|
|
153
153
|
const segs = canonical.replace(/\/+$/, "").split("/").filter(Boolean);
|
|
154
154
|
return segs[segs.length - 1] || canonical;
|
|
155
155
|
}
|
|
156
|
+
function sessionProjectKey(s) {
|
|
157
|
+
return s.repoName ?? projectKey(s.projectName);
|
|
158
|
+
}
|
|
159
|
+
function buildProjectKeyResolver(sessions) {
|
|
160
|
+
const alias = /* @__PURE__ */ new Map();
|
|
161
|
+
for (const s of sessions) {
|
|
162
|
+
if (s.repoName)
|
|
163
|
+
alias.set(projectKey(s.projectName), s.repoName);
|
|
164
|
+
}
|
|
165
|
+
return (s) => s.repoName ?? alias.get(projectKey(s.projectName)) ?? projectKey(s.projectName);
|
|
166
|
+
}
|
|
156
167
|
function makeDay(date) {
|
|
157
168
|
return {
|
|
158
169
|
date,
|
|
@@ -587,8 +598,9 @@ function summarizeBursts(bursts) {
|
|
|
587
598
|
}
|
|
588
599
|
function groupByProject(sessions) {
|
|
589
600
|
const map = /* @__PURE__ */ new Map();
|
|
601
|
+
const keyOf = buildProjectKeyResolver(sessions);
|
|
590
602
|
for (const s of sessions) {
|
|
591
|
-
const repo =
|
|
603
|
+
const repo = keyOf(s);
|
|
592
604
|
const key = repo;
|
|
593
605
|
let cur = map.get(key);
|
|
594
606
|
if (!cur) {
|
|
@@ -617,7 +629,7 @@ function groupByProject(sessions) {
|
|
|
617
629
|
p.metrics = highLevelMetrics(p.sessions);
|
|
618
630
|
const wtNames = /* @__PURE__ */ new Set();
|
|
619
631
|
for (const s of p.sessions) {
|
|
620
|
-
const wt = worktreeName(s.projectName);
|
|
632
|
+
const wt = s.worktreeName ?? worktreeName(s.projectName) ?? (s.cwd ? worktreeName(s.cwd) : null);
|
|
621
633
|
if (wt)
|
|
622
634
|
wtNames.add(wt);
|
|
623
635
|
}
|
|
@@ -636,7 +648,7 @@ function groupByProject(sessions) {
|
|
|
636
648
|
}
|
|
637
649
|
return Array.from(map.values()).sort((a, b) => (b.lastActiveMs ?? 0) - (a.lastActiveMs ?? 0));
|
|
638
650
|
}
|
|
639
|
-
var BLANK_USAGE, WORKTREE_MARKERS, CONDUCTOR_RE, SUPERSET_MARKER, UUID_SEG_RE, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
|
|
651
|
+
var BLANK_USAGE, WORKTREE_MARKERS, CONDUCTOR_RE, SUPERSET_MARKER, UUID_SEG_RE, projectRepoName, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
|
|
640
652
|
var init_analytics = __esm({
|
|
641
653
|
"../parser/dist/analytics.js"() {
|
|
642
654
|
"use strict";
|
|
@@ -649,6 +661,7 @@ var init_analytics = __esm({
|
|
|
649
661
|
CONDUCTOR_RE = /\/conductor\/workspaces\/[^/]+\/([^/]+)(?:\/|$)/;
|
|
650
662
|
SUPERSET_MARKER = "/.superset/worktrees/";
|
|
651
663
|
UUID_SEG_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
664
|
+
projectRepoName = projectKey;
|
|
652
665
|
PR_CREATE_RE = /gh\s+pr\s+create\b/i;
|
|
653
666
|
PR_NUMBER_RE = /#(\d+)/;
|
|
654
667
|
TITLE_FLAG_RE = /--title\s+["']([^"']+)["']/;
|
|
@@ -1447,6 +1460,187 @@ var init_parser = __esm({
|
|
|
1447
1460
|
}
|
|
1448
1461
|
});
|
|
1449
1462
|
|
|
1463
|
+
// ../parser/dist/git-project.js
|
|
1464
|
+
import { existsSync, readFileSync as readFileSync2, realpathSync, statSync } from "node:fs";
|
|
1465
|
+
import { homedir } from "node:os";
|
|
1466
|
+
import { basename, dirname as dirname2, isAbsolute, join, resolve } from "node:path";
|
|
1467
|
+
function resolveGitDir(root, dotGitText) {
|
|
1468
|
+
const m = dotGitText.match(/^gitdir:\s*(.+)\s*$/m);
|
|
1469
|
+
if (!m)
|
|
1470
|
+
return void 0;
|
|
1471
|
+
const gitDir = m[1].trim();
|
|
1472
|
+
return isAbsolute(gitDir) ? gitDir : resolve(root, gitDir);
|
|
1473
|
+
}
|
|
1474
|
+
function resolveCommonDir(gitDir) {
|
|
1475
|
+
const file = join(gitDir, "commondir");
|
|
1476
|
+
if (!existsSync(file))
|
|
1477
|
+
return void 0;
|
|
1478
|
+
const common = readFileSync2(file, "utf8").trim();
|
|
1479
|
+
if (!common)
|
|
1480
|
+
return void 0;
|
|
1481
|
+
return isAbsolute(common) ? common : resolve(gitDir, common);
|
|
1482
|
+
}
|
|
1483
|
+
function dotGitInfoFor(root) {
|
|
1484
|
+
const dotGit = join(root, ".git");
|
|
1485
|
+
const st = statSync(dotGit, { throwIfNoEntry: false });
|
|
1486
|
+
if (!st)
|
|
1487
|
+
return null;
|
|
1488
|
+
if (st.isDirectory())
|
|
1489
|
+
return { root, gitDir: dotGit, commonDir: dotGit };
|
|
1490
|
+
const gitDir = resolveGitDir(root, readFileSync2(dotGit, "utf8"));
|
|
1491
|
+
if (!gitDir)
|
|
1492
|
+
return { root };
|
|
1493
|
+
return { root, gitDir, commonDir: resolveCommonDir(gitDir) };
|
|
1494
|
+
}
|
|
1495
|
+
function walkBoundary(start2) {
|
|
1496
|
+
const home = realpathOrSelf(homedir());
|
|
1497
|
+
return start2 === home || start2.startsWith(`${home}/`) ? home : void 0;
|
|
1498
|
+
}
|
|
1499
|
+
function nearestDotGit(start2) {
|
|
1500
|
+
if (!start2 || !isAbsolute(start2))
|
|
1501
|
+
return null;
|
|
1502
|
+
const boundary = walkBoundary(start2);
|
|
1503
|
+
for (let dir = start2.replace(/\/+$/, "") || start2; ; dir = dirname2(dir)) {
|
|
1504
|
+
if (dir === boundary)
|
|
1505
|
+
return null;
|
|
1506
|
+
const info = dotGitInfoFor(dir);
|
|
1507
|
+
if (info)
|
|
1508
|
+
return info;
|
|
1509
|
+
const parent = dirname2(dir);
|
|
1510
|
+
if (parent === dir)
|
|
1511
|
+
return null;
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
function originUrl(configText) {
|
|
1515
|
+
let inOrigin = false;
|
|
1516
|
+
for (const line of configText.split("\n")) {
|
|
1517
|
+
const t = line.trim();
|
|
1518
|
+
if (t.startsWith("[")) {
|
|
1519
|
+
inOrigin = /^\[remote\s+"origin"\]/.test(t);
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
if (!inOrigin)
|
|
1523
|
+
continue;
|
|
1524
|
+
const m = t.match(/^url\s*=\s*(.+)$/);
|
|
1525
|
+
if (m)
|
|
1526
|
+
return m[1].trim();
|
|
1527
|
+
}
|
|
1528
|
+
return void 0;
|
|
1529
|
+
}
|
|
1530
|
+
function parseRemote(url) {
|
|
1531
|
+
const m = url.match(REMOTE_URL_RE);
|
|
1532
|
+
if (!m)
|
|
1533
|
+
return void 0;
|
|
1534
|
+
const host = m[1];
|
|
1535
|
+
const segs = m[2].split("/").filter(Boolean);
|
|
1536
|
+
if (segs.length < 2)
|
|
1537
|
+
return void 0;
|
|
1538
|
+
const name = segs[segs.length - 1];
|
|
1539
|
+
const owner = segs.slice(0, -1).join("/");
|
|
1540
|
+
return { host, owner, name, url, webUrl: `https://${host}/${owner}/${name}` };
|
|
1541
|
+
}
|
|
1542
|
+
function remoteFor(git) {
|
|
1543
|
+
const dir = git.commonDir ?? git.gitDir;
|
|
1544
|
+
if (!dir)
|
|
1545
|
+
return void 0;
|
|
1546
|
+
const config = join(dir, "config");
|
|
1547
|
+
if (!existsSync(config))
|
|
1548
|
+
return void 0;
|
|
1549
|
+
const url = originUrl(readFileSync2(config, "utf8"));
|
|
1550
|
+
return url ? parseRemote(url) : void 0;
|
|
1551
|
+
}
|
|
1552
|
+
function headBranch(gitDir) {
|
|
1553
|
+
if (!gitDir)
|
|
1554
|
+
return void 0;
|
|
1555
|
+
const head = join(gitDir, "HEAD");
|
|
1556
|
+
if (!existsSync(head))
|
|
1557
|
+
return void 0;
|
|
1558
|
+
const t = readFileSync2(head, "utf8").trim();
|
|
1559
|
+
const m = t.match(/^ref:\s*refs\/heads\/(.+)$/);
|
|
1560
|
+
return m ? m[1] : `detached @ ${t.slice(0, 7)}`;
|
|
1561
|
+
}
|
|
1562
|
+
function defaultBranch(commonDir) {
|
|
1563
|
+
if (!commonDir)
|
|
1564
|
+
return void 0;
|
|
1565
|
+
const head = join(commonDir, "refs", "remotes", "origin", "HEAD");
|
|
1566
|
+
if (existsSync(head)) {
|
|
1567
|
+
const m = readFileSync2(head, "utf8").trim().match(/refs\/remotes\/origin\/(.+)$/);
|
|
1568
|
+
if (m)
|
|
1569
|
+
return m[1];
|
|
1570
|
+
}
|
|
1571
|
+
const packed = join(commonDir, "packed-refs");
|
|
1572
|
+
if (existsSync(packed)) {
|
|
1573
|
+
const m = readFileSync2(packed, "utf8").match(/refs\/remotes\/origin\/(\S+)/);
|
|
1574
|
+
if (m && m[1] !== "HEAD")
|
|
1575
|
+
return m[1];
|
|
1576
|
+
}
|
|
1577
|
+
return void 0;
|
|
1578
|
+
}
|
|
1579
|
+
function readGitFolder(path7) {
|
|
1580
|
+
if (!existsSync(path7))
|
|
1581
|
+
return { exists: false, isWorktree: false };
|
|
1582
|
+
try {
|
|
1583
|
+
const git = nearestDotGit(realpathOrSelf(path7));
|
|
1584
|
+
if (!git)
|
|
1585
|
+
return { exists: true, isWorktree: false };
|
|
1586
|
+
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
1587
|
+
const isWorktree = !!projectRoot && realpathOrSelf(projectRoot) !== realpathOrSelf(git.root);
|
|
1588
|
+
return {
|
|
1589
|
+
exists: true,
|
|
1590
|
+
isWorktree,
|
|
1591
|
+
branch: headBranch(git.gitDir),
|
|
1592
|
+
defaultBranch: defaultBranch(git.commonDir),
|
|
1593
|
+
remote: remoteFor(git)
|
|
1594
|
+
};
|
|
1595
|
+
} catch {
|
|
1596
|
+
return { exists: true, isWorktree: false };
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
function projectRootFromCommonDir(commonDir) {
|
|
1600
|
+
if (!commonDir)
|
|
1601
|
+
return void 0;
|
|
1602
|
+
return basename(commonDir) === ".git" ? dirname2(commonDir) : void 0;
|
|
1603
|
+
}
|
|
1604
|
+
function realpathOrSelf(p) {
|
|
1605
|
+
try {
|
|
1606
|
+
return realpathSync(p);
|
|
1607
|
+
} catch {
|
|
1608
|
+
return p;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
function resolveProjectIdentity(cwd) {
|
|
1612
|
+
const normalized = realpathOrSelf(cwd.replace(/\/{2,}/g, "/"));
|
|
1613
|
+
try {
|
|
1614
|
+
const git = nearestDotGit(normalized);
|
|
1615
|
+
if (git) {
|
|
1616
|
+
const projectRoot = realpathOrSelf(projectRootFromCommonDir(git.commonDir) ?? git.root);
|
|
1617
|
+
const gitRoot = realpathOrSelf(git.root);
|
|
1618
|
+
const wt2 = projectRoot !== gitRoot ? worktreeName(normalized) ?? basename(git.root) : void 0;
|
|
1619
|
+
const identity = { projectName: projectRoot };
|
|
1620
|
+
if (wt2)
|
|
1621
|
+
identity.worktreeName = wt2;
|
|
1622
|
+
const remote = remoteFor(git);
|
|
1623
|
+
if (remote) {
|
|
1624
|
+
identity.remote = remote;
|
|
1625
|
+
identity.repoName = remote.name;
|
|
1626
|
+
}
|
|
1627
|
+
return identity;
|
|
1628
|
+
}
|
|
1629
|
+
} catch {
|
|
1630
|
+
}
|
|
1631
|
+
const projectName = canonicalProjectName(normalized);
|
|
1632
|
+
const wt = worktreeName(normalized) ?? void 0;
|
|
1633
|
+
return wt ? { projectName, worktreeName: wt } : { projectName };
|
|
1634
|
+
}
|
|
1635
|
+
var REMOTE_URL_RE;
|
|
1636
|
+
var init_git_project = __esm({
|
|
1637
|
+
"../parser/dist/git-project.js"() {
|
|
1638
|
+
"use strict";
|
|
1639
|
+
init_analytics();
|
|
1640
|
+
REMOTE_URL_RE = /^(?:(?:https?|ssh|git):\/\/)?(?:[^@/]+@)?([^/:]+)[:/](.+?)(?:\.git)?\/?$/;
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1643
|
+
|
|
1450
1644
|
// ../parser/dist/team.js
|
|
1451
1645
|
function groupByTeam(sessions, details) {
|
|
1452
1646
|
const byTeam = /* @__PURE__ */ new Map();
|
|
@@ -1915,12 +2109,16 @@ async function getCachedMeta(f) {
|
|
|
1915
2109
|
const sessionId = sessionIdFromFileName(f.fileName);
|
|
1916
2110
|
const projectDirPath = path.dirname(f.fullPath);
|
|
1917
2111
|
const wf = await scanWorkflowAggregate(projectDirPath, sessionId);
|
|
2112
|
+
const cwd = meta.cwd ?? decodeProjectName(f.projectDir);
|
|
2113
|
+
const project = resolveProjectIdentity(cwd);
|
|
1918
2114
|
const full = {
|
|
1919
2115
|
...meta,
|
|
1920
2116
|
id: sessionId,
|
|
1921
2117
|
filePath: f.fullPath,
|
|
1922
2118
|
projectDir: f.projectDir,
|
|
1923
|
-
projectName:
|
|
2119
|
+
projectName: project.projectName,
|
|
2120
|
+
worktreeName: project.worktreeName,
|
|
2121
|
+
repoName: project.repoName,
|
|
1924
2122
|
...wf.workflowCount > 0 ? { workflowCount: wf.workflowCount, spawnedAgentCount: wf.spawnedAgentCount } : {},
|
|
1925
2123
|
...foldWorkflowAgentTime(meta.activeSegments, wf.spans)
|
|
1926
2124
|
};
|
|
@@ -1941,12 +2139,16 @@ async function getCachedDetail(f) {
|
|
|
1941
2139
|
const sessionId = sessionIdFromFileName(f.fileName);
|
|
1942
2140
|
await applySubagentUsage(meta, rawLines, f);
|
|
1943
2141
|
const wf = await scanWorkflowAggregate(path.dirname(f.fullPath), sessionId);
|
|
2142
|
+
const cwd = meta.cwd ?? decodeProjectName(f.projectDir);
|
|
2143
|
+
const project = resolveProjectIdentity(cwd);
|
|
1944
2144
|
const detail = {
|
|
1945
2145
|
...meta,
|
|
1946
2146
|
id: sessionId,
|
|
1947
2147
|
filePath: f.fullPath,
|
|
1948
2148
|
projectDir: f.projectDir,
|
|
1949
|
-
projectName:
|
|
2149
|
+
projectName: project.projectName,
|
|
2150
|
+
worktreeName: project.worktreeName,
|
|
2151
|
+
repoName: project.repoName,
|
|
1950
2152
|
events,
|
|
1951
2153
|
...wf.workflowCount > 0 ? { workflowCount: wf.workflowCount, spawnedAgentCount: wf.spawnedAgentCount } : {},
|
|
1952
2154
|
...foldWorkflowAgentTime(meta.activeSegments, wf.spans)
|
|
@@ -2438,19 +2640,25 @@ async function listProjects(root = DEFAULT_ROOT) {
|
|
|
2438
2640
|
cur.lastActiveMs = f.mtimeMs;
|
|
2439
2641
|
byRawDir.set(f.projectDir, cur);
|
|
2440
2642
|
}
|
|
2441
|
-
const
|
|
2643
|
+
const cachedIdentityForProject = (dir) => {
|
|
2442
2644
|
for (const [, entry] of metaCache.entries()) {
|
|
2443
|
-
if (entry.meta.projectDir === dir
|
|
2444
|
-
return
|
|
2645
|
+
if (entry.meta.projectDir === dir) {
|
|
2646
|
+
return {
|
|
2647
|
+
cwd: entry.meta.cwd,
|
|
2648
|
+
projectName: entry.meta.projectName,
|
|
2649
|
+
worktreeName: entry.meta.worktreeName
|
|
2650
|
+
};
|
|
2445
2651
|
}
|
|
2446
2652
|
}
|
|
2447
2653
|
return void 0;
|
|
2448
2654
|
};
|
|
2449
2655
|
const canonicalMap = /* @__PURE__ */ new Map();
|
|
2450
2656
|
for (const [rawDir, { count, lastActiveMs }] of byRawDir) {
|
|
2451
|
-
const
|
|
2452
|
-
const
|
|
2453
|
-
const
|
|
2657
|
+
const cached = cachedIdentityForProject(rawDir);
|
|
2658
|
+
const cwdOrDecoded = cached?.cwd ?? decodeProjectName(rawDir);
|
|
2659
|
+
const projectName = cached?.projectName ?? canonicalProjectName(cwdOrDecoded);
|
|
2660
|
+
const wt = cached?.worktreeName ?? worktreeName(cwdOrDecoded) ?? void 0;
|
|
2661
|
+
const repo = projectKey(projectName);
|
|
2454
2662
|
const agg = canonicalMap.get(repo) ?? {
|
|
2455
2663
|
canonicalName: repo,
|
|
2456
2664
|
count: 0,
|
|
@@ -2516,6 +2724,7 @@ var init_claude_code = __esm({
|
|
|
2516
2724
|
"use strict";
|
|
2517
2725
|
init_parser();
|
|
2518
2726
|
init_analytics();
|
|
2727
|
+
init_git_project();
|
|
2519
2728
|
init_team();
|
|
2520
2729
|
init_agent_metadata();
|
|
2521
2730
|
init_calibration();
|
|
@@ -2822,13 +3031,16 @@ function parseRollout(file, lines) {
|
|
|
2822
3031
|
const activeSegments = computeActiveSegments2(tsMs);
|
|
2823
3032
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
2824
3033
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
2825
|
-
const
|
|
3034
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3035
|
+
const projectName = project?.projectName ?? "(unknown)";
|
|
2826
3036
|
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : "(unknown)";
|
|
2827
3037
|
const meta = {
|
|
2828
3038
|
agent: "codex",
|
|
2829
3039
|
id: file.sessionId,
|
|
2830
3040
|
filePath: file.filePath,
|
|
2831
3041
|
projectName,
|
|
3042
|
+
worktreeName: project?.worktreeName,
|
|
3043
|
+
repoName: project?.repoName,
|
|
2832
3044
|
projectDir,
|
|
2833
3045
|
sessionId: file.sessionId,
|
|
2834
3046
|
firstTimestamp,
|
|
@@ -2987,6 +3199,7 @@ var init_codex = __esm({
|
|
|
2987
3199
|
"../parser/dist/codex.js"() {
|
|
2988
3200
|
"use strict";
|
|
2989
3201
|
init_analytics();
|
|
3202
|
+
init_git_project();
|
|
2990
3203
|
init_user_input();
|
|
2991
3204
|
DEFAULT_CODEX_ROOT = path2.join(os2.homedir(), ".codex", "sessions");
|
|
2992
3205
|
ROLLOUT_RE = /^rollout-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})-([0-9a-f-]+)\.jsonl$/;
|
|
@@ -3366,13 +3579,16 @@ async function parseSession(file) {
|
|
|
3366
3579
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
3367
3580
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3368
3581
|
const sessionId = metaRec.sessionId ?? file.filenameId;
|
|
3369
|
-
const
|
|
3582
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3583
|
+
const projectName = project?.projectName ?? file.slug;
|
|
3370
3584
|
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : file.slug;
|
|
3371
3585
|
const meta = {
|
|
3372
3586
|
agent: "gemini",
|
|
3373
3587
|
id: sessionId,
|
|
3374
3588
|
filePath: file.filePath,
|
|
3375
3589
|
projectName,
|
|
3590
|
+
worktreeName: project?.worktreeName,
|
|
3591
|
+
repoName: project?.repoName,
|
|
3376
3592
|
projectDir,
|
|
3377
3593
|
sessionId,
|
|
3378
3594
|
firstTimestamp,
|
|
@@ -3486,6 +3702,7 @@ var init_gemini = __esm({
|
|
|
3486
3702
|
"../parser/dist/gemini.js"() {
|
|
3487
3703
|
"use strict";
|
|
3488
3704
|
init_analytics();
|
|
3705
|
+
init_git_project();
|
|
3489
3706
|
init_user_input();
|
|
3490
3707
|
DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
|
|
3491
3708
|
GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
|
|
@@ -3759,13 +3976,16 @@ async function parseSession2(file) {
|
|
|
3759
3976
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3760
3977
|
const sessionId = file.conversationId;
|
|
3761
3978
|
const cwd = file.cwd;
|
|
3762
|
-
const
|
|
3979
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3980
|
+
const projectName = project?.projectName ?? file.conversationId;
|
|
3763
3981
|
const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : file.conversationId;
|
|
3764
3982
|
const meta = {
|
|
3765
3983
|
agent: "antigravity",
|
|
3766
3984
|
id: sessionId,
|
|
3767
3985
|
filePath: file.filePath,
|
|
3768
3986
|
projectName,
|
|
3987
|
+
worktreeName: project?.worktreeName,
|
|
3988
|
+
repoName: project?.repoName,
|
|
3769
3989
|
projectDir,
|
|
3770
3990
|
sessionId,
|
|
3771
3991
|
firstTimestamp,
|
|
@@ -3872,6 +4092,7 @@ var init_antigravity = __esm({
|
|
|
3872
4092
|
"../parser/dist/antigravity.js"() {
|
|
3873
4093
|
"use strict";
|
|
3874
4094
|
init_analytics();
|
|
4095
|
+
init_git_project();
|
|
3875
4096
|
init_user_input();
|
|
3876
4097
|
DEFAULT_ANTIGRAVITY_ROOT = path4.join(os4.homedir(), ".gemini", "antigravity-cli");
|
|
3877
4098
|
IDLE_GAP_MS3 = 3 * 60 * 1e3;
|
|
@@ -3991,8 +4212,10 @@ function resolveProject(meta, spaceIdToPath) {
|
|
|
3991
4212
|
if (!projectPath) {
|
|
3992
4213
|
return { projectName: "cowork:unspaced", projectDir: "cowork-unspaced" };
|
|
3993
4214
|
}
|
|
4215
|
+
const project = resolveProjectIdentity(projectPath);
|
|
3994
4216
|
return {
|
|
3995
|
-
projectName:
|
|
4217
|
+
projectName: project.projectName,
|
|
4218
|
+
worktreeName: project.worktreeName,
|
|
3996
4219
|
projectDir: projectPath.replace(/^\//, "-").replace(/\//g, "-"),
|
|
3997
4220
|
cwd: projectPath
|
|
3998
4221
|
};
|
|
@@ -4219,8 +4442,8 @@ var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache, metaCache5, detailCache5;
|
|
|
4219
4442
|
var init_cowork = __esm({
|
|
4220
4443
|
"../parser/dist/cowork.js"() {
|
|
4221
4444
|
"use strict";
|
|
4222
|
-
init_analytics();
|
|
4223
4445
|
init_claude_code();
|
|
4446
|
+
init_git_project();
|
|
4224
4447
|
init_parser();
|
|
4225
4448
|
DEFAULT_COWORK_ROOT = defaultCoworkRoot();
|
|
4226
4449
|
SESSION_ID_RE = /^local_[0-9a-f-]+$/;
|
|
@@ -4231,21 +4454,21 @@ var init_cowork = __esm({
|
|
|
4231
4454
|
});
|
|
4232
4455
|
|
|
4233
4456
|
// ../parser/dist/team-config.js
|
|
4234
|
-
import { readFileSync as
|
|
4235
|
-
import { join } from "node:path";
|
|
4236
|
-
function shouldSyncProject(
|
|
4457
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2, renameSync } from "node:fs";
|
|
4458
|
+
import { join as join2 } from "node:path";
|
|
4459
|
+
function shouldSyncProject(projectKey2, sp) {
|
|
4237
4460
|
if (!sp)
|
|
4238
4461
|
return true;
|
|
4239
|
-
if (sp.excluded.includes(
|
|
4462
|
+
if (sp.excluded.includes(projectKey2))
|
|
4240
4463
|
return false;
|
|
4241
|
-
if (sp.included.includes(
|
|
4464
|
+
if (sp.included.includes(projectKey2))
|
|
4242
4465
|
return true;
|
|
4243
4466
|
return sp.autoIncludeNew;
|
|
4244
4467
|
}
|
|
4245
4468
|
function readTeamConfig(dir) {
|
|
4246
4469
|
const d = dir ?? cclensHome();
|
|
4247
4470
|
try {
|
|
4248
|
-
return JSON.parse(
|
|
4471
|
+
return JSON.parse(readFileSync3(join2(d, CONFIG_FILE), "utf8"));
|
|
4249
4472
|
} catch {
|
|
4250
4473
|
return null;
|
|
4251
4474
|
}
|
|
@@ -4253,14 +4476,14 @@ function readTeamConfig(dir) {
|
|
|
4253
4476
|
function writeTeamConfig(config, dir) {
|
|
4254
4477
|
const d = dir ?? cclensHome();
|
|
4255
4478
|
mkdirSync2(d, { recursive: true });
|
|
4256
|
-
const tmp =
|
|
4479
|
+
const tmp = join2(d, `${CONFIG_FILE}.${process.pid}.tmp`);
|
|
4257
4480
|
writeFileSync2(tmp, JSON.stringify(config, null, 2), { mode: 384 });
|
|
4258
|
-
renameSync(tmp,
|
|
4481
|
+
renameSync(tmp, join2(d, CONFIG_FILE));
|
|
4259
4482
|
}
|
|
4260
4483
|
function clearTeamConfig(dir) {
|
|
4261
4484
|
const d = dir ?? cclensHome();
|
|
4262
4485
|
try {
|
|
4263
|
-
unlinkSync2(
|
|
4486
|
+
unlinkSync2(join2(d, CONFIG_FILE));
|
|
4264
4487
|
} catch {
|
|
4265
4488
|
}
|
|
4266
4489
|
}
|
|
@@ -4326,8 +4549,10 @@ __export(fs_exports, {
|
|
|
4326
4549
|
loadTeamForSession: () => loadTeamForSession,
|
|
4327
4550
|
loadUsageByDay: () => loadUsageByDay,
|
|
4328
4551
|
loadWorkflowAgentDetail: () => loadWorkflowAgentDetail,
|
|
4552
|
+
readGitFolder: () => readGitFolder,
|
|
4329
4553
|
readJsonlFile: () => readJsonlFile,
|
|
4330
4554
|
readTeamConfig: () => readTeamConfig,
|
|
4555
|
+
resolveProjectIdentity: () => resolveProjectIdentity,
|
|
4331
4556
|
sessionIdFromFileName: () => sessionIdFromFileName,
|
|
4332
4557
|
shouldSyncProject: () => shouldSyncProject,
|
|
4333
4558
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
@@ -4603,6 +4828,7 @@ var init_fs = __esm({
|
|
|
4603
4828
|
init_antigravity();
|
|
4604
4829
|
init_cowork();
|
|
4605
4830
|
init_claude_code();
|
|
4831
|
+
init_git_project();
|
|
4606
4832
|
init_codex();
|
|
4607
4833
|
init_gemini();
|
|
4608
4834
|
init_antigravity();
|
|
@@ -4681,13 +4907,13 @@ __export(server_exports, {
|
|
|
4681
4907
|
stopServer: () => stopServer
|
|
4682
4908
|
});
|
|
4683
4909
|
import { spawn } from "node:child_process";
|
|
4684
|
-
import { join as
|
|
4910
|
+
import { join as join3, dirname as dirname3 } from "node:path";
|
|
4685
4911
|
import { fileURLToPath } from "node:url";
|
|
4686
|
-
import { existsSync } from "node:fs";
|
|
4687
|
-
import { homedir } from "node:os";
|
|
4912
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
4913
|
+
import { homedir as homedir2 } from "node:os";
|
|
4688
4914
|
function appDir() {
|
|
4689
|
-
const here =
|
|
4690
|
-
return
|
|
4915
|
+
const here = dirname3(fileURLToPath(import.meta.url));
|
|
4916
|
+
return join3(here, "..", "app", "apps", "web");
|
|
4691
4917
|
}
|
|
4692
4918
|
function getServerStatus() {
|
|
4693
4919
|
cleanStalePid(PID_FILE, SERVER_MARKERS);
|
|
@@ -4698,7 +4924,7 @@ function getServerStatus() {
|
|
|
4698
4924
|
return { running: false };
|
|
4699
4925
|
}
|
|
4700
4926
|
function isServerStale(status2) {
|
|
4701
|
-
return status2.running === true && status2.version !== "0.15.
|
|
4927
|
+
return status2.running === true && status2.version !== "0.15.3";
|
|
4702
4928
|
}
|
|
4703
4929
|
async function ensureCurrentServer(opts = {}) {
|
|
4704
4930
|
const status2 = getServerStatus();
|
|
@@ -4731,15 +4957,15 @@ async function ensureCurrentServer(opts = {}) {
|
|
|
4731
4957
|
}
|
|
4732
4958
|
async function startServer(opts = {}) {
|
|
4733
4959
|
const port = opts.port ?? (parseInt(process.env.CCLENS_PORT ?? "", 10) || DEFAULT_PORT);
|
|
4734
|
-
const serverJs =
|
|
4735
|
-
if (!
|
|
4960
|
+
const serverJs = join3(appDir(), "server.js");
|
|
4961
|
+
if (!existsSync2(serverJs)) {
|
|
4736
4962
|
throw new Error(`Server not found at ${serverJs}. Reinstall with: npm install -g fleetlens`);
|
|
4737
4963
|
}
|
|
4738
4964
|
const portInUse = await checkPort(port);
|
|
4739
4965
|
if (portInUse) {
|
|
4740
4966
|
throw new Error(`Port ${port} is in use. Use --port to specify a different port.`);
|
|
4741
4967
|
}
|
|
4742
|
-
const dataDir =
|
|
4968
|
+
const dataDir = join3(homedir2(), ".claude", "projects");
|
|
4743
4969
|
const child = spawn(process.execPath, [serverJs], {
|
|
4744
4970
|
detached: true,
|
|
4745
4971
|
stdio: "ignore",
|
|
@@ -4754,7 +4980,7 @@ async function startServer(opts = {}) {
|
|
|
4754
4980
|
});
|
|
4755
4981
|
child.unref();
|
|
4756
4982
|
const pid = child.pid;
|
|
4757
|
-
writePid(PID_FILE, pid, port, "0.15.
|
|
4983
|
+
writePid(PID_FILE, pid, port, "0.15.3");
|
|
4758
4984
|
await waitForHealth(`http://localhost:${port}`, 3e4);
|
|
4759
4985
|
return { pid, port };
|
|
4760
4986
|
}
|
|
@@ -4773,11 +4999,11 @@ function stopServer() {
|
|
|
4773
4999
|
}
|
|
4774
5000
|
async function checkPort(port) {
|
|
4775
5001
|
const { createServer } = await import("node:net");
|
|
4776
|
-
return new Promise((
|
|
5002
|
+
return new Promise((resolve4) => {
|
|
4777
5003
|
const server = createServer();
|
|
4778
|
-
server.once("error", () =>
|
|
5004
|
+
server.once("error", () => resolve4(true));
|
|
4779
5005
|
server.once("listening", () => {
|
|
4780
|
-
server.close(() =>
|
|
5006
|
+
server.close(() => resolve4(false));
|
|
4781
5007
|
});
|
|
4782
5008
|
server.listen(port, "localhost");
|
|
4783
5009
|
});
|
|
@@ -4825,15 +5051,15 @@ __export(storage_exports, {
|
|
|
4825
5051
|
latestSnapshot: () => latestSnapshot,
|
|
4826
5052
|
readSnapshots: () => readSnapshots
|
|
4827
5053
|
});
|
|
4828
|
-
import { appendFileSync, mkdirSync as mkdirSync3, readFileSync as
|
|
4829
|
-
import { dirname as
|
|
5054
|
+
import { appendFileSync, mkdirSync as mkdirSync3, readFileSync as readFileSync4, existsSync as existsSync3 } from "node:fs";
|
|
5055
|
+
import { dirname as dirname4 } from "node:path";
|
|
4830
5056
|
function appendSnapshot(filePath, snapshot) {
|
|
4831
|
-
mkdirSync3(
|
|
5057
|
+
mkdirSync3(dirname4(filePath), { recursive: true });
|
|
4832
5058
|
appendFileSync(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
4833
5059
|
}
|
|
4834
5060
|
function readSnapshots(filePath) {
|
|
4835
|
-
if (!
|
|
4836
|
-
const content =
|
|
5061
|
+
if (!existsSync3(filePath)) return [];
|
|
5062
|
+
const content = readFileSync4(filePath, "utf8");
|
|
4837
5063
|
const snapshots = [];
|
|
4838
5064
|
for (const line of content.split("\n")) {
|
|
4839
5065
|
if (!line.trim()) continue;
|
|
@@ -4871,9 +5097,9 @@ __export(daemon_exports, {
|
|
|
4871
5097
|
stopDaemonSilent: () => stopDaemonSilent
|
|
4872
5098
|
});
|
|
4873
5099
|
import { spawn as spawn2 } from "node:child_process";
|
|
4874
|
-
import { join as
|
|
5100
|
+
import { join as join4, dirname as dirname5 } from "node:path";
|
|
4875
5101
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
4876
|
-
import { existsSync as
|
|
5102
|
+
import { existsSync as existsSync4, statSync as statSync2, readFileSync as readFileSync5 } from "node:fs";
|
|
4877
5103
|
function startDaemonSilent() {
|
|
4878
5104
|
cleanStalePid(DAEMON_PID, DAEMON_MARKERS);
|
|
4879
5105
|
const existing = readPid(DAEMON_PID);
|
|
@@ -4881,7 +5107,7 @@ function startDaemonSilent() {
|
|
|
4881
5107
|
return { started: false, pid: existing.pid, alreadyRunning: true };
|
|
4882
5108
|
}
|
|
4883
5109
|
const script = workerPath();
|
|
4884
|
-
if (!
|
|
5110
|
+
if (!existsSync4(script)) {
|
|
4885
5111
|
return {
|
|
4886
5112
|
started: false,
|
|
4887
5113
|
pid: null,
|
|
@@ -4915,7 +5141,7 @@ function getDaemonStatusInfo() {
|
|
|
4915
5141
|
const running = entry !== null && isProcessAlive(entry.pid, DAEMON_MARKERS);
|
|
4916
5142
|
const latest = latestSnapshot(USAGE_LOG);
|
|
4917
5143
|
const lastSnapshotAgeMs = latest ? Date.now() - new Date(latest.captured_at).getTime() : null;
|
|
4918
|
-
const usageLogSize =
|
|
5144
|
+
const usageLogSize = existsSync4(USAGE_LOG) ? statSync2(USAGE_LOG).size : null;
|
|
4919
5145
|
return {
|
|
4920
5146
|
running,
|
|
4921
5147
|
pid: running ? entry.pid : null,
|
|
@@ -4925,8 +5151,8 @@ function getDaemonStatusInfo() {
|
|
|
4925
5151
|
};
|
|
4926
5152
|
}
|
|
4927
5153
|
function workerPath() {
|
|
4928
|
-
const here =
|
|
4929
|
-
return
|
|
5154
|
+
const here = dirname5(fileURLToPath2(import.meta.url));
|
|
5155
|
+
return join4(here, "daemon-worker.js");
|
|
4930
5156
|
}
|
|
4931
5157
|
async function daemon(args2) {
|
|
4932
5158
|
const sub = args2[0] ?? "status";
|
|
@@ -4991,11 +5217,11 @@ function daemonStatus() {
|
|
|
4991
5217
|
}
|
|
4992
5218
|
}
|
|
4993
5219
|
function daemonLogs() {
|
|
4994
|
-
if (!
|
|
5220
|
+
if (!existsSync4(DAEMON_LOG)) {
|
|
4995
5221
|
console.log("No daemon logs yet.");
|
|
4996
5222
|
return;
|
|
4997
5223
|
}
|
|
4998
|
-
const content =
|
|
5224
|
+
const content = readFileSync5(DAEMON_LOG, "utf8");
|
|
4999
5225
|
const lines = content.trim().split("\n").slice(-20);
|
|
5000
5226
|
for (const line of lines) process.stdout.write(line + "\n");
|
|
5001
5227
|
}
|
|
@@ -5015,8 +5241,8 @@ var init_daemon = __esm({
|
|
|
5015
5241
|
|
|
5016
5242
|
// src/updater.ts
|
|
5017
5243
|
import { execSync, spawnSync } from "node:child_process";
|
|
5018
|
-
import { existsSync as
|
|
5019
|
-
import { dirname as
|
|
5244
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, realpathSync as realpathSync2 } from "node:fs";
|
|
5245
|
+
import { dirname as dirname6, join as join5 } from "node:path";
|
|
5020
5246
|
function shouldUpdate(local, remote) {
|
|
5021
5247
|
const l = local.split(".").map(Number);
|
|
5022
5248
|
const r = remote.split(".").map(Number);
|
|
@@ -5058,15 +5284,15 @@ function verifyInstalledVersion() {
|
|
|
5058
5284
|
encoding: "utf8",
|
|
5059
5285
|
timeout: 5e3
|
|
5060
5286
|
}).trim();
|
|
5061
|
-
const pkgPath =
|
|
5062
|
-
const pkg = JSON.parse(
|
|
5287
|
+
const pkgPath = join5(globalRoot, PACKAGE_NAME, "package.json");
|
|
5288
|
+
const pkg = JSON.parse(readFileSync6(pkgPath, "utf8"));
|
|
5063
5289
|
if (!pkg.version) {
|
|
5064
5290
|
return { ok: false, reason: `no version field in ${pkgPath}` };
|
|
5065
5291
|
}
|
|
5066
5292
|
return {
|
|
5067
5293
|
ok: true,
|
|
5068
5294
|
installedVersion: pkg.version,
|
|
5069
|
-
installedPath:
|
|
5295
|
+
installedPath: join5(globalRoot, PACKAGE_NAME)
|
|
5070
5296
|
};
|
|
5071
5297
|
} catch (err) {
|
|
5072
5298
|
return { ok: false, reason: err.message };
|
|
@@ -5123,28 +5349,28 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
5123
5349
|
console.warn(
|
|
5124
5350
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
5125
5351
|
);
|
|
5126
|
-
} else if (verify.installedVersion !== "0.15.
|
|
5352
|
+
} else if (verify.installedVersion !== "0.15.3") {
|
|
5127
5353
|
console.log(
|
|
5128
|
-
` \u2192 This process is still running ${"0.15.
|
|
5354
|
+
` \u2192 This process is still running ${"0.15.3"}. Next invocation will use ${verify.installedVersion}.`
|
|
5129
5355
|
);
|
|
5130
5356
|
}
|
|
5131
5357
|
}
|
|
5132
5358
|
function resolvesIntoPackage(binPath, packagePath) {
|
|
5133
5359
|
try {
|
|
5134
|
-
const real =
|
|
5360
|
+
const real = realpathSync2(binPath);
|
|
5135
5361
|
if (real.startsWith(packagePath)) return true;
|
|
5136
5362
|
} catch {
|
|
5137
5363
|
}
|
|
5138
|
-
const binPrefix =
|
|
5139
|
-
const installPrefix =
|
|
5364
|
+
const binPrefix = dirname6(dirname6(binPath));
|
|
5365
|
+
const installPrefix = dirname6(dirname6(dirname6(packagePath)));
|
|
5140
5366
|
return binPrefix === installPrefix;
|
|
5141
5367
|
}
|
|
5142
5368
|
function reExec() {
|
|
5143
5369
|
const verify = verifyInstalledVersion();
|
|
5144
5370
|
let script = process.argv[1] ?? "";
|
|
5145
5371
|
if (verify.ok) {
|
|
5146
|
-
const candidate =
|
|
5147
|
-
if (
|
|
5372
|
+
const candidate = join5(verify.installedPath, "dist", "index.js");
|
|
5373
|
+
if (existsSync5(candidate)) script = candidate;
|
|
5148
5374
|
}
|
|
5149
5375
|
const result = spawnSync(process.argv[0], [script, ...process.argv.slice(2)], {
|
|
5150
5376
|
stdio: "inherit",
|
|
@@ -5160,14 +5386,14 @@ async function getUpdateAvailability() {
|
|
|
5160
5386
|
if (isDevMode()) return null;
|
|
5161
5387
|
const latest = await fetchLatestVersion();
|
|
5162
5388
|
if (latest === null) return {
|
|
5163
|
-
current: "0.15.
|
|
5389
|
+
current: "0.15.3",
|
|
5164
5390
|
latest: null,
|
|
5165
5391
|
updateAvailable: false
|
|
5166
5392
|
};
|
|
5167
5393
|
return {
|
|
5168
|
-
current: "0.15.
|
|
5394
|
+
current: "0.15.3",
|
|
5169
5395
|
latest,
|
|
5170
|
-
updateAvailable: shouldUpdate("0.15.
|
|
5396
|
+
updateAvailable: shouldUpdate("0.15.3", latest)
|
|
5171
5397
|
};
|
|
5172
5398
|
}
|
|
5173
5399
|
async function checkForUpdate() {
|
|
@@ -5257,7 +5483,7 @@ async function restartServices(state) {
|
|
|
5257
5483
|
}
|
|
5258
5484
|
async function forceUpdate() {
|
|
5259
5485
|
const latest = await fetchLatestVersion();
|
|
5260
|
-
const current = "0.15.
|
|
5486
|
+
const current = "0.15.3";
|
|
5261
5487
|
if (latest === null) {
|
|
5262
5488
|
console.error("Could not reach npm registry. Check your network.");
|
|
5263
5489
|
process.exit(1);
|
|
@@ -5309,27 +5535,27 @@ __export(autostart_exports, {
|
|
|
5309
5535
|
maybePromptAutostart: () => maybePromptAutostart,
|
|
5310
5536
|
recordOptOut: () => recordOptOut
|
|
5311
5537
|
});
|
|
5312
|
-
import { existsSync as
|
|
5313
|
-
import { homedir as
|
|
5314
|
-
import { join as
|
|
5538
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, rmSync, readFileSync as readFileSync7, realpathSync as realpathSync3 } from "node:fs";
|
|
5539
|
+
import { homedir as homedir3 } from "node:os";
|
|
5540
|
+
import { join as join6, dirname as dirname7 } from "node:path";
|
|
5315
5541
|
import { execFile } from "node:child_process";
|
|
5316
5542
|
import { promisify } from "node:util";
|
|
5317
5543
|
import { createInterface } from "node:readline";
|
|
5318
5544
|
function plistPath() {
|
|
5319
|
-
return
|
|
5545
|
+
return join6(homedir3(), "Library", "LaunchAgents", `${LABEL}.plist`);
|
|
5320
5546
|
}
|
|
5321
5547
|
function isMac() {
|
|
5322
5548
|
return process.platform === "darwin";
|
|
5323
5549
|
}
|
|
5324
5550
|
function isAutostartInstalled() {
|
|
5325
|
-
return isMac() &&
|
|
5551
|
+
return isMac() && existsSync6(plistPath());
|
|
5326
5552
|
}
|
|
5327
5553
|
function isStalePlistContent(content) {
|
|
5328
5554
|
return content.includes("<string>daemon</string>");
|
|
5329
5555
|
}
|
|
5330
5556
|
function installedPlistIsStale() {
|
|
5331
5557
|
try {
|
|
5332
|
-
return isStalePlistContent(
|
|
5558
|
+
return isStalePlistContent(readFileSync7(plistPath(), "utf8"));
|
|
5333
5559
|
} catch {
|
|
5334
5560
|
return false;
|
|
5335
5561
|
}
|
|
@@ -5337,7 +5563,7 @@ function installedPlistIsStale() {
|
|
|
5337
5563
|
function resolveScriptPath() {
|
|
5338
5564
|
const argv1 = process.argv[1] ?? "";
|
|
5339
5565
|
try {
|
|
5340
|
-
return
|
|
5566
|
+
return realpathSync3(argv1);
|
|
5341
5567
|
} catch {
|
|
5342
5568
|
return argv1;
|
|
5343
5569
|
}
|
|
@@ -5380,7 +5606,7 @@ async function installAutostart() {
|
|
|
5380
5606
|
const scriptPath = resolveScriptPath();
|
|
5381
5607
|
const logPath = cclensPath("daemon-autostart.log");
|
|
5382
5608
|
const p = plistPath();
|
|
5383
|
-
mkdirSync4(
|
|
5609
|
+
mkdirSync4(dirname7(p), { recursive: true });
|
|
5384
5610
|
writeFileSync3(p, buildPlist({ nodePath, scriptPath, logPath }), "utf8");
|
|
5385
5611
|
await runLaunchctl(["unload", p]).catch(() => {
|
|
5386
5612
|
});
|
|
@@ -5401,7 +5627,7 @@ async function uninstallAutostart() {
|
|
|
5401
5627
|
}
|
|
5402
5628
|
const p = plistPath();
|
|
5403
5629
|
recordOptOut();
|
|
5404
|
-
if (!
|
|
5630
|
+
if (!existsSync6(p)) {
|
|
5405
5631
|
console.log("Autostart is not installed \u2014 nothing to remove. Noted your opt-out; team join won't enable it.");
|
|
5406
5632
|
return;
|
|
5407
5633
|
}
|
|
@@ -5434,7 +5660,7 @@ async function statusAutostart() {
|
|
|
5434
5660
|
return;
|
|
5435
5661
|
}
|
|
5436
5662
|
const p = plistPath();
|
|
5437
|
-
const present =
|
|
5663
|
+
const present = existsSync6(p);
|
|
5438
5664
|
let loaded = false;
|
|
5439
5665
|
try {
|
|
5440
5666
|
const { stdout } = await execFileAsync("launchctl", ["list"]);
|
|
@@ -5449,7 +5675,7 @@ function promptFlagPath() {
|
|
|
5449
5675
|
}
|
|
5450
5676
|
function readFlags() {
|
|
5451
5677
|
try {
|
|
5452
|
-
return JSON.parse(
|
|
5678
|
+
return JSON.parse(readFileSync7(promptFlagPath(), "utf8"));
|
|
5453
5679
|
} catch {
|
|
5454
5680
|
return {};
|
|
5455
5681
|
}
|
|
@@ -5457,7 +5683,7 @@ function readFlags() {
|
|
|
5457
5683
|
function writeFlags(patch) {
|
|
5458
5684
|
const p = promptFlagPath();
|
|
5459
5685
|
try {
|
|
5460
|
-
mkdirSync4(
|
|
5686
|
+
mkdirSync4(dirname7(p), { recursive: true });
|
|
5461
5687
|
writeFileSync3(p, JSON.stringify({ ...readFlags(), ...patch }, null, 2), "utf8");
|
|
5462
5688
|
} catch {
|
|
5463
5689
|
}
|
|
@@ -5475,13 +5701,13 @@ function recordOptOut() {
|
|
|
5475
5701
|
writeFlags({ optedOut: true });
|
|
5476
5702
|
}
|
|
5477
5703
|
function promptYesNo(question, defaultYes) {
|
|
5478
|
-
return new Promise((
|
|
5704
|
+
return new Promise((resolve4) => {
|
|
5479
5705
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
5480
5706
|
rl.question(question, (answer) => {
|
|
5481
5707
|
rl.close();
|
|
5482
5708
|
const a = answer.trim().toLowerCase();
|
|
5483
|
-
if (a === "") return
|
|
5484
|
-
|
|
5709
|
+
if (a === "") return resolve4(defaultYes);
|
|
5710
|
+
resolve4(a === "y" || a === "yes");
|
|
5485
5711
|
});
|
|
5486
5712
|
});
|
|
5487
5713
|
}
|
|
@@ -5670,7 +5896,7 @@ async function status() {
|
|
|
5670
5896
|
console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
|
|
5671
5897
|
if (isServerStale(server)) {
|
|
5672
5898
|
console.log(
|
|
5673
|
-
` \u26A0 serving stale ${ver} (CLI is ${"0.15.
|
|
5899
|
+
` \u26A0 serving stale ${ver} (CLI is ${"0.15.3"}) \u2014 run 'fleetlens start' to restart on the current version`
|
|
5674
5900
|
);
|
|
5675
5901
|
}
|
|
5676
5902
|
} else {
|
|
@@ -5752,9 +5978,9 @@ var init_update = __esm({
|
|
|
5752
5978
|
|
|
5753
5979
|
// src/usage/token.ts
|
|
5754
5980
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
5755
|
-
import { readFileSync as
|
|
5756
|
-
import { homedir as
|
|
5757
|
-
import { join as
|
|
5981
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
5982
|
+
import { homedir as homedir4, platform } from "node:os";
|
|
5983
|
+
import { join as join7 } from "node:path";
|
|
5758
5984
|
function readOAuthCredentials() {
|
|
5759
5985
|
if (platform() === "darwin") {
|
|
5760
5986
|
return readFromMacKeychain() ?? readFromCredentialsFile();
|
|
@@ -5775,12 +6001,12 @@ function readFromMacKeychain() {
|
|
|
5775
6001
|
}
|
|
5776
6002
|
function readFromCredentialsFile() {
|
|
5777
6003
|
const candidates = [
|
|
5778
|
-
|
|
5779
|
-
|
|
6004
|
+
join7(homedir4(), ".claude", ".credentials.json"),
|
|
6005
|
+
join7(homedir4(), ".config", "claude", "credentials.json")
|
|
5780
6006
|
];
|
|
5781
6007
|
for (const path7 of candidates) {
|
|
5782
6008
|
try {
|
|
5783
|
-
const blob =
|
|
6009
|
+
const blob = readFileSync8(path7, "utf8");
|
|
5784
6010
|
const creds = extractCredentials(blob);
|
|
5785
6011
|
if (creds) return creds;
|
|
5786
6012
|
} catch {
|
|
@@ -6780,6 +7006,7 @@ __export(dist_exports, {
|
|
|
6780
7006
|
buildGanttDay: () => buildGanttDay,
|
|
6781
7007
|
buildMegaRows: () => buildMegaRows,
|
|
6782
7008
|
buildPresentation: () => buildPresentation,
|
|
7009
|
+
buildProjectKeyResolver: () => buildProjectKeyResolver,
|
|
6783
7010
|
buildSpendIndex: () => buildSpendIndex,
|
|
6784
7011
|
calendarMonth: () => calendarMonth,
|
|
6785
7012
|
calendarWeek: () => calendarWeek,
|
|
@@ -6808,10 +7035,12 @@ __export(dist_exports, {
|
|
|
6808
7035
|
predictAnchored: () => predictAnchored,
|
|
6809
7036
|
priorCalendarMonth: () => priorCalendarMonth,
|
|
6810
7037
|
priorCalendarWeek: () => priorCalendarWeek,
|
|
7038
|
+
projectKey: () => projectKey,
|
|
6811
7039
|
projectRepoName: () => projectRepoName,
|
|
6812
7040
|
rowPrimaryIndex: () => rowPrimaryIndex,
|
|
6813
7041
|
sessionAirTimeMs: () => sessionAirTimeMs,
|
|
6814
7042
|
sessionDay: () => sessionDay,
|
|
7043
|
+
sessionProjectKey: () => sessionProjectKey,
|
|
6815
7044
|
stripFrameworkBoilerplate: () => stripFrameworkBoilerplate,
|
|
6816
7045
|
summarizeBursts: () => summarizeBursts,
|
|
6817
7046
|
toLocalDay: () => toLocalDay,
|
|
@@ -7426,6 +7655,7 @@ function buildEntries(sessionDetail) {
|
|
|
7426
7655
|
const entries2 = [];
|
|
7427
7656
|
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7428
7657
|
const sessionFallbackProject = canonicalProjectName(sessionDetail.projectName ?? "");
|
|
7658
|
+
const trustSessionProject = !!sessionDetail.worktreeName;
|
|
7429
7659
|
for (const [local_day, dayEvents] of byDay) {
|
|
7430
7660
|
if (dayEvents.length === 0)
|
|
7431
7661
|
continue;
|
|
@@ -7490,7 +7720,7 @@ function buildEntries(sessionDetail) {
|
|
|
7490
7720
|
const finalAgentRaw = agg.finalAgent ?? "";
|
|
7491
7721
|
const final_agent = trunc(minimizeImages(finalAgentRaw), 400);
|
|
7492
7722
|
let project = sessionFallbackProject;
|
|
7493
|
-
if (agg.cwdCounts.size > 0) {
|
|
7723
|
+
if (!trustSessionProject && agg.cwdCounts.size > 0) {
|
|
7494
7724
|
const best = [...agg.cwdCounts.entries()].sort((a, b) => b[1] - a[1])[0];
|
|
7495
7725
|
project = canonicalProjectName(best[0]);
|
|
7496
7726
|
}
|
|
@@ -7600,11 +7830,11 @@ var init_dist2 = __esm({
|
|
|
7600
7830
|
});
|
|
7601
7831
|
|
|
7602
7832
|
// ../entries/dist/digest-fs.js
|
|
7603
|
-
import { readFileSync as
|
|
7604
|
-
import { dirname as
|
|
7833
|
+
import { readFileSync as readFileSync9, readdirSync, writeFileSync as writeFileSync4, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync5, existsSync as existsSync7 } from "node:fs";
|
|
7834
|
+
import { dirname as dirname8, join as join8 } from "node:path";
|
|
7605
7835
|
function parseDigestFile(path7, expectedVersion) {
|
|
7606
7836
|
try {
|
|
7607
|
-
const parsed = JSON.parse(
|
|
7837
|
+
const parsed = JSON.parse(readFileSync9(path7, "utf8"));
|
|
7608
7838
|
if (!parsed || typeof parsed !== "object")
|
|
7609
7839
|
return null;
|
|
7610
7840
|
if (parsed.version !== expectedVersion)
|
|
@@ -7625,22 +7855,22 @@ function digestsDir() {
|
|
|
7625
7855
|
}
|
|
7626
7856
|
function __setDigestsDirForTest(path7) {
|
|
7627
7857
|
digestsDirCached = path7;
|
|
7628
|
-
mkdirSync5(
|
|
7629
|
-
mkdirSync5(
|
|
7630
|
-
mkdirSync5(
|
|
7858
|
+
mkdirSync5(join8(path7, "day"), { recursive: true });
|
|
7859
|
+
mkdirSync5(join8(path7, "week"), { recursive: true });
|
|
7860
|
+
mkdirSync5(join8(path7, "month"), { recursive: true });
|
|
7631
7861
|
}
|
|
7632
7862
|
function dayDigestPath(date) {
|
|
7633
|
-
return
|
|
7863
|
+
return join8(digestsDir(), "day", `${date}.json`);
|
|
7634
7864
|
}
|
|
7635
7865
|
function weekDigestPath(monday) {
|
|
7636
|
-
return
|
|
7866
|
+
return join8(digestsDir(), "week", `${monday}.json`);
|
|
7637
7867
|
}
|
|
7638
7868
|
function monthDigestPath(yearMonth) {
|
|
7639
|
-
return
|
|
7869
|
+
return join8(digestsDir(), "month", `${yearMonth}.json`);
|
|
7640
7870
|
}
|
|
7641
7871
|
function writeDayDigest(digest2) {
|
|
7642
7872
|
const final = dayDigestPath(digest2.key);
|
|
7643
|
-
mkdirSync5(
|
|
7873
|
+
mkdirSync5(dirname8(final), { recursive: true });
|
|
7644
7874
|
const tmp = `${final}.tmp`;
|
|
7645
7875
|
writeFileSync4(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
7646
7876
|
if (process.platform !== "win32") {
|
|
@@ -7653,7 +7883,7 @@ function writeDayDigest(digest2) {
|
|
|
7653
7883
|
}
|
|
7654
7884
|
function readDayDigest(date) {
|
|
7655
7885
|
const p = dayDigestPath(date);
|
|
7656
|
-
if (!
|
|
7886
|
+
if (!existsSync7(p))
|
|
7657
7887
|
return null;
|
|
7658
7888
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
7659
7889
|
}
|
|
@@ -7676,7 +7906,7 @@ function __clearTodayCacheForTest() {
|
|
|
7676
7906
|
}
|
|
7677
7907
|
function writeWeekDigest(digest2) {
|
|
7678
7908
|
const final = weekDigestPath(digest2.key);
|
|
7679
|
-
mkdirSync5(
|
|
7909
|
+
mkdirSync5(dirname8(final), { recursive: true });
|
|
7680
7910
|
const tmp = `${final}.tmp`;
|
|
7681
7911
|
writeFileSync4(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
7682
7912
|
if (process.platform !== "win32") {
|
|
@@ -7689,13 +7919,13 @@ function writeWeekDigest(digest2) {
|
|
|
7689
7919
|
}
|
|
7690
7920
|
function readWeekDigest(monday) {
|
|
7691
7921
|
const p = weekDigestPath(monday);
|
|
7692
|
-
if (!
|
|
7922
|
+
if (!existsSync7(p))
|
|
7693
7923
|
return null;
|
|
7694
7924
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
7695
7925
|
}
|
|
7696
7926
|
function listWeekDigestKeys() {
|
|
7697
|
-
const dir =
|
|
7698
|
-
if (!
|
|
7927
|
+
const dir = join8(digestsDir(), "week");
|
|
7928
|
+
if (!existsSync7(dir))
|
|
7699
7929
|
return [];
|
|
7700
7930
|
return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}-\d{2}$/.test(k));
|
|
7701
7931
|
}
|
|
@@ -7713,7 +7943,7 @@ function setCurrentWeekDigestInCache(monday, digest2, nowMs) {
|
|
|
7713
7943
|
}
|
|
7714
7944
|
function writeMonthDigest(digest2) {
|
|
7715
7945
|
const final = monthDigestPath(digest2.key);
|
|
7716
|
-
mkdirSync5(
|
|
7946
|
+
mkdirSync5(dirname8(final), { recursive: true });
|
|
7717
7947
|
const tmp = `${final}.tmp`;
|
|
7718
7948
|
writeFileSync4(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
7719
7949
|
if (process.platform !== "win32") {
|
|
@@ -7726,13 +7956,13 @@ function writeMonthDigest(digest2) {
|
|
|
7726
7956
|
}
|
|
7727
7957
|
function readMonthDigest(yearMonth) {
|
|
7728
7958
|
const p = monthDigestPath(yearMonth);
|
|
7729
|
-
if (!
|
|
7959
|
+
if (!existsSync7(p))
|
|
7730
7960
|
return null;
|
|
7731
7961
|
return parseDigestFile(p, CURRENT_MONTH_DIGEST_SCHEMA_VERSION);
|
|
7732
7962
|
}
|
|
7733
7963
|
function listMonthDigestKeys() {
|
|
7734
|
-
const dir =
|
|
7735
|
-
if (!
|
|
7964
|
+
const dir = join8(digestsDir(), "month");
|
|
7965
|
+
if (!existsSync7(dir))
|
|
7736
7966
|
return [];
|
|
7737
7967
|
return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}$/.test(k));
|
|
7738
7968
|
}
|
|
@@ -7794,9 +8024,9 @@ __export(fs_exports2, {
|
|
|
7794
8024
|
writeMonthDigest: () => writeMonthDigest,
|
|
7795
8025
|
writeWeekDigest: () => writeWeekDigest
|
|
7796
8026
|
});
|
|
7797
|
-
import { readFileSync as
|
|
8027
|
+
import { readFileSync as readFileSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, renameSync as renameSync3, existsSync as existsSync8 } from "node:fs";
|
|
7798
8028
|
import { randomBytes } from "node:crypto";
|
|
7799
|
-
import { join as
|
|
8029
|
+
import { join as join9 } from "node:path";
|
|
7800
8030
|
function entriesDir() {
|
|
7801
8031
|
if (entriesDirCached)
|
|
7802
8032
|
return entriesDirCached;
|
|
@@ -7809,7 +8039,7 @@ function __setEntriesDirForTest(path7) {
|
|
|
7809
8039
|
mkdirSync6(path7, { recursive: true });
|
|
7810
8040
|
}
|
|
7811
8041
|
function pathFor(sessionId, localDay2) {
|
|
7812
|
-
return
|
|
8042
|
+
return join9(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
7813
8043
|
}
|
|
7814
8044
|
function tmpPathFor(final) {
|
|
7815
8045
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
@@ -7853,17 +8083,17 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
7853
8083
|
}
|
|
7854
8084
|
function readEntry(sessionId, localDay2) {
|
|
7855
8085
|
const p = pathFor(sessionId, localDay2);
|
|
7856
|
-
if (!
|
|
8086
|
+
if (!existsSync8(p))
|
|
7857
8087
|
return null;
|
|
7858
|
-
const raw =
|
|
8088
|
+
const raw = readFileSync10(p, "utf8");
|
|
7859
8089
|
return JSON.parse(raw);
|
|
7860
8090
|
}
|
|
7861
8091
|
function entryExists(sessionId, localDay2) {
|
|
7862
|
-
return
|
|
8092
|
+
return existsSync8(pathFor(sessionId, localDay2));
|
|
7863
8093
|
}
|
|
7864
8094
|
function listEntryKeys() {
|
|
7865
8095
|
const dir = entriesDir();
|
|
7866
|
-
if (!
|
|
8096
|
+
if (!existsSync8(dir))
|
|
7867
8097
|
return [];
|
|
7868
8098
|
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
7869
8099
|
}
|
|
@@ -12142,9 +12372,9 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
|
|
|
12142
12372
|
});
|
|
12143
12373
|
|
|
12144
12374
|
// ../entries/dist/tmux-runner.js
|
|
12145
|
-
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6, existsSync as
|
|
12146
|
-
import { join as
|
|
12147
|
-
import { homedir as
|
|
12375
|
+
import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6, existsSync as existsSync9, readdirSync as readdirSync3, realpathSync as realpathSync4, readFileSync as readFileSync11, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
12376
|
+
import { join as join10 } from "node:path";
|
|
12377
|
+
import { homedir as homedir5 } from "node:os";
|
|
12148
12378
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
12149
12379
|
function which(bin) {
|
|
12150
12380
|
const r = spawnSync2("/usr/bin/env", ["which", bin], { encoding: "utf8" });
|
|
@@ -12160,16 +12390,16 @@ function tmuxRunnerAvailable() {
|
|
|
12160
12390
|
return { ok: true };
|
|
12161
12391
|
}
|
|
12162
12392
|
function runtimeCwd() {
|
|
12163
|
-
const dir =
|
|
12164
|
-
if (!
|
|
12393
|
+
const dir = join10(homedir5(), ".cclens", "runtime");
|
|
12394
|
+
if (!existsSync9(dir))
|
|
12165
12395
|
mkdirSync7(dir, { recursive: true });
|
|
12166
|
-
return
|
|
12396
|
+
return realpathSync4(dir);
|
|
12167
12397
|
}
|
|
12168
12398
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
12169
|
-
const cfgPath =
|
|
12399
|
+
const cfgPath = join10(homedir5(), ".claude.json");
|
|
12170
12400
|
let cfg;
|
|
12171
12401
|
try {
|
|
12172
|
-
cfg = JSON.parse(
|
|
12402
|
+
cfg = JSON.parse(readFileSync11(cfgPath, "utf8"));
|
|
12173
12403
|
} catch {
|
|
12174
12404
|
return;
|
|
12175
12405
|
}
|
|
@@ -12211,9 +12441,9 @@ async function runClaudeUnderTmuxImpl(args2) {
|
|
|
12211
12441
|
ensureRuntimeCwdTrusted(cwd);
|
|
12212
12442
|
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
12213
12443
|
const sessionName = `cclens-${runId}`;
|
|
12214
|
-
const systemFile =
|
|
12215
|
-
const userFile =
|
|
12216
|
-
const wrapper =
|
|
12444
|
+
const systemFile = join10(cwd, `system-${runId}.txt`);
|
|
12445
|
+
const userFile = join10(cwd, `user-${runId}.txt`);
|
|
12446
|
+
const wrapper = join10(cwd, `run-${runId}.sh`);
|
|
12217
12447
|
writeFileSync6(systemFile, args2.systemPrompt);
|
|
12218
12448
|
writeFileSync6(userFile, args2.reminder ? `${args2.userPrompt}
|
|
12219
12449
|
|
|
@@ -12302,7 +12532,7 @@ function snapshotAllTranscripts() {
|
|
|
12302
12532
|
return out;
|
|
12303
12533
|
}
|
|
12304
12534
|
for (const sub of subs) {
|
|
12305
|
-
const dir =
|
|
12535
|
+
const dir = join10(root, sub);
|
|
12306
12536
|
let files;
|
|
12307
12537
|
try {
|
|
12308
12538
|
files = readdirSync3(dir);
|
|
@@ -12311,7 +12541,7 @@ function snapshotAllTranscripts() {
|
|
|
12311
12541
|
}
|
|
12312
12542
|
for (const f of files) {
|
|
12313
12543
|
if (f.endsWith(".jsonl"))
|
|
12314
|
-
out.add(
|
|
12544
|
+
out.add(join10(dir, f));
|
|
12315
12545
|
}
|
|
12316
12546
|
}
|
|
12317
12547
|
return out;
|
|
@@ -12319,7 +12549,7 @@ function snapshotAllTranscripts() {
|
|
|
12319
12549
|
function readJsonlCwd(path7, maxLines = 8) {
|
|
12320
12550
|
let raw;
|
|
12321
12551
|
try {
|
|
12322
|
-
raw =
|
|
12552
|
+
raw = readFileSync11(path7, "utf8");
|
|
12323
12553
|
} catch {
|
|
12324
12554
|
return void 0;
|
|
12325
12555
|
}
|
|
@@ -12352,7 +12582,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12352
12582
|
subs = [];
|
|
12353
12583
|
}
|
|
12354
12584
|
for (const sub of subs) {
|
|
12355
|
-
const dir =
|
|
12585
|
+
const dir = join10(root, sub);
|
|
12356
12586
|
let files;
|
|
12357
12587
|
try {
|
|
12358
12588
|
files = readdirSync3(dir);
|
|
@@ -12362,7 +12592,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12362
12592
|
for (const f of files) {
|
|
12363
12593
|
if (!f.endsWith(".jsonl"))
|
|
12364
12594
|
continue;
|
|
12365
|
-
const full =
|
|
12595
|
+
const full = join10(dir, f);
|
|
12366
12596
|
if (existingBefore.has(full))
|
|
12367
12597
|
continue;
|
|
12368
12598
|
if (readJsonlCwd(full) === targetCwd)
|
|
@@ -12376,7 +12606,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
12376
12606
|
function parseTranscript2(path7, defaultModel) {
|
|
12377
12607
|
let raw;
|
|
12378
12608
|
try {
|
|
12379
|
-
raw =
|
|
12609
|
+
raw = readFileSync11(path7, "utf8");
|
|
12380
12610
|
} catch {
|
|
12381
12611
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
12382
12612
|
}
|
|
@@ -12436,7 +12666,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
|
|
|
12436
12666
|
}
|
|
12437
12667
|
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
12438
12668
|
try {
|
|
12439
|
-
unlinkSync3(
|
|
12669
|
+
unlinkSync3(join10(cwd, f));
|
|
12440
12670
|
} catch {
|
|
12441
12671
|
}
|
|
12442
12672
|
}
|
|
@@ -12464,17 +12694,17 @@ var init_tmux_runner = __esm({
|
|
|
12464
12694
|
}
|
|
12465
12695
|
};
|
|
12466
12696
|
mutex = Promise.resolve();
|
|
12467
|
-
PROJECTS_ROOT = () =>
|
|
12697
|
+
PROJECTS_ROOT = () => join10(homedir5(), ".claude", "projects");
|
|
12468
12698
|
}
|
|
12469
12699
|
});
|
|
12470
12700
|
|
|
12471
12701
|
// ../entries/dist/llm-runner.js
|
|
12472
12702
|
import { spawn as spawn3 } from "node:child_process";
|
|
12473
|
-
import { mkdirSync as mkdirSync8, appendFileSync as appendFileSync2, writeFileSync as writeFileSync7, existsSync as
|
|
12474
|
-
import { join as
|
|
12703
|
+
import { mkdirSync as mkdirSync8, appendFileSync as appendFileSync2, writeFileSync as writeFileSync7, existsSync as existsSync10 } from "node:fs";
|
|
12704
|
+
import { join as join11 } from "node:path";
|
|
12475
12705
|
import { randomUUID } from "node:crypto";
|
|
12476
12706
|
function ensureRunsDir() {
|
|
12477
|
-
if (!
|
|
12707
|
+
if (!existsSync10(RUNS_DIR)) {
|
|
12478
12708
|
try {
|
|
12479
12709
|
mkdirSync8(RUNS_DIR, { recursive: true });
|
|
12480
12710
|
} catch {
|
|
@@ -12503,7 +12733,7 @@ function newRunId(kind) {
|
|
|
12503
12733
|
return `${ts}_${kind}_${short}`;
|
|
12504
12734
|
}
|
|
12505
12735
|
function tracePath(runId) {
|
|
12506
|
-
return
|
|
12736
|
+
return join11(RUNS_DIR, `${runId}.jsonl`);
|
|
12507
12737
|
}
|
|
12508
12738
|
function safeAppend(path7, line) {
|
|
12509
12739
|
try {
|
|
@@ -12591,7 +12821,7 @@ async function runClaudeSubprocess(args2) {
|
|
|
12591
12821
|
return runClaudePrintMode(args2);
|
|
12592
12822
|
}
|
|
12593
12823
|
function runClaudePrintMode(args2) {
|
|
12594
|
-
return new Promise((
|
|
12824
|
+
return new Promise((resolve4, reject) => {
|
|
12595
12825
|
ensureRunsDir();
|
|
12596
12826
|
const kind = detectKindFromSystemPrompt(args2.systemPrompt);
|
|
12597
12827
|
const runId = newRunId(kind);
|
|
@@ -12722,7 +12952,7 @@ ${args2.reminder}` : args2.userPrompt;
|
|
|
12722
12952
|
reject(new Error(`claude exited ${code}: ${stderr.trim().slice(0, 300)}`));
|
|
12723
12953
|
return;
|
|
12724
12954
|
}
|
|
12725
|
-
|
|
12955
|
+
resolve4({ content: buffer, input_tokens: inputTokens, output_tokens: outputTokens, model: modelUsed });
|
|
12726
12956
|
});
|
|
12727
12957
|
proc.on("error", (err) => {
|
|
12728
12958
|
safeAppend(trace, JSON.stringify({ _meta: { type: "spawn_error", run_id: runId, ts: (/* @__PURE__ */ new Date()).toISOString(), error: err.message } }) + "\n");
|
|
@@ -12919,8 +13149,8 @@ var init_enrich2 = __esm({
|
|
|
12919
13149
|
});
|
|
12920
13150
|
|
|
12921
13151
|
// ../entries/dist/budget.js
|
|
12922
|
-
import { appendFileSync as appendFileSync3, readFileSync as
|
|
12923
|
-
import { dirname as
|
|
13152
|
+
import { appendFileSync as appendFileSync3, readFileSync as readFileSync12, existsSync as existsSync11, mkdirSync as mkdirSync9 } from "node:fs";
|
|
13153
|
+
import { dirname as dirname9 } from "node:path";
|
|
12924
13154
|
function spendPath() {
|
|
12925
13155
|
if (spendPathCached)
|
|
12926
13156
|
return spendPathCached;
|
|
@@ -12932,17 +13162,17 @@ function __setSpendPathForTest(path7) {
|
|
|
12932
13162
|
}
|
|
12933
13163
|
function appendSpend(record) {
|
|
12934
13164
|
const p = spendPath();
|
|
12935
|
-
mkdirSync9(
|
|
13165
|
+
mkdirSync9(dirname9(p), { recursive: true });
|
|
12936
13166
|
appendFileSync3(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
12937
13167
|
}
|
|
12938
13168
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
12939
13169
|
const p = spendPath();
|
|
12940
|
-
if (!
|
|
13170
|
+
if (!existsSync11(p))
|
|
12941
13171
|
return 0;
|
|
12942
13172
|
const year = now.getUTCFullYear();
|
|
12943
13173
|
const month2 = now.getUTCMonth();
|
|
12944
13174
|
let total = 0;
|
|
12945
|
-
const raw =
|
|
13175
|
+
const raw = readFileSync12(p, "utf8");
|
|
12946
13176
|
for (const line of raw.split("\n")) {
|
|
12947
13177
|
if (!line)
|
|
12948
13178
|
continue;
|
|
@@ -12971,7 +13201,7 @@ var init_budget = __esm({
|
|
|
12971
13201
|
});
|
|
12972
13202
|
|
|
12973
13203
|
// ../entries/dist/pipeline-lock.js
|
|
12974
|
-
import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, existsSync as
|
|
13204
|
+
import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync4, existsSync as existsSync12, readFileSync as readFileSync13, statSync as statSync3 } from "node:fs";
|
|
12975
13205
|
function lockPath() {
|
|
12976
13206
|
if (lockPathCached)
|
|
12977
13207
|
return lockPathCached;
|
|
@@ -13016,13 +13246,13 @@ function pidAlive(pid) {
|
|
|
13016
13246
|
}
|
|
13017
13247
|
function interactiveLockFresh(nowMs) {
|
|
13018
13248
|
const p = lockPath();
|
|
13019
|
-
if (!
|
|
13249
|
+
if (!existsSync12(p))
|
|
13020
13250
|
return false;
|
|
13021
13251
|
try {
|
|
13022
|
-
const mtime =
|
|
13252
|
+
const mtime = statSync3(p).mtimeMs;
|
|
13023
13253
|
if (nowMs - mtime > STALE_MS)
|
|
13024
13254
|
return false;
|
|
13025
|
-
const pid = Number(
|
|
13255
|
+
const pid = Number(readFileSync13(p, "utf8").trim());
|
|
13026
13256
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
13027
13257
|
return false;
|
|
13028
13258
|
if (!pidAlive(pid))
|
|
@@ -13128,8 +13358,8 @@ var init_queue = __esm({
|
|
|
13128
13358
|
});
|
|
13129
13359
|
|
|
13130
13360
|
// ../entries/dist/settings.js
|
|
13131
|
-
import { readFileSync as
|
|
13132
|
-
import { dirname as
|
|
13361
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync9, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync10, existsSync as existsSync13 } from "node:fs";
|
|
13362
|
+
import { dirname as dirname10 } from "node:path";
|
|
13133
13363
|
function settingsPath() {
|
|
13134
13364
|
if (settingsPathCached)
|
|
13135
13365
|
return settingsPathCached;
|
|
@@ -13164,10 +13394,10 @@ function fromDisk(d) {
|
|
|
13164
13394
|
}
|
|
13165
13395
|
function readSettings() {
|
|
13166
13396
|
const p = settingsPath();
|
|
13167
|
-
if (!
|
|
13397
|
+
if (!existsSync13(p))
|
|
13168
13398
|
return DEFAULT_SETTINGS;
|
|
13169
13399
|
try {
|
|
13170
|
-
const raw =
|
|
13400
|
+
const raw = readFileSync14(p, "utf8");
|
|
13171
13401
|
return fromDisk(JSON.parse(raw));
|
|
13172
13402
|
} catch {
|
|
13173
13403
|
return DEFAULT_SETTINGS;
|
|
@@ -13175,7 +13405,7 @@ function readSettings() {
|
|
|
13175
13405
|
}
|
|
13176
13406
|
function writeSettings(s) {
|
|
13177
13407
|
const p = settingsPath();
|
|
13178
|
-
mkdirSync10(
|
|
13408
|
+
mkdirSync10(dirname10(p), { recursive: true });
|
|
13179
13409
|
const tmp = `${p}.tmp`;
|
|
13180
13410
|
writeFileSync9(tmp, JSON.stringify(toDisk(s), null, 2), { encoding: "utf8" });
|
|
13181
13411
|
if (process.platform !== "win32") {
|
|
@@ -16918,8 +17148,8 @@ var init_config = __esm({
|
|
|
16918
17148
|
});
|
|
16919
17149
|
|
|
16920
17150
|
// src/perception/build-entries.ts
|
|
16921
|
-
import { statSync as
|
|
16922
|
-
import { basename, dirname as
|
|
17151
|
+
import { statSync as statSync4, readFileSync as readFileSync15 } from "node:fs";
|
|
17152
|
+
import { basename as basename2, dirname as dirname11 } from "node:path";
|
|
16923
17153
|
function decodeProjectDirName(projectDir) {
|
|
16924
17154
|
if (projectDir.startsWith("-")) {
|
|
16925
17155
|
return "/" + projectDir.slice(1).replace(/-/g, "/");
|
|
@@ -16927,8 +17157,8 @@ function decodeProjectDirName(projectDir) {
|
|
|
16927
17157
|
return projectDir.replace(/-/g, "/");
|
|
16928
17158
|
}
|
|
16929
17159
|
function buildEntriesForFile(filePath) {
|
|
16930
|
-
const stat =
|
|
16931
|
-
const raw =
|
|
17160
|
+
const stat = statSync4(filePath);
|
|
17161
|
+
const raw = readFileSync15(filePath, "utf8");
|
|
16932
17162
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
16933
17163
|
try {
|
|
16934
17164
|
return JSON.parse(l);
|
|
@@ -16938,8 +17168,8 @@ function buildEntriesForFile(filePath) {
|
|
|
16938
17168
|
}).filter((x) => x !== null);
|
|
16939
17169
|
if (rawLines.length === 0) return null;
|
|
16940
17170
|
const { meta, events } = parseTranscript(rawLines);
|
|
16941
|
-
const fileName =
|
|
16942
|
-
const projectDir =
|
|
17171
|
+
const fileName = basename2(filePath);
|
|
17172
|
+
const projectDir = basename2(dirname11(filePath));
|
|
16943
17173
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
16944
17174
|
const sd = {
|
|
16945
17175
|
...meta,
|
|
@@ -17025,7 +17255,7 @@ function clipSegmentsToDay(segments, bounds) {
|
|
|
17025
17255
|
}
|
|
17026
17256
|
function filterSyncedSessions(sessions, syncProjects) {
|
|
17027
17257
|
if (!syncProjects) return sessions;
|
|
17028
|
-
return sessions.filter((s) => shouldSyncProject(
|
|
17258
|
+
return sessions.filter((s) => shouldSyncProject(projectKey(s.projectName), syncProjects));
|
|
17029
17259
|
}
|
|
17030
17260
|
function sessionTouchesDay(s, day2) {
|
|
17031
17261
|
const bounds = dayBoundsMs(day2);
|
|
@@ -17066,7 +17296,7 @@ function buildRichRollupBlocks(day2, daySessions, entries2, resolveRepo) {
|
|
|
17066
17296
|
const projects = /* @__PURE__ */ new Map();
|
|
17067
17297
|
for (const s of clippedSessions) {
|
|
17068
17298
|
const canonical = canonicalProjectName(s.projectName);
|
|
17069
|
-
const name =
|
|
17299
|
+
const name = projectKey(s.projectName);
|
|
17070
17300
|
const repo = resolveRepo?.(canonical) ?? sessionRepo.get(s.id);
|
|
17071
17301
|
const key = repo ?? name;
|
|
17072
17302
|
const ms = s.activeSegments.reduce((sum, seg) => sum + (seg.endMs - seg.startMs), 0);
|
|
@@ -17109,7 +17339,7 @@ function buildRichRollupBlocks(day2, daySessions, entries2, resolveRepo) {
|
|
|
17109
17339
|
commits += e.numbers.commits;
|
|
17110
17340
|
pushes += e.numbers.pushes;
|
|
17111
17341
|
if (e.github_repos?.length) {
|
|
17112
|
-
const key = sessionRepo.get(e.session_id) ??
|
|
17342
|
+
const key = sessionRepo.get(e.session_id) ?? projectKey(e.project);
|
|
17113
17343
|
const set = projectRepos.get(key) ?? /* @__PURE__ */ new Set();
|
|
17114
17344
|
for (const r of e.github_repos) set.add(r);
|
|
17115
17345
|
projectRepos.set(key, set);
|
|
@@ -17193,7 +17423,7 @@ function buildIngestPayload(inputs) {
|
|
|
17193
17423
|
return {
|
|
17194
17424
|
ingestId: randomUUID2(),
|
|
17195
17425
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
17196
|
-
cliVersion: "0.15.
|
|
17426
|
+
cliVersion: "0.15.3",
|
|
17197
17427
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
17198
17428
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
17199
17429
|
...richRollup ? { richRollup } : {},
|
|
@@ -17234,13 +17464,13 @@ var init_push = __esm({
|
|
|
17234
17464
|
});
|
|
17235
17465
|
|
|
17236
17466
|
// src/team/git-remote.ts
|
|
17237
|
-
import { existsSync as
|
|
17238
|
-
import { dirname as
|
|
17467
|
+
import { existsSync as existsSync14, readFileSync as readFileSync16, statSync as statSync5 } from "node:fs";
|
|
17468
|
+
import { dirname as dirname12, isAbsolute as isAbsolute2, join as join12, resolve as resolve2 } from "node:path";
|
|
17239
17469
|
function parseGithubRemote(url) {
|
|
17240
17470
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
17241
17471
|
return m ? `${m[1]}/${m[2]}`.toLowerCase() : null;
|
|
17242
17472
|
}
|
|
17243
|
-
function
|
|
17473
|
+
function originUrl2(configText) {
|
|
17244
17474
|
let inOrigin = false;
|
|
17245
17475
|
for (const line of configText.split("\n")) {
|
|
17246
17476
|
const t = line.trim();
|
|
@@ -17255,36 +17485,36 @@ function originUrl(configText) {
|
|
|
17255
17485
|
return null;
|
|
17256
17486
|
}
|
|
17257
17487
|
function gitConfigPathFor(dir) {
|
|
17258
|
-
const dotGit =
|
|
17259
|
-
const st =
|
|
17488
|
+
const dotGit = join12(dir, ".git");
|
|
17489
|
+
const st = statSync5(dotGit, { throwIfNoEntry: false });
|
|
17260
17490
|
if (!st) return null;
|
|
17261
|
-
if (st.isDirectory()) return
|
|
17262
|
-
const m =
|
|
17491
|
+
if (st.isDirectory()) return join12(dotGit, "config");
|
|
17492
|
+
const m = readFileSync16(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
17263
17493
|
if (!m) return null;
|
|
17264
|
-
const gd =
|
|
17265
|
-
const commondirFile =
|
|
17266
|
-
if (
|
|
17267
|
-
const common =
|
|
17268
|
-
return
|
|
17494
|
+
const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
|
|
17495
|
+
const commondirFile = join12(gd, "commondir");
|
|
17496
|
+
if (existsSync14(commondirFile)) {
|
|
17497
|
+
const common = readFileSync16(commondirFile, "utf8").trim();
|
|
17498
|
+
return join12(isAbsolute2(common) ? common : resolve2(gd, common), "config");
|
|
17269
17499
|
}
|
|
17270
|
-
return
|
|
17500
|
+
return join12(gd, "config");
|
|
17271
17501
|
}
|
|
17272
17502
|
function createRepoResolver() {
|
|
17273
17503
|
const cache = /* @__PURE__ */ new Map();
|
|
17274
17504
|
return (dir) => {
|
|
17275
|
-
if (!dir || !
|
|
17505
|
+
if (!dir || !isAbsolute2(dir)) return null;
|
|
17276
17506
|
const hit = cache.get(dir);
|
|
17277
17507
|
if (hit !== void 0) return hit;
|
|
17278
17508
|
let repo = null;
|
|
17279
17509
|
try {
|
|
17280
|
-
for (let d = dir; ; d =
|
|
17510
|
+
for (let d = dir; ; d = dirname12(d)) {
|
|
17281
17511
|
const config = gitConfigPathFor(d);
|
|
17282
|
-
if (config &&
|
|
17283
|
-
const url =
|
|
17512
|
+
if (config && existsSync14(config)) {
|
|
17513
|
+
const url = originUrl2(readFileSync16(config, "utf8"));
|
|
17284
17514
|
repo = url ? parseGithubRemote(url) : null;
|
|
17285
17515
|
break;
|
|
17286
17516
|
}
|
|
17287
|
-
if (d ===
|
|
17517
|
+
if (d === dirname12(d)) break;
|
|
17288
17518
|
}
|
|
17289
17519
|
} catch {
|
|
17290
17520
|
repo = null;
|
|
@@ -17302,14 +17532,14 @@ var init_git_remote = __esm({
|
|
|
17302
17532
|
});
|
|
17303
17533
|
|
|
17304
17534
|
// src/team/queue.ts
|
|
17305
|
-
import { readFileSync as
|
|
17306
|
-
import { dirname as
|
|
17535
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync10, appendFileSync as appendFileSync4, statSync as statSync6, mkdirSync as mkdirSync11 } from "node:fs";
|
|
17536
|
+
import { dirname as dirname13 } from "node:path";
|
|
17307
17537
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
17308
|
-
mkdirSync11(
|
|
17538
|
+
mkdirSync11(dirname13(queuePath), { recursive: true });
|
|
17309
17539
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
17310
17540
|
appendFileSync4(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
17311
17541
|
try {
|
|
17312
|
-
const { size } =
|
|
17542
|
+
const { size } = statSync6(queuePath);
|
|
17313
17543
|
if (size > MAX_SIZE_BYTES) {
|
|
17314
17544
|
pruneOldest(queuePath);
|
|
17315
17545
|
}
|
|
@@ -17319,7 +17549,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
17319
17549
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
17320
17550
|
let lines;
|
|
17321
17551
|
try {
|
|
17322
|
-
lines =
|
|
17552
|
+
lines = readFileSync17(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
17323
17553
|
} catch {
|
|
17324
17554
|
return [];
|
|
17325
17555
|
}
|
|
@@ -17340,7 +17570,7 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
17340
17570
|
function pruneOldest(queuePath) {
|
|
17341
17571
|
let lines;
|
|
17342
17572
|
try {
|
|
17343
|
-
lines =
|
|
17573
|
+
lines = readFileSync17(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
17344
17574
|
} catch {
|
|
17345
17575
|
return;
|
|
17346
17576
|
}
|
|
@@ -17359,8 +17589,8 @@ var init_queue2 = __esm({
|
|
|
17359
17589
|
});
|
|
17360
17590
|
|
|
17361
17591
|
// src/usage/profile.ts
|
|
17362
|
-
import { existsSync as
|
|
17363
|
-
import { dirname as
|
|
17592
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync12, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "node:fs";
|
|
17593
|
+
import { dirname as dirname14 } from "node:path";
|
|
17364
17594
|
function mapRateLimitTier(rateLimitTier) {
|
|
17365
17595
|
switch (rateLimitTier) {
|
|
17366
17596
|
case "default_claude_pro":
|
|
@@ -17400,9 +17630,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
17400
17630
|
};
|
|
17401
17631
|
}
|
|
17402
17632
|
function readCachedProfile(cachePath) {
|
|
17403
|
-
if (!
|
|
17633
|
+
if (!existsSync15(cachePath)) return null;
|
|
17404
17634
|
try {
|
|
17405
|
-
const raw = JSON.parse(
|
|
17635
|
+
const raw = JSON.parse(readFileSync18(cachePath, "utf8"));
|
|
17406
17636
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
17407
17637
|
return raw;
|
|
17408
17638
|
} catch {
|
|
@@ -17410,7 +17640,7 @@ function readCachedProfile(cachePath) {
|
|
|
17410
17640
|
}
|
|
17411
17641
|
}
|
|
17412
17642
|
function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
|
|
17413
|
-
mkdirSync12(
|
|
17643
|
+
mkdirSync12(dirname14(cachePath), { recursive: true });
|
|
17414
17644
|
writeFileSync11(
|
|
17415
17645
|
cachePath,
|
|
17416
17646
|
JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
|
|
@@ -17591,11 +17821,11 @@ var init_backfill = __esm({
|
|
|
17591
17821
|
});
|
|
17592
17822
|
|
|
17593
17823
|
// src/team/sync-log.ts
|
|
17594
|
-
import { readFileSync as
|
|
17824
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
17595
17825
|
function readPendingSyncLog(watermark) {
|
|
17596
17826
|
let raw;
|
|
17597
17827
|
try {
|
|
17598
|
-
raw =
|
|
17828
|
+
raw = readFileSync19(cclensPath("daemon.log"), "utf8");
|
|
17599
17829
|
} catch {
|
|
17600
17830
|
return { lines: [] };
|
|
17601
17831
|
}
|
|
@@ -17624,11 +17854,11 @@ var init_sync_log = __esm({
|
|
|
17624
17854
|
|
|
17625
17855
|
// src/team/last-push.ts
|
|
17626
17856
|
import { writeFileSync as writeFileSync12, unlinkSync as unlinkSync5, mkdirSync as mkdirSync13 } from "node:fs";
|
|
17627
|
-
import { join as
|
|
17857
|
+
import { join as join13 } from "node:path";
|
|
17628
17858
|
function write(record, dir) {
|
|
17629
17859
|
const d = dir ?? cclensHome();
|
|
17630
17860
|
mkdirSync13(d, { recursive: true });
|
|
17631
|
-
writeFileSync12(
|
|
17861
|
+
writeFileSync12(join13(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
17632
17862
|
}
|
|
17633
17863
|
function writeLastPushSuccess(payload, dir) {
|
|
17634
17864
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -17639,7 +17869,7 @@ function writeLastPushFailure(payload, error, dir) {
|
|
|
17639
17869
|
function clearLastPush(dir) {
|
|
17640
17870
|
const d = dir ?? cclensHome();
|
|
17641
17871
|
try {
|
|
17642
|
-
unlinkSync5(
|
|
17872
|
+
unlinkSync5(join13(d, LAST_PUSH_FILE));
|
|
17643
17873
|
} catch {
|
|
17644
17874
|
}
|
|
17645
17875
|
}
|
|
@@ -17659,25 +17889,25 @@ __export(file_probe_exports, {
|
|
|
17659
17889
|
probeArtifactSignals: () => probeArtifactSignals
|
|
17660
17890
|
});
|
|
17661
17891
|
import { createHash } from "node:crypto";
|
|
17662
|
-
import { existsSync as
|
|
17663
|
-
import { homedir as
|
|
17664
|
-
import { join as
|
|
17892
|
+
import { existsSync as existsSync16, readdirSync as readdirSync4, statSync as statSync7 } from "node:fs";
|
|
17893
|
+
import { homedir as homedir6 } from "node:os";
|
|
17894
|
+
import { join as join14, relative, resolve as resolve3, sep } from "node:path";
|
|
17665
17895
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
17666
17896
|
function pathHash(relPath) {
|
|
17667
17897
|
return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
17668
17898
|
}
|
|
17669
17899
|
function defaultScanRoots(extraRoots = []) {
|
|
17670
17900
|
const roots = [];
|
|
17671
|
-
const home =
|
|
17672
|
-
if (
|
|
17901
|
+
const home = join14(homedir6(), ".claude");
|
|
17902
|
+
if (existsSync16(home)) roots.push({ root: home, label: "user" });
|
|
17673
17903
|
for (const e of extraRoots) {
|
|
17674
|
-
const r =
|
|
17675
|
-
if (
|
|
17904
|
+
const r = resolve3(e, ".claude");
|
|
17905
|
+
if (existsSync16(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
17676
17906
|
}
|
|
17677
17907
|
return roots;
|
|
17678
17908
|
}
|
|
17679
17909
|
function listMarkdownFiles(dir) {
|
|
17680
|
-
if (!
|
|
17910
|
+
if (!existsSync16(dir)) return [];
|
|
17681
17911
|
const out = [];
|
|
17682
17912
|
let entries2;
|
|
17683
17913
|
try {
|
|
@@ -17687,10 +17917,10 @@ function listMarkdownFiles(dir) {
|
|
|
17687
17917
|
}
|
|
17688
17918
|
for (const name of entries2) {
|
|
17689
17919
|
if (name.startsWith(".")) continue;
|
|
17690
|
-
const full =
|
|
17920
|
+
const full = join14(dir, name);
|
|
17691
17921
|
let stat;
|
|
17692
17922
|
try {
|
|
17693
|
-
stat =
|
|
17923
|
+
stat = statSync7(full);
|
|
17694
17924
|
} catch {
|
|
17695
17925
|
continue;
|
|
17696
17926
|
}
|
|
@@ -17707,19 +17937,19 @@ function firstSeenDateOf(file) {
|
|
|
17707
17937
|
const out = execFileSync3(
|
|
17708
17938
|
"git",
|
|
17709
17939
|
["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
|
|
17710
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
17940
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname15(file) }
|
|
17711
17941
|
).trim().split("\n").filter(Boolean);
|
|
17712
17942
|
if (out.length > 0) return out[out.length - 1];
|
|
17713
17943
|
} catch {
|
|
17714
17944
|
}
|
|
17715
17945
|
try {
|
|
17716
|
-
const s =
|
|
17946
|
+
const s = statSync7(file);
|
|
17717
17947
|
return localDay(s.birthtime || s.mtime);
|
|
17718
17948
|
} catch {
|
|
17719
17949
|
return todayLocal();
|
|
17720
17950
|
}
|
|
17721
17951
|
}
|
|
17722
|
-
function
|
|
17952
|
+
function dirname15(p) {
|
|
17723
17953
|
const i = p.lastIndexOf(sep);
|
|
17724
17954
|
return i < 0 ? "." : p.slice(0, i);
|
|
17725
17955
|
}
|
|
@@ -17746,8 +17976,8 @@ function todayLocal() {
|
|
|
17746
17976
|
function scanAuthored(roots, subdir, day2) {
|
|
17747
17977
|
const out = [];
|
|
17748
17978
|
for (const r of roots) {
|
|
17749
|
-
const dir =
|
|
17750
|
-
if (!
|
|
17979
|
+
const dir = join14(r.root, subdir);
|
|
17980
|
+
if (!existsSync16(dir)) continue;
|
|
17751
17981
|
for (const f of listMarkdownFiles(dir)) {
|
|
17752
17982
|
const firstSeen = firstSeenDateOf(f);
|
|
17753
17983
|
if (firstSeen !== day2) continue;
|
|
@@ -17760,14 +17990,14 @@ function scanAuthored(roots, subdir, day2) {
|
|
|
17760
17990
|
function scanEdited(roots, day2) {
|
|
17761
17991
|
const out = [];
|
|
17762
17992
|
for (const r of roots) {
|
|
17763
|
-
const dir =
|
|
17764
|
-
if (!
|
|
17993
|
+
const dir = join14(r.root, "skills");
|
|
17994
|
+
if (!existsSync16(dir)) continue;
|
|
17765
17995
|
for (const f of listMarkdownFiles(dir)) {
|
|
17766
17996
|
const firstSeen = firstSeenDateOf(f);
|
|
17767
17997
|
if (firstSeen === day2) continue;
|
|
17768
17998
|
let stat;
|
|
17769
17999
|
try {
|
|
17770
|
-
stat =
|
|
18000
|
+
stat = statSync7(f);
|
|
17771
18001
|
} catch {
|
|
17772
18002
|
continue;
|
|
17773
18003
|
}
|
|
@@ -17783,17 +18013,17 @@ function claudemdLineDelta(extraRoots, authorEmail, day2) {
|
|
|
17783
18013
|
let delta = 0;
|
|
17784
18014
|
const candidates = [];
|
|
17785
18015
|
for (const e of extraRoots) {
|
|
17786
|
-
const f =
|
|
17787
|
-
if (
|
|
18016
|
+
const f = resolve3(e, "CLAUDE.md");
|
|
18017
|
+
if (existsSync16(f)) candidates.push(f);
|
|
17788
18018
|
}
|
|
17789
|
-
const homeClaudeMd =
|
|
17790
|
-
if (
|
|
18019
|
+
const homeClaudeMd = join14(homedir6(), "CLAUDE.md");
|
|
18020
|
+
if (existsSync16(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
17791
18021
|
for (const file of candidates) {
|
|
17792
18022
|
try {
|
|
17793
18023
|
const out = execFileSync3(
|
|
17794
18024
|
"git",
|
|
17795
18025
|
["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
|
|
17796
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
18026
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname15(file) }
|
|
17797
18027
|
);
|
|
17798
18028
|
let currentDate = "";
|
|
17799
18029
|
let currentEmail = "";
|
|
@@ -17857,8 +18087,8 @@ async function dispatchCommand(command2, config, log) {
|
|
|
17857
18087
|
}
|
|
17858
18088
|
}
|
|
17859
18089
|
async function runActivityBackfill(command2, config, log) {
|
|
17860
|
-
const { listSessions: listSessions2, shouldSyncProject: shouldSyncProject2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
17861
|
-
const { toLocalDay: toLocalDay4,
|
|
18090
|
+
const { listSessions: listSessions2, resolveProjectIdentity: resolveProjectIdentity2, shouldSyncProject: shouldSyncProject2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
18091
|
+
const { toLocalDay: toLocalDay4, projectKey: projectKey2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
17862
18092
|
const { probeArtifactSignals: probeArtifactSignals2 } = await Promise.resolve().then(() => (init_file_probe(), file_probe_exports));
|
|
17863
18093
|
const days = command2.params.days;
|
|
17864
18094
|
const todayMs = Date.now();
|
|
@@ -17892,7 +18122,7 @@ async function runActivityBackfill(command2, config, log) {
|
|
|
17892
18122
|
const richBlocks = buildRichBlocksForDay(rollup.day, daySessions, resolveRepo);
|
|
17893
18123
|
let artifactSignals = null;
|
|
17894
18124
|
try {
|
|
17895
|
-
const cwdAllowed = shouldSyncProject2(
|
|
18125
|
+
const cwdAllowed = shouldSyncProject2(projectKey2(resolveProjectIdentity2(process.cwd()).projectName), config.syncProjects);
|
|
17896
18126
|
artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: cwdAllowed ? [process.cwd()] : [] });
|
|
17897
18127
|
} catch {
|
|
17898
18128
|
}
|
|
@@ -18044,7 +18274,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
|
|
|
18044
18274
|
try {
|
|
18045
18275
|
resetEnsuredSessions();
|
|
18046
18276
|
const { listSessions: listSessions2, loadCalibrationCurve: loadCalibrationCurve2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
18047
|
-
const { toLocalDay: toLocalDay4
|
|
18277
|
+
const { toLocalDay: toLocalDay4 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
18048
18278
|
const today = toLocalDay4(Date.now());
|
|
18049
18279
|
let patches = {};
|
|
18050
18280
|
const persistConfig = (patch) => {
|
|
@@ -18231,7 +18461,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
|
|
|
18231
18461
|
} : void 0;
|
|
18232
18462
|
let artifactSignals = null;
|
|
18233
18463
|
try {
|
|
18234
|
-
const cwdAllowed = shouldSyncProject(
|
|
18464
|
+
const cwdAllowed = shouldSyncProject(projectKey(resolveProjectIdentity(process.cwd()).projectName), config.syncProjects);
|
|
18235
18465
|
artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: cwdAllowed ? [process.cwd()] : [] });
|
|
18236
18466
|
} catch {
|
|
18237
18467
|
}
|
|
@@ -18429,6 +18659,7 @@ var init_sync = __esm({
|
|
|
18429
18659
|
init_last_push();
|
|
18430
18660
|
init_commands();
|
|
18431
18661
|
init_profile();
|
|
18662
|
+
init_dist();
|
|
18432
18663
|
init_fs();
|
|
18433
18664
|
inFlightCommands = /* @__PURE__ */ new Set();
|
|
18434
18665
|
USAGE_LOG4 = cclensPath("usage.jsonl");
|
|
@@ -18659,11 +18890,11 @@ var logs_exports = {};
|
|
|
18659
18890
|
__export(logs_exports, {
|
|
18660
18891
|
teamLogs: () => teamLogs
|
|
18661
18892
|
});
|
|
18662
|
-
import { readFileSync as
|
|
18893
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
18663
18894
|
async function teamLogs() {
|
|
18664
18895
|
const logPath = cclensPath("daemon.log");
|
|
18665
18896
|
try {
|
|
18666
|
-
const lines =
|
|
18897
|
+
const lines = readFileSync20(logPath, "utf8").trim().split("\n");
|
|
18667
18898
|
const teamLines = lines.filter((l) => l.includes("[sync] ") || l.includes("team "));
|
|
18668
18899
|
if (teamLines.length === 0) {
|
|
18669
18900
|
console.log("No team-related log entries found.");
|
|
@@ -18791,8 +19022,8 @@ __export(runs_exports, {
|
|
|
18791
19022
|
runs: () => runs
|
|
18792
19023
|
});
|
|
18793
19024
|
import { execSync as execSync2 } from "node:child_process";
|
|
18794
|
-
import { existsSync as
|
|
18795
|
-
import { join as
|
|
19025
|
+
import { existsSync as existsSync17, readFileSync as readFileSync21, readdirSync as readdirSync5, statSync as statSync8 } from "node:fs";
|
|
19026
|
+
import { join as join15 } from "node:path";
|
|
18796
19027
|
async function runs(args2) {
|
|
18797
19028
|
const json = args2.includes("--json");
|
|
18798
19029
|
const watch = args2.includes("--watch");
|
|
@@ -18876,8 +19107,8 @@ function listActiveRuns() {
|
|
|
18876
19107
|
return runs2.sort((a, b) => a.elapsed_s - b.elapsed_s);
|
|
18877
19108
|
}
|
|
18878
19109
|
function readSpend(sinceMs) {
|
|
18879
|
-
if (!
|
|
18880
|
-
const lines =
|
|
19110
|
+
if (!existsSync17(SPEND_PATH)) return [];
|
|
19111
|
+
const lines = readFileSync21(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
|
|
18881
19112
|
const out = [];
|
|
18882
19113
|
for (const line of lines) {
|
|
18883
19114
|
try {
|
|
@@ -18998,23 +19229,23 @@ function ageLabel(ms) {
|
|
|
18998
19229
|
return `${Math.floor(ms / 864e5)}d`;
|
|
18999
19230
|
}
|
|
19000
19231
|
function listTraceFiles() {
|
|
19001
|
-
if (!
|
|
19232
|
+
if (!existsSync17(RUNS_DIR2)) return [];
|
|
19002
19233
|
const entries2 = readdirSync5(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
|
|
19003
19234
|
return entries2.map((f) => {
|
|
19004
|
-
const path7 =
|
|
19005
|
-
const st =
|
|
19235
|
+
const path7 = join15(RUNS_DIR2, f);
|
|
19236
|
+
const st = statSync8(path7);
|
|
19006
19237
|
return { runId: f.replace(/\.jsonl$/, ""), path: path7, mtimeMs: st.mtimeMs };
|
|
19007
19238
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
19008
19239
|
}
|
|
19009
19240
|
function resolveRunId(arg) {
|
|
19010
|
-
if (!
|
|
19241
|
+
if (!existsSync17(RUNS_DIR2)) return null;
|
|
19011
19242
|
if (arg === "latest") {
|
|
19012
19243
|
const all2 = listTraceFiles();
|
|
19013
19244
|
if (all2.length === 0) return null;
|
|
19014
19245
|
return { runId: all2[0].runId, path: all2[0].path };
|
|
19015
19246
|
}
|
|
19016
|
-
const exact =
|
|
19017
|
-
if (
|
|
19247
|
+
const exact = join15(RUNS_DIR2, `${arg}.jsonl`);
|
|
19248
|
+
if (existsSync17(exact)) return { runId: arg, path: exact };
|
|
19018
19249
|
const all = listTraceFiles();
|
|
19019
19250
|
const matches = all.filter((r) => r.runId.includes(arg));
|
|
19020
19251
|
if (matches.length === 1) return { runId: matches[0].runId, path: matches[0].path };
|
|
@@ -19026,7 +19257,7 @@ function resolveRunId(arg) {
|
|
|
19026
19257
|
return null;
|
|
19027
19258
|
}
|
|
19028
19259
|
function readTrace(path7) {
|
|
19029
|
-
return
|
|
19260
|
+
return readFileSync21(path7, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
|
|
19030
19261
|
try {
|
|
19031
19262
|
return JSON.parse(l);
|
|
19032
19263
|
} catch {
|
|
@@ -19038,7 +19269,7 @@ async function inspect(arg, follow, json) {
|
|
|
19038
19269
|
const r = resolveRunId(arg);
|
|
19039
19270
|
if (!r) {
|
|
19040
19271
|
console.error(`run not found: ${arg}`);
|
|
19041
|
-
if (
|
|
19272
|
+
if (existsSync17(RUNS_DIR2)) {
|
|
19042
19273
|
const all = listTraceFiles().slice(0, 5);
|
|
19043
19274
|
if (all.length > 0) {
|
|
19044
19275
|
console.error(`
|
|
@@ -19058,13 +19289,13 @@ recent runs:`);
|
|
|
19058
19289
|
const events = readTrace(r.path);
|
|
19059
19290
|
printTrace(r.runId, events);
|
|
19060
19291
|
if (!follow) return;
|
|
19061
|
-
let lastSize =
|
|
19292
|
+
let lastSize = statSync8(r.path).size;
|
|
19062
19293
|
let lastIdx = events.length;
|
|
19063
19294
|
console.log("\n \u27F6 following \xB7 ^C to quit\n");
|
|
19064
19295
|
process.on("SIGINT", () => process.exit(0));
|
|
19065
19296
|
while (true) {
|
|
19066
19297
|
await new Promise((res) => setTimeout(res, 500));
|
|
19067
|
-
const st =
|
|
19298
|
+
const st = statSync8(r.path);
|
|
19068
19299
|
if (st.size === lastSize) continue;
|
|
19069
19300
|
lastSize = st.size;
|
|
19070
19301
|
const all = readTrace(r.path);
|
|
@@ -19213,7 +19444,7 @@ async function main() {
|
|
|
19213
19444
|
case "version":
|
|
19214
19445
|
case "--version":
|
|
19215
19446
|
case "-v":
|
|
19216
|
-
console.log(`fleetlens ${"0.15.
|
|
19447
|
+
console.log(`fleetlens ${"0.15.3"}`);
|
|
19217
19448
|
break;
|
|
19218
19449
|
case "help":
|
|
19219
19450
|
case "--help":
|