@phnx-labs/agents-cli 1.22.113 → 1.22.115

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 (802) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +32 -113
  3. package/dist/browser.js +0 -0
  4. package/dist/cli/command-registry.d.ts +0 -60
  5. package/dist/cli/command-registry.js +57 -66
  6. package/dist/commands/accounts.d.ts +3 -77
  7. package/dist/commands/accounts.js +13 -366
  8. package/dist/commands/apply.d.ts +0 -4
  9. package/dist/commands/apply.js +3 -3
  10. package/dist/commands/audit.js +1 -1
  11. package/dist/commands/auth.js +0 -2
  12. package/dist/commands/browser-picker.d.ts +3 -6
  13. package/dist/commands/browser-picker.js +2 -2
  14. package/dist/commands/browser-sessions-picker.d.ts +2 -1
  15. package/dist/commands/browser.d.ts +53 -0
  16. package/dist/commands/browser.js +199 -9
  17. package/dist/commands/computer-sessions-picker.d.ts +2 -1
  18. package/dist/commands/computer.d.ts +14 -19
  19. package/dist/commands/computer.js +65 -10
  20. package/dist/commands/config.js +46 -2
  21. package/dist/commands/daemon.d.ts +0 -23
  22. package/dist/commands/daemon.js +1 -1
  23. package/dist/commands/detach-core.d.ts +2 -1
  24. package/dist/commands/detach.d.ts +0 -3
  25. package/dist/commands/detach.js +3 -3
  26. package/dist/commands/doctor.d.ts +2 -3
  27. package/dist/commands/doctor.js +0 -11
  28. package/dist/commands/events.d.ts +1 -3
  29. package/dist/commands/events.js +4 -7
  30. package/dist/commands/exec.d.ts +0 -1
  31. package/dist/commands/exec.js +2 -7
  32. package/dist/commands/feed-watch.js +52 -8
  33. package/dist/commands/feed.d.ts +3 -3
  34. package/dist/commands/feed.js +1 -1
  35. package/dist/commands/focus.d.ts +4 -4
  36. package/dist/commands/focus.js +1 -1
  37. package/dist/commands/go.d.ts +0 -17
  38. package/dist/commands/go.js +2 -19
  39. package/dist/commands/harness-hooks.d.ts +0 -7
  40. package/dist/commands/harness-hooks.js +1 -1
  41. package/dist/commands/harness-wizard.d.ts +2 -2
  42. package/dist/commands/harness.d.ts +3 -8
  43. package/dist/commands/harness.js +1 -1
  44. package/dist/commands/inspect.d.ts +2 -3
  45. package/dist/commands/inspect.js +1 -1
  46. package/dist/commands/logs.js +1 -1
  47. package/dist/commands/mcp.js +8 -83
  48. package/dist/commands/memory.js +4 -47
  49. package/dist/commands/message.d.ts +1 -1
  50. package/dist/commands/message.js +7 -7
  51. package/dist/commands/plugins.js +1 -93
  52. package/dist/commands/projects.d.ts +2 -18
  53. package/dist/commands/projects.js +89 -3
  54. package/dist/commands/repo.js +0 -44
  55. package/dist/commands/resource-view.d.ts +3 -2
  56. package/dist/commands/resume.d.ts +0 -1
  57. package/dist/commands/resume.js +5 -2
  58. package/dist/commands/routines.d.ts +1 -3
  59. package/dist/commands/routines.js +1 -1
  60. package/dist/commands/run-account-picker.d.ts +2 -1
  61. package/dist/commands/run-broadcast.d.ts +2 -1
  62. package/dist/commands/run-device-picker.d.ts +2 -1
  63. package/dist/commands/secrets-passthrough.d.ts +14 -0
  64. package/dist/commands/secrets-passthrough.js +23 -4
  65. package/dist/commands/send.d.ts +4 -4
  66. package/dist/commands/send.js +6 -51
  67. package/dist/commands/sessions-backfill.d.ts +2 -35
  68. package/dist/commands/sessions-backfill.js +1 -1
  69. package/dist/commands/sessions-backup-setup.js +1 -1
  70. package/dist/commands/sessions-bookmark.d.ts +0 -10
  71. package/dist/commands/sessions-bookmark.js +1 -1
  72. package/dist/commands/sessions-inject.d.ts +2 -3
  73. package/dist/commands/sessions-inject.js +8 -17
  74. package/dist/commands/sessions-picker-factory.d.ts +4 -14
  75. package/dist/commands/sessions-picker-factory.js +2 -2
  76. package/dist/commands/sessions-picker.d.ts +3 -9
  77. package/dist/commands/sessions-picker.js +2 -2
  78. package/dist/commands/sessions-resume.d.ts +2 -4
  79. package/dist/commands/sessions-resume.js +0 -6
  80. package/dist/commands/sessions-share.d.ts +5 -7
  81. package/dist/commands/sessions-share.js +98 -49
  82. package/dist/commands/sessions-stats.d.ts +2 -1
  83. package/dist/commands/sessions-stop.d.ts +0 -3
  84. package/dist/commands/sessions-stop.js +1 -1
  85. package/dist/commands/sessions-tail.d.ts +2 -1
  86. package/dist/commands/sessions-trace.d.ts +4 -6
  87. package/dist/commands/sessions-trace.js +1 -1
  88. package/dist/commands/sessions.d.ts +13 -104
  89. package/dist/commands/sessions.js +11 -18
  90. package/dist/commands/setup-browser.js +18 -2
  91. package/dist/commands/setup-computer.js +20 -6
  92. package/dist/commands/setup-mine.d.ts +0 -6
  93. package/dist/commands/setup-mine.js +1 -1
  94. package/dist/commands/setup-secrets.js +24 -4
  95. package/dist/commands/setup-terminal.d.ts +3 -0
  96. package/dist/commands/setup-terminal.js +22 -0
  97. package/dist/commands/setup.d.ts +3 -4
  98. package/dist/commands/setup.js +21 -11
  99. package/dist/commands/skills.js +0 -8
  100. package/dist/commands/ssh.d.ts +6 -0
  101. package/dist/commands/ssh.js +92 -233
  102. package/dist/commands/sync.js +14 -5
  103. package/dist/commands/teams-picker.d.ts +2 -5
  104. package/dist/commands/teams-picker.js +2 -2
  105. package/dist/commands/teams.d.ts +1 -7
  106. package/dist/commands/teams.js +2 -2
  107. package/dist/commands/tmux.d.ts +1 -1
  108. package/dist/commands/tmux.js +1 -1
  109. package/dist/commands/traces.js +1 -1
  110. package/dist/commands/upgrade.d.ts +2 -1
  111. package/dist/commands/utils.d.ts +1 -1
  112. package/dist/commands/utils.js +1 -1
  113. package/dist/lib/account-capabilities.d.ts +2 -1
  114. package/dist/lib/account-catalog.d.ts +4 -13
  115. package/dist/lib/account-catalog.js +1 -1
  116. package/dist/lib/account-registry.d.ts +3 -4
  117. package/dist/lib/account-registry.js +1 -1
  118. package/dist/lib/accounting/account-launch.d.ts +4 -3
  119. package/dist/lib/accounting/account-pool.d.ts +2 -1
  120. package/dist/lib/accounting/rotate.d.ts +3 -9
  121. package/dist/lib/accounting/rotate.js +2 -14
  122. package/dist/lib/accounting/usage-sync.d.ts +5 -4
  123. package/dist/lib/accounting/usage.d.ts +7 -31
  124. package/dist/lib/accounting/usage.js +4 -4
  125. package/dist/lib/accounts/add.d.ts +0 -5
  126. package/dist/lib/accounts/add.js +1 -7
  127. package/dist/lib/accounts/migrate.d.ts +8 -8
  128. package/dist/lib/accounts/migrate.js +1 -1
  129. package/dist/lib/acp/client.d.ts +3 -2
  130. package/dist/lib/acp/harnesses.d.ts +2 -2
  131. package/dist/lib/acp/harnesses.js +1 -1
  132. package/dist/lib/acp/run.d.ts +2 -1
  133. package/dist/lib/actor.d.ts +3 -2
  134. package/dist/lib/add-dir.d.ts +2 -17
  135. package/dist/lib/add-dir.js +2 -6
  136. package/dist/lib/address.d.ts +56 -0
  137. package/dist/lib/address.js +143 -0
  138. package/dist/lib/agent-spec/agents.d.ts +12 -28
  139. package/dist/lib/agent-spec/agents.js +2 -6
  140. package/dist/lib/agent-spec/primitives.d.ts +0 -7
  141. package/dist/lib/agent-spec/primitives.js +0 -6
  142. package/dist/lib/agent-spec/types.d.ts +2 -1
  143. package/dist/lib/analytics/dashboard.d.ts +1 -5
  144. package/dist/lib/analytics/dashboard.js +0 -2
  145. package/dist/lib/analytics/mix-commands.d.ts +0 -7
  146. package/dist/lib/analytics/mix-commands.js +3 -3
  147. package/dist/lib/analytics/recipes.d.ts +0 -12
  148. package/dist/lib/analytics/recipes.js +7 -31
  149. package/dist/lib/analytics/usage-db.d.ts +5 -32
  150. package/dist/lib/analytics/usage-db.js +1 -70
  151. package/dist/lib/answer-router.d.ts +7 -6
  152. package/dist/lib/answer-router.js +5 -11
  153. package/dist/lib/artifact-actions.d.ts +0 -4
  154. package/dist/lib/artifacts-client.d.ts +20 -0
  155. package/dist/lib/artifacts-client.js +46 -0
  156. package/dist/lib/ask-classifier.d.ts +3 -4
  157. package/dist/lib/ask-classifier.js +0 -7
  158. package/dist/lib/auth-health.d.ts +3 -46
  159. package/dist/lib/auth-health.js +3 -3
  160. package/dist/lib/auth-mint.d.ts +6 -6
  161. package/dist/lib/auth-mint.js +7 -7
  162. package/dist/lib/bench/runner.d.ts +2 -2
  163. package/dist/lib/bench/runner.js +1 -1
  164. package/dist/lib/bench/storage.d.ts +0 -1
  165. package/dist/lib/bench/storage.js +1 -1
  166. package/dist/lib/boot-profile.d.ts +0 -2
  167. package/dist/lib/boot-profile.js +0 -4
  168. package/dist/lib/brand.d.ts +0 -6
  169. package/dist/lib/brand.js +1 -1
  170. package/dist/lib/browser/arc-discovery.d.ts +4 -12
  171. package/dist/lib/browser/arc-discovery.js +1 -1
  172. package/dist/lib/browser/cdp.d.ts +1 -1
  173. package/dist/lib/browser/chrome.d.ts +2 -2
  174. package/dist/lib/browser/chrome.js +0 -4
  175. package/dist/lib/browser/chromium-discovery.d.ts +3 -2
  176. package/dist/lib/browser/drivers/arc.d.ts +3 -20
  177. package/dist/lib/browser/drivers/arc.js +2 -7
  178. package/dist/lib/browser/drivers/firefox.d.ts +2 -6
  179. package/dist/lib/browser/drivers/firefox.js +1 -1
  180. package/dist/lib/browser/drivers/local.d.ts +2 -1
  181. package/dist/lib/browser/drivers/ssh.d.ts +2 -3
  182. package/dist/lib/browser/drivers/ssh.js +0 -7
  183. package/dist/lib/browser/firefox-discovery.d.ts +4 -3
  184. package/dist/lib/browser/har.d.ts +8 -7
  185. package/dist/lib/browser/hygiene.d.ts +2 -3
  186. package/dist/lib/browser/hygiene.js +1 -1
  187. package/dist/lib/browser/ipc.d.ts +4 -3
  188. package/dist/lib/browser/ipc.js +1 -1
  189. package/dist/lib/browser/login-detection.d.ts +1 -8
  190. package/dist/lib/browser/registry.d.ts +2 -1
  191. package/dist/lib/browser/remote-control.d.ts +0 -7
  192. package/dist/lib/browser/remote-control.js +2 -2
  193. package/dist/lib/browser/resolve-target.d.ts +2 -6
  194. package/dist/lib/browser/resolve-target.js +3 -3
  195. package/dist/lib/browser/runtime-state.d.ts +59 -4
  196. package/dist/lib/browser/runtime-state.js +99 -18
  197. package/dist/lib/browser/service.d.ts +4 -4
  198. package/dist/lib/browser/service.js +21 -1
  199. package/dist/lib/browser/sessions-list.d.ts +0 -10
  200. package/dist/lib/browser/sessions-list.js +3 -3
  201. package/dist/lib/browser/stream.d.ts +2 -1
  202. package/dist/lib/browser/task-index.d.ts +4 -4
  203. package/dist/lib/browser/task-index.js +1 -1
  204. package/dist/lib/browser/types.d.ts +0 -20
  205. package/dist/lib/browser/types.js +1 -34
  206. package/dist/lib/browser/upload.d.ts +0 -27
  207. package/dist/lib/budget/ledger.d.ts +0 -2
  208. package/dist/lib/budget/ledger.js +1 -1
  209. package/dist/lib/budget/live-cloud.d.ts +2 -1
  210. package/dist/lib/budget/preflight.d.ts +3 -5
  211. package/dist/lib/budget/preflight.js +1 -1
  212. package/dist/lib/catchup.d.ts +2 -1
  213. package/dist/lib/channels/owner-forward.d.ts +5 -4
  214. package/dist/lib/channels/owner-sink.js +2 -2
  215. package/dist/lib/channels/providers/desktop.js +1 -1
  216. package/dist/lib/channels/providers/rush.d.ts +2 -1
  217. package/dist/lib/channels/registry.d.ts +1 -1
  218. package/dist/lib/channels/registry.js +1 -1
  219. package/dist/lib/channels/resolve.d.ts +3 -2
  220. package/dist/lib/channels/send.d.ts +5 -4
  221. package/dist/lib/cli-resources.d.ts +3 -9
  222. package/dist/lib/cli-resources.js +4 -2
  223. package/dist/lib/cloud/cursor.d.ts +1 -2
  224. package/dist/lib/cloud/cursor.js +1 -1
  225. package/dist/lib/cloud/dispatch.d.ts +2 -1
  226. package/dist/lib/cloud/dispatch.js +1 -1
  227. package/dist/lib/cloud/factory.d.ts +0 -2
  228. package/dist/lib/cloud/factory.js +1 -1
  229. package/dist/lib/cloud/rush.d.ts +3 -11
  230. package/dist/lib/cloud/rush.js +1 -1
  231. package/dist/lib/cloud/session-index.d.ts +2 -1
  232. package/dist/lib/cloud/types.d.ts +2 -1
  233. package/dist/lib/cloudflare/creds.d.ts +10 -0
  234. package/dist/lib/cloudflare/creds.js +46 -0
  235. package/dist/lib/cloudflare/provision.d.ts +35 -0
  236. package/dist/lib/cloudflare/provision.js +144 -0
  237. package/dist/lib/codex-policy.d.ts +2 -1
  238. package/dist/lib/commands.d.ts +7 -7
  239. package/dist/lib/commands.js +1 -1
  240. package/dist/lib/comms-render.d.ts +1 -1
  241. package/dist/lib/computer/context.d.ts +11 -3
  242. package/dist/lib/computer/context.js +2 -2
  243. package/dist/lib/computer/policy.d.ts +0 -12
  244. package/dist/lib/computer/policy.js +1 -1
  245. package/dist/lib/computer/sessions-list.d.ts +55 -0
  246. package/dist/lib/computer/sessions-list.js +168 -1
  247. package/dist/lib/computer-client.d.ts +3 -3
  248. package/dist/lib/computer-client.js +0 -1
  249. package/dist/lib/concurrency.d.ts +2 -1
  250. package/dist/lib/config-keys.d.ts +16 -3
  251. package/dist/lib/config-keys.js +47 -2
  252. package/dist/lib/convert.d.ts +0 -12
  253. package/dist/lib/convert.js +1 -12
  254. package/dist/lib/crabbox/cli.d.ts +6 -24
  255. package/dist/lib/crabbox/cli.js +2 -28
  256. package/dist/lib/crabbox/lease.d.ts +5 -6
  257. package/dist/lib/crabbox/lease.js +1 -1
  258. package/dist/lib/crabbox/progress.d.ts +2 -1
  259. package/dist/lib/crabbox/setup-copy.d.ts +2 -3
  260. package/dist/lib/crabbox/setup-copy.js +1 -1
  261. package/dist/lib/daemon/account-state-daemon-service.d.ts +1 -1
  262. package/dist/lib/daemon/attention-notify-service.d.ts +2 -1
  263. package/dist/lib/daemon/catchup-service.d.ts +2 -1
  264. package/dist/lib/daemon/daemon.d.ts +4 -4
  265. package/dist/lib/daemon/daemon.js +9 -2
  266. package/dist/lib/daemon/feed-stream-service.d.ts +23 -0
  267. package/dist/lib/daemon/feed-stream-service.js +40 -0
  268. package/dist/lib/daemon/harness-update-service.d.ts +2 -19
  269. package/dist/lib/daemon/harness-update-service.js +3 -3
  270. package/dist/lib/daemon/runner.d.ts +3 -3
  271. package/dist/lib/daemon/self-update-service.d.ts +1 -16
  272. package/dist/lib/daemon/self-update-service.js +6 -6
  273. package/dist/lib/daemon/state-dir-check-service.d.ts +2 -1
  274. package/dist/lib/daemon/supervisor.d.ts +3 -2
  275. package/dist/lib/daemon-services.d.ts +3 -2
  276. package/dist/lib/daemon-services.js +5 -0
  277. package/dist/lib/daemon-webhooks.d.ts +1 -1
  278. package/dist/lib/deeplink/register.d.ts +3 -13
  279. package/dist/lib/deeplink/register.js +3 -3
  280. package/dist/lib/deeplink/url.d.ts +3 -2
  281. package/dist/lib/device-config.d.ts +4 -15
  282. package/dist/lib/device-config.js +164 -8
  283. package/dist/lib/devices/connect.d.ts +51 -6
  284. package/dist/lib/devices/connect.js +169 -21
  285. package/dist/lib/devices/discovery-policy.d.ts +3 -2
  286. package/dist/lib/devices/doctor-findings.js +1 -1
  287. package/dist/lib/devices/doctor-overview-cache.d.ts +3 -2
  288. package/dist/lib/devices/fleet-divergence.d.ts +2 -1
  289. package/dist/lib/devices/fleet.d.ts +3 -4
  290. package/dist/lib/devices/fleet.js +1 -1
  291. package/dist/lib/devices/harness-inventory.d.ts +3 -2
  292. package/dist/lib/devices/health-report.d.ts +3 -2
  293. package/dist/lib/devices/health.d.ts +1 -8
  294. package/dist/lib/devices/health.js +1 -1
  295. package/dist/lib/devices/interactive-host.d.ts +0 -2
  296. package/dist/lib/devices/interactive-host.js +1 -1
  297. package/dist/lib/devices/known-hosts.d.ts +2 -20
  298. package/dist/lib/devices/known-hosts.js +2 -2
  299. package/dist/lib/devices/pool.d.ts +2 -1
  300. package/dist/lib/devices/resolve-target.d.ts +2 -2
  301. package/dist/lib/devices/rollout-verify.d.ts +3 -2
  302. package/dist/lib/devices/stats-cache.d.ts +3 -2
  303. package/dist/lib/devices/sync.d.ts +6 -5
  304. package/dist/lib/devices/worker-pick.d.ts +3 -12
  305. package/dist/lib/devices/worker-pick.js +1 -1
  306. package/dist/lib/diff-text.d.ts +2 -1
  307. package/dist/lib/doctor-diff.d.ts +2 -1
  308. package/dist/lib/drift-sync.d.ts +3 -2
  309. package/dist/lib/drift.d.ts +3 -3
  310. package/dist/lib/drift.js +1 -1
  311. package/dist/lib/event-families.d.ts +0 -6
  312. package/dist/lib/event-families.js +3 -3
  313. package/dist/lib/event-provenance.d.ts +2 -1
  314. package/dist/lib/events-ingest.d.ts +4 -3
  315. package/dist/lib/exec-account-home.d.ts +2 -4
  316. package/dist/lib/exec-account-home.js +1 -1
  317. package/dist/lib/exec-bounded.d.ts +3 -4
  318. package/dist/lib/exec-bounded.js +1 -1
  319. package/dist/lib/exec.d.ts +6 -18
  320. package/dist/lib/exec.js +1 -1
  321. package/dist/lib/factory/snapshot.d.ts +2 -2
  322. package/dist/lib/factory/snapshot.js +1 -1
  323. package/dist/lib/feed/activity-stream.d.ts +2 -5
  324. package/dist/lib/feed/activity-stream.js +2 -2
  325. package/dist/lib/feed/activity.d.ts +8 -33
  326. package/dist/lib/feed/activity.js +8 -8
  327. package/dist/lib/feed/answer.d.ts +3 -2
  328. package/dist/lib/feed/attention.js +5 -1
  329. package/dist/lib/feed/envelope.d.ts +79 -0
  330. package/dist/lib/feed/envelope.js +23 -0
  331. package/dist/lib/feed/events.d.ts +8 -47
  332. package/dist/lib/feed/events.js +9 -141
  333. package/dist/lib/feed/feed.d.ts +9 -42
  334. package/dist/lib/feed/feed.js +1 -60
  335. package/dist/lib/feed/hub-server.d.ts +86 -0
  336. package/dist/lib/feed/hub-server.js +334 -0
  337. package/dist/lib/feed/hub.d.ts +95 -0
  338. package/dist/lib/feed/hub.js +255 -0
  339. package/dist/lib/feed/pr-status.d.ts +0 -2
  340. package/dist/lib/feed/pr-status.js +1 -5
  341. package/dist/lib/feed/tool-activity.d.ts +108 -0
  342. package/dist/lib/feed/tool-activity.js +313 -0
  343. package/dist/lib/feed/tools.d.ts +198 -0
  344. package/dist/lib/feed/tools.js +265 -0
  345. package/dist/lib/feed/watch.d.ts +51 -52
  346. package/dist/lib/feed/watch.js +147 -17
  347. package/dist/lib/feed-broadcast.d.ts +5 -47
  348. package/dist/lib/feed-broadcast.js +9 -9
  349. package/dist/lib/feed-outcome.d.ts +3 -6
  350. package/dist/lib/feed-outcome.js +2 -2
  351. package/dist/lib/feed-policy.d.ts +5 -6
  352. package/dist/lib/feed-policy.js +2 -2
  353. package/dist/lib/feed-post.d.ts +3 -4
  354. package/dist/lib/feed-post.js +1 -1
  355. package/dist/lib/feed-ranking.d.ts +2 -2
  356. package/dist/lib/feed-ranking.js +1 -1
  357. package/dist/lib/fleet/apply.d.ts +5 -6
  358. package/dist/lib/fleet/apply.js +4 -4
  359. package/dist/lib/fleet/manifest.d.ts +2 -1
  360. package/dist/lib/fleet/remote-login.d.ts +18 -36
  361. package/dist/lib/fleet/remote-login.js +20 -19
  362. package/dist/lib/fleet/types.d.ts +0 -8
  363. package/dist/lib/fleet-cache.d.ts +1 -18
  364. package/dist/lib/fleet-cache.js +0 -5
  365. package/dist/lib/fleet-shared-repo-sync.d.ts +3 -3
  366. package/dist/lib/fleet-shared-repo-sync.js +1 -1
  367. package/dist/lib/fleet-shared-state.d.ts +3 -2
  368. package/dist/lib/format.d.ts +3 -2
  369. package/dist/lib/format.js +1 -1
  370. package/dist/lib/friction-heuristics.d.ts +2 -1
  371. package/dist/lib/fs-walk.d.ts +2 -1
  372. package/dist/lib/fuzzy.d.ts +2 -1
  373. package/dist/lib/gemini-settings.d.ts +0 -1
  374. package/dist/lib/gemini-settings.js +1 -1
  375. package/dist/lib/git.d.ts +7 -81
  376. package/dist/lib/git.js +2 -199
  377. package/dist/lib/github/gh-overload.d.ts +0 -4
  378. package/dist/lib/github/gh-overload.js +2 -2
  379. package/dist/lib/github/project-prs.d.ts +118 -0
  380. package/dist/lib/github/project-prs.js +173 -0
  381. package/dist/lib/github/rest.d.ts +2 -1
  382. package/dist/lib/harness/exec-config-version.d.ts +2 -1
  383. package/dist/lib/harness-auth-capabilities.d.ts +5 -4
  384. package/dist/lib/harness-connection-test.d.ts +2 -1
  385. package/dist/lib/heal.d.ts +3 -20
  386. package/dist/lib/heal.js +2 -39
  387. package/dist/lib/help.d.ts +3 -2
  388. package/dist/lib/helper-download.d.ts +0 -12
  389. package/dist/lib/helper-download.js +2 -2
  390. package/dist/lib/helper-versions.d.ts +2 -1
  391. package/dist/lib/helper-versions.js +1 -1
  392. package/dist/lib/hooks/install.d.ts +8 -49
  393. package/dist/lib/hooks/install.js +2 -96
  394. package/dist/lib/hooks/match.d.ts +2 -1
  395. package/dist/lib/hosts/credential-transport.d.ts +0 -2
  396. package/dist/lib/hosts/credential-transport.js +1 -1
  397. package/dist/lib/hosts/dispatch.d.ts +2 -24
  398. package/dist/lib/hosts/dispatch.js +2 -2
  399. package/dist/lib/hosts/logs.d.ts +2 -1
  400. package/dist/lib/hosts/passthrough.d.ts +1 -1
  401. package/dist/lib/hosts/passthrough.js +0 -1
  402. package/dist/lib/hosts/progress.d.ts +0 -5
  403. package/dist/lib/hosts/progress.js +1 -1
  404. package/dist/lib/hosts/ready.d.ts +3 -4
  405. package/dist/lib/hosts/ready.js +0 -8
  406. package/dist/lib/hosts/reconcile.d.ts +2 -8
  407. package/dist/lib/hosts/reconcile.js +1 -1
  408. package/dist/lib/hosts/reconnect.d.ts +4 -11
  409. package/dist/lib/hosts/reconnect.js +2 -2
  410. package/dist/lib/hosts/registry.d.ts +1 -1
  411. package/dist/lib/hosts/remote-cmd.d.ts +55 -4
  412. package/dist/lib/hosts/remote-cmd.js +125 -8
  413. package/dist/lib/hosts/remote-cmd.test-fixture.d.ts +2 -0
  414. package/dist/lib/hosts/remote-cmd.test-fixture.js +22 -0
  415. package/dist/lib/hosts/session-index.d.ts +3 -2
  416. package/dist/lib/hosts/ssh-config.d.ts +2 -3
  417. package/dist/lib/hosts/ssh-config.js +0 -10
  418. package/dist/lib/humans.d.ts +0 -2
  419. package/dist/lib/humans.js +2 -2
  420. package/dist/lib/import.d.ts +4 -3
  421. package/dist/lib/installations/installation-lock.d.ts +0 -2
  422. package/dist/lib/installations/installation-lock.js +2 -2
  423. package/dist/lib/installations/launch-gate.d.ts +0 -9
  424. package/dist/lib/installations/launch-gate.js +1 -1
  425. package/dist/lib/installations/migrate.d.ts +0 -11
  426. package/dist/lib/installations/migrate.js +1 -1
  427. package/dist/lib/installations/shims.d.ts +1 -1
  428. package/dist/lib/installations/shims.js +2 -2
  429. package/dist/lib/installations/update-runtime.js +1 -1
  430. package/dist/lib/linear-cache.d.ts +2 -1
  431. package/dist/lib/linux-userns.d.ts +2 -3
  432. package/dist/lib/linux-userns.js +0 -4
  433. package/dist/lib/loop.d.ts +2 -1
  434. package/dist/lib/mailbox-gc.d.ts +2 -1
  435. package/dist/lib/mailbox-target.d.ts +2 -1
  436. package/dist/lib/mailbox.d.ts +0 -6
  437. package/dist/lib/mailbox.js +1 -1
  438. package/dist/lib/manifest.d.ts +0 -14
  439. package/dist/lib/manifest.js +2 -2
  440. package/dist/lib/mcp-registry.d.ts +2 -1
  441. package/dist/lib/mcp.js +17 -11
  442. package/dist/lib/memory.d.ts +2 -13
  443. package/dist/lib/memory.js +4 -4
  444. package/dist/lib/menubar/download-menubar.d.ts +0 -2
  445. package/dist/lib/menubar/download-menubar.js +1 -5
  446. package/dist/lib/menubar/install-menubar.d.ts +3 -14
  447. package/dist/lib/menubar/install-menubar.js +3 -3
  448. package/dist/lib/menubar/migrate-prefs.d.ts +53 -0
  449. package/dist/lib/menubar/migrate-prefs.js +168 -0
  450. package/dist/lib/menubar/resolve-version.d.ts +1 -9
  451. package/dist/lib/menubar/resolve-version.js +4 -4
  452. package/dist/lib/menubar/snapshot.d.ts +24 -2
  453. package/dist/lib/menubar/snapshot.js +26 -0
  454. package/dist/lib/model-tier-overrides.d.ts +3 -2
  455. package/dist/lib/monitors/config.d.ts +0 -2
  456. package/dist/lib/monitors/config.js +0 -4
  457. package/dist/lib/monitors/engine.d.ts +1 -1
  458. package/dist/lib/monitors/remote.d.ts +3 -2
  459. package/dist/lib/monitors/sources/webhook.d.ts +2 -15
  460. package/dist/lib/monitors/sources/webhook.js +1 -38
  461. package/dist/lib/monitors/state.d.ts +4 -7
  462. package/dist/lib/monitors/state.js +2 -2
  463. package/dist/lib/notify.d.ts +1 -1
  464. package/dist/lib/notify.js +1 -1
  465. package/dist/lib/onepassword.d.ts +5 -14
  466. package/dist/lib/onepassword.js +0 -64
  467. package/dist/lib/open-url.d.ts +3 -2
  468. package/dist/lib/openclaw-keychain.d.ts +4 -17
  469. package/dist/lib/openclaw-keychain.js +3 -33
  470. package/dist/lib/operator.d.ts +2 -2
  471. package/dist/lib/operator.js +1 -1
  472. package/dist/lib/output/git-output.d.ts +4 -14
  473. package/dist/lib/output/git-output.js +1 -1
  474. package/dist/lib/owner-message.d.ts +3 -29
  475. package/dist/lib/owner-message.js +3 -3
  476. package/dist/lib/packages/output-home.d.ts +2 -4
  477. package/dist/lib/packages/output-home.js +2 -2
  478. package/dist/lib/perf/db.d.ts +0 -2
  479. package/dist/lib/perf/db.js +2 -7
  480. package/dist/lib/permissions-registry.d.ts +2 -3
  481. package/dist/lib/permissions-registry.js +0 -4
  482. package/dist/lib/permissions.d.ts +6 -16
  483. package/dist/lib/permissions.js +2 -15
  484. package/dist/lib/picker.d.ts +6 -5
  485. package/dist/lib/placement.d.ts +3 -6
  486. package/dist/lib/placement.js +0 -17
  487. package/dist/lib/platform/posixpath.d.ts +2 -1
  488. package/dist/lib/platform/winpath.d.ts +2 -1
  489. package/dist/lib/plugins/plugin-marketplace.d.ts +2 -2
  490. package/dist/lib/plugins/plugin-marketplace.js +1 -1
  491. package/dist/lib/pr-land-detach.d.ts +2 -1
  492. package/dist/lib/probe.d.ts +4 -1
  493. package/dist/lib/probe.js +5 -2
  494. package/dist/lib/profiles-presets.d.ts +2 -1
  495. package/dist/lib/profiles.d.ts +3 -9
  496. package/dist/lib/profiles.js +1 -9
  497. package/dist/lib/project-doctor.d.ts +2 -1
  498. package/dist/lib/project-launch.d.ts +2 -2
  499. package/dist/lib/project-probe.d.ts +4 -3
  500. package/dist/lib/project-pull.d.ts +2 -1
  501. package/dist/lib/project-resources.d.ts +2 -2
  502. package/dist/lib/project-resources.js +1 -1
  503. package/dist/lib/project-root.d.ts +2 -6
  504. package/dist/lib/project-root.js +1 -1
  505. package/dist/lib/project-schedule.d.ts +2 -1
  506. package/dist/lib/project-status.d.ts +2 -16
  507. package/dist/lib/project-status.js +3 -3
  508. package/dist/lib/pwsh.d.ts +33 -0
  509. package/dist/lib/pwsh.js +56 -0
  510. package/dist/lib/reconcile-and-repair.d.ts +5 -4
  511. package/dist/lib/redact.d.ts +15 -1
  512. package/dist/lib/redact.js +105 -3
  513. package/dist/lib/refresh-coordinator.d.ts +2 -1
  514. package/dist/lib/refresh.d.ts +9 -4
  515. package/dist/lib/refresh.js +92 -72
  516. package/dist/lib/remote-agents-json.d.ts +3 -2
  517. package/dist/lib/reserved-stores.d.ts +0 -2
  518. package/dist/lib/reserved-stores.js +3 -5
  519. package/dist/lib/resource-content-diff.d.ts +0 -2
  520. package/dist/lib/resource-content-diff.js +1 -1
  521. package/dist/lib/resource-patterns.d.ts +2 -1
  522. package/dist/lib/resource-profiles.d.ts +2 -8
  523. package/dist/lib/resource-profiles.js +3 -27
  524. package/dist/lib/resources/workflows.d.ts +1 -1
  525. package/dist/lib/resources.d.ts +4 -9
  526. package/dist/lib/resources.js +1 -1
  527. package/dist/lib/routine-context.d.ts +2 -5
  528. package/dist/lib/routine-context.js +2 -2
  529. package/dist/lib/routine-notify-owner.d.ts +8 -7
  530. package/dist/lib/routine-notify-owner.js +5 -5
  531. package/dist/lib/routine-process-cleanup.d.ts +2 -1
  532. package/dist/lib/routine-readiness.d.ts +0 -2
  533. package/dist/lib/routine-readiness.js +0 -7
  534. package/dist/lib/routines-project.d.ts +3 -4
  535. package/dist/lib/routines-project.js +1 -1
  536. package/dist/lib/rules/compile.d.ts +3 -25
  537. package/dist/lib/rules/compile.js +1 -1
  538. package/dist/lib/rules/compose.d.ts +3 -9
  539. package/dist/lib/rules/rules.d.ts +4 -15
  540. package/dist/lib/rules/rules.js +1 -64
  541. package/dist/lib/run-defaults.d.ts +1 -1
  542. package/dist/lib/run-notify.d.ts +2 -1
  543. package/dist/lib/run-trace-sync.d.ts +1 -1
  544. package/dist/lib/run-trace-sync.js +1 -1
  545. package/dist/lib/scheduler.d.ts +2 -1
  546. package/dist/lib/scheduling/routines.d.ts +9 -21
  547. package/dist/lib/scheduling/routines.js +3 -46
  548. package/dist/lib/secrets-cli.d.ts +11 -0
  549. package/dist/lib/secrets-cli.js +30 -0
  550. package/dist/lib/secrets-client.d.ts +0 -17
  551. package/dist/lib/secrets-client.js +7 -28
  552. package/dist/lib/secrets-policy.d.ts +12 -17
  553. package/dist/lib/secrets-policy.js +5 -5
  554. package/dist/lib/secrets-types.d.ts +3 -2
  555. package/dist/lib/secrets-types.js +2 -1
  556. package/dist/lib/self-heal/checks/install-staging.js +1 -1
  557. package/dist/lib/self-heal/registry.d.ts +3 -2
  558. package/dist/lib/self-heal/types.d.ts +1 -1
  559. package/dist/lib/self-heal/types.js +1 -1
  560. package/dist/lib/self-update.d.ts +5 -5
  561. package/dist/lib/self-update.js +4 -4
  562. package/dist/lib/session/actor-sidecar.d.ts +3 -2
  563. package/dist/lib/session/artifacts.d.ts +0 -2
  564. package/dist/lib/session/artifacts.js +1 -1
  565. package/dist/lib/session/bash-command.d.ts +2 -7
  566. package/dist/lib/session/bundle.d.ts +4 -6
  567. package/dist/lib/session/bundle.js +1 -5
  568. package/dist/lib/session/cloud.d.ts +0 -4
  569. package/dist/lib/session/cloud.js +2 -15
  570. package/dist/lib/session/detached.d.ts +9 -1
  571. package/dist/lib/session/detached.js +31 -2
  572. package/dist/lib/session/digest.d.ts +2 -2
  573. package/dist/lib/session/digest.js +1 -1
  574. package/dist/lib/session/fork.d.ts +3 -2
  575. package/dist/lib/session/highlights.d.ts +6 -5
  576. package/dist/lib/session/hook-sessions.d.ts +2 -1
  577. package/dist/lib/session/host-link.d.ts +2 -1
  578. package/dist/lib/session/inject.d.ts +1 -1
  579. package/dist/lib/session/inject.js +1 -1
  580. package/dist/lib/session/insights.d.ts +3 -15
  581. package/dist/lib/session/insights.js +2 -2
  582. package/dist/lib/session/local-tmux-attach.d.ts +2 -18
  583. package/dist/lib/session/local-tmux-attach.js +1 -1
  584. package/dist/lib/session/migrations.d.ts +0 -1
  585. package/dist/lib/session/migrations.js +1 -1
  586. package/dist/lib/session/mirror.d.ts +5 -8
  587. package/dist/lib/session/mirror.js +2 -2
  588. package/dist/lib/session/parse.d.ts +1 -32
  589. package/dist/lib/session/parse.js +4 -4
  590. package/dist/lib/session/presence.d.ts +2 -1
  591. package/dist/lib/session/prompt.d.ts +3 -2
  592. package/dist/lib/session/prompt.js +38 -1
  593. package/dist/lib/session/recovery.d.ts +3 -2
  594. package/dist/lib/session/remote/peer-stream.d.ts +26 -7
  595. package/dist/lib/session/remote/peer-stream.js +35 -8
  596. package/dist/lib/session/remote/remote-bundle.d.ts +2 -1
  597. package/dist/lib/session/remote/remote-list.d.ts +5 -5
  598. package/dist/lib/session/remote/remote.d.ts +4 -3
  599. package/dist/lib/session/remote/watch.d.ts +2 -7
  600. package/dist/lib/session/remote/watch.js +3 -3
  601. package/dist/lib/session/remote-active.d.ts +2 -1
  602. package/dist/lib/session/render.d.ts +2 -2
  603. package/dist/lib/session/render.js +1 -1
  604. package/dist/lib/session/resume-owner.d.ts +1 -1
  605. package/dist/lib/session/resume-owner.js +1 -1
  606. package/dist/lib/session/run-names.d.ts +2 -1
  607. package/dist/lib/session/session-cache.d.ts +7 -26
  608. package/dist/lib/session/session-cache.js +2 -8
  609. package/dist/lib/session/share-html.d.ts +1 -21
  610. package/dist/lib/session/share-html.js +1 -1
  611. package/dist/lib/session/shell-programs.d.ts +2 -1
  612. package/dist/lib/session/state.d.ts +41 -8
  613. package/dist/lib/session/state.js +112 -11
  614. package/dist/lib/session/stream-render.d.ts +2 -1
  615. package/dist/lib/session/sync/agents.d.ts +0 -4
  616. package/dist/lib/session/sync/agents.js +0 -0
  617. package/dist/lib/session/sync/backend.d.ts +8 -8
  618. package/dist/lib/session/sync/backend.js +3 -3
  619. package/dist/lib/session/sync/managed-config.d.ts +0 -8
  620. package/dist/lib/session/sync/managed-key.d.ts +0 -2
  621. package/dist/lib/session/sync/managed-key.js +1 -1
  622. package/dist/lib/session/sync/provision.d.ts +1 -1
  623. package/dist/lib/session/sync/provision.js +2 -2
  624. package/dist/lib/session/sync/r2.d.ts +4 -1
  625. package/dist/lib/session/sync/r2.js +4 -7
  626. package/dist/lib/session/sync/transcript-crypto.d.ts +2 -1
  627. package/dist/lib/session/tail.d.ts +2 -1
  628. package/dist/lib/session/team-filter.d.ts +1 -1
  629. package/dist/lib/session/throughput.d.ts +2 -3
  630. package/dist/lib/session/throughput.js +1 -1
  631. package/dist/lib/session/timeline-pass.d.ts +3 -42
  632. package/dist/lib/session/timeline-pass.js +4 -4
  633. package/dist/lib/session/timeline.d.ts +3 -13
  634. package/dist/lib/session/timeline.js +3 -3
  635. package/dist/lib/session/tool-calls.d.ts +2 -2
  636. package/dist/lib/session/tool-calls.js +1 -1
  637. package/dist/lib/session/tool-index.d.ts +0 -8
  638. package/dist/lib/session/tool-index.js +2 -2
  639. package/dist/lib/session/tool-store.d.ts +2 -1
  640. package/dist/lib/session/trajectory-compare.d.ts +2 -1
  641. package/dist/lib/session/trajectory-lineage.d.ts +2 -1
  642. package/dist/lib/session/trajectory-text.d.ts +3 -2
  643. package/dist/lib/session/trajectory.d.ts +2 -1
  644. package/dist/lib/session/viewing-in.d.ts +2 -1
  645. package/dist/lib/sessions-client.js +0 -3
  646. package/dist/lib/settings-manifest.d.ts +2 -1
  647. package/dist/lib/setup-tool-install.d.ts +3 -0
  648. package/dist/lib/setup-tool-install.js +26 -0
  649. package/dist/lib/setup-tool-status.d.ts +22 -0
  650. package/dist/lib/setup-tool-status.js +215 -0
  651. package/dist/lib/share-runtime.d.ts +11 -0
  652. package/dist/lib/share-runtime.js +63 -0
  653. package/dist/lib/shim-heal.d.ts +1 -5
  654. package/dist/lib/shim-heal.js +0 -6
  655. package/dist/lib/smart-launch.d.ts +5 -10
  656. package/dist/lib/smart-launch.js +4 -12
  657. package/dist/lib/snapshot.d.ts +3 -2
  658. package/dist/lib/ssh-exec.d.ts +49 -4
  659. package/dist/lib/ssh-exec.js +119 -0
  660. package/dist/lib/ssh-tunnel.d.ts +3 -2
  661. package/dist/lib/staleness/checkers/permissions.d.ts +0 -2
  662. package/dist/lib/staleness/checkers/permissions.js +1 -1
  663. package/dist/lib/staleness/fingerprint.d.ts +0 -7
  664. package/dist/lib/staleness/fingerprint.js +1 -1
  665. package/dist/lib/staleness/prune.d.ts +3 -2
  666. package/dist/lib/staleness/registry.d.ts +1 -1
  667. package/dist/lib/staleness/writers/sources.d.ts +0 -8
  668. package/dist/lib/staleness/writers/sources.js +1 -1
  669. package/dist/lib/startup/command-registry.d.ts +6 -4
  670. package/dist/lib/startup/command-registry.js +11 -8
  671. package/dist/lib/state.d.ts +1 -3
  672. package/dist/lib/state.js +3 -6
  673. package/dist/lib/storage/selection.d.ts +2 -2
  674. package/dist/lib/storage/selection.js +2 -2
  675. package/dist/lib/subagents-registry.d.ts +4 -3
  676. package/dist/lib/subagents.d.ts +2 -1
  677. package/dist/lib/subagents.js +3 -2
  678. package/dist/lib/summarizer/pass.d.ts +3 -6
  679. package/dist/lib/summarizer/pass.js +2 -2
  680. package/dist/lib/summarizer/summarize.d.ts +4 -3
  681. package/dist/lib/sync-passphrase.d.ts +3 -2
  682. package/dist/lib/sync-status.d.ts +3 -16
  683. package/dist/lib/sync-status.js +2 -2
  684. package/dist/lib/sync-umbrella.d.ts +9 -3
  685. package/dist/lib/sync-umbrella.js +18 -10
  686. package/dist/lib/system-run-sync.d.ts +2 -1
  687. package/dist/lib/teams/agents.d.ts +2 -4
  688. package/dist/lib/teams/agents.js +1 -1
  689. package/dist/lib/teams/forEach.d.ts +3 -2
  690. package/dist/lib/teams/pr-watch.d.ts +4 -11
  691. package/dist/lib/teams/pr-watch.js +4 -4
  692. package/dist/lib/teams/registry.d.ts +2 -3
  693. package/dist/lib/teams/registry.js +1 -1
  694. package/dist/lib/teams/remoteWorktree.d.ts +0 -16
  695. package/dist/lib/teams/remoteWorktree.js +3 -3
  696. package/dist/lib/teams/scheduler.d.ts +6 -5
  697. package/dist/lib/teams/scheduler.js +1 -1
  698. package/dist/lib/teams/supervisor.d.ts +4 -3
  699. package/dist/lib/teams/worktree.d.ts +0 -9
  700. package/dist/lib/teams/worktree.js +0 -32
  701. package/dist/lib/term-client.d.ts +44 -0
  702. package/dist/lib/term-client.js +117 -0
  703. package/dist/lib/terminal/inject.d.ts +3 -16
  704. package/dist/lib/terminal/inject.js +1 -29
  705. package/dist/lib/terminal/resolve.d.ts +3 -9
  706. package/dist/lib/terminal/resolve.js +3 -7
  707. package/dist/lib/tmux/binary.d.ts +2 -1
  708. package/dist/lib/tmux/orphan-reap.d.ts +6 -7
  709. package/dist/lib/tmux/orphan-reap.js +1 -1
  710. package/dist/lib/tmux/session.d.ts +4 -3
  711. package/dist/lib/traces/backend.d.ts +1 -2
  712. package/dist/lib/traces/backend.js +1 -2
  713. package/dist/lib/traces/classify.d.ts +3 -2
  714. package/dist/lib/traces/config.d.ts +0 -8
  715. package/dist/lib/traces/insights.d.ts +2 -1
  716. package/dist/lib/traces/phenotype.d.ts +3 -3
  717. package/dist/lib/traces/provision.d.ts +2 -4
  718. package/dist/lib/traces/provision.js +3 -3
  719. package/dist/lib/traces/schema2-build.d.ts +1 -1
  720. package/dist/lib/traces/schema2-danger.d.ts +2 -1
  721. package/dist/lib/traces/schema2.d.ts +5 -4
  722. package/dist/lib/traces/segments.d.ts +4 -20
  723. package/dist/lib/traces/segments.js +3 -3
  724. package/dist/lib/traces/sync.d.ts +2 -3
  725. package/dist/lib/traces/sync.js +1 -1
  726. package/dist/lib/triggers/handlers.d.ts +4 -13
  727. package/dist/lib/triggers/handlers.js +1 -1
  728. package/dist/lib/triggers/webhook.d.ts +5 -27
  729. package/dist/lib/triggers/webhook.js +4 -4
  730. package/dist/lib/types.d.ts +11 -9
  731. package/dist/lib/usage-refresh.d.ts +4 -10
  732. package/dist/lib/usage-refresh.js +3 -8
  733. package/dist/lib/verbs.d.ts +2 -1
  734. package/dist/lib/version-duplicates.d.ts +2 -3
  735. package/dist/lib/version-duplicates.js +3 -33
  736. package/dist/lib/version.d.ts +2 -1
  737. package/dist/lib/warn-unpushed.d.ts +2 -1
  738. package/dist/lib/watchdog/history.d.ts +3 -2
  739. package/dist/lib/watchdog/log.d.ts +0 -6
  740. package/dist/lib/watchdog/log.js +1 -1
  741. package/dist/lib/watchdog/rotate.d.ts +2 -26
  742. package/dist/lib/watchdog/rotate.js +4 -12
  743. package/dist/lib/watchdog/runner.d.ts +0 -7
  744. package/dist/lib/watchdog/runner.js +4 -4
  745. package/dist/lib/watchdog/service.d.ts +2 -2
  746. package/dist/lib/watchdog/service.js +1 -1
  747. package/dist/lib/watchdog/watchdog-agent.d.ts +2 -1
  748. package/dist/lib/watchdog/watchdog.d.ts +2 -1
  749. package/dist/lib/watchdog/watchdogTail.d.ts +2 -1
  750. package/dist/lib/workflows-registry.d.ts +3 -2
  751. package/dist/lib/workflows.d.ts +4 -7
  752. package/dist/lib/workflows.js +1 -1
  753. package/dist/lib/worktree/held.d.ts +4 -28
  754. package/dist/lib/worktree/held.js +3 -3
  755. package/package.json +3 -5
  756. package/scripts/postinstall.js +5 -4
  757. package/dist/commands/artifacts-setup.d.ts +0 -53
  758. package/dist/commands/artifacts-setup.js +0 -161
  759. package/dist/commands/artifacts.d.ts +0 -18
  760. package/dist/commands/artifacts.js +0 -58
  761. package/dist/commands/attach.d.ts +0 -12
  762. package/dist/commands/attach.js +0 -86
  763. package/dist/commands/auth-mint.d.ts +0 -12
  764. package/dist/commands/auth-mint.js +0 -108
  765. package/dist/commands/pty.d.ts +0 -20
  766. package/dist/commands/pty.js +0 -404
  767. package/dist/commands/reconnect.d.ts +0 -46
  768. package/dist/commands/reconnect.js +0 -115
  769. package/dist/commands/share.d.ts +0 -293
  770. package/dist/commands/share.js +0 -1424
  771. package/dist/lib/config-machine-keys.d.ts +0 -14
  772. package/dist/lib/config-machine-keys.js +0 -21
  773. package/dist/lib/pty-client.d.ts +0 -49
  774. package/dist/lib/pty-client.js +0 -315
  775. package/dist/lib/pty-server.d.ts +0 -59
  776. package/dist/lib/pty-server.js +0 -653
  777. package/dist/lib/share/analytics.d.ts +0 -13
  778. package/dist/lib/share/analytics.js +0 -45
  779. package/dist/lib/share/backend.d.ts +0 -120
  780. package/dist/lib/share/backend.js +0 -176
  781. package/dist/lib/share/capture.d.ts +0 -31
  782. package/dist/lib/share/capture.js +0 -174
  783. package/dist/lib/share/config.d.ts +0 -72
  784. package/dist/lib/share/config.js +0 -211
  785. package/dist/lib/share/delete.d.ts +0 -122
  786. package/dist/lib/share/delete.js +0 -173
  787. package/dist/lib/share/html.d.ts +0 -22
  788. package/dist/lib/share/html.js +0 -88
  789. package/dist/lib/share/http-error.d.ts +0 -52
  790. package/dist/lib/share/http-error.js +0 -65
  791. package/dist/lib/share/og.d.ts +0 -25
  792. package/dist/lib/share/og.js +0 -84
  793. package/dist/lib/share/provision.d.ts +0 -127
  794. package/dist/lib/share/provision.js +0 -285
  795. package/dist/lib/share/publish.d.ts +0 -388
  796. package/dist/lib/share/publish.js +0 -818
  797. package/dist/lib/share/worker-template.d.ts +0 -27
  798. package/dist/lib/share/worker-template.js +0 -2424
  799. package/dist/lib/storage/index.d.ts +0 -14
  800. package/dist/lib/storage/index.js +0 -14
  801. package/dist/lib/storage/visibility.d.ts +0 -82
  802. package/dist/lib/storage/visibility.js +0 -99
