fleetlens 0.14.0 → 0.15.1

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.
Files changed (212) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/app-path-routes-manifest.json +4 -0
  3. package/app/apps/web/.next/build-manifest.json +3 -3
  4. package/app/apps/web/.next/prerender-manifest.json +3 -3
  5. package/app/apps/web/.next/routes-manifest.json +24 -0
  6. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  7. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/app/apps/web/.next/server/app/_not-found/page.js +1 -1
  14. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/app/apps/web/.next/server/app/api/ask/route.js +3 -3
  17. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  18. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +4 -4
  19. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +4 -4
  21. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/digest/month-index/route.js +2 -2
  23. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  24. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +4 -4
  25. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/api/digest/week-index/route.js +2 -2
  27. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js +4 -4
  29. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
  30. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  31. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/api/settings/route.js +5 -4
  33. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  34. package/app/apps/web/.next/server/app/api/team/autostart/route/app-paths-manifest.json +3 -0
  35. package/app/apps/web/.next/server/app/api/team/autostart/route/build-manifest.json +9 -0
  36. package/app/apps/web/.next/server/app/api/team/autostart/route/server-reference-manifest.json +4 -0
  37. package/app/apps/web/.next/server/app/api/team/autostart/route.js +7 -0
  38. package/app/apps/web/.next/server/app/api/team/autostart/route.js.map +5 -0
  39. package/app/apps/web/.next/server/app/api/team/autostart/route.js.nft.json +1 -0
  40. package/app/apps/web/.next/server/app/api/team/autostart/route_client-reference-manifest.js +3 -0
  41. package/app/apps/web/.next/server/app/api/team/onboarding/start/route/app-paths-manifest.json +3 -0
  42. package/app/apps/web/.next/server/app/api/team/onboarding/start/route/build-manifest.json +9 -0
  43. package/app/apps/web/.next/server/app/api/team/onboarding/start/route/server-reference-manifest.json +4 -0
  44. package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js +8 -0
  45. package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js.map +5 -0
  46. package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js.nft.json +1 -0
  47. package/app/apps/web/.next/server/app/api/team/onboarding/start/route_client-reference-manifest.js +3 -0
  48. package/app/apps/web/.next/server/app/api/team/sync-projects/route/app-paths-manifest.json +3 -0
  49. package/app/apps/web/.next/server/app/api/team/sync-projects/route/build-manifest.json +9 -0
  50. package/app/apps/web/.next/server/app/api/team/sync-projects/route/server-reference-manifest.json +4 -0
  51. package/app/apps/web/.next/server/app/api/team/sync-projects/route.js +8 -0
  52. package/app/apps/web/.next/server/app/api/team/sync-projects/route.js.map +5 -0
  53. package/app/apps/web/.next/server/app/api/team/sync-projects/route.js.nft.json +1 -0
  54. package/app/apps/web/.next/server/app/api/team/sync-projects/route_client-reference-manifest.js +3 -0
  55. package/app/apps/web/.next/server/app/changelog/page.js +1 -1
  56. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  57. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  58. package/app/apps/web/.next/server/app/day/[date]/page.js +1 -1
  59. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  60. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  61. package/app/apps/web/.next/server/app/day/page.js +1 -1
  62. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  63. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  64. package/app/apps/web/.next/server/app/digest/[date]/page.js +1 -1
  65. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  66. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  67. package/app/apps/web/.next/server/app/digest/page.js +1 -1
  68. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  69. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  70. package/app/apps/web/.next/server/app/insights/[key]/page.js +1 -1
  71. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  72. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  73. package/app/apps/web/.next/server/app/insights/page.js +1 -1
  74. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  75. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  76. package/app/apps/web/.next/server/app/page.js +1 -1
  77. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  78. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  79. package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
  80. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  81. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  82. package/app/apps/web/.next/server/app/print/[key]/page.js +1 -1
  83. package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
  84. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  85. package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -1
  86. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  87. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  88. package/app/apps/web/.next/server/app/projects/page.js +1 -1
  89. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  90. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  91. package/app/apps/web/.next/server/app/runs/page.js +1 -1
  92. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  93. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  94. package/app/apps/web/.next/server/app/sessions/[id]/page.js +3 -3
  95. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  96. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  97. package/app/apps/web/.next/server/app/sessions/page.js +1 -1
  98. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  99. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  100. package/app/apps/web/.next/server/app/settings/page.js +2 -2
  101. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  102. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  103. package/app/apps/web/.next/server/app/team/onboarding/page/app-paths-manifest.json +3 -0
  104. package/app/apps/web/.next/server/app/team/onboarding/page/build-manifest.json +17 -0
  105. package/app/apps/web/.next/server/app/team/onboarding/page/next-font-manifest.json +6 -0
  106. package/app/apps/web/.next/server/app/team/onboarding/page/react-loadable-manifest.json +1 -0
  107. package/app/apps/web/.next/server/app/team/onboarding/page/server-reference-manifest.json +4 -0
  108. package/app/apps/web/.next/server/app/team/onboarding/page.js +19 -0
  109. package/app/apps/web/.next/server/app/team/onboarding/page.js.map +5 -0
  110. package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -0
  111. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +3 -0
  112. package/app/apps/web/.next/server/app/team/page.js +3 -2
  113. package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
  114. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  115. package/app/apps/web/.next/server/app/usage/page.js +1 -1
  116. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  117. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  118. package/app/apps/web/.next/server/app-paths-manifest.json +4 -0
  119. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_team_onboarding_start_route_actions_0zeptl_.js +3 -0
  120. package/app/apps/web/.next/server/chunks/0fuv_zod_v4_classic_external_0.z.vap.js +39 -0
  121. package/app/apps/web/.next/server/chunks/[root-of-the-server]__038-.1r._.js +6 -0
  122. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0~utv~v._.js → [root-of-the-server]__03ewxxu._.js} +2 -2
  123. package/app/apps/web/.next/server/chunks/[root-of-the-server]__03rmbz6._.js +3 -0
  124. package/app/apps/web/.next/server/chunks/{[externals]__0o43ejh._.js → [root-of-the-server]__065lib8._.js} +2 -2
  125. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0e.f-t.._.js → [root-of-the-server]__0a0~7d6._.js} +2 -2
  126. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0gril0u._.js → [root-of-the-server]__0acikq.._.js} +2 -2
  127. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0et2sqb._.js +3 -0
  128. package/app/apps/web/.next/server/chunks/{[externals]__09v47rg._.js → [root-of-the-server]__0jbc7tz._.js} +2 -2
  129. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0mq0or2._.js +3 -0
  130. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0mvl0qn._.js +3 -0
  131. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0n79hpm._.js → [root-of-the-server]__0ow1kn1._.js} +4 -4
  132. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0~xt99s._.js +3 -0
  133. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_team_autostart_route_actions_10-4s71.js +3 -0
  134. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_team_sync-projects_route_actions_0r_2f5n.js +3 -0
  135. package/app/apps/web/.next/server/chunks/node_modules_next_036my~r._.js +4 -40
  136. package/app/apps/web/.next/server/chunks/packages_09wmnv.._.js +3 -0
  137. package/app/apps/web/.next/server/chunks/packages_0o6.gpk._.js +3 -0
  138. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  139. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  140. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0a7n44-._.js +3 -0
  141. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0c00i76._.js +3 -0
  142. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0i.q-1h._.js +3 -0
  143. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0stu~~r._.js +3 -0
  144. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ufi3.w._.js +3 -0
  145. package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
  146. package/app/apps/web/.next/server/chunks/ssr/apps_web_0.97l5.._.js +3 -0
  147. package/app/apps/web/.next/server/chunks/ssr/{apps_web_app_settings_0u6z6rj._.js → apps_web_0q2x4a~._.js} +2 -2
  148. package/app/apps/web/.next/server/chunks/ssr/apps_web_114yo0v._.js +3 -0
  149. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_team_onboarding_page_actions_0pss~.k.js +3 -0
  150. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0c-tpft._.js +1 -1
  151. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +1 -1
  152. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  153. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
  154. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_team-config_ts_10egg08._.js +39 -0
  155. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_0w2y7fz._.js +2 -2
  156. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0jxvcfi.js +2 -2
  157. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0s5yhs4.js +4 -0
  158. package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
  159. package/app/apps/web/.next/server/functions-config-manifest.json +3 -0
  160. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  161. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  162. package/app/apps/web/.next/server/pages/500.html +1 -1
  163. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  164. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  165. package/app/apps/web/.next/static/chunks/{0wwcx42ng8i2e.js → 0-3_u.90d79wi.js} +1 -1
  166. package/app/apps/web/.next/static/chunks/00a9oyw~h5i1p.js +1 -0
  167. package/app/apps/web/.next/static/chunks/040s42ypidk7s.css +1 -0
  168. package/app/apps/web/.next/static/chunks/06qeg4pt5jdqs.js +1 -0
  169. package/app/apps/web/.next/static/chunks/0bikiz3oo~oy4.js +1 -0
  170. package/app/apps/web/.next/static/chunks/{0e_fzy0n8ij-o.js → 0u6gxpqhl0gc7.js} +1 -1
  171. package/app/apps/web/.next/static/chunks/18cj08-la37o-.js +1 -0
  172. package/app/apps/web/app/api/team/autostart/route.ts +41 -0
  173. package/app/apps/web/app/api/team/onboarding/start/route.ts +96 -0
  174. package/app/apps/web/app/api/team/sync-projects/route.ts +39 -0
  175. package/app/apps/web/app/globals.css +82 -0
  176. package/app/apps/web/app/settings/ai-features-form.tsx +1 -1
  177. package/app/apps/web/app/settings/page.tsx +21 -7
  178. package/app/apps/web/app/{settings → team}/force-sync-button.tsx +2 -4
  179. package/app/apps/web/app/team/onboarding/onboarding-wizard.tsx +503 -0
  180. package/app/apps/web/app/team/onboarding/page.tsx +28 -0
  181. package/app/apps/web/app/team/page.tsx +48 -17
  182. package/app/apps/web/app/{settings/team-connection-section.tsx → team/sync-activity-section.tsx} +6 -23
  183. package/app/apps/web/app/team/synced-projects-form.tsx +201 -0
  184. package/app/apps/web/app/team/synced-projects-section.tsx +37 -0
  185. package/app/apps/web/components/autostart-toggle.tsx +59 -0
  186. package/app/apps/web/components/project-sync-picker.tsx +109 -0
  187. package/app/apps/web/components/team-chip.tsx +1 -1
  188. package/app/apps/web/components/team-welcome-banner.tsx +1 -1
  189. package/app/apps/web/lib/autostart-data.ts +31 -0
  190. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  191. package/app/apps/web/lib/sync-projects-data.ts +36 -0
  192. package/app/apps/web/lib/team-config.ts +21 -2
  193. package/app/apps/web/package.json +1 -1
  194. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  195. package/dist/daemon-worker.js +150 -42
  196. package/dist/index.js +336 -102
  197. package/package.json +1 -1
  198. package/app/apps/web/.next/server/chunks/[root-of-the-server]__08agijy._.js +0 -3
  199. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i06ito._.js +0 -3
  200. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0y5p73y._.js +0 -3
  201. package/app/apps/web/.next/server/chunks/packages_0c-sz9n._.js +0 -3
  202. package/app/apps/web/.next/server/chunks/packages_0wywuu.._.js +0 -3
  203. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__09yxy53._.js +0 -3
  204. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0_hv6aq._.js +0 -3
  205. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0dh0q7b._.js +0 -3
  206. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0yv0m0q._.js +0 -3
  207. package/app/apps/web/.next/static/chunks/005ad7l-h1-.6.js +0 -1
  208. package/app/apps/web/.next/static/chunks/0h.ua.-myj.6z.js +0 -1
  209. package/app/apps/web/.next/static/chunks/0l4r0bqqtdju..css +0 -1
  210. /package/app/apps/web/.next/static/{3VbAChKD8EChlt8Tm5N5r → BnmSIRvauHhYldK_BrdFF}/_buildManifest.js +0 -0
  211. /package/app/apps/web/.next/static/{3VbAChKD8EChlt8Tm5N5r → BnmSIRvauHhYldK_BrdFF}/_clientMiddlewareManifest.js +0 -0
  212. /package/app/apps/web/.next/static/{3VbAChKD8EChlt8Tm5N5r → BnmSIRvauHhYldK_BrdFF}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -4222,8 +4222,17 @@ var init_cowork = __esm({
4222
4222
  });
