@phnx-labs/agents-cli 1.22.39 → 1.22.41

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 (569) hide show
  1. package/CHANGELOG.md +316 -0
  2. package/README.md +116 -70
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +45 -27
  5. package/dist/browser.js +2 -2
  6. package/dist/cli/command-registry.d.ts +135 -0
  7. package/dist/cli/command-registry.js +259 -0
  8. package/dist/commands/accounts.d.ts +20 -0
  9. package/dist/commands/accounts.js +186 -25
  10. package/dist/commands/apply.d.ts +3 -3
  11. package/dist/commands/apply.js +20 -63
  12. package/dist/commands/browser.d.ts +15 -0
  13. package/dist/commands/browser.js +318 -131
  14. package/dist/commands/budget.d.ts +7 -6
  15. package/dist/commands/budget.js +8 -7
  16. package/dist/commands/cloud.js +17 -20
  17. package/dist/commands/commands.js +1 -1
  18. package/dist/commands/computer-actions.d.ts +1 -35
  19. package/dist/commands/computer-actions.js +13 -181
  20. package/dist/commands/computer.d.ts +28 -3
  21. package/dist/commands/computer.js +93 -65
  22. package/dist/commands/config.js +16 -3
  23. package/dist/commands/cost.d.ts +2 -1
  24. package/dist/commands/cost.js +7 -6
  25. package/dist/commands/daemon.js +151 -4
  26. package/dist/commands/detach.js +1 -1
  27. package/dist/commands/doctor.js +19 -11
  28. package/dist/commands/events.js +1 -1
  29. package/dist/commands/exec.d.ts +2 -50
  30. package/dist/commands/exec.js +160 -215
  31. package/dist/commands/factory.js +1 -1
  32. package/dist/commands/feed.d.ts +2 -2
  33. package/dist/commands/feed.js +12 -23
  34. package/dist/commands/fleet-capture.js +25 -27
  35. package/dist/commands/focus.d.ts +2 -3
  36. package/dist/commands/focus.js +34 -9
  37. package/dist/commands/go.js +15 -5
  38. package/dist/commands/harness.d.ts +3 -3
  39. package/dist/commands/harness.js +53 -5
  40. package/dist/commands/hooks.js +1 -1
  41. package/dist/commands/import.js +2 -2
  42. package/dist/commands/insights.d.ts +5 -5
  43. package/dist/commands/insights.js +15 -9
  44. package/dist/commands/inspect.d.ts +2 -3
  45. package/dist/commands/inspect.js +4 -16
  46. package/dist/commands/logs.d.ts +2 -2
  47. package/dist/commands/logs.js +9 -9
  48. package/dist/commands/mcp.js +2 -2
  49. package/dist/commands/memory.js +1 -1
  50. package/dist/commands/message.d.ts +1 -1
  51. package/dist/commands/message.js +7 -7
  52. package/dist/commands/mine.d.ts +11 -8
  53. package/dist/commands/mine.js +11 -10
  54. package/dist/commands/models.js +1 -1
  55. package/dist/commands/modes.js +1 -1
  56. package/dist/commands/monitors.js +23 -6
  57. package/dist/commands/output.d.ts +7 -6
  58. package/dist/commands/output.js +11 -10
  59. package/dist/commands/packages.js +4 -4
  60. package/dist/commands/perf.js +1 -1
  61. package/dist/commands/permissions.js +49 -32
  62. package/dist/commands/plugins.d.ts +1 -1
  63. package/dist/commands/plugins.js +3 -3
  64. package/dist/commands/profiles.d.ts +6 -9
  65. package/dist/commands/profiles.js +8 -321
  66. package/dist/commands/projects.d.ts +9 -0
  67. package/dist/commands/projects.js +140 -8
  68. package/dist/commands/prune.js +5 -13
  69. package/dist/commands/refresh-rules.js +1 -1
  70. package/dist/commands/repo.d.ts +5 -7
  71. package/dist/commands/repo.js +34 -18
  72. package/dist/commands/resource-view.js +4 -0
  73. package/dist/commands/resume.d.ts +11 -7
  74. package/dist/commands/resume.js +82 -98
  75. package/dist/commands/route.d.ts +12 -0
  76. package/dist/commands/route.js +261 -0
  77. package/dist/commands/routines.d.ts +2 -3
  78. package/dist/commands/routines.js +120 -145
  79. package/dist/commands/rules.js +1 -1
  80. package/dist/commands/run-account-picker.d.ts +1 -1
  81. package/dist/commands/run-account-picker.js +2 -2
  82. package/dist/commands/run-broadcast.d.ts +21 -0
  83. package/dist/commands/run-broadcast.js +89 -0
  84. package/dist/commands/run-cloud.js +1 -1
  85. package/dist/commands/secrets-vault.d.ts +10 -0
  86. package/dist/commands/{login.js → secrets-vault.js} +34 -14
  87. package/dist/commands/secrets.d.ts +4 -4
  88. package/dist/commands/secrets.js +158 -159
  89. package/dist/commands/sessions-backfill.js +1 -1
  90. package/dist/commands/sessions-browser.d.ts +1 -1
  91. package/dist/commands/sessions-browser.js +9 -5
  92. package/dist/commands/sessions-export.js +2 -2
  93. package/dist/commands/sessions-inject.js +4 -5
  94. package/dist/commands/sessions-migrate.js +16 -27
  95. package/dist/commands/sessions-picker.d.ts +14 -0
  96. package/dist/commands/sessions-picker.js +209 -13
  97. package/dist/commands/sessions-resume.d.ts +7 -3
  98. package/dist/commands/sessions-resume.js +81 -33
  99. package/dist/commands/sessions-share.d.ts +25 -0
  100. package/dist/commands/sessions-share.js +166 -0
  101. package/dist/commands/sessions-stats.js +2 -2
  102. package/dist/commands/sessions.d.ts +75 -68
  103. package/dist/commands/sessions.js +144 -180
  104. package/dist/commands/setup-browser.js +1 -1
  105. package/dist/commands/setup-computer.js +1 -1
  106. package/dist/commands/setup-fleet.js +3 -0
  107. package/dist/commands/setup-mine.d.ts +7 -3
  108. package/dist/commands/setup-mine.js +13 -8
  109. package/dist/commands/setup-preferences.js +2 -2
  110. package/dist/commands/setup-secrets.js +2 -2
  111. package/dist/commands/setup-watchdog.js +2 -2
  112. package/dist/commands/setup.js +7 -2
  113. package/dist/commands/share.d.ts +65 -0
  114. package/dist/commands/share.js +253 -20
  115. package/dist/commands/skills.js +3 -3
  116. package/dist/commands/snapshot.d.ts +2 -2
  117. package/dist/commands/snapshot.js +9 -9
  118. package/dist/commands/ssh.d.ts +1 -1
  119. package/dist/commands/ssh.js +186 -64
  120. package/dist/commands/subagents.js +1 -1
  121. package/dist/commands/sync.js +24 -9
  122. package/dist/commands/teams.d.ts +2 -2
  123. package/dist/commands/teams.js +9 -18
  124. package/dist/commands/tmux.js +5 -1
  125. package/dist/commands/trash.js +1 -1
  126. package/dist/commands/usage.d.ts +1 -1
  127. package/dist/commands/usage.js +2 -2
  128. package/dist/commands/utils.d.ts +4 -14
  129. package/dist/commands/utils.js +6 -27
  130. package/dist/commands/versions.js +2 -2
  131. package/dist/commands/view.d.ts +9 -77
  132. package/dist/commands/view.js +23 -8
  133. package/dist/commands/watchdog.js +1 -1
  134. package/dist/commands/webhook.js +25 -34
  135. package/dist/commands/workflows.js +1 -1
  136. package/dist/index.js +1 -1
  137. package/dist/lib/account-capabilities.d.ts +39 -0
  138. package/dist/lib/account-capabilities.js +59 -0
  139. package/dist/lib/account-catalog.js +1 -1
  140. package/dist/lib/account-registry.d.ts +66 -0
  141. package/dist/lib/account-registry.js +151 -5
  142. package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
  143. package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
  144. package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
  145. package/dist/lib/{usage.js → accounting/usage.js} +11 -11
  146. package/dist/lib/agent-spec/provider.js +1 -1
  147. package/dist/lib/agents.d.ts +72 -4
  148. package/dist/lib/agents.js +231 -199
  149. package/dist/lib/answer-router.d.ts +2 -2
  150. package/dist/lib/ask-classifier.d.ts +1 -1
  151. package/dist/lib/ask-classifier.js +1 -1
  152. package/dist/lib/audit/log.js +1 -1
  153. package/dist/lib/auth-health.d.ts +1 -1
  154. package/dist/lib/auth-health.js +2 -2
  155. package/dist/lib/brand.js +1 -1
  156. package/dist/lib/browser/caller-identity.d.ts +28 -0
  157. package/dist/lib/browser/caller-identity.js +156 -0
  158. package/dist/lib/browser/cdp.js +5 -1
  159. package/dist/lib/browser/chrome.js +12 -1
  160. package/dist/lib/browser/drivers/ssh.d.ts +1 -1
  161. package/dist/lib/browser/drivers/ssh.js +3 -2
  162. package/dist/lib/browser/hygiene.d.ts +10 -2
  163. package/dist/lib/browser/hygiene.js +7 -4
  164. package/dist/lib/browser/ipc.d.ts +22 -2
  165. package/dist/lib/browser/ipc.js +185 -21
  166. package/dist/lib/browser/profiles.d.ts +69 -5
  167. package/dist/lib/browser/profiles.js +135 -13
  168. package/dist/lib/browser/remote-control.d.ts +2 -2
  169. package/dist/lib/browser/remote-control.js +3 -3
  170. package/dist/lib/browser/runtime-state.d.ts +79 -0
  171. package/dist/lib/browser/runtime-state.js +119 -1
  172. package/dist/lib/browser/service.d.ts +137 -2
  173. package/dist/lib/browser/service.js +492 -54
  174. package/dist/lib/browser/sessions-list.d.ts +2 -1
  175. package/dist/lib/browser/sessions-list.js +4 -13
  176. package/dist/lib/browser/types.d.ts +19 -1
  177. package/dist/lib/budget/config.js +1 -1
  178. package/dist/lib/budget/ledger.js +1 -1
  179. package/dist/lib/byok-usage.js +1 -1
  180. package/dist/lib/capabilities.js +3 -15
  181. package/dist/lib/catchup.d.ts +1 -1
  182. package/dist/lib/catchup.js +1 -1
  183. package/dist/lib/cloud/dispatch.js +1 -1
  184. package/dist/lib/cloud/host.d.ts +3 -3
  185. package/dist/lib/cloud/host.js +5 -5
  186. package/dist/lib/cloud/rush.d.ts +9 -21
  187. package/dist/lib/cloud/rush.js +33 -120
  188. package/dist/lib/cloud/types.d.ts +2 -2
  189. package/dist/lib/commands.js +3 -13
  190. package/dist/lib/computer/actions.d.ts +36 -0
  191. package/dist/lib/computer/actions.js +162 -0
  192. package/dist/lib/computer/dispatch.d.ts +2 -2
  193. package/dist/lib/computer/dispatch.js +2 -2
  194. package/dist/lib/computer/sessions-list.d.ts +3 -3
  195. package/dist/lib/computer/sessions-list.js +2 -2
  196. package/dist/lib/config-keys.d.ts +2 -1
  197. package/dist/lib/config-keys.js +8 -4
  198. package/dist/lib/config-machine-keys.d.ts +4 -2
  199. package/dist/lib/config-machine-keys.js +5 -2
  200. package/dist/lib/crabbox/lease.js +9 -1
  201. package/dist/lib/crabbox/runtimes.d.ts +32 -7
  202. package/dist/lib/crabbox/runtimes.js +72 -30
  203. package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
  204. package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
  205. package/dist/lib/daemon-services.d.ts +1 -1
  206. package/dist/lib/daemon-services.js +5 -0
  207. package/dist/lib/daemon-ticks.d.ts +25 -0
  208. package/dist/lib/daemon-ticks.js +31 -1
  209. package/dist/lib/daemon-webhooks.d.ts +104 -0
  210. package/dist/lib/daemon-webhooks.js +215 -0
  211. package/dist/lib/device-config.d.ts +85 -75
  212. package/dist/lib/device-config.js +280 -142
  213. package/dist/lib/devices/config-migration.d.ts +29 -34
  214. package/dist/lib/devices/config-migration.js +209 -130
  215. package/dist/lib/devices/connect.d.ts +2 -2
  216. package/dist/lib/devices/connect.js +2 -2
  217. package/dist/lib/devices/discovery-policy.d.ts +30 -0
  218. package/dist/lib/devices/discovery-policy.js +101 -0
  219. package/dist/lib/devices/fleet-inventory.js +8 -3
  220. package/dist/lib/devices/harness-inventory.d.ts +1 -1
  221. package/dist/lib/devices/harness-inventory.js +12 -3
  222. package/dist/lib/devices/known-hosts.js +1 -1
  223. package/dist/lib/devices/pool.d.ts +10 -5
  224. package/dist/lib/devices/pool.js +5 -7
  225. package/dist/lib/devices/registry.d.ts +1 -1
  226. package/dist/lib/devices/registry.js +1 -1
  227. package/dist/lib/devices/resolve-profile.d.ts +2 -2
  228. package/dist/lib/devices/resolve-profile.js +2 -2
  229. package/dist/lib/devices/resolve-target.d.ts +1 -1
  230. package/dist/lib/devices/resolve-target.js +4 -4
  231. package/dist/lib/devices/self-host.d.ts +1 -1
  232. package/dist/lib/devices/self-host.js +3 -3
  233. package/dist/lib/devices/ssh-config.d.ts +1 -1
  234. package/dist/lib/devices/stats-cache.js +1 -1
  235. package/dist/lib/devices/sync.d.ts +3 -1
  236. package/dist/lib/devices/sync.js +3 -3
  237. package/dist/lib/doctor-diff.js +4 -4
  238. package/dist/lib/drift-sync.js +2 -2
  239. package/dist/lib/drift.js +2 -2
  240. package/dist/lib/event-families.d.ts +1 -1
  241. package/dist/lib/event-stream.d.ts +1 -1
  242. package/dist/lib/event-stream.js +2 -2
  243. package/dist/lib/events-ingest.js +2 -2
  244. package/dist/lib/exec.d.ts +4 -4
  245. package/dist/lib/exec.js +11 -11
  246. package/dist/lib/factory/snapshot.d.ts +1 -1
  247. package/dist/lib/factory/snapshot.js +1 -1
  248. package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
  249. package/dist/lib/{activity.js → feed/activity.js} +7 -7
  250. package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
  251. package/dist/lib/{events.js → feed/events.js} +5 -5
  252. package/dist/lib/{feed.js → feed/feed.js} +4 -4
  253. package/dist/lib/feed-outcome.d.ts +1 -1
  254. package/dist/lib/feed-policy.d.ts +1 -1
  255. package/dist/lib/feed-policy.js +1 -1
  256. package/dist/lib/feed-post.d.ts +1 -1
  257. package/dist/lib/feed-post.js +1 -1
  258. package/dist/lib/feed-ranking.d.ts +1 -1
  259. package/dist/lib/fleet/apply.d.ts +0 -6
  260. package/dist/lib/fleet/apply.js +18 -45
  261. package/dist/lib/fleet/auth-sync.d.ts +16 -35
  262. package/dist/lib/fleet/auth-sync.js +16 -75
  263. package/dist/lib/fleet/capture.js +8 -6
  264. package/dist/lib/fleet/manifest.js +23 -11
  265. package/dist/lib/fleet/types.d.ts +19 -7
  266. package/dist/lib/fleet-cache.d.ts +1 -1
  267. package/dist/lib/fleet-cache.js +1 -1
  268. package/dist/lib/format.d.ts +19 -0
  269. package/dist/lib/format.js +44 -1
  270. package/dist/lib/friction-heuristics.d.ts +1 -1
  271. package/dist/lib/git.d.ts +24 -1
  272. package/dist/lib/git.js +82 -38
  273. package/dist/lib/heal.js +3 -3
  274. package/dist/lib/hooks.d.ts +18 -0
  275. package/dist/lib/hooks.js +113 -1
  276. package/dist/lib/hosts/credentials.d.ts +30 -10
  277. package/dist/lib/hosts/credentials.js +38 -26
  278. package/dist/lib/hosts/dispatch.d.ts +3 -3
  279. package/dist/lib/hosts/dispatch.js +3 -3
  280. package/dist/lib/hosts/option.d.ts +3 -3
  281. package/dist/lib/hosts/option.js +7 -8
  282. package/dist/lib/hosts/passthrough.d.ts +17 -17
  283. package/dist/lib/hosts/passthrough.js +67 -50
  284. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  285. package/dist/lib/hosts/providers/devices.js +1 -1
  286. package/dist/lib/hosts/reconcile.d.ts +1 -1
  287. package/dist/lib/hosts/reconcile.js +1 -1
  288. package/dist/lib/hosts/reconnect.d.ts +1 -1
  289. package/dist/lib/hosts/reconnect.js +2 -2
  290. package/dist/lib/hosts/registry.d.ts +5 -5
  291. package/dist/lib/hosts/registry.js +5 -5
  292. package/dist/lib/hosts/remote-cmd.d.ts +10 -10
  293. package/dist/lib/hosts/remote-cmd.js +25 -18
  294. package/dist/lib/hosts/remote-os.d.ts +4 -4
  295. package/dist/lib/hosts/remote-os.js +4 -4
  296. package/dist/lib/hosts/remote-session-id.d.ts +2 -2
  297. package/dist/lib/hosts/remote-session-id.js +2 -2
  298. package/dist/lib/hosts/routing-flag.d.ts +3 -3
  299. package/dist/lib/hosts/routing-flag.js +4 -5
  300. package/dist/lib/hosts/run-target.d.ts +4 -4
  301. package/dist/lib/hosts/run-target.js +4 -4
  302. package/dist/lib/hosts/session-index.d.ts +2 -2
  303. package/dist/lib/hosts/session-index.js +1 -1
  304. package/dist/lib/hosts/session-marker.d.ts +1 -1
  305. package/dist/lib/hosts/session-marker.js +1 -1
  306. package/dist/lib/hosts/types.d.ts +2 -2
  307. package/dist/lib/hosts/types.js +2 -2
  308. package/dist/lib/import.js +1 -1
  309. package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
  310. package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
  311. package/dist/lib/installations/resolve.js +1 -1
  312. package/dist/lib/installations/strategies.js +1 -1
  313. package/dist/lib/installations/update.js +2 -2
  314. package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
  315. package/dist/lib/{versions.js → installations/versions.js} +51 -31
  316. package/dist/lib/isolation-boundary-report.js +1 -1
  317. package/dist/lib/linear-projects.d.ts +28 -0
  318. package/dist/lib/linear-projects.js +30 -0
  319. package/dist/lib/loop.js +1 -1
  320. package/dist/lib/mailbox-gc.js +1 -1
  321. package/dist/lib/mailbox.js +1 -1
  322. package/dist/lib/mcp-registry.d.ts +62 -0
  323. package/dist/lib/mcp-registry.js +177 -0
  324. package/dist/lib/mcp.d.ts +5 -0
  325. package/dist/lib/mcp.js +124 -307
  326. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  327. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  328. package/dist/lib/menubar/install-menubar.d.ts +7 -0
  329. package/dist/lib/menubar/install-menubar.js +24 -6
  330. package/dist/lib/menubar/snapshot.d.ts +7 -0
  331. package/dist/lib/menubar/snapshot.js +8 -6
  332. package/dist/lib/models.js +1 -1
  333. package/dist/lib/monitors/config.d.ts +12 -0
  334. package/dist/lib/monitors/config.js +3 -0
  335. package/dist/lib/monitors/dispatch.js +26 -5
  336. package/dist/lib/monitors/engine.js +10 -0
  337. package/dist/lib/monitors/sources/webhook.d.ts +1 -1
  338. package/dist/lib/monitors/state.d.ts +42 -0
  339. package/dist/lib/monitors/state.js +30 -0
  340. package/dist/lib/notify.d.ts +1 -1
  341. package/dist/lib/observe-aliases.d.ts +3 -3
  342. package/dist/lib/observe-aliases.js +3 -21
  343. package/dist/lib/output/git-output.js +2 -2
  344. package/dist/lib/overdue.d.ts +1 -1
  345. package/dist/lib/overdue.js +1 -1
  346. package/dist/lib/permissions-registry.d.ts +65 -0
  347. package/dist/lib/permissions-registry.js +599 -0
  348. package/dist/lib/permissions.d.ts +24 -13
  349. package/dist/lib/permissions.js +52 -271
  350. package/dist/lib/picker.d.ts +16 -0
  351. package/dist/lib/picker.js +33 -3
  352. package/dist/lib/placement.d.ts +1 -1
  353. package/dist/lib/placement.js +4 -4
  354. package/dist/lib/platform/paths.d.ts +8 -0
  355. package/dist/lib/platform/paths.js +11 -0
  356. package/dist/lib/platform/posixpath.js +3 -3
  357. package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
  358. package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
  359. package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
  360. package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
  361. package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
  362. package/dist/lib/{skills.js → plugins/skills.js} +7 -7
  363. package/dist/lib/pricing/cost.d.ts +1 -1
  364. package/dist/lib/pricing/cost.js +1 -1
  365. package/dist/lib/profiles-presets.d.ts +1 -1
  366. package/dist/lib/profiles-presets.js +1 -1
  367. package/dist/lib/profiles.js +2 -2
  368. package/dist/lib/project-import.js +4 -1
  369. package/dist/lib/project-key.js +7 -0
  370. package/dist/lib/project-launch.d.ts +1 -1
  371. package/dist/lib/project-launch.js +3 -3
  372. package/dist/lib/project-pull.d.ts +128 -0
  373. package/dist/lib/project-pull.js +384 -0
  374. package/dist/lib/project-root.d.ts +2 -2
  375. package/dist/lib/project-root.js +2 -2
  376. package/dist/lib/project-status.js +1 -1
  377. package/dist/lib/projects.d.ts +23 -0
  378. package/dist/lib/projects.js +29 -6
  379. package/dist/lib/refresh.d.ts +12 -1
  380. package/dist/lib/refresh.js +16 -9
  381. package/dist/lib/registry.d.ts +9 -2
  382. package/dist/lib/registry.js +11 -4
  383. package/dist/lib/resources.d.ts +2 -2
  384. package/dist/lib/resources.js +2 -2
  385. package/dist/lib/routers.d.ts +81 -0
  386. package/dist/lib/routers.js +153 -0
  387. package/dist/lib/routine-context.d.ts +1 -0
  388. package/dist/lib/routine-context.js +7 -2
  389. package/dist/lib/routine-notify-owner.d.ts +1 -1
  390. package/dist/lib/routine-notify.d.ts +1 -1
  391. package/dist/lib/routine-notify.js +1 -1
  392. package/dist/lib/routine-process-cleanup.d.ts +1 -1
  393. package/dist/lib/routine-readiness.d.ts +1 -1
  394. package/dist/lib/routine-readiness.js +11 -4
  395. package/dist/lib/routines-placement.d.ts +12 -2
  396. package/dist/lib/routines-placement.js +20 -3
  397. package/dist/lib/routines-project.d.ts +1 -1
  398. package/dist/lib/routines-project.js +1 -1
  399. package/dist/lib/rules/compile.d.ts +1 -0
  400. package/dist/lib/rules/compile.js +10 -2
  401. package/dist/lib/rules/rules.js +1 -1
  402. package/dist/lib/run-notify.js +1 -1
  403. package/dist/lib/runner.d.ts +80 -2
  404. package/dist/lib/runner.js +261 -67
  405. package/dist/lib/sandbox.d.ts +1 -1
  406. package/dist/lib/scheduler.d.ts +1 -1
  407. package/dist/lib/scheduler.js +1 -1
  408. package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
  409. package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
  410. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  411. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  412. package/dist/lib/secrets/agent.js +2 -2
  413. package/dist/lib/secrets/audit.js +1 -1
  414. package/dist/lib/secrets/bundles.d.ts +4 -4
  415. package/dist/lib/secrets/bundles.js +8 -8
  416. package/dist/lib/secrets/headless.d.ts +16 -0
  417. package/dist/lib/secrets/headless.js +21 -0
  418. package/dist/lib/secrets/index.js +1 -1
  419. package/dist/lib/secrets/list-filter.d.ts +1 -1
  420. package/dist/lib/secrets/list-filter.js +2 -2
  421. package/dist/lib/secrets/push.d.ts +1 -1
  422. package/dist/lib/secrets/push.js +10 -12
  423. package/dist/lib/secrets/remote.d.ts +21 -17
  424. package/dist/lib/secrets/remote.js +39 -23
  425. package/dist/lib/secrets/vault.js +2 -2
  426. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  427. package/dist/lib/self-heal/checks/shims.js +1 -1
  428. package/dist/lib/self-update.d.ts +39 -4
  429. package/dist/lib/self-update.js +78 -25
  430. package/dist/lib/serve/control.d.ts +1 -1
  431. package/dist/lib/serve/control.js +4 -4
  432. package/dist/lib/serve/data.d.ts +1 -1
  433. package/dist/lib/serve/data.js +1 -1
  434. package/dist/lib/serve/stream.js +1 -1
  435. package/dist/lib/service-manifest.d.ts +29 -0
  436. package/dist/lib/service-manifest.js +80 -0
  437. package/dist/lib/session/active.d.ts +59 -7
  438. package/dist/lib/session/active.js +158 -17
  439. package/dist/lib/session/bash-command.js +1 -1
  440. package/dist/lib/session/claude-accounts.d.ts +1 -1
  441. package/dist/lib/session/claude-accounts.js +1 -1
  442. package/dist/lib/session/db.d.ts +10 -2
  443. package/dist/lib/session/db.js +25 -6
  444. package/dist/lib/session/discover.d.ts +77 -0
  445. package/dist/lib/session/discover.js +130 -25
  446. package/dist/lib/session/fork.js +1 -1
  447. package/dist/lib/session/inject.d.ts +1 -1
  448. package/dist/lib/session/insights.d.ts +1 -1
  449. package/dist/lib/session/insights.js +1 -1
  450. package/dist/lib/session/live-metadata.d.ts +15 -0
  451. package/dist/lib/session/live-metadata.js +76 -0
  452. package/dist/lib/session/migrate-targets.d.ts +1 -1
  453. package/dist/lib/session/recovery.d.ts +1 -1
  454. package/dist/lib/session/recovery.js +2 -2
  455. package/dist/lib/session/remote-active.d.ts +10 -1
  456. package/dist/lib/session/remote-active.js +8 -3
  457. package/dist/lib/session/remote-bundle.d.ts +1 -1
  458. package/dist/lib/session/remote-bundle.js +2 -2
  459. package/dist/lib/session/remote-list.d.ts +15 -4
  460. package/dist/lib/session/remote-list.js +40 -3
  461. package/dist/lib/session/remote.d.ts +5 -5
  462. package/dist/lib/session/remote.js +13 -17
  463. package/dist/lib/session/resume-command.d.ts +3 -2
  464. package/dist/lib/session/resume-command.js +4 -3
  465. package/dist/lib/session/resume-owner.d.ts +3 -3
  466. package/dist/lib/session/resume-owner.js +3 -3
  467. package/dist/lib/session/session-cache.d.ts +12 -0
  468. package/dist/lib/session/session-cache.js +2 -0
  469. package/dist/lib/session/share-html.d.ts +55 -0
  470. package/dist/lib/session/share-html.js +319 -0
  471. package/dist/lib/session/shell-programs.js +1 -1
  472. package/dist/lib/session/state.js +5 -5
  473. package/dist/lib/session/team-filter.d.ts +1 -1
  474. package/dist/lib/session/team-filter.js +1 -1
  475. package/dist/lib/session/types.d.ts +3 -3
  476. package/dist/lib/session/width.d.ts +2 -2
  477. package/dist/lib/session/width.js +2 -2
  478. package/dist/lib/settings-manifest.d.ts +2 -0
  479. package/dist/lib/settings-manifest.js +81 -3
  480. package/dist/lib/share/delete.d.ts +21 -0
  481. package/dist/lib/share/delete.js +42 -0
  482. package/dist/lib/share/publish.d.ts +120 -0
  483. package/dist/lib/share/publish.js +243 -18
  484. package/dist/lib/share/worker-template.js +172 -9
  485. package/dist/lib/shims.js +35 -7
  486. package/dist/lib/smart-launch.d.ts +4 -4
  487. package/dist/lib/smart-launch.js +6 -4
  488. package/dist/lib/snapshot.d.ts +4 -4
  489. package/dist/lib/snapshot.js +2 -2
  490. package/dist/lib/ssh-exec.d.ts +1 -1
  491. package/dist/lib/ssh-exec.js +2 -2
  492. package/dist/lib/ssh-tunnel.d.ts +10 -10
  493. package/dist/lib/ssh-tunnel.js +12 -12
  494. package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
  495. package/dist/lib/staleness/checkers/hooks.js +1 -1
  496. package/dist/lib/staleness/detectors/permissions.js +0 -23
  497. package/dist/lib/staleness/detectors/plugins.js +1 -1
  498. package/dist/lib/staleness/fingerprint.js +1 -1
  499. package/dist/lib/staleness/layers.d.ts +1 -1
  500. package/dist/lib/staleness/layers.js +1 -1
  501. package/dist/lib/staleness/writers/mcp.js +3 -1
  502. package/dist/lib/staleness/writers/plugins.js +1 -1
  503. package/dist/lib/staleness/writers/types.d.ts +8 -0
  504. package/dist/lib/startup/command-registry.d.ts +6 -147
  505. package/dist/lib/startup/command-registry.js +40 -303
  506. package/dist/lib/startup/dev-build.d.ts +0 -21
  507. package/dist/lib/startup/dev-build.js +29 -8
  508. package/dist/lib/state.d.ts +19 -1
  509. package/dist/lib/state.js +120 -51
  510. package/dist/lib/subagents.js +1 -1
  511. package/dist/lib/sync-status.js +1 -1
  512. package/dist/lib/sync-umbrella.d.ts +6 -1
  513. package/dist/lib/sync-umbrella.js +9 -4
  514. package/dist/lib/teams/agents.js +2 -2
  515. package/dist/lib/teams/registry.js +1 -1
  516. package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
  517. package/dist/lib/terminal/engine.js +1 -1
  518. package/dist/lib/terminal/index.d.ts +4 -0
  519. package/dist/lib/terminal/index.js +3 -0
  520. package/dist/lib/terminal/inject.d.ts +2 -2
  521. package/dist/lib/terminal/inject.js +2 -2
  522. package/dist/lib/terminal/transport.js +1 -1
  523. package/dist/lib/tmux/index.d.ts +1 -1
  524. package/dist/lib/tmux/index.js +1 -1
  525. package/dist/lib/tmux/session.d.ts +21 -5
  526. package/dist/lib/tmux/session.js +76 -22
  527. package/dist/lib/triggers/handlers.d.ts +38 -3
  528. package/dist/lib/triggers/handlers.js +58 -7
  529. package/dist/lib/triggers/webhook.d.ts +113 -5
  530. package/dist/lib/triggers/webhook.js +223 -44
  531. package/dist/lib/types.d.ts +19 -7
  532. package/dist/lib/usage-fleet.d.ts +1 -1
  533. package/dist/lib/usage-fleet.js +1 -1
  534. package/dist/lib/usage-refresh.d.ts +1 -1
  535. package/dist/lib/usage-refresh.js +3 -3
  536. package/dist/lib/version-duplicates.js +2 -2
  537. package/dist/lib/view-types.d.ts +56 -0
  538. package/dist/lib/view-types.js +1 -0
  539. package/dist/lib/watchdog/rotate.d.ts +2 -2
  540. package/dist/lib/watchdog/rotate.js +3 -3
  541. package/dist/lib/watchdog/runner.d.ts +2 -3
  542. package/dist/lib/watchdog/runner.js +3 -4
  543. package/dist/lib/workflows.js +1 -1
  544. package/dist/lib/wrap.d.ts +33 -0
  545. package/dist/lib/wrap.js +70 -0
  546. package/package.json +2 -1
  547. package/scripts/postinstall.js +2 -2
  548. package/dist/commands/bench.d.ts +0 -2
  549. package/dist/commands/bench.js +0 -101
  550. package/dist/commands/cp.d.ts +0 -84
  551. package/dist/commands/cp.js +0 -231
  552. package/dist/commands/login.d.ts +0 -2
  553. package/dist/lib/resources/commands.d.ts +0 -46
  554. package/dist/lib/resources/commands.js +0 -211
  555. package/dist/lib/resources/hooks.d.ts +0 -16
  556. package/dist/lib/resources/hooks.js +0 -153
  557. package/dist/lib/resources/mcp.d.ts +0 -34
  558. package/dist/lib/resources/mcp.js +0 -250
  559. package/dist/lib/resources/memory.d.ts +0 -15
  560. package/dist/lib/resources/memory.js +0 -46
  561. package/dist/lib/resources/permissions.d.ts +0 -13
  562. package/dist/lib/resources/permissions.js +0 -202
  563. package/dist/lib/resources/rules.d.ts +0 -46
  564. package/dist/lib/resources/rules.js +0 -179
  565. package/dist/lib/resources/skills.d.ts +0 -37
  566. package/dist/lib/resources/skills.js +0 -247
  567. package/dist/lib/resources/subagents.d.ts +0 -46
  568. package/dist/lib/resources/subagents.js +0 -202
  569. /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