@@ -1,1424 +0,0 @@
1
- // `agents artifacts share` — publish an HTML file to a shareable link. Signed-in
2
- // users hit the managed endpoint (share.getrush.ai) with the Phoenix bearer;
3
- // otherwise the existing BYO Cloudflare R2 + Worker path. See cli/docs/observability.md.
4
- //
5
- // Registered under the `artifacts` group by commands/artifacts.ts; the
6
- // provisioning door lives beside it at `agents artifacts setup`
7
- // (commands/artifacts-setup.ts), which calls `runShareProvision` below.
8
- import { existsSync } from 'node:fs';
9
- import { formatBytes } from '../lib/format.js';
10
- import { Argument, Option } from 'commander';
11
- import chalk from 'chalk';
12
- import { DEFAULT_BUCKET_NAME, DEFAULT_CF_BUNDLE, DEFAULT_SHARE_DOMAIN, DEFAULT_WORKER_NAME, generateWriteToken, readCloudflareCreds, readShareConfig, readWriteToken, readWriteTokenEnv, readWriteTokenFromBundle, storeWriteToken, writeShareConfig, } from '../lib/share/config.js';
13
- import { addCustomDomain, configureBucketLifecycle, createBucket, deployWorker, enableWorkersDev, findZoneId, hashWorkerScript, putWorkerSecret, updateWorker, WORKER_PHOENIX_ID_BASE_SECRET, WORKER_COLLAB_BASE_SECRET, WORKER_COLLAB_SERVICE_TOKEN_SECRET, setWorkerSecret, } from '../lib/share/provision.js';
14
- import { publishFile, resolveShareUsername, parseMetaEntries, sanitizeLabel, scanShareContent, formatSensitiveContentError, unlistedNotPrivateWarning, SHARE_VISIBILITY_LEVELS, PUBLISH_VISIBILITY_LEVELS, } from '../lib/share/publish.js';
15
- import { deleteShare, resolveDeleteTarget } from '../lib/share/delete.js';
16
- import { renderWorkerBundle } from '../lib/share/worker-template.js';
17
- import { analyticsEnabled } from '../lib/share/analytics.js';
18
- import { extractShareHttpError, formatShareHttpErrorDetail } from '../lib/share/http-error.js';
19
- import { collabConfigForDeploy, phoenixIdBaseForDeploy, resolveShareBackend, shouldUseManaged, } from '../lib/share/backend.js';
20
- import { publishVisibility } from '../lib/storage/visibility.js';
21
- import { resolveGitHubUsername } from '../lib/git.js';
22
- import { refreshSessionAvatar } from '../lib/identity/index.js';
23
- import { setHelpSections } from '../lib/help.js';
24
- import { showUrl } from '../lib/open-url.js';
25
- export function formatSharePublishResult(result, json = false) {
26
- if (json)
27
- return JSON.stringify(result, null, 2);
28
- const lines = [chalk.green(result.url)];
29
- if (result.slug)
30
- lines.push(chalk.dim(` slug: ${result.slug}`));
31
- if (result.label) {
32
- const hint = result.labelSource === 'derived' ? chalk.dim(' (derived — pass --label to set one)') : '';
33
- lines.push(chalk.dim(` "${result.label}"`) + hint);
34
- }
35
- if (result.coverUrl)
36
- lines.push(chalk.dim(` cover ${result.coverUrl}`));
37
- if (result.expiresAt)
38
- lines.push(chalk.dim(` expires ${new Date(result.expiresAt).toLocaleString()}`));
39
- else
40
- lines.push(chalk.dim(' expires never'));
41
- const visibility = result.visibility ?? (result.unlisted ? 'unlisted' : 'public');
42
- if (visibility === 'unlisted') {
43
- lines.push(chalk.dim(' visibility: unlisted (noindex, hidden from gallery — NOT authenticated)'));
44
- }
45
- else if (visibility === 'private') {
46
- lines.push(chalk.dim(' visibility: private (token-gated — 404 without the key; hidden from gallery)'));
47
- lines.push(chalk.yellow(' the key is in the URL above (?k=…) — treat the whole link as a secret'));
48
- }
49
- else if (visibility === 'me' || visibility === 'org') {
50
- lines.push(chalk.dim(` visibility: ${visibility} (login required, hidden from gallery)`));
51
- }
52
- else {
53
- lines.push(chalk.dim(` visibility: ${visibility}`));
54
- }
55
- return lines.join('\n');
56
- }
57
- /** Compare the configured endpoint's last-deployed template hash against the
58
- * hash of the CURRENT `worker-template.ts` render. A config with no recorded
59
- * hash (every endpoint provisioned before this field existed) is "unknown" —
60
- * never "current" or "outdated", since there is nothing to compare against. */
61
- export function shareTemplateStatus(cfg) {
62
- if (!cfg.templateHash)
63
- return 'unknown';
64
- return cfg.templateHash === hashWorkerScript(renderWorkerBundle().script) ? 'current' : 'outdated';
65
- }
66
- export async function runShareEdit(target, opts) {
67
- // Token-gated `private` can't be set in place: the metadata-edit route carries
68
- // no viewer token, so re-stamping visibility=private alone would leave the page
69
- // gated by a hash that doesn't exist — inaccessible to everyone (PHNX-3654).
70
- // Fail loud pointing at the publish path, which mints the key.
71
- if (opts.visibility === 'private') {
72
- throw new Error("Can't change a page to 'private' in place — a token-gated link needs a fresh viewer key. " +
73
- "Re-publish it with 'agents artifacts share <file> --protected' instead.");
74
- }
75
- // Same public-listing gate as publish: label + every metadata value are
76
- // world-readable in the gallery and `share list --list-json`.
77
- if (opts.force !== true) {
78
- const hits = [
79
- ...(typeof opts.label === 'string' ? scanShareContent(opts.label) : []),
80
- ...Object.values(opts.meta ?? {}).flatMap((value) => scanShareContent(value)),
81
- ];
82
- if (hits.length > 0)
83
- throw new Error(formatSensitiveContentError(hits));
84
- }
85
- const backend = resolveShareBackend({ githubUser: opts.githubUser, config: opts.config, writeToken: opts.writeToken, byo: opts.byo, session: opts.session });
86
- // me/org are Phoenix-only — surface a crisp login hint here rather than the
87
- // Worker's generic 400 for a signed-out caller (BYO WRITE_TOKEN can only set
88
- // public/unlisted).
89
- if ((opts.visibility === 'me' || opts.visibility === 'org') && backend.kind !== 'managed') {
90
- throw new Error(`Changing visibility to '${opts.visibility}' requires a Phoenix session. Run 'agents auth login'.`);
91
- }
92
- const { key } = await resolveDeleteTarget(target, { githubUser: backend.kind === 'managed' ? backend.namespace : opts.githubUser || backend.namespace });
93
- const res = await (opts.fetchEdit ?? fetch)(`${backend.baseUrl.replace(/\/+$/, '')}/${key}`, {
94
- method: 'PATCH',
95
- headers: { authorization: `Bearer ${backend.token}`, 'content-type': 'application/json' },
96
- body: JSON.stringify({
97
- ...(opts.label !== undefined ? { label: opts.label } : {}),
98
- ...(opts.visibility !== undefined ? { visibility: opts.visibility } : {}),
99
- meta: opts.meta ?? {}, metaMode: opts.metaMode ?? 'merge', removeMeta: opts.removeMeta ?? [],
100
- }),
101
- });
102
- const body = await res.text();
103
- if (!res.ok) {
104
- let detail = body;
105
- try {
106
- detail = String(JSON.parse(body).error ?? body);
107
- }
108
- catch { /* keep body */ }
109
- throw new Error(`Share metadata edit failed (${res.status}): ${detail || 'unknown error'}`);
110
- }
111
- const result = JSON.parse(body);
112
- // A Worker template that predates the visibility edit ignores the `visibility`
113
- // field and 200s without echoing it back — which would otherwise report a
114
- // silent success while the page's visibility never changed. Fail loud with the
115
- // update path instead (visibility rode in on RUSH-3135's metadata-edit route).
116
- if (opts.visibility !== undefined && result.visibility === undefined) {
117
- throw new Error("This share endpoint's Worker doesn't support in-place visibility changes yet — it predates them. " +
118
- "Run 'agents artifacts share update' to deploy the current Worker template, then retry " +
119
- "('agents artifacts share status' shows whether an update is due).");
120
- }
121
- return result;
122
- }
123
- /** Shown whenever the deployed Worker has no `?format=json` listing route — an
124
- * endpoint provisioned before this feature. Points at the RUSH-2449 update path
125
- * (`agents artifacts share update`) instead of letting the caller hit a 404 or an
126
- * HTML body and get a confusing parse error. */
127
- const OUTDATED_TEMPLATE_HINT = 'Your deployed share Worker has no machine-readable listing route — it predates `agents artifacts share list`. ' +
128
- 'Run `agents artifacts share update` to deploy the current Worker template, then retry (`agents artifacts share status` shows whether an update is due).';
129
- async function defaultListingFetch(url, headers) {
130
- const res = await fetch(url, { headers: { accept: 'application/json', ...(headers || {}) } });
131
- return { status: res.status, contentType: res.headers.get('content-type') ?? '', body: await res.text() };
132
- }
133
- /** Normalize the Worker's `meta` field (arbitrary `--meta key=value` entries,
134
- * RUSH-2683) into a plain string record — `{}` for a missing/malformed field
135
- * (a deployed Worker that predates it, or a non-object value), never throws. */
136
- function parseMetaField(raw) {
137
- if (!raw || typeof raw !== 'object' || Array.isArray(raw))
138
- return {};
139
- const out = {};
140
- for (const [k, v] of Object.entries(raw)) {
141
- out[k] = String(v);
142
- }
143
- return out;
144
- }
145
- /** Parse the Worker's listing JSON into a validated result, failing loud (with the
146
- * outdated-template hint) on any body that isn't the expected shape — an old Worker
147
- * serves the HTML gallery for a non-empty namespace, which must not be silently
148
- * accepted as "you have published nothing". */
149
- export function parseShareListing(user, body) {
150
- let data;
151
- try {
152
- data = JSON.parse(body);
153
- }
154
- catch {
155
- throw new Error(OUTDATED_TEMPLATE_HINT);
156
- }
157
- const objectsRaw = data?.objects;
158
- if (!data || typeof data !== 'object' || !Array.isArray(objectsRaw)) {
159
- throw new Error(OUTDATED_TEMPLATE_HINT);
160
- }
161
- const objects = objectsRaw.map((o) => {
162
- const item = o;
163
- return {
164
- slug: String(item.slug ?? ''),
165
- url: String(item.url ?? ''),
166
- size: typeof item.size === 'number' ? item.size : 0,
167
- contentType: item.contentType == null ? null : String(item.contentType),
168
- publishedAt: String(item.publishedAt ?? ''),
169
- expiresAt: item.expiresAt == null ? null : String(item.expiresAt),
170
- label: item.label == null ? null : String(item.label),
171
- agent: item.agent == null ? null : String(item.agent),
172
- session: item.session == null ? null : String(item.session),
173
- host: item.host == null ? null : String(item.host),
174
- repo: item.repo == null ? null : String(item.repo),
175
- revisionCount: typeof item.revisionCount === 'number' ? item.revisionCount : 0,
176
- visibility: item.visibility === 'unlisted' ||
177
- item.visibility === 'private' ||
178
- item.visibility === 'me' ||
179
- item.visibility === 'org'
180
- ? item.visibility
181
- : 'public',
182
- meta: parseMetaField(item.meta),
183
- };
184
- });
185
- return { user, count: objects.length, objects };
186
- }
187
- /** Namespace for list/revisions: managed uses the Phoenix handle (email
188
- * local-part); BYO still resolves GitHub username (gh / git config / --for-user). */
189
- async function namespaceForBackend(backend, githubUser) {
190
- if (backend.kind === 'managed')
191
- return backend.namespace;
192
- return resolveShareUsername({ githubUser: githubUser || backend.namespace || undefined });
193
- }
194
- /** Fetch and parse the machine-readable listing of the caller's namespace from the
195
- * Worker's `?format=json` route. Fails loud when share was never configured, when
196
- * the deployed template is known-outdated (RUSH-2449 templateHash), or when the
197
- * live response proves the route is absent (404 or a non-JSON 200 = the old HTML
198
- * gallery) — never a silent empty/wrong result. Signed-in users hit the managed
199
- * endpoint; BYO still uses `readShareConfig()`. */
200
- export async function runShareList(opts = {}) {
201
- const backend = resolveShareBackend({
202
- githubUser: opts.githubUser,
203
- config: opts.config,
204
- writeToken: opts.writeToken,
205
- byo: opts.byo,
206
- session: opts.phoenixSession,
207
- requireToken: false,
208
- });
209
- // Managed: the platform Worker is current; skip the BYO template-hash gate.
210
- // A known-stale BYO template can't have the listing route — say so before any
211
- // network call. 'unknown' (provisioned before templateHash tracking) is
212
- // attempted, then caught by the response checks below if the route is absent.
213
- let templateStatus = 'current';
214
- if (backend.kind === 'byo') {
215
- const cfg = opts.config ?? readShareConfig();
216
- templateStatus = cfg ? shareTemplateStatus(cfg) : 'unknown';
217
- if (templateStatus === 'outdated') {
218
- throw new Error(OUTDATED_TEMPLATE_HINT);
219
- }
220
- }
221
- const user = await namespaceForBackend(backend, opts.githubUser);
222
- const scope = opts.scope ?? 'public';
223
- const includeHidden = scope !== 'public';
224
- const query = new URLSearchParams({ format: 'json' });
225
- if (includeHidden)
226
- query.set('scope', 'mine');
227
- const listUrl = `${backend.baseUrl.replace(/\/+$/, '')}/${encodeURIComponent(user)}?${query.toString()}`;
228
- const listingHeaders = {};
229
- if (includeHidden) {
230
- if (!backend.token) {
231
- throw new Error(`Listing ${scope} shares requires owner authentication. Run 'agents auth login' for the managed endpoint, or ensure SHARE_WRITE_TOKEN / 'agents artifacts share join' is configured for BYO.`);
232
- }
233
- listingHeaders.authorization = `Bearer ${backend.token}`;
234
- }
235
- const fetchListing = opts.fetchListing ?? defaultListingFetch;
236
- const res = await fetchListing(listUrl, listingHeaders);
237
- if (res.status === 404) {
238
- // A single-segment path 404s either because the namespace is genuinely empty
239
- // (current template — the listing route gates on the namespace holding objects,
240
- // so a namespace with nothing falls through to an object GET) OR because the
241
- // endpoint predates the listing route entirely. The recorded templateHash
242
- // disambiguates: a 'current' template HAS the route, so its 404 means an empty
243
- // namespace ("nothing published"); otherwise the route may be absent, so point
244
- // at `agents artifacts share update`. Managed is always 'current'.
245
- if (templateStatus === 'current') {
246
- return { user, count: 0, objects: [] };
247
- }
248
- throw new Error(OUTDATED_TEMPLATE_HINT);
249
- }
250
- if (res.status !== 200) {
251
- const detail = formatShareHttpErrorDetail(extractShareHttpError({ status: res.status, body: res.body }));
252
- throw new Error(`Listing failed (${res.status}) for ${listUrl}${detail}. Check the endpoint is reachable, or that 'agents artifacts setup' / 'agents auth login' completed.`);
253
- }
254
- if (!/application\/json/i.test(res.contentType)) {
255
- // A 200 that isn't JSON means the old Worker ignored ?format=json and served
256
- // the HTML gallery — the deployed template is outdated. Managed never hits
257
- // this (platform Worker is current); fail loud if it somehow does.
258
- if (backend.kind === 'managed') {
259
- throw new Error(`Managed listing at ${listUrl} did not return JSON (${res.contentType || 'no content-type'}).`);
260
- }
261
- throw new Error(OUTDATED_TEMPLATE_HINT);
262
- }
263
- const parsed = parseShareListing(user, res.body);
264
- return applyShareListFilters(parsed, {
265
- agent: opts.agent,
266
- session: opts.session,
267
- label: opts.label,
268
- meta: opts.meta,
269
- scope,
270
- });
271
- }
272
- /** Client-side filtering over an already-fetched listing (RUSH-2683) — the
273
- * Worker has no query surface for this, so it narrows the fetched set instead
274
- * of a second round trip. `count` reflects the FILTERED set, matching what the
275
- * caller actually sees. */
276
- export function applyShareListFilters(result, filters) {
277
- let objects = result.objects;
278
- if (filters.scope && filters.scope !== 'all') {
279
- objects = objects.filter((o) => o.visibility === filters.scope);
280
- }
281
- if (filters.agent) {
282
- const needle = filters.agent.toLowerCase();
283
- objects = objects.filter((o) => (o.agent ?? '').toLowerCase() === needle);
284
- }
285
- if (filters.session) {
286
- objects = objects.filter((o) => o.session === filters.session);
287
- }
288
- if (filters.label) {
289
- const needle = filters.label.toLowerCase();
290
- objects = objects.filter((o) => (o.label ?? '').toLowerCase().includes(needle));
291
- }
292
- if (filters.meta) {
293
- objects = objects.filter((o) => Object.entries(filters.meta).every(([key, value]) => o.meta[key] === value));
294
- }
295
- return { user: result.user, count: objects.length, objects };
296
- }
297
- /** Human-readable bytes, e.g. `1.2 KB`, `640 B`. */
298
- /** Render an arbitrary `--meta` map as `k=v k2=v2` for a human table row, or
299
- * undefined when there's nothing to show (RUSH-2683). */
300
- function formatMetaPairs(meta) {
301
- if (!meta)
302
- return undefined;
303
- const entries = Object.entries(meta);
304
- if (entries.length === 0)
305
- return undefined;
306
- return entries.map(([k, v]) => `${k}=${v}`).join(' ');
307
- }
308
- export function formatShareList(result, json = false) {
309
- if (json)
310
- return JSON.stringify(result, null, 2);
311
- if (result.count === 0) {
312
- return chalk.dim(`No active pages published under @${result.user}.`);
313
- }
314
- const header = chalk.bold(`@${result.user}`) +
315
- chalk.dim(` ${result.count} published ${result.count === 1 ? 'page' : 'pages'}`);
316
- const rows = result.objects.map((o) => {
317
- const when = o.publishedAt ? o.publishedAt.slice(0, 10) : 'unknown';
318
- const visibility = o.visibility ?? 'public';
319
- const visibilityBit = visibility === 'public' ? chalk.green('public') : chalk.yellow(visibility);
320
- const bits = [visibilityBit, when, formatBytes(o.size)];
321
- if (o.agent)
322
- bits.push(o.agent);
323
- if (o.revisionCount > 0)
324
- bits.push(`${o.revisionCount} ${o.revisionCount === 1 ? 'revision' : 'revisions'}`);
325
- if (o.expiresAt)
326
- bits.push(`expires ${o.expiresAt.slice(0, 10)}`);
327
- const metaPairs = formatMetaPairs(o.meta);
328
- if (metaPairs)
329
- bits.push(metaPairs);
330
- const line = bits.join(' · ');
331
- const title = o.label ? `${chalk.bold(o.label)}\n ` : '';
332
- return `${title}${chalk.cyan(o.slug)} ${chalk.dim(line)}\n ${chalk.green(o.url)}`;
333
- });
334
- return [header, ...rows].join('\n');
335
- }
336
- /** Parse the Worker's `?revisions=json` payload, failing loud (with the same
337
- * outdated-template hint as {@link parseShareListing}) on an unexpected shape. */
338
- export function parseShareRevisions(key, body) {
339
- let data;
340
- try {
341
- data = JSON.parse(body);
342
- }
343
- catch {
344
- throw new Error(OUTDATED_TEMPLATE_HINT);
345
- }
346
- const revisionsRaw = data?.revisions;
347
- if (!data || typeof data !== 'object' || !Array.isArray(revisionsRaw)) {
348
- throw new Error(OUTDATED_TEMPLATE_HINT);
349
- }
350
- const revisions = revisionsRaw.map((o) => {
351
- const item = o;
352
- return {
353
- key: String(item.key ?? ''),
354
- url: String(item.url ?? ''),
355
- size: typeof item.size === 'number' ? item.size : 0,
356
- contentType: item.contentType == null ? null : String(item.contentType),
357
- uploadedAt: String(item.uploadedAt ?? ''),
358
- expiresAt: item.expiresAt == null ? null : String(item.expiresAt),
359
- label: item.label == null ? null : String(item.label),
360
- agent: item.agent == null ? null : String(item.agent),
361
- session: item.session == null ? null : String(item.session),
362
- host: item.host == null ? null : String(item.host),
363
- repo: item.repo == null ? null : String(item.repo),
364
- meta: parseMetaField(item.meta),
365
- };
366
- });
367
- return { key, count: revisions.length, revisions };
368
- }
369
- /** Fetch and parse the retained prior versions of one published slug. `target`
370
- * accepts the same three forms as `agents artifacts unshare` (a full URL, `<user>/<slug>`,
371
- * or a bare slug resolved against the caller's own namespace) — reuses
372
- * {@link resolveDeleteTarget} rather than re-deriving the key. */
373
- export async function runShareRevisions(target, opts = {}) {
374
- const backend = resolveShareBackend({
375
- githubUser: opts.githubUser,
376
- config: opts.config,
377
- writeToken: opts.writeToken,
378
- byo: opts.byo,
379
- session: opts.session,
380
- requireToken: false,
381
- });
382
- if (backend.kind === 'byo') {
383
- const cfg = opts.config ?? readShareConfig();
384
- if (cfg && shareTemplateStatus(cfg) === 'outdated') {
385
- throw new Error(OUTDATED_TEMPLATE_HINT);
386
- }
387
- }
388
- const githubUser = backend.kind === 'managed'
389
- ? backend.namespace
390
- : opts.githubUser || backend.namespace || undefined;
391
- const { key } = await resolveDeleteTarget(target, { githubUser });
392
- const revUrl = `${backend.baseUrl.replace(/\/+$/, '')}/${key}?revisions=json`;
393
- const fetchListing = opts.fetchListing ?? defaultListingFetch;
394
- const res = await fetchListing(revUrl);
395
- if (res.status !== 200) {
396
- const detail = formatShareHttpErrorDetail(extractShareHttpError({ status: res.status, body: res.body }));
397
- throw new Error(`Revisions lookup failed (${res.status}) for ${revUrl}${detail}. Check the endpoint is reachable, or that 'agents artifacts setup' / 'agents auth login' completed.`);
398
- }
399
- if (!/application\/json/i.test(res.contentType)) {
400
- if (backend.kind === 'managed') {
401
- throw new Error(`Managed revisions at ${revUrl} did not return JSON (${res.contentType || 'no content-type'}).`);
402
- }
403
- throw new Error(OUTDATED_TEMPLATE_HINT);
404
- }
405
- return parseShareRevisions(key, res.body);
406
- }
407
- /** Mint a one-time login ticket for the signed-in owner and build the URL that
408
- * opens their own published page **as the owner**, so the inline visibility
409
- * control is live in the browser. Managed backend only — the control is gated on
410
- * the Phoenix identity, and BYO (WRITE_TOKEN) endpoints have no per-viewer login.
411
- * `target` accepts the same three forms as `visibility`/`unshare` (a full URL,
412
- * `<user>/<slug>`, or a bare slug in the caller's namespace). */
413
- export async function runShareOpen(target, opts = {}) {
414
- const backend = resolveShareBackend({
415
- githubUser: opts.githubUser,
416
- config: opts.config,
417
- session: opts.session,
418
- requireToken: false,
419
- });
420
- if (backend.kind !== 'managed') {
421
- throw new Error("'agents artifacts share open' needs a managed (Phoenix) endpoint — the page's inline " +
422
- "visibility control is gated on your signed-in identity. Run 'agents auth login' first.");
423
- }
424
- const baseUrl = backend.baseUrl.replace(/\/+$/, '');
425
- const { key } = await resolveDeleteTarget(target, { githubUser: backend.namespace });
426
- const url = `${baseUrl}/${key}`;
427
- const doFetch = opts.fetchTicket ??
428
- (async (u, bearer) => {
429
- const res = await fetch(u, { method: 'POST', headers: { authorization: `Bearer ${bearer}` } });
430
- return { status: res.status, body: await res.text() };
431
- });
432
- const res = await doFetch(`${baseUrl}/__ticket`, backend.token);
433
- if (res.status !== 200) {
434
- throw new Error(`Could not mint a login ticket (${res.status}) from ${baseUrl}/__ticket. ` +
435
- "The endpoint may predate this feature — run 'agents artifacts share update' to redeploy the Worker.");
436
- }
437
- let ticket;
438
- try {
439
- const parsed = JSON.parse(res.body);
440
- if (typeof parsed.ticket !== 'string' || !parsed.ticket)
441
- throw new Error('no ticket in response');
442
- ticket = parsed.ticket;
443
- }
444
- catch {
445
- throw new Error(`Ticket endpoint at ${baseUrl}/__ticket did not return a usable ticket.`);
446
- }
447
- const ownerUrl = `${url}?phoenix_ticket=${encodeURIComponent(ticket)}`;
448
- return { key, url, ownerUrl };
449
- }
450
- export function formatShareRevisions(result, json = false) {
451
- if (json)
452
- return JSON.stringify(result, null, 2);
453
- if (result.count === 0) {
454
- return chalk.dim(`No retained revisions for ${result.key} (only the current version exists).`);
455
- }
456
- const header = chalk.bold(result.key) + chalk.dim(` ${result.count} retained ${result.count === 1 ? 'revision' : 'revisions'}`);
457
- const rows = result.revisions.map((r) => {
458
- const bits = [r.uploadedAt ? r.uploadedAt.slice(0, 10) : 'unknown', formatBytes(r.size)];
459
- if (r.agent)
460
- bits.push(r.agent);
461
- if (r.label)
462
- bits.push(r.label);
463
- const metaPairs = formatMetaPairs(r.meta);
464
- if (metaPairs)
465
- bits.push(metaPairs);
466
- return `${chalk.cyan(r.uploadedAt || r.key)} ${chalk.dim(bits.join(' · '))}\n ${chalk.green(r.url)}`;
467
- });
468
- return [header, ...rows].join('\n');
469
- }
470
- export function formatShareDeleteResult(result, json = false) {
471
- if (json)
472
- return JSON.stringify(result, null, 2);
473
- if (result.skipped)
474
- return chalk.dim(`skipped — ${result.url} was already gone`);
475
- const lines = [chalk.green(`deleted ${result.url}`)];
476
- if (result.cover) {
477
- lines.push(result.cover.existedBefore
478
- ? chalk.dim(` cover deleted ${result.cover.url}`)
479
- : chalk.dim(` cover (none) ${result.cover.url}`));
480
- }
481
- if (result.revisions?.length) {
482
- lines.push(chalk.dim(` ${result.revisions.length} retained ${result.revisions.length === 1 ? 'revision' : 'revisions'} deleted`));
483
- }
484
- return lines.join('\n');
485
- }
486
- /** Human summary of an in-place visibility change. */
487
- function formatShareVisibilityResult(result, requested) {
488
- const now = result.visibility ?? requested;
489
- const from = result.previousVisibility && result.previousVisibility !== now
490
- ? `${chalk.dim(result.previousVisibility)} → `
491
- : '';
492
- return [
493
- `${chalk.green('✓')} visibility ${from}${chalk.bold(now)}`,
494
- chalk.dim(` ${result.url}`),
495
- chalk.dim(' body unchanged — no revision created'),
496
- ].join('\n');
497
- }
498
- /** Shared handler for `agents artifacts share delete <targets...>` and the
499
- * nested `agents artifacts unshare <targets...>` alias. Deletes each target independently and
500
- * continues past a failed one (rm-style), reporting all results and exiting
501
- * non-zero if any target failed to verify as gone.
502
- *
503
- * `deleteFn` is a DI seam for tests (defaults to the real `deleteShare`) — it is
504
- * never exposed as a CLI flag, only used to inject a fake config/checker/deleter
505
- * without touching the keychain or a live endpoint. */
506
- export async function runShareDelete(targets, opts, deleteFn = deleteShare) {
507
- const results = [];
508
- for (const target of targets) {
509
- try {
510
- const result = await deleteFn(target, {
511
- keepCover: opts.keepCover === true,
512
- keepRevisions: opts.keepRevisions === true,
513
- ifExists: opts.ifExists === true,
514
- githubUser: opts.forUser,
515
- });
516
- results.push({ target, result });
517
- if (!opts.deleteJson)
518
- console.log(formatShareDeleteResult(result));
519
- }
520
- catch (e) {
521
- results.push({ target, error: e.message });
522
- if (!opts.deleteJson)
523
- console.error(chalk.red(`${target}: ${e.message}`));
524
- }
525
- }
526
- if (opts.deleteJson) {
527
- console.log(JSON.stringify(results, null, 2));
528
- }
529
- if (results.some((r) => r.error)) {
530
- process.exitCode = 1;
531
- }
532
- }
533
- function registerShareDeleteOptions(cmd) {
534
- return cmd
535
- .option('--keep-cover', 'leave the sibling <slug>.png OG cover in place (default: delete it too)')
536
- .option('--keep-revisions', 'leave retained revisions (<slug>/rev-*) in place (default: delete them too)')
537
- .option('--if-exists', 'treat an already-missing target as a no-op success instead of an error')
538
- // Named --for-user / --delete-json, not --github-user / --json: `share
539
- // <file>` (the parent of the nested `share delete`) already owns both
540
- // those long names, and commander resolves an option's long name against
541
- // the WHOLE ancestor chain — a same-named child option is silently
542
- // dropped at parse time even when it parses alone (RUSH-2687; verified
543
- // with a real program.parseAsync(), see share.test.ts). Matches the
544
- // `revisions` precedent (--for-user/--revisions-json) below, and applies
545
- // equally to the top-level `unshare` alias so both spellings stay
546
- // identical even though `unshare` itself has no ancestor collision.
547
- .option('--for-user <user>', 'GitHub username for resolving a bare-slug target (default: resolved from gh/git config)')
548
- .option('--delete-json', 'emit machine-readable results');
549
- }
550
- const SHARE_DELETE_EXAMPLES = `
551
- # Delete by full URL — also takes down the sibling OG cover and any retained revisions
552
- agents artifacts share delete https://share.getrush.ai/octocat/my-plan-a1b2
553
-
554
- # Delete by <user>/<slug>, or a bare slug in your own namespace
555
- agents artifacts share delete octocat/my-plan-a1b2
556
- agents artifacts unshare my-plan-a1b2
557
-
558
- # Several at once
559
- agents artifacts unshare my-plan-a1b2 old-report-9f3c
560
-
561
- # Keep the cover image up (rare — you usually want both gone)
562
- agents artifacts unshare my-plan-a1b2 --keep-cover
563
-
564
- # Keep retained revisions up too (rare — they're world-readable by URL like the page itself)
565
- agents artifacts unshare my-plan-a1b2 --keep-revisions
566
-
567
- # Don't error if it's already gone
568
- agents artifacts unshare my-plan-a1b2 --if-exists
569
- `;
570
- const SHARE_DELETE_NOTES = `
571
- A follow-up GET is required to resolve 404 before this reports success — the
572
- Worker's DELETE is idempotent and returns {"ok":true} even for a key that was
573
- never there, so that response alone is never proof of a takedown.
574
-
575
- Also deletes any retained revisions of the target (RUSH-2683) — a share that was
576
- republished at least once leaves its prior version(s) live at their own URL until
577
- they're purged too, so leaving them up would defeat the point of taking the page
578
- down. Pass --keep-revisions to leave them (they still expire via the bucket's
579
- lifecycle rule on their own schedule either way).
580
-
581
- agents artifacts share delete === agents artifacts unshare (same command, different name).
582
- `;
583
- const SHARE_VISIBILITY_EXAMPLES = `
584
- # Take a public page private to just you (Phoenix session required for me/org)
585
- agents artifacts share visibility https://share.getrush.ai/octocat/q3-plan me
586
-
587
- # Make it public again — by <user>/<slug> or a bare slug in your namespace
588
- agents artifacts share visibility octocat/q3-plan public
589
- agents artifacts share visibility q3-plan unlisted
590
-
591
- # Share with your Phoenix org (rejected on a public-inbox email domain)
592
- agents artifacts share visibility q3-plan org
593
-
594
- # Machine-readable result
595
- agents artifacts share visibility q3-plan me --visibility-json
596
- `;
597
- const SHARE_VISIBILITY_NOTES = `
598
- Changes an ALREADY-published page's visibility in place: the slug — and so the
599
- URL — is preserved. It re-stamps only the visibility on the stored object; the
600
- body, provenance, label, and --meta are untouched, so — like 'agents artifacts
601
- share edit' — this is a metadata-only rewrite and creates no revision.
602
-
603
- public is listed in the gallery; unlisted is a capability URL (GET still 200,
604
- X-Robots-Tag: noindex, hidden from gallery/list); me is visible only to the
605
- signed-in owner; org is visible to members of the same Phoenix organization.
606
- me and org require a Phoenix session — run 'agents auth login' first — and org
607
- is refused on a public-inbox email domain (gmail.com, outlook.com, …).
608
-
609
- This hits the live endpoint via the owner's Phoenix session (or the BYO
610
- WRITE_TOKEN for public/unlisted). It does not re-run the pre-publish
611
- sensitive-content scan — the body is unchanged.
612
- `;
613
- /**
614
- * Register the `share` subtree under its parent group — `agents artifacts share`
615
- * (see commands/artifacts.ts). `agents artifacts unshare` is the nested alias
616
- * registered via {@link registerUnshareCommand} on the artifacts group.
617
- * registration on the ROOT program, so it is {@link registerUnshareCommand}, not
618
- * part of this subtree.
619
- */
620
- export function registerShareCommands(artifactsCmd) {
621
- const shareCmd = artifactsCmd
622
- .command('share')
623
- // Child task commands intentionally reuse publish vocabulary (`edit --label`,
624
- // `list --meta`). Keep option ownership positional within this subtree so
625
- // Commander does not silently resolve those flags to the parent publisher.
626
- .enablePositionalOptions()
627
- .description('Publish an HTML file to a shareable link — managed if signed in, otherwise your Cloudflare R2.')
628
- .argument('[file]', 'file to publish (HTML or any static asset)')
629
- .option('--slug <slug>', 'URL slug override (default: stable slug of the artifact title, then filename)')
630
- .option('--github-user <user>', 'GitHub username for the share namespace (default: resolved from gh/git config; ignored on the managed endpoint)')
631
- .option('--handle <name>', 'managed only: publish under an alternate public handle instead of the email local-part (default: your email local-part). Escape hatch when your derived handle is taken, or for a vanity namespace — the Worker binds it with the same first-writer claim')
632
- .option('--expire <spec>', "auto-expire (default 30d). e.g. 12h, 30d, 2026-08-01, or 'never'")
633
- .addOption(new Option('--visibility <level>', 'public | unlisted | private | me | org. Default when signed in: me (owner-only, Phoenix-gated); use org for your whole email domain, public to opt into the gallery. unlisted is an UNAUTHENTICATED capability URL; private is token-gated (404 without the key). All but public are hidden from the gallery')
634
- .choices([...PUBLISH_VISIBILITY_LEVELS]))
635
- .addOption(new Option('--protected', 'token-gated link (= --visibility private): the URL carries a secret key and returns 404 without it — the authenticated alternative to --unlisted'))
636
- .addOption(new Option('--unlisted', 'hidden alias of --visibility unlisted (obscurity, NOT authentication)').hideHelp())
637
- .addOption(new Option('--private', 'hidden alias of --visibility unlisted (obscurity, NOT authentication — for real read-auth use --protected)').hideHelp())
638
- .option('--force', 'publish even when the file contains emails or credential-shaped strings')
639
- .option('--no-cover', 'skip the OG preview image (HTML pages get one by default)')
640
- .option('--no-analytics', 'skip injecting the Cloudflare Web Analytics beacon')
641
- .option('--label <text>', 'human display title, shown in the gallery and `share list` (default: derived from the HTML <title>, frontmatter title, or filename)')
642
- .option('--title <text>', 'alias of --label')
643
- .option('--meta <key=value>', 'structured metadata (repeatable), e.g. --meta kind=plan --meta ticket=RUSH-2683. Recommended keys: kind (plan|report|visual|screenshot|recording|deck|doc), project, ticket, status (draft|final). Reserved (set automatically, not settable): agent, session, host, repo, date, label', (val, prev) => [...prev, val], [])
644
- .option('--no-revision', "overwrite an existing slug in place — skip keeping the prior version as a <slug>/rev-<ts> backup (default: keep it, see 'agents artifacts share revisions')")
645
- .option('--json', 'emit machine-readable publish result for plan-render hooks and scripts')
646
- .action(async (file, opts) => {
647
- if (!file) {
648
- shareCmd.help();
649
- return;
650
- }
651
- if (!existsSync(file)) {
652
- console.error(chalk.red(`No such file: ${file}`));
653
- process.exitCode = 1;
654
- return;
655
- }
656
- try {
657
- const meta = parseMetaEntries(opts.meta);
658
- // Private by default: an explicit flag wins; otherwise the backend-aware
659
- // product default — `me` (owner-only) when signed in to Phoenix, `public`
660
- // for a BYO bucket (the Worker refuses `me`/`org` without a Phoenix owner).
661
- // `shouldUseManaged` reads the same session/BYO signals `publishFile` will
662
- // resolve, so the default matches the backend the publish actually uses.
663
- const visibility = publishVisibility({
664
- visibility: opts.visibility,
665
- unlisted: opts.unlisted === true || opts.private === true,
666
- protected: opts.protected === true,
667
- }, shouldUseManaged({}) ? 'managed' : 'byo');
668
- // unlisted (incl. its --private alias) is obscurity, not read-auth — warn
669
- // loudly before the publish so a "private" link is never mistaken for a
670
- // gated one (PHNX-3654). Skipped for --json so machine output stays clean.
671
- if (visibility === 'unlisted' && !opts.json) {
672
- console.error(chalk.yellow(`⚠ ${unlistedNotPrivateWarning()}`));
673
- }
674
- // Managed publish: fill the session's hosted avatar (one /auth/me call,
675
- // no-op when already known) so the attribution bar can show the OAuth
676
- // profile image — sessions written before the CLI tracked avatars only
677
- // carry token/email/userId (PHNX-3547).
678
- if (shouldUseManaged({}))
679
- await refreshSessionAvatar();
680
- const result = await publishFile(file, {
681
- slug: opts.slug,
682
- githubUser: opts.githubUser,
683
- handle: opts.handle,
684
- expire: opts.expire,
685
- visibility,
686
- unlisted: visibility === 'unlisted',
687
- protected: visibility === 'private',
688
- force: opts.force,
689
- cover: opts.cover,
690
- analytics: opts.analytics,
691
- label: opts.label ?? opts.title,
692
- meta,
693
- noRevision: opts.revision === false,
694
- });
695
- console.log(formatSharePublishResult(result, Boolean(opts.json)));
696
- }
697
- catch (e) {
698
- console.error(chalk.red(e.message));
699
- process.exitCode = 1;
700
- }
701
- });
702
- setHelpSections(shareCmd, {
703
- examples: `
704
- # Signed in? Just publish — no Cloudflare setup (managed endpoint).
705
- # Default is private: an owner-only 'me' link, Phoenix-gated.
706
- agents auth login
707
- agents artifacts share ./out/plan.html
708
-
709
- # Share with everyone at your email domain (no org setup — the domain is it)
710
- agents artifacts share ./out/plan.html --visibility org
711
-
712
- # Opt into the public gallery with an OG preview card
713
- agents artifacts share ./out/landing.html --visibility public
714
-
715
- # Hide from the public gallery (direct URL still works, noindex) and expire sooner
716
- agents artifacts share ./out/report.html --visibility unlisted --expire 12h
717
-
718
- # Token-gated link — GET returns 404 without the secret ?k= key
719
- agents artifacts share ./out/secret.html --protected
720
-
721
- # Permanent public page (the slug is derived from its title)
722
- agents artifacts share ./out/landing.html --visibility public --expire never
723
-
724
- # Optional slug override
725
- agents artifacts share ./out/report.html --slug q3-report --expire 7d
726
-
727
- # Human title + structured metadata, shown in the gallery and share list
728
- agents artifacts share ./out/plan.html --label "Q3 fleet plan" --meta kind=plan --meta ticket=RUSH-2683
729
-
730
- # Republish the same title to the same URL without retaining a revision
731
- agents artifacts share ./out/plan.html --no-revision
732
-
733
- # Your derived handle is taken (or you want a vanity namespace)
734
- agents artifacts share ./out/plan.html --handle acme-muqsit
735
- ${SHARE_DELETE_EXAMPLES}
736
- # One-time setup (or join an existing endpoint)
737
- agents artifacts setup
738
- agents artifacts share join https://share.getrush.ai
739
-
740
- # Push a worker-template.ts change out to an already-provisioned endpoint
741
- agents artifacts share update
742
- `,
743
- notes: `
744
- Signed-in users publish to the managed endpoint (share.getrush.ai/<handle>/…)
745
- with the Phoenix session — no Cloudflare account, bucket, or write token. The
746
- handle is the local-part of the signed-in email; --handle publishes under an
747
- alternate public namespace instead (first-writer-claimed like the derived one —
748
- the recovery path when your derived handle belongs to another account; a
749
- same-email re-login re-binds your old handle automatically). The default slug
750
- is derived
751
- deterministically from the HTML <title> or Markdown frontmatter title, then
752
- the filename, so republishing the same title updates the same URL. --slug is
753
- an optional override. Without a session, the existing BYO Cloudflare path still
754
- applies (setup / join). HTML is stored as one object: local images are inlined
755
- and Chrome-saved file:// TOC links become in-page hashes.
756
-
757
- Private by default: signed in, a publish with no --visibility is 'me' —
758
- owner-only, Phoenix-gated, not in the gallery. Pass --visibility org to share
759
- with everyone at your email domain (no org to create — the domain is the whole
760
- mechanism), or --visibility public to opt into the gallery with an OG card. A
761
- BYO publish (no Phoenix session) still defaults to public, since me/org need a
762
- Phoenix owner to gate on.
763
-
764
- Default expiry is 30d so an accidental publish decays. Pass --expire never for
765
- a permanent link. --visibility unlisted (hidden aliases: --unlisted / --private)
766
- hides the page from the public gallery and agents artifacts share list; the
767
- direct URL is still world-readable (unlisted, not secret) and GET sends
768
- X-Robots-Tag: noindex. --protected (= --visibility private) is token-gated
769
- read-auth: the published URL carries a secret ?k= key (Authorization: Bearer
770
- is accepted too) and GET returns 404 without it — treat the whole link as a
771
- secret. --visibility me requires a Phoenix session and is only
772
- visible to the signed-in owner; --visibility org requires the same and is
773
- visible to members of the same Phoenix organization. A pre-publish scan
774
- refuses emails and credential-shaped strings unless --force is passed.
775
-
776
- Every publish carries provenance auto-captured from the exec env/git/clock
777
- (agent, session, host, repo, date) — never invented, only sent when present —
778
- plus a label (explicit --label/--title, else derived from the HTML <title>,
779
- frontmatter title, or filename; never blocks on a prompt) and any --meta
780
- key=value pairs. Republishing an existing slug keeps the prior version as a
781
- retained revision by default; see 'agents artifacts share revisions'.
782
- ${SHARE_DELETE_NOTES}
783
- `,
784
- });
785
- const shareDeleteCmd = registerShareDeleteOptions(shareCmd
786
- .command('delete <targets...>')
787
- .description('Take down a published page (and by default its OG cover). Verifies the page 404s before reporting success. Nested alias: agents artifacts unshare.'));
788
- setHelpSections(shareDeleteCmd, { examples: SHARE_DELETE_EXAMPLES, notes: SHARE_DELETE_NOTES });
789
- shareDeleteCmd.action(async (targets, opts) => {
790
- await runShareDelete(targets, opts);
791
- });
792
- // `agents artifacts share visibility <target> <level>` — change an
793
- // already-published page's visibility in place. Kept in its own block; it
794
- // reuses the delete target parser and the same PATCH metadata-edit route as
795
- // `share edit` (visibility is metadata), so it re-stamps the stored object
796
- // rather than re-publishing — a re-publish over the PUT path can't express an
797
- // in-place change (GET injects the attribution bar at serve time and never
798
- // strips it, and the served body carries no provenance/label/--meta back to
799
- // re-send). --for-user / --visibility-json (not --github-user / --json): the
800
- // parent `share <file>` already owns both long names, and commander resolves a
801
- // child option's long name against the whole ancestor chain, silently dropping
802
- // a same-named child (RUSH-2687) — the same rename the delete/list blocks make.
803
- const shareVisibilityCmd = shareCmd
804
- .command('visibility')
805
- .description("Change an already-published page's visibility in place (public | unlisted | me | org). The slug/URL is preserved; the body is untouched, so no revision is created.")
806
- .addArgument(new Argument('<target>', 'the published page: a full URL, <user>/<slug>, or a bare slug in your namespace'))
807
- .addArgument(new Argument('<level>', 'new visibility').choices([...SHARE_VISIBILITY_LEVELS]))
808
- .option('--for-user <user>', 'GitHub username for resolving a bare-slug target (default: resolved from gh/git config)')
809
- .option('--visibility-json', 'emit a machine-readable result')
810
- .action(async (target, level, opts) => {
811
- try {
812
- const visibility = level;
813
- const result = await runShareEdit(target, { visibility, githubUser: opts.forUser });
814
- if (opts.visibilityJson) {
815
- console.log(JSON.stringify(result, null, 2));
816
- return;
817
- }
818
- console.log(formatShareVisibilityResult(result, visibility));
819
- }
820
- catch (e) {
821
- console.error(chalk.red(e.message));
822
- process.exitCode = 1;
823
- }
824
- });
825
- setHelpSections(shareVisibilityCmd, {
826
- examples: SHARE_VISIBILITY_EXAMPLES,
827
- notes: SHARE_VISIBILITY_NOTES,
828
- });
829
- const shareOpenCmd = shareCmd
830
- .command('open')
831
- .description("Open your own published page in the browser signed in as the owner, so the page's inline visibility control is live. Mints a one-time login ticket and appends it to the URL.")
832
- .addArgument(new Argument('<target>', 'the published page: a full URL, <user>/<slug>, or a bare slug in your namespace'))
833
- .option('--for-user <user>', 'GitHub username for resolving a bare-slug target (default: resolved from your Phoenix handle)')
834
- .option('--no-open', 'print the owner URL instead of opening a browser')
835
- .option('--json', 'emit a machine-readable result (includes the ticketed owner URL)')
836
- .action(async (target, opts) => {
837
- try {
838
- const result = await runShareOpen(target, { githubUser: opts.forUser });
839
- if (opts.json) {
840
- console.log(JSON.stringify(result, null, 2));
841
- return;
842
- }
843
- if (opts.open === false) {
844
- console.log(chalk.green(result.ownerUrl));
845
- console.log(chalk.dim(' open this to land on the page as the owner (the visibility chip becomes a control)'));
846
- return;
847
- }
848
- const shown = await showUrl(result.ownerUrl);
849
- if (shown.via === 'none') {
850
- console.log(chalk.green(result.ownerUrl));
851
- console.error(chalk.dim(' could not open a browser — open the URL above yourself'));
852
- }
853
- else {
854
- console.log(chalk.green(`Opened ${result.url} as owner — the visibility chip is now a live control.`));
855
- }
856
- }
857
- catch (e) {
858
- console.error(chalk.red(e.message));
859
- process.exitCode = 1;
860
- }
861
- });
862
- setHelpSections(shareOpenCmd, {
863
- examples: `agents artifacts share open q3-plan # open your page, signed in, ready to re-scope
864
- agents artifacts share open octocat/q3-plan
865
- agents artifacts share open https://share.getrush.ai/octocat/q3-plan --no-open`,
866
- notes: `The shared page's visibility chip is an interactive control only for the signed-in owner; a plain link has no login, so the chip renders as a static cue. This mints a short-lived, single-use login ticket (self-signed by your share Worker) and opens the page with it, so the chip becomes a dropdown you can switch in place.
867
- Managed (Phoenix) endpoints only — run 'agents auth login' first. If the mint 501s/404s, your Worker predates the feature: run 'agents artifacts share update' to redeploy it.
868
- Prefer to change visibility without a browser? Use 'agents artifacts share visibility <target> <level>'.`,
869
- });
870
- shareCmd
871
- .command('join')
872
- .description('Use an existing synced share endpoint and write token (no provisioning).')
873
- .argument('[baseUrl]', 'base URL of the endpoint, e.g. https://share.getrush.ai')
874
- .option('--token <token>', 'write token (else SHARE_WRITE_TOKEN env, existing bundle, or prompt)')
875
- .action(async (baseUrl, opts) => {
876
- try {
877
- await runShareJoin(baseUrl, opts);
878
- }
879
- catch (e) {
880
- console.error(chalk.red(e.message));
881
- process.exitCode = 1;
882
- }
883
- });
884
- const shareUpdateCmd = shareCmd
885
- .command('update')
886
- .description('Re-deploy the Worker script to the current template on an already-provisioned endpoint (idempotent).')
887
- .option('--bundle <name>', 'secrets bundle holding the Cloudflare API token', DEFAULT_CF_BUNDLE)
888
- .option('--account <id>', 'Cloudflare account id override (default: the configured endpoint\'s account)')
889
- .option('--token <t>', 'Cloudflare API token (else read from --bundle)')
890
- .option('--force', 're-deploy even if the deployed template already matches')
891
- .option('--check', 'report whether a deploy is needed and exit without deploying (needs no Cloudflare credentials)')
892
- // Named --update-json, not --json: `share <file>` (the parent) already
893
- // owns --json for its own publish-time result. Commander resolves an
894
- // option's long name against the WHOLE ancestor chain, so a same-named
895
- // child option is silently dropped at parse time (RUSH-2687).
896
- .option('--update-json', 'emit a machine-readable result')
897
- .action(async (opts) => {
898
- try {
899
- const result = await runShareUpdate(opts);
900
- if (opts.updateJson) {
901
- console.log(JSON.stringify(result, null, 2));
902
- return;
903
- }
904
- if (result.checked) {
905
- console.log(result.deployNeeded
906
- ? chalk.yellow(`Worker '${result.workerName}' template is outdated — deploy needed (current render ${result.templateHash.slice(0, 12)}…).`)
907
- : chalk.dim(`Worker '${result.workerName}' already matches the current template — no deploy needed.`));
908
- return;
909
- }
910
- if (result.updated) {
911
- console.log(chalk.green(`Worker '${result.workerName}' updated → template ${result.templateHash.slice(0, 12)}…`));
912
- }
913
- else {
914
- console.log(chalk.dim(`Worker '${result.workerName}' already matches the current template — no-op.`));
915
- }
916
- }
917
- catch (e) {
918
- console.error(chalk.red(e.message));
919
- process.exitCode = 1;
920
- }
921
- });
922
- setHelpSections(shareUpdateCmd, {
923
- examples: `
924
- # Push a worker-template.ts change out to your already-provisioned endpoint
925
- agents artifacts share update
926
-
927
- # Force a re-deploy even though the template hash already matches
928
- agents artifacts share update --force
929
-
930
- # Report whether a deploy is due without deploying (no Cloudflare creds needed)
931
- agents artifacts share update --check --update-json
932
- `,
933
- notes: `
934
- Reuses the existing account/worker/bucket from 'agents artifacts share status' and the
935
- existing write token — it never re-provisions a bucket, touches routes, or
936
- regenerates the token. See 'agents artifacts share status' for whether an update is due.
937
-
938
- --check renders the current template and compares its hash to what the endpoint last
939
- deployed, then exits — deploying nothing and reading no Cloudflare credentials. The
940
- release train uses it to decide, before publish, whether a release changes the Worker.
941
- `,
942
- });
943
- shareCmd
944
- .command('status')
945
- .description('Show the configured share endpoint and namespace.')
946
- .action(async () => {
947
- let backend;
948
- try {
949
- backend = resolveShareBackend({ requireToken: false });
950
- }
951
- catch (e) {
952
- console.log(chalk.dim(e.message));
953
- return;
954
- }
955
- if (backend.kind === 'managed') {
956
- console.log(`${chalk.bold('backend')} ${chalk.green('managed')}`);
957
- console.log(`${chalk.bold('endpoint')} ${chalk.green(backend.baseUrl)}`);
958
- console.log(`${chalk.bold('namespace')} ${chalk.cyan(`${backend.baseUrl}/${backend.namespace}`)}`);
959
- console.log(chalk.dim("Phoenix session — no Cloudflare setup. Force BYO with AGENTS_SHARE_BACKEND=byo."));
960
- return;
961
- }
962
- const cfg = readShareConfig();
963
- if (!cfg) {
964
- console.log(chalk.dim("Not configured. Run 'agents artifacts setup' or 'agents artifacts share join'."));
965
- return;
966
- }
967
- console.log(`${chalk.bold('backend')} ${chalk.green('byo')}`);
968
- console.log(`${chalk.bold('endpoint')} ${chalk.green(cfg.baseUrl)}`);
969
- console.log(chalk.dim(`worker ${cfg.workerName} · bucket ${cfg.bucketName} · account ${cfg.accountId || 'missing'}`));
970
- if (!cfg.accountId) {
971
- console.log(chalk.dim('account id empty — publish still uses baseUrl + WRITE_TOKEN; `agents artifacts share update` needs --account or join'));
972
- }
973
- const user = await resolveGitHubUsername();
974
- console.log(`${chalk.bold('namespace')} ${user ? chalk.cyan(`${cfg.baseUrl}/${user}`) : chalk.yellow('unknown — set gh auth or github.user')}`);
975
- console.log(`${chalk.bold('analytics')} ${analyticsEnabled(cfg) ? chalk.green('enabled') : chalk.dim('not configured')}`);
976
- const templateStatus = shareTemplateStatus(cfg);
977
- const templateLabel = templateStatus === 'current'
978
- ? chalk.green('current')
979
- : templateStatus === 'outdated'
980
- ? chalk.yellow('outdated — run `agents artifacts share update`')
981
- : chalk.dim("unknown — provisioned before version tracking; run `agents artifacts share update` to adopt it");
982
- console.log(`${chalk.bold('template')} ${templateLabel}`);
983
- });
984
- const shareListCmd = shareCmd
985
- .command('list')
986
- .description("List the pages you've published to your share namespace (human table; --list-json for scripts).")
987
- // Named --for-user / --list-json, not --github-user / --json: `share
988
- // <file>` (the parent) already owns both those long names, and commander
989
- // resolves an option's long name against the WHOLE ancestor chain — a
990
- // same-named child option is silently dropped at parse time even when it
991
- // parses alone (RUSH-2687; verified with a real program.parseAsync(), see
992
- // share.test.ts). Matches the `revisions` precedent (--for-user/
993
- // --revisions-json) and the `delete`/`unshare` precedent (--for-user/
994
- // --delete-json) below.
995
- //
996
- // `--visibility` is also owned by the parent `share <file>` command (publish),
997
- // so the listing filter is named `--scope` here; `--all` is the convenience
998
- // alias for `--scope all`.
999
- .option('--for-user <user>', 'GitHub username whose namespace to list (default: resolved from gh/git config)')
1000
- .addOption(new Option('--scope <level>', 'visibility filter: public (default), unlisted, private, me, org, or all')
1001
- .choices(['public', 'unlisted', 'private', 'me', 'org', 'all'])
1002
- .default('public'))
1003
- .option('--all', "list every page including hidden unlisted/private/me/org shares (alias for --scope all)")
1004
- .option('--agent <name>', 'filter to shares published by this agent/harness (case-insensitive)')
1005
- .option('--session <id>', 'filter to shares published from this session id')
1006
- // Named --label-contains, not --label: `share <file>` (the parent) already owns
1007
- // `--label`/`--title`, same collision class as --for-user/--list-json above.
1008
- .option('--label-contains <substr>', 'filter to shares whose label contains this text (case-insensitive)')
1009
- .option('--meta <key=value>', 'filter by an exact arbitrary metadata entry (repeatable)', (v, p) => [...p, v], [])
1010
- .option('--list-json', 'emit the machine-readable listing (slug, url, size, contentType, publishedAt, expiresAt, label, visibility, agent, session, host, repo, revisionCount, meta)')
1011
- .action(async (opts) => {
1012
- try {
1013
- const scope = opts.all ? 'all' : (opts.scope ?? 'public');
1014
- const parentMeta = shareCmd.opts().meta ?? [];
1015
- const result = await runShareList({
1016
- githubUser: opts.forUser,
1017
- scope,
1018
- agent: opts.agent,
1019
- session: opts.session,
1020
- label: opts.labelContains,
1021
- meta: parseMetaEntries(opts.meta.length ? opts.meta : parentMeta),
1022
- });
1023
- console.log(formatShareList(result, Boolean(opts.listJson)));
1024
- }
1025
- catch (e) {
1026
- console.error(chalk.red(e.message));
1027
- process.exitCode = 1;
1028
- }
1029
- });
1030
- setHelpSections(shareListCmd, {
1031
- examples: `
1032
- # Everything you've published, newest first
1033
- agents artifacts share list
1034
-
1035
- # Include your hidden pages (unlisted / private / me / org) so you can see everything
1036
- agents artifacts share list --all
1037
- agents artifacts share list --scope me
1038
- agents artifacts share list --scope unlisted
1039
- agents artifacts share list --scope private
1040
-
1041
- # Machine-readable — e.g. pull every still-public URL with jq
1042
- agents artifacts share list --list-json | jq -r '.objects[].url'
1043
-
1044
- # List another namespace
1045
- agents artifacts share list --for-user octocat
1046
-
1047
- # Narrow by who/what published it
1048
- agents artifacts share list --agent claude
1049
- agents artifacts share list --label-contains "fleet plan"
1050
- agents artifacts share list --meta kind=plan --meta status=final
1051
- `,
1052
- notes: `
1053
- Lists the ACTIVE pages in your namespace — expired links and the sibling .png OG
1054
- covers are omitted. By default this mirrors the public gallery (public pages only).
1055
- Use --scope unlisted|me|org or --all to include your hidden pages; those scopes
1056
- send the owner's bearer and a 'scope=mine' hint to the Worker's JSON listing route,
1057
- which returns hidden pages ONLY after verifying the caller owns the namespace.
1058
- Signed-in users list the managed endpoint (share.getrush.ai/<handle>); otherwise
1059
- BYO. It reads the endpoint's JSON listing route, which ships with the current
1060
- Worker template. If a BYO Worker predates this feature the command says so and
1061
- points you at 'agents artifacts share update' (RUSH-2449) rather than returning a
1062
- wrong or empty result — see 'agents artifacts share status' for whether an update
1063
- is due.
1064
-
1065
- --agent/--session/--label-contains/--meta filter the fetched listing client-side;
1066
- --list-json's count reflects the filtered set. Each human row shows the page's
1067
- visibility so public vs hidden is obvious at a glance.
1068
- `,
1069
- });
1070
- const shareEditCmd = shareCmd
1071
- .command('edit <target>')
1072
- .description('Edit a published share\'s label or arbitrary metadata without republishing its body.')
1073
- .option('--for-user <user>', 'namespace for resolving a bare slug (default: your namespace)')
1074
- .option('--label <text>', 'set or replace the display label')
1075
- .option('--remove-label', 'remove the display label')
1076
- .option('--meta <key=value>', 'merge a metadata entry (repeatable)', (v, p) => [...p, v], [])
1077
- .option('--replace-meta <key=value>', 'replace all arbitrary metadata with these entries (repeatable)', (v, p) => [...p, v], [])
1078
- .option('--remove-meta <key>', 'remove an arbitrary metadata key (repeatable)', (v, p) => [...p, v], [])
1079
- .option('--edit-json', 'emit the machine-readable edit result')
1080
- .action(async (target, opts) => {
1081
- try {
1082
- const parent = shareCmd.opts();
1083
- const label = opts.label ?? parent.label;
1084
- const mergeMeta = opts.meta.length ? opts.meta : (parent.meta ?? []);
1085
- if (label !== undefined && opts.removeLabel)
1086
- throw new Error('--label and --remove-label are mutually exclusive.');
1087
- if (mergeMeta.length && opts.replaceMeta.length)
1088
- throw new Error('--meta and --replace-meta are mutually exclusive.');
1089
- if (opts.replaceMeta.length && opts.removeMeta.length)
1090
- throw new Error('--replace-meta and --remove-meta are mutually exclusive.');
1091
- if (label === undefined && !opts.removeLabel && !mergeMeta.length && !opts.replaceMeta.length && !opts.removeMeta.length)
1092
- throw new Error('Nothing to edit. Pass --label, --remove-label, --meta, --replace-meta, or --remove-meta.');
1093
- const removeMeta = opts.removeMeta.map((key) => Object.keys(parseMetaEntries([`${key}=x`]))[0]);
1094
- const result = await runShareEdit(target, {
1095
- githubUser: opts.forUser,
1096
- label: opts.removeLabel ? null : label === undefined ? undefined : sanitizeLabel(label),
1097
- meta: parseMetaEntries(opts.replaceMeta.length ? opts.replaceMeta : mergeMeta),
1098
- metaMode: opts.replaceMeta.length ? 'replace' : 'merge',
1099
- removeMeta,
1100
- // Parent `share --force` (RUSH-2687: a child --force is silently dropped).
1101
- force: parent.force,
1102
- });
1103
- console.log(opts.editJson ? JSON.stringify(result, null, 2) : chalk.green(`updated ${result.url}`));
1104
- }
1105
- catch (e) {
1106
- console.error(chalk.red(e.message));
1107
- process.exitCode = 1;
1108
- }
1109
- });
1110
- setHelpSections(shareEditCmd, {
1111
- examples: `
1112
- # Change only the gallery/list title
1113
- agents artifacts share edit q3-plan --label "Q3 fleet plan"
1114
-
1115
- # Merge metadata, or deliberately replace/remove it
1116
- agents artifacts share edit q3-plan --meta status=final --meta ticket=PHNX-3278
1117
- agents artifacts share edit q3-plan --replace-meta kind=plan --replace-meta status=final
1118
- agents artifacts share edit q3-plan --remove-meta status
1119
- `,
1120
- notes: `
1121
- Metadata edits preserve the exact published body, content type/HTTP metadata,
1122
- publication time, visibility, expiry, provenance, cover, and retained revisions. --meta merges;
1123
- --replace-meta replaces all arbitrary metadata; --remove-meta deletes named keys.
1124
- Reserved Worker/provenance keys cannot be changed through metadata flags.
1125
- Edited labels and metadata values are scanned for emails and credential-shaped
1126
- strings the same way publish is — pass --force to write them anyway.
1127
- `,
1128
- });
1129
- const shareRevisionsCmd = shareCmd
1130
- .command('revisions <target>')
1131
- .description('Show the retained prior versions of a published slug, newest first (human table; --revisions-json for scripts).')
1132
- // Named --for-user / --revisions-json, not --github-user / --json: `share
1133
- // <file>` (the parent) already owns both those long names, and commander
1134
- // resolves an option's long name against the WHOLE ancestor chain — a
1135
- // same-named child option is silently dropped at parse time even when it
1136
- // parses alone (RUSH-2687; verified with a real program.parseAsync(), see
1137
- // share.test.ts). Same collision class as `list`/`update`/`delete` above.
1138
- .option('--for-user <user>', 'GitHub username for resolving a bare-slug target (default: resolved from gh/git config)')
1139
- .option('--revisions-json', 'emit the machine-readable revision list')
1140
- .action(async (target, opts) => {
1141
- try {
1142
- const result = await runShareRevisions(target, { githubUser: opts.forUser });
1143
- console.log(formatShareRevisions(result, Boolean(opts.revisionsJson)));
1144
- }
1145
- catch (e) {
1146
- console.error(chalk.red(e.message));
1147
- process.exitCode = 1;
1148
- }
1149
- });
1150
- setHelpSections(shareRevisionsCmd, {
1151
- examples: `
1152
- # Prior versions kept under this slug (bare slug — your own namespace)
1153
- agents artifacts share revisions q3-report
1154
-
1155
- # By <user>/<slug> or full URL, same target forms as 'agents artifacts unshare'
1156
- agents artifacts share revisions octocat/q3-report
1157
- agents artifacts share revisions https://share.getrush.ai/octocat/q3-report
1158
-
1159
- # Machine-readable, and a bare slug resolved against another namespace
1160
- agents artifacts share revisions q3-report --revisions-json
1161
- agents artifacts share revisions q3-report --for-user octocat
1162
- `,
1163
- notes: `
1164
- A revision is created automatically on every republish of an existing slug
1165
- (pass --no-revision at publish time to skip it) — this is history, never
1166
- shown on the public gallery or in 'agents artifacts share list' beyond its
1167
- count. Each revision's own URL is still directly reachable and honors its own
1168
- recorded expiry. Signed-in users resolve a bare slug against the managed
1169
- Phoenix namespace; otherwise BYO (GitHub username / --for-user).
1170
- `,
1171
- });
1172
- shareCmd
1173
- .command('analytics')
1174
- .description('Show the Cloudflare Web Analytics status for this share endpoint.')
1175
- .action(async () => {
1176
- let backend;
1177
- try {
1178
- backend = resolveShareBackend({ requireToken: false });
1179
- }
1180
- catch (e) {
1181
- console.log(chalk.dim(e.message));
1182
- return;
1183
- }
1184
- if (backend.kind === 'managed') {
1185
- console.log(chalk.yellow('Cloudflare Web Analytics is a BYO feature.'));
1186
- console.log(chalk.dim(`You're on the managed endpoint (${backend.baseUrl}). Per-page analytics for the managed endpoint is not in this release — provision your own Cloudflare with 'agents artifacts setup --analytics-token <token>', or force BYO with AGENTS_SHARE_BACKEND=byo.`));
1187
- return;
1188
- }
1189
- const cfg = readShareConfig();
1190
- if (!cfg) {
1191
- console.log(chalk.dim("Not configured. Run 'agents artifacts setup' or 'agents artifacts share join'."));
1192
- return;
1193
- }
1194
- if (!analyticsEnabled(cfg)) {
1195
- console.log(chalk.yellow('Cloudflare Web Analytics is not configured.'));
1196
- console.log(chalk.dim("Re-run setup with --analytics-token <token> or add analyticsToken to agents.yaml share:."));
1197
- return;
1198
- }
1199
- const dashboard = cfg.domain
1200
- ? `https://dash.cloudflare.com/${cfg.accountId}/web-analytics/${cfg.domain}`
1201
- : `https://dash.cloudflare.com/${cfg.accountId}/web-analytics`;
1202
- console.log(`${chalk.bold('analytics')} ${chalk.green('enabled')}`);
1203
- console.log(`${chalk.bold('token')} ${chalk.dim(cfg.analyticsToken.slice(0, 8) + '…')}`);
1204
- console.log(`${chalk.bold('dashboard')} ${chalk.cyan(dashboard)}`);
1205
- const user = await resolveGitHubUsername();
1206
- if (user) {
1207
- console.log(chalk.dim(`Per-page breakdown is available under Paths in the dashboard (filter by /${user}/).`));
1208
- }
1209
- });
1210
- }
1211
- /**
1212
- * Register `agents artifacts unshare <targets...>` as the nested alias of
1213
- * `agents artifacts share delete`. Top-level `agents unshare` is retired.
1214
- */
1215
- export function registerUnshareCommand(artifactsCmd) {
1216
- const unshareCmd = registerShareDeleteOptions(artifactsCmd
1217
- .command('unshare <targets...>')
1218
- .description('Alias of `agents artifacts share delete` — take down a published page (and by default its OG cover).'));
1219
- setHelpSections(unshareCmd, { examples: SHARE_DELETE_EXAMPLES, notes: SHARE_DELETE_NOTES });
1220
- unshareCmd.action(async (targets, opts) => {
1221
- await runShareDelete(targets, opts);
1222
- });
1223
- }
1224
- /** Provision a fresh R2 bucket + Worker on the user's Cloudflare and persist the
1225
- * endpoint config + write token. Shared by both modes of `agents artifacts setup`
1226
- * (the flag-driven provision and the interactive wizard). */
1227
- export async function runShareProvision(opts) {
1228
- const { default: ora } = await import('ora');
1229
- const { input } = await import('@inquirer/prompts');
1230
- const { apiToken, accountId: acctFromBundle } = readCloudflareCreds(opts.bundle, {
1231
- apiToken: opts.token,
1232
- accountId: opts.account,
1233
- });
1234
- const accountId = opts.account || acctFromBundle || (await input({ message: 'Cloudflare account id' }));
1235
- if (!accountId)
1236
- throw new Error('A Cloudflare account id is required.');
1237
- const workerName = opts.worker;
1238
- const bucketName = opts.bucket;
1239
- const token = generateWriteToken();
1240
- const requestedDomain = cleanHostname(opts.domain) ?? DEFAULT_SHARE_DOMAIN;
1241
- const worker = renderWorkerBundle();
1242
- const script = worker.script;
1243
- const spin = ora('Provisioning on Cloudflare…').start();
1244
- try {
1245
- const provisionOpts = opts.request ? { request: opts.request } : {};
1246
- await createBucket(apiToken, accountId, bucketName, provisionOpts);
1247
- spin.text = `R2 bucket '${bucketName}' ready`;
1248
- await configureBucketLifecycle(apiToken, accountId, bucketName, provisionOpts);
1249
- spin.text = `R2 bucket '${bucketName}' lifecycle ready`;
1250
- await deployWorker(apiToken, accountId, workerName, worker, bucketName, provisionOpts);
1251
- spin.text = `Worker '${workerName}' deployed`;
1252
- await setWorkerSecret(apiToken, accountId, workerName, token, provisionOpts);
1253
- spin.text = `Worker '${workerName}' write token set`;
1254
- const subdomain = await enableWorkersDev(apiToken, accountId, workerName, provisionOpts);
1255
- let baseUrl = `https://${workerName}.${subdomain}.workers.dev`;
1256
- let domain;
1257
- if (requestedDomain) {
1258
- spin.text = `Mapping ${requestedDomain}…`;
1259
- const zoneId = await findZoneId(apiToken, requestedDomain, provisionOpts);
1260
- if (zoneId) {
1261
- await addCustomDomain(apiToken, accountId, workerName, zoneId, requestedDomain, provisionOpts);
1262
- baseUrl = `https://${requestedDomain}`;
1263
- domain = requestedDomain;
1264
- }
1265
- else {
1266
- spin.warn(`Zone for ${requestedDomain} not visible to this token — staying on workers.dev`);
1267
- }
1268
- }
1269
- const phoenixIdBase = phoenixIdBaseForDeploy({ managed: opts.managed }, { baseUrl, domain });
1270
- if (phoenixIdBase) {
1271
- await putWorkerSecret(apiToken, accountId, workerName, WORKER_PHOENIX_ID_BASE_SECRET, phoenixIdBase, provisionOpts);
1272
- spin.text = `Worker '${workerName}' Phoenix ID base set`;
1273
- }
1274
- // Managed collaboration backend (PHNX-3835). Dormant unless BOTH
1275
- // PRIX_ARTIFACT_COLLAB_BASE and ARTIFACT_COLLAB_SERVICE_TOKEN are set in the
1276
- // deploy env; the service token rides the Secrets API, never rendered HTML.
1277
- const collab = collabConfigForDeploy({ managed: opts.managed }, { baseUrl, domain });
1278
- if (collab.collabBase && collab.collabServiceToken) {
1279
- await putWorkerSecret(apiToken, accountId, workerName, WORKER_COLLAB_BASE_SECRET, collab.collabBase, provisionOpts);
1280
- await putWorkerSecret(apiToken, accountId, workerName, WORKER_COLLAB_SERVICE_TOKEN_SECRET, collab.collabServiceToken, provisionOpts);
1281
- spin.text = `Worker '${workerName}' collaboration backend set`;
1282
- }
1283
- spin.succeed('Provisioned');
1284
- const cfg = {
1285
- baseUrl,
1286
- accountId,
1287
- workerName,
1288
- bucketName,
1289
- domain,
1290
- analyticsToken: opts.analyticsToken,
1291
- templateHash: hashWorkerScript(script),
1292
- };
1293
- writeShareConfig(cfg);
1294
- storeWriteToken(token);
1295
- console.log(chalk.green(`\nShare endpoint ready → ${chalk.bold(baseUrl)}`));
1296
- console.log(chalk.dim('Publish with: ') + chalk.cyan('agents artifacts share <file>'));
1297
- console.log(chalk.dim(`Fleet: push the token with 'agents secrets export share --device <box>' and pull config with 'agents repo pull'.`));
1298
- }
1299
- catch (e) {
1300
- spin.fail('Provisioning failed');
1301
- throw e;
1302
- }
1303
- }
1304
- /** Re-deploy the Worker script on an ALREADY-provisioned endpoint to match the
1305
- * current `worker-template.ts`. Reuses the existing account/worker/bucket and
1306
- * write token from `readShareConfig()`/the `share` bundle — never creates a
1307
- * bucket, touches routes/domains, or regenerates the token (see
1308
- * `updateWorker` in `lib/share/provision.ts` for how the token — and, on a
1309
- * managed endpoint, `PHOENIX_ID_BASE` — survives the re-upload). Idempotent:
1310
- * no-ops the script upload when the deployed hash already matches unless
1311
- * `force`; a managed endpoint still re-applies `PHOENIX_ID_BASE`. */
1312
- export async function runShareUpdate(opts = {}) {
1313
- const cfg = readShareConfig();
1314
- if (!cfg) {
1315
- throw new Error("Not configured. Run 'agents artifacts setup' (to provision) or 'agents artifacts share join' first.");
1316
- }
1317
- // Change detection is a pure local computation (render + sha256), so it needs
1318
- // no Cloudflare credentials. The release train calls this in `--check` mode
1319
- // during preflight — BEFORE it has verified the deploy creds — to decide
1320
- // whether this release changes the Worker at all. `shareTemplateStatus` is the
1321
- // same comparator `agents artifacts share status` uses; 'unknown' (an endpoint
1322
- // with no recorded hash) deploys, mirroring `updateWorker`'s undefined-previous
1323
- // behavior.
1324
- const worker = renderWorkerBundle();
1325
- const templateHash = hashWorkerScript(worker.script);
1326
- const deployNeeded = opts.force === true || shareTemplateStatus(cfg) !== 'current';
1327
- if (opts.check) {
1328
- return {
1329
- updated: false,
1330
- checked: true,
1331
- deployNeeded,
1332
- templateHash,
1333
- deployedHash: cfg.templateHash,
1334
- baseUrl: cfg.baseUrl,
1335
- workerName: cfg.workerName,
1336
- };
1337
- }
1338
- const { apiToken, accountId: acctFromBundle } = readCloudflareCreds(opts.bundle ?? DEFAULT_CF_BUNDLE, {
1339
- apiToken: opts.token,
1340
- accountId: opts.account,
1341
- });
1342
- const accountId = opts.account || acctFromBundle || cfg.accountId;
1343
- if (!accountId) {
1344
- throw new Error("Share endpoint has no Cloudflare account id — `agents artifacts share update` cannot call the API. Pass --account <id>, or re-run 'agents artifacts share join'.");
1345
- }
1346
- const writeToken = readWriteToken();
1347
- const phoenixIdBase = phoenixIdBaseForDeploy({ managed: opts.managed }, cfg);
1348
- const collab = collabConfigForDeploy({ managed: opts.managed }, cfg);
1349
- const provisionOpts = {
1350
- ...(opts.request ? { request: opts.request } : {}),
1351
- force: opts.force,
1352
- ...(phoenixIdBase !== undefined ? { phoenixIdBase } : {}),
1353
- ...(collab.collabBase !== undefined
1354
- ? { collabBase: collab.collabBase, collabServiceToken: collab.collabServiceToken }
1355
- : {}),
1356
- };
1357
- const result = await updateWorker(apiToken, accountId, cfg.workerName, cfg.bucketName, worker, writeToken, cfg.templateHash, provisionOpts);
1358
- if (!result.skipped) {
1359
- writeShareConfig({ ...cfg, accountId, templateHash: result.templateHash });
1360
- }
1361
- return {
1362
- updated: !result.skipped,
1363
- templateHash: result.templateHash,
1364
- deployNeeded,
1365
- deployedHash: cfg.templateHash,
1366
- baseUrl: cfg.baseUrl,
1367
- workerName: cfg.workerName,
1368
- };
1369
- }
1370
- function cleanHostname(domain) {
1371
- const raw = domain?.trim().replace(/\/+$/, '');
1372
- if (!raw)
1373
- return undefined;
1374
- try {
1375
- const url = new URL(raw.includes('://') ? raw : `https://${raw}`);
1376
- return url.hostname || undefined;
1377
- }
1378
- catch {
1379
- return raw;
1380
- }
1381
- }
1382
- /** Join an existing share endpoint (no provisioning): prompt for the endpoint
1383
- * details + write token and persist them. Shared by `agents artifacts share join`
1384
- * and the `agents artifacts setup` wizard. */
1385
- export async function runShareJoin(baseUrl, opts = {}) {
1386
- const { password, input } = await import('@inquirer/prompts');
1387
- const existing = readShareConfig();
1388
- const clean = baseUrl?.replace(/\/+$/, '');
1389
- if (!clean && !existing) {
1390
- throw new Error("No synced share endpoint found. Pull config first with 'agents repo pull', or pass the endpoint URL: agents artifacts share join <baseUrl>.");
1391
- }
1392
- let cfg;
1393
- if (existing && (!clean || clean === existing.baseUrl)) {
1394
- cfg = existing;
1395
- }
1396
- else {
1397
- if (!clean)
1398
- throw new Error('Share endpoint URL is required.');
1399
- const workerName = await input({ message: 'Worker name', default: DEFAULT_WORKER_NAME });
1400
- const bucketName = await input({ message: 'Bucket name', default: DEFAULT_BUCKET_NAME });
1401
- const accountId = await input({ message: 'Cloudflare account id' });
1402
- const domain = clean.startsWith('https://') && !clean.includes('.workers.dev')
1403
- ? clean.replace(/^https:\/\//, '')
1404
- : undefined;
1405
- cfg = { baseUrl: clean, accountId, workerName, bucketName, domain };
1406
- }
1407
- let token = opts.token?.trim() || readWriteTokenEnv() || '';
1408
- if (!token) {
1409
- try {
1410
- token = readWriteTokenFromBundle();
1411
- }
1412
- catch {
1413
- token = '';
1414
- }
1415
- }
1416
- if (!token) {
1417
- token = await password({ message: 'Write token (from the endpoint owner)', mask: true });
1418
- }
1419
- if (!token)
1420
- throw new Error('A write token is required to join.');
1421
- writeShareConfig(cfg);
1422
- storeWriteToken(token);
1423
- console.log(chalk.green(`Joined ${chalk.bold(cfg.baseUrl)} — publish with `) + chalk.cyan('agents artifacts share <file>'));
1424
- }