4223
4223
 
4224
4224
  // ../parser/dist/team-config.js
4225
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2 } from "node:fs";
4225
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2, renameSync } from "node:fs";
4226
4226
  import { join } from "node:path";
4227
+ function shouldSyncProject(repoName, sp) {
4228
+ if (!sp)
4229
+ return true;
4230
+ if (sp.excluded.includes(repoName))
4231
+ return false;
4232
+ if (sp.included.includes(repoName))
4233
+ return true;
4234
+ return sp.autoIncludeNew;
4235
+ }
4227
4236
  function readTeamConfig(dir) {
4228
4237
  const d = dir ?? cclensHome();
4229
4238
  try {
@@ -4235,7 +4244,9 @@ function readTeamConfig(dir) {
4235
4244
  function writeTeamConfig(config, dir) {
4236
4245
  const d = dir ?? cclensHome();
4237
4246
  mkdirSync2(d, { recursive: true });
4238
- writeFileSync2(join(d, CONFIG_FILE), JSON.stringify(config, null, 2), { mode: 384 });
4247
+ const tmp = join(d, `${CONFIG_FILE}.${process.pid}.tmp`);
4248
+ writeFileSync2(tmp, JSON.stringify(config, null, 2), { mode: 384 });
4249
+ renameSync(tmp, join(d, CONFIG_FILE));
4239
4250
  }
4240
4251
  function clearTeamConfig(dir) {
4241
4252
  const d = dir ?? cclensHome();
@@ -4309,6 +4320,7 @@ __export(fs_exports, {
4309
4320
  readJsonlFile: () => readJsonlFile,
4310
4321
  readTeamConfig: () => readTeamConfig,
4311
4322
  sessionIdFromFileName: () => sessionIdFromFileName,
4323
+ shouldSyncProject: () => shouldSyncProject,
4312
4324
  walkJsonlFiles: () => walkJsonlFiles,
4313
4325
  writeTeamConfig: () => writeTeamConfig
4314
4326
  });
@@ -4677,7 +4689,7 @@ function getServerStatus() {
4677
4689
  return { running: false };
4678
4690
  }
4679
4691
  function isServerStale(status2) {
4680
- return status2.running === true && status2.version !== "0.14.0";
4692
+ return status2.running === true && status2.version !== "0.15.1";
4681
4693
  }
4682
4694
  async function ensureCurrentServer(opts = {}) {
4683
4695
  const status2 = getServerStatus();
@@ -4733,8 +4745,8 @@ async function startServer(opts = {}) {
4733
4745
  });
4734
4746
  child.unref();
4735
4747
  const pid = child.pid;
4736
- writePid(PID_FILE, pid, port, "0.14.0");
4737
- await waitForHealth(`http://localhost:${port}`, 1e4);
4748
+ writePid(PID_FILE, pid, port, "0.15.1");
4749
+ await waitForHealth(`http://localhost:${port}`, 3e4);
4738
4750
  return { pid, port };
4739
4751
  }
4740
4752
  function stopServer() {
@@ -4796,6 +4808,13 @@ var init_server = __esm({
4796
4808
  });
4797
4809
 
4798
4810
  // src/usage/storage.ts
4811
+ var storage_exports = {};
4812
+ __export(storage_exports, {
4813
+ appendSnapshot: () => appendSnapshot,
4814
+ latestClaudeCodeSnapshot: () => latestClaudeCodeSnapshot,
4815
+ latestSnapshot: () => latestSnapshot,
4816
+ readSnapshots: () => readSnapshots
4817
+ });
4799
4818
  import { appendFileSync, mkdirSync as mkdirSync3, readFileSync as readFileSync3, existsSync as existsSync2 } from "node:fs";
4800
4819
  import { dirname as dirname3 } from "node:path";
4801
4820
  function appendSnapshot(filePath, snapshot) {
@@ -5013,7 +5032,7 @@ async function fetchLatestVersion() {
5013
5032
  }
5014
5033
  function runNpmInstall() {
5015
5034
  try {
5016
- execSync(`npm install -g ${PACKAGE_NAME}@latest`, {
5035
+ execSync(`npm install -g ${PACKAGE_NAME}@latest --prefer-online`, {
5017
5036
  stdio: "pipe",
5018
5037
  timeout: 6e4
5019
5038
  });
@@ -5093,9 +5112,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
5093
5112
  console.warn(
5094
5113
  ` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
5095
5114
  );
5096
- } else if (verify.installedVersion !== "0.14.0") {
5115
+ } else if (verify.installedVersion !== "0.15.1") {
5097
5116
  console.log(
5098
- ` \u2192 This process is still running ${"0.14.0"}. Next invocation will use ${verify.installedVersion}.`
5117
+ ` \u2192 This process is still running ${"0.15.1"}. Next invocation will use ${verify.installedVersion}.`
5099
5118
  );
5100
5119
  }
5101
5120
  }
@@ -5130,14 +5149,14 @@ async function getUpdateAvailability() {
5130
5149
  if (isDevMode()) return null;
5131
5150
  const latest = await fetchLatestVersion();
5132
5151
  if (latest === null) return {
5133
- current: "0.14.0",
5152
+ current: "0.15.1",
5134
5153
  latest: null,
5135
5154
  updateAvailable: false
5136
5155
  };
5137
5156
  return {
5138
- current: "0.14.0",
5157
+ current: "0.15.1",
5139
5158
  latest,
5140
- updateAvailable: shouldUpdate("0.14.0", latest)
5159
+ updateAvailable: shouldUpdate("0.15.1", latest)
5141
5160
  };
5142
5161
  }
5143
5162
  async function checkForUpdate() {
@@ -5227,7 +5246,7 @@ async function restartServices(state) {
5227
5246
  }
5228
5247
  async function forceUpdate() {
5229
5248
  const latest = await fetchLatestVersion();
5230
- const current = "0.14.0";
5249
+ const current = "0.15.1";
5231
5250
  if (latest === null) {
5232
5251
  console.error("Could not reach npm registry. Check your network.");
5233
5252
  process.exit(1);
@@ -5270,10 +5289,14 @@ __export(autostart_exports, {
5270
5289
  autostart: () => autostart,
5271
5290
  buildPlist: () => buildPlist,
5272
5291
  dismissPrompt: () => dismissPrompt,
5292
+ ensureTeamAutostart: () => ensureTeamAutostart,
5293
+ hasOptedOut: () => hasOptedOut,
5273
5294
  installAutostart: () => installAutostart,
5274
5295
  isAutostartInstalled: () => isAutostartInstalled,
5275
5296
  isPromptDismissed: () => isPromptDismissed,
5276
- maybePromptAutostart: () => maybePromptAutostart
5297
+ isStalePlistContent: () => isStalePlistContent,
5298
+ maybePromptAutostart: () => maybePromptAutostart,
5299
+ recordOptOut: () => recordOptOut
5277
5300
  });
5278
5301
  import { existsSync as existsSync5, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, rmSync, readFileSync as readFileSync6, realpathSync as realpathSync2 } from "node:fs";
5279
5302
  import { homedir as homedir2 } from "node:os";
@@ -5290,6 +5313,16 @@ function isMac() {
5290
5313
  function isAutostartInstalled() {
5291
5314
  return isMac() && existsSync5(plistPath());
5292
5315
  }
5316
+ function isStalePlistContent(content) {
5317
+ return content.includes("<string>daemon</string>");
5318
+ }
5319
+ function installedPlistIsStale() {
5320
+ try {
5321
+ return isStalePlistContent(readFileSync6(plistPath(), "utf8"));
5322
+ } catch {
5323
+ return false;
5324
+ }
5325
+ }
5293
5326
  function resolveScriptPath() {
5294
5327
  const argv1 = process.argv[1] ?? "";
5295
5328
  try {
@@ -5310,7 +5343,6 @@ function buildPlist(opts) {
5310
5343
  <array>
5311
5344
  <string>${nodePath}</string>
5312
5345
  <string>${scriptPath}</string>
5313
- <string>daemon</string>
5314
5346
  <string>start</string>
5315
5347
  </array>
5316
5348
  <key>RunAtLoad</key>
@@ -5342,9 +5374,10 @@ async function installAutostart() {
5342
5374
  await runLaunchctl(["unload", p]).catch(() => {
5343
5375
  });
5344
5376
  await runLaunchctl(["load", "-w", p]);
5345
- console.log("Autostart installed \u2014 the Fleetlens usage daemon will start at login.");
5377
+ writeFlags({ optedOut: false });
5378
+ console.log("Autostart installed \u2014 Fleetlens (dashboard + usage daemon) will start at login.");
5346
5379
  console.log(` LaunchAgent: ${p}`);
5347
- console.log(` Runs: ${nodePath} ${scriptPath} daemon start`);
5380
+ console.log(` Runs: ${nodePath} ${scriptPath} start`);
5348
5381
  console.log(
5349
5382
  " Note: the Node path above is baked in. If you upgrade or switch Node (e.g. via nvm), re-run `fleetlens autostart install`."
5350
5383
  );
@@ -5356,14 +5389,33 @@ async function uninstallAutostart() {
5356
5389
  return;
5357
5390
  }
5358
5391
  const p = plistPath();
5392
+ recordOptOut();
5359
5393
  if (!existsSync5(p)) {
5360
- console.log("Autostart is not installed \u2014 nothing to remove.");
5394
+ console.log("Autostart is not installed \u2014 nothing to remove. Noted your opt-out; team join won't enable it.");
5361
5395
  return;
5362
5396
  }
5363
5397
  await runLaunchctl(["unload", "-w", p]).catch(() => {
5364
5398
  });
5365
5399
  rmSync(p, { force: true });
5366
5400
  console.log(`Autostart removed (${p}). The daemon will no longer start at login.`);
5401
+ console.log(" Opt-out recorded \u2014 team join/start won't re-enable it.");
5402
+ }
5403
+ async function ensureTeamAutostart() {
5404
+ try {
5405
+ if (!isMac()) return;
5406
+ if (isAutostartInstalled()) {
5407
+ if (installedPlistIsStale()) {
5408
+ console.log(" Updating the Fleetlens login item to launch the full stack (dashboard + daemon).");
5409
+ await installAutostart();
5410
+ }
5411
+ return;
5412
+ }
5413
+ if (hasOptedOut()) return;
5414
+ console.log(" Team reporting stays on across reboots: enabling Fleetlens auto-start at login (dashboard + daemon).");
5415
+ console.log(" (Opt out anytime: fleetlens autostart uninstall \u2014 join won't re-enable it.)");
5416
+ await installAutostart();
5417
+ } catch {
5418
+ }
5367
5419
  }
5368
5420
  async function statusAutostart() {
5369
5421
  if (!isMac()) {
@@ -5384,22 +5436,33 @@ async function statusAutostart() {
5384
5436
  function promptFlagPath() {
5385
5437
  return cclensPath("autostart.json");
5386
5438
  }
5387
- function isPromptDismissed() {
5439
+ function readFlags() {
5388
5440
  try {
5389
- const j = JSON.parse(readFileSync6(promptFlagPath(), "utf8"));
5390
- return j.promptDismissed === true;
5441
+ return JSON.parse(readFileSync6(promptFlagPath(), "utf8"));
5391
5442
  } catch {
5392
- return false;
5443
+ return {};
5393
5444
  }
5394
5445
  }
5395
- function dismissPrompt() {
5446
+ function writeFlags(patch) {
5396
5447
  const p = promptFlagPath();
5397
5448
  try {
5398
5449
  mkdirSync4(dirname6(p), { recursive: true });
5399
- writeFileSync3(p, JSON.stringify({ promptDismissed: true }, null, 2), "utf8");
5450
+ writeFileSync3(p, JSON.stringify({ ...readFlags(), ...patch }, null, 2), "utf8");
5400
5451
  } catch {
5401
5452
  }
5402
5453
  }
5454
+ function isPromptDismissed() {
5455
+ return readFlags().promptDismissed === true;
5456
+ }
5457
+ function dismissPrompt() {
5458
+ writeFlags({ promptDismissed: true });
5459
+ }
5460
+ function hasOptedOut() {
5461
+ return readFlags().optedOut === true;
5462
+ }
5463
+ function recordOptOut() {
5464
+ writeFlags({ optedOut: true });
5465
+ }
5403
5466
  function promptYesNo(question, defaultYes) {
5404
5467
  return new Promise((resolve3) => {
5405
5468
  const rl = createInterface({ input: process.stdin, output: process.stdout });
@@ -5414,15 +5477,26 @@ function promptYesNo(question, defaultYes) {
5414
5477
  async function maybePromptAutostart(opts) {
5415
5478
  try {
5416
5479
  if (!isMac()) return;
5417
- if (!opts.daemonStarted) return;
5418
5480
  if (process.env.__FLEETLENS_UPDATED) return;
5481
+ const { readTeamConfig: readTeamConfig2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
5482
+ if (readTeamConfig2()) {
5483
+ await ensureTeamAutostart();
5484
+ return;
5485
+ }
5486
+ if (!opts.daemonStarted) return;
5419
5487
  if (!process.stdin.isTTY) return;
5420
- if (isAutostartInstalled()) return;
5488
+ if (isAutostartInstalled()) {
5489
+ if (installedPlistIsStale()) {
5490
+ console.log("Updating the Fleetlens login item to launch the full stack (dashboard + daemon).");
5491
+ await installAutostart();
5492
+ }
5493
+ return;
5494
+ }
5421
5495
  if (isPromptDismissed()) return;
5422
5496
  console.log("");
5423
- console.log("Tip: keep the Fleetlens usage daemon running after you restart your Mac?");
5424
- console.log(" This installs a launchd LaunchAgent that runs `fleetlens daemon start`");
5425
- console.log(" at login (daemon only \u2014 not the dashboard server).");
5497
+ console.log("Tip: keep Fleetlens running after you restart your Mac?");
5498
+ console.log(" This installs a launchd LaunchAgent that runs `fleetlens start`");
5499
+ console.log(" at login (dashboard server + usage daemon).");
5426
5500
  const yes = await promptYesNo("Set that up now? [Y/n] ", true);
5427
5501
  if (yes) {
5428
5502
  await installAutostart();
@@ -5585,7 +5659,7 @@ async function status() {
5585
5659
  console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
5586
5660
  if (isServerStale(server)) {
5587
5661
  console.log(
5588
- ` \u26A0 serving stale ${ver} (CLI is ${"0.14.0"}) \u2014 run 'fleetlens start' to restart on the current version`
5662
+ ` \u26A0 serving stale ${ver} (CLI is ${"0.15.1"}) \u2014 run 'fleetlens start' to restart on the current version`
5589
5663
  );
5590
5664
  }
5591
5665
  } else {
@@ -5723,6 +5797,11 @@ var init_token = __esm({
5723
5797
  });
5724
5798
 
5725
5799
  // src/usage/api.ts
5800
+ var api_exports = {};
5801
+ __export(api_exports, {
5802
+ UsageApiError: () => UsageApiError,
5803
+ fetchUsage: () => fetchUsage
5804
+ });
5726
5805
  async function fetchUsage() {
5727
5806
  const creds = readOAuthCredentials();
5728
5807
  if (!creds) {
@@ -7510,7 +7589,7 @@ var init_dist2 = __esm({
7510
7589
  });
7511
7590
 
7512
7591
  // ../entries/dist/digest-fs.js
7513
- import { readFileSync as readFileSync8, readdirSync, writeFileSync as writeFileSync4, renameSync, chmodSync, mkdirSync as mkdirSync5, existsSync as existsSync6 } from "node:fs";
7592
+ import { readFileSync as readFileSync8, readdirSync, writeFileSync as writeFileSync4, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync5, existsSync as existsSync6 } from "node:fs";
7514
7593
  import { dirname as dirname7, join as join7 } from "node:path";
7515
7594
  function parseDigestFile(path7, expectedVersion) {
7516
7595
  try {
@@ -7559,7 +7638,7 @@ function writeDayDigest(digest2) {
7559
7638
  } catch {
7560
7639
  }
7561
7640
  }
7562
- renameSync(tmp, final);
7641
+ renameSync2(tmp, final);
7563
7642
  }
7564
7643
  function readDayDigest(date) {
7565
7644
  const p = dayDigestPath(date);
@@ -7595,7 +7674,7 @@ function writeWeekDigest(digest2) {
7595
7674
  } catch {
7596
7675
  }
7597
7676
  }
7598
- renameSync(tmp, final);
7677
+ renameSync2(tmp, final);
7599
7678
  }
7600
7679
  function readWeekDigest(monday) {
7601
7680
  const p = weekDigestPath(monday);
@@ -7632,7 +7711,7 @@ function writeMonthDigest(digest2) {
7632
7711
  } catch {
7633
7712
  }
7634
7713
  }
7635
- renameSync(tmp, final);
7714
+ renameSync2(tmp, final);
7636
7715
  }
7637
7716
  function readMonthDigest(yearMonth) {
7638
7717
  const p = monthDigestPath(yearMonth);
@@ -7704,7 +7783,7 @@ __export(fs_exports2, {
7704
7783
  writeMonthDigest: () => writeMonthDigest,
7705
7784
  writeWeekDigest: () => writeWeekDigest
7706
7785
  });
7707
- import { readFileSync as readFileSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, renameSync as renameSync2, existsSync as existsSync7 } from "node:fs";
7786
+ import { readFileSync as readFileSync9, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, renameSync as renameSync3, existsSync as existsSync7 } from "node:fs";
7708
7787
  import { randomBytes } from "node:crypto";
7709
7788
  import { join as join8 } from "node:path";
7710
7789
  function entriesDir() {
@@ -7731,7 +7810,7 @@ function writeEntry(entry) {
7731
7810
  const tmp = tmpPathFor(final);
7732
7811
  const json = JSON.stringify(entry, null, 2);
7733
7812
  writeFileSync5(tmp, json, { encoding: "utf8" });
7734
- renameSync2(tmp, final);
7813
+ renameSync3(tmp, final);
7735
7814
  }
7736
7815
  function enrichmentInputHash(e) {
7737
7816
  return [
@@ -7759,7 +7838,7 @@ function writeEntryPreservingEnrichment(fresh) {
7759
7838
  }
7760
7839
  const tmp = tmpPathFor(final);
7761
7840
  writeFileSync5(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
7762
- renameSync2(tmp, final);
7841
+ renameSync3(tmp, final);
7763
7842
  }
7764
7843
  function readEntry(sessionId, localDay2) {
7765
7844
  const p = pathFor(sessionId, localDay2);
@@ -12052,7 +12131,7 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
12052
12131
  });
12053
12132
 
12054
12133
  // ../entries/dist/tmux-runner.js
12055
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6, existsSync as existsSync8, readdirSync as readdirSync3, realpathSync as realpathSync3, readFileSync as readFileSync10, unlinkSync as unlinkSync3, renameSync as renameSync3 } from "node:fs";
12134
+ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync6, existsSync as existsSync8, readdirSync as readdirSync3, realpathSync as realpathSync3, readFileSync as readFileSync10, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
12056
12135
  import { join as join9 } from "node:path";
12057
12136
  import { homedir as homedir4 } from "node:os";
12058
12137
  import { spawnSync as spawnSync2 } from "node:child_process";
@@ -12095,7 +12174,7 @@ function ensureRuntimeCwdTrusted(cwd) {
12095
12174
  const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
12096
12175
  try {
12097
12176
  writeFileSync6(tmp, JSON.stringify(cfg, null, 2));
12098
- renameSync3(tmp, cfgPath);
12177
+ renameSync4(tmp, cfgPath);
12099
12178
  } catch {
12100
12179
  try {
12101
12180
  unlinkSync3(tmp);
@@ -13038,7 +13117,7 @@ var init_queue = __esm({
13038
13117
  });
13039
13118
 
13040
13119
  // ../entries/dist/settings.js
13041
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, renameSync as renameSync4, chmodSync as chmodSync2, mkdirSync as mkdirSync10, existsSync as existsSync12 } from "node:fs";
13120
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync9, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync10, existsSync as existsSync12 } from "node:fs";
13042
13121
  import { dirname as dirname9 } from "node:path";
13043
13122
  function settingsPath() {
13044
13123
  if (settingsPathCached)
@@ -13091,7 +13170,7 @@ function writeSettings(s) {
13091
13170
  if (process.platform !== "win32") {
13092
13171
  chmodSync2(tmp, 384);
13093
13172
  }
13094
- renameSync4(tmp, p);
13173
+ renameSync5(tmp, p);
13095
13174
  }
13096
13175
  var DEFAULT_SETTINGS, settingsPathCached;
13097
13176
  var init_settings = __esm({
@@ -16933,6 +17012,10 @@ function clipSegmentsToDay(segments, bounds) {
16933
17012
  }
16934
17013
  return out;
16935
17014
  }
17015
+ function filterSyncedSessions(sessions, syncProjects) {
17016
+ if (!syncProjects) return sessions;
17017
+ return sessions.filter((s) => shouldSyncProject(projectRepoName(s.projectName), syncProjects));
17018
+ }
16936
17019
  function sessionTouchesDay(s, day2) {
16937
17020
  const bounds = dayBoundsMs(day2);
16938
17021
  if (s.activeSegments && s.activeSegments.length > 0) {
@@ -17087,7 +17170,8 @@ function ensureEntriesForDay(day2, daySessions) {
17087
17170
  }
17088
17171
  function buildRichBlocksForDay(day2, daySessions, resolveRepo) {
17089
17172
  ensureEntriesForDay(day2, daySessions);
17090
- const entries2 = listEntriesForDay(day2);
17173
+ const sessionIds = new Set(daySessions.map((s) => s.id));
17174
+ const entries2 = listEntriesForDay(day2).filter((e) => sessionIds.has(e.session_id));
17091
17175
  if (entries2.length === 0) return void 0;
17092
17176
  const rich = buildRichRollupBlocks(day2, daySessions, entries2, resolveRepo);
17093
17177
  const enriched = buildEnrichedExtras(entries2);
@@ -17098,7 +17182,7 @@ function buildIngestPayload(inputs) {
17098
17182
  return {
17099
17183
  ingestId: randomUUID2(),
17100
17184
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
17101
- cliVersion: "0.14.0",
17185
+ cliVersion: "0.15.1",
17102
17186
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
17103
17187
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
17104
17188
  ...richRollup ? { richRollup } : {},
@@ -17762,8 +17846,8 @@ async function dispatchCommand(command2, config, log) {
17762
17846
  }
17763
17847
  }
17764
17848
  async function runActivityBackfill(command2, config, log) {
17765
- const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
17766
- const { toLocalDay: toLocalDay4 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
17849
+ const { listSessions: listSessions2, shouldSyncProject: shouldSyncProject2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
17850
+ const { toLocalDay: toLocalDay4, projectRepoName: projectRepoName2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
17767
17851
  const { probeArtifactSignals: probeArtifactSignals2 } = await Promise.resolve().then(() => (init_file_probe(), file_probe_exports));
17768
17852
  const days = command2.params.days;
17769
17853
  const todayMs = Date.now();
@@ -17772,7 +17856,7 @@ async function runActivityBackfill(command2, config, log) {
17772
17856
  log("info", `command ${command2.id}: backfill-activity from ${targetDay} (${days} days)`);
17773
17857
  let sessions;
17774
17858
  try {
17775
- sessions = await listSessions2({ limit: 1e4 });
17859
+ sessions = filterSyncedSessions(await listSessions2({ limit: 1e4 }), config.syncProjects);
17776
17860
  } catch (err) {
17777
17861
  return {
17778
17862
  id: command2.id,
@@ -17797,7 +17881,8 @@ async function runActivityBackfill(command2, config, log) {
17797
17881
  const richBlocks = buildRichBlocksForDay(rollup.day, daySessions, resolveRepo);
17798
17882
  let artifactSignals = null;
17799
17883
  try {
17800
- artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: [process.cwd()] });
17884
+ const cwdAllowed = shouldSyncProject2(projectRepoName2(process.cwd()), config.syncProjects);
17885
+ artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: cwdAllowed ? [process.cwd()] : [] });
17801
17886
  } catch {
17802
17887
  }
17803
17888
  const payload = buildIngestPayload({
@@ -17902,6 +17987,26 @@ function buildSyncLine(status2, trigger, s, elapsedMs, nextSyncMs) {
17902
17987
  async function runTeamSync(log = noopLog2, configOverride, options = {}) {
17903
17988
  const config = configOverride === void 0 ? readTeamConfig() : configOverride;
17904
17989
  if (!config) return { paired: false, pushed: 0, queued: 0, queuedDrained: 0 };
17990
+ if (config.setupPending) {
17991
+ log(
17992
+ "info",
17993
+ buildSyncLine(
17994
+ "idle",
17995
+ options.trigger ?? "auto",
17996
+ {
17997
+ pushedDays: [],
17998
+ droppedDays: [],
17999
+ queued: 0,
18000
+ queuedDrained: 0,
18001
+ usageSnapshots: 0,
18002
+ idleReason: "setup pending \u2014 finish onboarding in the dashboard (/team/onboarding)"
18003
+ },
18004
+ 0,
18005
+ options.nextSyncMs
18006
+ )
18007
+ );
18008
+ return { paired: true, pushed: 0, queued: 0, queuedDrained: 0, setupPending: true };
18009
+ }
17905
18010
  const startedAt = Date.now();
17906
18011
  const trigger = options.trigger ?? "auto";
17907
18012
  const summary = {
@@ -17923,15 +18028,19 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
17923
18028
  summary.skipped = { ...summary.skipped, ...body.blocks.skipped };
17924
18029
  }
17925
18030
  };
18031
+ const emit = options.onProgress ?? (() => {
18032
+ });
17926
18033
  try {
17927
18034
  resetEnsuredSessions();
17928
18035
  const { listSessions: listSessions2, loadCalibrationCurve: loadCalibrationCurve2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
17929
- const { toLocalDay: toLocalDay4 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
18036
+ const { toLocalDay: toLocalDay4, projectRepoName: projectRepoName2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
17930
18037
  const today = toLocalDay4(Date.now());
17931
- let nextConfig = { ...config };
18038
+ let patches = {};
17932
18039
  const persistConfig = (patch) => {
17933
- nextConfig = { ...nextConfig, ...patch };
17934
- writeTeamConfig(nextConfig);
18040
+ patches = { ...patches, ...patch };
18041
+ const onDisk = readTeamConfig();
18042
+ if (!onDisk) return;
18043
+ writeTeamConfig({ ...onDisk, ...patches });
17935
18044
  };
17936
18045
  const pendingLog = readPendingSyncLog(config.lastSyncedLogAt);
17937
18046
  const collectedCommands = /* @__PURE__ */ new Map();
@@ -17976,7 +18085,12 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
17976
18085
  let drained = 0;
17977
18086
  const backlog = dequeuePayloads();
17978
18087
  for (let i = 0; i < backlog.length; i++) {
17979
- const qResult = await pushToTeamServer(config, backlog[i]);
18088
+ const queuedPayload = backlog[i];
18089
+ if (queuedPayload.richRollup?.projects?.some((p) => !shouldSyncProject(p.project, config.syncProjects))) {
18090
+ log("info", "team push: dropped queued payload containing now-excluded project(s)");
18091
+ continue;
18092
+ }
18093
+ const qResult = await pushToTeamServer(config, queuedPayload);
17980
18094
  if (!qResult.ok) {
17981
18095
  if (isValidationPoison(qResult.status)) {
17982
18096
  log("warn", `team push: queued payload rejected (HTTP ${qResult.status}); dropping unrecoverable item`);
@@ -17990,15 +18104,41 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
17990
18104
  }
17991
18105
  return drained;
17992
18106
  };
18107
+ emit({ type: "phase", phase: "usage-backfill" });
17993
18108
  const usageBackfill = await runTeamBackfill(log, USAGE_LOG4, config, {
17994
18109
  sinceCapturedAt: options.forceUsageBackfill ? void 0 : config.lastSyncedUsageSnapshotAt
17995
18110
  });
18111
+ emit({
18112
+ type: "usage",
18113
+ inserted: usageBackfill.insertedSnapshots ?? 0,
18114
+ alreadyKnown: usageBackfill.skippedSnapshots ?? 0
18115
+ });
17996
18116
  if (usageBackfill.lastSnapshotAt) {
17997
18117
  persistConfig({ lastSyncedUsageSnapshotAt: usageBackfill.lastSnapshotAt });
17998
18118
  }
17999
- const sessions = await listSessions2({ limit: 1e4 });
18119
+ const unfilteredSessions = await listSessions2({ limit: 1e4 });
18120
+ const sessions = filterSyncedSessions(unfilteredSessions, config.syncProjects);
18000
18121
  const allRollups = buildRollupsForRange(sessions);
18001
- const rollups = allRollups.filter((r) => !config.lastSyncedDay || r.day >= config.lastSyncedDay);
18122
+ const inWindow = (day2) => !config.lastSyncedDay || day2 >= config.lastSyncedDay;
18123
+ const rollups = allRollups.filter((r) => inWindow(r.day));
18124
+ if (config.syncProjects) {
18125
+ const filteredDays = new Set(allRollups.map((r) => r.day));
18126
+ for (const r of buildRollupsForRange(unfilteredSessions)) {
18127
+ if (!filteredDays.has(r.day) && inWindow(r.day)) {
18128
+ rollups.push({
18129
+ day: r.day,
18130
+ agentTimeMs: 0,
18131
+ sessions: 0,
18132
+ uniqueSessions: 0,
18133
+ toolCalls: 0,
18134
+ turns: 0,
18135
+ tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }
18136
+ });
18137
+ }
18138
+ }
18139
+ rollups.sort((a, b) => a.day < b.day ? -1 : 1);
18140
+ }
18141
+ emit({ type: "phase", phase: "activity", totalDays: rollups.length });
18002
18142
  const usageSnapshot = readLatestUsageSnapshotForWire(USAGE_LOG4) ?? void 0;
18003
18143
  const planTier = await getPlanTier(PROFILE_CACHE2).catch(() => null) ?? void 0;
18004
18144
  const cyclePeaks = await buildCyclePeaksForPush(planTier, loadCalibrationCurve2);
@@ -18012,6 +18152,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18012
18152
  summary.idleReason = "nothing to sync";
18013
18153
  finish("idle");
18014
18154
  }
18155
+ emit({ type: "done", pushed: 0, queued: 0, pushedDays: summary.pushedDays });
18015
18156
  return { paired: true, pushed: 0, queued: 0, queuedDrained: 0, usageBackfill };
18016
18157
  }
18017
18158
  summary.usageSnapshots = usageBackfill.sentSnapshots;
@@ -18024,6 +18165,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18024
18165
  writeLastPushFailure(payload, errLine2);
18025
18166
  summary.errorMsg = `live-snapshot push HTTP ${result.status} (validation) \u2014 dropped unrecoverable`;
18026
18167
  finish("error");
18168
+ emit({ type: "done", pushed: 0, queued: 0, pushedDays: summary.pushedDays });
18027
18169
  return { paired: true, pushed: 0, queued: 0, queuedDrained: 0, usageBackfill };
18028
18170
  }
18029
18171
  const errLine = `team push failed (${result.status})`;
@@ -18032,6 +18174,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18032
18174
  summary.queued = 1;
18033
18175
  summary.errorMsg = `live-snapshot push HTTP ${result.status} \u2014 queued for retry`;
18034
18176
  finish("failed");
18177
+ emit({ type: "done", pushed: 0, queued: 1, pushedDays: summary.pushedDays });
18035
18178
  return { paired: true, pushed: 0, queued: 1, queuedDrained: 0, usageBackfill };
18036
18179
  }
18037
18180
  writeLastPushSuccess(payload);
@@ -18045,12 +18188,12 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18045
18188
  summary.idleReason = "no new daily activity";
18046
18189
  finish(summary.skipped && Object.keys(summary.skipped).length ? "degraded" : "idle");
18047
18190
  await dispatchAndReport();
18191
+ emit({ type: "done", pushed: 1, queued: 0, pushedDays: summary.pushedDays });
18048
18192
  return { paired: true, pushed: 1, queued: 0, queuedDrained: queuedDrained2, usageBackfill };
18049
18193
  }
18050
18194
  let pushed = 0;
18051
18195
  let queued = 0;
18052
18196
  let failedDay;
18053
- let lastResolvedDay;
18054
18197
  const droppedDaysBefore = config.droppedDays ?? [];
18055
18198
  const workingDropped = [...droppedDaysBefore];
18056
18199
  let syncLogWasDelivered = false;
@@ -18059,15 +18202,32 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18059
18202
  const buildDayPayload = (rollup, opts) => {
18060
18203
  const daySessions = sessions.filter((s) => sessionTouchesDay(s, rollup.day));
18061
18204
  const richBlocks = buildRichBlocksForDay(rollup.day, daySessions, resolveRepo);
18205
+ const tombstone = daySessions.length === 0 && !!config.syncProjects;
18206
+ const emptyRich = tombstone ? {
18207
+ projects: [],
18208
+ workingShapes: [],
18209
+ concurrencyPeak: 0,
18210
+ parallelMinutes: 0,
18211
+ longAutonomous: { count: 0, totalMin: 0, maxSingleMin: 0 },
18212
+ toolErrors: 0,
18213
+ skillsLoaded: [],
18214
+ subagentsDispatched: [],
18215
+ brainstormWarmupSessions: 0,
18216
+ planModeUsed: 0,
18217
+ prs: 0,
18218
+ commits: 0,
18219
+ pushes: 0
18220
+ } : void 0;
18062
18221
  let artifactSignals = null;
18063
18222
  try {
18064
- artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: [process.cwd()] });
18223
+ const cwdAllowed = shouldSyncProject(projectRepoName2(process.cwd()), config.syncProjects);
18224
+ artifactSignals = probeArtifactSignals2({ day: rollup.day, extraRoots: cwdAllowed ? [process.cwd()] : [] });
18065
18225
  } catch {
18066
18226
  }
18067
18227
  return buildIngestPayload({
18068
18228
  rollup,
18069
- richExtras: richBlocks?.rich,
18070
- enrichedExtras: richBlocks?.enriched,
18229
+ richExtras: richBlocks?.rich ?? emptyRich,
18230
+ enrichedExtras: richBlocks?.enriched ?? (tombstone ? { outcomeMix: {}, helpfulnessMix: {}, goalMix: {} } : void 0),
18071
18231
  artifactSignals: artifactSignals ?? void 0,
18072
18232
  // Current-cycle data only on the latest day so older days aren't tagged
18073
18233
  // with today's snapshot / peaks.
@@ -18077,9 +18237,10 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18077
18237
  syncLog: opts.syncLog
18078
18238
  });
18079
18239
  };
18080
- for (let i = 0; i < rollups.length; i++) {
18081
- const rollup = rollups[i];
18082
- const isLatest = i === rollups.length - 1;
18240
+ const rollupsDesc = [...rollups].reverse();
18241
+ for (let i = 0; i < rollupsDesc.length; i++) {
18242
+ const rollup = rollupsDesc[i];
18243
+ const isLatest = i === 0;
18083
18244
  const payload = buildDayPayload(rollup, {
18084
18245
  latest: isLatest,
18085
18246
  syncLog: i === 0 ? pendingLog.lines : void 0
@@ -18091,7 +18252,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18091
18252
  writeLastPushFailure(payload, errLine2);
18092
18253
  summary.droppedDays.push(rollup.day);
18093
18254
  if (!workingDropped.includes(rollup.day)) workingDropped.push(rollup.day);
18094
- lastResolvedDay = rollup.day;
18255
+ emit({ type: "day", day: rollup.day, index: i + 1, total: rollupsDesc.length, outcome: "dropped" });
18095
18256
  continue;
18096
18257
  }
18097
18258
  const errLine = `team push failed on ${rollup.day} (${result.status})`;
@@ -18101,6 +18262,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18101
18262
  summary.queuedDay = rollup.day;
18102
18263
  summary.queuedStatus = result.status;
18103
18264
  failedDay = rollup.day;
18265
+ emit({ type: "day", day: rollup.day, index: i + 1, total: rollupsDesc.length, outcome: "queued" });
18104
18266
  break;
18105
18267
  }
18106
18268
  writeLastPushSuccess(payload);
@@ -18109,11 +18271,24 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18109
18271
  if (i === 0) syncLogWasDelivered = syncLogDelivered(result.body);
18110
18272
  pushed++;
18111
18273
  summary.pushedDays.push(rollup.day);
18112
- lastResolvedDay = rollup.day;
18274
+ emit({ type: "day", day: rollup.day, index: i + 1, total: rollupsDesc.length, outcome: "pushed" });
18113
18275
  }
18114
18276
  if (!failedDay) {
18115
18277
  const retryDay = [...droppedDaysBefore].sort().find((d) => !summary.droppedDays.includes(d));
18116
- const retryRollup = retryDay ? allRollups.find((r) => r.day === retryDay) : void 0;
18278
+ if (retryDay && summary.pushedDays.includes(retryDay)) {
18279
+ const idx = workingDropped.indexOf(retryDay);
18280
+ if (idx >= 0) workingDropped.splice(idx, 1);
18281
+ summary.recoveredDays = [retryDay];
18282
+ }
18283
+ const retryRollup = retryDay && !summary.pushedDays.includes(retryDay) ? allRollups.find((r) => r.day === retryDay) ?? (config.syncProjects ? {
18284
+ day: retryDay,
18285
+ agentTimeMs: 0,
18286
+ sessions: 0,
18287
+ uniqueSessions: 0,
18288
+ toolCalls: 0,
18289
+ turns: 0,
18290
+ tokens: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }
18291
+ } : void 0) : void 0;
18117
18292
  if (retryDay && retryRollup) {
18118
18293
  const payload = buildDayPayload(retryRollup, { latest: false });
18119
18294
  const result = await pushToTeamServer(config, payload);
@@ -18134,9 +18309,7 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18134
18309
  const droppedChanged = nextDropped.length !== prevDropped.length || nextDropped.some((d, i) => d !== prevDropped[i]);
18135
18310
  const droppedPatch = droppedChanged ? { droppedDays: nextDropped } : {};
18136
18311
  if (failedDay) {
18137
- if (lastResolvedDay || droppedChanged) {
18138
- persistConfig({ ...lastResolvedDay ? { lastSyncedDay: lastResolvedDay } : {}, ...droppedPatch });
18139
- }
18312
+ if (droppedChanged) persistConfig(droppedPatch);
18140
18313
  } else {
18141
18314
  persistConfig({ lastSyncedDay: today, ...droppedPatch });
18142
18315
  }
@@ -18153,10 +18326,12 @@ async function runTeamSync(log = noopLog2, configOverride, options = {}) {
18153
18326
  else status2 = "ok";
18154
18327
  finish(status2);
18155
18328
  await dispatchAndReport();
18329
+ emit({ type: "done", pushed, queued, pushedDays: summary.pushedDays });
18156
18330
  return { paired: true, pushed, queued, queuedDrained, usageBackfill, failedDay };
18157
18331
  } catch (err) {
18158
18332
  const message = err.message;
18159
18333
  summary.errorMsg = `sync aborted: ${message}`;
18334
+ emit({ type: "error", message });
18160
18335
  finish("error");
18161
18336
  writeLastPushFailure(
18162
18337
  { ingestId: "n/a", observedAt: (/* @__PURE__ */ new Date()).toISOString() },
@@ -18279,12 +18454,20 @@ var init_daemon_log = __esm({
18279
18454
  // src/team/join.ts
18280
18455
  var join_exports = {};
18281
18456
  __export(join_exports, {
18457
+ carryOverSyncProjects: () => carryOverSyncProjects,
18282
18458
  joinTeam: () => joinTeam
18283
18459
  });
18460
+ function carryOverSyncProjects(existing, serverUrl, teamSlug) {
18461
+ if (existing && existing.serverUrl === serverUrl && existing.teamSlug === teamSlug) {
18462
+ return existing.syncProjects;
18463
+ }
18464
+ return void 0;
18465
+ }
18284
18466
  async function joinTeam(args2) {
18285
- const [serverUrl, bearerToken] = args2;
18467
+ const noBrowser = args2.includes("--no-browser");
18468
+ const [serverUrl, bearerToken] = args2.filter((a) => !a.startsWith("--"));
18286
18469
  if (!serverUrl || !bearerToken) {
18287
- console.error("Usage: fleetlens team join <server-url> <device-token>");
18470
+ console.error("Usage: fleetlens team join <server-url> <device-token> [--no-browser]");
18288
18471
  console.error("");
18289
18472
  console.error("Get the device token from the dashboard after signup,");
18290
18473
  console.error("or from Settings \u2192 My device token.");
@@ -18300,6 +18483,7 @@ async function joinTeam(args2) {
18300
18483
  process.exit(1);
18301
18484
  }
18302
18485
  const data = await res.json();
18486
+ const existing = readTeamConfig();
18303
18487
  const config = {
18304
18488
  serverUrl,
18305
18489
  memberId: data.membership.id,
@@ -18311,36 +18495,70 @@ async function joinTeam(args2) {
18311
18495
  // doesn't sweep the prior team's [sync] lines onto this team's log. The
18312
18496
  // pair run's own [sync] line is written after this instant, so it still
18313
18497
  // uploads on the next sync.
18314
- lastSyncedLogAt: (/* @__PURE__ */ new Date()).toISOString()
18498
+ lastSyncedLogAt: (/* @__PURE__ */ new Date()).toISOString(),
18499
+ syncProjects: carryOverSyncProjects(existing, serverUrl, data.team.slug),
18500
+ // Browser path: gate the daemon until the wizard's "Start syncing".
18501
+ ...noBrowser ? {} : { setupPending: true }
18315
18502
  };
18316
18503
  writeTeamConfig(config);
18317
18504
  console.log(`Paired with "${data.team.name}" as ${data.user.displayName || data.user.email}`);
18318
18505
  console.log(` role: ${data.membership.role}`);
18319
- console.log(" Syncing local history\u2026");
18320
- const sync = await runTeamSync(logToDaemonLog, config, {
18321
- forceUsageBackfill: true,
18322
- trigger: "pair"
18323
- });
18324
- const backfill = sync.usageBackfill;
18325
- if (backfill?.error) {
18326
- console.log(` \u26A0 Usage history sync failed: ${backfill.error} \u2014 daemon will retry automatically.`);
18327
- } else if ((backfill?.insertedSnapshots ?? 0) > 0) {
18328
- console.log(
18329
- ` \u2713 Synced ${backfill.insertedSnapshots} usage snapshot${backfill.insertedSnapshots === 1 ? "" : "s"} from local history.`
18330
- );
18331
- } else if ((backfill?.sentSnapshots ?? 0) > 0) {
18332
- console.log(` \u2713 ${backfill.sentSnapshots} usage snapshots already on server (deduped on capture time).`);
18333
- } else {
18334
- console.log(" \xB7 No local usage snapshots yet \u2014 daemon will start collecting.");
18506
+ if (noBrowser) {
18507
+ console.log(" Syncing local history\u2026");
18508
+ const sync = await runTeamSync(logToDaemonLog, config, {
18509
+ forceUsageBackfill: true,
18510
+ trigger: "pair"
18511
+ });
18512
+ const backfill = sync.usageBackfill;
18513
+ if (backfill?.error) {
18514
+ console.log(` \u26A0 Usage history sync failed: ${backfill.error} \u2014 daemon will retry automatically.`);
18515
+ } else if ((backfill?.insertedSnapshots ?? 0) > 0) {
18516
+ console.log(
18517
+ ` \u2713 Synced ${backfill.insertedSnapshots} usage snapshot${backfill.insertedSnapshots === 1 ? "" : "s"} from local history.`
18518
+ );
18519
+ } else if ((backfill?.sentSnapshots ?? 0) > 0) {
18520
+ console.log(` \u2713 ${backfill.sentSnapshots} usage snapshots already on server (deduped on capture time).`);
18521
+ } else {
18522
+ console.log(" \xB7 No local usage snapshots yet \u2014 daemon will start collecting.");
18523
+ }
18524
+ if (sync.error) {
18525
+ console.log(` \u26A0 Team sync failed: ${sync.error} \u2014 will retry on next daemon cycle.`);
18526
+ } else if (sync.pushed > 0) {
18527
+ console.log(` \u2713 Synced ${sync.pushed} activity payload${sync.pushed === 1 ? "" : "s"}.`);
18528
+ } else {
18529
+ console.log(" \xB7 No new session activity to push.");
18530
+ }
18531
+ console.log(" Daemon polls every 5 minutes \u2014 next push happens automatically.");
18532
+ const { ensureTeamAutostart: ensureNoBrowser } = await Promise.resolve().then(() => (init_autostart(), autostart_exports));
18533
+ await ensureNoBrowser();
18534
+ return;
18335
18535
  }
18336
- if (sync.error) {
18337
- console.log(` \u26A0 Team sync failed: ${sync.error} \u2014 will retry on next daemon cycle.`);
18338
- } else if (sync.pushed > 0) {
18339
- console.log(` \u2713 Synced ${sync.pushed} activity payload${sync.pushed === 1 ? "" : "s"}.`);
18340
- } else {
18341
- console.log(" \xB7 No new session activity to push.");
18536
+ try {
18537
+ const { fetchUsage: fetchUsage2 } = await Promise.resolve().then(() => (init_api(), api_exports));
18538
+ const { appendSnapshot: appendSnapshot2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
18539
+ const { cclensPath: cclensPath2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
18540
+ appendSnapshot2(cclensPath2("usage.jsonl"), await fetchUsage2());
18541
+ } catch {
18542
+ }
18543
+ const { ensureTeamAutostart: ensureTeamAutostart2 } = await Promise.resolve().then(() => (init_autostart(), autostart_exports));
18544
+ await ensureTeamAutostart2();
18545
+ console.log(" Opening your browser to finish setup\u2026");
18546
+ let url;
18547
+ try {
18548
+ const server = await ensureCurrentServer({});
18549
+ url = `http://localhost:${server.port}/team/onboarding`;
18550
+ const daemon2 = startDaemonSilent();
18551
+ if (!daemon2.started && !daemon2.alreadyRunning) {
18552
+ console.warn(` \u26A0 Daemon failed to start \u2014 ${daemon2.error}`);
18553
+ }
18554
+ } catch (err) {
18555
+ console.error(` \u26A0 Could not start the dashboard: ${err.message}`);
18556
+ console.error(" Re-run 'fleetlens team join' after fixing it, or use --no-browser to sync everything from the terminal.");
18557
+ process.exit(1);
18342
18558
  }
18343
- console.log(" Daemon polls every 5 minutes \u2014 next push happens automatically.");
18559
+ openBrowser(url);
18560
+ console.log(` Continue in your browser: ${url}`);
18561
+ console.log(" Nothing syncs until you finish setup there.");
18344
18562
  }
18345
18563
  var logToDaemonLog;
18346
18564
  var init_join = __esm({
@@ -18349,6 +18567,8 @@ var init_join = __esm({
18349
18567
  init_config();
18350
18568
  init_sync();
18351
18569
  init_daemon_log();
18570
+ init_server();
18571
+ init_daemon();
18352
18572
  logToDaemonLog = appendDaemonLogLine;
18353
18573
  }
18354
18574
  });
@@ -18481,28 +18701,42 @@ async function team(args2) {
18481
18701
  break;
18482
18702
  }
18483
18703
  case "sync": {
18704
+ const progressJson = args2.includes("--progress-json");
18484
18705
  const { runTeamSync: runTeamSync2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
18485
18706
  const { appendDaemonLogLine: appendDaemonLogLine2 } = await Promise.resolve().then(() => (init_daemon_log(), daemon_log_exports));
18486
18707
  const outcome = await runTeamSync2(
18487
18708
  (level, msg) => {
18488
- console.log(`[${level}] ${msg}`);
18709
+ if (!progressJson) console.log(`[${level}] ${msg}`);
18489
18710
  appendDaemonLogLine2(level, msg);
18490
18711
  },
18491
18712
  void 0,
18492
- { trigger: "manual" }
18713
+ {
18714
+ trigger: "manual",
18715
+ onProgress: progressJson ? (ev) => console.log(JSON.stringify(ev)) : void 0
18716
+ }
18493
18717
  );
18494
18718
  if (!outcome.paired) {
18495
18719
  console.error("Not paired. Run 'fleetlens team join <url> <device-token>' first.");
18496
18720
  process.exit(1);
18497
18721
  }
18722
+ if (outcome.setupPending) {
18723
+ if (progressJson) {
18724
+ console.log(JSON.stringify({ type: "error", message: "setup pending \u2014 selection not saved yet" }));
18725
+ } else {
18726
+ console.error("Setup pending \u2014 nothing synced. Finish onboarding in the dashboard (/team/onboarding) or re-run 'fleetlens team join'.");
18727
+ }
18728
+ process.exit(1);
18729
+ }
18498
18730
  const inserted = outcome.usageBackfill?.insertedSnapshots ?? 0;
18499
18731
  const madeProgress = outcome.pushed > 0 || outcome.queuedDrained > 0 || inserted > 0;
18500
18732
  if (outcome.error || outcome.usageBackfill?.error && !madeProgress) process.exit(1);
18501
- const sent = outcome.usageBackfill?.sentSnapshots ?? 0;
18502
- const usageChecked = sent > 0 ? `, ${sent} usage snapshot${sent === 1 ? "" : "s"} checked` : "";
18503
- console.log(
18504
- `\u2713 ${outcome.pushed} activity payload${outcome.pushed === 1 ? "" : "s"} pushed` + usageChecked + (outcome.queuedDrained ? `, ${outcome.queuedDrained} queued retried` : "") + (outcome.queued ? `, ${outcome.queued} queued for retry (will fire next cycle)` : "")
18505
- );
18733
+ if (!progressJson) {
18734
+ const sent = outcome.usageBackfill?.sentSnapshots ?? 0;
18735
+ const usageChecked = sent > 0 ? `, ${sent} usage snapshot${sent === 1 ? "" : "s"} checked` : "";
18736
+ console.log(
18737
+ `\u2713 ${outcome.pushed} activity payload${outcome.pushed === 1 ? "" : "s"} pushed` + usageChecked + (outcome.queuedDrained ? `, ${outcome.queuedDrained} queued retried` : "") + (outcome.queued ? `, ${outcome.queued} queued for retry (will fire next cycle)` : "")
18738
+ );
18739
+ }
18506
18740
  break;
18507
18741
  }
18508
18742
  case "backfill": {
@@ -18526,7 +18760,7 @@ async function team(args2) {
18526
18760
  default:
18527
18761
  console.log(`Usage: fleetlens team <join|status|leave|logs|sync|backfill>
18528
18762
 
18529
- join <url> <device-token> Pair daemon with a team server (auto-backfills usage history)
18763
+ join <url> <device-token> [--no-browser] Pair with a team server (opens browser setup; --no-browser syncs everything immediately)
18530
18764
  status Show team pairing state and sync info
18531
18765
  leave Unpair from the team server
18532
18766
  logs Show recent team-related daemon log entries
@@ -18968,7 +19202,7 @@ async function main() {
18968
19202
  case "version":
18969
19203
  case "--version":
18970
19204
  case "-v":
18971
- console.log(`fleetlens ${"0.14.0"}`);
19205
+ console.log(`fleetlens ${"0.15.1"}`);
18972
19206
  break;
18973
19207
  case "help":
18974
19208
  case "--help":
@@ -18997,7 +19231,7 @@ Advanced:
18997
19231
  autostart <install|uninstall|status> Run the usage daemon at login (macOS launchd)
18998
19232
 
18999
19233
  Team:
19000
- team join <url> <token> Pair with a team server
19234
+ team join <url> <token> Pair with a team server (browser setup)
19001
19235
  team status Show team pairing state
19002
19236
  team leave Unpair from team server
19003
19237
  team logs Show team-related daemon logs