@@ -4,7 +4,7 @@ const SHELL_WRAPPERS = new Set(['bash', 'sh', 'zsh', 'dash', 'ksh']);
4
4
  const PROGRAM_WRAPPERS = new Set(['command', 'builtin', 'env', 'nohup', 'sudo']);
5
5
  const MAX_NESTED_DEPTH = 3;
6
6
  const SUDO_OPTIONS_WITH_VALUE = new Set([
7
- '-C', '--close-from', '-D', '--chdir', '-g', '--group', '-h', '--host',
7
+ '-C', '--close-from', '-D', '--chdir', '-g', '--group', '-h', '--device',
8
8
  '-p', '--prompt', '-R', '--chroot', '-r', '--role', '-t', '--type',
9
9
  '-T', '--command-timeout', '-u', '--user',
10
10
  ]);
@@ -208,15 +208,15 @@ const GH_ISSUE_URL_RE = /https:\/\/github\.com\/[^\s"'()<>]+\/issues\/(\d+)/;
208
208
  * Flags of `teams create` / `teams add` that take a value, so the value is not
209
209
  * mistaken for the positional team name. Mirrors their value-taking flags in
210
210
  * `commands/teams.ts` — most are `.option('… <x>')` registrations, but
211
- * `--device`/`--host` come from `addHostOption`, so auditing this list against
212
- * `.option(` alone would wrongly drop them. A flag missing here degrades to "no
211
+ * `--device` comes from `addHostOption`, so auditing this list against
212
+ * `.option(` alone would wrongly drop it. A flag missing here degrades to "no
213
213
  * team detected", never to a wrong one.
214
214
  */
215
215
  const TEAM_VALUE_FLAGS = [
216
216
  '-d', '--description', '--use-worktree', '--devices', '--hosts', '--repo',
217
217
  '-n', '--name', '-m', '--mode', '-e', '--effort', '--model', '--env',
218
218
  '--cwd', '--worktree', '--after', '--task-type', '--cloud', '--branch',
219
- '--device', '--host',
219
+ '--device',
220
220
  ];
221
221
  /**
222
222
  * One flag value: a quoted string or a bare token. `-d "sessions lineage"` is the
@@ -319,11 +319,11 @@ export function detectSpawnedTeam(command) {
319
319
  if (!m)
320
320
  return undefined;
321
321
  const name = m[1];
322
- // A single character is a doc placeholder (`agents teams create t --host <box>`)
322
+ // A single character is a doc placeholder (`agents teams create t --device <box>`)
323
323
  // far more often than a real team, and an English article is prose. Both used to
324
324
  // land in the index as a team name, and now that the name is rendered on the row
325
325
  // a wrong one is worse than none.
326
- // A single character is a doc placeholder (`agents teams create t --host <name>`)
326
+ // A single character is a doc placeholder (`agents teams create t --device <name>`)
327
327
  // far more often than a real team; an all-digits token is a flag value or a list
328
328
  // index that leaked through, never a name someone typed. Both had reached the
329
329
  // index, and now that the name is rendered a wrong one is worse than none.
@@ -69,7 +69,7 @@ export declare function filterTeamSessions(sessions: SessionMeta[], showTeams: b
69
69
  * record backs the origin ({@link TeamOrigin.source} === `'meta'`).
70
70
  *
71
71
  * `source` is newer than the rest of {@link TeamOrigin}, so a row that arrived
72
- * from a pre-`source` peer over the `--host` fan-out carries none. There the
72
+ * from a pre-`source` peer over the `--device` fan-out carries none. There the
73
73
  * meta-only fields settle it: the entrypoint fallback is a bare `{ handle }`, so
74
74
  * any `team` / `mode` / `parentSessionId` / `startedAt` means a real teammate
75
75
  * record produced it — otherwise a genuine teammate from an unupgraded peer
@@ -184,7 +184,7 @@ export function filterTeamSessions(sessions, showTeams) {
184
184
  * record backs the origin ({@link TeamOrigin.source} === `'meta'`).
185
185
  *
186
186
  * `source` is newer than the rest of {@link TeamOrigin}, so a row that arrived
187
- * from a pre-`source` peer over the `--host` fan-out carries none. There the
187
+ * from a pre-`source` peer over the `--device` fan-out carries none. There the
188
188
  * meta-only fields settle it: the entrypoint fallback is a bare `{ handle }`, so
189
189
  * any `team` / `mode` / `parentSessionId` / `startedAt` means a real teammate
190
190
  * record produced it — otherwise a genuine teammate from an unupgraded peer
@@ -173,11 +173,11 @@ export interface SessionMeta {
173
173
  gitBranch?: string;
174
174
  messageCount?: number;
175
175
  tokenCount?: number;
176
- /** Real generated (output) tokens — excludes cache-read/-write context (issue: `agents output`). */
176
+ /** Real generated (output) tokens — excludes cache-read/-write context (issue: `agents insights output`). */
177
177
  outputTokens?: number;
178
178
  /**
179
179
  * Uncached input tokens, cache-read tokens, and cache-write (cache-creation)
180
- * tokens — the burn split `agents output` reports, kept only for harnesses that
180
+ * tokens — the burn split `agents insights output` reports, kept only for harnesses that
181
181
  * record a per-message cache split (Claude/Codex/Gemini/Droid). Undefined for
182
182
  * harnesses that expose no split (RUSH-2287).
183
183
  */
@@ -188,7 +188,7 @@ export interface SessionMeta {
188
188
  costUsd?: number;
189
189
  /**
190
190
  * USD cost priced as if caching were off — cache read/write billed at the full
191
- * input rate. Backs `agents output --pricing no-cache` (RUSH-2287). Undefined
191
+ * input rate. Backs `agents insights output --pricing no-cache` (RUSH-2287). Undefined
192
192
  * when the harness records no cache split (then no-cache == actual by definition).
193
193
  */
194
194
  costUsdNoCache?: number;
@@ -4,7 +4,7 @@
4
4
  * `String.length` is the wrong ruler for a terminal: it over-counts ANSI colour
5
5
  * escapes (chalk output) and under-counts wide glyphs (CJK, emoji) which occupy
6
6
  * two cells. The result is the drifting, wrapping session-table line users see
7
- * under tmux and over `--host` SSH. Every renderer that sizes a session-table
7
+ * under tmux and over `--device` SSH. Every renderer that sizes a session-table
8
8
  * cell measures and truncates through this module so alignment is computed once,
9
9
  * correctly, from the same source of truth.
10
10
  */
@@ -22,7 +22,7 @@ export declare function truncateToWidth(s: string, max: number): string;
22
22
  export declare function padToWidth(s: string, width: number): string;
23
23
  /**
24
24
  * Effective terminal width. Reads `$COLUMNS` first so it survives tmux and
25
- * `--host` SSH (where `process.stdout.columns` is unset or wrong), falls back to
25
+ * `--device` SSH (where `process.stdout.columns` is unset or wrong), falls back to
26
26
  * the TTY's reported width, then to `fallback`. Clamped to a sane band so a
27
27
  * bogus value can't produce a 0-wide or absurdly long table.
28
28
  */
@@ -4,7 +4,7 @@
4
4
  * `String.length` is the wrong ruler for a terminal: it over-counts ANSI colour
5
5
  * escapes (chalk output) and under-counts wide glyphs (CJK, emoji) which occupy
6
6
  * two cells. The result is the drifting, wrapping session-table line users see
7
- * under tmux and over `--host` SSH. Every renderer that sizes a session-table
7
+ * under tmux and over `--device` SSH. Every renderer that sizes a session-table
8
8
  * cell measures and truncates through this module so alignment is computed once,
9
9
  * correctly, from the same source of truth.
10
10
  */
@@ -88,7 +88,7 @@ export function padToWidth(s, width) {
88
88
  }
89
89
  /**
90
90
  * Effective terminal width. Reads `$COLUMNS` first so it survives tmux and
91
- * `--host` SSH (where `process.stdout.columns` is unset or wrong), falls back to
91
+ * `--device` SSH (where `process.stdout.columns` is unset or wrong), falls back to
92
92
  * the TTY's reported width, then to `fallback`. Clamped to a sane band so a
93
93
  * bogus value can't produce a 0-wide or absurdly long table.
94
94
  */
@@ -13,6 +13,8 @@
13
13
  * version home. It never overwrites a value the target already has: scalars
14
14
  * keep the target's value, objects merge recursively, arrays union. That makes
15
15
  * the operation idempotent and safe to run on every `agents add` / `agents use`.
16
+ * (One scoped exception: the 'claude-trust' strategy promotes a stamped-default
17
+ * `hasTrustDialogAccepted: false` to `true` — see the note on that entry.)
16
18
  */
17
19
  import type { AgentId } from './types.js';
18
20
  export interface CarryForwardResult {
@@ -13,16 +13,26 @@
13
13
  * version home. It never overwrites a value the target already has: scalars
14
14
  * keep the target's value, objects merge recursively, arrays union. That makes
15
15
  * the operation idempotent and safe to run on every `agents add` / `agents use`.
16
+ * (One scoped exception: the 'claude-trust' strategy promotes a stamped-default
17
+ * `hasTrustDialogAccepted: false` to `true` — see the note on that entry.)
16
18
  */
17
19
  import * as fs from 'fs';
18
20
  import * as path from 'path';
19
21
  import * as TOML from 'smol-toml';
22
+ import { atomicWriteFileSync } from './fs-atomic.js';
20
23
  import { getBackupsDir } from './state.js';
21
24
  const SETTINGS_MANIFEST = {
22
25
  claude: [
23
26
  { rel: '.claude/settings.json', strategy: 'json-merge' },
24
27
  { rel: '.claude/settings.local.json', strategy: 'copy-if-absent' },
25
28
  { rel: '.claude/keybindings.json', strategy: 'copy-if-absent' },
29
+ // `.claude.json` holds the login (oauthAccount) and per-session stats, so it
30
+ // must never merge wholesale — but it is also where Claude records workspace
31
+ // trust (`projects[<path>].hasTrustDialogAccepted`). Without carrying that,
32
+ // every newly pinned version re-shows the trust dialog once per project
33
+ // (issue #2776). The 'claude-trust' strategy projects ONLY the trust flags
34
+ // out of the source file; credentials and stats stay per-version.
35
+ { rel: '.claude.json', strategy: 'claude-trust' },
26
36
  ],
27
37
  codex: [
28
38
  {
@@ -33,9 +43,10 @@ const SETTINGS_MANIFEST = {
33
43
  // `.codex/auth.json` is deliberately NOT carried forward. Copying it seeded
34
44
  // every new Codex version with the current default's ChatGPT token, so two
35
45
  // installed versions always reported the same account and could never sign
36
- // into separate accounts. Claude omits its credential (`.claude.json`) for
37
- // the same reason a version home holds its own login, keeping accounts
38
- // per-version. A fresh Codex version installs signed-out; run `codex login`
46
+ // into separate accounts. Claude never merges `.claude.json` for the same
47
+ // reason (its 'claude-trust' entry extracts only the trust flags) a
48
+ // version home holds its own login, keeping accounts per-version. A fresh
49
+ // Codex version installs signed-out; run `codex login`
39
50
  // (or `agents run codex --version <v>`) inside it to authenticate.
40
51
  { rel: '.codex/instructions.md', strategy: 'copy-if-absent' },
41
52
  { rel: '.codex/hooks.json', strategy: 'copy-if-absent' },
@@ -70,6 +81,21 @@ export function fillGaps(target, source) {
70
81
  }
71
82
  return out;
72
83
  }
84
+ /**
85
+ * Project paths the source `.claude.json` records an accepted trust dialog for.
86
+ * Only an explicit `true` counts: Claude Code never persists a decline (the
87
+ * dialog exits without writing), so `false` is only ever the stamped default —
88
+ * not a user decision worth propagating. Verified against Claude Code
89
+ * 2.1.219/2.1.220 (decline paths exit via code 1 / code 0 without a config
90
+ * write); if a future Claude Code starts persisting declines, this premise —
91
+ * and the false→true promotion in the 'claude-trust' case — must be revisited.
92
+ */
93
+ function trustedClaudeProjects(source) {
94
+ const projects = isPlainObject(source.projects) ? source.projects : {};
95
+ return Object.entries(projects)
96
+ .filter(([, project]) => isPlainObject(project) && project.hasTrustDialogAccepted === true)
97
+ .map(([projectPath]) => projectPath);
98
+ }
73
99
  function stripStateKeys(obj, stateKeys) {
74
100
  if (!stateKeys?.length)
75
101
  return obj;
@@ -128,6 +154,58 @@ export function carryForwardSettings(agent, fromHome, toHome) {
128
154
  result.applied.push(entry.rel);
129
155
  break;
130
156
  }
157
+ case 'claude-trust': {
158
+ // Projection, not a merge: pull ONLY `projects[<path>].hasTrustDialogAccepted`
159
+ // out of the source `.claude.json`. Everything else in that file
160
+ // (oauthAccount, onboarding state, per-session stats) stays per-version.
161
+ // Trust granted anywhere wins over the target's stamped-default `false`
162
+ // (headless runs create project entries with the flag unset-as-false
163
+ // without ever showing the dialog), but a target entry's other keys
164
+ // are preserved untouched.
165
+ const source = JSON.parse(fs.readFileSync(sourcePath, 'utf-8'));
166
+ const trusted = trustedClaudeProjects(source);
167
+ if (trusted.length === 0)
168
+ break;
169
+ const targetExists = fs.existsSync(targetPath);
170
+ const parsedTarget = targetExists
171
+ ? JSON.parse(fs.readFileSync(targetPath, 'utf-8'))
172
+ : {};
173
+ // A target that isn't an object (or whose `projects` isn't) is not
174
+ // ours to repair — skip rather than clobber it with a rebuilt shape.
175
+ if (!isPlainObject(parsedTarget))
176
+ break;
177
+ const targetObj = parsedTarget;
178
+ if ('projects' in targetObj && !isPlainObject(targetObj.projects))
179
+ break;
180
+ const targetProjects = isPlainObject(targetObj.projects) ? { ...targetObj.projects } : {};
181
+ let changed = false;
182
+ for (const projectPath of trusted) {
183
+ const existing = isPlainObject(targetProjects[projectPath])
184
+ ? targetProjects[projectPath]
185
+ : {};
186
+ if (existing.hasTrustDialogAccepted === true)
187
+ continue;
188
+ targetProjects[projectPath] = { ...existing, hasTrustDialogAccepted: true };
189
+ changed = true;
190
+ }
191
+ if (!changed)
192
+ break;
193
+ if (targetExists) {
194
+ backupFile(backupRoot, toHome, entry.rel);
195
+ result.backupDir = backupRoot;
196
+ }
197
+ else {
198
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
199
+ }
200
+ // Atomic (tmp + rename): a running Claude session rewrites this exact
201
+ // file (it holds the login and session stats), so a plain write risks
202
+ // a reader seeing a partial file. The OUTSIDE `.claude.json` is the
203
+ // real file (the INSIDE `.claude/.claude.json` symlink resolves to it
204
+ // and survives the rename).
205
+ atomicWriteFileSync(targetPath, JSON.stringify({ ...targetObj, projects: targetProjects }, null, 2) + '\n');
206
+ result.applied.push(entry.rel);
207
+ break;
208
+ }
131
209
  case 'json-merge':
132
210
  case 'toml-merge': {
133
211
  const parse = entry.strategy === 'json-merge'
@@ -8,6 +8,12 @@ export type DeleteFn = (url: string, headers: Record<string, string>) => Promise
8
8
  export type CheckFn = (url: string) => Promise<{
9
9
  status: number;
10
10
  }>;
11
+ /** DI seam for tests — override the real HTTP GET of the revisions listing route. */
12
+ export type RevisionsFetchFn = (url: string) => Promise<{
13
+ status: number;
14
+ contentType: string;
15
+ body: string;
16
+ }>;
11
17
  export interface DeleteEndpoint {
12
18
  baseUrl: string;
13
19
  token: string;
@@ -59,6 +65,11 @@ export declare function deleteObject(endpoint: DeleteEndpoint, key: string, opts
59
65
  export interface DeleteShareOptions {
60
66
  /** Skip deleting the sibling `<slug>.png` OG cover (default: delete it too). */
61
67
  keepCover?: boolean;
68
+ /** Skip deleting the target's retained revisions (`<key>/rev-*`, RUSH-2683
69
+ * revision retention) — default: delete them too. A republished-then-deleted
70
+ * share would otherwise leave its prior world-readable versions live for up
71
+ * to the bucket's lifecycle max-age (see docs/share.md §Revisions). */
72
+ keepRevisions?: boolean;
62
73
  /** Treat an already-missing target as a no-op success instead of an error
63
74
  * (mirrors SQL's `DROP ... IF EXISTS`). Default: missing target is an error. */
64
75
  ifExists?: boolean;
@@ -72,6 +83,8 @@ export interface DeleteShareOptions {
72
83
  deleter?: DeleteFn;
73
84
  /** DI seam for tests — override the real HTTP existence check. */
74
85
  checker?: CheckFn;
86
+ /** DI seam for tests — override the real HTTP GET of the revisions listing route. */
87
+ fetchRevisions?: RevisionsFetchFn;
75
88
  }
76
89
  export interface DeleteShareResult {
77
90
  key: string;
@@ -86,6 +99,14 @@ export interface DeleteShareResult {
86
99
  existedBefore: boolean;
87
100
  verified404: boolean;
88
101
  };
102
+ /** Retained revisions of this target that were also deleted (omitted when
103
+ * there were none, or `keepRevisions` was passed). */
104
+ revisions?: Array<{
105
+ key: string;
106
+ url: string;
107
+ existedBefore: boolean;
108
+ verified404: boolean;
109
+ }>;
89
110
  }
90
111
  /** Delete one share target (page + by default its OG cover) and verify both
91
112
  * are gone. Throws on an unverified takedown — never reports success for an
@@ -61,6 +61,33 @@ async function defaultDelete(url, headers) {
61
61
  const res = await fetch(url, { method: 'DELETE', headers });
62
62
  return { ok: res.ok, status: res.status };
63
63
  }
64
+ async function defaultRevisionsFetch(url) {
65
+ const res = await fetch(url, { headers: { accept: 'application/json' } });
66
+ return { status: res.status, contentType: res.headers.get('content-type') ?? '', body: await res.text() };
67
+ }
68
+ /**
69
+ * List the R2 keys of a slug's retained revisions via the Worker's
70
+ * `?revisions=json` route (worker-template.ts `renderRevisions`). Best-effort:
71
+ * any failure to reach or parse the route (an endpoint provisioned before
72
+ * revisions existed, a network blip) yields an empty list rather than
73
+ * throwing — purging revisions is a safety improvement on top of the primary
74
+ * delete contract (take the canonical page down), never a reason to fail it.
75
+ */
76
+ async function listRevisionKeys(endpoint, key, fetchRevisions) {
77
+ try {
78
+ const url = `${endpoint.baseUrl.replace(/\/+$/, '')}/${key}?revisions=json`;
79
+ const res = await fetchRevisions(url);
80
+ if (res.status !== 200 || !/application\/json/i.test(res.contentType))
81
+ return [];
82
+ const data = JSON.parse(res.body);
83
+ if (!Array.isArray(data.revisions))
84
+ return [];
85
+ return data.revisions.map((r) => String(r.key ?? '')).filter(Boolean);
86
+ }
87
+ catch {
88
+ return [];
89
+ }
90
+ }
64
91
  /**
65
92
  * Delete one R2 object behind the share Worker and assert the postcondition.
66
93
  * `{"ok":true}` from the Worker is not evidence a page came down — R2 delete is
@@ -123,5 +150,20 @@ export async function deleteShare(target, opts = {}) {
123
150
  throw new Error(`Cover delete reported success but ${cover.url} still resolves — takedown NOT verified. Retry, or pass --keep-cover and delete it manually.`);
124
151
  }
125
152
  }
153
+ if (!opts.keepRevisions) {
154
+ const revisionKeys = await listRevisionKeys(endpoint, resolved.key, opts.fetchRevisions ?? defaultRevisionsFetch);
155
+ if (revisionKeys.length > 0) {
156
+ const revisions = [];
157
+ for (const revisionKey of revisionKeys) {
158
+ const rev = await deleteObject(endpoint, revisionKey, { deleter: opts.deleter, checker: opts.checker });
159
+ revisions.push({ key: rev.key, url: rev.url, existedBefore: rev.existedBefore, verified404: rev.verified404 });
160
+ }
161
+ result.revisions = revisions;
162
+ const stillUp = revisions.filter((r) => r.existedBefore && !r.verified404);
163
+ if (stillUp.length > 0) {
164
+ throw new Error(`Delete reported success but ${stillUp.length} retained revision(s) still resolve — takedown NOT verified. Retry, or pass --keep-revisions and delete them manually.`);
165
+ }
166
+ }
167
+ }
126
168
  return result;
127
169
  }
@@ -45,6 +45,27 @@ export interface PublishOptions {
45
45
  uploader?: PutFn;
46
46
  /** DI seam for tests — override cover capture (returns a PNG buffer or null). */
47
47
  capturer?: (htmlPath: string) => Promise<Buffer | null>;
48
+ /**
49
+ * Human display title, shown instead of the slug in the gallery and
50
+ * `agents artifacts share list`. When omitted, one is derived (HTML `<title>`,
51
+ * else a Markdown frontmatter `title:`, else the filename) — a share always
52
+ * carries a label, never a blocking prompt (see {@link deriveLabel}).
53
+ */
54
+ label?: string;
55
+ /**
56
+ * Structured metadata (`--meta key=value`, repeatable). Keys are validated by
57
+ * {@link parseMetaEntries} — lowercase `[a-z0-9-]`, and may not collide with
58
+ * {@link RESERVED_META_KEYS}, which the CLI sets automatically.
59
+ */
60
+ meta?: Record<string, string>;
61
+ /**
62
+ * Skip revision retention on this publish — overwrite an existing slug's
63
+ * object in place with no `<slug>/rev-<ts>` backup of the version it replaces
64
+ * (default: keep it; see docs/share.md §Revisions).
65
+ */
66
+ noRevision?: boolean;
67
+ /** DI seam for tests — override provenance auto-capture (agent/session/host/repo/date). */
68
+ provenance?: ShareProvenance;
48
69
  }
49
70
  export interface PublishResult {
50
71
  url: string;
@@ -52,7 +73,87 @@ export interface PublishResult {
52
73
  coverUrl?: string;
53
74
  /** True when the page was published with `visibility=unlisted`. */
54
75
  unlisted?: boolean;
76
+ /** The label stored with this share — explicit (`--label`) or derived. */
77
+ label?: string;
78
+ /** Whether `label` came from `--label` or was auto-derived. */
79
+ labelSource?: 'explicit' | 'derived';
80
+ }
81
+ export interface ShareProvenance {
82
+ /** Harness/agent name (`AGENTS_AGENT_NAME`), when publishing from an agent run. */
83
+ agent?: string;
84
+ /** Session id (`AGENTS_SESSION_ID` / `AGENT_SESSION_ID`), when publishing from an agent run. */
85
+ session?: string;
86
+ /** The machine the publish ran from (`os.hostname()`) — always present. */
87
+ host?: string;
88
+ /** git repo name at publish time, absent outside a git checkout — never invented. */
89
+ repo?: string;
90
+ /** ISO date (`yyyy-mm-dd`) this publish happened, from the local clock. */
91
+ date?: string;
55
92
  }
93
+ /**
94
+ * Reserved `customMetadata` keys the CLI sets automatically from the exec env,
95
+ * git, and the local clock (plus `label`/`label-source`) — a `--meta key=value`
96
+ * may not target any of these (see {@link parseMetaEntries}).
97
+ */
98
+ export declare const RESERVED_META_KEYS: readonly ["agent", "session", "host", "repo", "date", "label", "label-source"];
99
+ /**
100
+ * Auto-capture publish provenance from the exec env, git, and the local clock.
101
+ * Every field is present only when the environment genuinely carries it — a
102
+ * human running the command by hand outside a git repo yields `session`/`agent`/
103
+ * `repo` all undefined, never an invented value. `host` is always present
104
+ * (`os.hostname()` never fails to return something real about where the publish
105
+ * ran, so it isn't "invented" in the same sense).
106
+ */
107
+ export declare function resolveShareProvenance(opts?: {
108
+ env?: NodeJS.ProcessEnv;
109
+ hostname?: string;
110
+ dir?: string;
111
+ now?: Date;
112
+ }): ShareProvenance;
113
+ /**
114
+ * Parse repeated `--meta key=value` CLI args into a validated metadata record.
115
+ * Keys are lowercase `[a-z0-9-]`, up to 64 characters, and may not collide with
116
+ * {@link RESERVED_META_KEYS} (the provenance the CLI sets automatically, plus
117
+ * label/label-source) — throws naming the offending pair on any violation.
118
+ */
119
+ export declare function parseMetaEntries(pairs: string[]): Record<string, string>;
120
+ /** Throws when the combined `customMetadata` payload would exceed {@link MAX_METADATA_BYTES}. */
121
+ export declare function assertMetadataSize(customMetadata: Record<string, string>): void;
122
+ /**
123
+ * Collapse a label to a single line before it goes into the `x-share-label`
124
+ * header or public customMetadata. `<title>[^<]{1,200}</title>` matches
125
+ * newlines (`[^<]` excludes only `<`), and `.trim()` only strips leading/
126
+ * trailing whitespace, not embedded newlines — a multi-line `<title>` (or an
127
+ * explicit `--label`/`--title` the caller typed with a literal newline) was
128
+ * previously passed straight into `Headers.set()` unsanitized, which throws
129
+ * an unhandled `TypeError: Invalid value` and crashes the publish outright.
130
+ */
131
+ export declare function sanitizeLabel(text: string): string;
132
+ /**
133
+ * Make a free-text value safe to put in an HTTP header.
134
+ *
135
+ * `fetch` encodes header values as a **ByteString**, so any code point above 255
136
+ * throws `TypeError: Cannot convert argument to a ByteString` — an unhandled
137
+ * crash with a stack trace, mid-publish, after the body has already been read.
138
+ * Reproduced by publishing a session whose title ended in `…` (U+2026), and
139
+ * reachable by any emoji, curly quote, accented name, or CJK text in a `--label`,
140
+ * a `--meta` value, or a repo name.
141
+ *
142
+ * The transliterations above cover what actually shows up; anything else outside
143
+ * latin1 is dropped, and a value that transliterates to nothing at all (a title
144
+ * written entirely in a non-latin script) degrades to a marker rather than an
145
+ * empty header. Lossy on purpose: carrying full Unicode needs percent-encoding
146
+ * here AND a matching decode in the Worker, which every already-deployed Worker
147
+ * would render as `%E2%80%A6` until its operator ran `agents artifacts share
148
+ * update` — tracked as RUSH-2786.
149
+ */
150
+ export declare function toHeaderValue(text: string): string;
151
+ /**
152
+ * Best-effort human title when `--label` is omitted: the HTML `<title>`, else a
153
+ * Markdown frontmatter `title:`, else the filename. Always returns something —
154
+ * a headless publish must never hang waiting on a prompt for one.
155
+ */
156
+ export declare function deriveLabel(filePath: string, body: Buffer): string;
56
157
  /** Default auto-expire for unflagged publishes — accidental links decay (RUSH-2443). */
57
158
  export declare const DEFAULT_SHARE_EXPIRE = "30d";
58
159
  /** `30d` / `12h` / `2026-08-01` → an absolute ISO timestamp (or undefined). */
@@ -68,6 +169,25 @@ export interface SensitiveHit {
68
169
  /** Short redacted sample so the error names *what* was found without dumping it. */
69
170
  sample: string;
70
171
  }
172
+ /**
173
+ * Mask every email address in `text`, so a page can be published without tripping
174
+ * {@link scanShareContent}.
175
+ *
176
+ * Lives here, beside the scanner, rather than in `lib/redact.ts`: it exists solely
177
+ * to satisfy this gate, and sharing {@link EMAIL_RE} is what makes the masking
178
+ * *sufficient* to clear it rather than merely reducing the hit count. Two copies of
179
+ * the pattern in two modules would drift, and the failure mode of that drift is a
180
+ * refused publish at runtime.
181
+ *
182
+ * Deliberately NOT part of `redactSecrets`: an email is not a credential, and a
183
+ * transcript rendered for a private gist or local review reads better with the real
184
+ * author addresses intact. It only becomes a leak once the text is PUBLISHED — a
185
+ * world-readable page carrying seven of them is the RUSH-2428 incident.
186
+ *
187
+ * The whole address goes, domain included — a personal domain identifies its owner
188
+ * as surely as the local part does, and keeping it would buy the reader nothing.
189
+ */
190
+ export declare function redactEmails(text: string): string;
71
191
  /**
72
192
  * Scan a text body for email addresses and credential-shaped strings. Returns
73
193
  * the first few hits (deduped by kind+sample). Binary / non-text bodies yield