fleetlens 0.16.4 → 0.16.7
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 +32 -3
- package/app/apps/web/.next/routes-manifest.json +6 -0
- package/app/apps/web/.next/server/app/_global-error/page.js +2 -2
- package/app/apps/web/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/_global-error.html +1 -1
- package/app/apps/web/.next/server/app/_global-error.rsc +7 -7
- package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- 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 +10 -9
- 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/agent/page.js +10 -9
- package/app/apps/web/.next/server/app/agent/page.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/index/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/mcp/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/agent/suggestions/route.js.nft.json +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.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
- package/app/apps/web/.next/server/app/api/settings/credentials/route.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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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/icon.svg/route/app-paths-manifest.json +3 -0
- package/app/apps/web/.next/server/app/icon.svg/route/build-manifest.json +9 -0
- package/app/apps/web/.next/server/app/icon.svg/route.js +7 -0
- package/app/apps/web/.next/server/app/icon.svg/route.js.map +5 -0
- package/app/apps/web/.next/server/app/icon.svg/route.js.nft.json +1 -0
- package/app/apps/web/.next/server/app/icon.svg.body +7 -0
- package/app/apps/web/.next/server/app/icon.svg.meta +1 -0
- package/app/apps/web/.next/server/app/insights/[key]/page.js +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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 +10 -9
- 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/[root-of-the-server]__0o.75vf._.js +3 -0
- package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_icon_svg_route_actions_09mu110.js +3 -0
- package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
- package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0-zxvif._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__01etyrg._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__01wj6p0._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0lz4a~g._.js → [root-of-the-server]__021z658._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__07e35nb._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__11xp-1u._.js → [root-of-the-server]__0a-_-_a._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0xy1qim._.js → [root-of-the-server]__0b6a93u._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0f3q8gt._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0o1_g.~._.js → [root-of-the-server]__0fosdzf._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__04qodwp._.js → [root-of-the-server]__0h~6fzv._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ix~bkq._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0j3r6mu._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__10srpu0._.js → [root-of-the-server]__0m3g~yv._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__07~kk2~._.js → [root-of-the-server]__0n3n~yr._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0kml6jt._.js → [root-of-the-server]__0omu7re._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0.zquoa._.js → [root-of-the-server]__0ovph2e._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0ar_8wr._.js → [root-of-the-server]__0tz4w46._.js} +3 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0u0n8z~._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0ufi3.w._.js → [root-of-the-server]__0wraeyz._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0u39afl._.js → [root-of-the-server]__0wy2-yx._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ygwqfa._.js +12 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0z0wa91._.js +12 -0
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0~.gwld._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0.wm54e._.js → [root-of-the-server]__12mxxlm._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__12s3gv9._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/_0sz8~hl._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0epqfet._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_0~aj0~u._.js +1 -1
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0x014hn._.js +2 -2
- package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.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_next_dist_06u0kr8._.js +3 -0
- package/app/apps/web/.next/server/chunks/ssr/{node_modules_next_dist_06c_2qf._.js → node_modules_next_dist_0ve2ws3._.js} +2 -2
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_00g~mhv.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_01.bezr.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0289ttk.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02eo3j_.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_03vhmnm.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_07_oby5.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0bm6hj~.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dd8f-e.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0e-9-6e.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0hvl-ct.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0i1kx1j.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0j8zf-y.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0kpe55j.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0q1syx3.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0q4~c_f.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0w_~1n4.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0wcoddw.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0wil2ok.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0z65c3i.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0zaz56w.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0~onns0.js +4 -0
- package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
- package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/app/apps/web/.next/server/middleware-manifest.json +5 -5
- package/app/apps/web/.next/server/pages/500.html +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/app/apps/web/.next/static/chunks/0d~6j~aj2vr1t.js +1 -0
- package/app/apps/web/.next/static/chunks/0guxw7.w8n21l.js +14 -0
- package/app/apps/web/.next/static/chunks/{0389wb_f0j78j.js → 0n1d620va1z.z.js} +1 -1
- package/app/apps/web/.next/static/chunks/{0-z49mtd-zwgv.js → 0~opjw4gew2-w.js} +1 -1
- package/app/apps/web/.next/static/media/icon.0h9o_.fpzdvkq.svg +7 -0
- package/app/apps/web/app/icon.svg +7 -0
- package/app/apps/web/app/settings/page.tsx +1 -1
- package/app/apps/web/app/usage/page.tsx +157 -2
- package/app/apps/web/components/menubar-install-banner.tsx +1 -1
- package/app/apps/web/components/menubar-install.tsx +1 -1
- package/app/apps/web/components/sidebar.tsx +5 -11
- package/app/apps/web/components/usage-chart-range.tsx +9 -3
- package/app/apps/web/components/usage-chart.tsx +9 -3
- package/app/apps/web/components/usage-charts-dashboard.tsx +10 -3
- package/app/apps/web/lib/changelog-data.generated.ts +1 -1
- package/app/apps/web/lib/format.test.ts +10 -0
- package/app/apps/web/lib/format.ts +6 -4
- package/app/apps/web/lib/usage-data.ts +9 -0
- package/app/apps/web/package.json +1 -1
- package/app/apps/web/tsconfig.tsbuildinfo +1 -1
- package/dist/daemon-worker.js +1312 -365
- package/dist/index.js +1399 -440
- package/menubar/FleetlensMenubar.app/Contents/Info.plist +2 -2
- package/menubar/FleetlensMenubar.app/Contents/MacOS/FleetlensMenubar +0 -0
- package/package.json +1 -1
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__04eq6z2._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__09rjz7_._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0_78i1t._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0blm9gz._.js +0 -12
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0d5y90m._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0i.q-1h._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0j683am._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0lmftab._.js +0 -12
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0p1x6v2._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0stu~~r._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0tejjy_._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0k0tl52._.js +0 -3
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_02rcy0h.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0602nef.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_07orc4m.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_09aewh9.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_09rx8oz.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0d3d4wn.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0edz1ko.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0eq.n-n.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0hcvt-s.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0hshwu7.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0hwycdb.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0jxvcfi.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0nd5zu0.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0s5yhs4.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0uwo3v3.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0~g07z5.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10cdrh2.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10op6u-.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_11j1qy0.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12n1lw_.js +0 -4
- package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12r67~s.js +0 -4
- package/app/apps/web/.next/static/chunks/0rrcj195v1nd..js +0 -1
- package/app/apps/web/.next/static/chunks/13hdlcc0bj_zt.js +0 -14
- /package/app/apps/web/.next/static/{cKCY-h3trXN9_kNrMfxWd → Zna-9B0LUDyz-sTA_YAsM}/_buildManifest.js +0 -0
- /package/app/apps/web/.next/static/{cKCY-h3trXN9_kNrMfxWd → Zna-9B0LUDyz-sTA_YAsM}/_clientMiddlewareManifest.js +0 -0
- /package/app/apps/web/.next/static/{cKCY-h3trXN9_kNrMfxWd → Zna-9B0LUDyz-sTA_YAsM}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -675,7 +675,7 @@ function getAgentMetadata(kind) {
|
|
|
675
675
|
function isAgentKind(s) {
|
|
676
676
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
677
677
|
}
|
|
678
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
678
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, COPILOT_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
679
679
|
var init_agent_metadata = __esm({
|
|
680
680
|
"../parser/dist/agent-metadata.js"() {
|
|
681
681
|
"use strict";
|
|
@@ -693,6 +693,13 @@ var init_agent_metadata = __esm({
|
|
|
693
693
|
accentColor: "rgb(16, 163, 127)",
|
|
694
694
|
iconChar: "\u25C6"
|
|
695
695
|
};
|
|
696
|
+
COPILOT_METADATA = {
|
|
697
|
+
kind: "copilot",
|
|
698
|
+
displayName: "GitHub Copilot CLI",
|
|
699
|
+
shortLabel: "Copilot",
|
|
700
|
+
accentColor: "rgb(137, 87, 229)",
|
|
701
|
+
iconChar: "\u221E"
|
|
702
|
+
};
|
|
696
703
|
GEMINI_METADATA = {
|
|
697
704
|
kind: "gemini",
|
|
698
705
|
displayName: "Gemini CLI",
|
|
@@ -732,6 +739,7 @@ var init_agent_metadata = __esm({
|
|
|
732
739
|
agentMetadata = [
|
|
733
740
|
CLAUDE_CODE_METADATA,
|
|
734
741
|
CODEX_METADATA,
|
|
742
|
+
COPILOT_METADATA,
|
|
735
743
|
GEMINI_METADATA,
|
|
736
744
|
ANTIGRAVITY_METADATA,
|
|
737
745
|
COWORK_METADATA,
|
|
@@ -1593,11 +1601,11 @@ function defaultBranch(commonDir) {
|
|
|
1593
1601
|
}
|
|
1594
1602
|
return void 0;
|
|
1595
1603
|
}
|
|
1596
|
-
function readGitFolder(
|
|
1597
|
-
if (!existsSync(
|
|
1604
|
+
function readGitFolder(path11) {
|
|
1605
|
+
if (!existsSync(path11))
|
|
1598
1606
|
return { exists: false, isWorktree: false };
|
|
1599
1607
|
try {
|
|
1600
|
-
const git = nearestDotGit(realpathOrSelf(
|
|
1608
|
+
const git = nearestDotGit(realpathOrSelf(path11));
|
|
1601
1609
|
if (!git)
|
|
1602
1610
|
return { exists: true, isWorktree: false };
|
|
1603
1611
|
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
@@ -3379,24 +3387,442 @@ var init_codex = __esm({
|
|
|
3379
3387
|
}
|
|
3380
3388
|
});
|
|
3381
3389
|
|
|
3382
|
-
// ../parser/dist/
|
|
3390
|
+
// ../parser/dist/copilot.js
|
|
3383
3391
|
import { promises as fs3 } from "node:fs";
|
|
3384
3392
|
import os3 from "node:os";
|
|
3385
3393
|
import path3 from "node:path";
|
|
3386
|
-
|
|
3387
|
-
return
|
|
3394
|
+
function recordOf(value) {
|
|
3395
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
3396
|
+
}
|
|
3397
|
+
function stringOf(value) {
|
|
3398
|
+
return typeof value === "string" ? value : void 0;
|
|
3399
|
+
}
|
|
3400
|
+
function numberOf2(value) {
|
|
3401
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
3402
|
+
}
|
|
3403
|
+
function emptyUsage2() {
|
|
3404
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3405
|
+
}
|
|
3406
|
+
function previewOf2(value) {
|
|
3407
|
+
const text = typeof value === "string" ? value : JSON.stringify(value ?? "");
|
|
3408
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3409
|
+
}
|
|
3410
|
+
function tokenCount(details, key) {
|
|
3411
|
+
return numberOf2(recordOf(details?.[key])?.tokenCount);
|
|
3412
|
+
}
|
|
3413
|
+
function syntheticProjectDir(cwd) {
|
|
3414
|
+
return cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : "(unknown)";
|
|
3388
3415
|
}
|
|
3389
3416
|
async function listSessionFiles(root) {
|
|
3417
|
+
const entries2 = await fs3.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
3418
|
+
const out = [];
|
|
3419
|
+
for (const entry of entries2) {
|
|
3420
|
+
if (!entry.isDirectory())
|
|
3421
|
+
continue;
|
|
3422
|
+
const filePath = path3.join(root, entry.name, "events.jsonl");
|
|
3423
|
+
const stat = await fs3.stat(filePath).catch(() => null);
|
|
3424
|
+
if (!stat?.isFile())
|
|
3425
|
+
continue;
|
|
3426
|
+
out.push({
|
|
3427
|
+
filePath,
|
|
3428
|
+
sessionId: entry.name,
|
|
3429
|
+
mtimeMs: stat.mtimeMs,
|
|
3430
|
+
sizeBytes: stat.size
|
|
3431
|
+
});
|
|
3432
|
+
}
|
|
3433
|
+
return out;
|
|
3434
|
+
}
|
|
3435
|
+
async function readJsonl2(filePath) {
|
|
3436
|
+
const raw = await fs3.readFile(filePath, "utf8");
|
|
3437
|
+
const out = [];
|
|
3438
|
+
for (const line of raw.split("\n")) {
|
|
3439
|
+
const trimmed = line.trim();
|
|
3440
|
+
if (!trimmed)
|
|
3441
|
+
continue;
|
|
3442
|
+
try {
|
|
3443
|
+
out.push(JSON.parse(trimmed));
|
|
3444
|
+
} catch {
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
return out;
|
|
3448
|
+
}
|
|
3449
|
+
function computeActiveSegments3(timestamps) {
|
|
3450
|
+
const sorted = [...new Set(timestamps)].sort((a, b) => a - b);
|
|
3451
|
+
if (sorted.length === 0)
|
|
3452
|
+
return [];
|
|
3453
|
+
const segments = [];
|
|
3454
|
+
let start2 = sorted[0];
|
|
3455
|
+
let end = start2;
|
|
3456
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
3457
|
+
const next = sorted[i];
|
|
3458
|
+
if (next - end > IDLE_GAP_MS2) {
|
|
3459
|
+
segments.push({ startMs: start2, endMs: end });
|
|
3460
|
+
start2 = next;
|
|
3461
|
+
}
|
|
3462
|
+
end = next;
|
|
3463
|
+
}
|
|
3464
|
+
segments.push({ startMs: start2, endMs: end });
|
|
3465
|
+
return segments;
|
|
3466
|
+
}
|
|
3467
|
+
function parseSession(file, lines) {
|
|
3468
|
+
const records = lines.map(recordOf).filter((line) => line !== void 0);
|
|
3469
|
+
const executionCallIds = /* @__PURE__ */ new Set();
|
|
3470
|
+
for (const record of records) {
|
|
3471
|
+
if (record.type !== "tool.execution_start")
|
|
3472
|
+
continue;
|
|
3473
|
+
const callId = stringOf(recordOf(record.data)?.toolCallId);
|
|
3474
|
+
if (callId)
|
|
3475
|
+
executionCallIds.add(callId);
|
|
3476
|
+
}
|
|
3477
|
+
const events = [];
|
|
3478
|
+
const timestamps = [];
|
|
3479
|
+
const totalUsage = emptyUsage2();
|
|
3480
|
+
let firstMs;
|
|
3481
|
+
let lastMs;
|
|
3482
|
+
let cwd;
|
|
3483
|
+
let repository;
|
|
3484
|
+
let gitBranch;
|
|
3485
|
+
let model;
|
|
3486
|
+
let firstUserPreview;
|
|
3487
|
+
let lastUserPreview;
|
|
3488
|
+
let lastAgentPreview;
|
|
3489
|
+
let toolCallCount = 0;
|
|
3490
|
+
let turnCount = 0;
|
|
3491
|
+
let observedOutput = 0;
|
|
3492
|
+
let sawShutdown = false;
|
|
3493
|
+
let linesAdded;
|
|
3494
|
+
let linesRemoved;
|
|
3495
|
+
let filesEdited;
|
|
3496
|
+
let idx = 0;
|
|
3497
|
+
function push(event) {
|
|
3498
|
+
events.push({ index: idx++, ...event });
|
|
3499
|
+
}
|
|
3500
|
+
for (const obj of records) {
|
|
3501
|
+
const type = stringOf(obj.type) ?? "";
|
|
3502
|
+
const data = recordOf(obj.data) ?? {};
|
|
3503
|
+
const timestamp = stringOf(obj.timestamp);
|
|
3504
|
+
if (timestamp) {
|
|
3505
|
+
const ms = Date.parse(timestamp);
|
|
3506
|
+
if (Number.isFinite(ms)) {
|
|
3507
|
+
timestamps.push(ms);
|
|
3508
|
+
firstMs = firstMs === void 0 ? ms : Math.min(firstMs, ms);
|
|
3509
|
+
lastMs = lastMs === void 0 ? ms : Math.max(lastMs, ms);
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3512
|
+
if (type === "session.start") {
|
|
3513
|
+
const context = recordOf(data.context);
|
|
3514
|
+
cwd = stringOf(context?.cwd) ?? cwd;
|
|
3515
|
+
repository = stringOf(context?.repository) ?? repository;
|
|
3516
|
+
gitBranch = stringOf(context?.branch) ?? gitBranch;
|
|
3517
|
+
push({
|
|
3518
|
+
timestamp,
|
|
3519
|
+
role: "meta",
|
|
3520
|
+
rawType: type,
|
|
3521
|
+
preview: "Copilot session started",
|
|
3522
|
+
blocks: [],
|
|
3523
|
+
raw: obj
|
|
3524
|
+
});
|
|
3525
|
+
continue;
|
|
3526
|
+
}
|
|
3527
|
+
if (type === "session.model_change") {
|
|
3528
|
+
const selected = stringOf(data.newModel);
|
|
3529
|
+
if (selected && selected !== "auto")
|
|
3530
|
+
model = selected;
|
|
3531
|
+
} else if (type === "session.auto_mode_resolved") {
|
|
3532
|
+
model = stringOf(data.chosenModel) ?? model;
|
|
3533
|
+
} else if (type === "assistant.turn_start" || type === "assistant.message") {
|
|
3534
|
+
model = stringOf(data.model) ?? model;
|
|
3535
|
+
}
|
|
3536
|
+
if (type === "system.message") {
|
|
3537
|
+
push({
|
|
3538
|
+
timestamp,
|
|
3539
|
+
role: "system",
|
|
3540
|
+
rawType: type,
|
|
3541
|
+
preview: "Copilot system instructions",
|
|
3542
|
+
blocks: [],
|
|
3543
|
+
raw: obj
|
|
3544
|
+
});
|
|
3545
|
+
continue;
|
|
3546
|
+
}
|
|
3547
|
+
if (type === "user.message") {
|
|
3548
|
+
const text = stringOf(data.content) ?? "";
|
|
3549
|
+
const preview = previewOf2(text);
|
|
3550
|
+
if (text && !isFrameworkInjectedUserInput(text)) {
|
|
3551
|
+
firstUserPreview ??= preview;
|
|
3552
|
+
lastUserPreview = preview;
|
|
3553
|
+
turnCount += 1;
|
|
3554
|
+
}
|
|
3555
|
+
push({
|
|
3556
|
+
timestamp,
|
|
3557
|
+
role: "user",
|
|
3558
|
+
rawType: type,
|
|
3559
|
+
preview,
|
|
3560
|
+
blocks: text ? [{ type: "text", text }] : [],
|
|
3561
|
+
raw: obj
|
|
3562
|
+
});
|
|
3563
|
+
continue;
|
|
3564
|
+
}
|
|
3565
|
+
if (type === "assistant.message") {
|
|
3566
|
+
const text = stringOf(data.content) ?? "";
|
|
3567
|
+
const outputTokens = numberOf2(data.outputTokens) ?? 0;
|
|
3568
|
+
observedOutput += outputTokens;
|
|
3569
|
+
if (text) {
|
|
3570
|
+
const preview = previewOf2(text);
|
|
3571
|
+
lastAgentPreview = preview;
|
|
3572
|
+
push({
|
|
3573
|
+
timestamp,
|
|
3574
|
+
role: "agent",
|
|
3575
|
+
rawType: type,
|
|
3576
|
+
messageId: stringOf(data.messageId),
|
|
3577
|
+
preview,
|
|
3578
|
+
blocks: [{ type: "text", text }],
|
|
3579
|
+
model,
|
|
3580
|
+
raw: obj
|
|
3581
|
+
});
|
|
3582
|
+
}
|
|
3583
|
+
const requests = Array.isArray(data.toolRequests) ? data.toolRequests : [];
|
|
3584
|
+
for (const requestValue of requests) {
|
|
3585
|
+
const request = recordOf(requestValue);
|
|
3586
|
+
if (!request)
|
|
3587
|
+
continue;
|
|
3588
|
+
const callId = stringOf(request.toolCallId);
|
|
3589
|
+
if (callId && executionCallIds.has(callId))
|
|
3590
|
+
continue;
|
|
3591
|
+
const name = stringOf(request.name) ?? "(unknown)";
|
|
3592
|
+
const input = recordOf(request.arguments) ?? request.arguments ?? null;
|
|
3593
|
+
toolCallCount += 1;
|
|
3594
|
+
push({
|
|
3595
|
+
timestamp,
|
|
3596
|
+
role: "tool-call",
|
|
3597
|
+
rawType: "assistant.message/tool_request",
|
|
3598
|
+
preview: `${name}(${previewOf2(input).slice(0, 80)})`,
|
|
3599
|
+
blocks: [{ type: "tool_use", id: callId ?? `copilot-${idx}`, name, input }],
|
|
3600
|
+
toolName: name,
|
|
3601
|
+
toolUseId: callId,
|
|
3602
|
+
model,
|
|
3603
|
+
raw: obj
|
|
3604
|
+
});
|
|
3605
|
+
}
|
|
3606
|
+
continue;
|
|
3607
|
+
}
|
|
3608
|
+
if (type === "tool.execution_start") {
|
|
3609
|
+
const callId = stringOf(data.toolCallId);
|
|
3610
|
+
const name = stringOf(data.toolName) ?? "(unknown)";
|
|
3611
|
+
const input = data.arguments ?? null;
|
|
3612
|
+
toolCallCount += 1;
|
|
3613
|
+
push({
|
|
3614
|
+
timestamp,
|
|
3615
|
+
role: "tool-call",
|
|
3616
|
+
rawType: type,
|
|
3617
|
+
preview: `${name}(${previewOf2(input).slice(0, 80)})`,
|
|
3618
|
+
blocks: [{ type: "tool_use", id: callId ?? `copilot-${idx}`, name, input }],
|
|
3619
|
+
toolName: name,
|
|
3620
|
+
toolUseId: callId,
|
|
3621
|
+
model: stringOf(data.model) ?? model,
|
|
3622
|
+
raw: obj
|
|
3623
|
+
});
|
|
3624
|
+
continue;
|
|
3625
|
+
}
|
|
3626
|
+
if (type === "tool.execution_complete") {
|
|
3627
|
+
const callId = stringOf(data.toolCallId);
|
|
3628
|
+
const resultRecord = recordOf(data.result);
|
|
3629
|
+
const result = resultRecord && "content" in resultRecord ? resultRecord.content : data.result;
|
|
3630
|
+
const success = data.success !== false;
|
|
3631
|
+
push({
|
|
3632
|
+
timestamp,
|
|
3633
|
+
role: "tool-result",
|
|
3634
|
+
rawType: type,
|
|
3635
|
+
preview: previewOf2(result),
|
|
3636
|
+
blocks: [{ type: "tool_result", tool_use_id: callId ?? "", content: result, is_error: !success }],
|
|
3637
|
+
toolUseId: callId,
|
|
3638
|
+
toolResult: data.result,
|
|
3639
|
+
raw: obj
|
|
3640
|
+
});
|
|
3641
|
+
continue;
|
|
3642
|
+
}
|
|
3643
|
+
if (type === "assistant.reasoning") {
|
|
3644
|
+
const text = stringOf(data.content) ?? "";
|
|
3645
|
+
push({
|
|
3646
|
+
timestamp,
|
|
3647
|
+
role: "agent-thinking",
|
|
3648
|
+
rawType: type,
|
|
3649
|
+
preview: previewOf2(text),
|
|
3650
|
+
blocks: text ? [{ type: "thinking", thinking: text }] : [],
|
|
3651
|
+
model,
|
|
3652
|
+
raw: obj
|
|
3653
|
+
});
|
|
3654
|
+
continue;
|
|
3655
|
+
}
|
|
3656
|
+
if (type === "session.shutdown") {
|
|
3657
|
+
sawShutdown = true;
|
|
3658
|
+
model = stringOf(data.currentModel) ?? model;
|
|
3659
|
+
const details = recordOf(data.tokenDetails);
|
|
3660
|
+
totalUsage.input = tokenCount(details, "input") ?? totalUsage.input;
|
|
3661
|
+
totalUsage.output = tokenCount(details, "output") ?? observedOutput;
|
|
3662
|
+
totalUsage.cacheRead = tokenCount(details, "cache_read") ?? totalUsage.cacheRead;
|
|
3663
|
+
totalUsage.cacheWrite = tokenCount(details, "cache_write") ?? totalUsage.cacheWrite;
|
|
3664
|
+
const changes = recordOf(data.codeChanges);
|
|
3665
|
+
linesAdded = numberOf2(changes?.linesAdded);
|
|
3666
|
+
linesRemoved = numberOf2(changes?.linesRemoved);
|
|
3667
|
+
const modified = changes?.filesModified;
|
|
3668
|
+
filesEdited = Array.isArray(modified) ? modified.length : void 0;
|
|
3669
|
+
}
|
|
3670
|
+
push({
|
|
3671
|
+
timestamp,
|
|
3672
|
+
role: "meta",
|
|
3673
|
+
rawType: type,
|
|
3674
|
+
preview: "",
|
|
3675
|
+
blocks: [],
|
|
3676
|
+
raw: obj
|
|
3677
|
+
});
|
|
3678
|
+
}
|
|
3679
|
+
if (totalUsage.output === 0)
|
|
3680
|
+
totalUsage.output = observedOutput;
|
|
3681
|
+
if (totalUsage.input || totalUsage.output || totalUsage.cacheRead || totalUsage.cacheWrite) {
|
|
3682
|
+
const usageEvent = [...events].reverse().find((event) => event.role === "agent" || event.role === "agent-thinking" || event.role === "tool-call");
|
|
3683
|
+
if (usageEvent) {
|
|
3684
|
+
usageEvent.messageId = `copilot-${file.sessionId}-total`;
|
|
3685
|
+
usageEvent.usage = { ...totalUsage };
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
const firstTimestamp = firstMs === void 0 ? void 0 : new Date(firstMs).toISOString();
|
|
3689
|
+
const lastTimestamp = lastMs === void 0 ? void 0 : new Date(lastMs).toISOString();
|
|
3690
|
+
if (firstMs !== void 0) {
|
|
3691
|
+
let previousMs;
|
|
3692
|
+
for (const event of events) {
|
|
3693
|
+
if (!event.timestamp)
|
|
3694
|
+
continue;
|
|
3695
|
+
const ms = Date.parse(event.timestamp);
|
|
3696
|
+
if (!Number.isFinite(ms))
|
|
3697
|
+
continue;
|
|
3698
|
+
event.tOffsetMs = Math.max(0, ms - firstMs);
|
|
3699
|
+
if (previousMs !== void 0)
|
|
3700
|
+
event.gapMs = Math.max(0, ms - previousMs);
|
|
3701
|
+
previousMs = ms;
|
|
3702
|
+
}
|
|
3703
|
+
}
|
|
3704
|
+
const activeSegments = computeActiveSegments3(timestamps);
|
|
3705
|
+
const airTimeMs = activeSegments.reduce((sum, segment) => sum + segment.endMs - segment.startMs, 0);
|
|
3706
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3707
|
+
const repoName = project?.repoName ?? repository?.split("/").filter(Boolean).at(-1);
|
|
3708
|
+
const meta = {
|
|
3709
|
+
agent: "copilot",
|
|
3710
|
+
id: file.sessionId,
|
|
3711
|
+
filePath: file.filePath,
|
|
3712
|
+
projectName: project?.projectName ?? cwd ?? "(unknown)",
|
|
3713
|
+
worktreeName: project?.worktreeName,
|
|
3714
|
+
repoName,
|
|
3715
|
+
projectDir: syntheticProjectDir(cwd),
|
|
3716
|
+
sessionId: file.sessionId,
|
|
3717
|
+
firstTimestamp,
|
|
3718
|
+
lastTimestamp,
|
|
3719
|
+
lastActivityMs: file.mtimeMs,
|
|
3720
|
+
durationMs: firstMs !== void 0 && lastMs !== void 0 ? lastMs - firstMs : void 0,
|
|
3721
|
+
eventCount: events.length,
|
|
3722
|
+
model,
|
|
3723
|
+
cwd,
|
|
3724
|
+
gitBranch,
|
|
3725
|
+
totalUsage,
|
|
3726
|
+
status: sawShutdown || Date.now() - file.mtimeMs > IDLE_GAP_MS2 ? "idle" : "running",
|
|
3727
|
+
firstUserPreview,
|
|
3728
|
+
lastUserPreview,
|
|
3729
|
+
lastAgentPreview,
|
|
3730
|
+
toolCallCount,
|
|
3731
|
+
turnCount,
|
|
3732
|
+
linesAdded,
|
|
3733
|
+
linesRemoved,
|
|
3734
|
+
filesEdited,
|
|
3735
|
+
airTimeMs,
|
|
3736
|
+
activeSegments
|
|
3737
|
+
};
|
|
3738
|
+
return { meta, events };
|
|
3739
|
+
}
|
|
3740
|
+
function clearCopilotCaches() {
|
|
3741
|
+
metaCache3.clear();
|
|
3742
|
+
detailCache3.clear();
|
|
3743
|
+
}
|
|
3744
|
+
async function scanCopilot(root) {
|
|
3745
|
+
const files = await listSessionFiles(root);
|
|
3746
|
+
const out = [];
|
|
3747
|
+
for (const file of files) {
|
|
3748
|
+
const cached = metaCache3.get(file.filePath);
|
|
3749
|
+
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3750
|
+
out.push({ file, meta: cached.meta });
|
|
3751
|
+
continue;
|
|
3752
|
+
}
|
|
3753
|
+
try {
|
|
3754
|
+
const lines = await readJsonl2(file.filePath);
|
|
3755
|
+
const { meta } = parseSession(file, lines);
|
|
3756
|
+
metaCache3.set(file.filePath, { meta, mtimeMs: file.mtimeMs, sizeBytes: file.sizeBytes });
|
|
3757
|
+
out.push({ file, meta });
|
|
3758
|
+
} catch {
|
|
3759
|
+
}
|
|
3760
|
+
}
|
|
3761
|
+
return out;
|
|
3762
|
+
}
|
|
3763
|
+
async function listCopilotSessions(opts = {}) {
|
|
3764
|
+
const root = opts.root ?? DEFAULT_COPILOT_ROOT;
|
|
3765
|
+
const sessions = (await scanCopilot(root)).map((entry) => entry.meta);
|
|
3766
|
+
sessions.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
|
|
3767
|
+
return opts.limit === void 0 ? sessions : sessions.slice(0, opts.limit);
|
|
3768
|
+
}
|
|
3769
|
+
async function getCopilotSession(id, opts = {}) {
|
|
3770
|
+
const root = opts.root ?? DEFAULT_COPILOT_ROOT;
|
|
3771
|
+
const entry = (await scanCopilot(root)).find((candidate) => candidate.meta.id === id);
|
|
3772
|
+
if (!entry)
|
|
3773
|
+
return null;
|
|
3774
|
+
const cached = detailCache3.get(entry.file.filePath);
|
|
3775
|
+
if (cached && cached.mtimeMs === entry.file.mtimeMs && cached.sizeBytes === entry.file.sizeBytes) {
|
|
3776
|
+
return cached.detail;
|
|
3777
|
+
}
|
|
3778
|
+
const lines = await readJsonl2(entry.file.filePath);
|
|
3779
|
+
const { meta, events } = parseSession(entry.file, lines);
|
|
3780
|
+
const detail = { ...meta, events };
|
|
3781
|
+
detailCache3.set(entry.file.filePath, {
|
|
3782
|
+
detail,
|
|
3783
|
+
mtimeMs: entry.file.mtimeMs,
|
|
3784
|
+
sizeBytes: entry.file.sizeBytes
|
|
3785
|
+
});
|
|
3786
|
+
return detail;
|
|
3787
|
+
}
|
|
3788
|
+
function copilotSessionLocalDay(meta) {
|
|
3789
|
+
if (!meta.firstTimestamp)
|
|
3790
|
+
return void 0;
|
|
3791
|
+
const ms = Date.parse(meta.firstTimestamp);
|
|
3792
|
+
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
3793
|
+
}
|
|
3794
|
+
var DEFAULT_COPILOT_ROOT, IDLE_GAP_MS2, metaCache3, detailCache3;
|
|
3795
|
+
var init_copilot = __esm({
|
|
3796
|
+
"../parser/dist/copilot.js"() {
|
|
3797
|
+
"use strict";
|
|
3798
|
+
init_analytics();
|
|
3799
|
+
init_git_project();
|
|
3800
|
+
init_user_input();
|
|
3801
|
+
DEFAULT_COPILOT_ROOT = path3.join(os3.homedir(), ".copilot", "session-state");
|
|
3802
|
+
IDLE_GAP_MS2 = 3 * 60 * 1e3;
|
|
3803
|
+
metaCache3 = /* @__PURE__ */ new Map();
|
|
3804
|
+
detailCache3 = /* @__PURE__ */ new Map();
|
|
3805
|
+
}
|
|
3806
|
+
});
|
|
3807
|
+
|
|
3808
|
+
// ../parser/dist/gemini.js
|
|
3809
|
+
import { promises as fs4 } from "node:fs";
|
|
3810
|
+
import os4 from "node:os";
|
|
3811
|
+
import path4 from "node:path";
|
|
3812
|
+
async function safeReaddir2(p) {
|
|
3813
|
+
return fs4.readdir(p).catch(() => []);
|
|
3814
|
+
}
|
|
3815
|
+
async function listSessionFiles2(root) {
|
|
3390
3816
|
const out = [];
|
|
3391
3817
|
const slugs = await safeReaddir2(root);
|
|
3392
3818
|
for (const slug of slugs) {
|
|
3393
|
-
const chatsDir =
|
|
3819
|
+
const chatsDir = path4.join(root, slug, "chats");
|
|
3394
3820
|
const entries2 = await safeReaddir2(chatsDir);
|
|
3395
3821
|
for (const entry of entries2) {
|
|
3396
3822
|
if (!SESSION_FILE_RE.test(entry))
|
|
3397
3823
|
continue;
|
|
3398
|
-
const full =
|
|
3399
|
-
const stat = await
|
|
3824
|
+
const full = path4.join(chatsDir, entry);
|
|
3825
|
+
const stat = await fs4.stat(full).catch(() => null);
|
|
3400
3826
|
if (!stat || !stat.isFile())
|
|
3401
3827
|
continue;
|
|
3402
3828
|
const filenameId = entry.replace(/\.(jsonl|json)$/, "").split("-").pop() ?? entry;
|
|
@@ -3413,13 +3839,13 @@ async function listSessionFiles(root) {
|
|
|
3413
3839
|
return out;
|
|
3414
3840
|
}
|
|
3415
3841
|
async function loadSlugToCwd() {
|
|
3416
|
-
const stat = await
|
|
3842
|
+
const stat = await fs4.stat(GEMINI_PROJECTS_FILE).catch(() => null);
|
|
3417
3843
|
if (!stat)
|
|
3418
3844
|
return /* @__PURE__ */ new Map();
|
|
3419
3845
|
if (projectsCache && projectsCache.mtimeMs === stat.mtimeMs) {
|
|
3420
3846
|
return projectsCache.slugToCwd;
|
|
3421
3847
|
}
|
|
3422
|
-
const raw = await
|
|
3848
|
+
const raw = await fs4.readFile(GEMINI_PROJECTS_FILE, "utf8").catch(() => "");
|
|
3423
3849
|
let parsed;
|
|
3424
3850
|
try {
|
|
3425
3851
|
parsed = JSON.parse(raw);
|
|
@@ -3444,7 +3870,7 @@ function isMessageRecord(o) {
|
|
|
3444
3870
|
return !!o && typeof o === "object" && typeof o.id === "string" && typeof o.type === "string";
|
|
3445
3871
|
}
|
|
3446
3872
|
async function readAndReplay(file) {
|
|
3447
|
-
const raw = await
|
|
3873
|
+
const raw = await fs4.readFile(file.filePath, "utf8");
|
|
3448
3874
|
if (file.format === "legacy-json") {
|
|
3449
3875
|
let blob;
|
|
3450
3876
|
try {
|
|
@@ -3519,10 +3945,10 @@ async function readAndReplay(file) {
|
|
|
3519
3945
|
}
|
|
3520
3946
|
return { meta, messages };
|
|
3521
3947
|
}
|
|
3522
|
-
function
|
|
3948
|
+
function emptyUsage3() {
|
|
3523
3949
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3524
3950
|
}
|
|
3525
|
-
function
|
|
3951
|
+
function previewOf3(text) {
|
|
3526
3952
|
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3527
3953
|
}
|
|
3528
3954
|
function flattenContent(c) {
|
|
@@ -3561,12 +3987,12 @@ function flattenContent(c) {
|
|
|
3561
3987
|
function truncate3(s, n) {
|
|
3562
3988
|
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
3563
3989
|
}
|
|
3564
|
-
async function
|
|
3990
|
+
async function parseSession2(file) {
|
|
3565
3991
|
const { meta: metaRec, messages } = await readAndReplay(file);
|
|
3566
3992
|
const slugToCwd = await loadSlugToCwd();
|
|
3567
3993
|
const cwd = slugToCwd.get(file.slug);
|
|
3568
3994
|
const events = [];
|
|
3569
|
-
const totalUsage =
|
|
3995
|
+
const totalUsage = emptyUsage3();
|
|
3570
3996
|
let firstTimestamp;
|
|
3571
3997
|
let lastTimestamp;
|
|
3572
3998
|
let model;
|
|
@@ -3592,7 +4018,7 @@ async function parseSession(file) {
|
|
|
3592
4018
|
const ts = msg.timestamp;
|
|
3593
4019
|
if (msg.type === "user") {
|
|
3594
4020
|
const text = flattenContent(msg.displayContent ?? msg.content);
|
|
3595
|
-
const preview =
|
|
4021
|
+
const preview = previewOf3(text);
|
|
3596
4022
|
const isHidden = isFrameworkInjectedUserInput(text);
|
|
3597
4023
|
if (text && !isHidden) {
|
|
3598
4024
|
if (!firstUserPreview)
|
|
@@ -3616,7 +4042,7 @@ async function parseSession(file) {
|
|
|
3616
4042
|
if (typeof msg.model === "string")
|
|
3617
4043
|
model = msg.model;
|
|
3618
4044
|
const text = flattenContent(msg.content);
|
|
3619
|
-
const preview =
|
|
4045
|
+
const preview = previewOf3(text);
|
|
3620
4046
|
if (text)
|
|
3621
4047
|
lastAgentPreview = preview;
|
|
3622
4048
|
let usage2;
|
|
@@ -3642,7 +4068,7 @@ async function parseSession(file) {
|
|
|
3642
4068
|
timestamp: th.timestamp ?? ts,
|
|
3643
4069
|
role: "agent-thinking",
|
|
3644
4070
|
rawType: "gemini/thought",
|
|
3645
|
-
preview:
|
|
4071
|
+
preview: previewOf3(thText),
|
|
3646
4072
|
blocks: [{ type: "thinking", thinking: thText }],
|
|
3647
4073
|
model,
|
|
3648
4074
|
raw: th
|
|
@@ -3699,7 +4125,7 @@ async function parseSession(file) {
|
|
|
3699
4125
|
timestamp: tc.timestamp ?? ts,
|
|
3700
4126
|
role: "tool-result",
|
|
3701
4127
|
rawType: "gemini/tool_result",
|
|
3702
|
-
preview:
|
|
4128
|
+
preview: previewOf3(resultText),
|
|
3703
4129
|
blocks: [
|
|
3704
4130
|
{
|
|
3705
4131
|
type: "tool_result",
|
|
@@ -3723,7 +4149,7 @@ async function parseSession(file) {
|
|
|
3723
4149
|
timestamp: ts,
|
|
3724
4150
|
role: "meta",
|
|
3725
4151
|
rawType: `gemini/${msg.type}`,
|
|
3726
|
-
preview:
|
|
4152
|
+
preview: previewOf3(text),
|
|
3727
4153
|
blocks: text ? [{ type: "text", text }] : [],
|
|
3728
4154
|
raw: msg
|
|
3729
4155
|
});
|
|
@@ -3745,7 +4171,7 @@ async function parseSession(file) {
|
|
|
3745
4171
|
prevMs = ms;
|
|
3746
4172
|
}
|
|
3747
4173
|
}
|
|
3748
|
-
const activeSegments =
|
|
4174
|
+
const activeSegments = computeActiveSegments4(tsMs);
|
|
3749
4175
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
3750
4176
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3751
4177
|
const sessionId = metaRec.sessionId ?? file.filenameId;
|
|
@@ -3779,7 +4205,7 @@ async function parseSession(file) {
|
|
|
3779
4205
|
};
|
|
3780
4206
|
return { meta, events };
|
|
3781
4207
|
}
|
|
3782
|
-
function
|
|
4208
|
+
function computeActiveSegments4(tsMs) {
|
|
3783
4209
|
if (tsMs.length === 0)
|
|
3784
4210
|
return [];
|
|
3785
4211
|
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
@@ -3787,7 +4213,7 @@ function computeActiveSegments3(tsMs) {
|
|
|
3787
4213
|
let segStart = sorted[0];
|
|
3788
4214
|
let segEnd = sorted[0];
|
|
3789
4215
|
for (let i = 1; i < sorted.length; i++) {
|
|
3790
|
-
if (sorted[i] - segEnd >
|
|
4216
|
+
if (sorted[i] - segEnd > IDLE_GAP_MS3) {
|
|
3791
4217
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
3792
4218
|
segStart = sorted[i];
|
|
3793
4219
|
}
|
|
@@ -3797,23 +4223,23 @@ function computeActiveSegments3(tsMs) {
|
|
|
3797
4223
|
return out;
|
|
3798
4224
|
}
|
|
3799
4225
|
function clearGeminiCaches() {
|
|
3800
|
-
|
|
3801
|
-
|
|
4226
|
+
metaCache4.clear();
|
|
4227
|
+
detailCache4.clear();
|
|
3802
4228
|
projectsCache = null;
|
|
3803
4229
|
}
|
|
3804
4230
|
async function listGeminiSessions(opts = {}) {
|
|
3805
4231
|
const root = opts.root ?? DEFAULT_GEMINI_ROOT;
|
|
3806
|
-
const files = await
|
|
4232
|
+
const files = await listSessionFiles2(root);
|
|
3807
4233
|
const out = [];
|
|
3808
4234
|
for (const file of files) {
|
|
3809
|
-
const cached =
|
|
4235
|
+
const cached = metaCache4.get(file.filePath);
|
|
3810
4236
|
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3811
4237
|
out.push(cached.meta);
|
|
3812
4238
|
continue;
|
|
3813
4239
|
}
|
|
3814
4240
|
try {
|
|
3815
|
-
const { meta } = await
|
|
3816
|
-
|
|
4241
|
+
const { meta } = await parseSession2(file);
|
|
4242
|
+
metaCache4.set(file.filePath, {
|
|
3817
4243
|
meta,
|
|
3818
4244
|
mtimeMs: file.mtimeMs,
|
|
3819
4245
|
sizeBytes: file.sizeBytes
|
|
@@ -3829,7 +4255,7 @@ async function listGeminiSessions(opts = {}) {
|
|
|
3829
4255
|
}
|
|
3830
4256
|
async function getGeminiSession(id, opts = {}) {
|
|
3831
4257
|
const root = opts.root ?? DEFAULT_GEMINI_ROOT;
|
|
3832
|
-
const files = await
|
|
4258
|
+
const files = await listSessionFiles2(root);
|
|
3833
4259
|
let chosen;
|
|
3834
4260
|
for (const file of files) {
|
|
3835
4261
|
if (file.filenameId === id || id.startsWith(file.filenameId)) {
|
|
@@ -3839,7 +4265,7 @@ async function getGeminiSession(id, opts = {}) {
|
|
|
3839
4265
|
}
|
|
3840
4266
|
if (!chosen) {
|
|
3841
4267
|
for (const file of files) {
|
|
3842
|
-
const { meta: meta2 } = await
|
|
4268
|
+
const { meta: meta2 } = await parseSession2(file).catch(() => ({ meta: { id: "" } }));
|
|
3843
4269
|
if (meta2.id === id) {
|
|
3844
4270
|
chosen = file;
|
|
3845
4271
|
break;
|
|
@@ -3848,13 +4274,13 @@ async function getGeminiSession(id, opts = {}) {
|
|
|
3848
4274
|
}
|
|
3849
4275
|
if (!chosen)
|
|
3850
4276
|
return null;
|
|
3851
|
-
const cached =
|
|
4277
|
+
const cached = detailCache4.get(chosen.filePath);
|
|
3852
4278
|
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
|
|
3853
4279
|
return cached.detail;
|
|
3854
4280
|
}
|
|
3855
|
-
const { meta, events } = await
|
|
4281
|
+
const { meta, events } = await parseSession2(chosen);
|
|
3856
4282
|
const detail = { ...meta, events };
|
|
3857
|
-
|
|
4283
|
+
detailCache4.set(chosen.filePath, {
|
|
3858
4284
|
detail,
|
|
3859
4285
|
mtimeMs: chosen.mtimeMs,
|
|
3860
4286
|
sizeBytes: chosen.sizeBytes
|
|
@@ -3867,39 +4293,39 @@ function geminiSessionLocalDay(meta) {
|
|
|
3867
4293
|
const ms = Date.parse(meta.firstTimestamp);
|
|
3868
4294
|
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
3869
4295
|
}
|
|
3870
|
-
var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE,
|
|
4296
|
+
var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE, IDLE_GAP_MS3, projectsCache, metaCache4, detailCache4;
|
|
3871
4297
|
var init_gemini = __esm({
|
|
3872
4298
|
"../parser/dist/gemini.js"() {
|
|
3873
4299
|
"use strict";
|
|
3874
4300
|
init_analytics();
|
|
3875
4301
|
init_git_project();
|
|
3876
4302
|
init_user_input();
|
|
3877
|
-
DEFAULT_GEMINI_ROOT =
|
|
3878
|
-
GEMINI_PROJECTS_FILE =
|
|
4303
|
+
DEFAULT_GEMINI_ROOT = path4.join(os4.homedir(), ".gemini", "tmp");
|
|
4304
|
+
GEMINI_PROJECTS_FILE = path4.join(os4.homedir(), ".gemini", "projects.json");
|
|
3879
4305
|
SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
|
|
3880
|
-
|
|
4306
|
+
IDLE_GAP_MS3 = 3 * 60 * 1e3;
|
|
3881
4307
|
projectsCache = null;
|
|
3882
|
-
|
|
3883
|
-
|
|
4308
|
+
metaCache4 = /* @__PURE__ */ new Map();
|
|
4309
|
+
detailCache4 = /* @__PURE__ */ new Map();
|
|
3884
4310
|
}
|
|
3885
4311
|
});
|
|
3886
4312
|
|
|
3887
4313
|
// ../parser/dist/antigravity.js
|
|
3888
|
-
import { promises as
|
|
3889
|
-
import
|
|
3890
|
-
import
|
|
4314
|
+
import { promises as fs5 } from "node:fs";
|
|
4315
|
+
import os5 from "node:os";
|
|
4316
|
+
import path5 from "node:path";
|
|
3891
4317
|
async function safeReaddir3(p) {
|
|
3892
|
-
return
|
|
4318
|
+
return fs5.readdir(p).catch(() => []);
|
|
3893
4319
|
}
|
|
3894
4320
|
async function loadSlugToCwd2(root) {
|
|
3895
|
-
const historyFile =
|
|
3896
|
-
const stat = await
|
|
4321
|
+
const historyFile = path5.join(root, "history.jsonl");
|
|
4322
|
+
const stat = await fs5.stat(historyFile).catch(() => null);
|
|
3897
4323
|
if (!stat)
|
|
3898
4324
|
return /* @__PURE__ */ new Map();
|
|
3899
4325
|
if (historyCache && historyCache.mtimeMs === stat.mtimeMs) {
|
|
3900
4326
|
return historyCache.slugToCwd;
|
|
3901
4327
|
}
|
|
3902
|
-
const raw = await
|
|
4328
|
+
const raw = await fs5.readFile(historyFile, "utf8").catch(() => "");
|
|
3903
4329
|
const slugToCwd = /* @__PURE__ */ new Map();
|
|
3904
4330
|
for (const line of raw.split("\n")) {
|
|
3905
4331
|
const trimmed = line.trim();
|
|
@@ -3916,14 +4342,14 @@ async function loadSlugToCwd2(root) {
|
|
|
3916
4342
|
historyCache = { mtimeMs: stat.mtimeMs, slugToCwd };
|
|
3917
4343
|
return slugToCwd;
|
|
3918
4344
|
}
|
|
3919
|
-
async function
|
|
4345
|
+
async function listSessionFiles3(root) {
|
|
3920
4346
|
const slugToCwd = await loadSlugToCwd2(root);
|
|
3921
4347
|
const out = [];
|
|
3922
|
-
const brainDir =
|
|
4348
|
+
const brainDir = path5.join(root, "brain");
|
|
3923
4349
|
const entries2 = await safeReaddir3(brainDir);
|
|
3924
4350
|
for (const entry of entries2) {
|
|
3925
|
-
const transcriptPath =
|
|
3926
|
-
const stat = await
|
|
4351
|
+
const transcriptPath = path5.join(brainDir, entry, ".system_generated", "logs", "transcript.jsonl");
|
|
4352
|
+
const stat = await fs5.stat(transcriptPath).catch(() => null);
|
|
3927
4353
|
if (stat && stat.isFile()) {
|
|
3928
4354
|
out.push({
|
|
3929
4355
|
filePath: transcriptPath,
|
|
@@ -3936,19 +4362,19 @@ async function listSessionFiles2(root) {
|
|
|
3936
4362
|
}
|
|
3937
4363
|
return out;
|
|
3938
4364
|
}
|
|
3939
|
-
function
|
|
4365
|
+
function emptyUsage4() {
|
|
3940
4366
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3941
4367
|
}
|
|
3942
|
-
function
|
|
4368
|
+
function previewOf4(text) {
|
|
3943
4369
|
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3944
4370
|
}
|
|
3945
4371
|
function truncate4(s, n) {
|
|
3946
4372
|
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
3947
4373
|
}
|
|
3948
|
-
async function
|
|
3949
|
-
const raw = await
|
|
4374
|
+
async function parseSession3(file) {
|
|
4375
|
+
const raw = await fs5.readFile(file.filePath, "utf8");
|
|
3950
4376
|
const events = [];
|
|
3951
|
-
const totalUsage =
|
|
4377
|
+
const totalUsage = emptyUsage4();
|
|
3952
4378
|
let firstTimestamp;
|
|
3953
4379
|
let lastTimestamp;
|
|
3954
4380
|
let model;
|
|
@@ -4020,7 +4446,7 @@ async function parseSession2(file) {
|
|
|
4020
4446
|
if (requestMatch) {
|
|
4021
4447
|
text2 = requestMatch[1].trim();
|
|
4022
4448
|
}
|
|
4023
|
-
const preview =
|
|
4449
|
+
const preview = previewOf4(text2);
|
|
4024
4450
|
const isHidden = isFrameworkInjectedUserInput(text2);
|
|
4025
4451
|
if (text2 && !isHidden) {
|
|
4026
4452
|
if (!firstUserPreview)
|
|
@@ -4049,14 +4475,14 @@ async function parseSession2(file) {
|
|
|
4049
4475
|
timestamp: ts,
|
|
4050
4476
|
role: "agent-thinking",
|
|
4051
4477
|
rawType: "antigravity/thought",
|
|
4052
|
-
preview:
|
|
4478
|
+
preview: previewOf4(thinking),
|
|
4053
4479
|
blocks: [{ type: "thinking", thinking }],
|
|
4054
4480
|
model,
|
|
4055
4481
|
raw: eventObj
|
|
4056
4482
|
});
|
|
4057
4483
|
}
|
|
4058
4484
|
if (content) {
|
|
4059
|
-
const preview =
|
|
4485
|
+
const preview = previewOf4(content);
|
|
4060
4486
|
lastAgentPreview = preview;
|
|
4061
4487
|
pushEvent({
|
|
4062
4488
|
index: idx++,
|
|
@@ -4102,7 +4528,7 @@ async function parseSession2(file) {
|
|
|
4102
4528
|
timestamp: ts,
|
|
4103
4529
|
role: "tool-result",
|
|
4104
4530
|
rawType: "antigravity/tool_result",
|
|
4105
|
-
preview:
|
|
4531
|
+
preview: previewOf4(contentStr),
|
|
4106
4532
|
blocks: [{
|
|
4107
4533
|
type: "tool_result",
|
|
4108
4534
|
tool_use_id: toolUseId,
|
|
@@ -4121,7 +4547,7 @@ async function parseSession2(file) {
|
|
|
4121
4547
|
timestamp: ts,
|
|
4122
4548
|
role: "meta",
|
|
4123
4549
|
rawType: `antigravity/${eventObj.type?.toLowerCase() || "unknown"}`,
|
|
4124
|
-
preview:
|
|
4550
|
+
preview: previewOf4(text),
|
|
4125
4551
|
blocks: text ? [{ type: "text", text }] : [],
|
|
4126
4552
|
raw: eventObj
|
|
4127
4553
|
});
|
|
@@ -4141,7 +4567,7 @@ async function parseSession2(file) {
|
|
|
4141
4567
|
prevMs = ms;
|
|
4142
4568
|
}
|
|
4143
4569
|
}
|
|
4144
|
-
const activeSegments =
|
|
4570
|
+
const activeSegments = computeActiveSegments5(tsMs);
|
|
4145
4571
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
4146
4572
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
4147
4573
|
const sessionId = file.conversationId;
|
|
@@ -4176,7 +4602,7 @@ async function parseSession2(file) {
|
|
|
4176
4602
|
};
|
|
4177
4603
|
return { meta, events };
|
|
4178
4604
|
}
|
|
4179
|
-
function
|
|
4605
|
+
function computeActiveSegments5(tsMs) {
|
|
4180
4606
|
if (tsMs.length === 0)
|
|
4181
4607
|
return [];
|
|
4182
4608
|
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
@@ -4184,7 +4610,7 @@ function computeActiveSegments4(tsMs) {
|
|
|
4184
4610
|
let segStart = sorted[0];
|
|
4185
4611
|
let segEnd = sorted[0];
|
|
4186
4612
|
for (let i = 1; i < sorted.length; i++) {
|
|
4187
|
-
if (sorted[i] - segEnd >
|
|
4613
|
+
if (sorted[i] - segEnd > IDLE_GAP_MS4) {
|
|
4188
4614
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
4189
4615
|
segStart = sorted[i];
|
|
4190
4616
|
}
|
|
@@ -4194,23 +4620,23 @@ function computeActiveSegments4(tsMs) {
|
|
|
4194
4620
|
return out;
|
|
4195
4621
|
}
|
|
4196
4622
|
function clearAntigravityCaches() {
|
|
4197
|
-
|
|
4198
|
-
|
|
4623
|
+
metaCache5.clear();
|
|
4624
|
+
detailCache5.clear();
|
|
4199
4625
|
historyCache = null;
|
|
4200
4626
|
}
|
|
4201
4627
|
async function listAntigravitySessions(opts = {}) {
|
|
4202
4628
|
const root = opts.root ?? DEFAULT_ANTIGRAVITY_ROOT;
|
|
4203
|
-
const files = await
|
|
4629
|
+
const files = await listSessionFiles3(root);
|
|
4204
4630
|
const out = [];
|
|
4205
4631
|
for (const file of files) {
|
|
4206
|
-
const cached =
|
|
4632
|
+
const cached = metaCache5.get(file.filePath);
|
|
4207
4633
|
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes && cached.cwd === file.cwd) {
|
|
4208
4634
|
out.push(cached.meta);
|
|
4209
4635
|
continue;
|
|
4210
4636
|
}
|
|
4211
4637
|
try {
|
|
4212
|
-
const { meta } = await
|
|
4213
|
-
|
|
4638
|
+
const { meta } = await parseSession3(file);
|
|
4639
|
+
metaCache5.set(file.filePath, {
|
|
4214
4640
|
meta,
|
|
4215
4641
|
mtimeMs: file.mtimeMs,
|
|
4216
4642
|
sizeBytes: file.sizeBytes,
|
|
@@ -4227,7 +4653,7 @@ async function listAntigravitySessions(opts = {}) {
|
|
|
4227
4653
|
}
|
|
4228
4654
|
async function getAntigravitySession(id, opts = {}) {
|
|
4229
4655
|
const root = opts.root ?? DEFAULT_ANTIGRAVITY_ROOT;
|
|
4230
|
-
const files = await
|
|
4656
|
+
const files = await listSessionFiles3(root);
|
|
4231
4657
|
let chosen;
|
|
4232
4658
|
for (const file of files) {
|
|
4233
4659
|
if (file.conversationId === id) {
|
|
@@ -4237,13 +4663,13 @@ async function getAntigravitySession(id, opts = {}) {
|
|
|
4237
4663
|
}
|
|
4238
4664
|
if (!chosen)
|
|
4239
4665
|
return null;
|
|
4240
|
-
const cached =
|
|
4666
|
+
const cached = detailCache5.get(chosen.filePath);
|
|
4241
4667
|
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes && cached.cwd === chosen.cwd) {
|
|
4242
4668
|
return cached.detail;
|
|
4243
4669
|
}
|
|
4244
|
-
const { meta, events } = await
|
|
4670
|
+
const { meta, events } = await parseSession3(chosen);
|
|
4245
4671
|
const detail = { ...meta, events };
|
|
4246
|
-
|
|
4672
|
+
detailCache5.set(chosen.filePath, {
|
|
4247
4673
|
detail,
|
|
4248
4674
|
mtimeMs: chosen.mtimeMs,
|
|
4249
4675
|
sizeBytes: chosen.sizeBytes,
|
|
@@ -4257,61 +4683,61 @@ function antigravitySessionLocalDay(meta) {
|
|
|
4257
4683
|
const ms = Date.parse(meta.firstTimestamp);
|
|
4258
4684
|
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
4259
4685
|
}
|
|
4260
|
-
var DEFAULT_ANTIGRAVITY_ROOT,
|
|
4686
|
+
var DEFAULT_ANTIGRAVITY_ROOT, IDLE_GAP_MS4, historyCache, metaCache5, detailCache5;
|
|
4261
4687
|
var init_antigravity = __esm({
|
|
4262
4688
|
"../parser/dist/antigravity.js"() {
|
|
4263
4689
|
"use strict";
|
|
4264
4690
|
init_analytics();
|
|
4265
4691
|
init_git_project();
|
|
4266
4692
|
init_user_input();
|
|
4267
|
-
DEFAULT_ANTIGRAVITY_ROOT =
|
|
4268
|
-
|
|
4693
|
+
DEFAULT_ANTIGRAVITY_ROOT = path5.join(os5.homedir(), ".gemini", "antigravity-cli");
|
|
4694
|
+
IDLE_GAP_MS4 = 3 * 60 * 1e3;
|
|
4269
4695
|
historyCache = null;
|
|
4270
|
-
|
|
4271
|
-
|
|
4696
|
+
metaCache5 = /* @__PURE__ */ new Map();
|
|
4697
|
+
detailCache5 = /* @__PURE__ */ new Map();
|
|
4272
4698
|
}
|
|
4273
4699
|
});
|
|
4274
4700
|
|
|
4275
4701
|
// ../parser/dist/cowork.js
|
|
4276
|
-
import { promises as
|
|
4277
|
-
import
|
|
4278
|
-
import
|
|
4702
|
+
import { promises as fs6 } from "node:fs";
|
|
4703
|
+
import os6 from "node:os";
|
|
4704
|
+
import path6 from "node:path";
|
|
4279
4705
|
function defaultCoworkRoot() {
|
|
4280
|
-
const home =
|
|
4706
|
+
const home = os6.homedir();
|
|
4281
4707
|
if (process.platform === "darwin") {
|
|
4282
|
-
return
|
|
4708
|
+
return path6.join(home, "Library", "Application Support", "Claude", "local-agent-mode-sessions");
|
|
4283
4709
|
}
|
|
4284
4710
|
if (process.platform === "win32") {
|
|
4285
|
-
const appData = process.env.APPDATA ??
|
|
4286
|
-
return
|
|
4711
|
+
const appData = process.env.APPDATA ?? path6.join(home, "AppData", "Roaming");
|
|
4712
|
+
return path6.join(appData, "Claude", "local-agent-mode-sessions");
|
|
4287
4713
|
}
|
|
4288
|
-
return
|
|
4714
|
+
return path6.join(home, ".config", "Claude", "local-agent-mode-sessions");
|
|
4289
4715
|
}
|
|
4290
4716
|
async function safeReaddir4(p) {
|
|
4291
|
-
return
|
|
4717
|
+
return fs6.readdir(p).catch(() => []);
|
|
4292
4718
|
}
|
|
4293
4719
|
async function statMs(p) {
|
|
4294
|
-
const s = await
|
|
4720
|
+
const s = await fs6.stat(p).catch(() => null);
|
|
4295
4721
|
return s ? s.mtimeMs : 0;
|
|
4296
4722
|
}
|
|
4297
|
-
async function
|
|
4723
|
+
async function listSessionFiles4(root) {
|
|
4298
4724
|
const out = [];
|
|
4299
4725
|
const accounts = await safeReaddir4(root);
|
|
4300
4726
|
for (const accountId of accounts) {
|
|
4301
|
-
const accountDir =
|
|
4727
|
+
const accountDir = path6.join(root, accountId);
|
|
4302
4728
|
const workspaces = await safeReaddir4(accountDir);
|
|
4303
4729
|
for (const workspaceId of workspaces) {
|
|
4304
|
-
const workspaceDir =
|
|
4305
|
-
const spacesMtimeMs = await statMs(
|
|
4730
|
+
const workspaceDir = path6.join(accountDir, workspaceId);
|
|
4731
|
+
const spacesMtimeMs = await statMs(path6.join(workspaceDir, "spaces.json"));
|
|
4306
4732
|
const entries2 = await safeReaddir4(workspaceDir);
|
|
4307
4733
|
for (const entry of entries2) {
|
|
4308
4734
|
if (!SESSION_ID_RE.test(entry))
|
|
4309
4735
|
continue;
|
|
4310
|
-
const auditPath =
|
|
4311
|
-
const auditStat = await
|
|
4736
|
+
const auditPath = path6.join(workspaceDir, entry, "audit.jsonl");
|
|
4737
|
+
const auditStat = await fs6.stat(auditPath).catch(() => null);
|
|
4312
4738
|
if (!auditStat || !auditStat.isFile() || auditStat.size === 0)
|
|
4313
4739
|
continue;
|
|
4314
|
-
const metaPath =
|
|
4740
|
+
const metaPath = path6.join(workspaceDir, `${entry}.json`);
|
|
4315
4741
|
const metaMtimeMs = await statMs(metaPath);
|
|
4316
4742
|
out.push({
|
|
4317
4743
|
sessionId: entry,
|
|
@@ -4329,14 +4755,14 @@ async function listSessionFiles3(root) {
|
|
|
4329
4755
|
return out;
|
|
4330
4756
|
}
|
|
4331
4757
|
async function loadSpacesForWorkspace(workspaceDir) {
|
|
4332
|
-
const spacesPath =
|
|
4333
|
-
const stat = await
|
|
4758
|
+
const spacesPath = path6.join(workspaceDir, "spaces.json");
|
|
4759
|
+
const stat = await fs6.stat(spacesPath).catch(() => null);
|
|
4334
4760
|
if (!stat)
|
|
4335
4761
|
return /* @__PURE__ */ new Map();
|
|
4336
4762
|
const cached = spacesCache.get(workspaceDir);
|
|
4337
4763
|
if (cached && cached.mtimeMs === stat.mtimeMs)
|
|
4338
4764
|
return cached.spaceIdToPath;
|
|
4339
|
-
const raw = await
|
|
4765
|
+
const raw = await fs6.readFile(spacesPath, "utf8").catch(() => "");
|
|
4340
4766
|
const out = /* @__PURE__ */ new Map();
|
|
4341
4767
|
try {
|
|
4342
4768
|
const parsed = JSON.parse(raw);
|
|
@@ -4354,7 +4780,7 @@ async function loadSpacesForWorkspace(workspaceDir) {
|
|
|
4354
4780
|
return out;
|
|
4355
4781
|
}
|
|
4356
4782
|
async function readCoworkMeta(metaPath) {
|
|
4357
|
-
const raw = await
|
|
4783
|
+
const raw = await fs6.readFile(metaPath, "utf8").catch(() => "");
|
|
4358
4784
|
if (!raw)
|
|
4359
4785
|
return {};
|
|
4360
4786
|
try {
|
|
@@ -4390,8 +4816,8 @@ function resolveProject(meta, spaceIdToPath) {
|
|
|
4390
4816
|
cwd: projectPath
|
|
4391
4817
|
};
|
|
4392
4818
|
}
|
|
4393
|
-
async function
|
|
4394
|
-
const raw = await
|
|
4819
|
+
async function readJsonl3(filePath) {
|
|
4820
|
+
const raw = await fs6.readFile(filePath, "utf8");
|
|
4395
4821
|
const out = [];
|
|
4396
4822
|
for (const line of raw.split("\n")) {
|
|
4397
4823
|
const trimmed = line.trim();
|
|
@@ -4527,7 +4953,7 @@ function buildCoworkSubagents(subagentGroups, allLines, sessionStartMs) {
|
|
|
4527
4953
|
}
|
|
4528
4954
|
async function parseCoworkSession(file) {
|
|
4529
4955
|
const [lines, coworkMeta, spaceIdToPath] = await Promise.all([
|
|
4530
|
-
|
|
4956
|
+
readJsonl3(file.auditPath),
|
|
4531
4957
|
readCoworkMeta(file.metaPath),
|
|
4532
4958
|
loadSpacesForWorkspace(file.workspaceDir)
|
|
4533
4959
|
]);
|
|
@@ -4562,24 +4988,24 @@ function cacheKeyMatches(a, b) {
|
|
|
4562
4988
|
return a.auditMtimeMs === b.auditMtimeMs && a.auditSize === b.auditSize && a.metaMtimeMs === b.metaMtimeMs && a.spacesMtimeMs === b.spacesMtimeMs;
|
|
4563
4989
|
}
|
|
4564
4990
|
function clearCoworkCaches() {
|
|
4565
|
-
|
|
4566
|
-
|
|
4991
|
+
metaCache6.clear();
|
|
4992
|
+
detailCache6.clear();
|
|
4567
4993
|
spacesCache.clear();
|
|
4568
4994
|
}
|
|
4569
4995
|
async function listCoworkSessions(opts = {}) {
|
|
4570
4996
|
const root = opts.root ?? DEFAULT_COWORK_ROOT;
|
|
4571
|
-
const files = await
|
|
4997
|
+
const files = await listSessionFiles4(root);
|
|
4572
4998
|
const out = [];
|
|
4573
4999
|
for (const file of files) {
|
|
4574
5000
|
const key = cacheKeyFor(file);
|
|
4575
|
-
const cached =
|
|
5001
|
+
const cached = metaCache6.get(file.auditPath);
|
|
4576
5002
|
if (cached && cacheKeyMatches(cached.key, key)) {
|
|
4577
5003
|
out.push(cached.meta);
|
|
4578
5004
|
continue;
|
|
4579
5005
|
}
|
|
4580
5006
|
try {
|
|
4581
5007
|
const { meta } = await parseCoworkSession(file);
|
|
4582
|
-
|
|
5008
|
+
metaCache6.set(file.auditPath, { meta, key });
|
|
4583
5009
|
out.push(meta);
|
|
4584
5010
|
} catch {
|
|
4585
5011
|
}
|
|
@@ -4591,12 +5017,12 @@ async function listCoworkSessions(opts = {}) {
|
|
|
4591
5017
|
}
|
|
4592
5018
|
async function getCoworkSession(id, opts = {}) {
|
|
4593
5019
|
const root = opts.root ?? DEFAULT_COWORK_ROOT;
|
|
4594
|
-
const files = await
|
|
5020
|
+
const files = await listSessionFiles4(root);
|
|
4595
5021
|
const file = files.find((f) => f.sessionId === id);
|
|
4596
5022
|
if (!file)
|
|
4597
5023
|
return null;
|
|
4598
5024
|
const key = cacheKeyFor(file);
|
|
4599
|
-
const cached =
|
|
5025
|
+
const cached = detailCache6.get(file.auditPath);
|
|
4600
5026
|
if (cached && cacheKeyMatches(cached.key, key))
|
|
4601
5027
|
return cached.detail;
|
|
4602
5028
|
const { meta, events, subagents } = await parseCoworkSession(file);
|
|
@@ -4605,10 +5031,10 @@ async function getCoworkSession(id, opts = {}) {
|
|
|
4605
5031
|
events,
|
|
4606
5032
|
...subagents.length ? { subagents } : {}
|
|
4607
5033
|
};
|
|
4608
|
-
|
|
5034
|
+
detailCache6.set(file.auditPath, { detail, key });
|
|
4609
5035
|
return detail;
|
|
4610
5036
|
}
|
|
4611
|
-
var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache,
|
|
5037
|
+
var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache, metaCache6, detailCache6;
|
|
4612
5038
|
var init_cowork = __esm({
|
|
4613
5039
|
"../parser/dist/cowork.js"() {
|
|
4614
5040
|
"use strict";
|
|
@@ -4618,24 +5044,24 @@ var init_cowork = __esm({
|
|
|
4618
5044
|
DEFAULT_COWORK_ROOT = defaultCoworkRoot();
|
|
4619
5045
|
SESSION_ID_RE = /^local_[0-9a-f-]+$/;
|
|
4620
5046
|
spacesCache = /* @__PURE__ */ new Map();
|
|
4621
|
-
|
|
4622
|
-
|
|
5047
|
+
metaCache6 = /* @__PURE__ */ new Map();
|
|
5048
|
+
detailCache6 = /* @__PURE__ */ new Map();
|
|
4623
5049
|
}
|
|
4624
5050
|
});
|
|
4625
5051
|
|
|
4626
5052
|
// ../parser/dist/grok.js
|
|
4627
|
-
import { promises as
|
|
4628
|
-
import
|
|
4629
|
-
import
|
|
5053
|
+
import { promises as fs7 } from "node:fs";
|
|
5054
|
+
import os7 from "node:os";
|
|
5055
|
+
import path7 from "node:path";
|
|
4630
5056
|
function resolveDefaultGrokRoot() {
|
|
4631
|
-
const home = process.env.GROK_HOME ||
|
|
4632
|
-
return
|
|
5057
|
+
const home = process.env.GROK_HOME || path7.join(os7.homedir(), ".grok");
|
|
5058
|
+
return path7.join(home, "sessions");
|
|
4633
5059
|
}
|
|
4634
5060
|
async function safeReaddir5(p) {
|
|
4635
|
-
return
|
|
5061
|
+
return fs7.readdir(p).catch(() => []);
|
|
4636
5062
|
}
|
|
4637
5063
|
async function safeReadJson(p) {
|
|
4638
|
-
const raw = await
|
|
5064
|
+
const raw = await fs7.readFile(p, "utf8").catch(() => null);
|
|
4639
5065
|
if (raw == null)
|
|
4640
5066
|
return null;
|
|
4641
5067
|
try {
|
|
@@ -4645,8 +5071,8 @@ async function safeReadJson(p) {
|
|
|
4645
5071
|
}
|
|
4646
5072
|
}
|
|
4647
5073
|
async function resolveEncodedCwd(groupDir, encoded) {
|
|
4648
|
-
const cwdFile =
|
|
4649
|
-
const fromFile = await
|
|
5074
|
+
const cwdFile = path7.join(groupDir, ".cwd");
|
|
5075
|
+
const fromFile = await fs7.readFile(cwdFile, "utf8").catch(() => null);
|
|
4650
5076
|
if (fromFile && fromFile.trim())
|
|
4651
5077
|
return fromFile.trim();
|
|
4652
5078
|
try {
|
|
@@ -4661,8 +5087,8 @@ async function listSessionDirs(root) {
|
|
|
4661
5087
|
for (const group of groups) {
|
|
4662
5088
|
if (group === "session_search.sqlite" || group.startsWith("."))
|
|
4663
5089
|
continue;
|
|
4664
|
-
const groupDir =
|
|
4665
|
-
const groupStat = await
|
|
5090
|
+
const groupDir = path7.join(root, group);
|
|
5091
|
+
const groupStat = await fs7.stat(groupDir).catch(() => null);
|
|
4666
5092
|
if (!groupStat?.isDirectory())
|
|
4667
5093
|
continue;
|
|
4668
5094
|
const decodedCwd = await resolveEncodedCwd(groupDir, group);
|
|
@@ -4670,14 +5096,14 @@ async function listSessionDirs(root) {
|
|
|
4670
5096
|
for (const entry of entries2) {
|
|
4671
5097
|
if (entry === "prompt_history.jsonl" || entry.startsWith("."))
|
|
4672
5098
|
continue;
|
|
4673
|
-
const dirPath =
|
|
4674
|
-
const summaryPath =
|
|
4675
|
-
const updatesPath =
|
|
4676
|
-
const signalsCandidate =
|
|
5099
|
+
const dirPath = path7.join(groupDir, entry);
|
|
5100
|
+
const summaryPath = path7.join(dirPath, "summary.json");
|
|
5101
|
+
const updatesPath = path7.join(dirPath, "updates.jsonl");
|
|
5102
|
+
const signalsCandidate = path7.join(dirPath, "signals.json");
|
|
4677
5103
|
const [summaryStat, updatesStat, signalsStat] = await Promise.all([
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
5104
|
+
fs7.stat(summaryPath).catch(() => null),
|
|
5105
|
+
fs7.stat(updatesPath).catch(() => null),
|
|
5106
|
+
fs7.stat(signalsCandidate).catch(() => null)
|
|
4681
5107
|
]);
|
|
4682
5108
|
if (!summaryStat?.isFile())
|
|
4683
5109
|
continue;
|
|
@@ -4698,10 +5124,10 @@ async function listSessionDirs(root) {
|
|
|
4698
5124
|
}
|
|
4699
5125
|
return out;
|
|
4700
5126
|
}
|
|
4701
|
-
function
|
|
5127
|
+
function emptyUsage5() {
|
|
4702
5128
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
4703
5129
|
}
|
|
4704
|
-
function
|
|
5130
|
+
function previewOf5(text) {
|
|
4705
5131
|
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
4706
5132
|
}
|
|
4707
5133
|
function truncate5(s, n) {
|
|
@@ -4815,7 +5241,7 @@ function lineTimestampIso(line) {
|
|
|
4815
5241
|
}
|
|
4816
5242
|
return void 0;
|
|
4817
5243
|
}
|
|
4818
|
-
function
|
|
5244
|
+
function computeActiveSegments6(tsMs) {
|
|
4819
5245
|
if (tsMs.length === 0)
|
|
4820
5246
|
return [];
|
|
4821
5247
|
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
@@ -4824,7 +5250,7 @@ function computeActiveSegments5(tsMs) {
|
|
|
4824
5250
|
let segEnd = sorted[0];
|
|
4825
5251
|
for (let i = 1; i < sorted.length; i++) {
|
|
4826
5252
|
const t = sorted[i];
|
|
4827
|
-
if (t - segEnd >
|
|
5253
|
+
if (t - segEnd > IDLE_GAP_MS5) {
|
|
4828
5254
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
4829
5255
|
segStart = t;
|
|
4830
5256
|
}
|
|
@@ -4833,17 +5259,17 @@ function computeActiveSegments5(tsMs) {
|
|
|
4833
5259
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
4834
5260
|
return out;
|
|
4835
5261
|
}
|
|
4836
|
-
async function
|
|
5262
|
+
async function parseSession4(dir) {
|
|
4837
5263
|
const [summary, signals, updatesRaw] = await Promise.all([
|
|
4838
5264
|
safeReadJson(dir.summaryPath),
|
|
4839
5265
|
dir.signalsPath ? safeReadJson(dir.signalsPath) : Promise.resolve(null),
|
|
4840
|
-
|
|
5266
|
+
fs7.readFile(dir.updatesPath, "utf8").catch(() => "")
|
|
4841
5267
|
]);
|
|
4842
5268
|
const sessionId = summary?.info?.id ?? dir.sessionId;
|
|
4843
5269
|
const cwd = summary?.info?.cwd ?? dir.decodedCwd;
|
|
4844
5270
|
let model = summary?.current_model_id ?? signals?.primaryModelId ?? signals?.modelsUsed?.[0];
|
|
4845
5271
|
const events = [];
|
|
4846
|
-
const totalUsage =
|
|
5272
|
+
const totalUsage = emptyUsage5();
|
|
4847
5273
|
if (signals?.contextTokensUsed && signals.contextTokensUsed > 0) {
|
|
4848
5274
|
totalUsage.input = signals.contextTokensUsed;
|
|
4849
5275
|
}
|
|
@@ -4877,7 +5303,7 @@ async function parseSession3(dir) {
|
|
|
4877
5303
|
if (!buf)
|
|
4878
5304
|
return;
|
|
4879
5305
|
const text = buf.texts.join("");
|
|
4880
|
-
const preview =
|
|
5306
|
+
const preview = previewOf5(text);
|
|
4881
5307
|
if (buf.kind === "user") {
|
|
4882
5308
|
const isHidden = !text || isFrameworkInjectedUserInput(text);
|
|
4883
5309
|
if (text && !isHidden) {
|
|
@@ -5037,7 +5463,7 @@ async function parseSession3(dir) {
|
|
|
5037
5463
|
timestamp: ts,
|
|
5038
5464
|
role: "tool-result",
|
|
5039
5465
|
rawType: "grok/tool_result",
|
|
5040
|
-
preview:
|
|
5466
|
+
preview: previewOf5(resultText),
|
|
5041
5467
|
blocks: [
|
|
5042
5468
|
{
|
|
5043
5469
|
type: "tool_result",
|
|
@@ -5086,7 +5512,7 @@ async function parseSession3(dir) {
|
|
|
5086
5512
|
prevMs = ms;
|
|
5087
5513
|
}
|
|
5088
5514
|
}
|
|
5089
|
-
const activeSegments =
|
|
5515
|
+
const activeSegments = computeActiveSegments6(tsMs);
|
|
5090
5516
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
5091
5517
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
5092
5518
|
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
@@ -5095,7 +5521,7 @@ async function parseSession3(dir) {
|
|
|
5095
5521
|
if (!firstUserPreview) {
|
|
5096
5522
|
const title = summary?.generated_title || summary?.session_summary;
|
|
5097
5523
|
if (title)
|
|
5098
|
-
firstUserPreview =
|
|
5524
|
+
firstUserPreview = previewOf5(title);
|
|
5099
5525
|
}
|
|
5100
5526
|
const spawnedAgentCount = await countSubagentChildren(dir.dirPath);
|
|
5101
5527
|
const meta = {
|
|
@@ -5132,38 +5558,38 @@ async function parseSession3(dir) {
|
|
|
5132
5558
|
return { meta, events, sessionKind: summary?.session_kind };
|
|
5133
5559
|
}
|
|
5134
5560
|
async function countSubagentChildren(dirPath) {
|
|
5135
|
-
const subRoot =
|
|
5561
|
+
const subRoot = path7.join(dirPath, "subagents");
|
|
5136
5562
|
const entries2 = await safeReaddir5(subRoot);
|
|
5137
5563
|
let n = 0;
|
|
5138
5564
|
for (const e of entries2) {
|
|
5139
|
-
const st = await
|
|
5565
|
+
const st = await fs7.stat(path7.join(subRoot, e)).catch(() => null);
|
|
5140
5566
|
if (st?.isDirectory())
|
|
5141
5567
|
n += 1;
|
|
5142
5568
|
}
|
|
5143
5569
|
return n;
|
|
5144
5570
|
}
|
|
5145
5571
|
async function loadGrokSubagents(parentDir, parentStartMs) {
|
|
5146
|
-
const subRoot =
|
|
5572
|
+
const subRoot = path7.join(parentDir.dirPath, "subagents");
|
|
5147
5573
|
const entries2 = await safeReaddir5(subRoot);
|
|
5148
|
-
const groupDir =
|
|
5574
|
+
const groupDir = path7.dirname(parentDir.dirPath);
|
|
5149
5575
|
const runs2 = [];
|
|
5150
5576
|
for (const entry of entries2) {
|
|
5151
|
-
const metaPath =
|
|
5577
|
+
const metaPath = path7.join(subRoot, entry, "meta.json");
|
|
5152
5578
|
const meta = await safeReadJson(metaPath);
|
|
5153
5579
|
if (!meta)
|
|
5154
5580
|
continue;
|
|
5155
5581
|
const childId = meta.child_session_id ?? meta.subagent_id ?? entry;
|
|
5156
|
-
const childDir =
|
|
5582
|
+
const childDir = path7.join(groupDir, childId);
|
|
5157
5583
|
const [childSummary, childSignals] = await Promise.all([
|
|
5158
|
-
safeReadJson(
|
|
5159
|
-
safeReadJson(
|
|
5584
|
+
safeReadJson(path7.join(childDir, "summary.json")),
|
|
5585
|
+
safeReadJson(path7.join(childDir, "signals.json"))
|
|
5160
5586
|
]);
|
|
5161
5587
|
const startMs = childSummary?.created_at ? Date.parse(childSummary.created_at) : void 0;
|
|
5162
5588
|
const endIso = childSummary?.last_active_at ?? childSummary?.updated_at;
|
|
5163
5589
|
const endMs = endIso ? Date.parse(endIso) : void 0;
|
|
5164
5590
|
const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
|
|
5165
5591
|
const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
|
|
5166
|
-
const usage2 =
|
|
5592
|
+
const usage2 = emptyUsage5();
|
|
5167
5593
|
if (childSignals?.contextTokensUsed)
|
|
5168
5594
|
usage2.input = childSignals.contextTokensUsed;
|
|
5169
5595
|
runs2.push({
|
|
@@ -5186,8 +5612,8 @@ async function loadGrokSubagents(parentDir, parentStartMs) {
|
|
|
5186
5612
|
return runs2;
|
|
5187
5613
|
}
|
|
5188
5614
|
function clearGrokCaches() {
|
|
5189
|
-
|
|
5190
|
-
|
|
5615
|
+
metaCache7.clear();
|
|
5616
|
+
detailCache7.clear();
|
|
5191
5617
|
}
|
|
5192
5618
|
async function listGrokSessions(opts = {}) {
|
|
5193
5619
|
const root = opts.root ?? resolveDefaultGrokRoot();
|
|
@@ -5197,16 +5623,16 @@ async function listGrokSessions(opts = {}) {
|
|
|
5197
5623
|
const summaryPeek = await safeReadJson(dir.summaryPath);
|
|
5198
5624
|
if (summaryPeek?.session_kind === "subagent")
|
|
5199
5625
|
continue;
|
|
5200
|
-
const cached =
|
|
5626
|
+
const cached = metaCache7.get(dir.dirPath);
|
|
5201
5627
|
if (cached && cached.mtimeMs === dir.mtimeMs && cached.sizeBytes === dir.sizeBytes) {
|
|
5202
5628
|
out.push(cached.meta);
|
|
5203
5629
|
continue;
|
|
5204
5630
|
}
|
|
5205
5631
|
try {
|
|
5206
|
-
const { meta, sessionKind } = await
|
|
5632
|
+
const { meta, sessionKind } = await parseSession4(dir);
|
|
5207
5633
|
if (sessionKind === "subagent")
|
|
5208
5634
|
continue;
|
|
5209
|
-
|
|
5635
|
+
metaCache7.set(dir.dirPath, {
|
|
5210
5636
|
meta,
|
|
5211
5637
|
mtimeMs: dir.mtimeMs,
|
|
5212
5638
|
sizeBytes: dir.sizeBytes
|
|
@@ -5227,10 +5653,10 @@ async function getGrokSession(id, opts = {}) {
|
|
|
5227
5653
|
if (!chosen) {
|
|
5228
5654
|
for (const dir of dirs) {
|
|
5229
5655
|
try {
|
|
5230
|
-
const { meta: meta2, events: events2 } = await
|
|
5656
|
+
const { meta: meta2, events: events2 } = await parseSession4(dir);
|
|
5231
5657
|
if (meta2.id === id) {
|
|
5232
5658
|
const detail2 = { ...meta2, events: events2 };
|
|
5233
|
-
|
|
5659
|
+
detailCache7.set(dir.dirPath, {
|
|
5234
5660
|
detail: detail2,
|
|
5235
5661
|
mtimeMs: dir.mtimeMs,
|
|
5236
5662
|
sizeBytes: dir.sizeBytes
|
|
@@ -5242,11 +5668,11 @@ async function getGrokSession(id, opts = {}) {
|
|
|
5242
5668
|
}
|
|
5243
5669
|
return null;
|
|
5244
5670
|
}
|
|
5245
|
-
const cached =
|
|
5671
|
+
const cached = detailCache7.get(chosen.dirPath);
|
|
5246
5672
|
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
|
|
5247
5673
|
return cached.detail;
|
|
5248
5674
|
}
|
|
5249
|
-
const { meta, events } = await
|
|
5675
|
+
const { meta, events } = await parseSession4(chosen);
|
|
5250
5676
|
const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
|
|
5251
5677
|
const subagents = await loadGrokSubagents(chosen, parentStartMs !== void 0 && Number.isFinite(parentStartMs) ? parentStartMs : void 0);
|
|
5252
5678
|
const detail = {
|
|
@@ -5254,12 +5680,12 @@ async function getGrokSession(id, opts = {}) {
|
|
|
5254
5680
|
events,
|
|
5255
5681
|
...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
|
|
5256
5682
|
};
|
|
5257
|
-
|
|
5683
|
+
detailCache7.set(chosen.dirPath, {
|
|
5258
5684
|
detail,
|
|
5259
5685
|
mtimeMs: chosen.mtimeMs,
|
|
5260
5686
|
sizeBytes: chosen.sizeBytes
|
|
5261
5687
|
});
|
|
5262
|
-
|
|
5688
|
+
metaCache7.set(chosen.dirPath, {
|
|
5263
5689
|
meta: {
|
|
5264
5690
|
...meta,
|
|
5265
5691
|
...subagents.length > 0 ? { spawnedAgentCount: subagents.length } : {}
|
|
@@ -5275,17 +5701,17 @@ function grokSessionLocalDay(meta) {
|
|
|
5275
5701
|
const ms = Date.parse(meta.firstTimestamp);
|
|
5276
5702
|
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
5277
5703
|
}
|
|
5278
|
-
var DEFAULT_GROK_ROOT,
|
|
5704
|
+
var DEFAULT_GROK_ROOT, IDLE_GAP_MS5, metaCache7, detailCache7;
|
|
5279
5705
|
var init_grok = __esm({
|
|
5280
5706
|
"../parser/dist/grok.js"() {
|
|
5281
5707
|
"use strict";
|
|
5282
5708
|
init_analytics();
|
|
5283
5709
|
init_git_project();
|
|
5284
5710
|
init_user_input();
|
|
5285
|
-
DEFAULT_GROK_ROOT =
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5711
|
+
DEFAULT_GROK_ROOT = path7.join(os7.homedir(), ".grok", "sessions");
|
|
5712
|
+
IDLE_GAP_MS5 = 3 * 60 * 1e3;
|
|
5713
|
+
metaCache7 = /* @__PURE__ */ new Map();
|
|
5714
|
+
detailCache7 = /* @__PURE__ */ new Map();
|
|
5289
5715
|
}
|
|
5290
5716
|
});
|
|
5291
5717
|
|
|
@@ -5346,6 +5772,7 @@ var fs_exports = {};
|
|
|
5346
5772
|
__export(fs_exports, {
|
|
5347
5773
|
DEFAULT_ANTIGRAVITY_ROOT: () => DEFAULT_ANTIGRAVITY_ROOT,
|
|
5348
5774
|
DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
|
|
5775
|
+
DEFAULT_COPILOT_ROOT: () => DEFAULT_COPILOT_ROOT,
|
|
5349
5776
|
DEFAULT_COWORK_ROOT: () => DEFAULT_COWORK_ROOT,
|
|
5350
5777
|
DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
|
|
5351
5778
|
DEFAULT_GROK_ROOT: () => DEFAULT_GROK_ROOT,
|
|
@@ -5362,6 +5789,7 @@ __export(fs_exports, {
|
|
|
5362
5789
|
clearGrokCaches: () => clearGrokCaches,
|
|
5363
5790
|
clearTeamConfig: () => clearTeamConfig,
|
|
5364
5791
|
codexSessionLocalDay: () => codexSessionLocalDay,
|
|
5792
|
+
copilotSessionLocalDay: () => copilotSessionLocalDay,
|
|
5365
5793
|
decodeProjectName: () => decodeProjectName,
|
|
5366
5794
|
findTeamLead: () => findTeamLead,
|
|
5367
5795
|
geminiSessionLocalDay: () => geminiSessionLocalDay,
|
|
@@ -5369,6 +5797,7 @@ __export(fs_exports, {
|
|
|
5369
5797
|
getAntigravitySession: () => getAntigravitySession,
|
|
5370
5798
|
getAnySession: () => getAnySession,
|
|
5371
5799
|
getCodexSession: () => getCodexSession,
|
|
5800
|
+
getCopilotSession: () => getCopilotSession,
|
|
5372
5801
|
getCoworkSession: () => getCoworkSession,
|
|
5373
5802
|
getGeminiSession: () => getGeminiSession,
|
|
5374
5803
|
getGrokSession: () => getGrokSession,
|
|
@@ -5380,6 +5809,7 @@ __export(fs_exports, {
|
|
|
5380
5809
|
listAllSessions: () => listAllSessions,
|
|
5381
5810
|
listAntigravitySessions: () => listAntigravitySessions,
|
|
5382
5811
|
listCodexSessions: () => listCodexSessions,
|
|
5812
|
+
listCopilotSessions: () => listCopilotSessions,
|
|
5383
5813
|
listCoworkSessions: () => listCoworkSessions,
|
|
5384
5814
|
listGeminiSessions: () => listGeminiSessions,
|
|
5385
5815
|
listGrokSessions: () => listGrokSessions,
|
|
@@ -5402,14 +5832,14 @@ __export(fs_exports, {
|
|
|
5402
5832
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
5403
5833
|
writeTeamConfig: () => writeTeamConfig
|
|
5404
5834
|
});
|
|
5405
|
-
import { promises as
|
|
5406
|
-
import
|
|
5407
|
-
import
|
|
5835
|
+
import { promises as fs8, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
|
|
5836
|
+
import os8 from "node:os";
|
|
5837
|
+
import path8 from "node:path";
|
|
5408
5838
|
function cclensHome() {
|
|
5409
|
-
return process.env.CCLENS_HOME ||
|
|
5839
|
+
return process.env.CCLENS_HOME || path8.join(os8.homedir(), ".cclens");
|
|
5410
5840
|
}
|
|
5411
5841
|
function cclensPath(...parts) {
|
|
5412
|
-
return
|
|
5842
|
+
return path8.join(cclensHome(), ...parts);
|
|
5413
5843
|
}
|
|
5414
5844
|
function cacheStats() {
|
|
5415
5845
|
return claudeCodeCacheStats();
|
|
@@ -5417,6 +5847,7 @@ function cacheStats() {
|
|
|
5417
5847
|
function clearCaches() {
|
|
5418
5848
|
clearClaudeCodeCaches();
|
|
5419
5849
|
clearCodexCaches();
|
|
5850
|
+
clearCopilotCaches();
|
|
5420
5851
|
clearGeminiCaches();
|
|
5421
5852
|
clearAntigravityCaches();
|
|
5422
5853
|
clearCoworkCaches();
|
|
@@ -5451,7 +5882,7 @@ function usageLogPath() {
|
|
|
5451
5882
|
}
|
|
5452
5883
|
function appendUsageSnapshot(snapshot) {
|
|
5453
5884
|
const p = usageLogPath();
|
|
5454
|
-
mkdirSync3(
|
|
5885
|
+
mkdirSync3(path8.dirname(p), { recursive: true });
|
|
5455
5886
|
appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
|
|
5456
5887
|
}
|
|
5457
5888
|
function pruneUsageAgent(agent) {
|
|
@@ -5467,13 +5898,13 @@ function pruneUsageAgent(agent) {
|
|
|
5467
5898
|
return true;
|
|
5468
5899
|
}
|
|
5469
5900
|
});
|
|
5470
|
-
mkdirSync3(
|
|
5901
|
+
mkdirSync3(path8.dirname(p), { recursive: true });
|
|
5471
5902
|
writeFileSync3(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
5472
5903
|
}
|
|
5473
5904
|
async function loadUsageByDay(start2, end) {
|
|
5474
5905
|
let raw;
|
|
5475
5906
|
try {
|
|
5476
|
-
raw = await
|
|
5907
|
+
raw = await fs8.readFile(usageLogPath(), "utf8");
|
|
5477
5908
|
} catch {
|
|
5478
5909
|
return { by_day: [] };
|
|
5479
5910
|
}
|
|
@@ -5518,7 +5949,7 @@ async function loadUsageByDay(start2, end) {
|
|
|
5518
5949
|
async function loadCalibrationSnapshots() {
|
|
5519
5950
|
let raw;
|
|
5520
5951
|
try {
|
|
5521
|
-
raw = await
|
|
5952
|
+
raw = await fs8.readFile(usageLogPath(), "utf8");
|
|
5522
5953
|
} catch {
|
|
5523
5954
|
return [];
|
|
5524
5955
|
}
|
|
@@ -5682,7 +6113,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
|
|
|
5682
6113
|
]);
|
|
5683
6114
|
return buildCalibrationCurve(events, snapshots, tier, granularityMin);
|
|
5684
6115
|
}
|
|
5685
|
-
var codexSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
|
|
6116
|
+
var codexSource, copilotSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
|
|
5686
6117
|
var init_fs = __esm({
|
|
5687
6118
|
"../parser/dist/fs.js"() {
|
|
5688
6119
|
"use strict";
|
|
@@ -5691,6 +6122,7 @@ var init_fs = __esm({
|
|
|
5691
6122
|
init_calibration();
|
|
5692
6123
|
init_claude_code();
|
|
5693
6124
|
init_codex();
|
|
6125
|
+
init_copilot();
|
|
5694
6126
|
init_gemini();
|
|
5695
6127
|
init_antigravity();
|
|
5696
6128
|
init_cowork();
|
|
@@ -5698,6 +6130,7 @@ var init_fs = __esm({
|
|
|
5698
6130
|
init_claude_code();
|
|
5699
6131
|
init_git_project();
|
|
5700
6132
|
init_codex();
|
|
6133
|
+
init_copilot();
|
|
5701
6134
|
init_gemini();
|
|
5702
6135
|
init_antigravity();
|
|
5703
6136
|
init_cowork();
|
|
@@ -5712,18 +6145,16 @@ var init_fs = __esm({
|
|
|
5712
6145
|
},
|
|
5713
6146
|
async getSession(id) {
|
|
5714
6147
|
return getCodexSession(id);
|
|
6148
|
+
}
|
|
6149
|
+
};
|
|
6150
|
+
copilotSource = {
|
|
6151
|
+
...COPILOT_METADATA,
|
|
6152
|
+
defaultRoot: DEFAULT_COPILOT_ROOT,
|
|
6153
|
+
async listSessions(opts) {
|
|
6154
|
+
return listCopilotSessions(opts);
|
|
5715
6155
|
},
|
|
5716
|
-
async
|
|
5717
|
-
|
|
5718
|
-
if (!w)
|
|
5719
|
-
return null;
|
|
5720
|
-
return {
|
|
5721
|
-
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5722
|
-
agent: "codex",
|
|
5723
|
-
five_hour: w.five_hour,
|
|
5724
|
-
seven_day: w.seven_day,
|
|
5725
|
-
plan_type: w.plan_type
|
|
5726
|
-
};
|
|
6156
|
+
async getSession(id, opts) {
|
|
6157
|
+
return getCopilotSession(id, opts);
|
|
5727
6158
|
}
|
|
5728
6159
|
};
|
|
5729
6160
|
geminiSource = {
|
|
@@ -5770,6 +6201,7 @@ var init_fs = __esm({
|
|
|
5770
6201
|
agentSources = [
|
|
5771
6202
|
claudeCodeSource,
|
|
5772
6203
|
codexSource,
|
|
6204
|
+
copilotSource,
|
|
5773
6205
|
geminiSource,
|
|
5774
6206
|
antigravitySource,
|
|
5775
6207
|
coworkSource,
|
|
@@ -5809,9 +6241,9 @@ function onDiskVersion() {
|
|
|
5809
6241
|
try {
|
|
5810
6242
|
const here = dirname3(fileURLToPath(import.meta.url));
|
|
5811
6243
|
const pkg = JSON.parse(readFileSync5(join3(here, "..", "package.json"), "utf8"));
|
|
5812
|
-
return pkg.version ?? "0.16.
|
|
6244
|
+
return pkg.version ?? "0.16.7";
|
|
5813
6245
|
} catch {
|
|
5814
|
-
return "0.16.
|
|
6246
|
+
return "0.16.7";
|
|
5815
6247
|
}
|
|
5816
6248
|
}
|
|
5817
6249
|
function getServerStatus() {
|
|
@@ -5823,7 +6255,7 @@ function getServerStatus() {
|
|
|
5823
6255
|
return { running: false };
|
|
5824
6256
|
}
|
|
5825
6257
|
function isServerStale(status2) {
|
|
5826
|
-
return status2.running === true && status2.version !== "0.16.
|
|
6258
|
+
return status2.running === true && status2.version !== "0.16.7";
|
|
5827
6259
|
}
|
|
5828
6260
|
async function ensureCurrentServer(opts = {}) {
|
|
5829
6261
|
const status2 = getServerStatus();
|
|
@@ -6262,9 +6694,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
|
|
|
6262
6694
|
console.warn(
|
|
6263
6695
|
` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
|
|
6264
6696
|
);
|
|
6265
|
-
} else if (verify.installedVersion !== "0.16.
|
|
6697
|
+
} else if (verify.installedVersion !== "0.16.7") {
|
|
6266
6698
|
console.log(
|
|
6267
|
-
` \u2192 This process is still running ${"0.16.
|
|
6699
|
+
` \u2192 This process is still running ${"0.16.7"}. Next invocation will use ${verify.installedVersion}.`
|
|
6268
6700
|
);
|
|
6269
6701
|
}
|
|
6270
6702
|
}
|
|
@@ -6299,14 +6731,14 @@ async function getUpdateAvailability() {
|
|
|
6299
6731
|
if (isDevMode()) return null;
|
|
6300
6732
|
const latest = await fetchLatestVersion();
|
|
6301
6733
|
if (latest === null) return {
|
|
6302
|
-
current: "0.16.
|
|
6734
|
+
current: "0.16.7",
|
|
6303
6735
|
latest: null,
|
|
6304
6736
|
updateAvailable: false
|
|
6305
6737
|
};
|
|
6306
6738
|
return {
|
|
6307
|
-
current: "0.16.
|
|
6739
|
+
current: "0.16.7",
|
|
6308
6740
|
latest,
|
|
6309
|
-
updateAvailable: shouldUpdate("0.16.
|
|
6741
|
+
updateAvailable: shouldUpdate("0.16.7", latest)
|
|
6310
6742
|
};
|
|
6311
6743
|
}
|
|
6312
6744
|
async function checkForUpdate() {
|
|
@@ -6396,7 +6828,7 @@ async function restartServices(state) {
|
|
|
6396
6828
|
}
|
|
6397
6829
|
async function forceUpdate() {
|
|
6398
6830
|
const latest = await fetchLatestVersion();
|
|
6399
|
-
const current = "0.16.
|
|
6831
|
+
const current = "0.16.7";
|
|
6400
6832
|
if (latest === null) {
|
|
6401
6833
|
console.error("Could not reach npm registry. Check your network.");
|
|
6402
6834
|
process.exit(1);
|
|
@@ -6809,7 +7241,7 @@ async function status() {
|
|
|
6809
7241
|
console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
|
|
6810
7242
|
if (isServerStale(server)) {
|
|
6811
7243
|
console.log(
|
|
6812
|
-
` \u26A0 serving stale ${ver} (CLI is ${"0.16.
|
|
7244
|
+
` \u26A0 serving stale ${ver} (CLI is ${"0.16.7"}) \u2014 run 'fleetlens start' to restart on the current version`
|
|
6813
7245
|
);
|
|
6814
7246
|
}
|
|
6815
7247
|
} else {
|
|
@@ -6848,7 +7280,7 @@ async function web(args2) {
|
|
|
6848
7280
|
const open = args2.includes("--open");
|
|
6849
7281
|
const positional = args2.filter((a) => !a.startsWith("--"));
|
|
6850
7282
|
const rawPath = positional[0] ?? "";
|
|
6851
|
-
const
|
|
7283
|
+
const path11 = rawPath.startsWith("/") ? rawPath : rawPath ? `/${rawPath}` : "";
|
|
6852
7284
|
let result;
|
|
6853
7285
|
try {
|
|
6854
7286
|
result = await ensureCurrentServer({});
|
|
@@ -6856,7 +7288,7 @@ async function web(args2) {
|
|
|
6856
7288
|
console.error(`Failed to start: ${err.message}`);
|
|
6857
7289
|
process.exit(1);
|
|
6858
7290
|
}
|
|
6859
|
-
const url = `http://localhost:${result.port}${
|
|
7291
|
+
const url = `http://localhost:${result.port}${path11}`;
|
|
6860
7292
|
if (result.restarted) {
|
|
6861
7293
|
console.log(`fleetlens restarted on http://localhost:${result.port} (PID ${result.pid}) \u2014 replaced stale ${result.previousVersion ?? "unknown"} server`);
|
|
6862
7294
|
}
|
|
@@ -6917,9 +7349,9 @@ function readFromCredentialsFile() {
|
|
|
6917
7349
|
join7(homedir4(), ".claude", ".credentials.json"),
|
|
6918
7350
|
join7(homedir4(), ".config", "claude", "credentials.json")
|
|
6919
7351
|
];
|
|
6920
|
-
for (const
|
|
7352
|
+
for (const path11 of candidates) {
|
|
6921
7353
|
try {
|
|
6922
|
-
const blob = readFileSync10(
|
|
7354
|
+
const blob = readFileSync10(path11, "utf8");
|
|
6923
7355
|
const creds = extractCredentials(blob);
|
|
6924
7356
|
if (creds) return creds;
|
|
6925
7357
|
} catch {
|
|
@@ -7043,13 +7475,13 @@ var init_api = __esm({
|
|
|
7043
7475
|
|
|
7044
7476
|
// src/usage/grok.ts
|
|
7045
7477
|
import { existsSync as existsSync8, readFileSync as readFileSync11 } from "node:fs";
|
|
7046
|
-
import
|
|
7047
|
-
import
|
|
7478
|
+
import os9 from "node:os";
|
|
7479
|
+
import path9 from "node:path";
|
|
7048
7480
|
function grokHome() {
|
|
7049
|
-
return process.env.GROK_HOME ||
|
|
7481
|
+
return process.env.GROK_HOME || path9.join(os9.homedir(), ".grok");
|
|
7050
7482
|
}
|
|
7051
7483
|
function authPath() {
|
|
7052
|
-
return
|
|
7484
|
+
return path9.join(grokHome(), "auth.json");
|
|
7053
7485
|
}
|
|
7054
7486
|
function loadAuthEntry() {
|
|
7055
7487
|
const p = authPath();
|
|
@@ -7112,8 +7544,8 @@ async function refreshAccessToken(entry) {
|
|
|
7112
7544
|
break;
|
|
7113
7545
|
}
|
|
7114
7546
|
}
|
|
7115
|
-
const { writeFileSync:
|
|
7116
|
-
|
|
7547
|
+
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
7548
|
+
writeFileSync18(p, JSON.stringify(raw, null, 2), "utf8");
|
|
7117
7549
|
} catch {
|
|
7118
7550
|
}
|
|
7119
7551
|
return j.access_token;
|
|
@@ -7259,6 +7691,500 @@ var init_grok2 = __esm({
|
|
|
7259
7691
|
}
|
|
7260
7692
|
});
|
|
7261
7693
|
|
|
7694
|
+
// src/usage/codex.ts
|
|
7695
|
+
import {
|
|
7696
|
+
existsSync as existsSync9,
|
|
7697
|
+
readFileSync as readFileSync12,
|
|
7698
|
+
writeFileSync as writeFileSync6
|
|
7699
|
+
} from "node:fs";
|
|
7700
|
+
import os10 from "node:os";
|
|
7701
|
+
import path10 from "node:path";
|
|
7702
|
+
function codexHome() {
|
|
7703
|
+
const env = process.env.CODEX_HOME?.trim();
|
|
7704
|
+
if (env) return env;
|
|
7705
|
+
return path10.join(os10.homedir(), ".codex");
|
|
7706
|
+
}
|
|
7707
|
+
function authPath2() {
|
|
7708
|
+
return path10.join(codexHome(), "auth.json");
|
|
7709
|
+
}
|
|
7710
|
+
function loadAuth() {
|
|
7711
|
+
const p = authPath2();
|
|
7712
|
+
if (!existsSync9(p)) {
|
|
7713
|
+
throw new CodexApiError(
|
|
7714
|
+
"Codex not logged in. Run `codex` to authenticate.",
|
|
7715
|
+
"no_auth"
|
|
7716
|
+
);
|
|
7717
|
+
}
|
|
7718
|
+
let auth;
|
|
7719
|
+
try {
|
|
7720
|
+
auth = JSON.parse(readFileSync12(p, "utf8"));
|
|
7721
|
+
} catch {
|
|
7722
|
+
throw new CodexApiError(
|
|
7723
|
+
"Codex auth.json is unreadable. Run `codex` to log in again.",
|
|
7724
|
+
"no_auth"
|
|
7725
|
+
);
|
|
7726
|
+
}
|
|
7727
|
+
const access = auth.tokens?.access_token?.trim();
|
|
7728
|
+
if (!access) {
|
|
7729
|
+
if (auth.OPENAI_API_KEY?.trim()) {
|
|
7730
|
+
throw new CodexApiError(
|
|
7731
|
+
"Codex usage is not available for API-key-only auth. Sign in with a ChatGPT account via `codex`.",
|
|
7732
|
+
"api_key_only"
|
|
7733
|
+
);
|
|
7734
|
+
}
|
|
7735
|
+
throw new CodexApiError(
|
|
7736
|
+
"Codex auth has no access token. Run `codex` to log in.",
|
|
7737
|
+
"no_auth"
|
|
7738
|
+
);
|
|
7739
|
+
}
|
|
7740
|
+
return { auth, path: p };
|
|
7741
|
+
}
|
|
7742
|
+
function accessTokenExpiresAtMs(token) {
|
|
7743
|
+
const parts = token.split(".");
|
|
7744
|
+
if (parts.length < 2) return null;
|
|
7745
|
+
try {
|
|
7746
|
+
const pad2 = "=".repeat((4 - parts[1].length % 4) % 4);
|
|
7747
|
+
const json = Buffer.from(parts[1] + pad2, "base64url").toString("utf8");
|
|
7748
|
+
const payload = JSON.parse(json);
|
|
7749
|
+
if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
|
|
7750
|
+
return null;
|
|
7751
|
+
}
|
|
7752
|
+
return payload.exp * 1e3;
|
|
7753
|
+
} catch {
|
|
7754
|
+
return null;
|
|
7755
|
+
}
|
|
7756
|
+
}
|
|
7757
|
+
function needsRefresh2(accessToken, lastRefresh, nowMs = Date.now()) {
|
|
7758
|
+
const expMs = accessTokenExpiresAtMs(accessToken);
|
|
7759
|
+
if (expMs !== null) {
|
|
7760
|
+
return nowMs >= expMs - REFRESH_BUFFER_MS2;
|
|
7761
|
+
}
|
|
7762
|
+
if (!lastRefresh) return false;
|
|
7763
|
+
const ms = Date.parse(lastRefresh);
|
|
7764
|
+
if (!Number.isFinite(ms)) return false;
|
|
7765
|
+
return nowMs - ms > 8 * 24 * 60 * 60 * 1e3;
|
|
7766
|
+
}
|
|
7767
|
+
async function refreshAccessToken2(auth, filePath) {
|
|
7768
|
+
const refresh = auth.tokens?.refresh_token?.trim();
|
|
7769
|
+
if (!refresh) return null;
|
|
7770
|
+
const body = new URLSearchParams({
|
|
7771
|
+
grant_type: "refresh_token",
|
|
7772
|
+
client_id: CLIENT_ID,
|
|
7773
|
+
refresh_token: refresh
|
|
7774
|
+
});
|
|
7775
|
+
let res;
|
|
7776
|
+
try {
|
|
7777
|
+
res = await fetch(REFRESH_URL2, {
|
|
7778
|
+
method: "POST",
|
|
7779
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
7780
|
+
body: body.toString()
|
|
7781
|
+
});
|
|
7782
|
+
} catch {
|
|
7783
|
+
return null;
|
|
7784
|
+
}
|
|
7785
|
+
if (!res.ok) return null;
|
|
7786
|
+
try {
|
|
7787
|
+
const j = await res.json();
|
|
7788
|
+
if (typeof j.access_token !== "string" || !j.access_token) return null;
|
|
7789
|
+
const next = {
|
|
7790
|
+
...auth,
|
|
7791
|
+
tokens: {
|
|
7792
|
+
...auth.tokens,
|
|
7793
|
+
access_token: j.access_token,
|
|
7794
|
+
refresh_token: j.refresh_token ?? auth.tokens?.refresh_token,
|
|
7795
|
+
id_token: j.id_token ?? auth.tokens?.id_token
|
|
7796
|
+
},
|
|
7797
|
+
last_refresh: (/* @__PURE__ */ new Date()).toISOString()
|
|
7798
|
+
};
|
|
7799
|
+
try {
|
|
7800
|
+
writeFileSync6(filePath, `${JSON.stringify(next, null, 2)}
|
|
7801
|
+
`, {
|
|
7802
|
+
encoding: "utf8",
|
|
7803
|
+
mode: 384
|
|
7804
|
+
});
|
|
7805
|
+
} catch {
|
|
7806
|
+
}
|
|
7807
|
+
return { accessToken: j.access_token, auth: next };
|
|
7808
|
+
} catch {
|
|
7809
|
+
return null;
|
|
7810
|
+
}
|
|
7811
|
+
}
|
|
7812
|
+
function authHeaders2(accessToken, accountId) {
|
|
7813
|
+
const headers = {
|
|
7814
|
+
Authorization: `Bearer ${accessToken}`,
|
|
7815
|
+
Accept: "application/json",
|
|
7816
|
+
"User-Agent": "fleetlens"
|
|
7817
|
+
};
|
|
7818
|
+
if (accountId?.trim()) {
|
|
7819
|
+
headers["ChatGPT-Account-Id"] = accountId.trim();
|
|
7820
|
+
}
|
|
7821
|
+
return headers;
|
|
7822
|
+
}
|
|
7823
|
+
function numberOf3(v) {
|
|
7824
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
7825
|
+
if (typeof v === "string" && v.trim()) {
|
|
7826
|
+
const n = Number(v);
|
|
7827
|
+
if (Number.isFinite(n)) return n;
|
|
7828
|
+
}
|
|
7829
|
+
return void 0;
|
|
7830
|
+
}
|
|
7831
|
+
function windowSeconds(raw) {
|
|
7832
|
+
if (!raw) return void 0;
|
|
7833
|
+
const sec = numberOf3(raw.limit_window_seconds);
|
|
7834
|
+
if (sec !== void 0) return sec;
|
|
7835
|
+
const minutes = numberOf3(raw.window_minutes);
|
|
7836
|
+
if (minutes !== void 0) return minutes * 60;
|
|
7837
|
+
return void 0;
|
|
7838
|
+
}
|
|
7839
|
+
function normalizeWindow2(raw, headerPercent, nowMs) {
|
|
7840
|
+
const used = numberOf3(raw?.used_percent) ?? headerPercent;
|
|
7841
|
+
if (used === void 0) return null;
|
|
7842
|
+
let resetsAt = null;
|
|
7843
|
+
const resetUnix = numberOf3(raw?.reset_at) ?? numberOf3(raw?.resets_at);
|
|
7844
|
+
if (resetUnix !== void 0) {
|
|
7845
|
+
resetsAt = new Date(resetUnix * 1e3).toISOString();
|
|
7846
|
+
} else {
|
|
7847
|
+
const after = numberOf3(raw?.reset_after_seconds);
|
|
7848
|
+
if (after !== void 0) {
|
|
7849
|
+
resetsAt = new Date(nowMs + after * 1e3).toISOString();
|
|
7850
|
+
}
|
|
7851
|
+
}
|
|
7852
|
+
return {
|
|
7853
|
+
utilization: Math.min(100, Math.max(0, used)),
|
|
7854
|
+
resets_at: resetsAt
|
|
7855
|
+
};
|
|
7856
|
+
}
|
|
7857
|
+
function parseCodexWhamUsage(body, headers = {}, nowMs = Date.now()) {
|
|
7858
|
+
if (!body || typeof body !== "object") {
|
|
7859
|
+
throw new CodexApiError("Codex usage response missing body", "parse");
|
|
7860
|
+
}
|
|
7861
|
+
const b = body;
|
|
7862
|
+
const rateLimit = b.rate_limit && typeof b.rate_limit === "object" ? b.rate_limit : {};
|
|
7863
|
+
const headerPrimary = numberOf3(headers["x-codex-primary-used-percent"]);
|
|
7864
|
+
const headerSecondary = numberOf3(headers["x-codex-secondary-used-percent"]);
|
|
7865
|
+
const primary = rateLimit.primary_window && typeof rateLimit.primary_window === "object" ? rateLimit.primary_window : null;
|
|
7866
|
+
const secondary = rateLimit.secondary_window && typeof rateLimit.secondary_window === "object" ? rateLimit.secondary_window : null;
|
|
7867
|
+
const candidates = [
|
|
7868
|
+
{ raw: primary, headerPercent: headerPrimary, fallback: "five_hour" },
|
|
7869
|
+
{ raw: secondary, headerPercent: headerSecondary, fallback: "seven_day" }
|
|
7870
|
+
];
|
|
7871
|
+
let fiveHour = null;
|
|
7872
|
+
let sevenDay = null;
|
|
7873
|
+
for (const c of candidates) {
|
|
7874
|
+
const secs = windowSeconds(c.raw);
|
|
7875
|
+
const window = normalizeWindow2(c.raw, c.headerPercent, nowMs);
|
|
7876
|
+
if (!window) continue;
|
|
7877
|
+
if (secs === FIVE_HOUR_SECONDS) fiveHour = window;
|
|
7878
|
+
else if (secs === SEVEN_DAY_SECONDS) sevenDay = window;
|
|
7879
|
+
}
|
|
7880
|
+
if (!fiveHour || !sevenDay) {
|
|
7881
|
+
for (const c of candidates) {
|
|
7882
|
+
const secs = windowSeconds(c.raw);
|
|
7883
|
+
if (secs === FIVE_HOUR_SECONDS || secs === SEVEN_DAY_SECONDS) continue;
|
|
7884
|
+
const window = normalizeWindow2(c.raw, c.headerPercent, nowMs);
|
|
7885
|
+
if (!window) continue;
|
|
7886
|
+
if (c.fallback === "five_hour" && !fiveHour) fiveHour = window;
|
|
7887
|
+
else if (c.fallback === "seven_day" && !sevenDay) sevenDay = window;
|
|
7888
|
+
}
|
|
7889
|
+
}
|
|
7890
|
+
const planRaw = b.plan_type;
|
|
7891
|
+
const planType = typeof planRaw === "string" && planRaw.trim() ? planRaw.trim() : null;
|
|
7892
|
+
return {
|
|
7893
|
+
five_hour: fiveHour ?? { utilization: null, resets_at: null },
|
|
7894
|
+
seven_day: sevenDay ?? { utilization: null, resets_at: null },
|
|
7895
|
+
plan_type: planType
|
|
7896
|
+
};
|
|
7897
|
+
}
|
|
7898
|
+
async function fetchUsageResponse(accessToken, accountId) {
|
|
7899
|
+
let res;
|
|
7900
|
+
try {
|
|
7901
|
+
res = await fetch(USAGE_URL, {
|
|
7902
|
+
headers: authHeaders2(accessToken, accountId)
|
|
7903
|
+
});
|
|
7904
|
+
} catch (err) {
|
|
7905
|
+
throw new CodexApiError(
|
|
7906
|
+
`Network error reaching Codex usage: ${err.message}`,
|
|
7907
|
+
"network"
|
|
7908
|
+
);
|
|
7909
|
+
}
|
|
7910
|
+
const headers = {};
|
|
7911
|
+
res.headers.forEach((value, key) => {
|
|
7912
|
+
headers[key.toLowerCase()] = value;
|
|
7913
|
+
});
|
|
7914
|
+
let body = null;
|
|
7915
|
+
try {
|
|
7916
|
+
body = await res.json();
|
|
7917
|
+
} catch {
|
|
7918
|
+
}
|
|
7919
|
+
return { status: res.status, body, headers };
|
|
7920
|
+
}
|
|
7921
|
+
async function fetchCodexUsage() {
|
|
7922
|
+
const loaded = loadAuth();
|
|
7923
|
+
let auth = loaded.auth;
|
|
7924
|
+
let access = auth.tokens.access_token.trim();
|
|
7925
|
+
const accountId = auth.tokens?.account_id;
|
|
7926
|
+
if (needsRefresh2(access, auth.last_refresh)) {
|
|
7927
|
+
const refreshed = await refreshAccessToken2(auth, loaded.path);
|
|
7928
|
+
if (refreshed) {
|
|
7929
|
+
access = refreshed.accessToken;
|
|
7930
|
+
auth = refreshed.auth;
|
|
7931
|
+
}
|
|
7932
|
+
}
|
|
7933
|
+
let { status: status2, body, headers } = await fetchUsageResponse(access, accountId);
|
|
7934
|
+
if (status2 === 401 || status2 === 403) {
|
|
7935
|
+
const refreshed = await refreshAccessToken2(auth, loaded.path);
|
|
7936
|
+
if (refreshed) {
|
|
7937
|
+
access = refreshed.accessToken;
|
|
7938
|
+
({ status: status2, body, headers } = await fetchUsageResponse(access, accountId));
|
|
7939
|
+
}
|
|
7940
|
+
}
|
|
7941
|
+
if (status2 < 200 || status2 >= 300) {
|
|
7942
|
+
throw new CodexApiError(
|
|
7943
|
+
`Codex usage returned HTTP ${status2}`,
|
|
7944
|
+
status2 === 401 || status2 === 403 ? "no_auth" : "http"
|
|
7945
|
+
);
|
|
7946
|
+
}
|
|
7947
|
+
const windows = parseCodexWhamUsage(body, headers);
|
|
7948
|
+
return {
|
|
7949
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7950
|
+
agent: "codex",
|
|
7951
|
+
five_hour: windows.five_hour,
|
|
7952
|
+
seven_day: windows.seven_day,
|
|
7953
|
+
seven_day_opus: null,
|
|
7954
|
+
seven_day_sonnet: null,
|
|
7955
|
+
seven_day_oauth_apps: null,
|
|
7956
|
+
seven_day_cowork: null,
|
|
7957
|
+
extra_usage: null,
|
|
7958
|
+
plan_type: windows.plan_type
|
|
7959
|
+
};
|
|
7960
|
+
}
|
|
7961
|
+
var USAGE_URL, REFRESH_URL2, CLIENT_ID, FIVE_HOUR_SECONDS, SEVEN_DAY_SECONDS, REFRESH_BUFFER_MS2, CodexApiError;
|
|
7962
|
+
var init_codex2 = __esm({
|
|
7963
|
+
"src/usage/codex.ts"() {
|
|
7964
|
+
"use strict";
|
|
7965
|
+
USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
7966
|
+
REFRESH_URL2 = "https://auth.openai.com/oauth/token";
|
|
7967
|
+
CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
7968
|
+
FIVE_HOUR_SECONDS = 5 * 60 * 60;
|
|
7969
|
+
SEVEN_DAY_SECONDS = 7 * 24 * 60 * 60;
|
|
7970
|
+
REFRESH_BUFFER_MS2 = 5 * 60 * 1e3;
|
|
7971
|
+
CodexApiError = class extends Error {
|
|
7972
|
+
constructor(message, code) {
|
|
7973
|
+
super(message);
|
|
7974
|
+
this.code = code;
|
|
7975
|
+
}
|
|
7976
|
+
};
|
|
7977
|
+
}
|
|
7978
|
+
});
|
|
7979
|
+
|
|
7980
|
+
// src/usage/copilot.ts
|
|
7981
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
7982
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
7983
|
+
import { dirname as dirname8, join as join8 } from "node:path";
|
|
7984
|
+
function recordOf2(value) {
|
|
7985
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
7986
|
+
}
|
|
7987
|
+
function numberOf4(value) {
|
|
7988
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
7989
|
+
}
|
|
7990
|
+
function clampPercent(value) {
|
|
7991
|
+
return Math.min(100, Math.max(0, value));
|
|
7992
|
+
}
|
|
7993
|
+
function nextCopilotMonthlyReset(nowMs = Date.now()) {
|
|
7994
|
+
const now = new Date(nowMs);
|
|
7995
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)).toISOString();
|
|
7996
|
+
}
|
|
7997
|
+
function quotaResetDate(value, nowMs) {
|
|
7998
|
+
const parsed = typeof value === "string" ? Date.parse(value) : Number.NaN;
|
|
7999
|
+
return Number.isFinite(parsed) && parsed > nowMs + 6e4 ? new Date(parsed).toISOString() : nextCopilotMonthlyReset(nowMs);
|
|
8000
|
+
}
|
|
8001
|
+
function parseCopilotQuota(body, nowMs = Date.now()) {
|
|
8002
|
+
const root = recordOf2(body);
|
|
8003
|
+
const snapshots = recordOf2(root?.quotaSnapshots);
|
|
8004
|
+
if (!snapshots) {
|
|
8005
|
+
throw new CopilotApiError("Copilot quota response missing quotaSnapshots", "parse");
|
|
8006
|
+
}
|
|
8007
|
+
const chat = recordOf2(snapshots.chat);
|
|
8008
|
+
const legacy = recordOf2(snapshots.premium_interactions);
|
|
8009
|
+
const chatLimit = numberOf4(chat?.entitlementRequests);
|
|
8010
|
+
const quota = chat && (chatLimit !== void 0 && chatLimit > 0 || chat.isUnlimitedEntitlement === true) ? chat : legacy;
|
|
8011
|
+
if (!quota) {
|
|
8012
|
+
throw new CopilotApiError("Copilot quota response has no chat allowance", "parse");
|
|
8013
|
+
}
|
|
8014
|
+
const unlimited = quota.isUnlimitedEntitlement === true;
|
|
8015
|
+
const remainingPercent = numberOf4(quota.remainingPercentage);
|
|
8016
|
+
const utilization = unlimited ? null : remainingPercent === void 0 ? null : clampPercent(100 - remainingPercent);
|
|
8017
|
+
const limit = numberOf4(quota.entitlementRequests) ?? null;
|
|
8018
|
+
const used = numberOf4(quota.usedRequests) ?? null;
|
|
8019
|
+
const unit = quota.tokenBasedBilling === true ? "ai-credits" : "premium-requests";
|
|
8020
|
+
return {
|
|
8021
|
+
captured_at: new Date(nowMs).toISOString(),
|
|
8022
|
+
agent: "copilot",
|
|
8023
|
+
five_hour: { utilization: null, resets_at: null },
|
|
8024
|
+
seven_day: { utilization: null, resets_at: null },
|
|
8025
|
+
monthly: {
|
|
8026
|
+
utilization,
|
|
8027
|
+
resets_at: quotaResetDate(quota.resetDate, nowMs)
|
|
8028
|
+
},
|
|
8029
|
+
monthly_quota: {
|
|
8030
|
+
used,
|
|
8031
|
+
limit,
|
|
8032
|
+
remaining: used !== null && limit !== null ? Math.max(0, limit - used) : null,
|
|
8033
|
+
unit,
|
|
8034
|
+
unlimited
|
|
8035
|
+
},
|
|
8036
|
+
seven_day_opus: null,
|
|
8037
|
+
seven_day_sonnet: null,
|
|
8038
|
+
seven_day_oauth_apps: null,
|
|
8039
|
+
seven_day_cowork: null,
|
|
8040
|
+
extra_usage: null,
|
|
8041
|
+
plan_type: unit === "ai-credits" ? "AI credits" : "premium requests"
|
|
8042
|
+
};
|
|
8043
|
+
}
|
|
8044
|
+
function rpcFrame(message) {
|
|
8045
|
+
const body = Buffer.from(JSON.stringify(message), "utf8");
|
|
8046
|
+
return Buffer.concat([
|
|
8047
|
+
Buffer.from(`Content-Length: ${body.length}\r
|
|
8048
|
+
\r
|
|
8049
|
+
`, "ascii"),
|
|
8050
|
+
body
|
|
8051
|
+
]);
|
|
8052
|
+
}
|
|
8053
|
+
function resolveCopilotCliPath() {
|
|
8054
|
+
const configured = process.env.COPILOT_CLI_PATH?.trim();
|
|
8055
|
+
if (configured) return configured;
|
|
8056
|
+
const sibling = join8(dirname8(process.execPath), process.platform === "win32" ? "copilot.cmd" : "copilot");
|
|
8057
|
+
return existsSync10(sibling) ? sibling : process.platform === "win32" ? "copilot.cmd" : "copilot";
|
|
8058
|
+
}
|
|
8059
|
+
async function requestQuota(child) {
|
|
8060
|
+
const decoder = new ContentLengthDecoder();
|
|
8061
|
+
const pending = /* @__PURE__ */ new Map();
|
|
8062
|
+
let nextId = 1;
|
|
8063
|
+
const rejectAll = (error) => {
|
|
8064
|
+
for (const waiter of pending.values()) waiter.reject(error);
|
|
8065
|
+
pending.clear();
|
|
8066
|
+
};
|
|
8067
|
+
child.stdout.on("data", (chunk2) => {
|
|
8068
|
+
try {
|
|
8069
|
+
for (const value of decoder.push(chunk2)) {
|
|
8070
|
+
const message = recordOf2(value);
|
|
8071
|
+
const id = numberOf4(message?.id);
|
|
8072
|
+
if (id === void 0) continue;
|
|
8073
|
+
const waiter = pending.get(id);
|
|
8074
|
+
if (!waiter) continue;
|
|
8075
|
+
pending.delete(id);
|
|
8076
|
+
const rpcError = recordOf2(message?.error);
|
|
8077
|
+
if (rpcError) {
|
|
8078
|
+
waiter.reject(new CopilotApiError(
|
|
8079
|
+
typeof rpcError.message === "string" ? rpcError.message : "Copilot RPC request failed",
|
|
8080
|
+
"protocol"
|
|
8081
|
+
));
|
|
8082
|
+
} else {
|
|
8083
|
+
waiter.resolve(message?.result);
|
|
8084
|
+
}
|
|
8085
|
+
}
|
|
8086
|
+
} catch (error) {
|
|
8087
|
+
rejectAll(error);
|
|
8088
|
+
}
|
|
8089
|
+
});
|
|
8090
|
+
const exited = new Promise((_, reject) => {
|
|
8091
|
+
child.once("error", (error) => {
|
|
8092
|
+
reject(new CopilotApiError(
|
|
8093
|
+
error.message,
|
|
8094
|
+
error.code === "ENOENT" ? "no_cli" : "protocol"
|
|
8095
|
+
));
|
|
8096
|
+
});
|
|
8097
|
+
child.once("exit", (code) => {
|
|
8098
|
+
reject(new CopilotApiError(`Copilot RPC exited before responding (code ${code ?? "unknown"})`, "protocol"));
|
|
8099
|
+
});
|
|
8100
|
+
});
|
|
8101
|
+
const request = (method, params = {}) => {
|
|
8102
|
+
const id = nextId++;
|
|
8103
|
+
const response = new Promise((resolve4, reject) => {
|
|
8104
|
+
pending.set(id, { resolve: resolve4, reject });
|
|
8105
|
+
child.stdin.write(rpcFrame({ jsonrpc: "2.0", id, method, params }));
|
|
8106
|
+
});
|
|
8107
|
+
return Promise.race([response, exited]);
|
|
8108
|
+
};
|
|
8109
|
+
await request("connect", {});
|
|
8110
|
+
return request("account.getQuota", {});
|
|
8111
|
+
}
|
|
8112
|
+
async function fetchCopilotUsage() {
|
|
8113
|
+
const cliPath = resolveCopilotCliPath();
|
|
8114
|
+
const child = spawn3(cliPath, ["--headless", "--no-auto-update", "--stdio", "--log-level", "none"], {
|
|
8115
|
+
cwd: process.cwd(),
|
|
8116
|
+
env: process.env,
|
|
8117
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
8118
|
+
windowsHide: true,
|
|
8119
|
+
shell: process.platform === "win32"
|
|
8120
|
+
});
|
|
8121
|
+
let stderr = "";
|
|
8122
|
+
child.stderr.on("data", (chunk2) => {
|
|
8123
|
+
stderr = (stderr + chunk2.toString("utf8")).slice(-2e3);
|
|
8124
|
+
});
|
|
8125
|
+
const timeout = new Promise((_, reject) => {
|
|
8126
|
+
const handle = setTimeout(() => {
|
|
8127
|
+
reject(new CopilotApiError("Timed out reading Copilot quota", "timeout"));
|
|
8128
|
+
}, RPC_TIMEOUT_MS);
|
|
8129
|
+
handle.unref();
|
|
8130
|
+
});
|
|
8131
|
+
try {
|
|
8132
|
+
const body = await Promise.race([requestQuota(child), timeout]);
|
|
8133
|
+
return parseCopilotQuota(body);
|
|
8134
|
+
} catch (error) {
|
|
8135
|
+
if (error instanceof CopilotApiError) {
|
|
8136
|
+
const message = `${error.message} ${stderr}`.toLowerCase();
|
|
8137
|
+
if (message.includes("not logged") || message.includes("authentication")) {
|
|
8138
|
+
throw new CopilotApiError("Copilot not logged in. Run `copilot login`.", "no_auth");
|
|
8139
|
+
}
|
|
8140
|
+
throw error;
|
|
8141
|
+
}
|
|
8142
|
+
throw new CopilotApiError(error.message, "protocol");
|
|
8143
|
+
} finally {
|
|
8144
|
+
child.kill();
|
|
8145
|
+
}
|
|
8146
|
+
}
|
|
8147
|
+
var RPC_TIMEOUT_MS, CopilotApiError, ContentLengthDecoder;
|
|
8148
|
+
var init_copilot2 = __esm({
|
|
8149
|
+
"src/usage/copilot.ts"() {
|
|
8150
|
+
"use strict";
|
|
8151
|
+
RPC_TIMEOUT_MS = 1e4;
|
|
8152
|
+
CopilotApiError = class extends Error {
|
|
8153
|
+
constructor(message, code) {
|
|
8154
|
+
super(message);
|
|
8155
|
+
this.code = code;
|
|
8156
|
+
}
|
|
8157
|
+
};
|
|
8158
|
+
ContentLengthDecoder = class {
|
|
8159
|
+
buffer = Buffer.alloc(0);
|
|
8160
|
+
push(chunk2) {
|
|
8161
|
+
this.buffer = Buffer.concat([this.buffer, chunk2]);
|
|
8162
|
+
const messages = [];
|
|
8163
|
+
while (true) {
|
|
8164
|
+
const headerEnd = this.buffer.indexOf("\r\n\r\n");
|
|
8165
|
+
if (headerEnd === -1) break;
|
|
8166
|
+
const header = this.buffer.subarray(0, headerEnd).toString("ascii");
|
|
8167
|
+
const match = header.match(/(?:^|\r\n)Content-Length:\s*(\d+)/i);
|
|
8168
|
+
if (!match) {
|
|
8169
|
+
throw new CopilotApiError("Copilot RPC response missing Content-Length", "protocol");
|
|
8170
|
+
}
|
|
8171
|
+
const length = Number(match[1]);
|
|
8172
|
+
const bodyStart = headerEnd + 4;
|
|
8173
|
+
if (this.buffer.length < bodyStart + length) break;
|
|
8174
|
+
const body = this.buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
|
|
8175
|
+
this.buffer = this.buffer.subarray(bodyStart + length);
|
|
8176
|
+
try {
|
|
8177
|
+
messages.push(JSON.parse(body));
|
|
8178
|
+
} catch {
|
|
8179
|
+
throw new CopilotApiError("Copilot RPC returned invalid JSON", "protocol");
|
|
8180
|
+
}
|
|
8181
|
+
}
|
|
8182
|
+
return messages;
|
|
8183
|
+
}
|
|
8184
|
+
};
|
|
8185
|
+
}
|
|
8186
|
+
});
|
|
8187
|
+
|
|
7262
8188
|
// src/usage/format.ts
|
|
7263
8189
|
function formatUsage(snapshot) {
|
|
7264
8190
|
const rows = [
|
|
@@ -7598,6 +8524,51 @@ var usage_exports = {};
|
|
|
7598
8524
|
__export(usage_exports, {
|
|
7599
8525
|
usage: () => usage
|
|
7600
8526
|
});
|
|
8527
|
+
async function saveAuxiliarySnapshots() {
|
|
8528
|
+
let saved = 0;
|
|
8529
|
+
for (const source of agentSources) {
|
|
8530
|
+
if (source.kind === "claude-code" || !source.usagePoller) continue;
|
|
8531
|
+
try {
|
|
8532
|
+
const partial = await source.usagePoller();
|
|
8533
|
+
if (!partial) continue;
|
|
8534
|
+
appendSnapshot(USAGE_LOG2, {
|
|
8535
|
+
...partial,
|
|
8536
|
+
seven_day_opus: null,
|
|
8537
|
+
seven_day_sonnet: null,
|
|
8538
|
+
seven_day_oauth_apps: null,
|
|
8539
|
+
seven_day_cowork: null,
|
|
8540
|
+
extra_usage: null
|
|
8541
|
+
});
|
|
8542
|
+
saved += 1;
|
|
8543
|
+
} catch {
|
|
8544
|
+
}
|
|
8545
|
+
}
|
|
8546
|
+
try {
|
|
8547
|
+
appendSnapshot(USAGE_LOG2, await fetchCodexUsage());
|
|
8548
|
+
saved += 1;
|
|
8549
|
+
} catch (err) {
|
|
8550
|
+
if (!(err instanceof CodexApiError) || err.code !== "no_auth" && err.code !== "api_key_only") {
|
|
8551
|
+
console.warn(`codex usage: ${err.message}`);
|
|
8552
|
+
}
|
|
8553
|
+
}
|
|
8554
|
+
try {
|
|
8555
|
+
appendSnapshot(USAGE_LOG2, await fetchCopilotUsage());
|
|
8556
|
+
saved += 1;
|
|
8557
|
+
} catch (err) {
|
|
8558
|
+
if (!(err instanceof CopilotApiError) || err.code !== "no_cli" && err.code !== "no_auth") {
|
|
8559
|
+
console.warn(`copilot usage: ${err.message}`);
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
try {
|
|
8563
|
+
appendSnapshot(USAGE_LOG2, await fetchGrokUsage());
|
|
8564
|
+
saved += 1;
|
|
8565
|
+
} catch (err) {
|
|
8566
|
+
if (!(err instanceof GrokApiError) || err.code !== "no_auth" && err.code !== "not_weekly") {
|
|
8567
|
+
console.warn(`grok usage: ${err.message}`);
|
|
8568
|
+
}
|
|
8569
|
+
}
|
|
8570
|
+
return saved;
|
|
8571
|
+
}
|
|
7601
8572
|
async function usage(args2) {
|
|
7602
8573
|
if (args2.includes("--help") || args2.includes("-h")) {
|
|
7603
8574
|
console.log(`fleetlens usage \u2014 plan utilization snapshot
|
|
@@ -7614,42 +8585,27 @@ Usage:
|
|
|
7614
8585
|
return;
|
|
7615
8586
|
}
|
|
7616
8587
|
const save = args2.includes("--save");
|
|
8588
|
+
let snapshot;
|
|
7617
8589
|
try {
|
|
7618
|
-
|
|
8590
|
+
snapshot = await fetchUsage();
|
|
7619
8591
|
if (save) appendSnapshot(USAGE_LOG2, snapshot);
|
|
7620
8592
|
process.stdout.write(formatUsage(snapshot));
|
|
7621
|
-
if (save) {
|
|
7622
|
-
for (const source of agentSources) {
|
|
7623
|
-
if (source.kind === "claude-code" || !source.usagePoller) continue;
|
|
7624
|
-
try {
|
|
7625
|
-
const partial = await source.usagePoller();
|
|
7626
|
-
if (!partial) continue;
|
|
7627
|
-
appendSnapshot(USAGE_LOG2, {
|
|
7628
|
-
...partial,
|
|
7629
|
-
seven_day_opus: null,
|
|
7630
|
-
seven_day_sonnet: null,
|
|
7631
|
-
seven_day_oauth_apps: null,
|
|
7632
|
-
seven_day_cowork: null,
|
|
7633
|
-
extra_usage: null
|
|
7634
|
-
});
|
|
7635
|
-
} catch {
|
|
7636
|
-
}
|
|
7637
|
-
}
|
|
7638
|
-
try {
|
|
7639
|
-
appendSnapshot(USAGE_LOG2, await fetchGrokUsage());
|
|
7640
|
-
} catch (err) {
|
|
7641
|
-
if (!(err instanceof GrokApiError && err.code === "no_auth")) {
|
|
7642
|
-
}
|
|
7643
|
-
}
|
|
7644
|
-
}
|
|
7645
|
-
process.stdout.write("\n (tip: run with --history for the daily token/cost table)\n");
|
|
7646
8593
|
} catch (err) {
|
|
7647
|
-
if (err instanceof UsageApiError) {
|
|
8594
|
+
if (!save || !(err instanceof UsageApiError)) {
|
|
8595
|
+
if (!(err instanceof UsageApiError)) throw err;
|
|
7648
8596
|
console.error(`Error: ${err.message}`);
|
|
7649
|
-
process.
|
|
8597
|
+
process.exitCode = 1;
|
|
8598
|
+
return;
|
|
7650
8599
|
}
|
|
7651
|
-
|
|
8600
|
+
const saved = await saveAuxiliarySnapshots();
|
|
8601
|
+
if (saved === 0) {
|
|
8602
|
+
console.error(`Error: ${err.message}`);
|
|
8603
|
+
process.exitCode = 1;
|
|
8604
|
+
}
|
|
8605
|
+
return;
|
|
7652
8606
|
}
|
|
8607
|
+
if (save) await saveAuxiliarySnapshots();
|
|
8608
|
+
process.stdout.write("\n (tip: run with --history for the daily token/cost table)\n");
|
|
7653
8609
|
}
|
|
7654
8610
|
var USAGE_LOG2;
|
|
7655
8611
|
var init_usage = __esm({
|
|
@@ -7657,6 +8613,8 @@ var init_usage = __esm({
|
|
|
7657
8613
|
"use strict";
|
|
7658
8614
|
init_api();
|
|
7659
8615
|
init_grok2();
|
|
8616
|
+
init_codex2();
|
|
8617
|
+
init_copilot2();
|
|
7660
8618
|
init_format();
|
|
7661
8619
|
init_storage();
|
|
7662
8620
|
init_fs();
|
|
@@ -8151,6 +9109,7 @@ __export(dist_exports, {
|
|
|
8151
9109
|
ANTIGRAVITY_METADATA: () => ANTIGRAVITY_METADATA,
|
|
8152
9110
|
CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
|
|
8153
9111
|
CODEX_METADATA: () => CODEX_METADATA,
|
|
9112
|
+
COPILOT_METADATA: () => COPILOT_METADATA,
|
|
8154
9113
|
COWORK_METADATA: () => COWORK_METADATA,
|
|
8155
9114
|
GEMINI_METADATA: () => GEMINI_METADATA,
|
|
8156
9115
|
GROK_METADATA: () => GROK_METADATA,
|
|
@@ -8567,7 +9526,7 @@ function closeTurn(t, closed, cwd) {
|
|
|
8567
9526
|
let active = 0;
|
|
8568
9527
|
for (let i = 1; i < ts.length; i++) {
|
|
8569
9528
|
const dt = ts[i] - ts[i - 1];
|
|
8570
|
-
if (dt <
|
|
9529
|
+
if (dt < IDLE_GAP_MS6)
|
|
8571
9530
|
active += dt;
|
|
8572
9531
|
}
|
|
8573
9532
|
closed.push({
|
|
@@ -8764,7 +9723,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
|
|
|
8764
9723
|
let activeMs2 = 0;
|
|
8765
9724
|
for (let i = 1; i < tsSorted.length; i++) {
|
|
8766
9725
|
const dt = tsSorted[i] - tsSorted[i - 1];
|
|
8767
|
-
if (dt <
|
|
9726
|
+
if (dt < IDLE_GAP_MS6)
|
|
8768
9727
|
activeMs2 += dt;
|
|
8769
9728
|
}
|
|
8770
9729
|
const tsSortedStrings = dayEvents.map((e) => e.timestamp).filter((t) => !!t).sort();
|
|
@@ -8951,7 +9910,7 @@ function buildEntries(sessionDetail) {
|
|
|
8951
9910
|
entries2.sort((a, b) => a.local_day.localeCompare(b.local_day));
|
|
8952
9911
|
return entries2;
|
|
8953
9912
|
}
|
|
8954
|
-
var
|
|
9913
|
+
var IDLE_GAP_MS6, INTERRUPT_RE2, PR_TITLE_RE, BASH_CHAIN_SPLIT_RE, SHELL_NOISE, IMAGE_BLOCK_RE;
|
|
8955
9914
|
var init_build = __esm({
|
|
8956
9915
|
"../entries/dist/build.js"() {
|
|
8957
9916
|
"use strict";
|
|
@@ -8959,7 +9918,7 @@ var init_build = __esm({
|
|
|
8959
9918
|
init_types();
|
|
8960
9919
|
init_signals();
|
|
8961
9920
|
init_trivial();
|
|
8962
|
-
|
|
9921
|
+
IDLE_GAP_MS6 = 3 * 60 * 1e3;
|
|
8963
9922
|
INTERRUPT_RE2 = /\[request interrupted|interrupted by user/i;
|
|
8964
9923
|
PR_TITLE_RE = /--title\s+["']([^"']+)["']/;
|
|
8965
9924
|
BASH_CHAIN_SPLIT_RE = /\|\||&&|;|\|/;
|
|
@@ -8988,11 +9947,11 @@ var init_dist2 = __esm({
|
|
|
8988
9947
|
});
|
|
8989
9948
|
|
|
8990
9949
|
// ../entries/dist/digest-fs.js
|
|
8991
|
-
import { readFileSync as
|
|
8992
|
-
import { dirname as
|
|
8993
|
-
function parseDigestFile(
|
|
9950
|
+
import { readFileSync as readFileSync13, readdirSync, writeFileSync as writeFileSync7, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync6, existsSync as existsSync11 } from "node:fs";
|
|
9951
|
+
import { dirname as dirname9, join as join9 } from "node:path";
|
|
9952
|
+
function parseDigestFile(path11, expectedVersion) {
|
|
8994
9953
|
try {
|
|
8995
|
-
const parsed = JSON.parse(
|
|
9954
|
+
const parsed = JSON.parse(readFileSync13(path11, "utf8"));
|
|
8996
9955
|
if (!parsed || typeof parsed !== "object")
|
|
8997
9956
|
return null;
|
|
8998
9957
|
if (parsed.version !== expectedVersion)
|
|
@@ -9011,26 +9970,26 @@ function digestsDir() {
|
|
|
9011
9970
|
digestsDirCached = envOverride ?? cclensPath("digests");
|
|
9012
9971
|
return digestsDirCached;
|
|
9013
9972
|
}
|
|
9014
|
-
function __setDigestsDirForTest(
|
|
9015
|
-
digestsDirCached =
|
|
9016
|
-
mkdirSync6(
|
|
9017
|
-
mkdirSync6(
|
|
9018
|
-
mkdirSync6(
|
|
9973
|
+
function __setDigestsDirForTest(path11) {
|
|
9974
|
+
digestsDirCached = path11;
|
|
9975
|
+
mkdirSync6(join9(path11, "day"), { recursive: true });
|
|
9976
|
+
mkdirSync6(join9(path11, "week"), { recursive: true });
|
|
9977
|
+
mkdirSync6(join9(path11, "month"), { recursive: true });
|
|
9019
9978
|
}
|
|
9020
9979
|
function dayDigestPath(date) {
|
|
9021
|
-
return
|
|
9980
|
+
return join9(digestsDir(), "day", `${date}.json`);
|
|
9022
9981
|
}
|
|
9023
9982
|
function weekDigestPath(monday) {
|
|
9024
|
-
return
|
|
9983
|
+
return join9(digestsDir(), "week", `${monday}.json`);
|
|
9025
9984
|
}
|
|
9026
9985
|
function monthDigestPath(yearMonth) {
|
|
9027
|
-
return
|
|
9986
|
+
return join9(digestsDir(), "month", `${yearMonth}.json`);
|
|
9028
9987
|
}
|
|
9029
9988
|
function writeDayDigest(digest2) {
|
|
9030
9989
|
const final = dayDigestPath(digest2.key);
|
|
9031
|
-
mkdirSync6(
|
|
9990
|
+
mkdirSync6(dirname9(final), { recursive: true });
|
|
9032
9991
|
const tmp = `${final}.tmp`;
|
|
9033
|
-
|
|
9992
|
+
writeFileSync7(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
9034
9993
|
if (process.platform !== "win32") {
|
|
9035
9994
|
try {
|
|
9036
9995
|
chmodSync(tmp, 384);
|
|
@@ -9041,7 +10000,7 @@ function writeDayDigest(digest2) {
|
|
|
9041
10000
|
}
|
|
9042
10001
|
function readDayDigest(date) {
|
|
9043
10002
|
const p = dayDigestPath(date);
|
|
9044
|
-
if (!
|
|
10003
|
+
if (!existsSync11(p))
|
|
9045
10004
|
return null;
|
|
9046
10005
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
9047
10006
|
}
|
|
@@ -9064,9 +10023,9 @@ function __clearTodayCacheForTest() {
|
|
|
9064
10023
|
}
|
|
9065
10024
|
function writeWeekDigest(digest2) {
|
|
9066
10025
|
const final = weekDigestPath(digest2.key);
|
|
9067
|
-
mkdirSync6(
|
|
10026
|
+
mkdirSync6(dirname9(final), { recursive: true });
|
|
9068
10027
|
const tmp = `${final}.tmp`;
|
|
9069
|
-
|
|
10028
|
+
writeFileSync7(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
9070
10029
|
if (process.platform !== "win32") {
|
|
9071
10030
|
try {
|
|
9072
10031
|
chmodSync(tmp, 384);
|
|
@@ -9077,13 +10036,13 @@ function writeWeekDigest(digest2) {
|
|
|
9077
10036
|
}
|
|
9078
10037
|
function readWeekDigest(monday) {
|
|
9079
10038
|
const p = weekDigestPath(monday);
|
|
9080
|
-
if (!
|
|
10039
|
+
if (!existsSync11(p))
|
|
9081
10040
|
return null;
|
|
9082
10041
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
9083
10042
|
}
|
|
9084
10043
|
function listWeekDigestKeys() {
|
|
9085
|
-
const dir =
|
|
9086
|
-
if (!
|
|
10044
|
+
const dir = join9(digestsDir(), "week");
|
|
10045
|
+
if (!existsSync11(dir))
|
|
9087
10046
|
return [];
|
|
9088
10047
|
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));
|
|
9089
10048
|
}
|
|
@@ -9101,9 +10060,9 @@ function setCurrentWeekDigestInCache(monday, digest2, nowMs) {
|
|
|
9101
10060
|
}
|
|
9102
10061
|
function writeMonthDigest(digest2) {
|
|
9103
10062
|
const final = monthDigestPath(digest2.key);
|
|
9104
|
-
mkdirSync6(
|
|
10063
|
+
mkdirSync6(dirname9(final), { recursive: true });
|
|
9105
10064
|
const tmp = `${final}.tmp`;
|
|
9106
|
-
|
|
10065
|
+
writeFileSync7(tmp, JSON.stringify(digest2, null, 2), "utf8");
|
|
9107
10066
|
if (process.platform !== "win32") {
|
|
9108
10067
|
try {
|
|
9109
10068
|
chmodSync(tmp, 384);
|
|
@@ -9114,13 +10073,13 @@ function writeMonthDigest(digest2) {
|
|
|
9114
10073
|
}
|
|
9115
10074
|
function readMonthDigest(yearMonth) {
|
|
9116
10075
|
const p = monthDigestPath(yearMonth);
|
|
9117
|
-
if (!
|
|
10076
|
+
if (!existsSync11(p))
|
|
9118
10077
|
return null;
|
|
9119
10078
|
return parseDigestFile(p, CURRENT_MONTH_DIGEST_SCHEMA_VERSION);
|
|
9120
10079
|
}
|
|
9121
10080
|
function listMonthDigestKeys() {
|
|
9122
|
-
const dir =
|
|
9123
|
-
if (!
|
|
10081
|
+
const dir = join9(digestsDir(), "month");
|
|
10082
|
+
if (!existsSync11(dir))
|
|
9124
10083
|
return [];
|
|
9125
10084
|
return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}$/.test(k));
|
|
9126
10085
|
}
|
|
@@ -9182,9 +10141,9 @@ __export(fs_exports2, {
|
|
|
9182
10141
|
writeMonthDigest: () => writeMonthDigest,
|
|
9183
10142
|
writeWeekDigest: () => writeWeekDigest
|
|
9184
10143
|
});
|
|
9185
|
-
import { readFileSync as
|
|
10144
|
+
import { readFileSync as readFileSync14, readdirSync as readdirSync2, writeFileSync as writeFileSync8, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync12 } from "node:fs";
|
|
9186
10145
|
import { randomBytes } from "node:crypto";
|
|
9187
|
-
import { join as
|
|
10146
|
+
import { join as join10 } from "node:path";
|
|
9188
10147
|
function entriesDir() {
|
|
9189
10148
|
if (entriesDirCached)
|
|
9190
10149
|
return entriesDirCached;
|
|
@@ -9192,12 +10151,12 @@ function entriesDir() {
|
|
|
9192
10151
|
entriesDirCached = envOverride ?? cclensPath("entries");
|
|
9193
10152
|
return entriesDirCached;
|
|
9194
10153
|
}
|
|
9195
|
-
function __setEntriesDirForTest(
|
|
9196
|
-
entriesDirCached =
|
|
9197
|
-
mkdirSync7(
|
|
10154
|
+
function __setEntriesDirForTest(path11) {
|
|
10155
|
+
entriesDirCached = path11;
|
|
10156
|
+
mkdirSync7(path11, { recursive: true });
|
|
9198
10157
|
}
|
|
9199
10158
|
function pathFor(sessionId, localDay2) {
|
|
9200
|
-
return
|
|
10159
|
+
return join10(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
9201
10160
|
}
|
|
9202
10161
|
function tmpPathFor(final) {
|
|
9203
10162
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
@@ -9208,7 +10167,7 @@ function writeEntry(entry) {
|
|
|
9208
10167
|
const final = pathFor(entry.session_id, entry.local_day);
|
|
9209
10168
|
const tmp = tmpPathFor(final);
|
|
9210
10169
|
const json = JSON.stringify(entry, null, 2);
|
|
9211
|
-
|
|
10170
|
+
writeFileSync8(tmp, json, { encoding: "utf8" });
|
|
9212
10171
|
renameSync3(tmp, final);
|
|
9213
10172
|
}
|
|
9214
10173
|
function enrichmentInputHash(e) {
|
|
@@ -9236,22 +10195,22 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
9236
10195
|
toWrite = { ...fresh, enrichment: existing.enrichment };
|
|
9237
10196
|
}
|
|
9238
10197
|
const tmp = tmpPathFor(final);
|
|
9239
|
-
|
|
10198
|
+
writeFileSync8(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
|
|
9240
10199
|
renameSync3(tmp, final);
|
|
9241
10200
|
}
|
|
9242
10201
|
function readEntry(sessionId, localDay2) {
|
|
9243
10202
|
const p = pathFor(sessionId, localDay2);
|
|
9244
|
-
if (!
|
|
10203
|
+
if (!existsSync12(p))
|
|
9245
10204
|
return null;
|
|
9246
|
-
const raw =
|
|
10205
|
+
const raw = readFileSync14(p, "utf8");
|
|
9247
10206
|
return JSON.parse(raw);
|
|
9248
10207
|
}
|
|
9249
10208
|
function entryExists(sessionId, localDay2) {
|
|
9250
|
-
return
|
|
10209
|
+
return existsSync12(pathFor(sessionId, localDay2));
|
|
9251
10210
|
}
|
|
9252
10211
|
function listEntryKeys() {
|
|
9253
10212
|
const dir = entriesDir();
|
|
9254
|
-
if (!
|
|
10213
|
+
if (!existsSync12(dir))
|
|
9255
10214
|
return [];
|
|
9256
10215
|
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
9257
10216
|
}
|
|
@@ -9733,8 +10692,8 @@ var init_parseUtil = __esm({
|
|
|
9733
10692
|
init_errors();
|
|
9734
10693
|
init_en();
|
|
9735
10694
|
makeIssue = (params) => {
|
|
9736
|
-
const { data, path:
|
|
9737
|
-
const fullPath = [...
|
|
10695
|
+
const { data, path: path11, errorMaps, issueData } = params;
|
|
10696
|
+
const fullPath = [...path11, ...issueData.path || []];
|
|
9738
10697
|
const fullIssue = {
|
|
9739
10698
|
...issueData,
|
|
9740
10699
|
path: fullPath
|
|
@@ -10042,11 +11001,11 @@ var init_types3 = __esm({
|
|
|
10042
11001
|
init_parseUtil();
|
|
10043
11002
|
init_util();
|
|
10044
11003
|
ParseInputLazyPath = class {
|
|
10045
|
-
constructor(parent, value,
|
|
11004
|
+
constructor(parent, value, path11, key) {
|
|
10046
11005
|
this._cachedPath = [];
|
|
10047
11006
|
this.parent = parent;
|
|
10048
11007
|
this.data = value;
|
|
10049
|
-
this._path =
|
|
11008
|
+
this._path = path11;
|
|
10050
11009
|
this._key = key;
|
|
10051
11010
|
}
|
|
10052
11011
|
get path() {
|
|
@@ -13530,8 +14489,8 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
|
|
|
13530
14489
|
});
|
|
13531
14490
|
|
|
13532
14491
|
// ../entries/dist/tmux-runner.js
|
|
13533
|
-
import { mkdirSync as mkdirSync8, writeFileSync as
|
|
13534
|
-
import { join as
|
|
14492
|
+
import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, existsSync as existsSync13, readdirSync as readdirSync3, realpathSync as realpathSync5, readFileSync as readFileSync15, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
|
|
14493
|
+
import { join as join11 } from "node:path";
|
|
13535
14494
|
import { homedir as homedir5 } from "node:os";
|
|
13536
14495
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
13537
14496
|
function which(bin) {
|
|
@@ -13548,16 +14507,16 @@ function tmuxRunnerAvailable() {
|
|
|
13548
14507
|
return { ok: true };
|
|
13549
14508
|
}
|
|
13550
14509
|
function runtimeCwd() {
|
|
13551
|
-
const dir =
|
|
13552
|
-
if (!
|
|
14510
|
+
const dir = join11(homedir5(), ".cclens", "runtime");
|
|
14511
|
+
if (!existsSync13(dir))
|
|
13553
14512
|
mkdirSync8(dir, { recursive: true });
|
|
13554
14513
|
return realpathSync5(dir);
|
|
13555
14514
|
}
|
|
13556
14515
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
13557
|
-
const cfgPath =
|
|
14516
|
+
const cfgPath = join11(homedir5(), ".claude.json");
|
|
13558
14517
|
let cfg;
|
|
13559
14518
|
try {
|
|
13560
|
-
cfg = JSON.parse(
|
|
14519
|
+
cfg = JSON.parse(readFileSync15(cfgPath, "utf8"));
|
|
13561
14520
|
} catch {
|
|
13562
14521
|
return;
|
|
13563
14522
|
}
|
|
@@ -13572,7 +14531,7 @@ function ensureRuntimeCwdTrusted(cwd) {
|
|
|
13572
14531
|
cfg.projects = projects;
|
|
13573
14532
|
const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
|
|
13574
14533
|
try {
|
|
13575
|
-
|
|
14534
|
+
writeFileSync9(tmp, JSON.stringify(cfg, null, 2));
|
|
13576
14535
|
renameSync4(tmp, cfgPath);
|
|
13577
14536
|
} catch {
|
|
13578
14537
|
try {
|
|
@@ -13599,16 +14558,16 @@ async function runClaudeUnderTmuxImpl(args2) {
|
|
|
13599
14558
|
ensureRuntimeCwdTrusted(cwd);
|
|
13600
14559
|
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
13601
14560
|
const sessionName = `cclens-${runId}`;
|
|
13602
|
-
const systemFile =
|
|
13603
|
-
const userFile =
|
|
13604
|
-
const wrapper =
|
|
13605
|
-
|
|
13606
|
-
|
|
14561
|
+
const systemFile = join11(cwd, `system-${runId}.txt`);
|
|
14562
|
+
const userFile = join11(cwd, `user-${runId}.txt`);
|
|
14563
|
+
const wrapper = join11(cwd, `run-${runId}.sh`);
|
|
14564
|
+
writeFileSync9(systemFile, args2.systemPrompt);
|
|
14565
|
+
writeFileSync9(userFile, args2.reminder ? `${args2.userPrompt}
|
|
13607
14566
|
|
|
13608
14567
|
---
|
|
13609
14568
|
|
|
13610
14569
|
${args2.reminder}` : args2.userPrompt);
|
|
13611
|
-
|
|
14570
|
+
writeFileSync9(wrapper, `#!/bin/bash
|
|
13612
14571
|
SYS="$(cat ${shellEscape(systemFile)})"
|
|
13613
14572
|
USR="$(cat ${shellEscape(userFile)})"
|
|
13614
14573
|
exec ${shellEscape(claudeBin)} \\
|
|
@@ -13620,10 +14579,10 @@ exec ${shellEscape(claudeBin)} \\
|
|
|
13620
14579
|
"$USR"
|
|
13621
14580
|
`, { mode: 493 });
|
|
13622
14581
|
const existingBefore = snapshotAllTranscripts();
|
|
13623
|
-
const
|
|
13624
|
-
if (
|
|
14582
|
+
const spawn5 = spawnSync2(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
|
|
14583
|
+
if (spawn5.status !== 0) {
|
|
13625
14584
|
cleanup(cwd, runId, tmuxBin, sessionName);
|
|
13626
|
-
throw new TmuxRunError(`tmux new-session failed: ${
|
|
14585
|
+
throw new TmuxRunError(`tmux new-session failed: ${spawn5.stderr.trim()}`);
|
|
13627
14586
|
}
|
|
13628
14587
|
const onAbort = () => {
|
|
13629
14588
|
try {
|
|
@@ -13690,7 +14649,7 @@ function snapshotAllTranscripts() {
|
|
|
13690
14649
|
return out;
|
|
13691
14650
|
}
|
|
13692
14651
|
for (const sub of subs) {
|
|
13693
|
-
const dir =
|
|
14652
|
+
const dir = join11(root, sub);
|
|
13694
14653
|
let files;
|
|
13695
14654
|
try {
|
|
13696
14655
|
files = readdirSync3(dir);
|
|
@@ -13699,15 +14658,15 @@ function snapshotAllTranscripts() {
|
|
|
13699
14658
|
}
|
|
13700
14659
|
for (const f of files) {
|
|
13701
14660
|
if (f.endsWith(".jsonl"))
|
|
13702
|
-
out.add(
|
|
14661
|
+
out.add(join11(dir, f));
|
|
13703
14662
|
}
|
|
13704
14663
|
}
|
|
13705
14664
|
return out;
|
|
13706
14665
|
}
|
|
13707
|
-
function readJsonlCwd(
|
|
14666
|
+
function readJsonlCwd(path11, maxLines = 8) {
|
|
13708
14667
|
let raw;
|
|
13709
14668
|
try {
|
|
13710
|
-
raw =
|
|
14669
|
+
raw = readFileSync15(path11, "utf8");
|
|
13711
14670
|
} catch {
|
|
13712
14671
|
return void 0;
|
|
13713
14672
|
}
|
|
@@ -13740,7 +14699,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
13740
14699
|
subs = [];
|
|
13741
14700
|
}
|
|
13742
14701
|
for (const sub of subs) {
|
|
13743
|
-
const dir =
|
|
14702
|
+
const dir = join11(root, sub);
|
|
13744
14703
|
let files;
|
|
13745
14704
|
try {
|
|
13746
14705
|
files = readdirSync3(dir);
|
|
@@ -13750,7 +14709,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
13750
14709
|
for (const f of files) {
|
|
13751
14710
|
if (!f.endsWith(".jsonl"))
|
|
13752
14711
|
continue;
|
|
13753
|
-
const full =
|
|
14712
|
+
const full = join11(dir, f);
|
|
13754
14713
|
if (existingBefore.has(full))
|
|
13755
14714
|
continue;
|
|
13756
14715
|
if (readJsonlCwd(full) === targetCwd)
|
|
@@ -13761,10 +14720,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
13761
14720
|
}
|
|
13762
14721
|
throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
|
|
13763
14722
|
}
|
|
13764
|
-
function parseTranscript2(
|
|
14723
|
+
function parseTranscript2(path11, defaultModel) {
|
|
13765
14724
|
let raw;
|
|
13766
14725
|
try {
|
|
13767
|
-
raw =
|
|
14726
|
+
raw = readFileSync15(path11, "utf8");
|
|
13768
14727
|
} catch {
|
|
13769
14728
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
13770
14729
|
}
|
|
@@ -13824,7 +14783,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
|
|
|
13824
14783
|
}
|
|
13825
14784
|
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
13826
14785
|
try {
|
|
13827
|
-
unlinkSync3(
|
|
14786
|
+
unlinkSync3(join11(cwd, f));
|
|
13828
14787
|
} catch {
|
|
13829
14788
|
}
|
|
13830
14789
|
}
|
|
@@ -13852,17 +14811,17 @@ var init_tmux_runner = __esm({
|
|
|
13852
14811
|
}
|
|
13853
14812
|
};
|
|
13854
14813
|
mutex = Promise.resolve();
|
|
13855
|
-
PROJECTS_ROOT = () =>
|
|
14814
|
+
PROJECTS_ROOT = () => join11(homedir5(), ".claude", "projects");
|
|
13856
14815
|
}
|
|
13857
14816
|
});
|
|
13858
14817
|
|
|
13859
14818
|
// ../entries/dist/llm-runner.js
|
|
13860
|
-
import { spawn as
|
|
13861
|
-
import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as
|
|
13862
|
-
import { join as
|
|
14819
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
14820
|
+
import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync10, existsSync as existsSync14 } from "node:fs";
|
|
14821
|
+
import { join as join12 } from "node:path";
|
|
13863
14822
|
import { randomUUID } from "node:crypto";
|
|
13864
14823
|
function ensureRunsDir() {
|
|
13865
|
-
if (!
|
|
14824
|
+
if (!existsSync14(RUNS_DIR)) {
|
|
13866
14825
|
try {
|
|
13867
14826
|
mkdirSync9(RUNS_DIR, { recursive: true });
|
|
13868
14827
|
} catch {
|
|
@@ -13891,17 +14850,17 @@ function newRunId(kind) {
|
|
|
13891
14850
|
return `${ts}_${kind}_${short}`;
|
|
13892
14851
|
}
|
|
13893
14852
|
function tracePath(runId) {
|
|
13894
|
-
return
|
|
14853
|
+
return join12(RUNS_DIR, `${runId}.jsonl`);
|
|
13895
14854
|
}
|
|
13896
|
-
function safeAppend(
|
|
14855
|
+
function safeAppend(path11, line) {
|
|
13897
14856
|
try {
|
|
13898
|
-
appendFileSync3(
|
|
14857
|
+
appendFileSync3(path11, line);
|
|
13899
14858
|
} catch {
|
|
13900
14859
|
}
|
|
13901
14860
|
}
|
|
13902
|
-
function safeWrite(
|
|
14861
|
+
function safeWrite(path11, line) {
|
|
13903
14862
|
try {
|
|
13904
|
-
|
|
14863
|
+
writeFileSync10(path11, line);
|
|
13905
14864
|
} catch {
|
|
13906
14865
|
}
|
|
13907
14866
|
}
|
|
@@ -14034,7 +14993,7 @@ function runClaudePrintMode(args2) {
|
|
|
14034
14993
|
"--append-system-prompt",
|
|
14035
14994
|
args2.systemPrompt
|
|
14036
14995
|
];
|
|
14037
|
-
const proc =
|
|
14996
|
+
const proc = spawn4("claude", claudeArgs, { stdio: ["pipe", "pipe", "pipe"], env: { ...process.env } });
|
|
14038
14997
|
safeAppend(trace, JSON.stringify({ _meta: { type: "spawned", run_id: runId, pid: proc.pid } }) + "\n");
|
|
14039
14998
|
const stdinPayload = args2.reminder ? `${args2.userPrompt}
|
|
14040
14999
|
|
|
@@ -14307,30 +15266,30 @@ var init_enrich2 = __esm({
|
|
|
14307
15266
|
});
|
|
14308
15267
|
|
|
14309
15268
|
// ../entries/dist/budget.js
|
|
14310
|
-
import { appendFileSync as appendFileSync4, readFileSync as
|
|
14311
|
-
import { dirname as
|
|
15269
|
+
import { appendFileSync as appendFileSync4, readFileSync as readFileSync16, existsSync as existsSync15, mkdirSync as mkdirSync10 } from "node:fs";
|
|
15270
|
+
import { dirname as dirname10 } from "node:path";
|
|
14312
15271
|
function spendPath() {
|
|
14313
15272
|
if (spendPathCached)
|
|
14314
15273
|
return spendPathCached;
|
|
14315
15274
|
spendPathCached = cclensPath("llm-spend.jsonl");
|
|
14316
15275
|
return spendPathCached;
|
|
14317
15276
|
}
|
|
14318
|
-
function __setSpendPathForTest(
|
|
14319
|
-
spendPathCached =
|
|
15277
|
+
function __setSpendPathForTest(path11) {
|
|
15278
|
+
spendPathCached = path11;
|
|
14320
15279
|
}
|
|
14321
15280
|
function appendSpend(record) {
|
|
14322
15281
|
const p = spendPath();
|
|
14323
|
-
mkdirSync10(
|
|
15282
|
+
mkdirSync10(dirname10(p), { recursive: true });
|
|
14324
15283
|
appendFileSync4(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
14325
15284
|
}
|
|
14326
15285
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
14327
15286
|
const p = spendPath();
|
|
14328
|
-
if (!
|
|
15287
|
+
if (!existsSync15(p))
|
|
14329
15288
|
return 0;
|
|
14330
15289
|
const year = now.getUTCFullYear();
|
|
14331
15290
|
const month2 = now.getUTCMonth();
|
|
14332
15291
|
let total = 0;
|
|
14333
|
-
const raw =
|
|
15292
|
+
const raw = readFileSync16(p, "utf8");
|
|
14334
15293
|
for (const line of raw.split("\n")) {
|
|
14335
15294
|
if (!line)
|
|
14336
15295
|
continue;
|
|
@@ -14359,18 +15318,18 @@ var init_budget = __esm({
|
|
|
14359
15318
|
});
|
|
14360
15319
|
|
|
14361
15320
|
// ../entries/dist/pipeline-lock.js
|
|
14362
|
-
import { writeFileSync as
|
|
15321
|
+
import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync4, existsSync as existsSync16, readFileSync as readFileSync17, statSync as statSync3 } from "node:fs";
|
|
14363
15322
|
function lockPath() {
|
|
14364
15323
|
if (lockPathCached)
|
|
14365
15324
|
return lockPathCached;
|
|
14366
15325
|
lockPathCached = cclensPath("llm-interactive.lock");
|
|
14367
15326
|
return lockPathCached;
|
|
14368
15327
|
}
|
|
14369
|
-
function __setInteractiveLockPathForTest(
|
|
14370
|
-
lockPathCached =
|
|
15328
|
+
function __setInteractiveLockPathForTest(path11) {
|
|
15329
|
+
lockPathCached = path11;
|
|
14371
15330
|
}
|
|
14372
15331
|
function touchLock() {
|
|
14373
|
-
|
|
15332
|
+
writeFileSync11(lockPath(), String(process.pid), "utf8");
|
|
14374
15333
|
}
|
|
14375
15334
|
function writeInteractiveLock() {
|
|
14376
15335
|
touchLock();
|
|
@@ -14404,13 +15363,13 @@ function pidAlive(pid) {
|
|
|
14404
15363
|
}
|
|
14405
15364
|
function interactiveLockFresh(nowMs) {
|
|
14406
15365
|
const p = lockPath();
|
|
14407
|
-
if (!
|
|
15366
|
+
if (!existsSync16(p))
|
|
14408
15367
|
return false;
|
|
14409
15368
|
try {
|
|
14410
15369
|
const mtime = statSync3(p).mtimeMs;
|
|
14411
15370
|
if (nowMs - mtime > STALE_MS)
|
|
14412
15371
|
return false;
|
|
14413
|
-
const pid = Number(
|
|
15372
|
+
const pid = Number(readFileSync17(p, "utf8").trim());
|
|
14414
15373
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
14415
15374
|
return false;
|
|
14416
15375
|
if (!pidAlive(pid))
|
|
@@ -14516,16 +15475,16 @@ var init_queue = __esm({
|
|
|
14516
15475
|
});
|
|
14517
15476
|
|
|
14518
15477
|
// ../entries/dist/settings.js
|
|
14519
|
-
import { readFileSync as
|
|
14520
|
-
import { dirname as
|
|
15478
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync17 } from "node:fs";
|
|
15479
|
+
import { dirname as dirname11 } from "node:path";
|
|
14521
15480
|
function settingsPath() {
|
|
14522
15481
|
if (settingsPathCached)
|
|
14523
15482
|
return settingsPathCached;
|
|
14524
15483
|
settingsPathCached = cclensPath("settings.json");
|
|
14525
15484
|
return settingsPathCached;
|
|
14526
15485
|
}
|
|
14527
|
-
function __setSettingsPathForTest(
|
|
14528
|
-
settingsPathCached =
|
|
15486
|
+
function __setSettingsPathForTest(path11) {
|
|
15487
|
+
settingsPathCached = path11;
|
|
14529
15488
|
}
|
|
14530
15489
|
function toDisk(s) {
|
|
14531
15490
|
return {
|
|
@@ -14552,10 +15511,10 @@ function fromDisk(d) {
|
|
|
14552
15511
|
}
|
|
14553
15512
|
function readSettings() {
|
|
14554
15513
|
const p = settingsPath();
|
|
14555
|
-
if (!
|
|
15514
|
+
if (!existsSync17(p))
|
|
14556
15515
|
return DEFAULT_SETTINGS;
|
|
14557
15516
|
try {
|
|
14558
|
-
const raw =
|
|
15517
|
+
const raw = readFileSync18(p, "utf8");
|
|
14559
15518
|
return fromDisk(JSON.parse(raw));
|
|
14560
15519
|
} catch {
|
|
14561
15520
|
return DEFAULT_SETTINGS;
|
|
@@ -14563,9 +15522,9 @@ function readSettings() {
|
|
|
14563
15522
|
}
|
|
14564
15523
|
function writeSettings(s) {
|
|
14565
15524
|
const p = settingsPath();
|
|
14566
|
-
mkdirSync11(
|
|
15525
|
+
mkdirSync11(dirname11(p), { recursive: true });
|
|
14567
15526
|
const tmp = `${p}.tmp`;
|
|
14568
|
-
|
|
15527
|
+
writeFileSync12(tmp, JSON.stringify(toDisk(s), null, 2), { encoding: "utf8" });
|
|
14569
15528
|
if (process.platform !== "win32") {
|
|
14570
15529
|
chmodSync2(tmp, 384);
|
|
14571
15530
|
}
|
|
@@ -16628,7 +17587,7 @@ function activeMs(timestamps) {
|
|
|
16628
17587
|
let active = 0;
|
|
16629
17588
|
for (let i = 1; i < ts.length; i++) {
|
|
16630
17589
|
const dt = ts[i] - ts[i - 1];
|
|
16631
|
-
if (dt <
|
|
17590
|
+
if (dt < IDLE_GAP_MS7)
|
|
16632
17591
|
active += dt;
|
|
16633
17592
|
}
|
|
16634
17593
|
return active;
|
|
@@ -16799,7 +17758,7 @@ function buildSessionSlice(entry, events, daySignature) {
|
|
|
16799
17758
|
let intEnd = sortedTs[0];
|
|
16800
17759
|
for (let i = 1; i < sortedTs.length; i++) {
|
|
16801
17760
|
const dt = sortedTs[i] - intEnd;
|
|
16802
|
-
if (dt >=
|
|
17761
|
+
if (dt >= IDLE_GAP_MS7) {
|
|
16803
17762
|
intervals.push({
|
|
16804
17763
|
start_min: fmtMin(intStart - sliceStartMs),
|
|
16805
17764
|
end_min: fmtMin(intEnd - sliceStartMs)
|
|
@@ -17196,14 +18155,14 @@ async function generateTopSession(slice, opts = {}) {
|
|
|
17196
18155
|
void lastModel;
|
|
17197
18156
|
}
|
|
17198
18157
|
}
|
|
17199
|
-
var
|
|
18158
|
+
var IDLE_GAP_MS7, LONG_AUTONOMOUS_MIN, N_USER, N_FIRST_AGENT, N_LAST_AGENT, N_USER_TURN1, N_SUBAGENT, SHELL_NOISE2, INTERRUPT_RE3, PR_TITLE_RE2, PinResponseSchema, TopSessionResponseSchema, SYSTEM_PROMPT5, TOP_SESSION_SYSTEM_PROMPT, DEFAULT_MODEL5, defaultCallLLMTopSession, validateTopSession;
|
|
17200
18159
|
var init_top_sessions = __esm({
|
|
17201
18160
|
"../entries/dist/top-sessions.js"() {
|
|
17202
18161
|
"use strict";
|
|
17203
18162
|
init_zod();
|
|
17204
18163
|
init_signals();
|
|
17205
18164
|
init_llm_runner();
|
|
17206
|
-
|
|
18165
|
+
IDLE_GAP_MS7 = 3 * 60 * 1e3;
|
|
17207
18166
|
LONG_AUTONOMOUS_MIN = 20;
|
|
17208
18167
|
N_USER = 150;
|
|
17209
18168
|
N_FIRST_AGENT = 150;
|
|
@@ -17745,8 +18704,8 @@ var init_digest_month_pipeline = __esm({
|
|
|
17745
18704
|
});
|
|
17746
18705
|
|
|
17747
18706
|
// ../entries/dist/credentials.js
|
|
17748
|
-
import { writeFileSync as
|
|
17749
|
-
import { dirname as
|
|
18707
|
+
import { writeFileSync as writeFileSync13, readFileSync as readFileSync19, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync18, unlinkSync as unlinkSync5 } from "node:fs";
|
|
18708
|
+
import { dirname as dirname12 } from "node:path";
|
|
17750
18709
|
async function fetchZaiUsage(candidate) {
|
|
17751
18710
|
const key = candidate.trim();
|
|
17752
18711
|
if (!key)
|
|
@@ -17816,10 +18775,10 @@ function credentialsPath() {
|
|
|
17816
18775
|
}
|
|
17817
18776
|
function readCredentials() {
|
|
17818
18777
|
const p = credentialsPath();
|
|
17819
|
-
if (!
|
|
18778
|
+
if (!existsSync18(p))
|
|
17820
18779
|
return {};
|
|
17821
18780
|
try {
|
|
17822
|
-
const raw =
|
|
18781
|
+
const raw = readFileSync19(p, "utf8");
|
|
17823
18782
|
return JSON.parse(raw);
|
|
17824
18783
|
} catch {
|
|
17825
18784
|
return {};
|
|
@@ -17842,9 +18801,9 @@ function writeZaiKey(apiKey) {
|
|
|
17842
18801
|
const store = readCredentials();
|
|
17843
18802
|
store.zai = { ...store.zai ?? {}, apiKey };
|
|
17844
18803
|
const p = credentialsPath();
|
|
17845
|
-
mkdirSync12(
|
|
18804
|
+
mkdirSync12(dirname12(p), { recursive: true });
|
|
17846
18805
|
const tmp = `${p}.tmp`;
|
|
17847
|
-
|
|
18806
|
+
writeFileSync13(tmp, JSON.stringify(store, null, 2), { encoding: "utf8" });
|
|
17848
18807
|
if (process.platform !== "win32") {
|
|
17849
18808
|
chmodSync3(tmp, 384);
|
|
17850
18809
|
}
|
|
@@ -17862,7 +18821,7 @@ function deleteZaiKey() {
|
|
|
17862
18821
|
return;
|
|
17863
18822
|
}
|
|
17864
18823
|
const tmp = `${p}.tmp`;
|
|
17865
|
-
|
|
18824
|
+
writeFileSync13(tmp, JSON.stringify(store, null, 2), { encoding: "utf8" });
|
|
17866
18825
|
if (process.platform !== "win32") {
|
|
17867
18826
|
chmodSync3(tmp, 384);
|
|
17868
18827
|
}
|
|
@@ -18449,9 +19408,9 @@ var menubar_exports = {};
|
|
|
18449
19408
|
__export(menubar_exports, {
|
|
18450
19409
|
menubar: () => menubar
|
|
18451
19410
|
});
|
|
18452
|
-
import { existsSync as
|
|
19411
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync4, writeFileSync as writeFileSync14, realpathSync as realpathSync6 } from "node:fs";
|
|
18453
19412
|
import { homedir as homedir6 } from "node:os";
|
|
18454
|
-
import { join as
|
|
19413
|
+
import { join as join13, dirname as dirname13 } from "node:path";
|
|
18455
19414
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
18456
19415
|
import { execFile as execFile2 } from "node:child_process";
|
|
18457
19416
|
import { promisify as promisify2 } from "node:util";
|
|
@@ -18459,8 +19418,8 @@ function isMac2() {
|
|
|
18459
19418
|
return process.platform === "darwin";
|
|
18460
19419
|
}
|
|
18461
19420
|
function bundledAppPath() {
|
|
18462
|
-
const here =
|
|
18463
|
-
return
|
|
19421
|
+
const here = dirname13(fileURLToPath3(import.meta.url));
|
|
19422
|
+
return join13(here, "..", "menubar", APP_BUNDLE);
|
|
18464
19423
|
}
|
|
18465
19424
|
function resolveScriptPath2() {
|
|
18466
19425
|
const argv1 = process.argv[1] ?? "";
|
|
@@ -18472,7 +19431,7 @@ function resolveScriptPath2() {
|
|
|
18472
19431
|
}
|
|
18473
19432
|
function writeCliLaunchFile() {
|
|
18474
19433
|
try {
|
|
18475
|
-
|
|
19434
|
+
writeFileSync14(
|
|
18476
19435
|
cclensPath("cli-launch.json"),
|
|
18477
19436
|
JSON.stringify({ node: process.execPath, script: resolveScriptPath2() }),
|
|
18478
19437
|
"utf8"
|
|
@@ -18481,7 +19440,7 @@ function writeCliLaunchFile() {
|
|
|
18481
19440
|
}
|
|
18482
19441
|
}
|
|
18483
19442
|
function installedAppPath() {
|
|
18484
|
-
return
|
|
19443
|
+
return join13(homedir6(), "Applications", APP_BUNDLE);
|
|
18485
19444
|
}
|
|
18486
19445
|
async function isRunning() {
|
|
18487
19446
|
try {
|
|
@@ -18491,8 +19450,8 @@ async function isRunning() {
|
|
|
18491
19450
|
return false;
|
|
18492
19451
|
}
|
|
18493
19452
|
}
|
|
18494
|
-
async function launchApp(
|
|
18495
|
-
await execFileAsync2("open", ["-a",
|
|
19453
|
+
async function launchApp(path11) {
|
|
19454
|
+
await execFileAsync2("open", ["-a", path11]);
|
|
18496
19455
|
}
|
|
18497
19456
|
async function quitApp() {
|
|
18498
19457
|
await execFileAsync2("osascript", ["-e", `tell application "${BUNDLE_EXEC}" to quit`]).catch(
|
|
@@ -18513,14 +19472,14 @@ async function installMenubar(opts) {
|
|
|
18513
19472
|
return;
|
|
18514
19473
|
}
|
|
18515
19474
|
const src = bundledAppPath();
|
|
18516
|
-
if (!
|
|
19475
|
+
if (!existsSync19(src)) {
|
|
18517
19476
|
console.error(
|
|
18518
19477
|
`Bundled widget not found at ${src}.
|
|
18519
19478
|
This install was probably built without the menubar artifact. Run \`node apps/menubar/build-app.sh && cp -R apps/menubar/dist/FleetlensMenubar.app packages/cli/menubar/\` and rebuild.`
|
|
18520
19479
|
);
|
|
18521
19480
|
process.exit(1);
|
|
18522
19481
|
}
|
|
18523
|
-
const destDir =
|
|
19482
|
+
const destDir = join13(homedir6(), "Applications");
|
|
18524
19483
|
mkdirSync13(destDir, { recursive: true });
|
|
18525
19484
|
const dest = installedAppPath();
|
|
18526
19485
|
if (await isRunning()) {
|
|
@@ -18555,7 +19514,7 @@ async function uninstallMenubar() {
|
|
|
18555
19514
|
await new Promise((r) => setTimeout(r, 300));
|
|
18556
19515
|
}
|
|
18557
19516
|
const dest = installedAppPath();
|
|
18558
|
-
if (
|
|
19517
|
+
if (existsSync19(dest)) {
|
|
18559
19518
|
rmSync2(dest, { recursive: true, force: true });
|
|
18560
19519
|
console.log(`Removed ${dest}`);
|
|
18561
19520
|
} else {
|
|
@@ -18569,7 +19528,7 @@ async function openMenubar() {
|
|
|
18569
19528
|
return;
|
|
18570
19529
|
}
|
|
18571
19530
|
const dest = installedAppPath();
|
|
18572
|
-
if (!
|
|
19531
|
+
if (!existsSync19(dest)) {
|
|
18573
19532
|
console.log("Widget not installed yet. Run `fleetlens menubar install` first.");
|
|
18574
19533
|
return;
|
|
18575
19534
|
}
|
|
@@ -18586,15 +19545,15 @@ async function statusMenubar() {
|
|
|
18586
19545
|
return;
|
|
18587
19546
|
}
|
|
18588
19547
|
const dest = installedAppPath();
|
|
18589
|
-
const installed =
|
|
19548
|
+
const installed = existsSync19(dest);
|
|
18590
19549
|
const running = await isRunning();
|
|
18591
|
-
const bundled =
|
|
19550
|
+
const bundled = existsSync19(bundledAppPath());
|
|
18592
19551
|
console.log(`Menu bar widget: ${installed ? "installed" : "not installed"}${installed ? ` (${dest})` : ""}`);
|
|
18593
19552
|
console.log(`Running: ${running ? "yes" : "no"}`);
|
|
18594
19553
|
console.log(`Bundled in CLI: ${bundled ? "yes" : "no \u2014 this build ships without the widget"}`);
|
|
18595
19554
|
if (installed) {
|
|
18596
19555
|
try {
|
|
18597
|
-
const apps = readdirSync4(
|
|
19556
|
+
const apps = readdirSync4(join13(homedir6(), "Applications"));
|
|
18598
19557
|
const ours = apps.find((a) => a === APP_BUNDLE);
|
|
18599
19558
|
console.log(`App bundle: ${ours ? "present in ~/Applications" : "missing"}`);
|
|
18600
19559
|
} catch {
|
|
@@ -18677,8 +19636,8 @@ var init_config = __esm({
|
|
|
18677
19636
|
});
|
|
18678
19637
|
|
|
18679
19638
|
// src/perception/build-entries.ts
|
|
18680
|
-
import { statSync as statSync4, readFileSync as
|
|
18681
|
-
import { basename as basename2, dirname as
|
|
19639
|
+
import { statSync as statSync4, readFileSync as readFileSync20 } from "node:fs";
|
|
19640
|
+
import { basename as basename2, dirname as dirname14 } from "node:path";
|
|
18682
19641
|
function decodeProjectDirName(projectDir) {
|
|
18683
19642
|
if (projectDir.startsWith("-")) {
|
|
18684
19643
|
return "/" + projectDir.slice(1).replace(/-/g, "/");
|
|
@@ -18687,7 +19646,7 @@ function decodeProjectDirName(projectDir) {
|
|
|
18687
19646
|
}
|
|
18688
19647
|
function buildEntriesForFile(filePath) {
|
|
18689
19648
|
const stat = statSync4(filePath);
|
|
18690
|
-
const raw =
|
|
19649
|
+
const raw = readFileSync20(filePath, "utf8");
|
|
18691
19650
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
18692
19651
|
try {
|
|
18693
19652
|
return JSON.parse(l);
|
|
@@ -18698,7 +19657,7 @@ function buildEntriesForFile(filePath) {
|
|
|
18698
19657
|
if (rawLines.length === 0) return null;
|
|
18699
19658
|
const { meta, events } = parseTranscript(rawLines);
|
|
18700
19659
|
const fileName = basename2(filePath);
|
|
18701
|
-
const projectDir = basename2(
|
|
19660
|
+
const projectDir = basename2(dirname14(filePath));
|
|
18702
19661
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
18703
19662
|
const sd = {
|
|
18704
19663
|
...meta,
|
|
@@ -18952,7 +19911,7 @@ function buildIngestPayload(inputs) {
|
|
|
18952
19911
|
return {
|
|
18953
19912
|
ingestId: randomUUID2(),
|
|
18954
19913
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18955
|
-
cliVersion: "0.16.
|
|
19914
|
+
cliVersion: "0.16.7",
|
|
18956
19915
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
18957
19916
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
18958
19917
|
...richRollup ? { richRollup } : {},
|
|
@@ -18993,8 +19952,8 @@ var init_push = __esm({
|
|
|
18993
19952
|
});
|
|
18994
19953
|
|
|
18995
19954
|
// src/team/git-remote.ts
|
|
18996
|
-
import { existsSync as
|
|
18997
|
-
import { dirname as
|
|
19955
|
+
import { existsSync as existsSync20, readFileSync as readFileSync21, statSync as statSync5 } from "node:fs";
|
|
19956
|
+
import { dirname as dirname15, isAbsolute as isAbsolute2, join as join14, resolve as resolve2 } from "node:path";
|
|
18998
19957
|
function parseGithubRemote(url) {
|
|
18999
19958
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
19000
19959
|
return m ? `${m[1]}/${m[2]}`.toLowerCase() : null;
|
|
@@ -19014,19 +19973,19 @@ function originUrl2(configText) {
|
|
|
19014
19973
|
return null;
|
|
19015
19974
|
}
|
|
19016
19975
|
function gitConfigPathFor(dir) {
|
|
19017
|
-
const dotGit =
|
|
19976
|
+
const dotGit = join14(dir, ".git");
|
|
19018
19977
|
const st = statSync5(dotGit, { throwIfNoEntry: false });
|
|
19019
19978
|
if (!st) return null;
|
|
19020
|
-
if (st.isDirectory()) return
|
|
19021
|
-
const m =
|
|
19979
|
+
if (st.isDirectory()) return join14(dotGit, "config");
|
|
19980
|
+
const m = readFileSync21(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
19022
19981
|
if (!m) return null;
|
|
19023
19982
|
const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
|
|
19024
|
-
const commondirFile =
|
|
19025
|
-
if (
|
|
19026
|
-
const common =
|
|
19027
|
-
return
|
|
19983
|
+
const commondirFile = join14(gd, "commondir");
|
|
19984
|
+
if (existsSync20(commondirFile)) {
|
|
19985
|
+
const common = readFileSync21(commondirFile, "utf8").trim();
|
|
19986
|
+
return join14(isAbsolute2(common) ? common : resolve2(gd, common), "config");
|
|
19028
19987
|
}
|
|
19029
|
-
return
|
|
19988
|
+
return join14(gd, "config");
|
|
19030
19989
|
}
|
|
19031
19990
|
function createRepoResolver() {
|
|
19032
19991
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -19036,14 +19995,14 @@ function createRepoResolver() {
|
|
|
19036
19995
|
if (hit !== void 0) return hit;
|
|
19037
19996
|
let repo = null;
|
|
19038
19997
|
try {
|
|
19039
|
-
for (let d = dir; ; d =
|
|
19998
|
+
for (let d = dir; ; d = dirname15(d)) {
|
|
19040
19999
|
const config = gitConfigPathFor(d);
|
|
19041
|
-
if (config &&
|
|
19042
|
-
const url = originUrl2(
|
|
20000
|
+
if (config && existsSync20(config)) {
|
|
20001
|
+
const url = originUrl2(readFileSync21(config, "utf8"));
|
|
19043
20002
|
repo = url ? parseGithubRemote(url) : null;
|
|
19044
20003
|
break;
|
|
19045
20004
|
}
|
|
19046
|
-
if (d ===
|
|
20005
|
+
if (d === dirname15(d)) break;
|
|
19047
20006
|
}
|
|
19048
20007
|
} catch {
|
|
19049
20008
|
repo = null;
|
|
@@ -19061,10 +20020,10 @@ var init_git_remote = __esm({
|
|
|
19061
20020
|
});
|
|
19062
20021
|
|
|
19063
20022
|
// src/team/queue.ts
|
|
19064
|
-
import { readFileSync as
|
|
19065
|
-
import { dirname as
|
|
20023
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync15, appendFileSync as appendFileSync5, statSync as statSync6, mkdirSync as mkdirSync14 } from "node:fs";
|
|
20024
|
+
import { dirname as dirname16 } from "node:path";
|
|
19066
20025
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
19067
|
-
mkdirSync14(
|
|
20026
|
+
mkdirSync14(dirname16(queuePath), { recursive: true });
|
|
19068
20027
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
19069
20028
|
appendFileSync5(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
19070
20029
|
try {
|
|
@@ -19078,7 +20037,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
19078
20037
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
19079
20038
|
let lines;
|
|
19080
20039
|
try {
|
|
19081
|
-
lines =
|
|
20040
|
+
lines = readFileSync22(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
19082
20041
|
} catch {
|
|
19083
20042
|
return [];
|
|
19084
20043
|
}
|
|
@@ -19093,18 +20052,18 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
19093
20052
|
} catch {
|
|
19094
20053
|
}
|
|
19095
20054
|
}
|
|
19096
|
-
|
|
20055
|
+
writeFileSync15(queuePath, "", "utf8");
|
|
19097
20056
|
return valid.map((e) => e.payload);
|
|
19098
20057
|
}
|
|
19099
20058
|
function pruneOldest(queuePath) {
|
|
19100
20059
|
let lines;
|
|
19101
20060
|
try {
|
|
19102
|
-
lines =
|
|
20061
|
+
lines = readFileSync22(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
19103
20062
|
} catch {
|
|
19104
20063
|
return;
|
|
19105
20064
|
}
|
|
19106
20065
|
const keep = lines.slice(Math.floor(lines.length / 2));
|
|
19107
|
-
|
|
20066
|
+
writeFileSync15(queuePath, keep.join("\n") + "\n", "utf8");
|
|
19108
20067
|
}
|
|
19109
20068
|
var QUEUE_PATH, MAX_SIZE_BYTES, MAX_AGE_MS;
|
|
19110
20069
|
var init_queue2 = __esm({
|
|
@@ -19118,8 +20077,8 @@ var init_queue2 = __esm({
|
|
|
19118
20077
|
});
|
|
19119
20078
|
|
|
19120
20079
|
// src/usage/profile.ts
|
|
19121
|
-
import { existsSync as
|
|
19122
|
-
import { dirname as
|
|
20080
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync15, readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "node:fs";
|
|
20081
|
+
import { dirname as dirname17 } from "node:path";
|
|
19123
20082
|
function mapRateLimitTier(rateLimitTier) {
|
|
19124
20083
|
switch (rateLimitTier) {
|
|
19125
20084
|
case "default_claude_pro":
|
|
@@ -19159,9 +20118,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
19159
20118
|
};
|
|
19160
20119
|
}
|
|
19161
20120
|
function readCachedProfile(cachePath) {
|
|
19162
|
-
if (!
|
|
20121
|
+
if (!existsSync21(cachePath)) return null;
|
|
19163
20122
|
try {
|
|
19164
|
-
const raw = JSON.parse(
|
|
20123
|
+
const raw = JSON.parse(readFileSync23(cachePath, "utf8"));
|
|
19165
20124
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
19166
20125
|
return raw;
|
|
19167
20126
|
} catch {
|
|
@@ -19169,8 +20128,8 @@ function readCachedProfile(cachePath) {
|
|
|
19169
20128
|
}
|
|
19170
20129
|
}
|
|
19171
20130
|
function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
|
|
19172
|
-
mkdirSync15(
|
|
19173
|
-
|
|
20131
|
+
mkdirSync15(dirname17(cachePath), { recursive: true });
|
|
20132
|
+
writeFileSync16(
|
|
19174
20133
|
cachePath,
|
|
19175
20134
|
JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
|
|
19176
20135
|
{ mode: 384 }
|
|
@@ -19350,11 +20309,11 @@ var init_backfill = __esm({
|
|
|
19350
20309
|
});
|
|
19351
20310
|
|
|
19352
20311
|
// src/team/sync-log.ts
|
|
19353
|
-
import { readFileSync as
|
|
20312
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
19354
20313
|
function readPendingSyncLog(watermark) {
|
|
19355
20314
|
let raw;
|
|
19356
20315
|
try {
|
|
19357
|
-
raw =
|
|
20316
|
+
raw = readFileSync24(cclensPath("daemon.log"), "utf8");
|
|
19358
20317
|
} catch {
|
|
19359
20318
|
return { lines: [] };
|
|
19360
20319
|
}
|
|
@@ -19382,12 +20341,12 @@ var init_sync_log = __esm({
|
|
|
19382
20341
|
});
|
|
19383
20342
|
|
|
19384
20343
|
// src/team/last-push.ts
|
|
19385
|
-
import { writeFileSync as
|
|
19386
|
-
import { join as
|
|
20344
|
+
import { writeFileSync as writeFileSync17, unlinkSync as unlinkSync6, mkdirSync as mkdirSync16 } from "node:fs";
|
|
20345
|
+
import { join as join15 } from "node:path";
|
|
19387
20346
|
function write(record, dir) {
|
|
19388
20347
|
const d = dir ?? cclensHome();
|
|
19389
20348
|
mkdirSync16(d, { recursive: true });
|
|
19390
|
-
|
|
20349
|
+
writeFileSync17(join15(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
19391
20350
|
}
|
|
19392
20351
|
function writeLastPushSuccess(payload, dir) {
|
|
19393
20352
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -19398,7 +20357,7 @@ function writeLastPushFailure(payload, error, dir) {
|
|
|
19398
20357
|
function clearLastPush(dir) {
|
|
19399
20358
|
const d = dir ?? cclensHome();
|
|
19400
20359
|
try {
|
|
19401
|
-
unlinkSync6(
|
|
20360
|
+
unlinkSync6(join15(d, LAST_PUSH_FILE));
|
|
19402
20361
|
} catch {
|
|
19403
20362
|
}
|
|
19404
20363
|
}
|
|
@@ -19418,25 +20377,25 @@ __export(file_probe_exports, {
|
|
|
19418
20377
|
probeArtifactSignals: () => probeArtifactSignals
|
|
19419
20378
|
});
|
|
19420
20379
|
import { createHash } from "node:crypto";
|
|
19421
|
-
import { existsSync as
|
|
20380
|
+
import { existsSync as existsSync22, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
|
|
19422
20381
|
import { homedir as homedir7 } from "node:os";
|
|
19423
|
-
import { join as
|
|
20382
|
+
import { join as join16, relative, resolve as resolve3, sep } from "node:path";
|
|
19424
20383
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
19425
20384
|
function pathHash(relPath) {
|
|
19426
20385
|
return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
19427
20386
|
}
|
|
19428
20387
|
function defaultScanRoots(extraRoots = []) {
|
|
19429
20388
|
const roots = [];
|
|
19430
|
-
const home =
|
|
19431
|
-
if (
|
|
20389
|
+
const home = join16(homedir7(), ".claude");
|
|
20390
|
+
if (existsSync22(home)) roots.push({ root: home, label: "user" });
|
|
19432
20391
|
for (const e of extraRoots) {
|
|
19433
20392
|
const r = resolve3(e, ".claude");
|
|
19434
|
-
if (
|
|
20393
|
+
if (existsSync22(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
19435
20394
|
}
|
|
19436
20395
|
return roots;
|
|
19437
20396
|
}
|
|
19438
20397
|
function listMarkdownFiles(dir) {
|
|
19439
|
-
if (!
|
|
20398
|
+
if (!existsSync22(dir)) return [];
|
|
19440
20399
|
const out = [];
|
|
19441
20400
|
let entries2;
|
|
19442
20401
|
try {
|
|
@@ -19446,7 +20405,7 @@ function listMarkdownFiles(dir) {
|
|
|
19446
20405
|
}
|
|
19447
20406
|
for (const name of entries2) {
|
|
19448
20407
|
if (name.startsWith(".")) continue;
|
|
19449
|
-
const full =
|
|
20408
|
+
const full = join16(dir, name);
|
|
19450
20409
|
let stat;
|
|
19451
20410
|
try {
|
|
19452
20411
|
stat = statSync7(full);
|
|
@@ -19466,7 +20425,7 @@ function firstSeenDateOf(file) {
|
|
|
19466
20425
|
const out = execFileSync3(
|
|
19467
20426
|
"git",
|
|
19468
20427
|
["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
|
|
19469
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
20428
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname18(file) }
|
|
19470
20429
|
).trim().split("\n").filter(Boolean);
|
|
19471
20430
|
if (out.length > 0) return out[out.length - 1];
|
|
19472
20431
|
} catch {
|
|
@@ -19478,7 +20437,7 @@ function firstSeenDateOf(file) {
|
|
|
19478
20437
|
return todayLocal();
|
|
19479
20438
|
}
|
|
19480
20439
|
}
|
|
19481
|
-
function
|
|
20440
|
+
function dirname18(p) {
|
|
19482
20441
|
const i = p.lastIndexOf(sep);
|
|
19483
20442
|
return i < 0 ? "." : p.slice(0, i);
|
|
19484
20443
|
}
|
|
@@ -19505,8 +20464,8 @@ function todayLocal() {
|
|
|
19505
20464
|
function scanAuthored(roots, subdir, day2) {
|
|
19506
20465
|
const out = [];
|
|
19507
20466
|
for (const r of roots) {
|
|
19508
|
-
const dir =
|
|
19509
|
-
if (!
|
|
20467
|
+
const dir = join16(r.root, subdir);
|
|
20468
|
+
if (!existsSync22(dir)) continue;
|
|
19510
20469
|
for (const f of listMarkdownFiles(dir)) {
|
|
19511
20470
|
const firstSeen = firstSeenDateOf(f);
|
|
19512
20471
|
if (firstSeen !== day2) continue;
|
|
@@ -19519,8 +20478,8 @@ function scanAuthored(roots, subdir, day2) {
|
|
|
19519
20478
|
function scanEdited(roots, day2) {
|
|
19520
20479
|
const out = [];
|
|
19521
20480
|
for (const r of roots) {
|
|
19522
|
-
const dir =
|
|
19523
|
-
if (!
|
|
20481
|
+
const dir = join16(r.root, "skills");
|
|
20482
|
+
if (!existsSync22(dir)) continue;
|
|
19524
20483
|
for (const f of listMarkdownFiles(dir)) {
|
|
19525
20484
|
const firstSeen = firstSeenDateOf(f);
|
|
19526
20485
|
if (firstSeen === day2) continue;
|
|
@@ -19543,16 +20502,16 @@ function claudemdLineDelta(extraRoots, authorEmail, day2) {
|
|
|
19543
20502
|
const candidates = [];
|
|
19544
20503
|
for (const e of extraRoots) {
|
|
19545
20504
|
const f = resolve3(e, "CLAUDE.md");
|
|
19546
|
-
if (
|
|
20505
|
+
if (existsSync22(f)) candidates.push(f);
|
|
19547
20506
|
}
|
|
19548
|
-
const homeClaudeMd =
|
|
19549
|
-
if (
|
|
20507
|
+
const homeClaudeMd = join16(homedir7(), "CLAUDE.md");
|
|
20508
|
+
if (existsSync22(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
19550
20509
|
for (const file of candidates) {
|
|
19551
20510
|
try {
|
|
19552
20511
|
const out = execFileSync3(
|
|
19553
20512
|
"git",
|
|
19554
20513
|
["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
|
|
19555
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
20514
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname18(file) }
|
|
19556
20515
|
);
|
|
19557
20516
|
let currentDate = "";
|
|
19558
20517
|
let currentEmail = "";
|
|
@@ -20436,11 +21395,11 @@ var logs_exports = {};
|
|
|
20436
21395
|
__export(logs_exports, {
|
|
20437
21396
|
teamLogs: () => teamLogs
|
|
20438
21397
|
});
|
|
20439
|
-
import { readFileSync as
|
|
21398
|
+
import { readFileSync as readFileSync25 } from "node:fs";
|
|
20440
21399
|
async function teamLogs() {
|
|
20441
21400
|
const logPath = cclensPath("daemon.log");
|
|
20442
21401
|
try {
|
|
20443
|
-
const lines =
|
|
21402
|
+
const lines = readFileSync25(logPath, "utf8").trim().split("\n");
|
|
20444
21403
|
const teamLines = lines.filter((l) => l.includes("[sync] ") || l.includes("team "));
|
|
20445
21404
|
if (teamLines.length === 0) {
|
|
20446
21405
|
console.log("No team-related log entries found.");
|
|
@@ -20568,8 +21527,8 @@ __export(runs_exports, {
|
|
|
20568
21527
|
runs: () => runs
|
|
20569
21528
|
});
|
|
20570
21529
|
import { execSync as execSync2 } from "node:child_process";
|
|
20571
|
-
import { existsSync as
|
|
20572
|
-
import { join as
|
|
21530
|
+
import { existsSync as existsSync23, readFileSync as readFileSync26, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
|
|
21531
|
+
import { join as join17 } from "node:path";
|
|
20573
21532
|
async function runs(args2) {
|
|
20574
21533
|
const json = args2.includes("--json");
|
|
20575
21534
|
const watch = args2.includes("--watch");
|
|
@@ -20653,8 +21612,8 @@ function listActiveRuns() {
|
|
|
20653
21612
|
return runs2.sort((a, b) => a.elapsed_s - b.elapsed_s);
|
|
20654
21613
|
}
|
|
20655
21614
|
function readSpend(sinceMs) {
|
|
20656
|
-
if (!
|
|
20657
|
-
const lines =
|
|
21615
|
+
if (!existsSync23(SPEND_PATH)) return [];
|
|
21616
|
+
const lines = readFileSync26(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
|
|
20658
21617
|
const out = [];
|
|
20659
21618
|
for (const line of lines) {
|
|
20660
21619
|
try {
|
|
@@ -20775,23 +21734,23 @@ function ageLabel(ms) {
|
|
|
20775
21734
|
return `${Math.floor(ms / 864e5)}d`;
|
|
20776
21735
|
}
|
|
20777
21736
|
function listTraceFiles() {
|
|
20778
|
-
if (!
|
|
21737
|
+
if (!existsSync23(RUNS_DIR2)) return [];
|
|
20779
21738
|
const entries2 = readdirSync6(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
|
|
20780
21739
|
return entries2.map((f) => {
|
|
20781
|
-
const
|
|
20782
|
-
const st = statSync8(
|
|
20783
|
-
return { runId: f.replace(/\.jsonl$/, ""), path:
|
|
21740
|
+
const path11 = join17(RUNS_DIR2, f);
|
|
21741
|
+
const st = statSync8(path11);
|
|
21742
|
+
return { runId: f.replace(/\.jsonl$/, ""), path: path11, mtimeMs: st.mtimeMs };
|
|
20784
21743
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
20785
21744
|
}
|
|
20786
21745
|
function resolveRunId(arg) {
|
|
20787
|
-
if (!
|
|
21746
|
+
if (!existsSync23(RUNS_DIR2)) return null;
|
|
20788
21747
|
if (arg === "latest") {
|
|
20789
21748
|
const all2 = listTraceFiles();
|
|
20790
21749
|
if (all2.length === 0) return null;
|
|
20791
21750
|
return { runId: all2[0].runId, path: all2[0].path };
|
|
20792
21751
|
}
|
|
20793
|
-
const exact =
|
|
20794
|
-
if (
|
|
21752
|
+
const exact = join17(RUNS_DIR2, `${arg}.jsonl`);
|
|
21753
|
+
if (existsSync23(exact)) return { runId: arg, path: exact };
|
|
20795
21754
|
const all = listTraceFiles();
|
|
20796
21755
|
const matches = all.filter((r) => r.runId.includes(arg));
|
|
20797
21756
|
if (matches.length === 1) return { runId: matches[0].runId, path: matches[0].path };
|
|
@@ -20802,8 +21761,8 @@ function resolveRunId(arg) {
|
|
|
20802
21761
|
}
|
|
20803
21762
|
return null;
|
|
20804
21763
|
}
|
|
20805
|
-
function readTrace(
|
|
20806
|
-
return
|
|
21764
|
+
function readTrace(path11) {
|
|
21765
|
+
return readFileSync26(path11, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
|
|
20807
21766
|
try {
|
|
20808
21767
|
return JSON.parse(l);
|
|
20809
21768
|
} catch {
|
|
@@ -20815,7 +21774,7 @@ async function inspect(arg, follow, json) {
|
|
|
20815
21774
|
const r = resolveRunId(arg);
|
|
20816
21775
|
if (!r) {
|
|
20817
21776
|
console.error(`run not found: ${arg}`);
|
|
20818
|
-
if (
|
|
21777
|
+
if (existsSync23(RUNS_DIR2)) {
|
|
20819
21778
|
const all = listTraceFiles().slice(0, 5);
|
|
20820
21779
|
if (all.length > 0) {
|
|
20821
21780
|
console.error(`
|
|
@@ -20995,7 +21954,7 @@ async function main() {
|
|
|
20995
21954
|
case "version":
|
|
20996
21955
|
case "--version":
|
|
20997
21956
|
case "-v":
|
|
20998
|
-
console.log(`fleetlens ${"0.16.
|
|
21957
|
+
console.log(`fleetlens ${"0.16.7"}`);
|
|
20999
21958
|
break;
|
|
21000
21959
|
case "help":
|
|
21001
21960
|
case "--help":
|