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/daemon-worker.js
CHANGED
|
@@ -607,7 +607,7 @@ function getAgentMetadata(kind) {
|
|
|
607
607
|
function isAgentKind(s) {
|
|
608
608
|
return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
|
|
609
609
|
}
|
|
610
|
-
var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
610
|
+
var CLAUDE_CODE_METADATA, CODEX_METADATA, COPILOT_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
|
|
611
611
|
var init_agent_metadata = __esm({
|
|
612
612
|
"../parser/dist/agent-metadata.js"() {
|
|
613
613
|
"use strict";
|
|
@@ -625,6 +625,13 @@ var init_agent_metadata = __esm({
|
|
|
625
625
|
accentColor: "rgb(16, 163, 127)",
|
|
626
626
|
iconChar: "\u25C6"
|
|
627
627
|
};
|
|
628
|
+
COPILOT_METADATA = {
|
|
629
|
+
kind: "copilot",
|
|
630
|
+
displayName: "GitHub Copilot CLI",
|
|
631
|
+
shortLabel: "Copilot",
|
|
632
|
+
accentColor: "rgb(137, 87, 229)",
|
|
633
|
+
iconChar: "\u221E"
|
|
634
|
+
};
|
|
628
635
|
GEMINI_METADATA = {
|
|
629
636
|
kind: "gemini",
|
|
630
637
|
displayName: "Gemini CLI",
|
|
@@ -664,6 +671,7 @@ var init_agent_metadata = __esm({
|
|
|
664
671
|
agentMetadata = [
|
|
665
672
|
CLAUDE_CODE_METADATA,
|
|
666
673
|
CODEX_METADATA,
|
|
674
|
+
COPILOT_METADATA,
|
|
667
675
|
GEMINI_METADATA,
|
|
668
676
|
ANTIGRAVITY_METADATA,
|
|
669
677
|
COWORK_METADATA,
|
|
@@ -1525,11 +1533,11 @@ function defaultBranch(commonDir) {
|
|
|
1525
1533
|
}
|
|
1526
1534
|
return void 0;
|
|
1527
1535
|
}
|
|
1528
|
-
function readGitFolder(
|
|
1529
|
-
if (!existsSync(
|
|
1536
|
+
function readGitFolder(path11) {
|
|
1537
|
+
if (!existsSync(path11))
|
|
1530
1538
|
return { exists: false, isWorktree: false };
|
|
1531
1539
|
try {
|
|
1532
|
-
const git = nearestDotGit(realpathOrSelf(
|
|
1540
|
+
const git = nearestDotGit(realpathOrSelf(path11));
|
|
1533
1541
|
if (!git)
|
|
1534
1542
|
return { exists: true, isWorktree: false };
|
|
1535
1543
|
const projectRoot = projectRootFromCommonDir(git.commonDir);
|
|
@@ -3311,24 +3319,442 @@ var init_codex = __esm({
|
|
|
3311
3319
|
}
|
|
3312
3320
|
});
|
|
3313
3321
|
|
|
3314
|
-
// ../parser/dist/
|
|
3322
|
+
// ../parser/dist/copilot.js
|
|
3315
3323
|
import { promises as fs3 } from "node:fs";
|
|
3316
3324
|
import os3 from "node:os";
|
|
3317
3325
|
import path3 from "node:path";
|
|
3318
|
-
|
|
3319
|
-
return
|
|
3326
|
+
function recordOf(value) {
|
|
3327
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
3328
|
+
}
|
|
3329
|
+
function stringOf(value) {
|
|
3330
|
+
return typeof value === "string" ? value : void 0;
|
|
3331
|
+
}
|
|
3332
|
+
function numberOf2(value) {
|
|
3333
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
3334
|
+
}
|
|
3335
|
+
function emptyUsage2() {
|
|
3336
|
+
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3337
|
+
}
|
|
3338
|
+
function previewOf2(value) {
|
|
3339
|
+
const text = typeof value === "string" ? value : JSON.stringify(value ?? "");
|
|
3340
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3341
|
+
}
|
|
3342
|
+
function tokenCount(details, key) {
|
|
3343
|
+
return numberOf2(recordOf(details?.[key])?.tokenCount);
|
|
3344
|
+
}
|
|
3345
|
+
function syntheticProjectDir(cwd) {
|
|
3346
|
+
return cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : "(unknown)";
|
|
3320
3347
|
}
|
|
3321
3348
|
async function listSessionFiles(root) {
|
|
3349
|
+
const entries = await fs3.readdir(root, { withFileTypes: true }).catch(() => []);
|
|
3350
|
+
const out = [];
|
|
3351
|
+
for (const entry of entries) {
|
|
3352
|
+
if (!entry.isDirectory())
|
|
3353
|
+
continue;
|
|
3354
|
+
const filePath = path3.join(root, entry.name, "events.jsonl");
|
|
3355
|
+
const stat = await fs3.stat(filePath).catch(() => null);
|
|
3356
|
+
if (!stat?.isFile())
|
|
3357
|
+
continue;
|
|
3358
|
+
out.push({
|
|
3359
|
+
filePath,
|
|
3360
|
+
sessionId: entry.name,
|
|
3361
|
+
mtimeMs: stat.mtimeMs,
|
|
3362
|
+
sizeBytes: stat.size
|
|
3363
|
+
});
|
|
3364
|
+
}
|
|
3365
|
+
return out;
|
|
3366
|
+
}
|
|
3367
|
+
async function readJsonl2(filePath) {
|
|
3368
|
+
const raw = await fs3.readFile(filePath, "utf8");
|
|
3369
|
+
const out = [];
|
|
3370
|
+
for (const line of raw.split("\n")) {
|
|
3371
|
+
const trimmed = line.trim();
|
|
3372
|
+
if (!trimmed)
|
|
3373
|
+
continue;
|
|
3374
|
+
try {
|
|
3375
|
+
out.push(JSON.parse(trimmed));
|
|
3376
|
+
} catch {
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
return out;
|
|
3380
|
+
}
|
|
3381
|
+
function computeActiveSegments3(timestamps) {
|
|
3382
|
+
const sorted = [...new Set(timestamps)].sort((a, b) => a - b);
|
|
3383
|
+
if (sorted.length === 0)
|
|
3384
|
+
return [];
|
|
3385
|
+
const segments = [];
|
|
3386
|
+
let start = sorted[0];
|
|
3387
|
+
let end = start;
|
|
3388
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
3389
|
+
const next = sorted[i];
|
|
3390
|
+
if (next - end > IDLE_GAP_MS2) {
|
|
3391
|
+
segments.push({ startMs: start, endMs: end });
|
|
3392
|
+
start = next;
|
|
3393
|
+
}
|
|
3394
|
+
end = next;
|
|
3395
|
+
}
|
|
3396
|
+
segments.push({ startMs: start, endMs: end });
|
|
3397
|
+
return segments;
|
|
3398
|
+
}
|
|
3399
|
+
function parseSession(file, lines) {
|
|
3400
|
+
const records = lines.map(recordOf).filter((line) => line !== void 0);
|
|
3401
|
+
const executionCallIds = /* @__PURE__ */ new Set();
|
|
3402
|
+
for (const record of records) {
|
|
3403
|
+
if (record.type !== "tool.execution_start")
|
|
3404
|
+
continue;
|
|
3405
|
+
const callId = stringOf(recordOf(record.data)?.toolCallId);
|
|
3406
|
+
if (callId)
|
|
3407
|
+
executionCallIds.add(callId);
|
|
3408
|
+
}
|
|
3409
|
+
const events = [];
|
|
3410
|
+
const timestamps = [];
|
|
3411
|
+
const totalUsage = emptyUsage2();
|
|
3412
|
+
let firstMs;
|
|
3413
|
+
let lastMs;
|
|
3414
|
+
let cwd;
|
|
3415
|
+
let repository;
|
|
3416
|
+
let gitBranch;
|
|
3417
|
+
let model;
|
|
3418
|
+
let firstUserPreview;
|
|
3419
|
+
let lastUserPreview;
|
|
3420
|
+
let lastAgentPreview;
|
|
3421
|
+
let toolCallCount = 0;
|
|
3422
|
+
let turnCount = 0;
|
|
3423
|
+
let observedOutput = 0;
|
|
3424
|
+
let sawShutdown = false;
|
|
3425
|
+
let linesAdded;
|
|
3426
|
+
let linesRemoved;
|
|
3427
|
+
let filesEdited;
|
|
3428
|
+
let idx = 0;
|
|
3429
|
+
function push(event) {
|
|
3430
|
+
events.push({ index: idx++, ...event });
|
|
3431
|
+
}
|
|
3432
|
+
for (const obj of records) {
|
|
3433
|
+
const type = stringOf(obj.type) ?? "";
|
|
3434
|
+
const data = recordOf(obj.data) ?? {};
|
|
3435
|
+
const timestamp = stringOf(obj.timestamp);
|
|
3436
|
+
if (timestamp) {
|
|
3437
|
+
const ms = Date.parse(timestamp);
|
|
3438
|
+
if (Number.isFinite(ms)) {
|
|
3439
|
+
timestamps.push(ms);
|
|
3440
|
+
firstMs = firstMs === void 0 ? ms : Math.min(firstMs, ms);
|
|
3441
|
+
lastMs = lastMs === void 0 ? ms : Math.max(lastMs, ms);
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
if (type === "session.start") {
|
|
3445
|
+
const context = recordOf(data.context);
|
|
3446
|
+
cwd = stringOf(context?.cwd) ?? cwd;
|
|
3447
|
+
repository = stringOf(context?.repository) ?? repository;
|
|
3448
|
+
gitBranch = stringOf(context?.branch) ?? gitBranch;
|
|
3449
|
+
push({
|
|
3450
|
+
timestamp,
|
|
3451
|
+
role: "meta",
|
|
3452
|
+
rawType: type,
|
|
3453
|
+
preview: "Copilot session started",
|
|
3454
|
+
blocks: [],
|
|
3455
|
+
raw: obj
|
|
3456
|
+
});
|
|
3457
|
+
continue;
|
|
3458
|
+
}
|
|
3459
|
+
if (type === "session.model_change") {
|
|
3460
|
+
const selected = stringOf(data.newModel);
|
|
3461
|
+
if (selected && selected !== "auto")
|
|
3462
|
+
model = selected;
|
|
3463
|
+
} else if (type === "session.auto_mode_resolved") {
|
|
3464
|
+
model = stringOf(data.chosenModel) ?? model;
|
|
3465
|
+
} else if (type === "assistant.turn_start" || type === "assistant.message") {
|
|
3466
|
+
model = stringOf(data.model) ?? model;
|
|
3467
|
+
}
|
|
3468
|
+
if (type === "system.message") {
|
|
3469
|
+
push({
|
|
3470
|
+
timestamp,
|
|
3471
|
+
role: "system",
|
|
3472
|
+
rawType: type,
|
|
3473
|
+
preview: "Copilot system instructions",
|
|
3474
|
+
blocks: [],
|
|
3475
|
+
raw: obj
|
|
3476
|
+
});
|
|
3477
|
+
continue;
|
|
3478
|
+
}
|
|
3479
|
+
if (type === "user.message") {
|
|
3480
|
+
const text = stringOf(data.content) ?? "";
|
|
3481
|
+
const preview = previewOf2(text);
|
|
3482
|
+
if (text && !isFrameworkInjectedUserInput(text)) {
|
|
3483
|
+
firstUserPreview ??= preview;
|
|
3484
|
+
lastUserPreview = preview;
|
|
3485
|
+
turnCount += 1;
|
|
3486
|
+
}
|
|
3487
|
+
push({
|
|
3488
|
+
timestamp,
|
|
3489
|
+
role: "user",
|
|
3490
|
+
rawType: type,
|
|
3491
|
+
preview,
|
|
3492
|
+
blocks: text ? [{ type: "text", text }] : [],
|
|
3493
|
+
raw: obj
|
|
3494
|
+
});
|
|
3495
|
+
continue;
|
|
3496
|
+
}
|
|
3497
|
+
if (type === "assistant.message") {
|
|
3498
|
+
const text = stringOf(data.content) ?? "";
|
|
3499
|
+
const outputTokens = numberOf2(data.outputTokens) ?? 0;
|
|
3500
|
+
observedOutput += outputTokens;
|
|
3501
|
+
if (text) {
|
|
3502
|
+
const preview = previewOf2(text);
|
|
3503
|
+
lastAgentPreview = preview;
|
|
3504
|
+
push({
|
|
3505
|
+
timestamp,
|
|
3506
|
+
role: "agent",
|
|
3507
|
+
rawType: type,
|
|
3508
|
+
messageId: stringOf(data.messageId),
|
|
3509
|
+
preview,
|
|
3510
|
+
blocks: [{ type: "text", text }],
|
|
3511
|
+
model,
|
|
3512
|
+
raw: obj
|
|
3513
|
+
});
|
|
3514
|
+
}
|
|
3515
|
+
const requests = Array.isArray(data.toolRequests) ? data.toolRequests : [];
|
|
3516
|
+
for (const requestValue of requests) {
|
|
3517
|
+
const request = recordOf(requestValue);
|
|
3518
|
+
if (!request)
|
|
3519
|
+
continue;
|
|
3520
|
+
const callId = stringOf(request.toolCallId);
|
|
3521
|
+
if (callId && executionCallIds.has(callId))
|
|
3522
|
+
continue;
|
|
3523
|
+
const name = stringOf(request.name) ?? "(unknown)";
|
|
3524
|
+
const input = recordOf(request.arguments) ?? request.arguments ?? null;
|
|
3525
|
+
toolCallCount += 1;
|
|
3526
|
+
push({
|
|
3527
|
+
timestamp,
|
|
3528
|
+
role: "tool-call",
|
|
3529
|
+
rawType: "assistant.message/tool_request",
|
|
3530
|
+
preview: `${name}(${previewOf2(input).slice(0, 80)})`,
|
|
3531
|
+
blocks: [{ type: "tool_use", id: callId ?? `copilot-${idx}`, name, input }],
|
|
3532
|
+
toolName: name,
|
|
3533
|
+
toolUseId: callId,
|
|
3534
|
+
model,
|
|
3535
|
+
raw: obj
|
|
3536
|
+
});
|
|
3537
|
+
}
|
|
3538
|
+
continue;
|
|
3539
|
+
}
|
|
3540
|
+
if (type === "tool.execution_start") {
|
|
3541
|
+
const callId = stringOf(data.toolCallId);
|
|
3542
|
+
const name = stringOf(data.toolName) ?? "(unknown)";
|
|
3543
|
+
const input = data.arguments ?? null;
|
|
3544
|
+
toolCallCount += 1;
|
|
3545
|
+
push({
|
|
3546
|
+
timestamp,
|
|
3547
|
+
role: "tool-call",
|
|
3548
|
+
rawType: type,
|
|
3549
|
+
preview: `${name}(${previewOf2(input).slice(0, 80)})`,
|
|
3550
|
+
blocks: [{ type: "tool_use", id: callId ?? `copilot-${idx}`, name, input }],
|
|
3551
|
+
toolName: name,
|
|
3552
|
+
toolUseId: callId,
|
|
3553
|
+
model: stringOf(data.model) ?? model,
|
|
3554
|
+
raw: obj
|
|
3555
|
+
});
|
|
3556
|
+
continue;
|
|
3557
|
+
}
|
|
3558
|
+
if (type === "tool.execution_complete") {
|
|
3559
|
+
const callId = stringOf(data.toolCallId);
|
|
3560
|
+
const resultRecord = recordOf(data.result);
|
|
3561
|
+
const result = resultRecord && "content" in resultRecord ? resultRecord.content : data.result;
|
|
3562
|
+
const success = data.success !== false;
|
|
3563
|
+
push({
|
|
3564
|
+
timestamp,
|
|
3565
|
+
role: "tool-result",
|
|
3566
|
+
rawType: type,
|
|
3567
|
+
preview: previewOf2(result),
|
|
3568
|
+
blocks: [{ type: "tool_result", tool_use_id: callId ?? "", content: result, is_error: !success }],
|
|
3569
|
+
toolUseId: callId,
|
|
3570
|
+
toolResult: data.result,
|
|
3571
|
+
raw: obj
|
|
3572
|
+
});
|
|
3573
|
+
continue;
|
|
3574
|
+
}
|
|
3575
|
+
if (type === "assistant.reasoning") {
|
|
3576
|
+
const text = stringOf(data.content) ?? "";
|
|
3577
|
+
push({
|
|
3578
|
+
timestamp,
|
|
3579
|
+
role: "agent-thinking",
|
|
3580
|
+
rawType: type,
|
|
3581
|
+
preview: previewOf2(text),
|
|
3582
|
+
blocks: text ? [{ type: "thinking", thinking: text }] : [],
|
|
3583
|
+
model,
|
|
3584
|
+
raw: obj
|
|
3585
|
+
});
|
|
3586
|
+
continue;
|
|
3587
|
+
}
|
|
3588
|
+
if (type === "session.shutdown") {
|
|
3589
|
+
sawShutdown = true;
|
|
3590
|
+
model = stringOf(data.currentModel) ?? model;
|
|
3591
|
+
const details = recordOf(data.tokenDetails);
|
|
3592
|
+
totalUsage.input = tokenCount(details, "input") ?? totalUsage.input;
|
|
3593
|
+
totalUsage.output = tokenCount(details, "output") ?? observedOutput;
|
|
3594
|
+
totalUsage.cacheRead = tokenCount(details, "cache_read") ?? totalUsage.cacheRead;
|
|
3595
|
+
totalUsage.cacheWrite = tokenCount(details, "cache_write") ?? totalUsage.cacheWrite;
|
|
3596
|
+
const changes = recordOf(data.codeChanges);
|
|
3597
|
+
linesAdded = numberOf2(changes?.linesAdded);
|
|
3598
|
+
linesRemoved = numberOf2(changes?.linesRemoved);
|
|
3599
|
+
const modified = changes?.filesModified;
|
|
3600
|
+
filesEdited = Array.isArray(modified) ? modified.length : void 0;
|
|
3601
|
+
}
|
|
3602
|
+
push({
|
|
3603
|
+
timestamp,
|
|
3604
|
+
role: "meta",
|
|
3605
|
+
rawType: type,
|
|
3606
|
+
preview: "",
|
|
3607
|
+
blocks: [],
|
|
3608
|
+
raw: obj
|
|
3609
|
+
});
|
|
3610
|
+
}
|
|
3611
|
+
if (totalUsage.output === 0)
|
|
3612
|
+
totalUsage.output = observedOutput;
|
|
3613
|
+
if (totalUsage.input || totalUsage.output || totalUsage.cacheRead || totalUsage.cacheWrite) {
|
|
3614
|
+
const usageEvent = [...events].reverse().find((event) => event.role === "agent" || event.role === "agent-thinking" || event.role === "tool-call");
|
|
3615
|
+
if (usageEvent) {
|
|
3616
|
+
usageEvent.messageId = `copilot-${file.sessionId}-total`;
|
|
3617
|
+
usageEvent.usage = { ...totalUsage };
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
const firstTimestamp = firstMs === void 0 ? void 0 : new Date(firstMs).toISOString();
|
|
3621
|
+
const lastTimestamp = lastMs === void 0 ? void 0 : new Date(lastMs).toISOString();
|
|
3622
|
+
if (firstMs !== void 0) {
|
|
3623
|
+
let previousMs;
|
|
3624
|
+
for (const event of events) {
|
|
3625
|
+
if (!event.timestamp)
|
|
3626
|
+
continue;
|
|
3627
|
+
const ms = Date.parse(event.timestamp);
|
|
3628
|
+
if (!Number.isFinite(ms))
|
|
3629
|
+
continue;
|
|
3630
|
+
event.tOffsetMs = Math.max(0, ms - firstMs);
|
|
3631
|
+
if (previousMs !== void 0)
|
|
3632
|
+
event.gapMs = Math.max(0, ms - previousMs);
|
|
3633
|
+
previousMs = ms;
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
const activeSegments = computeActiveSegments3(timestamps);
|
|
3637
|
+
const airTimeMs = activeSegments.reduce((sum, segment) => sum + segment.endMs - segment.startMs, 0);
|
|
3638
|
+
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
3639
|
+
const repoName = project?.repoName ?? repository?.split("/").filter(Boolean).at(-1);
|
|
3640
|
+
const meta = {
|
|
3641
|
+
agent: "copilot",
|
|
3642
|
+
id: file.sessionId,
|
|
3643
|
+
filePath: file.filePath,
|
|
3644
|
+
projectName: project?.projectName ?? cwd ?? "(unknown)",
|
|
3645
|
+
worktreeName: project?.worktreeName,
|
|
3646
|
+
repoName,
|
|
3647
|
+
projectDir: syntheticProjectDir(cwd),
|
|
3648
|
+
sessionId: file.sessionId,
|
|
3649
|
+
firstTimestamp,
|
|
3650
|
+
lastTimestamp,
|
|
3651
|
+
lastActivityMs: file.mtimeMs,
|
|
3652
|
+
durationMs: firstMs !== void 0 && lastMs !== void 0 ? lastMs - firstMs : void 0,
|
|
3653
|
+
eventCount: events.length,
|
|
3654
|
+
model,
|
|
3655
|
+
cwd,
|
|
3656
|
+
gitBranch,
|
|
3657
|
+
totalUsage,
|
|
3658
|
+
status: sawShutdown || Date.now() - file.mtimeMs > IDLE_GAP_MS2 ? "idle" : "running",
|
|
3659
|
+
firstUserPreview,
|
|
3660
|
+
lastUserPreview,
|
|
3661
|
+
lastAgentPreview,
|
|
3662
|
+
toolCallCount,
|
|
3663
|
+
turnCount,
|
|
3664
|
+
linesAdded,
|
|
3665
|
+
linesRemoved,
|
|
3666
|
+
filesEdited,
|
|
3667
|
+
airTimeMs,
|
|
3668
|
+
activeSegments
|
|
3669
|
+
};
|
|
3670
|
+
return { meta, events };
|
|
3671
|
+
}
|
|
3672
|
+
function clearCopilotCaches() {
|
|
3673
|
+
metaCache3.clear();
|
|
3674
|
+
detailCache3.clear();
|
|
3675
|
+
}
|
|
3676
|
+
async function scanCopilot(root) {
|
|
3677
|
+
const files = await listSessionFiles(root);
|
|
3678
|
+
const out = [];
|
|
3679
|
+
for (const file of files) {
|
|
3680
|
+
const cached = metaCache3.get(file.filePath);
|
|
3681
|
+
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3682
|
+
out.push({ file, meta: cached.meta });
|
|
3683
|
+
continue;
|
|
3684
|
+
}
|
|
3685
|
+
try {
|
|
3686
|
+
const lines = await readJsonl2(file.filePath);
|
|
3687
|
+
const { meta } = parseSession(file, lines);
|
|
3688
|
+
metaCache3.set(file.filePath, { meta, mtimeMs: file.mtimeMs, sizeBytes: file.sizeBytes });
|
|
3689
|
+
out.push({ file, meta });
|
|
3690
|
+
} catch {
|
|
3691
|
+
}
|
|
3692
|
+
}
|
|
3693
|
+
return out;
|
|
3694
|
+
}
|
|
3695
|
+
async function listCopilotSessions(opts = {}) {
|
|
3696
|
+
const root = opts.root ?? DEFAULT_COPILOT_ROOT;
|
|
3697
|
+
const sessions = (await scanCopilot(root)).map((entry) => entry.meta);
|
|
3698
|
+
sessions.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
|
|
3699
|
+
return opts.limit === void 0 ? sessions : sessions.slice(0, opts.limit);
|
|
3700
|
+
}
|
|
3701
|
+
async function getCopilotSession(id, opts = {}) {
|
|
3702
|
+
const root = opts.root ?? DEFAULT_COPILOT_ROOT;
|
|
3703
|
+
const entry = (await scanCopilot(root)).find((candidate) => candidate.meta.id === id);
|
|
3704
|
+
if (!entry)
|
|
3705
|
+
return null;
|
|
3706
|
+
const cached = detailCache3.get(entry.file.filePath);
|
|
3707
|
+
if (cached && cached.mtimeMs === entry.file.mtimeMs && cached.sizeBytes === entry.file.sizeBytes) {
|
|
3708
|
+
return cached.detail;
|
|
3709
|
+
}
|
|
3710
|
+
const lines = await readJsonl2(entry.file.filePath);
|
|
3711
|
+
const { meta, events } = parseSession(entry.file, lines);
|
|
3712
|
+
const detail = { ...meta, events };
|
|
3713
|
+
detailCache3.set(entry.file.filePath, {
|
|
3714
|
+
detail,
|
|
3715
|
+
mtimeMs: entry.file.mtimeMs,
|
|
3716
|
+
sizeBytes: entry.file.sizeBytes
|
|
3717
|
+
});
|
|
3718
|
+
return detail;
|
|
3719
|
+
}
|
|
3720
|
+
function copilotSessionLocalDay(meta) {
|
|
3721
|
+
if (!meta.firstTimestamp)
|
|
3722
|
+
return void 0;
|
|
3723
|
+
const ms = Date.parse(meta.firstTimestamp);
|
|
3724
|
+
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
3725
|
+
}
|
|
3726
|
+
var DEFAULT_COPILOT_ROOT, IDLE_GAP_MS2, metaCache3, detailCache3;
|
|
3727
|
+
var init_copilot = __esm({
|
|
3728
|
+
"../parser/dist/copilot.js"() {
|
|
3729
|
+
"use strict";
|
|
3730
|
+
init_analytics();
|
|
3731
|
+
init_git_project();
|
|
3732
|
+
init_user_input();
|
|
3733
|
+
DEFAULT_COPILOT_ROOT = path3.join(os3.homedir(), ".copilot", "session-state");
|
|
3734
|
+
IDLE_GAP_MS2 = 3 * 60 * 1e3;
|
|
3735
|
+
metaCache3 = /* @__PURE__ */ new Map();
|
|
3736
|
+
detailCache3 = /* @__PURE__ */ new Map();
|
|
3737
|
+
}
|
|
3738
|
+
});
|
|
3739
|
+
|
|
3740
|
+
// ../parser/dist/gemini.js
|
|
3741
|
+
import { promises as fs4 } from "node:fs";
|
|
3742
|
+
import os4 from "node:os";
|
|
3743
|
+
import path4 from "node:path";
|
|
3744
|
+
async function safeReaddir2(p) {
|
|
3745
|
+
return fs4.readdir(p).catch(() => []);
|
|
3746
|
+
}
|
|
3747
|
+
async function listSessionFiles2(root) {
|
|
3322
3748
|
const out = [];
|
|
3323
3749
|
const slugs = await safeReaddir2(root);
|
|
3324
3750
|
for (const slug of slugs) {
|
|
3325
|
-
const chatsDir =
|
|
3751
|
+
const chatsDir = path4.join(root, slug, "chats");
|
|
3326
3752
|
const entries = await safeReaddir2(chatsDir);
|
|
3327
3753
|
for (const entry of entries) {
|
|
3328
3754
|
if (!SESSION_FILE_RE.test(entry))
|
|
3329
3755
|
continue;
|
|
3330
|
-
const full =
|
|
3331
|
-
const stat = await
|
|
3756
|
+
const full = path4.join(chatsDir, entry);
|
|
3757
|
+
const stat = await fs4.stat(full).catch(() => null);
|
|
3332
3758
|
if (!stat || !stat.isFile())
|
|
3333
3759
|
continue;
|
|
3334
3760
|
const filenameId = entry.replace(/\.(jsonl|json)$/, "").split("-").pop() ?? entry;
|
|
@@ -3345,13 +3771,13 @@ async function listSessionFiles(root) {
|
|
|
3345
3771
|
return out;
|
|
3346
3772
|
}
|
|
3347
3773
|
async function loadSlugToCwd() {
|
|
3348
|
-
const stat = await
|
|
3774
|
+
const stat = await fs4.stat(GEMINI_PROJECTS_FILE).catch(() => null);
|
|
3349
3775
|
if (!stat)
|
|
3350
3776
|
return /* @__PURE__ */ new Map();
|
|
3351
3777
|
if (projectsCache && projectsCache.mtimeMs === stat.mtimeMs) {
|
|
3352
3778
|
return projectsCache.slugToCwd;
|
|
3353
3779
|
}
|
|
3354
|
-
const raw = await
|
|
3780
|
+
const raw = await fs4.readFile(GEMINI_PROJECTS_FILE, "utf8").catch(() => "");
|
|
3355
3781
|
let parsed;
|
|
3356
3782
|
try {
|
|
3357
3783
|
parsed = JSON.parse(raw);
|
|
@@ -3376,7 +3802,7 @@ function isMessageRecord(o) {
|
|
|
3376
3802
|
return !!o && typeof o === "object" && typeof o.id === "string" && typeof o.type === "string";
|
|
3377
3803
|
}
|
|
3378
3804
|
async function readAndReplay(file) {
|
|
3379
|
-
const raw = await
|
|
3805
|
+
const raw = await fs4.readFile(file.filePath, "utf8");
|
|
3380
3806
|
if (file.format === "legacy-json") {
|
|
3381
3807
|
let blob;
|
|
3382
3808
|
try {
|
|
@@ -3451,10 +3877,10 @@ async function readAndReplay(file) {
|
|
|
3451
3877
|
}
|
|
3452
3878
|
return { meta, messages };
|
|
3453
3879
|
}
|
|
3454
|
-
function
|
|
3880
|
+
function emptyUsage3() {
|
|
3455
3881
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3456
3882
|
}
|
|
3457
|
-
function
|
|
3883
|
+
function previewOf3(text) {
|
|
3458
3884
|
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3459
3885
|
}
|
|
3460
3886
|
function flattenContent(c) {
|
|
@@ -3493,12 +3919,12 @@ function flattenContent(c) {
|
|
|
3493
3919
|
function truncate3(s, n) {
|
|
3494
3920
|
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
3495
3921
|
}
|
|
3496
|
-
async function
|
|
3922
|
+
async function parseSession2(file) {
|
|
3497
3923
|
const { meta: metaRec, messages } = await readAndReplay(file);
|
|
3498
3924
|
const slugToCwd = await loadSlugToCwd();
|
|
3499
3925
|
const cwd = slugToCwd.get(file.slug);
|
|
3500
3926
|
const events = [];
|
|
3501
|
-
const totalUsage =
|
|
3927
|
+
const totalUsage = emptyUsage3();
|
|
3502
3928
|
let firstTimestamp;
|
|
3503
3929
|
let lastTimestamp;
|
|
3504
3930
|
let model;
|
|
@@ -3524,7 +3950,7 @@ async function parseSession(file) {
|
|
|
3524
3950
|
const ts = msg.timestamp;
|
|
3525
3951
|
if (msg.type === "user") {
|
|
3526
3952
|
const text = flattenContent(msg.displayContent ?? msg.content);
|
|
3527
|
-
const preview =
|
|
3953
|
+
const preview = previewOf3(text);
|
|
3528
3954
|
const isHidden = isFrameworkInjectedUserInput(text);
|
|
3529
3955
|
if (text && !isHidden) {
|
|
3530
3956
|
if (!firstUserPreview)
|
|
@@ -3548,7 +3974,7 @@ async function parseSession(file) {
|
|
|
3548
3974
|
if (typeof msg.model === "string")
|
|
3549
3975
|
model = msg.model;
|
|
3550
3976
|
const text = flattenContent(msg.content);
|
|
3551
|
-
const preview =
|
|
3977
|
+
const preview = previewOf3(text);
|
|
3552
3978
|
if (text)
|
|
3553
3979
|
lastAgentPreview = preview;
|
|
3554
3980
|
let usage;
|
|
@@ -3574,7 +4000,7 @@ async function parseSession(file) {
|
|
|
3574
4000
|
timestamp: th.timestamp ?? ts,
|
|
3575
4001
|
role: "agent-thinking",
|
|
3576
4002
|
rawType: "gemini/thought",
|
|
3577
|
-
preview:
|
|
4003
|
+
preview: previewOf3(thText),
|
|
3578
4004
|
blocks: [{ type: "thinking", thinking: thText }],
|
|
3579
4005
|
model,
|
|
3580
4006
|
raw: th
|
|
@@ -3631,7 +4057,7 @@ async function parseSession(file) {
|
|
|
3631
4057
|
timestamp: tc.timestamp ?? ts,
|
|
3632
4058
|
role: "tool-result",
|
|
3633
4059
|
rawType: "gemini/tool_result",
|
|
3634
|
-
preview:
|
|
4060
|
+
preview: previewOf3(resultText),
|
|
3635
4061
|
blocks: [
|
|
3636
4062
|
{
|
|
3637
4063
|
type: "tool_result",
|
|
@@ -3655,7 +4081,7 @@ async function parseSession(file) {
|
|
|
3655
4081
|
timestamp: ts,
|
|
3656
4082
|
role: "meta",
|
|
3657
4083
|
rawType: `gemini/${msg.type}`,
|
|
3658
|
-
preview:
|
|
4084
|
+
preview: previewOf3(text),
|
|
3659
4085
|
blocks: text ? [{ type: "text", text }] : [],
|
|
3660
4086
|
raw: msg
|
|
3661
4087
|
});
|
|
@@ -3677,7 +4103,7 @@ async function parseSession(file) {
|
|
|
3677
4103
|
prevMs = ms;
|
|
3678
4104
|
}
|
|
3679
4105
|
}
|
|
3680
|
-
const activeSegments =
|
|
4106
|
+
const activeSegments = computeActiveSegments4(tsMs);
|
|
3681
4107
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
3682
4108
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
3683
4109
|
const sessionId = metaRec.sessionId ?? file.filenameId;
|
|
@@ -3711,7 +4137,7 @@ async function parseSession(file) {
|
|
|
3711
4137
|
};
|
|
3712
4138
|
return { meta, events };
|
|
3713
4139
|
}
|
|
3714
|
-
function
|
|
4140
|
+
function computeActiveSegments4(tsMs) {
|
|
3715
4141
|
if (tsMs.length === 0)
|
|
3716
4142
|
return [];
|
|
3717
4143
|
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
@@ -3719,7 +4145,7 @@ function computeActiveSegments3(tsMs) {
|
|
|
3719
4145
|
let segStart = sorted[0];
|
|
3720
4146
|
let segEnd = sorted[0];
|
|
3721
4147
|
for (let i = 1; i < sorted.length; i++) {
|
|
3722
|
-
if (sorted[i] - segEnd >
|
|
4148
|
+
if (sorted[i] - segEnd > IDLE_GAP_MS3) {
|
|
3723
4149
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
3724
4150
|
segStart = sorted[i];
|
|
3725
4151
|
}
|
|
@@ -3729,23 +4155,23 @@ function computeActiveSegments3(tsMs) {
|
|
|
3729
4155
|
return out;
|
|
3730
4156
|
}
|
|
3731
4157
|
function clearGeminiCaches() {
|
|
3732
|
-
|
|
3733
|
-
|
|
4158
|
+
metaCache4.clear();
|
|
4159
|
+
detailCache4.clear();
|
|
3734
4160
|
projectsCache = null;
|
|
3735
4161
|
}
|
|
3736
4162
|
async function listGeminiSessions(opts = {}) {
|
|
3737
4163
|
const root = opts.root ?? DEFAULT_GEMINI_ROOT;
|
|
3738
|
-
const files = await
|
|
4164
|
+
const files = await listSessionFiles2(root);
|
|
3739
4165
|
const out = [];
|
|
3740
4166
|
for (const file of files) {
|
|
3741
|
-
const cached =
|
|
4167
|
+
const cached = metaCache4.get(file.filePath);
|
|
3742
4168
|
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
|
|
3743
4169
|
out.push(cached.meta);
|
|
3744
4170
|
continue;
|
|
3745
4171
|
}
|
|
3746
4172
|
try {
|
|
3747
|
-
const { meta } = await
|
|
3748
|
-
|
|
4173
|
+
const { meta } = await parseSession2(file);
|
|
4174
|
+
metaCache4.set(file.filePath, {
|
|
3749
4175
|
meta,
|
|
3750
4176
|
mtimeMs: file.mtimeMs,
|
|
3751
4177
|
sizeBytes: file.sizeBytes
|
|
@@ -3761,7 +4187,7 @@ async function listGeminiSessions(opts = {}) {
|
|
|
3761
4187
|
}
|
|
3762
4188
|
async function getGeminiSession(id, opts = {}) {
|
|
3763
4189
|
const root = opts.root ?? DEFAULT_GEMINI_ROOT;
|
|
3764
|
-
const files = await
|
|
4190
|
+
const files = await listSessionFiles2(root);
|
|
3765
4191
|
let chosen;
|
|
3766
4192
|
for (const file of files) {
|
|
3767
4193
|
if (file.filenameId === id || id.startsWith(file.filenameId)) {
|
|
@@ -3771,7 +4197,7 @@ async function getGeminiSession(id, opts = {}) {
|
|
|
3771
4197
|
}
|
|
3772
4198
|
if (!chosen) {
|
|
3773
4199
|
for (const file of files) {
|
|
3774
|
-
const { meta: meta2 } = await
|
|
4200
|
+
const { meta: meta2 } = await parseSession2(file).catch(() => ({ meta: { id: "" } }));
|
|
3775
4201
|
if (meta2.id === id) {
|
|
3776
4202
|
chosen = file;
|
|
3777
4203
|
break;
|
|
@@ -3780,13 +4206,13 @@ async function getGeminiSession(id, opts = {}) {
|
|
|
3780
4206
|
}
|
|
3781
4207
|
if (!chosen)
|
|
3782
4208
|
return null;
|
|
3783
|
-
const cached =
|
|
4209
|
+
const cached = detailCache4.get(chosen.filePath);
|
|
3784
4210
|
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
|
|
3785
4211
|
return cached.detail;
|
|
3786
4212
|
}
|
|
3787
|
-
const { meta, events } = await
|
|
4213
|
+
const { meta, events } = await parseSession2(chosen);
|
|
3788
4214
|
const detail = { ...meta, events };
|
|
3789
|
-
|
|
4215
|
+
detailCache4.set(chosen.filePath, {
|
|
3790
4216
|
detail,
|
|
3791
4217
|
mtimeMs: chosen.mtimeMs,
|
|
3792
4218
|
sizeBytes: chosen.sizeBytes
|
|
@@ -3799,39 +4225,39 @@ function geminiSessionLocalDay(meta) {
|
|
|
3799
4225
|
const ms = Date.parse(meta.firstTimestamp);
|
|
3800
4226
|
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
3801
4227
|
}
|
|
3802
|
-
var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE,
|
|
4228
|
+
var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE, IDLE_GAP_MS3, projectsCache, metaCache4, detailCache4;
|
|
3803
4229
|
var init_gemini = __esm({
|
|
3804
4230
|
"../parser/dist/gemini.js"() {
|
|
3805
4231
|
"use strict";
|
|
3806
4232
|
init_analytics();
|
|
3807
4233
|
init_git_project();
|
|
3808
4234
|
init_user_input();
|
|
3809
|
-
DEFAULT_GEMINI_ROOT =
|
|
3810
|
-
GEMINI_PROJECTS_FILE =
|
|
4235
|
+
DEFAULT_GEMINI_ROOT = path4.join(os4.homedir(), ".gemini", "tmp");
|
|
4236
|
+
GEMINI_PROJECTS_FILE = path4.join(os4.homedir(), ".gemini", "projects.json");
|
|
3811
4237
|
SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
|
|
3812
|
-
|
|
4238
|
+
IDLE_GAP_MS3 = 3 * 60 * 1e3;
|
|
3813
4239
|
projectsCache = null;
|
|
3814
|
-
|
|
3815
|
-
|
|
4240
|
+
metaCache4 = /* @__PURE__ */ new Map();
|
|
4241
|
+
detailCache4 = /* @__PURE__ */ new Map();
|
|
3816
4242
|
}
|
|
3817
4243
|
});
|
|
3818
4244
|
|
|
3819
4245
|
// ../parser/dist/antigravity.js
|
|
3820
|
-
import { promises as
|
|
3821
|
-
import
|
|
3822
|
-
import
|
|
4246
|
+
import { promises as fs5 } from "node:fs";
|
|
4247
|
+
import os5 from "node:os";
|
|
4248
|
+
import path5 from "node:path";
|
|
3823
4249
|
async function safeReaddir3(p) {
|
|
3824
|
-
return
|
|
4250
|
+
return fs5.readdir(p).catch(() => []);
|
|
3825
4251
|
}
|
|
3826
4252
|
async function loadSlugToCwd2(root) {
|
|
3827
|
-
const historyFile =
|
|
3828
|
-
const stat = await
|
|
4253
|
+
const historyFile = path5.join(root, "history.jsonl");
|
|
4254
|
+
const stat = await fs5.stat(historyFile).catch(() => null);
|
|
3829
4255
|
if (!stat)
|
|
3830
4256
|
return /* @__PURE__ */ new Map();
|
|
3831
4257
|
if (historyCache && historyCache.mtimeMs === stat.mtimeMs) {
|
|
3832
4258
|
return historyCache.slugToCwd;
|
|
3833
4259
|
}
|
|
3834
|
-
const raw = await
|
|
4260
|
+
const raw = await fs5.readFile(historyFile, "utf8").catch(() => "");
|
|
3835
4261
|
const slugToCwd = /* @__PURE__ */ new Map();
|
|
3836
4262
|
for (const line of raw.split("\n")) {
|
|
3837
4263
|
const trimmed = line.trim();
|
|
@@ -3848,14 +4274,14 @@ async function loadSlugToCwd2(root) {
|
|
|
3848
4274
|
historyCache = { mtimeMs: stat.mtimeMs, slugToCwd };
|
|
3849
4275
|
return slugToCwd;
|
|
3850
4276
|
}
|
|
3851
|
-
async function
|
|
4277
|
+
async function listSessionFiles3(root) {
|
|
3852
4278
|
const slugToCwd = await loadSlugToCwd2(root);
|
|
3853
4279
|
const out = [];
|
|
3854
|
-
const brainDir =
|
|
4280
|
+
const brainDir = path5.join(root, "brain");
|
|
3855
4281
|
const entries = await safeReaddir3(brainDir);
|
|
3856
4282
|
for (const entry of entries) {
|
|
3857
|
-
const transcriptPath =
|
|
3858
|
-
const stat = await
|
|
4283
|
+
const transcriptPath = path5.join(brainDir, entry, ".system_generated", "logs", "transcript.jsonl");
|
|
4284
|
+
const stat = await fs5.stat(transcriptPath).catch(() => null);
|
|
3859
4285
|
if (stat && stat.isFile()) {
|
|
3860
4286
|
out.push({
|
|
3861
4287
|
filePath: transcriptPath,
|
|
@@ -3868,19 +4294,19 @@ async function listSessionFiles2(root) {
|
|
|
3868
4294
|
}
|
|
3869
4295
|
return out;
|
|
3870
4296
|
}
|
|
3871
|
-
function
|
|
4297
|
+
function emptyUsage4() {
|
|
3872
4298
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
3873
4299
|
}
|
|
3874
|
-
function
|
|
4300
|
+
function previewOf4(text) {
|
|
3875
4301
|
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
3876
4302
|
}
|
|
3877
4303
|
function truncate4(s, n) {
|
|
3878
4304
|
return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
|
|
3879
4305
|
}
|
|
3880
|
-
async function
|
|
3881
|
-
const raw = await
|
|
4306
|
+
async function parseSession3(file) {
|
|
4307
|
+
const raw = await fs5.readFile(file.filePath, "utf8");
|
|
3882
4308
|
const events = [];
|
|
3883
|
-
const totalUsage =
|
|
4309
|
+
const totalUsage = emptyUsage4();
|
|
3884
4310
|
let firstTimestamp;
|
|
3885
4311
|
let lastTimestamp;
|
|
3886
4312
|
let model;
|
|
@@ -3952,7 +4378,7 @@ async function parseSession2(file) {
|
|
|
3952
4378
|
if (requestMatch) {
|
|
3953
4379
|
text2 = requestMatch[1].trim();
|
|
3954
4380
|
}
|
|
3955
|
-
const preview =
|
|
4381
|
+
const preview = previewOf4(text2);
|
|
3956
4382
|
const isHidden = isFrameworkInjectedUserInput(text2);
|
|
3957
4383
|
if (text2 && !isHidden) {
|
|
3958
4384
|
if (!firstUserPreview)
|
|
@@ -3981,14 +4407,14 @@ async function parseSession2(file) {
|
|
|
3981
4407
|
timestamp: ts,
|
|
3982
4408
|
role: "agent-thinking",
|
|
3983
4409
|
rawType: "antigravity/thought",
|
|
3984
|
-
preview:
|
|
4410
|
+
preview: previewOf4(thinking),
|
|
3985
4411
|
blocks: [{ type: "thinking", thinking }],
|
|
3986
4412
|
model,
|
|
3987
4413
|
raw: eventObj
|
|
3988
4414
|
});
|
|
3989
4415
|
}
|
|
3990
4416
|
if (content) {
|
|
3991
|
-
const preview =
|
|
4417
|
+
const preview = previewOf4(content);
|
|
3992
4418
|
lastAgentPreview = preview;
|
|
3993
4419
|
pushEvent({
|
|
3994
4420
|
index: idx++,
|
|
@@ -4034,7 +4460,7 @@ async function parseSession2(file) {
|
|
|
4034
4460
|
timestamp: ts,
|
|
4035
4461
|
role: "tool-result",
|
|
4036
4462
|
rawType: "antigravity/tool_result",
|
|
4037
|
-
preview:
|
|
4463
|
+
preview: previewOf4(contentStr),
|
|
4038
4464
|
blocks: [{
|
|
4039
4465
|
type: "tool_result",
|
|
4040
4466
|
tool_use_id: toolUseId,
|
|
@@ -4053,7 +4479,7 @@ async function parseSession2(file) {
|
|
|
4053
4479
|
timestamp: ts,
|
|
4054
4480
|
role: "meta",
|
|
4055
4481
|
rawType: `antigravity/${eventObj.type?.toLowerCase() || "unknown"}`,
|
|
4056
|
-
preview:
|
|
4482
|
+
preview: previewOf4(text),
|
|
4057
4483
|
blocks: text ? [{ type: "text", text }] : [],
|
|
4058
4484
|
raw: eventObj
|
|
4059
4485
|
});
|
|
@@ -4073,7 +4499,7 @@ async function parseSession2(file) {
|
|
|
4073
4499
|
prevMs = ms;
|
|
4074
4500
|
}
|
|
4075
4501
|
}
|
|
4076
|
-
const activeSegments =
|
|
4502
|
+
const activeSegments = computeActiveSegments5(tsMs);
|
|
4077
4503
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
4078
4504
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
4079
4505
|
const sessionId = file.conversationId;
|
|
@@ -4108,7 +4534,7 @@ async function parseSession2(file) {
|
|
|
4108
4534
|
};
|
|
4109
4535
|
return { meta, events };
|
|
4110
4536
|
}
|
|
4111
|
-
function
|
|
4537
|
+
function computeActiveSegments5(tsMs) {
|
|
4112
4538
|
if (tsMs.length === 0)
|
|
4113
4539
|
return [];
|
|
4114
4540
|
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
@@ -4116,7 +4542,7 @@ function computeActiveSegments4(tsMs) {
|
|
|
4116
4542
|
let segStart = sorted[0];
|
|
4117
4543
|
let segEnd = sorted[0];
|
|
4118
4544
|
for (let i = 1; i < sorted.length; i++) {
|
|
4119
|
-
if (sorted[i] - segEnd >
|
|
4545
|
+
if (sorted[i] - segEnd > IDLE_GAP_MS4) {
|
|
4120
4546
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
4121
4547
|
segStart = sorted[i];
|
|
4122
4548
|
}
|
|
@@ -4126,23 +4552,23 @@ function computeActiveSegments4(tsMs) {
|
|
|
4126
4552
|
return out;
|
|
4127
4553
|
}
|
|
4128
4554
|
function clearAntigravityCaches() {
|
|
4129
|
-
|
|
4130
|
-
|
|
4555
|
+
metaCache5.clear();
|
|
4556
|
+
detailCache5.clear();
|
|
4131
4557
|
historyCache = null;
|
|
4132
4558
|
}
|
|
4133
4559
|
async function listAntigravitySessions(opts = {}) {
|
|
4134
4560
|
const root = opts.root ?? DEFAULT_ANTIGRAVITY_ROOT;
|
|
4135
|
-
const files = await
|
|
4561
|
+
const files = await listSessionFiles3(root);
|
|
4136
4562
|
const out = [];
|
|
4137
4563
|
for (const file of files) {
|
|
4138
|
-
const cached =
|
|
4564
|
+
const cached = metaCache5.get(file.filePath);
|
|
4139
4565
|
if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes && cached.cwd === file.cwd) {
|
|
4140
4566
|
out.push(cached.meta);
|
|
4141
4567
|
continue;
|
|
4142
4568
|
}
|
|
4143
4569
|
try {
|
|
4144
|
-
const { meta } = await
|
|
4145
|
-
|
|
4570
|
+
const { meta } = await parseSession3(file);
|
|
4571
|
+
metaCache5.set(file.filePath, {
|
|
4146
4572
|
meta,
|
|
4147
4573
|
mtimeMs: file.mtimeMs,
|
|
4148
4574
|
sizeBytes: file.sizeBytes,
|
|
@@ -4159,7 +4585,7 @@ async function listAntigravitySessions(opts = {}) {
|
|
|
4159
4585
|
}
|
|
4160
4586
|
async function getAntigravitySession(id, opts = {}) {
|
|
4161
4587
|
const root = opts.root ?? DEFAULT_ANTIGRAVITY_ROOT;
|
|
4162
|
-
const files = await
|
|
4588
|
+
const files = await listSessionFiles3(root);
|
|
4163
4589
|
let chosen;
|
|
4164
4590
|
for (const file of files) {
|
|
4165
4591
|
if (file.conversationId === id) {
|
|
@@ -4169,13 +4595,13 @@ async function getAntigravitySession(id, opts = {}) {
|
|
|
4169
4595
|
}
|
|
4170
4596
|
if (!chosen)
|
|
4171
4597
|
return null;
|
|
4172
|
-
const cached =
|
|
4598
|
+
const cached = detailCache5.get(chosen.filePath);
|
|
4173
4599
|
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes && cached.cwd === chosen.cwd) {
|
|
4174
4600
|
return cached.detail;
|
|
4175
4601
|
}
|
|
4176
|
-
const { meta, events } = await
|
|
4602
|
+
const { meta, events } = await parseSession3(chosen);
|
|
4177
4603
|
const detail = { ...meta, events };
|
|
4178
|
-
|
|
4604
|
+
detailCache5.set(chosen.filePath, {
|
|
4179
4605
|
detail,
|
|
4180
4606
|
mtimeMs: chosen.mtimeMs,
|
|
4181
4607
|
sizeBytes: chosen.sizeBytes,
|
|
@@ -4189,61 +4615,61 @@ function antigravitySessionLocalDay(meta) {
|
|
|
4189
4615
|
const ms = Date.parse(meta.firstTimestamp);
|
|
4190
4616
|
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
4191
4617
|
}
|
|
4192
|
-
var DEFAULT_ANTIGRAVITY_ROOT,
|
|
4618
|
+
var DEFAULT_ANTIGRAVITY_ROOT, IDLE_GAP_MS4, historyCache, metaCache5, detailCache5;
|
|
4193
4619
|
var init_antigravity = __esm({
|
|
4194
4620
|
"../parser/dist/antigravity.js"() {
|
|
4195
4621
|
"use strict";
|
|
4196
4622
|
init_analytics();
|
|
4197
4623
|
init_git_project();
|
|
4198
4624
|
init_user_input();
|
|
4199
|
-
DEFAULT_ANTIGRAVITY_ROOT =
|
|
4200
|
-
|
|
4625
|
+
DEFAULT_ANTIGRAVITY_ROOT = path5.join(os5.homedir(), ".gemini", "antigravity-cli");
|
|
4626
|
+
IDLE_GAP_MS4 = 3 * 60 * 1e3;
|
|
4201
4627
|
historyCache = null;
|
|
4202
|
-
|
|
4203
|
-
|
|
4628
|
+
metaCache5 = /* @__PURE__ */ new Map();
|
|
4629
|
+
detailCache5 = /* @__PURE__ */ new Map();
|
|
4204
4630
|
}
|
|
4205
4631
|
});
|
|
4206
4632
|
|
|
4207
4633
|
// ../parser/dist/cowork.js
|
|
4208
|
-
import { promises as
|
|
4209
|
-
import
|
|
4210
|
-
import
|
|
4634
|
+
import { promises as fs6 } from "node:fs";
|
|
4635
|
+
import os6 from "node:os";
|
|
4636
|
+
import path6 from "node:path";
|
|
4211
4637
|
function defaultCoworkRoot() {
|
|
4212
|
-
const home =
|
|
4638
|
+
const home = os6.homedir();
|
|
4213
4639
|
if (process.platform === "darwin") {
|
|
4214
|
-
return
|
|
4640
|
+
return path6.join(home, "Library", "Application Support", "Claude", "local-agent-mode-sessions");
|
|
4215
4641
|
}
|
|
4216
4642
|
if (process.platform === "win32") {
|
|
4217
|
-
const appData = process.env.APPDATA ??
|
|
4218
|
-
return
|
|
4643
|
+
const appData = process.env.APPDATA ?? path6.join(home, "AppData", "Roaming");
|
|
4644
|
+
return path6.join(appData, "Claude", "local-agent-mode-sessions");
|
|
4219
4645
|
}
|
|
4220
|
-
return
|
|
4646
|
+
return path6.join(home, ".config", "Claude", "local-agent-mode-sessions");
|
|
4221
4647
|
}
|
|
4222
4648
|
async function safeReaddir4(p) {
|
|
4223
|
-
return
|
|
4649
|
+
return fs6.readdir(p).catch(() => []);
|
|
4224
4650
|
}
|
|
4225
4651
|
async function statMs(p) {
|
|
4226
|
-
const s = await
|
|
4652
|
+
const s = await fs6.stat(p).catch(() => null);
|
|
4227
4653
|
return s ? s.mtimeMs : 0;
|
|
4228
4654
|
}
|
|
4229
|
-
async function
|
|
4655
|
+
async function listSessionFiles4(root) {
|
|
4230
4656
|
const out = [];
|
|
4231
4657
|
const accounts = await safeReaddir4(root);
|
|
4232
4658
|
for (const accountId of accounts) {
|
|
4233
|
-
const accountDir =
|
|
4659
|
+
const accountDir = path6.join(root, accountId);
|
|
4234
4660
|
const workspaces = await safeReaddir4(accountDir);
|
|
4235
4661
|
for (const workspaceId of workspaces) {
|
|
4236
|
-
const workspaceDir =
|
|
4237
|
-
const spacesMtimeMs = await statMs(
|
|
4662
|
+
const workspaceDir = path6.join(accountDir, workspaceId);
|
|
4663
|
+
const spacesMtimeMs = await statMs(path6.join(workspaceDir, "spaces.json"));
|
|
4238
4664
|
const entries = await safeReaddir4(workspaceDir);
|
|
4239
4665
|
for (const entry of entries) {
|
|
4240
4666
|
if (!SESSION_ID_RE.test(entry))
|
|
4241
4667
|
continue;
|
|
4242
|
-
const auditPath =
|
|
4243
|
-
const auditStat = await
|
|
4668
|
+
const auditPath = path6.join(workspaceDir, entry, "audit.jsonl");
|
|
4669
|
+
const auditStat = await fs6.stat(auditPath).catch(() => null);
|
|
4244
4670
|
if (!auditStat || !auditStat.isFile() || auditStat.size === 0)
|
|
4245
4671
|
continue;
|
|
4246
|
-
const metaPath =
|
|
4672
|
+
const metaPath = path6.join(workspaceDir, `${entry}.json`);
|
|
4247
4673
|
const metaMtimeMs = await statMs(metaPath);
|
|
4248
4674
|
out.push({
|
|
4249
4675
|
sessionId: entry,
|
|
@@ -4261,14 +4687,14 @@ async function listSessionFiles3(root) {
|
|
|
4261
4687
|
return out;
|
|
4262
4688
|
}
|
|
4263
4689
|
async function loadSpacesForWorkspace(workspaceDir) {
|
|
4264
|
-
const spacesPath =
|
|
4265
|
-
const stat = await
|
|
4690
|
+
const spacesPath = path6.join(workspaceDir, "spaces.json");
|
|
4691
|
+
const stat = await fs6.stat(spacesPath).catch(() => null);
|
|
4266
4692
|
if (!stat)
|
|
4267
4693
|
return /* @__PURE__ */ new Map();
|
|
4268
4694
|
const cached = spacesCache.get(workspaceDir);
|
|
4269
4695
|
if (cached && cached.mtimeMs === stat.mtimeMs)
|
|
4270
4696
|
return cached.spaceIdToPath;
|
|
4271
|
-
const raw = await
|
|
4697
|
+
const raw = await fs6.readFile(spacesPath, "utf8").catch(() => "");
|
|
4272
4698
|
const out = /* @__PURE__ */ new Map();
|
|
4273
4699
|
try {
|
|
4274
4700
|
const parsed = JSON.parse(raw);
|
|
@@ -4286,7 +4712,7 @@ async function loadSpacesForWorkspace(workspaceDir) {
|
|
|
4286
4712
|
return out;
|
|
4287
4713
|
}
|
|
4288
4714
|
async function readCoworkMeta(metaPath) {
|
|
4289
|
-
const raw = await
|
|
4715
|
+
const raw = await fs6.readFile(metaPath, "utf8").catch(() => "");
|
|
4290
4716
|
if (!raw)
|
|
4291
4717
|
return {};
|
|
4292
4718
|
try {
|
|
@@ -4322,8 +4748,8 @@ function resolveProject(meta, spaceIdToPath) {
|
|
|
4322
4748
|
cwd: projectPath
|
|
4323
4749
|
};
|
|
4324
4750
|
}
|
|
4325
|
-
async function
|
|
4326
|
-
const raw = await
|
|
4751
|
+
async function readJsonl3(filePath) {
|
|
4752
|
+
const raw = await fs6.readFile(filePath, "utf8");
|
|
4327
4753
|
const out = [];
|
|
4328
4754
|
for (const line of raw.split("\n")) {
|
|
4329
4755
|
const trimmed = line.trim();
|
|
@@ -4459,7 +4885,7 @@ function buildCoworkSubagents(subagentGroups, allLines, sessionStartMs) {
|
|
|
4459
4885
|
}
|
|
4460
4886
|
async function parseCoworkSession(file) {
|
|
4461
4887
|
const [lines, coworkMeta, spaceIdToPath] = await Promise.all([
|
|
4462
|
-
|
|
4888
|
+
readJsonl3(file.auditPath),
|
|
4463
4889
|
readCoworkMeta(file.metaPath),
|
|
4464
4890
|
loadSpacesForWorkspace(file.workspaceDir)
|
|
4465
4891
|
]);
|
|
@@ -4494,24 +4920,24 @@ function cacheKeyMatches(a, b) {
|
|
|
4494
4920
|
return a.auditMtimeMs === b.auditMtimeMs && a.auditSize === b.auditSize && a.metaMtimeMs === b.metaMtimeMs && a.spacesMtimeMs === b.spacesMtimeMs;
|
|
4495
4921
|
}
|
|
4496
4922
|
function clearCoworkCaches() {
|
|
4497
|
-
|
|
4498
|
-
|
|
4923
|
+
metaCache6.clear();
|
|
4924
|
+
detailCache6.clear();
|
|
4499
4925
|
spacesCache.clear();
|
|
4500
4926
|
}
|
|
4501
4927
|
async function listCoworkSessions(opts = {}) {
|
|
4502
4928
|
const root = opts.root ?? DEFAULT_COWORK_ROOT;
|
|
4503
|
-
const files = await
|
|
4929
|
+
const files = await listSessionFiles4(root);
|
|
4504
4930
|
const out = [];
|
|
4505
4931
|
for (const file of files) {
|
|
4506
4932
|
const key = cacheKeyFor(file);
|
|
4507
|
-
const cached =
|
|
4933
|
+
const cached = metaCache6.get(file.auditPath);
|
|
4508
4934
|
if (cached && cacheKeyMatches(cached.key, key)) {
|
|
4509
4935
|
out.push(cached.meta);
|
|
4510
4936
|
continue;
|
|
4511
4937
|
}
|
|
4512
4938
|
try {
|
|
4513
4939
|
const { meta } = await parseCoworkSession(file);
|
|
4514
|
-
|
|
4940
|
+
metaCache6.set(file.auditPath, { meta, key });
|
|
4515
4941
|
out.push(meta);
|
|
4516
4942
|
} catch {
|
|
4517
4943
|
}
|
|
@@ -4523,12 +4949,12 @@ async function listCoworkSessions(opts = {}) {
|
|
|
4523
4949
|
}
|
|
4524
4950
|
async function getCoworkSession(id, opts = {}) {
|
|
4525
4951
|
const root = opts.root ?? DEFAULT_COWORK_ROOT;
|
|
4526
|
-
const files = await
|
|
4952
|
+
const files = await listSessionFiles4(root);
|
|
4527
4953
|
const file = files.find((f) => f.sessionId === id);
|
|
4528
4954
|
if (!file)
|
|
4529
4955
|
return null;
|
|
4530
4956
|
const key = cacheKeyFor(file);
|
|
4531
|
-
const cached =
|
|
4957
|
+
const cached = detailCache6.get(file.auditPath);
|
|
4532
4958
|
if (cached && cacheKeyMatches(cached.key, key))
|
|
4533
4959
|
return cached.detail;
|
|
4534
4960
|
const { meta, events, subagents } = await parseCoworkSession(file);
|
|
@@ -4537,10 +4963,10 @@ async function getCoworkSession(id, opts = {}) {
|
|
|
4537
4963
|
events,
|
|
4538
4964
|
...subagents.length ? { subagents } : {}
|
|
4539
4965
|
};
|
|
4540
|
-
|
|
4966
|
+
detailCache6.set(file.auditPath, { detail, key });
|
|
4541
4967
|
return detail;
|
|
4542
4968
|
}
|
|
4543
|
-
var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache,
|
|
4969
|
+
var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache, metaCache6, detailCache6;
|
|
4544
4970
|
var init_cowork = __esm({
|
|
4545
4971
|
"../parser/dist/cowork.js"() {
|
|
4546
4972
|
"use strict";
|
|
@@ -4550,24 +4976,24 @@ var init_cowork = __esm({
|
|
|
4550
4976
|
DEFAULT_COWORK_ROOT = defaultCoworkRoot();
|
|
4551
4977
|
SESSION_ID_RE = /^local_[0-9a-f-]+$/;
|
|
4552
4978
|
spacesCache = /* @__PURE__ */ new Map();
|
|
4553
|
-
|
|
4554
|
-
|
|
4979
|
+
metaCache6 = /* @__PURE__ */ new Map();
|
|
4980
|
+
detailCache6 = /* @__PURE__ */ new Map();
|
|
4555
4981
|
}
|
|
4556
4982
|
});
|
|
4557
4983
|
|
|
4558
4984
|
// ../parser/dist/grok.js
|
|
4559
|
-
import { promises as
|
|
4560
|
-
import
|
|
4561
|
-
import
|
|
4985
|
+
import { promises as fs7 } from "node:fs";
|
|
4986
|
+
import os7 from "node:os";
|
|
4987
|
+
import path7 from "node:path";
|
|
4562
4988
|
function resolveDefaultGrokRoot() {
|
|
4563
|
-
const home = process.env.GROK_HOME ||
|
|
4564
|
-
return
|
|
4989
|
+
const home = process.env.GROK_HOME || path7.join(os7.homedir(), ".grok");
|
|
4990
|
+
return path7.join(home, "sessions");
|
|
4565
4991
|
}
|
|
4566
4992
|
async function safeReaddir5(p) {
|
|
4567
|
-
return
|
|
4993
|
+
return fs7.readdir(p).catch(() => []);
|
|
4568
4994
|
}
|
|
4569
4995
|
async function safeReadJson(p) {
|
|
4570
|
-
const raw = await
|
|
4996
|
+
const raw = await fs7.readFile(p, "utf8").catch(() => null);
|
|
4571
4997
|
if (raw == null)
|
|
4572
4998
|
return null;
|
|
4573
4999
|
try {
|
|
@@ -4577,8 +5003,8 @@ async function safeReadJson(p) {
|
|
|
4577
5003
|
}
|
|
4578
5004
|
}
|
|
4579
5005
|
async function resolveEncodedCwd(groupDir, encoded) {
|
|
4580
|
-
const cwdFile =
|
|
4581
|
-
const fromFile = await
|
|
5006
|
+
const cwdFile = path7.join(groupDir, ".cwd");
|
|
5007
|
+
const fromFile = await fs7.readFile(cwdFile, "utf8").catch(() => null);
|
|
4582
5008
|
if (fromFile && fromFile.trim())
|
|
4583
5009
|
return fromFile.trim();
|
|
4584
5010
|
try {
|
|
@@ -4593,8 +5019,8 @@ async function listSessionDirs(root) {
|
|
|
4593
5019
|
for (const group of groups) {
|
|
4594
5020
|
if (group === "session_search.sqlite" || group.startsWith("."))
|
|
4595
5021
|
continue;
|
|
4596
|
-
const groupDir =
|
|
4597
|
-
const groupStat = await
|
|
5022
|
+
const groupDir = path7.join(root, group);
|
|
5023
|
+
const groupStat = await fs7.stat(groupDir).catch(() => null);
|
|
4598
5024
|
if (!groupStat?.isDirectory())
|
|
4599
5025
|
continue;
|
|
4600
5026
|
const decodedCwd = await resolveEncodedCwd(groupDir, group);
|
|
@@ -4602,14 +5028,14 @@ async function listSessionDirs(root) {
|
|
|
4602
5028
|
for (const entry of entries) {
|
|
4603
5029
|
if (entry === "prompt_history.jsonl" || entry.startsWith("."))
|
|
4604
5030
|
continue;
|
|
4605
|
-
const dirPath =
|
|
4606
|
-
const summaryPath =
|
|
4607
|
-
const updatesPath =
|
|
4608
|
-
const signalsCandidate =
|
|
5031
|
+
const dirPath = path7.join(groupDir, entry);
|
|
5032
|
+
const summaryPath = path7.join(dirPath, "summary.json");
|
|
5033
|
+
const updatesPath = path7.join(dirPath, "updates.jsonl");
|
|
5034
|
+
const signalsCandidate = path7.join(dirPath, "signals.json");
|
|
4609
5035
|
const [summaryStat, updatesStat, signalsStat] = await Promise.all([
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
5036
|
+
fs7.stat(summaryPath).catch(() => null),
|
|
5037
|
+
fs7.stat(updatesPath).catch(() => null),
|
|
5038
|
+
fs7.stat(signalsCandidate).catch(() => null)
|
|
4613
5039
|
]);
|
|
4614
5040
|
if (!summaryStat?.isFile())
|
|
4615
5041
|
continue;
|
|
@@ -4630,10 +5056,10 @@ async function listSessionDirs(root) {
|
|
|
4630
5056
|
}
|
|
4631
5057
|
return out;
|
|
4632
5058
|
}
|
|
4633
|
-
function
|
|
5059
|
+
function emptyUsage5() {
|
|
4634
5060
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
4635
5061
|
}
|
|
4636
|
-
function
|
|
5062
|
+
function previewOf5(text) {
|
|
4637
5063
|
return text.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
4638
5064
|
}
|
|
4639
5065
|
function truncate5(s, n) {
|
|
@@ -4747,7 +5173,7 @@ function lineTimestampIso(line) {
|
|
|
4747
5173
|
}
|
|
4748
5174
|
return void 0;
|
|
4749
5175
|
}
|
|
4750
|
-
function
|
|
5176
|
+
function computeActiveSegments6(tsMs) {
|
|
4751
5177
|
if (tsMs.length === 0)
|
|
4752
5178
|
return [];
|
|
4753
5179
|
const sorted = [...tsMs].sort((a, b) => a - b);
|
|
@@ -4756,7 +5182,7 @@ function computeActiveSegments5(tsMs) {
|
|
|
4756
5182
|
let segEnd = sorted[0];
|
|
4757
5183
|
for (let i = 1; i < sorted.length; i++) {
|
|
4758
5184
|
const t = sorted[i];
|
|
4759
|
-
if (t - segEnd >
|
|
5185
|
+
if (t - segEnd > IDLE_GAP_MS5) {
|
|
4760
5186
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
4761
5187
|
segStart = t;
|
|
4762
5188
|
}
|
|
@@ -4765,17 +5191,17 @@ function computeActiveSegments5(tsMs) {
|
|
|
4765
5191
|
out.push({ startMs: segStart, endMs: segEnd });
|
|
4766
5192
|
return out;
|
|
4767
5193
|
}
|
|
4768
|
-
async function
|
|
5194
|
+
async function parseSession4(dir) {
|
|
4769
5195
|
const [summary, signals, updatesRaw] = await Promise.all([
|
|
4770
5196
|
safeReadJson(dir.summaryPath),
|
|
4771
5197
|
dir.signalsPath ? safeReadJson(dir.signalsPath) : Promise.resolve(null),
|
|
4772
|
-
|
|
5198
|
+
fs7.readFile(dir.updatesPath, "utf8").catch(() => "")
|
|
4773
5199
|
]);
|
|
4774
5200
|
const sessionId = summary?.info?.id ?? dir.sessionId;
|
|
4775
5201
|
const cwd = summary?.info?.cwd ?? dir.decodedCwd;
|
|
4776
5202
|
let model = summary?.current_model_id ?? signals?.primaryModelId ?? signals?.modelsUsed?.[0];
|
|
4777
5203
|
const events = [];
|
|
4778
|
-
const totalUsage =
|
|
5204
|
+
const totalUsage = emptyUsage5();
|
|
4779
5205
|
if (signals?.contextTokensUsed && signals.contextTokensUsed > 0) {
|
|
4780
5206
|
totalUsage.input = signals.contextTokensUsed;
|
|
4781
5207
|
}
|
|
@@ -4809,7 +5235,7 @@ async function parseSession3(dir) {
|
|
|
4809
5235
|
if (!buf)
|
|
4810
5236
|
return;
|
|
4811
5237
|
const text = buf.texts.join("");
|
|
4812
|
-
const preview =
|
|
5238
|
+
const preview = previewOf5(text);
|
|
4813
5239
|
if (buf.kind === "user") {
|
|
4814
5240
|
const isHidden = !text || isFrameworkInjectedUserInput(text);
|
|
4815
5241
|
if (text && !isHidden) {
|
|
@@ -4969,7 +5395,7 @@ async function parseSession3(dir) {
|
|
|
4969
5395
|
timestamp: ts,
|
|
4970
5396
|
role: "tool-result",
|
|
4971
5397
|
rawType: "grok/tool_result",
|
|
4972
|
-
preview:
|
|
5398
|
+
preview: previewOf5(resultText),
|
|
4973
5399
|
blocks: [
|
|
4974
5400
|
{
|
|
4975
5401
|
type: "tool_result",
|
|
@@ -5018,7 +5444,7 @@ async function parseSession3(dir) {
|
|
|
5018
5444
|
prevMs = ms;
|
|
5019
5445
|
}
|
|
5020
5446
|
}
|
|
5021
|
-
const activeSegments =
|
|
5447
|
+
const activeSegments = computeActiveSegments6(tsMs);
|
|
5022
5448
|
const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
|
|
5023
5449
|
const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
|
|
5024
5450
|
const project = cwd ? resolveProjectIdentity(cwd) : void 0;
|
|
@@ -5027,7 +5453,7 @@ async function parseSession3(dir) {
|
|
|
5027
5453
|
if (!firstUserPreview) {
|
|
5028
5454
|
const title = summary?.generated_title || summary?.session_summary;
|
|
5029
5455
|
if (title)
|
|
5030
|
-
firstUserPreview =
|
|
5456
|
+
firstUserPreview = previewOf5(title);
|
|
5031
5457
|
}
|
|
5032
5458
|
const spawnedAgentCount = await countSubagentChildren(dir.dirPath);
|
|
5033
5459
|
const meta = {
|
|
@@ -5064,38 +5490,38 @@ async function parseSession3(dir) {
|
|
|
5064
5490
|
return { meta, events, sessionKind: summary?.session_kind };
|
|
5065
5491
|
}
|
|
5066
5492
|
async function countSubagentChildren(dirPath) {
|
|
5067
|
-
const subRoot =
|
|
5493
|
+
const subRoot = path7.join(dirPath, "subagents");
|
|
5068
5494
|
const entries = await safeReaddir5(subRoot);
|
|
5069
5495
|
let n = 0;
|
|
5070
5496
|
for (const e of entries) {
|
|
5071
|
-
const st = await
|
|
5497
|
+
const st = await fs7.stat(path7.join(subRoot, e)).catch(() => null);
|
|
5072
5498
|
if (st?.isDirectory())
|
|
5073
5499
|
n += 1;
|
|
5074
5500
|
}
|
|
5075
5501
|
return n;
|
|
5076
5502
|
}
|
|
5077
5503
|
async function loadGrokSubagents(parentDir, parentStartMs) {
|
|
5078
|
-
const subRoot =
|
|
5504
|
+
const subRoot = path7.join(parentDir.dirPath, "subagents");
|
|
5079
5505
|
const entries = await safeReaddir5(subRoot);
|
|
5080
|
-
const groupDir =
|
|
5506
|
+
const groupDir = path7.dirname(parentDir.dirPath);
|
|
5081
5507
|
const runs = [];
|
|
5082
5508
|
for (const entry of entries) {
|
|
5083
|
-
const metaPath =
|
|
5509
|
+
const metaPath = path7.join(subRoot, entry, "meta.json");
|
|
5084
5510
|
const meta = await safeReadJson(metaPath);
|
|
5085
5511
|
if (!meta)
|
|
5086
5512
|
continue;
|
|
5087
5513
|
const childId = meta.child_session_id ?? meta.subagent_id ?? entry;
|
|
5088
|
-
const childDir =
|
|
5514
|
+
const childDir = path7.join(groupDir, childId);
|
|
5089
5515
|
const [childSummary, childSignals] = await Promise.all([
|
|
5090
|
-
safeReadJson(
|
|
5091
|
-
safeReadJson(
|
|
5516
|
+
safeReadJson(path7.join(childDir, "summary.json")),
|
|
5517
|
+
safeReadJson(path7.join(childDir, "signals.json"))
|
|
5092
5518
|
]);
|
|
5093
5519
|
const startMs = childSummary?.created_at ? Date.parse(childSummary.created_at) : void 0;
|
|
5094
5520
|
const endIso = childSummary?.last_active_at ?? childSummary?.updated_at;
|
|
5095
5521
|
const endMs = endIso ? Date.parse(endIso) : void 0;
|
|
5096
5522
|
const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
|
|
5097
5523
|
const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
|
|
5098
|
-
const usage =
|
|
5524
|
+
const usage = emptyUsage5();
|
|
5099
5525
|
if (childSignals?.contextTokensUsed)
|
|
5100
5526
|
usage.input = childSignals.contextTokensUsed;
|
|
5101
5527
|
runs.push({
|
|
@@ -5118,8 +5544,8 @@ async function loadGrokSubagents(parentDir, parentStartMs) {
|
|
|
5118
5544
|
return runs;
|
|
5119
5545
|
}
|
|
5120
5546
|
function clearGrokCaches() {
|
|
5121
|
-
|
|
5122
|
-
|
|
5547
|
+
metaCache7.clear();
|
|
5548
|
+
detailCache7.clear();
|
|
5123
5549
|
}
|
|
5124
5550
|
async function listGrokSessions(opts = {}) {
|
|
5125
5551
|
const root = opts.root ?? resolveDefaultGrokRoot();
|
|
@@ -5129,16 +5555,16 @@ async function listGrokSessions(opts = {}) {
|
|
|
5129
5555
|
const summaryPeek = await safeReadJson(dir.summaryPath);
|
|
5130
5556
|
if (summaryPeek?.session_kind === "subagent")
|
|
5131
5557
|
continue;
|
|
5132
|
-
const cached =
|
|
5558
|
+
const cached = metaCache7.get(dir.dirPath);
|
|
5133
5559
|
if (cached && cached.mtimeMs === dir.mtimeMs && cached.sizeBytes === dir.sizeBytes) {
|
|
5134
5560
|
out.push(cached.meta);
|
|
5135
5561
|
continue;
|
|
5136
5562
|
}
|
|
5137
5563
|
try {
|
|
5138
|
-
const { meta, sessionKind } = await
|
|
5564
|
+
const { meta, sessionKind } = await parseSession4(dir);
|
|
5139
5565
|
if (sessionKind === "subagent")
|
|
5140
5566
|
continue;
|
|
5141
|
-
|
|
5567
|
+
metaCache7.set(dir.dirPath, {
|
|
5142
5568
|
meta,
|
|
5143
5569
|
mtimeMs: dir.mtimeMs,
|
|
5144
5570
|
sizeBytes: dir.sizeBytes
|
|
@@ -5159,10 +5585,10 @@ async function getGrokSession(id, opts = {}) {
|
|
|
5159
5585
|
if (!chosen) {
|
|
5160
5586
|
for (const dir of dirs) {
|
|
5161
5587
|
try {
|
|
5162
|
-
const { meta: meta2, events: events2 } = await
|
|
5588
|
+
const { meta: meta2, events: events2 } = await parseSession4(dir);
|
|
5163
5589
|
if (meta2.id === id) {
|
|
5164
5590
|
const detail2 = { ...meta2, events: events2 };
|
|
5165
|
-
|
|
5591
|
+
detailCache7.set(dir.dirPath, {
|
|
5166
5592
|
detail: detail2,
|
|
5167
5593
|
mtimeMs: dir.mtimeMs,
|
|
5168
5594
|
sizeBytes: dir.sizeBytes
|
|
@@ -5174,11 +5600,11 @@ async function getGrokSession(id, opts = {}) {
|
|
|
5174
5600
|
}
|
|
5175
5601
|
return null;
|
|
5176
5602
|
}
|
|
5177
|
-
const cached =
|
|
5603
|
+
const cached = detailCache7.get(chosen.dirPath);
|
|
5178
5604
|
if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
|
|
5179
5605
|
return cached.detail;
|
|
5180
5606
|
}
|
|
5181
|
-
const { meta, events } = await
|
|
5607
|
+
const { meta, events } = await parseSession4(chosen);
|
|
5182
5608
|
const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
|
|
5183
5609
|
const subagents = await loadGrokSubagents(chosen, parentStartMs !== void 0 && Number.isFinite(parentStartMs) ? parentStartMs : void 0);
|
|
5184
5610
|
const detail = {
|
|
@@ -5186,12 +5612,12 @@ async function getGrokSession(id, opts = {}) {
|
|
|
5186
5612
|
events,
|
|
5187
5613
|
...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
|
|
5188
5614
|
};
|
|
5189
|
-
|
|
5615
|
+
detailCache7.set(chosen.dirPath, {
|
|
5190
5616
|
detail,
|
|
5191
5617
|
mtimeMs: chosen.mtimeMs,
|
|
5192
5618
|
sizeBytes: chosen.sizeBytes
|
|
5193
5619
|
});
|
|
5194
|
-
|
|
5620
|
+
metaCache7.set(chosen.dirPath, {
|
|
5195
5621
|
meta: {
|
|
5196
5622
|
...meta,
|
|
5197
5623
|
...subagents.length > 0 ? { spawnedAgentCount: subagents.length } : {}
|
|
@@ -5207,17 +5633,17 @@ function grokSessionLocalDay(meta) {
|
|
|
5207
5633
|
const ms = Date.parse(meta.firstTimestamp);
|
|
5208
5634
|
return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
|
|
5209
5635
|
}
|
|
5210
|
-
var DEFAULT_GROK_ROOT,
|
|
5636
|
+
var DEFAULT_GROK_ROOT, IDLE_GAP_MS5, metaCache7, detailCache7;
|
|
5211
5637
|
var init_grok = __esm({
|
|
5212
5638
|
"../parser/dist/grok.js"() {
|
|
5213
5639
|
"use strict";
|
|
5214
5640
|
init_analytics();
|
|
5215
5641
|
init_git_project();
|
|
5216
5642
|
init_user_input();
|
|
5217
|
-
DEFAULT_GROK_ROOT =
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5643
|
+
DEFAULT_GROK_ROOT = path7.join(os7.homedir(), ".grok", "sessions");
|
|
5644
|
+
IDLE_GAP_MS5 = 3 * 60 * 1e3;
|
|
5645
|
+
metaCache7 = /* @__PURE__ */ new Map();
|
|
5646
|
+
detailCache7 = /* @__PURE__ */ new Map();
|
|
5221
5647
|
}
|
|
5222
5648
|
});
|
|
5223
5649
|
|
|
@@ -5278,6 +5704,7 @@ var fs_exports = {};
|
|
|
5278
5704
|
__export(fs_exports, {
|
|
5279
5705
|
DEFAULT_ANTIGRAVITY_ROOT: () => DEFAULT_ANTIGRAVITY_ROOT,
|
|
5280
5706
|
DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
|
|
5707
|
+
DEFAULT_COPILOT_ROOT: () => DEFAULT_COPILOT_ROOT,
|
|
5281
5708
|
DEFAULT_COWORK_ROOT: () => DEFAULT_COWORK_ROOT,
|
|
5282
5709
|
DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
|
|
5283
5710
|
DEFAULT_GROK_ROOT: () => DEFAULT_GROK_ROOT,
|
|
@@ -5294,6 +5721,7 @@ __export(fs_exports, {
|
|
|
5294
5721
|
clearGrokCaches: () => clearGrokCaches,
|
|
5295
5722
|
clearTeamConfig: () => clearTeamConfig,
|
|
5296
5723
|
codexSessionLocalDay: () => codexSessionLocalDay,
|
|
5724
|
+
copilotSessionLocalDay: () => copilotSessionLocalDay,
|
|
5297
5725
|
decodeProjectName: () => decodeProjectName,
|
|
5298
5726
|
findTeamLead: () => findTeamLead,
|
|
5299
5727
|
geminiSessionLocalDay: () => geminiSessionLocalDay,
|
|
@@ -5301,6 +5729,7 @@ __export(fs_exports, {
|
|
|
5301
5729
|
getAntigravitySession: () => getAntigravitySession,
|
|
5302
5730
|
getAnySession: () => getAnySession,
|
|
5303
5731
|
getCodexSession: () => getCodexSession,
|
|
5732
|
+
getCopilotSession: () => getCopilotSession,
|
|
5304
5733
|
getCoworkSession: () => getCoworkSession,
|
|
5305
5734
|
getGeminiSession: () => getGeminiSession,
|
|
5306
5735
|
getGrokSession: () => getGrokSession,
|
|
@@ -5312,6 +5741,7 @@ __export(fs_exports, {
|
|
|
5312
5741
|
listAllSessions: () => listAllSessions,
|
|
5313
5742
|
listAntigravitySessions: () => listAntigravitySessions,
|
|
5314
5743
|
listCodexSessions: () => listCodexSessions,
|
|
5744
|
+
listCopilotSessions: () => listCopilotSessions,
|
|
5315
5745
|
listCoworkSessions: () => listCoworkSessions,
|
|
5316
5746
|
listGeminiSessions: () => listGeminiSessions,
|
|
5317
5747
|
listGrokSessions: () => listGrokSessions,
|
|
@@ -5334,14 +5764,14 @@ __export(fs_exports, {
|
|
|
5334
5764
|
walkJsonlFiles: () => walkJsonlFiles,
|
|
5335
5765
|
writeTeamConfig: () => writeTeamConfig
|
|
5336
5766
|
});
|
|
5337
|
-
import { promises as
|
|
5338
|
-
import
|
|
5339
|
-
import
|
|
5767
|
+
import { promises as fs8, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
|
|
5768
|
+
import os8 from "node:os";
|
|
5769
|
+
import path8 from "node:path";
|
|
5340
5770
|
function cclensHome() {
|
|
5341
|
-
return process.env.CCLENS_HOME ||
|
|
5771
|
+
return process.env.CCLENS_HOME || path8.join(os8.homedir(), ".cclens");
|
|
5342
5772
|
}
|
|
5343
5773
|
function cclensPath(...parts) {
|
|
5344
|
-
return
|
|
5774
|
+
return path8.join(cclensHome(), ...parts);
|
|
5345
5775
|
}
|
|
5346
5776
|
function cacheStats() {
|
|
5347
5777
|
return claudeCodeCacheStats();
|
|
@@ -5349,6 +5779,7 @@ function cacheStats() {
|
|
|
5349
5779
|
function clearCaches() {
|
|
5350
5780
|
clearClaudeCodeCaches();
|
|
5351
5781
|
clearCodexCaches();
|
|
5782
|
+
clearCopilotCaches();
|
|
5352
5783
|
clearGeminiCaches();
|
|
5353
5784
|
clearAntigravityCaches();
|
|
5354
5785
|
clearCoworkCaches();
|
|
@@ -5383,7 +5814,7 @@ function usageLogPath() {
|
|
|
5383
5814
|
}
|
|
5384
5815
|
function appendUsageSnapshot(snapshot) {
|
|
5385
5816
|
const p = usageLogPath();
|
|
5386
|
-
mkdirSync2(
|
|
5817
|
+
mkdirSync2(path8.dirname(p), { recursive: true });
|
|
5387
5818
|
appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
|
|
5388
5819
|
}
|
|
5389
5820
|
function pruneUsageAgent(agent) {
|
|
@@ -5399,13 +5830,13 @@ function pruneUsageAgent(agent) {
|
|
|
5399
5830
|
return true;
|
|
5400
5831
|
}
|
|
5401
5832
|
});
|
|
5402
|
-
mkdirSync2(
|
|
5833
|
+
mkdirSync2(path8.dirname(p), { recursive: true });
|
|
5403
5834
|
writeFileSync2(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
5404
5835
|
}
|
|
5405
5836
|
async function loadUsageByDay(start, end) {
|
|
5406
5837
|
let raw;
|
|
5407
5838
|
try {
|
|
5408
|
-
raw = await
|
|
5839
|
+
raw = await fs8.readFile(usageLogPath(), "utf8");
|
|
5409
5840
|
} catch {
|
|
5410
5841
|
return { by_day: [] };
|
|
5411
5842
|
}
|
|
@@ -5450,7 +5881,7 @@ async function loadUsageByDay(start, end) {
|
|
|
5450
5881
|
async function loadCalibrationSnapshots() {
|
|
5451
5882
|
let raw;
|
|
5452
5883
|
try {
|
|
5453
|
-
raw = await
|
|
5884
|
+
raw = await fs8.readFile(usageLogPath(), "utf8");
|
|
5454
5885
|
} catch {
|
|
5455
5886
|
return [];
|
|
5456
5887
|
}
|
|
@@ -5614,7 +6045,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
|
|
|
5614
6045
|
]);
|
|
5615
6046
|
return buildCalibrationCurve(events, snapshots, tier, granularityMin);
|
|
5616
6047
|
}
|
|
5617
|
-
var codexSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
|
|
6048
|
+
var codexSource, copilotSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
|
|
5618
6049
|
var init_fs = __esm({
|
|
5619
6050
|
"../parser/dist/fs.js"() {
|
|
5620
6051
|
"use strict";
|
|
@@ -5623,6 +6054,7 @@ var init_fs = __esm({
|
|
|
5623
6054
|
init_calibration();
|
|
5624
6055
|
init_claude_code();
|
|
5625
6056
|
init_codex();
|
|
6057
|
+
init_copilot();
|
|
5626
6058
|
init_gemini();
|
|
5627
6059
|
init_antigravity();
|
|
5628
6060
|
init_cowork();
|
|
@@ -5630,6 +6062,7 @@ var init_fs = __esm({
|
|
|
5630
6062
|
init_claude_code();
|
|
5631
6063
|
init_git_project();
|
|
5632
6064
|
init_codex();
|
|
6065
|
+
init_copilot();
|
|
5633
6066
|
init_gemini();
|
|
5634
6067
|
init_antigravity();
|
|
5635
6068
|
init_cowork();
|
|
@@ -5644,18 +6077,16 @@ var init_fs = __esm({
|
|
|
5644
6077
|
},
|
|
5645
6078
|
async getSession(id) {
|
|
5646
6079
|
return getCodexSession(id);
|
|
6080
|
+
}
|
|
6081
|
+
};
|
|
6082
|
+
copilotSource = {
|
|
6083
|
+
...COPILOT_METADATA,
|
|
6084
|
+
defaultRoot: DEFAULT_COPILOT_ROOT,
|
|
6085
|
+
async listSessions(opts) {
|
|
6086
|
+
return listCopilotSessions(opts);
|
|
5647
6087
|
},
|
|
5648
|
-
async
|
|
5649
|
-
|
|
5650
|
-
if (!w)
|
|
5651
|
-
return null;
|
|
5652
|
-
return {
|
|
5653
|
-
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5654
|
-
agent: "codex",
|
|
5655
|
-
five_hour: w.five_hour,
|
|
5656
|
-
seven_day: w.seven_day,
|
|
5657
|
-
plan_type: w.plan_type
|
|
5658
|
-
};
|
|
6088
|
+
async getSession(id, opts) {
|
|
6089
|
+
return getCopilotSession(id, opts);
|
|
5659
6090
|
}
|
|
5660
6091
|
};
|
|
5661
6092
|
geminiSource = {
|
|
@@ -5702,6 +6133,7 @@ var init_fs = __esm({
|
|
|
5702
6133
|
agentSources = [
|
|
5703
6134
|
claudeCodeSource,
|
|
5704
6135
|
codexSource,
|
|
6136
|
+
copilotSource,
|
|
5705
6137
|
geminiSource,
|
|
5706
6138
|
antigravitySource,
|
|
5707
6139
|
coworkSource,
|
|
@@ -5711,15 +6143,15 @@ var init_fs = __esm({
|
|
|
5711
6143
|
});
|
|
5712
6144
|
|
|
5713
6145
|
// src/usage/storage.ts
|
|
5714
|
-
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as
|
|
5715
|
-
import { dirname as
|
|
6146
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync7 } from "node:fs";
|
|
6147
|
+
import { dirname as dirname3 } from "node:path";
|
|
5716
6148
|
function appendSnapshot(filePath, snapshot) {
|
|
5717
|
-
mkdirSync3(
|
|
6149
|
+
mkdirSync3(dirname3(filePath), { recursive: true });
|
|
5718
6150
|
appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
|
|
5719
6151
|
}
|
|
5720
6152
|
function readSnapshots(filePath) {
|
|
5721
|
-
if (!
|
|
5722
|
-
const content =
|
|
6153
|
+
if (!existsSync7(filePath)) return [];
|
|
6154
|
+
const content = readFileSync8(filePath, "utf8");
|
|
5723
6155
|
const snapshots = [];
|
|
5724
6156
|
for (const line of content.split("\n")) {
|
|
5725
6157
|
if (!line.trim()) continue;
|
|
@@ -5731,8 +6163,8 @@ function readSnapshots(filePath) {
|
|
|
5731
6163
|
return snapshots;
|
|
5732
6164
|
}
|
|
5733
6165
|
function pruneAgent(filePath, agent) {
|
|
5734
|
-
if (!
|
|
5735
|
-
const kept =
|
|
6166
|
+
if (!existsSync7(filePath)) return;
|
|
6167
|
+
const kept = readFileSync8(filePath, "utf8").split("\n").filter((line) => {
|
|
5736
6168
|
if (!line.trim()) return false;
|
|
5737
6169
|
try {
|
|
5738
6170
|
return JSON.parse(line).agent !== agent;
|
|
@@ -5740,8 +6172,8 @@ function pruneAgent(filePath, agent) {
|
|
|
5740
6172
|
return true;
|
|
5741
6173
|
}
|
|
5742
6174
|
});
|
|
5743
|
-
mkdirSync3(
|
|
5744
|
-
|
|
6175
|
+
mkdirSync3(dirname3(filePath), { recursive: true });
|
|
6176
|
+
writeFileSync4(filePath, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
|
|
5745
6177
|
}
|
|
5746
6178
|
function latestClaudeCodeSnapshot(filePath) {
|
|
5747
6179
|
const all = readSnapshots(filePath);
|
|
@@ -6168,6 +6600,7 @@ __export(dist_exports, {
|
|
|
6168
6600
|
ANTIGRAVITY_METADATA: () => ANTIGRAVITY_METADATA,
|
|
6169
6601
|
CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
|
|
6170
6602
|
CODEX_METADATA: () => CODEX_METADATA,
|
|
6603
|
+
COPILOT_METADATA: () => COPILOT_METADATA,
|
|
6171
6604
|
COWORK_METADATA: () => COWORK_METADATA,
|
|
6172
6605
|
GEMINI_METADATA: () => GEMINI_METADATA,
|
|
6173
6606
|
GROK_METADATA: () => GROK_METADATA,
|
|
@@ -6244,25 +6677,25 @@ __export(file_probe_exports, {
|
|
|
6244
6677
|
probeArtifactSignals: () => probeArtifactSignals
|
|
6245
6678
|
});
|
|
6246
6679
|
import { createHash } from "node:crypto";
|
|
6247
|
-
import { existsSync as
|
|
6680
|
+
import { existsSync as existsSync12, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
|
|
6248
6681
|
import { homedir as homedir3 } from "node:os";
|
|
6249
|
-
import { join as
|
|
6682
|
+
import { join as join9, relative, resolve as resolve3, sep } from "node:path";
|
|
6250
6683
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
6251
6684
|
function pathHash(relPath) {
|
|
6252
6685
|
return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
|
|
6253
6686
|
}
|
|
6254
6687
|
function defaultScanRoots(extraRoots = []) {
|
|
6255
6688
|
const roots = [];
|
|
6256
|
-
const home =
|
|
6257
|
-
if (
|
|
6689
|
+
const home = join9(homedir3(), ".claude");
|
|
6690
|
+
if (existsSync12(home)) roots.push({ root: home, label: "user" });
|
|
6258
6691
|
for (const e of extraRoots) {
|
|
6259
6692
|
const r = resolve3(e, ".claude");
|
|
6260
|
-
if (
|
|
6693
|
+
if (existsSync12(r) && r !== home) roots.push({ root: r, label: "project" });
|
|
6261
6694
|
}
|
|
6262
6695
|
return roots;
|
|
6263
6696
|
}
|
|
6264
6697
|
function listMarkdownFiles(dir) {
|
|
6265
|
-
if (!
|
|
6698
|
+
if (!existsSync12(dir)) return [];
|
|
6266
6699
|
const out = [];
|
|
6267
6700
|
let entries;
|
|
6268
6701
|
try {
|
|
@@ -6272,7 +6705,7 @@ function listMarkdownFiles(dir) {
|
|
|
6272
6705
|
}
|
|
6273
6706
|
for (const name of entries) {
|
|
6274
6707
|
if (name.startsWith(".")) continue;
|
|
6275
|
-
const full =
|
|
6708
|
+
const full = join9(dir, name);
|
|
6276
6709
|
let stat;
|
|
6277
6710
|
try {
|
|
6278
6711
|
stat = statSync5(full);
|
|
@@ -6292,7 +6725,7 @@ function firstSeenDateOf(file) {
|
|
|
6292
6725
|
const out = execFileSync2(
|
|
6293
6726
|
"git",
|
|
6294
6727
|
["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
|
|
6295
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
6728
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname9(file) }
|
|
6296
6729
|
).trim().split("\n").filter(Boolean);
|
|
6297
6730
|
if (out.length > 0) return out[out.length - 1];
|
|
6298
6731
|
} catch {
|
|
@@ -6304,7 +6737,7 @@ function firstSeenDateOf(file) {
|
|
|
6304
6737
|
return todayLocal();
|
|
6305
6738
|
}
|
|
6306
6739
|
}
|
|
6307
|
-
function
|
|
6740
|
+
function dirname9(p) {
|
|
6308
6741
|
const i = p.lastIndexOf(sep);
|
|
6309
6742
|
return i < 0 ? "." : p.slice(0, i);
|
|
6310
6743
|
}
|
|
@@ -6331,8 +6764,8 @@ function todayLocal() {
|
|
|
6331
6764
|
function scanAuthored(roots, subdir, day) {
|
|
6332
6765
|
const out = [];
|
|
6333
6766
|
for (const r of roots) {
|
|
6334
|
-
const dir =
|
|
6335
|
-
if (!
|
|
6767
|
+
const dir = join9(r.root, subdir);
|
|
6768
|
+
if (!existsSync12(dir)) continue;
|
|
6336
6769
|
for (const f of listMarkdownFiles(dir)) {
|
|
6337
6770
|
const firstSeen = firstSeenDateOf(f);
|
|
6338
6771
|
if (firstSeen !== day) continue;
|
|
@@ -6345,8 +6778,8 @@ function scanAuthored(roots, subdir, day) {
|
|
|
6345
6778
|
function scanEdited(roots, day) {
|
|
6346
6779
|
const out = [];
|
|
6347
6780
|
for (const r of roots) {
|
|
6348
|
-
const dir =
|
|
6349
|
-
if (!
|
|
6781
|
+
const dir = join9(r.root, "skills");
|
|
6782
|
+
if (!existsSync12(dir)) continue;
|
|
6350
6783
|
for (const f of listMarkdownFiles(dir)) {
|
|
6351
6784
|
const firstSeen = firstSeenDateOf(f);
|
|
6352
6785
|
if (firstSeen === day) continue;
|
|
@@ -6369,16 +6802,16 @@ function claudemdLineDelta(extraRoots, authorEmail, day) {
|
|
|
6369
6802
|
const candidates = [];
|
|
6370
6803
|
for (const e of extraRoots) {
|
|
6371
6804
|
const f = resolve3(e, "CLAUDE.md");
|
|
6372
|
-
if (
|
|
6805
|
+
if (existsSync12(f)) candidates.push(f);
|
|
6373
6806
|
}
|
|
6374
|
-
const homeClaudeMd =
|
|
6375
|
-
if (
|
|
6807
|
+
const homeClaudeMd = join9(homedir3(), "CLAUDE.md");
|
|
6808
|
+
if (existsSync12(homeClaudeMd)) candidates.push(homeClaudeMd);
|
|
6376
6809
|
for (const file of candidates) {
|
|
6377
6810
|
try {
|
|
6378
6811
|
const out = execFileSync2(
|
|
6379
6812
|
"git",
|
|
6380
6813
|
["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
|
|
6381
|
-
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd:
|
|
6814
|
+
{ encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname9(file) }
|
|
6382
6815
|
);
|
|
6383
6816
|
let currentDate = "";
|
|
6384
6817
|
let currentEmail = "";
|
|
@@ -6428,9 +6861,9 @@ var init_file_probe = __esm({
|
|
|
6428
6861
|
});
|
|
6429
6862
|
|
|
6430
6863
|
// src/daemon-worker.ts
|
|
6431
|
-
import { spawn as
|
|
6432
|
-
import { closeSync, existsSync as
|
|
6433
|
-
import { dirname as
|
|
6864
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
6865
|
+
import { closeSync, existsSync as existsSync19, mkdirSync as mkdirSync14, openSync, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
|
|
6866
|
+
import { dirname as dirname12, join as join13 } from "node:path";
|
|
6434
6867
|
import { fileURLToPath } from "node:url";
|
|
6435
6868
|
|
|
6436
6869
|
// src/usage/token.ts
|
|
@@ -6461,9 +6894,9 @@ function readFromCredentialsFile() {
|
|
|
6461
6894
|
join(homedir(), ".claude", ".credentials.json"),
|
|
6462
6895
|
join(homedir(), ".config", "claude", "credentials.json")
|
|
6463
6896
|
];
|
|
6464
|
-
for (const
|
|
6897
|
+
for (const path11 of candidates) {
|
|
6465
6898
|
try {
|
|
6466
|
-
const blob = readFileSync(
|
|
6899
|
+
const blob = readFileSync(path11, "utf8");
|
|
6467
6900
|
const creds = extractCredentials(blob);
|
|
6468
6901
|
if (creds) return creds;
|
|
6469
6902
|
} catch {
|
|
@@ -6677,8 +7110,8 @@ async function fetchZaiUsage() {
|
|
|
6677
7110
|
|
|
6678
7111
|
// src/usage/grok.ts
|
|
6679
7112
|
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
|
|
6680
|
-
import
|
|
6681
|
-
import
|
|
7113
|
+
import os9 from "node:os";
|
|
7114
|
+
import path9 from "node:path";
|
|
6682
7115
|
var CREDITS_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
|
|
6683
7116
|
var SETTINGS_URL = "https://cli-chat-proxy.grok.com/v1/settings";
|
|
6684
7117
|
var REFRESH_URL = "https://auth.x.ai/oauth2/token";
|
|
@@ -6693,10 +7126,10 @@ var GrokApiError = class extends Error {
|
|
|
6693
7126
|
}
|
|
6694
7127
|
};
|
|
6695
7128
|
function grokHome() {
|
|
6696
|
-
return process.env.GROK_HOME ||
|
|
7129
|
+
return process.env.GROK_HOME || path9.join(os9.homedir(), ".grok");
|
|
6697
7130
|
}
|
|
6698
7131
|
function authPath() {
|
|
6699
|
-
return
|
|
7132
|
+
return path9.join(grokHome(), "auth.json");
|
|
6700
7133
|
}
|
|
6701
7134
|
function loadAuthEntry() {
|
|
6702
7135
|
const p = authPath();
|
|
@@ -6759,8 +7192,8 @@ async function refreshAccessToken(entry) {
|
|
|
6759
7192
|
break;
|
|
6760
7193
|
}
|
|
6761
7194
|
}
|
|
6762
|
-
const { writeFileSync:
|
|
6763
|
-
|
|
7195
|
+
const { writeFileSync: writeFileSync16 } = await import("node:fs");
|
|
7196
|
+
writeFileSync16(p, JSON.stringify(raw, null, 2), "utf8");
|
|
6764
7197
|
} catch {
|
|
6765
7198
|
}
|
|
6766
7199
|
return j.access_token;
|
|
@@ -6887,6 +7320,488 @@ async function fetchGrokUsage() {
|
|
|
6887
7320
|
};
|
|
6888
7321
|
}
|
|
6889
7322
|
|
|
7323
|
+
// src/usage/codex.ts
|
|
7324
|
+
import {
|
|
7325
|
+
existsSync as existsSync5,
|
|
7326
|
+
readFileSync as readFileSync7,
|
|
7327
|
+
writeFileSync as writeFileSync3
|
|
7328
|
+
} from "node:fs";
|
|
7329
|
+
import os10 from "node:os";
|
|
7330
|
+
import path10 from "node:path";
|
|
7331
|
+
var USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
|
|
7332
|
+
var REFRESH_URL2 = "https://auth.openai.com/oauth/token";
|
|
7333
|
+
var CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
7334
|
+
var FIVE_HOUR_SECONDS = 5 * 60 * 60;
|
|
7335
|
+
var SEVEN_DAY_SECONDS = 7 * 24 * 60 * 60;
|
|
7336
|
+
var REFRESH_BUFFER_MS2 = 5 * 60 * 1e3;
|
|
7337
|
+
var CodexApiError = class extends Error {
|
|
7338
|
+
constructor(message, code) {
|
|
7339
|
+
super(message);
|
|
7340
|
+
this.code = code;
|
|
7341
|
+
}
|
|
7342
|
+
};
|
|
7343
|
+
function codexHome() {
|
|
7344
|
+
const env = process.env.CODEX_HOME?.trim();
|
|
7345
|
+
if (env) return env;
|
|
7346
|
+
return path10.join(os10.homedir(), ".codex");
|
|
7347
|
+
}
|
|
7348
|
+
function authPath2() {
|
|
7349
|
+
return path10.join(codexHome(), "auth.json");
|
|
7350
|
+
}
|
|
7351
|
+
function loadAuth() {
|
|
7352
|
+
const p = authPath2();
|
|
7353
|
+
if (!existsSync5(p)) {
|
|
7354
|
+
throw new CodexApiError(
|
|
7355
|
+
"Codex not logged in. Run `codex` to authenticate.",
|
|
7356
|
+
"no_auth"
|
|
7357
|
+
);
|
|
7358
|
+
}
|
|
7359
|
+
let auth;
|
|
7360
|
+
try {
|
|
7361
|
+
auth = JSON.parse(readFileSync7(p, "utf8"));
|
|
7362
|
+
} catch {
|
|
7363
|
+
throw new CodexApiError(
|
|
7364
|
+
"Codex auth.json is unreadable. Run `codex` to log in again.",
|
|
7365
|
+
"no_auth"
|
|
7366
|
+
);
|
|
7367
|
+
}
|
|
7368
|
+
const access = auth.tokens?.access_token?.trim();
|
|
7369
|
+
if (!access) {
|
|
7370
|
+
if (auth.OPENAI_API_KEY?.trim()) {
|
|
7371
|
+
throw new CodexApiError(
|
|
7372
|
+
"Codex usage is not available for API-key-only auth. Sign in with a ChatGPT account via `codex`.",
|
|
7373
|
+
"api_key_only"
|
|
7374
|
+
);
|
|
7375
|
+
}
|
|
7376
|
+
throw new CodexApiError(
|
|
7377
|
+
"Codex auth has no access token. Run `codex` to log in.",
|
|
7378
|
+
"no_auth"
|
|
7379
|
+
);
|
|
7380
|
+
}
|
|
7381
|
+
return { auth, path: p };
|
|
7382
|
+
}
|
|
7383
|
+
function accessTokenExpiresAtMs(token) {
|
|
7384
|
+
const parts = token.split(".");
|
|
7385
|
+
if (parts.length < 2) return null;
|
|
7386
|
+
try {
|
|
7387
|
+
const pad = "=".repeat((4 - parts[1].length % 4) % 4);
|
|
7388
|
+
const json = Buffer.from(parts[1] + pad, "base64url").toString("utf8");
|
|
7389
|
+
const payload = JSON.parse(json);
|
|
7390
|
+
if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
|
|
7391
|
+
return null;
|
|
7392
|
+
}
|
|
7393
|
+
return payload.exp * 1e3;
|
|
7394
|
+
} catch {
|
|
7395
|
+
return null;
|
|
7396
|
+
}
|
|
7397
|
+
}
|
|
7398
|
+
function needsRefresh2(accessToken, lastRefresh, nowMs = Date.now()) {
|
|
7399
|
+
const expMs = accessTokenExpiresAtMs(accessToken);
|
|
7400
|
+
if (expMs !== null) {
|
|
7401
|
+
return nowMs >= expMs - REFRESH_BUFFER_MS2;
|
|
7402
|
+
}
|
|
7403
|
+
if (!lastRefresh) return false;
|
|
7404
|
+
const ms = Date.parse(lastRefresh);
|
|
7405
|
+
if (!Number.isFinite(ms)) return false;
|
|
7406
|
+
return nowMs - ms > 8 * 24 * 60 * 60 * 1e3;
|
|
7407
|
+
}
|
|
7408
|
+
async function refreshAccessToken2(auth, filePath) {
|
|
7409
|
+
const refresh = auth.tokens?.refresh_token?.trim();
|
|
7410
|
+
if (!refresh) return null;
|
|
7411
|
+
const body = new URLSearchParams({
|
|
7412
|
+
grant_type: "refresh_token",
|
|
7413
|
+
client_id: CLIENT_ID,
|
|
7414
|
+
refresh_token: refresh
|
|
7415
|
+
});
|
|
7416
|
+
let res;
|
|
7417
|
+
try {
|
|
7418
|
+
res = await fetch(REFRESH_URL2, {
|
|
7419
|
+
method: "POST",
|
|
7420
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
7421
|
+
body: body.toString()
|
|
7422
|
+
});
|
|
7423
|
+
} catch {
|
|
7424
|
+
return null;
|
|
7425
|
+
}
|
|
7426
|
+
if (!res.ok) return null;
|
|
7427
|
+
try {
|
|
7428
|
+
const j = await res.json();
|
|
7429
|
+
if (typeof j.access_token !== "string" || !j.access_token) return null;
|
|
7430
|
+
const next = {
|
|
7431
|
+
...auth,
|
|
7432
|
+
tokens: {
|
|
7433
|
+
...auth.tokens,
|
|
7434
|
+
access_token: j.access_token,
|
|
7435
|
+
refresh_token: j.refresh_token ?? auth.tokens?.refresh_token,
|
|
7436
|
+
id_token: j.id_token ?? auth.tokens?.id_token
|
|
7437
|
+
},
|
|
7438
|
+
last_refresh: (/* @__PURE__ */ new Date()).toISOString()
|
|
7439
|
+
};
|
|
7440
|
+
try {
|
|
7441
|
+
writeFileSync3(filePath, `${JSON.stringify(next, null, 2)}
|
|
7442
|
+
`, {
|
|
7443
|
+
encoding: "utf8",
|
|
7444
|
+
mode: 384
|
|
7445
|
+
});
|
|
7446
|
+
} catch {
|
|
7447
|
+
}
|
|
7448
|
+
return { accessToken: j.access_token, auth: next };
|
|
7449
|
+
} catch {
|
|
7450
|
+
return null;
|
|
7451
|
+
}
|
|
7452
|
+
}
|
|
7453
|
+
function authHeaders2(accessToken, accountId) {
|
|
7454
|
+
const headers = {
|
|
7455
|
+
Authorization: `Bearer ${accessToken}`,
|
|
7456
|
+
Accept: "application/json",
|
|
7457
|
+
"User-Agent": "fleetlens"
|
|
7458
|
+
};
|
|
7459
|
+
if (accountId?.trim()) {
|
|
7460
|
+
headers["ChatGPT-Account-Id"] = accountId.trim();
|
|
7461
|
+
}
|
|
7462
|
+
return headers;
|
|
7463
|
+
}
|
|
7464
|
+
function numberOf3(v) {
|
|
7465
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
7466
|
+
if (typeof v === "string" && v.trim()) {
|
|
7467
|
+
const n = Number(v);
|
|
7468
|
+
if (Number.isFinite(n)) return n;
|
|
7469
|
+
}
|
|
7470
|
+
return void 0;
|
|
7471
|
+
}
|
|
7472
|
+
function windowSeconds(raw) {
|
|
7473
|
+
if (!raw) return void 0;
|
|
7474
|
+
const sec = numberOf3(raw.limit_window_seconds);
|
|
7475
|
+
if (sec !== void 0) return sec;
|
|
7476
|
+
const minutes = numberOf3(raw.window_minutes);
|
|
7477
|
+
if (minutes !== void 0) return minutes * 60;
|
|
7478
|
+
return void 0;
|
|
7479
|
+
}
|
|
7480
|
+
function normalizeWindow2(raw, headerPercent, nowMs) {
|
|
7481
|
+
const used = numberOf3(raw?.used_percent) ?? headerPercent;
|
|
7482
|
+
if (used === void 0) return null;
|
|
7483
|
+
let resetsAt = null;
|
|
7484
|
+
const resetUnix = numberOf3(raw?.reset_at) ?? numberOf3(raw?.resets_at);
|
|
7485
|
+
if (resetUnix !== void 0) {
|
|
7486
|
+
resetsAt = new Date(resetUnix * 1e3).toISOString();
|
|
7487
|
+
} else {
|
|
7488
|
+
const after = numberOf3(raw?.reset_after_seconds);
|
|
7489
|
+
if (after !== void 0) {
|
|
7490
|
+
resetsAt = new Date(nowMs + after * 1e3).toISOString();
|
|
7491
|
+
}
|
|
7492
|
+
}
|
|
7493
|
+
return {
|
|
7494
|
+
utilization: Math.min(100, Math.max(0, used)),
|
|
7495
|
+
resets_at: resetsAt
|
|
7496
|
+
};
|
|
7497
|
+
}
|
|
7498
|
+
function parseCodexWhamUsage(body, headers = {}, nowMs = Date.now()) {
|
|
7499
|
+
if (!body || typeof body !== "object") {
|
|
7500
|
+
throw new CodexApiError("Codex usage response missing body", "parse");
|
|
7501
|
+
}
|
|
7502
|
+
const b = body;
|
|
7503
|
+
const rateLimit = b.rate_limit && typeof b.rate_limit === "object" ? b.rate_limit : {};
|
|
7504
|
+
const headerPrimary = numberOf3(headers["x-codex-primary-used-percent"]);
|
|
7505
|
+
const headerSecondary = numberOf3(headers["x-codex-secondary-used-percent"]);
|
|
7506
|
+
const primary = rateLimit.primary_window && typeof rateLimit.primary_window === "object" ? rateLimit.primary_window : null;
|
|
7507
|
+
const secondary = rateLimit.secondary_window && typeof rateLimit.secondary_window === "object" ? rateLimit.secondary_window : null;
|
|
7508
|
+
const candidates = [
|
|
7509
|
+
{ raw: primary, headerPercent: headerPrimary, fallback: "five_hour" },
|
|
7510
|
+
{ raw: secondary, headerPercent: headerSecondary, fallback: "seven_day" }
|
|
7511
|
+
];
|
|
7512
|
+
let fiveHour = null;
|
|
7513
|
+
let sevenDay = null;
|
|
7514
|
+
for (const c of candidates) {
|
|
7515
|
+
const secs = windowSeconds(c.raw);
|
|
7516
|
+
const window = normalizeWindow2(c.raw, c.headerPercent, nowMs);
|
|
7517
|
+
if (!window) continue;
|
|
7518
|
+
if (secs === FIVE_HOUR_SECONDS) fiveHour = window;
|
|
7519
|
+
else if (secs === SEVEN_DAY_SECONDS) sevenDay = window;
|
|
7520
|
+
}
|
|
7521
|
+
if (!fiveHour || !sevenDay) {
|
|
7522
|
+
for (const c of candidates) {
|
|
7523
|
+
const secs = windowSeconds(c.raw);
|
|
7524
|
+
if (secs === FIVE_HOUR_SECONDS || secs === SEVEN_DAY_SECONDS) continue;
|
|
7525
|
+
const window = normalizeWindow2(c.raw, c.headerPercent, nowMs);
|
|
7526
|
+
if (!window) continue;
|
|
7527
|
+
if (c.fallback === "five_hour" && !fiveHour) fiveHour = window;
|
|
7528
|
+
else if (c.fallback === "seven_day" && !sevenDay) sevenDay = window;
|
|
7529
|
+
}
|
|
7530
|
+
}
|
|
7531
|
+
const planRaw = b.plan_type;
|
|
7532
|
+
const planType = typeof planRaw === "string" && planRaw.trim() ? planRaw.trim() : null;
|
|
7533
|
+
return {
|
|
7534
|
+
five_hour: fiveHour ?? { utilization: null, resets_at: null },
|
|
7535
|
+
seven_day: sevenDay ?? { utilization: null, resets_at: null },
|
|
7536
|
+
plan_type: planType
|
|
7537
|
+
};
|
|
7538
|
+
}
|
|
7539
|
+
async function fetchUsageResponse(accessToken, accountId) {
|
|
7540
|
+
let res;
|
|
7541
|
+
try {
|
|
7542
|
+
res = await fetch(USAGE_URL, {
|
|
7543
|
+
headers: authHeaders2(accessToken, accountId)
|
|
7544
|
+
});
|
|
7545
|
+
} catch (err) {
|
|
7546
|
+
throw new CodexApiError(
|
|
7547
|
+
`Network error reaching Codex usage: ${err.message}`,
|
|
7548
|
+
"network"
|
|
7549
|
+
);
|
|
7550
|
+
}
|
|
7551
|
+
const headers = {};
|
|
7552
|
+
res.headers.forEach((value, key) => {
|
|
7553
|
+
headers[key.toLowerCase()] = value;
|
|
7554
|
+
});
|
|
7555
|
+
let body = null;
|
|
7556
|
+
try {
|
|
7557
|
+
body = await res.json();
|
|
7558
|
+
} catch {
|
|
7559
|
+
}
|
|
7560
|
+
return { status: res.status, body, headers };
|
|
7561
|
+
}
|
|
7562
|
+
async function fetchCodexUsage() {
|
|
7563
|
+
const loaded = loadAuth();
|
|
7564
|
+
let auth = loaded.auth;
|
|
7565
|
+
let access = auth.tokens.access_token.trim();
|
|
7566
|
+
const accountId = auth.tokens?.account_id;
|
|
7567
|
+
if (needsRefresh2(access, auth.last_refresh)) {
|
|
7568
|
+
const refreshed = await refreshAccessToken2(auth, loaded.path);
|
|
7569
|
+
if (refreshed) {
|
|
7570
|
+
access = refreshed.accessToken;
|
|
7571
|
+
auth = refreshed.auth;
|
|
7572
|
+
}
|
|
7573
|
+
}
|
|
7574
|
+
let { status, body, headers } = await fetchUsageResponse(access, accountId);
|
|
7575
|
+
if (status === 401 || status === 403) {
|
|
7576
|
+
const refreshed = await refreshAccessToken2(auth, loaded.path);
|
|
7577
|
+
if (refreshed) {
|
|
7578
|
+
access = refreshed.accessToken;
|
|
7579
|
+
({ status, body, headers } = await fetchUsageResponse(access, accountId));
|
|
7580
|
+
}
|
|
7581
|
+
}
|
|
7582
|
+
if (status < 200 || status >= 300) {
|
|
7583
|
+
throw new CodexApiError(
|
|
7584
|
+
`Codex usage returned HTTP ${status}`,
|
|
7585
|
+
status === 401 || status === 403 ? "no_auth" : "http"
|
|
7586
|
+
);
|
|
7587
|
+
}
|
|
7588
|
+
const windows = parseCodexWhamUsage(body, headers);
|
|
7589
|
+
return {
|
|
7590
|
+
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7591
|
+
agent: "codex",
|
|
7592
|
+
five_hour: windows.five_hour,
|
|
7593
|
+
seven_day: windows.seven_day,
|
|
7594
|
+
seven_day_opus: null,
|
|
7595
|
+
seven_day_sonnet: null,
|
|
7596
|
+
seven_day_oauth_apps: null,
|
|
7597
|
+
seven_day_cowork: null,
|
|
7598
|
+
extra_usage: null,
|
|
7599
|
+
plan_type: windows.plan_type
|
|
7600
|
+
};
|
|
7601
|
+
}
|
|
7602
|
+
|
|
7603
|
+
// src/usage/copilot.ts
|
|
7604
|
+
import { spawn } from "node:child_process";
|
|
7605
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
7606
|
+
import { dirname as dirname2, join as join4 } from "node:path";
|
|
7607
|
+
var RPC_TIMEOUT_MS = 1e4;
|
|
7608
|
+
var CopilotApiError = class extends Error {
|
|
7609
|
+
constructor(message, code) {
|
|
7610
|
+
super(message);
|
|
7611
|
+
this.code = code;
|
|
7612
|
+
}
|
|
7613
|
+
};
|
|
7614
|
+
function recordOf2(value) {
|
|
7615
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
7616
|
+
}
|
|
7617
|
+
function numberOf4(value) {
|
|
7618
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
7619
|
+
}
|
|
7620
|
+
function clampPercent(value) {
|
|
7621
|
+
return Math.min(100, Math.max(0, value));
|
|
7622
|
+
}
|
|
7623
|
+
function nextCopilotMonthlyReset(nowMs = Date.now()) {
|
|
7624
|
+
const now = new Date(nowMs);
|
|
7625
|
+
return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)).toISOString();
|
|
7626
|
+
}
|
|
7627
|
+
function quotaResetDate(value, nowMs) {
|
|
7628
|
+
const parsed = typeof value === "string" ? Date.parse(value) : Number.NaN;
|
|
7629
|
+
return Number.isFinite(parsed) && parsed > nowMs + 6e4 ? new Date(parsed).toISOString() : nextCopilotMonthlyReset(nowMs);
|
|
7630
|
+
}
|
|
7631
|
+
function parseCopilotQuota(body, nowMs = Date.now()) {
|
|
7632
|
+
const root = recordOf2(body);
|
|
7633
|
+
const snapshots = recordOf2(root?.quotaSnapshots);
|
|
7634
|
+
if (!snapshots) {
|
|
7635
|
+
throw new CopilotApiError("Copilot quota response missing quotaSnapshots", "parse");
|
|
7636
|
+
}
|
|
7637
|
+
const chat = recordOf2(snapshots.chat);
|
|
7638
|
+
const legacy = recordOf2(snapshots.premium_interactions);
|
|
7639
|
+
const chatLimit = numberOf4(chat?.entitlementRequests);
|
|
7640
|
+
const quota = chat && (chatLimit !== void 0 && chatLimit > 0 || chat.isUnlimitedEntitlement === true) ? chat : legacy;
|
|
7641
|
+
if (!quota) {
|
|
7642
|
+
throw new CopilotApiError("Copilot quota response has no chat allowance", "parse");
|
|
7643
|
+
}
|
|
7644
|
+
const unlimited = quota.isUnlimitedEntitlement === true;
|
|
7645
|
+
const remainingPercent = numberOf4(quota.remainingPercentage);
|
|
7646
|
+
const utilization = unlimited ? null : remainingPercent === void 0 ? null : clampPercent(100 - remainingPercent);
|
|
7647
|
+
const limit = numberOf4(quota.entitlementRequests) ?? null;
|
|
7648
|
+
const used = numberOf4(quota.usedRequests) ?? null;
|
|
7649
|
+
const unit = quota.tokenBasedBilling === true ? "ai-credits" : "premium-requests";
|
|
7650
|
+
return {
|
|
7651
|
+
captured_at: new Date(nowMs).toISOString(),
|
|
7652
|
+
agent: "copilot",
|
|
7653
|
+
five_hour: { utilization: null, resets_at: null },
|
|
7654
|
+
seven_day: { utilization: null, resets_at: null },
|
|
7655
|
+
monthly: {
|
|
7656
|
+
utilization,
|
|
7657
|
+
resets_at: quotaResetDate(quota.resetDate, nowMs)
|
|
7658
|
+
},
|
|
7659
|
+
monthly_quota: {
|
|
7660
|
+
used,
|
|
7661
|
+
limit,
|
|
7662
|
+
remaining: used !== null && limit !== null ? Math.max(0, limit - used) : null,
|
|
7663
|
+
unit,
|
|
7664
|
+
unlimited
|
|
7665
|
+
},
|
|
7666
|
+
seven_day_opus: null,
|
|
7667
|
+
seven_day_sonnet: null,
|
|
7668
|
+
seven_day_oauth_apps: null,
|
|
7669
|
+
seven_day_cowork: null,
|
|
7670
|
+
extra_usage: null,
|
|
7671
|
+
plan_type: unit === "ai-credits" ? "AI credits" : "premium requests"
|
|
7672
|
+
};
|
|
7673
|
+
}
|
|
7674
|
+
var ContentLengthDecoder = class {
|
|
7675
|
+
buffer = Buffer.alloc(0);
|
|
7676
|
+
push(chunk2) {
|
|
7677
|
+
this.buffer = Buffer.concat([this.buffer, chunk2]);
|
|
7678
|
+
const messages = [];
|
|
7679
|
+
while (true) {
|
|
7680
|
+
const headerEnd = this.buffer.indexOf("\r\n\r\n");
|
|
7681
|
+
if (headerEnd === -1) break;
|
|
7682
|
+
const header = this.buffer.subarray(0, headerEnd).toString("ascii");
|
|
7683
|
+
const match = header.match(/(?:^|\r\n)Content-Length:\s*(\d+)/i);
|
|
7684
|
+
if (!match) {
|
|
7685
|
+
throw new CopilotApiError("Copilot RPC response missing Content-Length", "protocol");
|
|
7686
|
+
}
|
|
7687
|
+
const length = Number(match[1]);
|
|
7688
|
+
const bodyStart = headerEnd + 4;
|
|
7689
|
+
if (this.buffer.length < bodyStart + length) break;
|
|
7690
|
+
const body = this.buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
|
|
7691
|
+
this.buffer = this.buffer.subarray(bodyStart + length);
|
|
7692
|
+
try {
|
|
7693
|
+
messages.push(JSON.parse(body));
|
|
7694
|
+
} catch {
|
|
7695
|
+
throw new CopilotApiError("Copilot RPC returned invalid JSON", "protocol");
|
|
7696
|
+
}
|
|
7697
|
+
}
|
|
7698
|
+
return messages;
|
|
7699
|
+
}
|
|
7700
|
+
};
|
|
7701
|
+
function rpcFrame(message) {
|
|
7702
|
+
const body = Buffer.from(JSON.stringify(message), "utf8");
|
|
7703
|
+
return Buffer.concat([
|
|
7704
|
+
Buffer.from(`Content-Length: ${body.length}\r
|
|
7705
|
+
\r
|
|
7706
|
+
`, "ascii"),
|
|
7707
|
+
body
|
|
7708
|
+
]);
|
|
7709
|
+
}
|
|
7710
|
+
function resolveCopilotCliPath() {
|
|
7711
|
+
const configured = process.env.COPILOT_CLI_PATH?.trim();
|
|
7712
|
+
if (configured) return configured;
|
|
7713
|
+
const sibling = join4(dirname2(process.execPath), process.platform === "win32" ? "copilot.cmd" : "copilot");
|
|
7714
|
+
return existsSync6(sibling) ? sibling : process.platform === "win32" ? "copilot.cmd" : "copilot";
|
|
7715
|
+
}
|
|
7716
|
+
async function requestQuota(child) {
|
|
7717
|
+
const decoder = new ContentLengthDecoder();
|
|
7718
|
+
const pending = /* @__PURE__ */ new Map();
|
|
7719
|
+
let nextId = 1;
|
|
7720
|
+
const rejectAll = (error) => {
|
|
7721
|
+
for (const waiter of pending.values()) waiter.reject(error);
|
|
7722
|
+
pending.clear();
|
|
7723
|
+
};
|
|
7724
|
+
child.stdout.on("data", (chunk2) => {
|
|
7725
|
+
try {
|
|
7726
|
+
for (const value of decoder.push(chunk2)) {
|
|
7727
|
+
const message = recordOf2(value);
|
|
7728
|
+
const id = numberOf4(message?.id);
|
|
7729
|
+
if (id === void 0) continue;
|
|
7730
|
+
const waiter = pending.get(id);
|
|
7731
|
+
if (!waiter) continue;
|
|
7732
|
+
pending.delete(id);
|
|
7733
|
+
const rpcError = recordOf2(message?.error);
|
|
7734
|
+
if (rpcError) {
|
|
7735
|
+
waiter.reject(new CopilotApiError(
|
|
7736
|
+
typeof rpcError.message === "string" ? rpcError.message : "Copilot RPC request failed",
|
|
7737
|
+
"protocol"
|
|
7738
|
+
));
|
|
7739
|
+
} else {
|
|
7740
|
+
waiter.resolve(message?.result);
|
|
7741
|
+
}
|
|
7742
|
+
}
|
|
7743
|
+
} catch (error) {
|
|
7744
|
+
rejectAll(error);
|
|
7745
|
+
}
|
|
7746
|
+
});
|
|
7747
|
+
const exited = new Promise((_, reject) => {
|
|
7748
|
+
child.once("error", (error) => {
|
|
7749
|
+
reject(new CopilotApiError(
|
|
7750
|
+
error.message,
|
|
7751
|
+
error.code === "ENOENT" ? "no_cli" : "protocol"
|
|
7752
|
+
));
|
|
7753
|
+
});
|
|
7754
|
+
child.once("exit", (code) => {
|
|
7755
|
+
reject(new CopilotApiError(`Copilot RPC exited before responding (code ${code ?? "unknown"})`, "protocol"));
|
|
7756
|
+
});
|
|
7757
|
+
});
|
|
7758
|
+
const request = (method, params = {}) => {
|
|
7759
|
+
const id = nextId++;
|
|
7760
|
+
const response = new Promise((resolve4, reject) => {
|
|
7761
|
+
pending.set(id, { resolve: resolve4, reject });
|
|
7762
|
+
child.stdin.write(rpcFrame({ jsonrpc: "2.0", id, method, params }));
|
|
7763
|
+
});
|
|
7764
|
+
return Promise.race([response, exited]);
|
|
7765
|
+
};
|
|
7766
|
+
await request("connect", {});
|
|
7767
|
+
return request("account.getQuota", {});
|
|
7768
|
+
}
|
|
7769
|
+
async function fetchCopilotUsage() {
|
|
7770
|
+
const cliPath = resolveCopilotCliPath();
|
|
7771
|
+
const child = spawn(cliPath, ["--headless", "--no-auto-update", "--stdio", "--log-level", "none"], {
|
|
7772
|
+
cwd: process.cwd(),
|
|
7773
|
+
env: process.env,
|
|
7774
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
7775
|
+
windowsHide: true,
|
|
7776
|
+
shell: process.platform === "win32"
|
|
7777
|
+
});
|
|
7778
|
+
let stderr = "";
|
|
7779
|
+
child.stderr.on("data", (chunk2) => {
|
|
7780
|
+
stderr = (stderr + chunk2.toString("utf8")).slice(-2e3);
|
|
7781
|
+
});
|
|
7782
|
+
const timeout = new Promise((_, reject) => {
|
|
7783
|
+
const handle = setTimeout(() => {
|
|
7784
|
+
reject(new CopilotApiError("Timed out reading Copilot quota", "timeout"));
|
|
7785
|
+
}, RPC_TIMEOUT_MS);
|
|
7786
|
+
handle.unref();
|
|
7787
|
+
});
|
|
7788
|
+
try {
|
|
7789
|
+
const body = await Promise.race([requestQuota(child), timeout]);
|
|
7790
|
+
return parseCopilotQuota(body);
|
|
7791
|
+
} catch (error) {
|
|
7792
|
+
if (error instanceof CopilotApiError) {
|
|
7793
|
+
const message = `${error.message} ${stderr}`.toLowerCase();
|
|
7794
|
+
if (message.includes("not logged") || message.includes("authentication")) {
|
|
7795
|
+
throw new CopilotApiError("Copilot not logged in. Run `copilot login`.", "no_auth");
|
|
7796
|
+
}
|
|
7797
|
+
throw error;
|
|
7798
|
+
}
|
|
7799
|
+
throw new CopilotApiError(error.message, "protocol");
|
|
7800
|
+
} finally {
|
|
7801
|
+
child.kill();
|
|
7802
|
+
}
|
|
7803
|
+
}
|
|
7804
|
+
|
|
6890
7805
|
// src/daemon-worker.ts
|
|
6891
7806
|
init_storage();
|
|
6892
7807
|
init_fs();
|
|
@@ -6928,9 +7843,9 @@ import { randomUUID } from "node:crypto";
|
|
|
6928
7843
|
|
|
6929
7844
|
// ../entries/dist/fs.js
|
|
6930
7845
|
init_fs();
|
|
6931
|
-
import { readFileSync as
|
|
7846
|
+
import { readFileSync as readFileSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync9 } from "node:fs";
|
|
6932
7847
|
import { randomBytes } from "node:crypto";
|
|
6933
|
-
import { join as
|
|
7848
|
+
import { join as join6 } from "node:path";
|
|
6934
7849
|
|
|
6935
7850
|
// ../entries/dist/types.js
|
|
6936
7851
|
var CURRENT_ENTRY_SCHEMA_VERSION = 2;
|
|
@@ -7003,12 +7918,12 @@ var PROMPT_FRAME_ORIGIN = {
|
|
|
7003
7918
|
|
|
7004
7919
|
// ../entries/dist/digest-fs.js
|
|
7005
7920
|
init_fs();
|
|
7006
|
-
import { readFileSync as
|
|
7007
|
-
import { dirname as
|
|
7921
|
+
import { readFileSync as readFileSync9, readdirSync, writeFileSync as writeFileSync5, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync8 } from "node:fs";
|
|
7922
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
7008
7923
|
var digestsDirCached = null;
|
|
7009
|
-
function parseDigestFile(
|
|
7924
|
+
function parseDigestFile(path11, expectedVersion) {
|
|
7010
7925
|
try {
|
|
7011
|
-
const parsed = JSON.parse(
|
|
7926
|
+
const parsed = JSON.parse(readFileSync9(path11, "utf8"));
|
|
7012
7927
|
if (!parsed || typeof parsed !== "object")
|
|
7013
7928
|
return null;
|
|
7014
7929
|
if (parsed.version !== expectedVersion)
|
|
@@ -7028,16 +7943,16 @@ function digestsDir() {
|
|
|
7028
7943
|
return digestsDirCached;
|
|
7029
7944
|
}
|
|
7030
7945
|
function dayDigestPath(date) {
|
|
7031
|
-
return
|
|
7946
|
+
return join5(digestsDir(), "day", `${date}.json`);
|
|
7032
7947
|
}
|
|
7033
7948
|
function weekDigestPath(monday) {
|
|
7034
|
-
return
|
|
7949
|
+
return join5(digestsDir(), "week", `${monday}.json`);
|
|
7035
7950
|
}
|
|
7036
7951
|
function writeDayDigest(digest) {
|
|
7037
7952
|
const final = dayDigestPath(digest.key);
|
|
7038
|
-
mkdirSync4(
|
|
7953
|
+
mkdirSync4(dirname4(final), { recursive: true });
|
|
7039
7954
|
const tmp = `${final}.tmp`;
|
|
7040
|
-
|
|
7955
|
+
writeFileSync5(tmp, JSON.stringify(digest, null, 2), "utf8");
|
|
7041
7956
|
if (process.platform !== "win32") {
|
|
7042
7957
|
try {
|
|
7043
7958
|
chmodSync(tmp, 384);
|
|
@@ -7048,7 +7963,7 @@ function writeDayDigest(digest) {
|
|
|
7048
7963
|
}
|
|
7049
7964
|
function readDayDigest(date) {
|
|
7050
7965
|
const p = dayDigestPath(date);
|
|
7051
|
-
if (!
|
|
7966
|
+
if (!existsSync8(p))
|
|
7052
7967
|
return null;
|
|
7053
7968
|
return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
|
|
7054
7969
|
}
|
|
@@ -7068,9 +7983,9 @@ function setTodayDigestInCache(date, digest, nowMs) {
|
|
|
7068
7983
|
}
|
|
7069
7984
|
function writeWeekDigest(digest) {
|
|
7070
7985
|
const final = weekDigestPath(digest.key);
|
|
7071
|
-
mkdirSync4(
|
|
7986
|
+
mkdirSync4(dirname4(final), { recursive: true });
|
|
7072
7987
|
const tmp = `${final}.tmp`;
|
|
7073
|
-
|
|
7988
|
+
writeFileSync5(tmp, JSON.stringify(digest, null, 2), "utf8");
|
|
7074
7989
|
if (process.platform !== "win32") {
|
|
7075
7990
|
try {
|
|
7076
7991
|
chmodSync(tmp, 384);
|
|
@@ -7081,7 +7996,7 @@ function writeWeekDigest(digest) {
|
|
|
7081
7996
|
}
|
|
7082
7997
|
function readWeekDigest(monday) {
|
|
7083
7998
|
const p = weekDigestPath(monday);
|
|
7084
|
-
if (!
|
|
7999
|
+
if (!existsSync8(p))
|
|
7085
8000
|
return null;
|
|
7086
8001
|
return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
|
|
7087
8002
|
}
|
|
@@ -7111,7 +8026,7 @@ function entriesDir() {
|
|
|
7111
8026
|
return entriesDirCached;
|
|
7112
8027
|
}
|
|
7113
8028
|
function pathFor(sessionId, localDay2) {
|
|
7114
|
-
return
|
|
8029
|
+
return join6(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
|
|
7115
8030
|
}
|
|
7116
8031
|
function tmpPathFor(final) {
|
|
7117
8032
|
return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
|
|
@@ -7122,7 +8037,7 @@ function writeEntry(entry) {
|
|
|
7122
8037
|
const final = pathFor(entry.session_id, entry.local_day);
|
|
7123
8038
|
const tmp = tmpPathFor(final);
|
|
7124
8039
|
const json = JSON.stringify(entry, null, 2);
|
|
7125
|
-
|
|
8040
|
+
writeFileSync6(tmp, json, { encoding: "utf8" });
|
|
7126
8041
|
renameSync3(tmp, final);
|
|
7127
8042
|
}
|
|
7128
8043
|
var PRESERVABLE_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -7154,22 +8069,22 @@ function writeEntryPreservingEnrichment(fresh) {
|
|
|
7154
8069
|
toWrite = { ...fresh, enrichment: existing.enrichment };
|
|
7155
8070
|
}
|
|
7156
8071
|
const tmp = tmpPathFor(final);
|
|
7157
|
-
|
|
8072
|
+
writeFileSync6(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
|
|
7158
8073
|
renameSync3(tmp, final);
|
|
7159
8074
|
}
|
|
7160
8075
|
function readEntry(sessionId, localDay2) {
|
|
7161
8076
|
const p = pathFor(sessionId, localDay2);
|
|
7162
|
-
if (!
|
|
8077
|
+
if (!existsSync9(p))
|
|
7163
8078
|
return null;
|
|
7164
|
-
const raw =
|
|
8079
|
+
const raw = readFileSync10(p, "utf8");
|
|
7165
8080
|
return JSON.parse(raw);
|
|
7166
8081
|
}
|
|
7167
8082
|
function entryExists(sessionId, localDay2) {
|
|
7168
|
-
return
|
|
8083
|
+
return existsSync9(pathFor(sessionId, localDay2));
|
|
7169
8084
|
}
|
|
7170
8085
|
function listEntryKeys() {
|
|
7171
8086
|
const dir = entriesDir();
|
|
7172
|
-
if (!
|
|
8087
|
+
if (!existsSync9(dir))
|
|
7173
8088
|
return [];
|
|
7174
8089
|
return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
|
|
7175
8090
|
}
|
|
@@ -7188,8 +8103,8 @@ function listEntriesForDay(localDay2) {
|
|
|
7188
8103
|
|
|
7189
8104
|
// src/perception/build-entries.ts
|
|
7190
8105
|
init_dist();
|
|
7191
|
-
import { statSync as statSync2, readFileSync as
|
|
7192
|
-
import { basename as basename2, dirname as
|
|
8106
|
+
import { statSync as statSync2, readFileSync as readFileSync11 } from "node:fs";
|
|
8107
|
+
import { basename as basename2, dirname as dirname5 } from "node:path";
|
|
7193
8108
|
|
|
7194
8109
|
// ../entries/dist/signals.js
|
|
7195
8110
|
init_dist();
|
|
@@ -7422,7 +8337,7 @@ function viewEvent(ev) {
|
|
|
7422
8337
|
cwd: rawCwd
|
|
7423
8338
|
};
|
|
7424
8339
|
}
|
|
7425
|
-
var
|
|
8340
|
+
var IDLE_GAP_MS6 = 3 * 60 * 1e3;
|
|
7426
8341
|
var INTERRUPT_RE2 = /\[request interrupted|interrupted by user/i;
|
|
7427
8342
|
var PR_TITLE_RE = /--title\s+["']([^"']+)["']/;
|
|
7428
8343
|
var BASH_CHAIN_SPLIT_RE = /\|\||&&|;|\|/;
|
|
@@ -7534,7 +8449,7 @@ function closeTurn(t, closed, cwd) {
|
|
|
7534
8449
|
let active = 0;
|
|
7535
8450
|
for (let i = 1; i < ts.length; i++) {
|
|
7536
8451
|
const dt = ts[i] - ts[i - 1];
|
|
7537
|
-
if (dt <
|
|
8452
|
+
if (dt < IDLE_GAP_MS6)
|
|
7538
8453
|
active += dt;
|
|
7539
8454
|
}
|
|
7540
8455
|
closed.push({
|
|
@@ -7731,7 +8646,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
|
|
|
7731
8646
|
let activeMs2 = 0;
|
|
7732
8647
|
for (let i = 1; i < tsSorted.length; i++) {
|
|
7733
8648
|
const dt = tsSorted[i] - tsSorted[i - 1];
|
|
7734
|
-
if (dt <
|
|
8649
|
+
if (dt < IDLE_GAP_MS6)
|
|
7735
8650
|
activeMs2 += dt;
|
|
7736
8651
|
}
|
|
7737
8652
|
const tsSortedStrings = dayEvents.map((e) => e.timestamp).filter((t) => !!t).sort();
|
|
@@ -7928,7 +8843,7 @@ function decodeProjectDirName(projectDir) {
|
|
|
7928
8843
|
}
|
|
7929
8844
|
function buildEntriesForFile(filePath) {
|
|
7930
8845
|
const stat = statSync2(filePath);
|
|
7931
|
-
const raw =
|
|
8846
|
+
const raw = readFileSync11(filePath, "utf8");
|
|
7932
8847
|
const rawLines = raw.split("\n").filter(Boolean).map((l) => {
|
|
7933
8848
|
try {
|
|
7934
8849
|
return JSON.parse(l);
|
|
@@ -7939,7 +8854,7 @@ function buildEntriesForFile(filePath) {
|
|
|
7939
8854
|
if (rawLines.length === 0) return null;
|
|
7940
8855
|
const { meta, events } = parseTranscript(rawLines);
|
|
7941
8856
|
const fileName = basename2(filePath);
|
|
7942
|
-
const projectDir = basename2(
|
|
8857
|
+
const projectDir = basename2(dirname5(filePath));
|
|
7943
8858
|
const sessionId = fileName.replace(/\.jsonl$/, "");
|
|
7944
8859
|
const sd = {
|
|
7945
8860
|
...meta,
|
|
@@ -8189,7 +9104,7 @@ function buildIngestPayload(inputs) {
|
|
|
8189
9104
|
return {
|
|
8190
9105
|
ingestId: randomUUID(),
|
|
8191
9106
|
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8192
|
-
cliVersion: "0.16.
|
|
9107
|
+
cliVersion: "0.16.7",
|
|
8193
9108
|
...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
|
|
8194
9109
|
...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
|
|
8195
9110
|
...richRollup ? { richRollup } : {},
|
|
@@ -8216,8 +9131,8 @@ async function pushToTeamServer(config, payload) {
|
|
|
8216
9131
|
}
|
|
8217
9132
|
|
|
8218
9133
|
// src/team/git-remote.ts
|
|
8219
|
-
import { existsSync as
|
|
8220
|
-
import { dirname as
|
|
9134
|
+
import { existsSync as existsSync10, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
|
|
9135
|
+
import { dirname as dirname6, isAbsolute as isAbsolute2, join as join7, resolve as resolve2 } from "node:path";
|
|
8221
9136
|
var GITHUB_URL_RE = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/;
|
|
8222
9137
|
function parseGithubRemote(url) {
|
|
8223
9138
|
const m = url.trim().match(GITHUB_URL_RE);
|
|
@@ -8238,19 +9153,19 @@ function originUrl2(configText) {
|
|
|
8238
9153
|
return null;
|
|
8239
9154
|
}
|
|
8240
9155
|
function gitConfigPathFor(dir) {
|
|
8241
|
-
const dotGit =
|
|
9156
|
+
const dotGit = join7(dir, ".git");
|
|
8242
9157
|
const st = statSync3(dotGit, { throwIfNoEntry: false });
|
|
8243
9158
|
if (!st) return null;
|
|
8244
|
-
if (st.isDirectory()) return
|
|
8245
|
-
const m =
|
|
9159
|
+
if (st.isDirectory()) return join7(dotGit, "config");
|
|
9160
|
+
const m = readFileSync12(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
|
|
8246
9161
|
if (!m) return null;
|
|
8247
9162
|
const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
|
|
8248
|
-
const commondirFile =
|
|
8249
|
-
if (
|
|
8250
|
-
const common =
|
|
8251
|
-
return
|
|
9163
|
+
const commondirFile = join7(gd, "commondir");
|
|
9164
|
+
if (existsSync10(commondirFile)) {
|
|
9165
|
+
const common = readFileSync12(commondirFile, "utf8").trim();
|
|
9166
|
+
return join7(isAbsolute2(common) ? common : resolve2(gd, common), "config");
|
|
8252
9167
|
}
|
|
8253
|
-
return
|
|
9168
|
+
return join7(gd, "config");
|
|
8254
9169
|
}
|
|
8255
9170
|
function createRepoResolver() {
|
|
8256
9171
|
const cache = /* @__PURE__ */ new Map();
|
|
@@ -8260,14 +9175,14 @@ function createRepoResolver() {
|
|
|
8260
9175
|
if (hit !== void 0) return hit;
|
|
8261
9176
|
let repo = null;
|
|
8262
9177
|
try {
|
|
8263
|
-
for (let d = dir; ; d =
|
|
9178
|
+
for (let d = dir; ; d = dirname6(d)) {
|
|
8264
9179
|
const config = gitConfigPathFor(d);
|
|
8265
|
-
if (config &&
|
|
8266
|
-
const url = originUrl2(
|
|
9180
|
+
if (config && existsSync10(config)) {
|
|
9181
|
+
const url = originUrl2(readFileSync12(config, "utf8"));
|
|
8267
9182
|
repo = url ? parseGithubRemote(url) : null;
|
|
8268
9183
|
break;
|
|
8269
9184
|
}
|
|
8270
|
-
if (d ===
|
|
9185
|
+
if (d === dirname6(d)) break;
|
|
8271
9186
|
}
|
|
8272
9187
|
} catch {
|
|
8273
9188
|
repo = null;
|
|
@@ -8279,13 +9194,13 @@ function createRepoResolver() {
|
|
|
8279
9194
|
|
|
8280
9195
|
// src/team/queue.ts
|
|
8281
9196
|
init_fs();
|
|
8282
|
-
import { readFileSync as
|
|
8283
|
-
import { dirname as
|
|
9197
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, appendFileSync as appendFileSync4, statSync as statSync4, mkdirSync as mkdirSync6 } from "node:fs";
|
|
9198
|
+
import { dirname as dirname7 } from "node:path";
|
|
8284
9199
|
var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
|
|
8285
9200
|
var MAX_SIZE_BYTES = 10 * 1024 * 1024;
|
|
8286
9201
|
var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8287
9202
|
function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
8288
|
-
mkdirSync6(
|
|
9203
|
+
mkdirSync6(dirname7(queuePath), { recursive: true });
|
|
8289
9204
|
const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
8290
9205
|
appendFileSync4(queuePath, JSON.stringify(entry) + "\n", "utf8");
|
|
8291
9206
|
try {
|
|
@@ -8299,7 +9214,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
|
|
|
8299
9214
|
function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
8300
9215
|
let lines;
|
|
8301
9216
|
try {
|
|
8302
|
-
lines =
|
|
9217
|
+
lines = readFileSync13(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
8303
9218
|
} catch {
|
|
8304
9219
|
return [];
|
|
8305
9220
|
}
|
|
@@ -8314,18 +9229,18 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
|
|
|
8314
9229
|
} catch {
|
|
8315
9230
|
}
|
|
8316
9231
|
}
|
|
8317
|
-
|
|
9232
|
+
writeFileSync7(queuePath, "", "utf8");
|
|
8318
9233
|
return valid.map((e) => e.payload);
|
|
8319
9234
|
}
|
|
8320
9235
|
function pruneOldest(queuePath) {
|
|
8321
9236
|
let lines;
|
|
8322
9237
|
try {
|
|
8323
|
-
lines =
|
|
9238
|
+
lines = readFileSync13(queuePath, "utf8").trim().split("\n").filter(Boolean);
|
|
8324
9239
|
} catch {
|
|
8325
9240
|
return;
|
|
8326
9241
|
}
|
|
8327
9242
|
const keep = lines.slice(Math.floor(lines.length / 2));
|
|
8328
|
-
|
|
9243
|
+
writeFileSync7(queuePath, keep.join("\n") + "\n", "utf8");
|
|
8329
9244
|
}
|
|
8330
9245
|
|
|
8331
9246
|
// src/team/backfill.ts
|
|
@@ -8333,8 +9248,8 @@ init_storage();
|
|
|
8333
9248
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
8334
9249
|
|
|
8335
9250
|
// src/usage/profile.ts
|
|
8336
|
-
import { existsSync as
|
|
8337
|
-
import { dirname as
|
|
9251
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
|
|
9252
|
+
import { dirname as dirname8 } from "node:path";
|
|
8338
9253
|
var PROFILE_ENDPOINT = "https://api.anthropic.com/api/oauth/profile";
|
|
8339
9254
|
var BETA_HEADER2 = "oauth-2025-04-20";
|
|
8340
9255
|
var PROFILE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -8377,9 +9292,9 @@ async function fetchProfile(nowMs = Date.now()) {
|
|
|
8377
9292
|
};
|
|
8378
9293
|
}
|
|
8379
9294
|
function readCachedProfile(cachePath) {
|
|
8380
|
-
if (!
|
|
9295
|
+
if (!existsSync11(cachePath)) return null;
|
|
8381
9296
|
try {
|
|
8382
|
-
const raw = JSON.parse(
|
|
9297
|
+
const raw = JSON.parse(readFileSync14(cachePath, "utf8"));
|
|
8383
9298
|
if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
|
|
8384
9299
|
return raw;
|
|
8385
9300
|
} catch {
|
|
@@ -8387,8 +9302,8 @@ function readCachedProfile(cachePath) {
|
|
|
8387
9302
|
}
|
|
8388
9303
|
}
|
|
8389
9304
|
function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
|
|
8390
|
-
mkdirSync7(
|
|
8391
|
-
|
|
9305
|
+
mkdirSync7(dirname8(cachePath), { recursive: true });
|
|
9306
|
+
writeFileSync8(
|
|
8392
9307
|
cachePath,
|
|
8393
9308
|
JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
|
|
8394
9309
|
{ mode: 384 }
|
|
@@ -8548,13 +9463,13 @@ async function runTeamBackfill(log3 = noopLog, filePath = USAGE_LOG, configOverr
|
|
|
8548
9463
|
|
|
8549
9464
|
// src/team/sync-log.ts
|
|
8550
9465
|
init_fs();
|
|
8551
|
-
import { readFileSync as
|
|
9466
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
8552
9467
|
var MAX_LINES = 300;
|
|
8553
9468
|
var MAX_MSG_CHARS = 1900;
|
|
8554
9469
|
function readPendingSyncLog(watermark) {
|
|
8555
9470
|
let raw;
|
|
8556
9471
|
try {
|
|
8557
|
-
raw =
|
|
9472
|
+
raw = readFileSync15(cclensPath("daemon.log"), "utf8");
|
|
8558
9473
|
} catch {
|
|
8559
9474
|
return { lines: [] };
|
|
8560
9475
|
}
|
|
@@ -8574,13 +9489,13 @@ function readPendingSyncLog(watermark) {
|
|
|
8574
9489
|
|
|
8575
9490
|
// src/team/last-push.ts
|
|
8576
9491
|
init_fs();
|
|
8577
|
-
import { writeFileSync as
|
|
8578
|
-
import { join as
|
|
9492
|
+
import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "node:fs";
|
|
9493
|
+
import { join as join8 } from "node:path";
|
|
8579
9494
|
var LAST_PUSH_FILE = "team-last-push.json";
|
|
8580
9495
|
function write(record, dir) {
|
|
8581
9496
|
const d = dir ?? cclensHome();
|
|
8582
9497
|
mkdirSync8(d, { recursive: true });
|
|
8583
|
-
|
|
9498
|
+
writeFileSync9(join8(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
|
|
8584
9499
|
}
|
|
8585
9500
|
function writeLastPushSuccess(payload, dir) {
|
|
8586
9501
|
write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
|
|
@@ -9180,8 +10095,8 @@ init_fs();
|
|
|
9180
10095
|
|
|
9181
10096
|
// src/perception/state.ts
|
|
9182
10097
|
init_fs();
|
|
9183
|
-
import { existsSync as
|
|
9184
|
-
import { dirname as
|
|
10098
|
+
import { existsSync as existsSync13, readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
|
|
10099
|
+
import { dirname as dirname10 } from "node:path";
|
|
9185
10100
|
var STALE_MS = 15 * 60 * 1e3;
|
|
9186
10101
|
var pathCached = null;
|
|
9187
10102
|
function statePath() {
|
|
@@ -9191,7 +10106,7 @@ function statePath() {
|
|
|
9191
10106
|
}
|
|
9192
10107
|
function readState() {
|
|
9193
10108
|
const p = statePath();
|
|
9194
|
-
if (!
|
|
10109
|
+
if (!existsSync13(p)) {
|
|
9195
10110
|
return {
|
|
9196
10111
|
sweep_in_progress: false,
|
|
9197
10112
|
last_sweep_started_at: null,
|
|
@@ -9199,14 +10114,14 @@ function readState() {
|
|
|
9199
10114
|
file_checkpoints: {}
|
|
9200
10115
|
};
|
|
9201
10116
|
}
|
|
9202
|
-
const raw =
|
|
10117
|
+
const raw = readFileSync16(p, "utf8");
|
|
9203
10118
|
return JSON.parse(raw);
|
|
9204
10119
|
}
|
|
9205
10120
|
function writeState(s) {
|
|
9206
10121
|
const p = statePath();
|
|
9207
|
-
mkdirSync9(
|
|
10122
|
+
mkdirSync9(dirname10(p), { recursive: true });
|
|
9208
10123
|
const tmp = `${p}.tmp`;
|
|
9209
|
-
|
|
10124
|
+
writeFileSync10(tmp, JSON.stringify(s, null, 2), "utf8");
|
|
9210
10125
|
renameSync4(tmp, p);
|
|
9211
10126
|
}
|
|
9212
10127
|
function markSweepStart() {
|
|
@@ -9236,17 +10151,17 @@ function updateCheckpoint(jsonlPath, cp) {
|
|
|
9236
10151
|
|
|
9237
10152
|
// src/perception/scan.ts
|
|
9238
10153
|
import { readdirSync as readdirSync4 } from "node:fs";
|
|
9239
|
-
import { join as
|
|
10154
|
+
import { join as join10 } from "node:path";
|
|
9240
10155
|
import { homedir as homedir4 } from "node:os";
|
|
9241
10156
|
async function listAllSessionJsonls(root) {
|
|
9242
|
-
const projectsRoot = root ??
|
|
10157
|
+
const projectsRoot = root ?? join10(homedir4(), ".claude", "projects");
|
|
9243
10158
|
const out = [];
|
|
9244
10159
|
try {
|
|
9245
10160
|
for (const project of readdirSync4(projectsRoot)) {
|
|
9246
|
-
const dir =
|
|
10161
|
+
const dir = join10(projectsRoot, project);
|
|
9247
10162
|
try {
|
|
9248
10163
|
for (const f of readdirSync4(dir)) {
|
|
9249
|
-
if (f.endsWith(".jsonl")) out.push(
|
|
10164
|
+
if (f.endsWith(".jsonl")) out.push(join10(dir, f));
|
|
9250
10165
|
}
|
|
9251
10166
|
} catch {
|
|
9252
10167
|
}
|
|
@@ -9807,8 +10722,8 @@ function getErrorMap() {
|
|
|
9807
10722
|
|
|
9808
10723
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
9809
10724
|
var makeIssue = (params) => {
|
|
9810
|
-
const { data, path:
|
|
9811
|
-
const fullPath = [...
|
|
10725
|
+
const { data, path: path11, errorMaps, issueData } = params;
|
|
10726
|
+
const fullPath = [...path11, ...issueData.path || []];
|
|
9812
10727
|
const fullIssue = {
|
|
9813
10728
|
...issueData,
|
|
9814
10729
|
path: fullPath
|
|
@@ -9924,11 +10839,11 @@ var errorUtil;
|
|
|
9924
10839
|
|
|
9925
10840
|
// ../../node_modules/zod/v3/types.js
|
|
9926
10841
|
var ParseInputLazyPath = class {
|
|
9927
|
-
constructor(parent, value,
|
|
10842
|
+
constructor(parent, value, path11, key) {
|
|
9928
10843
|
this._cachedPath = [];
|
|
9929
10844
|
this.parent = parent;
|
|
9930
10845
|
this.data = value;
|
|
9931
|
-
this._path =
|
|
10846
|
+
this._path = path11;
|
|
9932
10847
|
this._key = key;
|
|
9933
10848
|
}
|
|
9934
10849
|
get path() {
|
|
@@ -13461,14 +14376,14 @@ var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
|
|
|
13461
14376
|
|
|
13462
14377
|
// ../entries/dist/llm-runner.js
|
|
13463
14378
|
init_fs();
|
|
13464
|
-
import { spawn } from "node:child_process";
|
|
13465
|
-
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as
|
|
13466
|
-
import { join as
|
|
14379
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
14380
|
+
import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync12, existsSync as existsSync15 } from "node:fs";
|
|
14381
|
+
import { join as join12 } from "node:path";
|
|
13467
14382
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
13468
14383
|
|
|
13469
14384
|
// ../entries/dist/tmux-runner.js
|
|
13470
|
-
import { mkdirSync as mkdirSync10, writeFileSync as
|
|
13471
|
-
import { join as
|
|
14385
|
+
import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync14, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync17, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
|
|
14386
|
+
import { join as join11 } from "node:path";
|
|
13472
14387
|
import { homedir as homedir5 } from "node:os";
|
|
13473
14388
|
import { spawnSync } from "node:child_process";
|
|
13474
14389
|
var TmuxUnavailableError = class extends Error {
|
|
@@ -13497,16 +14412,16 @@ function tmuxRunnerAvailable() {
|
|
|
13497
14412
|
return { ok: true };
|
|
13498
14413
|
}
|
|
13499
14414
|
function runtimeCwd() {
|
|
13500
|
-
const dir =
|
|
13501
|
-
if (!
|
|
14415
|
+
const dir = join11(homedir5(), ".cclens", "runtime");
|
|
14416
|
+
if (!existsSync14(dir))
|
|
13502
14417
|
mkdirSync10(dir, { recursive: true });
|
|
13503
14418
|
return realpathSync2(dir);
|
|
13504
14419
|
}
|
|
13505
14420
|
function ensureRuntimeCwdTrusted(cwd) {
|
|
13506
|
-
const cfgPath =
|
|
14421
|
+
const cfgPath = join11(homedir5(), ".claude.json");
|
|
13507
14422
|
let cfg;
|
|
13508
14423
|
try {
|
|
13509
|
-
cfg = JSON.parse(
|
|
14424
|
+
cfg = JSON.parse(readFileSync17(cfgPath, "utf8"));
|
|
13510
14425
|
} catch {
|
|
13511
14426
|
return;
|
|
13512
14427
|
}
|
|
@@ -13521,7 +14436,7 @@ function ensureRuntimeCwdTrusted(cwd) {
|
|
|
13521
14436
|
cfg.projects = projects;
|
|
13522
14437
|
const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
|
|
13523
14438
|
try {
|
|
13524
|
-
|
|
14439
|
+
writeFileSync11(tmp, JSON.stringify(cfg, null, 2));
|
|
13525
14440
|
renameSync5(tmp, cfgPath);
|
|
13526
14441
|
} catch {
|
|
13527
14442
|
try {
|
|
@@ -13549,16 +14464,16 @@ async function runClaudeUnderTmuxImpl(args) {
|
|
|
13549
14464
|
ensureRuntimeCwdTrusted(cwd);
|
|
13550
14465
|
const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
13551
14466
|
const sessionName = `cclens-${runId}`;
|
|
13552
|
-
const systemFile =
|
|
13553
|
-
const userFile =
|
|
13554
|
-
const wrapper =
|
|
13555
|
-
|
|
13556
|
-
|
|
14467
|
+
const systemFile = join11(cwd, `system-${runId}.txt`);
|
|
14468
|
+
const userFile = join11(cwd, `user-${runId}.txt`);
|
|
14469
|
+
const wrapper = join11(cwd, `run-${runId}.sh`);
|
|
14470
|
+
writeFileSync11(systemFile, args.systemPrompt);
|
|
14471
|
+
writeFileSync11(userFile, args.reminder ? `${args.userPrompt}
|
|
13557
14472
|
|
|
13558
14473
|
---
|
|
13559
14474
|
|
|
13560
14475
|
${args.reminder}` : args.userPrompt);
|
|
13561
|
-
|
|
14476
|
+
writeFileSync11(wrapper, `#!/bin/bash
|
|
13562
14477
|
SYS="$(cat ${shellEscape(systemFile)})"
|
|
13563
14478
|
USR="$(cat ${shellEscape(userFile)})"
|
|
13564
14479
|
exec ${shellEscape(claudeBin)} \\
|
|
@@ -13570,10 +14485,10 @@ exec ${shellEscape(claudeBin)} \\
|
|
|
13570
14485
|
"$USR"
|
|
13571
14486
|
`, { mode: 493 });
|
|
13572
14487
|
const existingBefore = snapshotAllTranscripts();
|
|
13573
|
-
const
|
|
13574
|
-
if (
|
|
14488
|
+
const spawn4 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
|
|
14489
|
+
if (spawn4.status !== 0) {
|
|
13575
14490
|
cleanup(cwd, runId, tmuxBin, sessionName);
|
|
13576
|
-
throw new TmuxRunError(`tmux new-session failed: ${
|
|
14491
|
+
throw new TmuxRunError(`tmux new-session failed: ${spawn4.stderr.trim()}`);
|
|
13577
14492
|
}
|
|
13578
14493
|
const onAbort = () => {
|
|
13579
14494
|
try {
|
|
@@ -13630,7 +14545,7 @@ function num(v) {
|
|
|
13630
14545
|
function sleep(ms) {
|
|
13631
14546
|
return new Promise((r) => setTimeout(r, ms));
|
|
13632
14547
|
}
|
|
13633
|
-
var PROJECTS_ROOT = () =>
|
|
14548
|
+
var PROJECTS_ROOT = () => join11(homedir5(), ".claude", "projects");
|
|
13634
14549
|
function snapshotAllTranscripts() {
|
|
13635
14550
|
const out = /* @__PURE__ */ new Set();
|
|
13636
14551
|
const root = PROJECTS_ROOT();
|
|
@@ -13641,7 +14556,7 @@ function snapshotAllTranscripts() {
|
|
|
13641
14556
|
return out;
|
|
13642
14557
|
}
|
|
13643
14558
|
for (const sub of subs) {
|
|
13644
|
-
const dir =
|
|
14559
|
+
const dir = join11(root, sub);
|
|
13645
14560
|
let files;
|
|
13646
14561
|
try {
|
|
13647
14562
|
files = readdirSync5(dir);
|
|
@@ -13650,15 +14565,15 @@ function snapshotAllTranscripts() {
|
|
|
13650
14565
|
}
|
|
13651
14566
|
for (const f of files) {
|
|
13652
14567
|
if (f.endsWith(".jsonl"))
|
|
13653
|
-
out.add(
|
|
14568
|
+
out.add(join11(dir, f));
|
|
13654
14569
|
}
|
|
13655
14570
|
}
|
|
13656
14571
|
return out;
|
|
13657
14572
|
}
|
|
13658
|
-
function readJsonlCwd(
|
|
14573
|
+
function readJsonlCwd(path11, maxLines = 8) {
|
|
13659
14574
|
let raw;
|
|
13660
14575
|
try {
|
|
13661
|
-
raw =
|
|
14576
|
+
raw = readFileSync17(path11, "utf8");
|
|
13662
14577
|
} catch {
|
|
13663
14578
|
return void 0;
|
|
13664
14579
|
}
|
|
@@ -13691,7 +14606,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
13691
14606
|
subs = [];
|
|
13692
14607
|
}
|
|
13693
14608
|
for (const sub of subs) {
|
|
13694
|
-
const dir =
|
|
14609
|
+
const dir = join11(root, sub);
|
|
13695
14610
|
let files;
|
|
13696
14611
|
try {
|
|
13697
14612
|
files = readdirSync5(dir);
|
|
@@ -13701,7 +14616,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
13701
14616
|
for (const f of files) {
|
|
13702
14617
|
if (!f.endsWith(".jsonl"))
|
|
13703
14618
|
continue;
|
|
13704
|
-
const full =
|
|
14619
|
+
const full = join11(dir, f);
|
|
13705
14620
|
if (existingBefore.has(full))
|
|
13706
14621
|
continue;
|
|
13707
14622
|
if (readJsonlCwd(full) === targetCwd)
|
|
@@ -13712,10 +14627,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
|
|
|
13712
14627
|
}
|
|
13713
14628
|
throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
|
|
13714
14629
|
}
|
|
13715
|
-
function parseTranscript2(
|
|
14630
|
+
function parseTranscript2(path11, defaultModel) {
|
|
13716
14631
|
let raw;
|
|
13717
14632
|
try {
|
|
13718
|
-
raw =
|
|
14633
|
+
raw = readFileSync17(path11, "utf8");
|
|
13719
14634
|
} catch {
|
|
13720
14635
|
return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
|
|
13721
14636
|
}
|
|
@@ -13775,7 +14690,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
|
|
|
13775
14690
|
}
|
|
13776
14691
|
for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
|
|
13777
14692
|
try {
|
|
13778
|
-
unlinkSync3(
|
|
14693
|
+
unlinkSync3(join11(cwd, f));
|
|
13779
14694
|
} catch {
|
|
13780
14695
|
}
|
|
13781
14696
|
}
|
|
@@ -13790,7 +14705,7 @@ function shellEscape(s) {
|
|
|
13790
14705
|
// ../entries/dist/llm-runner.js
|
|
13791
14706
|
var RUNS_DIR = cclensPath("llm-runs");
|
|
13792
14707
|
function ensureRunsDir() {
|
|
13793
|
-
if (!
|
|
14708
|
+
if (!existsSync15(RUNS_DIR)) {
|
|
13794
14709
|
try {
|
|
13795
14710
|
mkdirSync11(RUNS_DIR, { recursive: true });
|
|
13796
14711
|
} catch {
|
|
@@ -13819,17 +14734,17 @@ function newRunId(kind) {
|
|
|
13819
14734
|
return `${ts}_${kind}_${short}`;
|
|
13820
14735
|
}
|
|
13821
14736
|
function tracePath(runId) {
|
|
13822
|
-
return
|
|
14737
|
+
return join12(RUNS_DIR, `${runId}.jsonl`);
|
|
13823
14738
|
}
|
|
13824
|
-
function safeAppend(
|
|
14739
|
+
function safeAppend(path11, line) {
|
|
13825
14740
|
try {
|
|
13826
|
-
appendFileSync5(
|
|
14741
|
+
appendFileSync5(path11, line);
|
|
13827
14742
|
} catch {
|
|
13828
14743
|
}
|
|
13829
14744
|
}
|
|
13830
|
-
function safeWrite(
|
|
14745
|
+
function safeWrite(path11, line) {
|
|
13831
14746
|
try {
|
|
13832
|
-
|
|
14747
|
+
writeFileSync12(path11, line);
|
|
13833
14748
|
} catch {
|
|
13834
14749
|
}
|
|
13835
14750
|
}
|
|
@@ -13962,7 +14877,7 @@ function runClaudePrintMode(args) {
|
|
|
13962
14877
|
"--append-system-prompt",
|
|
13963
14878
|
args.systemPrompt
|
|
13964
14879
|
];
|
|
13965
|
-
const proc =
|
|
14880
|
+
const proc = spawn2("claude", claudeArgs, { stdio: ["pipe", "pipe", "pipe"], env: { ...process.env } });
|
|
13966
14881
|
safeAppend(trace, JSON.stringify({ _meta: { type: "spawned", run_id: runId, pid: proc.pid } }) + "\n");
|
|
13967
14882
|
const stdinPayload = args.reminder ? `${args.userPrompt}
|
|
13968
14883
|
|
|
@@ -14218,8 +15133,8 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
|
|
|
14218
15133
|
|
|
14219
15134
|
// ../entries/dist/budget.js
|
|
14220
15135
|
init_fs();
|
|
14221
|
-
import { appendFileSync as appendFileSync6, readFileSync as
|
|
14222
|
-
import { dirname as
|
|
15136
|
+
import { appendFileSync as appendFileSync6, readFileSync as readFileSync18, existsSync as existsSync16, mkdirSync as mkdirSync12 } from "node:fs";
|
|
15137
|
+
import { dirname as dirname11 } from "node:path";
|
|
14223
15138
|
var spendPathCached = null;
|
|
14224
15139
|
function spendPath() {
|
|
14225
15140
|
if (spendPathCached)
|
|
@@ -14229,17 +15144,17 @@ function spendPath() {
|
|
|
14229
15144
|
}
|
|
14230
15145
|
function appendSpend(record) {
|
|
14231
15146
|
const p = spendPath();
|
|
14232
|
-
mkdirSync12(
|
|
15147
|
+
mkdirSync12(dirname11(p), { recursive: true });
|
|
14233
15148
|
appendFileSync6(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
|
|
14234
15149
|
}
|
|
14235
15150
|
function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
14236
15151
|
const p = spendPath();
|
|
14237
|
-
if (!
|
|
15152
|
+
if (!existsSync16(p))
|
|
14238
15153
|
return 0;
|
|
14239
15154
|
const year = now.getUTCFullYear();
|
|
14240
15155
|
const month = now.getUTCMonth();
|
|
14241
15156
|
let total = 0;
|
|
14242
|
-
const raw =
|
|
15157
|
+
const raw = readFileSync18(p, "utf8");
|
|
14243
15158
|
for (const line of raw.split("\n")) {
|
|
14244
15159
|
if (!line)
|
|
14245
15160
|
continue;
|
|
@@ -14261,7 +15176,7 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
|
|
|
14261
15176
|
|
|
14262
15177
|
// ../entries/dist/pipeline-lock.js
|
|
14263
15178
|
init_fs();
|
|
14264
|
-
import { writeFileSync as
|
|
15179
|
+
import { writeFileSync as writeFileSync13, unlinkSync as unlinkSync4, existsSync as existsSync17, readFileSync as readFileSync19, statSync as statSync7 } from "node:fs";
|
|
14265
15180
|
var STALE_MS2 = 60 * 1e3;
|
|
14266
15181
|
var HEARTBEAT_MS = 30 * 1e3;
|
|
14267
15182
|
var lockPathCached = null;
|
|
@@ -14273,7 +15188,7 @@ function lockPath() {
|
|
|
14273
15188
|
return lockPathCached;
|
|
14274
15189
|
}
|
|
14275
15190
|
function touchLock() {
|
|
14276
|
-
|
|
15191
|
+
writeFileSync13(lockPath(), String(process.pid), "utf8");
|
|
14277
15192
|
}
|
|
14278
15193
|
function writeInteractiveLock() {
|
|
14279
15194
|
touchLock();
|
|
@@ -14307,13 +15222,13 @@ function pidAlive(pid) {
|
|
|
14307
15222
|
}
|
|
14308
15223
|
function interactiveLockFresh(nowMs) {
|
|
14309
15224
|
const p = lockPath();
|
|
14310
|
-
if (!
|
|
15225
|
+
if (!existsSync17(p))
|
|
14311
15226
|
return false;
|
|
14312
15227
|
try {
|
|
14313
15228
|
const mtime = statSync7(p).mtimeMs;
|
|
14314
15229
|
if (nowMs - mtime > STALE_MS2)
|
|
14315
15230
|
return false;
|
|
14316
|
-
const pid = Number(
|
|
15231
|
+
const pid = Number(readFileSync19(p, "utf8").trim());
|
|
14317
15232
|
if (!Number.isFinite(pid) || pid <= 0)
|
|
14318
15233
|
return false;
|
|
14319
15234
|
if (!pidAlive(pid))
|
|
@@ -14328,7 +15243,7 @@ function interactiveLockFresh(nowMs) {
|
|
|
14328
15243
|
var THIRTY_MIN_MS = 30 * 60 * 1e3;
|
|
14329
15244
|
|
|
14330
15245
|
// ../entries/dist/settings.js
|
|
14331
|
-
import { readFileSync as
|
|
15246
|
+
import { readFileSync as readFileSync20, writeFileSync as writeFileSync14, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync18 } from "node:fs";
|
|
14332
15247
|
init_fs();
|
|
14333
15248
|
var DEFAULT_SETTINGS = {
|
|
14334
15249
|
ai_features: {
|
|
@@ -14360,10 +15275,10 @@ function fromDisk(d) {
|
|
|
14360
15275
|
}
|
|
14361
15276
|
function readSettings() {
|
|
14362
15277
|
const p = settingsPath();
|
|
14363
|
-
if (!
|
|
15278
|
+
if (!existsSync18(p))
|
|
14364
15279
|
return DEFAULT_SETTINGS;
|
|
14365
15280
|
try {
|
|
14366
|
-
const raw =
|
|
15281
|
+
const raw = readFileSync20(p, "utf8");
|
|
14367
15282
|
return fromDisk(JSON.parse(raw));
|
|
14368
15283
|
} catch {
|
|
14369
15284
|
return DEFAULT_SETTINGS;
|
|
@@ -16034,7 +16949,7 @@ var MonthDigestResponseSchema = external_exports.object({
|
|
|
16034
16949
|
}).passthrough();
|
|
16035
16950
|
|
|
16036
16951
|
// ../entries/dist/top-sessions.js
|
|
16037
|
-
var
|
|
16952
|
+
var IDLE_GAP_MS7 = 3 * 60 * 1e3;
|
|
16038
16953
|
var LONG_AUTONOMOUS_MIN = 20;
|
|
16039
16954
|
var N_USER = 150;
|
|
16040
16955
|
var N_FIRST_AGENT = 150;
|
|
@@ -16065,7 +16980,7 @@ function activeMs(timestamps) {
|
|
|
16065
16980
|
let active = 0;
|
|
16066
16981
|
for (let i = 1; i < ts.length; i++) {
|
|
16067
16982
|
const dt = ts[i] - ts[i - 1];
|
|
16068
|
-
if (dt <
|
|
16983
|
+
if (dt < IDLE_GAP_MS7)
|
|
16069
16984
|
active += dt;
|
|
16070
16985
|
}
|
|
16071
16986
|
return active;
|
|
@@ -16239,7 +17154,7 @@ function buildSessionSlice(entry, events, daySignature) {
|
|
|
16239
17154
|
let intEnd = sortedTs[0];
|
|
16240
17155
|
for (let i = 1; i < sortedTs.length; i++) {
|
|
16241
17156
|
const dt = sortedTs[i] - intEnd;
|
|
16242
|
-
if (dt >=
|
|
17157
|
+
if (dt >= IDLE_GAP_MS7) {
|
|
16243
17158
|
intervals.push({
|
|
16244
17159
|
start_min: fmtMin(intStart - sliceStartMs),
|
|
16245
17160
|
end_min: fmtMin(intEnd - sliceStartMs)
|
|
@@ -17123,14 +18038,14 @@ async function getUpdateAvailability() {
|
|
|
17123
18038
|
if (isDevMode()) return null;
|
|
17124
18039
|
const latest = await fetchLatestVersion();
|
|
17125
18040
|
if (latest === null) return {
|
|
17126
|
-
current: "0.16.
|
|
18041
|
+
current: "0.16.7",
|
|
17127
18042
|
latest: null,
|
|
17128
18043
|
updateAvailable: false
|
|
17129
18044
|
};
|
|
17130
18045
|
return {
|
|
17131
|
-
current: "0.16.
|
|
18046
|
+
current: "0.16.7",
|
|
17132
18047
|
latest,
|
|
17133
|
-
updateAvailable: shouldUpdate("0.16.
|
|
18048
|
+
updateAvailable: shouldUpdate("0.16.7", latest)
|
|
17134
18049
|
};
|
|
17135
18050
|
}
|
|
17136
18051
|
|
|
@@ -17140,11 +18055,12 @@ var DAEMON_LOG = cclensPath("daemon.log");
|
|
|
17140
18055
|
var UPDATE_STATE = cclensPath("daemon-update.json");
|
|
17141
18056
|
var WATCHDOG_INTERVAL_MS = 5 * 1e3;
|
|
17142
18057
|
var AUTO_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
17143
|
-
mkdirSync14(
|
|
18058
|
+
mkdirSync14(dirname12(USAGE_LOG3), { recursive: true });
|
|
17144
18059
|
function log2(level, message) {
|
|
17145
18060
|
appendDaemonLogLine(level, message);
|
|
17146
18061
|
}
|
|
17147
18062
|
var nextPollAtMs = 0;
|
|
18063
|
+
var nextAuxPollAtMs = 0;
|
|
17148
18064
|
var nextTeamSyncAtMs = 0;
|
|
17149
18065
|
var firstTeamSync = true;
|
|
17150
18066
|
var currentIntervalMs = BASE_INTERVAL_MS;
|
|
@@ -17178,14 +18094,14 @@ var perceptionHandle = setInterval(async () => {
|
|
|
17178
18094
|
}, PERCEPTION_INTERVAL_MS);
|
|
17179
18095
|
function readUpdateState() {
|
|
17180
18096
|
try {
|
|
17181
|
-
return JSON.parse(
|
|
18097
|
+
return JSON.parse(readFileSync21(UPDATE_STATE, "utf8"));
|
|
17182
18098
|
} catch {
|
|
17183
18099
|
return null;
|
|
17184
18100
|
}
|
|
17185
18101
|
}
|
|
17186
18102
|
function writeUpdateState(state) {
|
|
17187
18103
|
try {
|
|
17188
|
-
|
|
18104
|
+
writeFileSync15(UPDATE_STATE, JSON.stringify(state, null, 2), { mode: 384 });
|
|
17189
18105
|
} catch {
|
|
17190
18106
|
}
|
|
17191
18107
|
}
|
|
@@ -17198,7 +18114,7 @@ function nextUpdateCheckFromState(nowMs) {
|
|
|
17198
18114
|
}
|
|
17199
18115
|
var nextUpdateCheckAtMs = nextUpdateCheckFromState(Date.now());
|
|
17200
18116
|
function cliEntryPath() {
|
|
17201
|
-
return
|
|
18117
|
+
return join13(dirname12(fileURLToPath(import.meta.url)), "index.js");
|
|
17202
18118
|
}
|
|
17203
18119
|
async function runDaemonUpdateCheck() {
|
|
17204
18120
|
if (process.env.FLEETLENS_DAEMON_AUTO_UPDATE === "0") {
|
|
@@ -17230,7 +18146,7 @@ async function runDaemonUpdateCheck() {
|
|
|
17230
18146
|
return;
|
|
17231
18147
|
}
|
|
17232
18148
|
const entry = cliEntryPath();
|
|
17233
|
-
if (!
|
|
18149
|
+
if (!existsSync19(entry)) {
|
|
17234
18150
|
log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
|
|
17235
18151
|
return;
|
|
17236
18152
|
}
|
|
@@ -17239,7 +18155,7 @@ async function runDaemonUpdateCheck() {
|
|
|
17239
18155
|
logFd = openSync(DAEMON_LOG, "a");
|
|
17240
18156
|
} catch {
|
|
17241
18157
|
}
|
|
17242
|
-
const child =
|
|
18158
|
+
const child = spawn3(process.execPath, [entry, "update"], {
|
|
17243
18159
|
detached: true,
|
|
17244
18160
|
stdio: ["ignore", logFd, logFd],
|
|
17245
18161
|
env: { ...process.env, FLEETLENS_UPDATE_SOURCE: "daemon" }
|
|
@@ -17269,7 +18185,7 @@ async function runDaemonUpdateCheck() {
|
|
|
17269
18185
|
nextUpdateCheckAtMs = Date.now() + AUTO_UPDATE_INTERVAL_MS;
|
|
17270
18186
|
}
|
|
17271
18187
|
}
|
|
17272
|
-
async function
|
|
18188
|
+
async function pollAuxiliaryUsage() {
|
|
17273
18189
|
for (const source of agentSources) {
|
|
17274
18190
|
if (source.kind === "claude-code") continue;
|
|
17275
18191
|
if (!source.usagePoller) continue;
|
|
@@ -17309,6 +18225,31 @@ async function tick() {
|
|
|
17309
18225
|
log2("warn", `zai poll failed: ${err.message}`);
|
|
17310
18226
|
}
|
|
17311
18227
|
}
|
|
18228
|
+
try {
|
|
18229
|
+
const copilotSnapshot = await fetchCopilotUsage();
|
|
18230
|
+
appendSnapshot(USAGE_LOG3, copilotSnapshot);
|
|
18231
|
+
const monthly = copilotSnapshot.monthly?.utilization;
|
|
18232
|
+
log2("info", `copilot snapshot monthly=${monthly === null || monthly === void 0 ? "\u2014" : `${monthly}%`}`);
|
|
18233
|
+
} catch (err) {
|
|
18234
|
+
if (err instanceof CopilotApiError && err.code === "no_cli") {
|
|
18235
|
+
pruneAgent(USAGE_LOG3, "copilot");
|
|
18236
|
+
} else if (!(err instanceof CopilotApiError && err.code === "no_auth")) {
|
|
18237
|
+
log2("warn", `copilot poll failed: ${err.message}`);
|
|
18238
|
+
}
|
|
18239
|
+
}
|
|
18240
|
+
try {
|
|
18241
|
+
const codexSnapshot = await fetchCodexUsage();
|
|
18242
|
+
appendSnapshot(USAGE_LOG3, codexSnapshot);
|
|
18243
|
+
const fiveHour = codexSnapshot.five_hour.utilization === null ? "\u2014" : `${codexSnapshot.five_hour.utilization}%`;
|
|
18244
|
+
const sevenDay = codexSnapshot.seven_day.utilization === null ? "\u2014" : `${codexSnapshot.seven_day.utilization}%`;
|
|
18245
|
+
log2("info", `codex snapshot 5h=${fiveHour} 7d=${sevenDay}`);
|
|
18246
|
+
} catch (err) {
|
|
18247
|
+
if (err instanceof CodexApiError && (err.code === "no_auth" || err.code === "api_key_only")) {
|
|
18248
|
+
pruneAgent(USAGE_LOG3, "codex");
|
|
18249
|
+
} else {
|
|
18250
|
+
log2("warn", `codex poll failed: ${err.message}`);
|
|
18251
|
+
}
|
|
18252
|
+
}
|
|
17312
18253
|
try {
|
|
17313
18254
|
const grokSnapshot = await fetchGrokUsage();
|
|
17314
18255
|
appendSnapshot(USAGE_LOG3, grokSnapshot);
|
|
@@ -17327,6 +18268,8 @@ async function tick() {
|
|
|
17327
18268
|
log2("warn", `grok poll failed: ${err.message}`);
|
|
17328
18269
|
}
|
|
17329
18270
|
}
|
|
18271
|
+
}
|
|
18272
|
+
async function pollClaudeUsage() {
|
|
17330
18273
|
try {
|
|
17331
18274
|
const snapshot = await fetchUsage();
|
|
17332
18275
|
appendSnapshot(USAGE_LOG3, snapshot);
|
|
@@ -17361,6 +18304,10 @@ function sleep2(ms) {
|
|
|
17361
18304
|
async function runLoop() {
|
|
17362
18305
|
while (true) {
|
|
17363
18306
|
const now = Date.now();
|
|
18307
|
+
if (now >= nextAuxPollAtMs) {
|
|
18308
|
+
await pollAuxiliaryUsage();
|
|
18309
|
+
nextAuxPollAtMs = Date.now() + BASE_INTERVAL_MS;
|
|
18310
|
+
}
|
|
17364
18311
|
if (now >= nextPollAtMs) {
|
|
17365
18312
|
if (nextPollAtMs > 0 && now - nextPollAtMs > currentIntervalMs) {
|
|
17366
18313
|
log2(
|
|
@@ -17383,7 +18330,7 @@ async function runLoop() {
|
|
|
17383
18330
|
log2("info", "token refreshed; resuming polls");
|
|
17384
18331
|
waitingForRefresh = false;
|
|
17385
18332
|
}
|
|
17386
|
-
const outcome = await
|
|
18333
|
+
const outcome = await pollClaudeUsage();
|
|
17387
18334
|
scheduleAfter(Date.now(), outcome);
|
|
17388
18335
|
}
|
|
17389
18336
|
}
|