@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
@@ -523,22 +523,59 @@ export async function resolvePeerTarget(machine) {
523
523
  }
524
524
  return undefined;
525
525
  }
526
+ /** Interactive ceiling for a picker-driven peer preview fetch. Tighter than the
527
+ * fan-out's 60s: the user is arrowing through rows, and a peer that can't
528
+ * answer a one-session digest in this window should degrade to the metadata
529
+ * card rather than hold a "fetching…" pane open. */
530
+ const PEER_PREVIEW_TIMEOUT_MS = 15_000;
531
+ /**
532
+ * Fetch one remote session's preview digest from its owning peer — the data
533
+ * behind the picker pane for a `_remote` row, whose transcript file this
534
+ * machine cannot parse. Runs the peer's own `agents sessions preview <id>
535
+ * --local --json` (the same envelope `agents sessions preview` already
536
+ * delegates to for a remote id) and returns its `preview` object, verbatim and
537
+ * UNSANITIZED — the caller owns scrubbing peer-supplied strings before any of
538
+ * them reach a TTY. Undefined on every failure: unregistered machine, SSH
539
+ * error, timeout, version-skewed peer with no `--json` preview envelope.
540
+ */
541
+ export async function fetchPeerPreviewDigest(sessionId, machine, timeoutMs = PEER_PREVIEW_TIMEOUT_MS) {
542
+ const peer = await resolvePeerTarget(machine);
543
+ if (!peer)
544
+ return undefined;
545
+ const cmd = remoteListCommand(['sessions', 'preview', sessionId, '--local', '--json'], peer.os);
546
+ const capture = await sshCapture(peer.target, cmd, timeoutMs);
547
+ if (capture.code !== 0)
548
+ return undefined;
549
+ let parsed;
550
+ try {
551
+ parsed = JSON.parse(stripClixml(capture.stdout));
552
+ }
553
+ catch {
554
+ return undefined;
555
+ }
556
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
557
+ return undefined;
558
+ const preview = parsed.preview;
559
+ if (!preview || typeof preview !== 'object' || Array.isArray(preview))
560
+ return undefined;
561
+ return preview;
562
+ }
526
563
  /**
527
564
  * Run `agents <args>` ON a peer over SSH, attached to this terminal (inherited
528
565
  * stdio). `args` is the full arg vector after the binary — callers pass e.g.
529
566
  * `['sessions', id, '--markdown']` or `['sessions', 'resume', id]`. Used when a
530
567
  * picked session lives on another machine: its transcript and agent binary are
531
568
  * there, so both reading (no TTY) and resuming (TTY) must execute on the peer —
532
- * not via a local `--host` hop, which would discover locally and dead-end for a
569
+ * not via a local `--device` hop, which would discover locally and dead-end for a
533
570
  * session that exists only on the peer. Resolves 'no-target' when the machine
534
571
  * isn't a dialable registered device; the caller surfaces a clear message.
535
572
  *
536
573
  * `opts.env` adds variables to the remote command. It deliberately does NOT
537
- * carry `AGENTS_FLEET_REMOTE` the way the `--host` passthrough does: that marker
574
+ * carry `AGENTS_FLEET_REMOTE` the way the `--device` passthrough does: that marker
538
575
  * gates consent-sensitive actions on the far side
539
576
  * (lib/browser/remote-control.ts), and a resumed agent is a long-lived session
540
577
  * that would inherit it for its whole life — `agents browser start` inside it
541
- * would then be refused as a cross-machine drive. A one-shot `--host` command
578
+ * would then be refused as a cross-machine drive. A one-shot `--device` command
542
579
  * can carry the marker; a session cannot.
543
580
  */
544
581
  export async function runOnPeer(args, machine, opts = {}) {
@@ -6,11 +6,11 @@
6
6
  */
7
7
  export declare function shellQuote(s: string): string;
8
8
  /**
9
- * Strip the `--host`/`-H` flag (and its value) from a raw `agents sessions` argv,
9
+ * Strip the `--device`/`-D` flag (and its value) from a raw `agents sessions` argv,
10
10
  * leaving the args to forward to the remote unchanged. The remote runs the same
11
11
  * binary, so every other flag (`--since`, `--last`, `--json`, query, …) carries
12
- * over for free. Handles every form commander accepts: `--host h`, `--host=h`,
13
- * `-H h`, `-H=h`, and the glued short form `-Hh`.
12
+ * over for free. Handles every form commander accepts: `--device h`, `--device=h`,
13
+ * `-D h`, `-D=h`, and the glued short form `-Dh`.
14
14
  *
15
15
  * @param argv full process argv; the sessions args begin at index 2
16
16
  * (`[runtime, script, 'sessions', ...]`).
@@ -20,9 +20,9 @@ export declare function buildForwardedArgs(argv: string[], hosts?: Set<string>):
20
20
  * Force a forwarded `agents sessions` listing to span the peer's WHOLE index.
21
21
  *
22
22
  * A remote listing runs in the peer's SSH-login cwd — its home dir — and the
23
- * default listing is silently cwd-scoped, so `sessions --host box` reads as
23
+ * default listing is silently cwd-scoped, so `sessions --device box` reads as
24
24
  * empty even when the box's index is full (`No sessions found for /home/<user>`).
25
- * Across SSH a peer's cwd is meaningless, so `--host` defaults to `--all`
25
+ * Across SSH a peer's cwd is meaningless, so `--device` defaults to `--all`
26
26
  * (whole-index) scope. This only drops the *cwd* narrowing — an explicit path
27
27
  * query, `--project`, `--since`, or `--agent` filter still narrows on top, and
28
28
  * a query that looks like a path takes precedence over `--all` on the remote.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `agents sessions --host <target>` — run the session query on a remote machine
2
+ * `agents sessions --device <target>` — run the session query on a remote machine
3
3
  * over SSH and stream its output back. Session transcripts and the index DB live
4
4
  * on the machine that produced them (see `discover.ts`, all `os.homedir()`-rooted),
5
5
  * so instead of syncing the bytes here we invoke the *remote's own* `agents
@@ -18,7 +18,7 @@
18
18
  * banner. The cache is a byproduct of fetches you already made — freely
19
19
  * deletable — so the fetch-don't-replicate model holds.
20
20
  *
21
- * Mirrors the transport already used by `agents secrets export --host`
21
+ * Mirrors the transport already used by `agents secrets export --device`
22
22
  * (`src/commands/secrets.ts`): `ssh -o BatchMode=yes <host> bash -lc '<cmd>'`,
23
23
  * with `bash -lc` so the remote login PATH resolves `agents`.
24
24
  */
@@ -44,11 +44,11 @@ export function shellQuote(s) {
44
44
  return `'${s.replace(/'/g, `'\\''`)}'`;
45
45
  }
46
46
  /**
47
- * Strip the `--host`/`-H` flag (and its value) from a raw `agents sessions` argv,
47
+ * Strip the `--device`/`-D` flag (and its value) from a raw `agents sessions` argv,
48
48
  * leaving the args to forward to the remote unchanged. The remote runs the same
49
49
  * binary, so every other flag (`--since`, `--last`, `--json`, query, …) carries
50
- * over for free. Handles every form commander accepts: `--host h`, `--host=h`,
51
- * `-H h`, `-H=h`, and the glued short form `-Hh`.
50
+ * over for free. Handles every form commander accepts: `--device h`, `--device=h`,
51
+ * `-D h`, `-D=h`, and the glued short form `-Dh`.
52
52
  *
53
53
  * @param argv full process argv; the sessions args begin at index 2
54
54
  * (`[runtime, script, 'sessions', ...]`).
@@ -58,12 +58,10 @@ export function buildForwardedArgs(argv, hosts = new Set()) {
58
58
  const out = [];
59
59
  for (let i = 0; i < args.length; i++) {
60
60
  const a = args[i];
61
- if (a === '--host' || a === '-H' || a === '--device' || a === '--devices') {
62
- // Commander's `<target...>` variadic accepts both `--host a --host b` and
63
- // `--host a b` — consume every consecutive token that is a known host so
64
- // the variadic form doesn't leak the extra hosts into the remote argv.
65
- // `--device` is an alias for `--host` (its values are merged into the same
66
- // host set), so strip it the same way — else the peer would re-fan-out.
61
+ if (a === '--device' || a === '--devices') {
62
+ // Commander's `<target...>` variadic accepts both `--device a --device b`
63
+ // and `--device a b` — consume every consecutive token that is a known host
64
+ // so the variadic form doesn't leak the extra hosts into the remote argv.
67
65
  // Fall back to consuming the single next token when we have no host set
68
66
  // (e.g. malformed input) so the flag value never leaks either way.
69
67
  if (hosts.size > 0) {
@@ -75,10 +73,8 @@ export function buildForwardedArgs(argv, hosts = new Set()) {
75
73
  }
76
74
  continue;
77
75
  }
78
- if (a.startsWith('--host=') || a.startsWith('-H=') || a.startsWith('--device=') || a.startsWith('--devices='))
76
+ if (a.startsWith('--device=') || a.startsWith('--devices='))
79
77
  continue;
80
- if (/^-H.+/.test(a))
81
- continue; // glued short form: -Hyosemite-s1
82
78
  out.push(a);
83
79
  }
84
80
  return out;
@@ -87,9 +83,9 @@ export function buildForwardedArgs(argv, hosts = new Set()) {
87
83
  * Force a forwarded `agents sessions` listing to span the peer's WHOLE index.
88
84
  *
89
85
  * A remote listing runs in the peer's SSH-login cwd — its home dir — and the
90
- * default listing is silently cwd-scoped, so `sessions --host box` reads as
86
+ * default listing is silently cwd-scoped, so `sessions --device box` reads as
91
87
  * empty even when the box's index is full (`No sessions found for /home/<user>`).
92
- * Across SSH a peer's cwd is meaningless, so `--host` defaults to `--all`
88
+ * Across SSH a peer's cwd is meaningless, so `--device` defaults to `--all`
93
89
  * (whole-index) scope. This only drops the *cwd* narrowing — an explicit path
94
90
  * query, `--project`, `--since`, or `--agent` filter still narrows on top, and
95
91
  * a query that looks like a path takes precedence over `--all` on the remote.
@@ -110,7 +106,7 @@ export function ensureWholeIndex(forwardedArgs) {
110
106
  * remote renders its table to the local screen.
111
107
  */
112
108
  export function buildRemoteCommand(forwardedArgs, columns, os) {
113
- // `--host <box>` means "that box's own sessions" — so the peer must answer for
109
+ // `--device <box>` means "that box's own sessions" — so the peer must answer for
114
110
  // ITSELF and not re-sweep its fleet. Without this the remote `agents sessions`
115
111
  // fans back out to every device IT knows (including us), printing a spurious
116
112
  // `<this-machine>: unreachable`. AGENTS_SESSIONS_LOCAL=1 pins the peer local,
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * The one public command used by UI and lifecycle consumers to reopen a session.
3
- * `agents resume` owns identity resolution, source-device routing, version/home
4
- * selection, and harness-specific continuation; callers must not recreate it.
3
+ * `agents sessions resume` owns identity resolution, source-device routing,
4
+ * version/home selection, and harness-specific continuation; callers must not
5
+ * recreate it.
5
6
  */
6
7
  export declare function buildCanonicalResumeCommand(sessionId: string): string[];
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * The one public command used by UI and lifecycle consumers to reopen a session.
3
- * `agents resume` owns identity resolution, source-device routing, version/home
4
- * selection, and harness-specific continuation; callers must not recreate it.
3
+ * `agents sessions resume` owns identity resolution, source-device routing,
4
+ * version/home selection, and harness-specific continuation; callers must not
5
+ * recreate it.
5
6
  */
6
7
  export function buildCanonicalResumeCommand(sessionId) {
7
- return ['agents', 'resume', sessionId];
8
+ return ['agents', 'sessions', 'resume', sessionId];
8
9
  }
@@ -20,10 +20,10 @@
20
20
  * remote session resumed in whatever directory the user happened to be in.
21
21
  *
22
22
  * Callers act on the answer differently, and the difference is deliberate:
23
- * `agents resume` and `agents sessions attach` HOP to the owner over SSH, while
23
+ * `agents sessions resume` and `agents sessions attach` HOP to the owner over SSH, while
24
24
  * `resumeSessionInPlace` — the local takeover every routed caller reaches only
25
25
  * after deciding — REFUSES. The batch `sessions resume` needs no check of its
26
- * own: each of its tabs runs the canonical `agents resume <id>`
26
+ * own: each of its tabs runs the canonical `agents sessions resume <id>`
27
27
  * (lib/session/resume-command.ts), which routes itself.
28
28
  */
29
29
  import type { SessionMeta } from './types.js';
@@ -41,7 +41,7 @@ import type { SessionMeta } from './types.js';
41
41
  export declare const RESUME_PINNED_ENV = "AGENTS_RESUME_PINNED";
42
42
  /**
43
43
  * Whether this process was handed a resume by its owner-routing hop — read once,
44
- * then cleared so a nested `agents resume` inside the running agent still routes
44
+ * then cleared so a nested `agents sessions resume` inside the running agent still routes
45
45
  * normally.
46
46
  */
47
47
  export declare function consumeResumePinned(): boolean;
@@ -20,10 +20,10 @@
20
20
  * remote session resumed in whatever directory the user happened to be in.
21
21
  *
22
22
  * Callers act on the answer differently, and the difference is deliberate:
23
- * `agents resume` and `agents sessions attach` HOP to the owner over SSH, while
23
+ * `agents sessions resume` and `agents sessions attach` HOP to the owner over SSH, while
24
24
  * `resumeSessionInPlace` — the local takeover every routed caller reaches only
25
25
  * after deciding — REFUSES. The batch `sessions resume` needs no check of its
26
- * own: each of its tabs runs the canonical `agents resume <id>`
26
+ * own: each of its tabs runs the canonical `agents sessions resume <id>`
27
27
  * (lib/session/resume-command.ts), which routes itself.
28
28
  */
29
29
  import { isSelfHost } from '../devices/self-host.js';
@@ -41,7 +41,7 @@ import { isSelfHost } from '../devices/self-host.js';
41
41
  export const RESUME_PINNED_ENV = 'AGENTS_RESUME_PINNED';
42
42
  /**
43
43
  * Whether this process was handed a resume by its owner-routing hop — read once,
44
- * then cleared so a nested `agents resume` inside the running agent still routes
44
+ * then cleared so a nested `agents sessions resume` inside the running agent still routes
45
45
  * normally.
46
46
  */
47
47
  export function consumeResumePinned() {
@@ -154,6 +154,10 @@ export interface LoadFleetActiveSessionsOptions {
154
154
  gather: () => Promise<{
155
155
  sessions: ActiveSession[];
156
156
  remoteDeviceCount: number;
157
+ /** Peer names that went unheard on this gather (RUSH-2507). Undefined when the gather didn't compute it. */
158
+ remoteSkipped?: string[];
159
+ /** True when the device list itself could not be loaded — no peer was even attempted. */
160
+ remoteDiscoveryFailed?: boolean;
157
161
  }>;
158
162
  readCache?: typeof readActiveSessionsCache;
159
163
  writeCache?: typeof writeActiveSessionsCache;
@@ -163,6 +167,14 @@ export interface LoadFleetActiveSessionsResult {
163
167
  remoteDeviceCount: number;
164
168
  servedFromCache: boolean;
165
169
  capturedAt: number;
170
+ /**
171
+ * Diagnostics from the gather that produced this result. Only populated on a
172
+ * live gather (`servedFromCache: false`) — a cache hit serves a prior
173
+ * snapshot that never persisted these fields, so they read `undefined`
174
+ * ("not probed this call") rather than falsely claiming a clean fleet.
175
+ */
176
+ remoteSkipped?: string[];
177
+ remoteDiscoveryFailed?: boolean;
166
178
  }
167
179
  /**
168
180
  * Cache-first load of the fleet-wide active set. A prior gather (or any surface
@@ -442,6 +442,8 @@ export async function loadFleetActiveSessions(opts) {
442
442
  remoteDeviceCount: live.remoteDeviceCount,
443
443
  servedFromCache: false,
444
444
  capturedAt: snap.capturedAt,
445
+ remoteSkipped: live.remoteSkipped,
446
+ remoteDiscoveryFailed: live.remoteDiscoveryFailed,
445
447
  };
446
448
  }
447
449
  /**
@@ -0,0 +1,55 @@
1
+ import type { SessionMeta } from './types.js';
2
+ export interface SessionHtmlOptions {
3
+ /** Whether the Markdown was rendered with redaction on — shown in the footer. */
4
+ redacted?: boolean;
5
+ }
6
+ /** One metadata chip in the page header. */
7
+ interface Chip {
8
+ label: string;
9
+ value: string;
10
+ }
11
+ export declare function escapeHtml(text: string): string;
12
+ /**
13
+ * Lift every folded reasoning block out of the Markdown, leaving a sentinel.
14
+ *
15
+ * `renderer.html` escapes raw HTML unconditionally — the transcript body is model
16
+ * and tool output, so nothing in it may round-trip as markup. That also escaped
17
+ * the `<details>` wrapper `--reasoning fold` emits, which is why the disclosure
18
+ * element has to be reconstructed here instead of allowlisted through.
19
+ *
20
+ * Allowlisting was tried twice and is the wrong shape: marked hands the same
21
+ * markup over as several different raw strings depending on context (a whole-token
22
+ * gate passed the opening tag and escaped the closing one in a real document), and
23
+ * a bare `<details>` in ordinary prose is a complete INLINE html token — so prose
24
+ * that merely mentions the tag would emit a live, unclosed element that swallows
25
+ * every later turn into it. Reconstructing both ends here makes the pairing
26
+ * structural: it cannot be unbalanced by anything the transcript contains.
27
+ */
28
+ export declare function liftFoldBlocks(markdown: string): {
29
+ text: string;
30
+ blocks: string[];
31
+ };
32
+ /** Human duration — "13 minutes", never "12m 49s". */
33
+ export declare function formatDuration(ms: number): string;
34
+ /**
35
+ * The chips shown under the title.
36
+ *
37
+ * Deliberately excludes `account` (an email — the publish-time sensitive-content
38
+ * scan rejects those, and correctly), `cwd`, and `machine`: a published transcript
39
+ * should not carry the operator's identity or local paths in its chrome. Host and
40
+ * repo already ride in the share object's provenance metadata, which is the right
41
+ * home for them.
42
+ */
43
+ export declare function buildChips(session: SessionMeta): Chip[];
44
+ /**
45
+ * The page's `<title>` — `deriveLabel()` reads this as the share's gallery label.
46
+ *
47
+ * The document heading is derived from the session's first prompt, which in a real
48
+ * session is routinely a pasted URL plus a file path plus the actual request. Left
49
+ * whole it renders as a three-line wall above the transcript and an unreadable
50
+ * gallery row, so it is collapsed to one line and cut at a word boundary. `--label`
51
+ * overrides it outright.
52
+ */
53
+ export declare function sessionPageTitle(session: SessionMeta, markdown: string): string;
54
+ export declare function renderSessionHtmlDocument(session: SessionMeta, markdown: string, options?: SessionHtmlOptions): string;
55
+ export {};
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Wrap an already-rendered session transcript in ONE self-contained HTML page for
3
+ * `agents sessions share`.
4
+ *
5
+ * Takes the Markdown document as an argument rather than producing it, so the
6
+ * decisions that make a transcript safe to publish — redaction, synthetic-turn
7
+ * filtering, tool-output truncation, reasoning visibility — stay in
8
+ * `renderSessionMarkdownDocument()` and the HTML path can never drift from the
9
+ * Markdown one. That also keeps this a pure presentation function with no import
10
+ * back into the command layer.
11
+ *
12
+ * Self-contained on purpose: an inline <style>, no external assets, no CDN, no
13
+ * dependency on the artifacts-cli host CLI (which is not configured on every box,
14
+ * RUSH-2728). The page is uploaded verbatim to the share Worker.
15
+ *
16
+ * Terminal-coded per the agents-cli brand (#0a0a0a bg, #a3e635 lime accent,
17
+ * JetBrains Mono), with a light theme under `prefers-color-scheme: light` and an
18
+ * in-page toggle so a published link is readable in bright light and dim alike.
19
+ */
20
+ import { marked, Renderer } from 'marked';
21
+ export function escapeHtml(text) {
22
+ return text
23
+ .replace(/&/g, '&amp;')
24
+ .replace(/</g, '&lt;')
25
+ .replace(/>/g, '&gt;')
26
+ .replace(/"/g, '&quot;')
27
+ .replace(/'/g, '&#39;');
28
+ }
29
+ /**
30
+ * A transcript is untrusted text: it carries whatever the model wrote and whatever
31
+ * a tool printed. marked passes raw HTML through by default, so a session that
32
+ * merely *discussed* a `<script>` tag would ship an executable one on a public URL.
33
+ * Escaping the html token's raw source neutralizes that without mangling the
34
+ * visible text, and non-http(s) link schemes are dropped so `javascript:` cannot
35
+ * ride in through a Markdown link.
36
+ */
37
+ /**
38
+ * The only raw HTML the transcript renderer itself emits: `--reasoning fold` wraps
39
+ * each thinking block in a disclosure element (`session/render.ts` — the `fold`
40
+ * branch pushes `<details>\n<summary>Reasoning</summary>` and `</details>`).
41
+ *
42
+ * Escaping those along with everything else published `&lt;details&gt;` as visible
43
+ * text and no collapsing, so `--reasoning fold` shipped broken. They are allowed
44
+ * back through by EXACT match on the token's raw source, not by parsing tags:
45
+ * attribute-free `details`/`summary` carry no script, no URL, and no event handler,
46
+ * and an exact-string gate cannot be widened by crafted input the way a tag parser
47
+ * can. Anything else — including `<details onclick=…>` — still escapes.
48
+ */
49
+ /**
50
+ * Sentinel standing in for one folded reasoning block while the document goes
51
+ * through marked. Deliberately not valid Markdown or HTML, and any pre-existing
52
+ * occurrence in the transcript is neutralized before substitution.
53
+ */
54
+ const FOLD_SENTINEL = 'aGeNtSfOlDbLoCk';
55
+ // The neutralization below is only sound because this literal is BORDER-FREE: its
56
+ // first character occurs nowhere else in it, so no occurrence can overlap another
57
+ // and splitting on it cannot leave a fresh one behind. A bordered literal (`aba`
58
+ // splits into a leftover `a` + `ba`) is defeatable. Keep that property if you
59
+ // ever change the string.
60
+ /** The exact block `session/render.ts` pushes on its `fold` branch. */
61
+ const FOLD_BLOCK = /<details>\n<summary>Reasoning<\/summary>\n\n([\s\S]*?)\n\n<\/details>/g;
62
+ /**
63
+ * Lift every folded reasoning block out of the Markdown, leaving a sentinel.
64
+ *
65
+ * `renderer.html` escapes raw HTML unconditionally — the transcript body is model
66
+ * and tool output, so nothing in it may round-trip as markup. That also escaped
67
+ * the `<details>` wrapper `--reasoning fold` emits, which is why the disclosure
68
+ * element has to be reconstructed here instead of allowlisted through.
69
+ *
70
+ * Allowlisting was tried twice and is the wrong shape: marked hands the same
71
+ * markup over as several different raw strings depending on context (a whole-token
72
+ * gate passed the opening tag and escaped the closing one in a real document), and
73
+ * a bare `<details>` in ordinary prose is a complete INLINE html token — so prose
74
+ * that merely mentions the tag would emit a live, unclosed element that swallows
75
+ * every later turn into it. Reconstructing both ends here makes the pairing
76
+ * structural: it cannot be unbalanced by anything the transcript contains.
77
+ */
78
+ export function liftFoldBlocks(markdown) {
79
+ const blocks = [];
80
+ // A transcript that literally contains the sentinel must not be able to forge a
81
+ // disclosure element, so break any occurrence before inserting our own.
82
+ const safe = markdown.split(FOLD_SENTINEL).join(`${FOLD_SENTINEL[0]}​${FOLD_SENTINEL.slice(1)}`);
83
+ const text = safe.replace(FOLD_BLOCK, (_match, inner) => {
84
+ blocks.push(inner);
85
+ return `${FOLD_SENTINEL}${blocks.length - 1}${FOLD_SENTINEL}`;
86
+ });
87
+ return { text, blocks };
88
+ }
89
+ function safeRenderer() {
90
+ const renderer = new Renderer();
91
+ renderer.html = ({ raw }) => escapeHtml(raw);
92
+ const isSafeHref = (href) => /^(https?:|mailto:|#|\/)/i.test(href.trim());
93
+ renderer.link = ({ href, title, tokens }) => {
94
+ const text = renderer.parser.parseInline(tokens);
95
+ if (!isSafeHref(href))
96
+ return text;
97
+ const attrs = title ? ` title="${escapeHtml(title)}"` : '';
98
+ return `<a href="${escapeHtml(href)}"${attrs} rel="noopener noreferrer nofollow">${text}</a>`;
99
+ };
100
+ renderer.image = ({ href, title, text }) => {
101
+ if (!isSafeHref(href))
102
+ return escapeHtml(text);
103
+ const attrs = title ? ` title="${escapeHtml(title)}"` : '';
104
+ return `<img src="${escapeHtml(href)}" alt="${escapeHtml(text)}"${attrs} loading="lazy" />`;
105
+ };
106
+ return renderer;
107
+ }
108
+ /** Human duration — "13 minutes", never "12m 49s". */
109
+ export function formatDuration(ms) {
110
+ const minutes = Math.round(ms / 60_000);
111
+ if (minutes < 1)
112
+ return 'under a minute';
113
+ if (minutes < 60)
114
+ return `${minutes} minute${minutes === 1 ? '' : 's'}`;
115
+ const hours = Math.round(ms / 3_600_000);
116
+ if (hours < 24)
117
+ return `${hours} hour${hours === 1 ? '' : 's'}`;
118
+ const days = Math.round(ms / 86_400_000);
119
+ return `${days} day${days === 1 ? '' : 's'}`;
120
+ }
121
+ /**
122
+ * The chips shown under the title.
123
+ *
124
+ * Deliberately excludes `account` (an email — the publish-time sensitive-content
125
+ * scan rejects those, and correctly), `cwd`, and `machine`: a published transcript
126
+ * should not carry the operator's identity or local paths in its chrome. Host and
127
+ * repo already ride in the share object's provenance metadata, which is the right
128
+ * home for them.
129
+ */
130
+ export function buildChips(session) {
131
+ const chips = [{ label: 'agent', value: session.agent }];
132
+ if (session.model)
133
+ chips.push({ label: 'model', value: session.model });
134
+ if (session.mode)
135
+ chips.push({ label: 'mode', value: session.mode });
136
+ if (session.project)
137
+ chips.push({ label: 'project', value: session.project });
138
+ if (session.gitBranch)
139
+ chips.push({ label: 'branch', value: session.gitBranch });
140
+ if (session.ticketId)
141
+ chips.push({ label: 'ticket', value: session.ticketId });
142
+ const date = (session.timestamp || '').slice(0, 10);
143
+ if (date)
144
+ chips.push({ label: 'date', value: date });
145
+ if (session.durationMs)
146
+ chips.push({ label: 'duration', value: formatDuration(session.durationMs) });
147
+ if (session.messageCount)
148
+ chips.push({ label: 'turns', value: String(session.messageCount) });
149
+ if (session.toolCallCount)
150
+ chips.push({ label: 'tools', value: String(session.toolCallCount) });
151
+ return chips;
152
+ }
153
+ /** Longest title that stays one readable line in the header and the gallery. */
154
+ const TITLE_MAX = 90;
155
+ /**
156
+ * The page's `<title>` — `deriveLabel()` reads this as the share's gallery label.
157
+ *
158
+ * The document heading is derived from the session's first prompt, which in a real
159
+ * session is routinely a pasted URL plus a file path plus the actual request. Left
160
+ * whole it renders as a three-line wall above the transcript and an unreadable
161
+ * gallery row, so it is collapsed to one line and cut at a word boundary. `--label`
162
+ * overrides it outright.
163
+ */
164
+ export function sessionPageTitle(session, markdown) {
165
+ const heading = /^#\s+(.+)$/m.exec(markdown)?.[1]?.replace(/\s+/g, ' ').trim();
166
+ if (!heading)
167
+ return `${session.agent} session ${session.shortId || session.id}`;
168
+ if (heading.length <= TITLE_MAX)
169
+ return heading;
170
+ const cut = heading.slice(0, TITLE_MAX);
171
+ const lastSpace = cut.lastIndexOf(' ');
172
+ // A single unbroken token longer than the cap (a URL) has no boundary to cut on;
173
+ // a hard slice beats returning the whole thing.
174
+ return `${(lastSpace > TITLE_MAX / 2 ? cut.slice(0, lastSpace) : cut).trimEnd()}…`;
175
+ }
176
+ export function renderSessionHtmlDocument(session, markdown, options = {}) {
177
+ const title = sessionPageTitle(session, markdown);
178
+ // The <h1> is re-rendered as the page header, so drop it from the body to
179
+ // avoid printing the title twice.
180
+ const { text, blocks } = liftFoldBlocks(markdown.replace(/^#\s+.+\n/, ''));
181
+ const render = (md) => marked.parse(md, { renderer: safeRenderer(), async: false });
182
+ // Reconstruct each disclosure element around its own separately-rendered
183
+ // content, so the open/close pairing is ours and cannot be unbalanced by the
184
+ // transcript.
185
+ const body = blocks.reduce((html, inner, i) => html.replace(new RegExp(`<p>${FOLD_SENTINEL}${i}${FOLD_SENTINEL}</p>`),
186
+ // A FUNCTION replacement, never a string one. String.replace expands `$&`,
187
+ // `` $` ``, `$'` and `$n` inside a string replacement, and marked turns
188
+ // `& < > " '` into entities — so reasoning text containing `$'` (bash
189
+ // ANSI-C quoting), `$&` (sed), or `$<` (make) would splice the matched
190
+ // sentinel back into the page and destroy the character after it. A
191
+ // function's return value is inserted verbatim.
192
+ () => `<details><summary>Reasoning</summary>\n${render(inner)}</details>`), render(text));
193
+ const chips = buildChips(session)
194
+ .map((c) => `<span class="chip"><span class="k">${escapeHtml(c.label)}</span>${escapeHtml(c.value)}</span>`)
195
+ .join('\n ');
196
+ const redacted = options.redacted !== false;
197
+ return `<!DOCTYPE html>
198
+ <html lang="en" data-theme="auto">
199
+ <head>
200
+ <meta charset="utf-8" />
201
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
202
+ <meta name="robots" content="noindex" />
203
+ <title>${escapeHtml(title)}</title>
204
+ <style>
205
+ :root {
206
+ --bg: #0a0a0a; --panel: #121212; --border: #262626; --fg: #e5e5e5;
207
+ --dim: #737373; --accent: #a3e635; --quote: #1a1a1a;
208
+ }
209
+ html[data-theme="light"] {
210
+ --bg: #fafafa; --panel: #ffffff; --border: #e5e5e5; --fg: #171717;
211
+ --dim: #737373; --accent: #4d7c0f; --quote: #f5f5f5;
212
+ }
213
+ @media (prefers-color-scheme: light) {
214
+ html[data-theme="auto"] {
215
+ --bg: #fafafa; --panel: #ffffff; --border: #e5e5e5; --fg: #171717;
216
+ --dim: #737373; --accent: #4d7c0f; --quote: #f5f5f5;
217
+ }
218
+ }
219
+ * { box-sizing: border-box; }
220
+ body {
221
+ margin: 0; background: var(--bg); color: var(--fg);
222
+ font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, sans-serif;
223
+ font-size: 15px; line-height: 1.65;
224
+ }
225
+ header {
226
+ border-bottom: 1px solid var(--border); padding: 28px 20px 20px;
227
+ }
228
+ header .inner, main { max-width: 900px; margin: 0 auto; }
229
+ header .mark {
230
+ color: var(--accent); font-weight: 700; letter-spacing: .5px; font-size: 12px;
231
+ text-transform: uppercase; font-family: ui-monospace, "JetBrains Mono", Menlo, monospace;
232
+ }
233
+ header h1 { font-size: 24px; line-height: 1.3; margin: 10px 0 14px; }
234
+ .chips { display: flex; flex-wrap: wrap; gap: 6px; }
235
+ .chip {
236
+ font-family: ui-monospace, "JetBrains Mono", Menlo, monospace; font-size: 11px;
237
+ color: var(--fg); background: var(--panel); border: 1px solid var(--border);
238
+ border-radius: 10px; padding: 2px 9px;
239
+ }
240
+ .chip .k { color: var(--dim); margin-right: 6px; }
241
+ .toggle {
242
+ float: right; cursor: pointer; background: none; border: 1px solid var(--border);
243
+ color: var(--dim); border-radius: 6px; padding: 2px 8px; font-size: 14px;
244
+ }
245
+ main { padding: 24px 20px 64px; }
246
+ h2 {
247
+ font-size: 13px; color: var(--accent); border-bottom: 1px solid var(--border);
248
+ padding-bottom: 6px; margin: 36px 0 14px; text-transform: uppercase;
249
+ letter-spacing: 1px; font-family: ui-monospace, "JetBrains Mono", Menlo, monospace;
250
+ }
251
+ h3 { font-size: 15px; margin: 26px 0 8px; }
252
+ h4 { font-size: 13px; color: var(--dim); margin: 20px 0 6px; font-weight: 600; }
253
+ a { color: var(--accent); }
254
+ blockquote {
255
+ margin: 0 0 20px; padding: 12px 16px; background: var(--quote);
256
+ border-left: 2px solid var(--border); border-radius: 0 6px 6px 0; color: var(--dim);
257
+ }
258
+ blockquote p { margin: 0 0 6px; }
259
+ blockquote p:last-child { margin: 0; }
260
+ pre {
261
+ background: var(--panel); border: 1px solid var(--border); border-radius: 6px;
262
+ padding: 12px 14px; overflow-x: auto;
263
+ }
264
+ code {
265
+ font-family: ui-monospace, "JetBrains Mono", Menlo, monospace; font-size: 12.5px;
266
+ }
267
+ :not(pre) > code {
268
+ background: var(--panel); border: 1px solid var(--border);
269
+ border-radius: 4px; padding: 1px 5px;
270
+ }
271
+ hr { border: none; border-top: 1px solid var(--border); margin: 32px 0; }
272
+ details { margin: 0 0 12px; }
273
+ summary { cursor: pointer; color: var(--dim); font-size: 13px; }
274
+ table { border-collapse: collapse; width: 100%; font-size: 13px; }
275
+ th, td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
276
+ footer {
277
+ max-width: 900px; margin: 0 auto; padding: 0 20px 48px;
278
+ color: var(--dim); font-size: 12px;
279
+ font-family: ui-monospace, "JetBrains Mono", Menlo, monospace;
280
+ }
281
+ footer a { color: var(--dim); }
282
+ </style>
283
+ </head>
284
+ <body>
285
+ <header>
286
+ <div class="inner">
287
+ <button class="toggle" id="theme" title="Toggle light and dark">&#9689;</button>
288
+ <div class="mark">agents session</div>
289
+ <h1>${escapeHtml(title)}</h1>
290
+ <div class="chips">
291
+ ${chips}
292
+ </div>
293
+ </div>
294
+ </header>
295
+ <main>
296
+ ${body}
297
+ </main>
298
+ <footer>
299
+ ${redacted ? 'Secret-redacted transcript' : 'Unredacted transcript'} rendered by
300
+ <a href="https://agents-cli.sh">agents-cli</a> &middot; <code>agents sessions share</code>
301
+ </footer>
302
+ <script>
303
+ (function () {
304
+ var root = document.documentElement;
305
+ var saved = null;
306
+ try { saved = localStorage.getItem('agents-share-theme'); } catch (e) {}
307
+ if (saved) root.setAttribute('data-theme', saved);
308
+ document.getElementById('theme').addEventListener('click', function () {
309
+ var dark = getComputedStyle(root).getPropertyValue('--bg').trim() === '#0a0a0a';
310
+ var next = dark ? 'light' : 'dark';
311
+ root.setAttribute('data-theme', next);
312
+ try { localStorage.setItem('agents-share-theme', next); } catch (e) {}
313
+ });
314
+ })();
315
+ </script>
316
+ </body>
317
+ </html>
318
+ `;
319
+ }