@phnx-labs/agents-cli 1.22.39 → 1.22.40

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 (554) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +111 -70
  3. package/dist/bin/agents +0 -0
  4. package/dist/bootstrap.js +45 -26
  5. package/dist/browser.js +2 -2
  6. package/dist/cli/command-registry.d.ts +135 -0
  7. package/dist/cli/command-registry.js +260 -0
  8. package/dist/commands/accounts.d.ts +20 -0
  9. package/dist/commands/accounts.js +186 -25
  10. package/dist/commands/apply.d.ts +3 -3
  11. package/dist/commands/apply.js +20 -63
  12. package/dist/commands/browser.js +206 -94
  13. package/dist/commands/budget.d.ts +7 -6
  14. package/dist/commands/budget.js +8 -7
  15. package/dist/commands/cloud.js +17 -20
  16. package/dist/commands/commands.js +1 -1
  17. package/dist/commands/computer-actions.d.ts +1 -35
  18. package/dist/commands/computer-actions.js +13 -181
  19. package/dist/commands/computer.d.ts +28 -3
  20. package/dist/commands/computer.js +93 -65
  21. package/dist/commands/config.js +16 -3
  22. package/dist/commands/cost.d.ts +2 -1
  23. package/dist/commands/cost.js +7 -6
  24. package/dist/commands/daemon.js +151 -4
  25. package/dist/commands/detach.js +1 -1
  26. package/dist/commands/doctor.js +19 -11
  27. package/dist/commands/events.js +1 -1
  28. package/dist/commands/exec.d.ts +2 -50
  29. package/dist/commands/exec.js +160 -215
  30. package/dist/commands/factory.js +1 -1
  31. package/dist/commands/feed.d.ts +2 -2
  32. package/dist/commands/feed.js +9 -12
  33. package/dist/commands/fleet-capture.js +25 -27
  34. package/dist/commands/focus.d.ts +2 -3
  35. package/dist/commands/focus.js +34 -9
  36. package/dist/commands/go.js +15 -5
  37. package/dist/commands/harness.d.ts +3 -3
  38. package/dist/commands/harness.js +53 -5
  39. package/dist/commands/hooks.js +1 -1
  40. package/dist/commands/import.js +2 -2
  41. package/dist/commands/insights.d.ts +5 -5
  42. package/dist/commands/insights.js +15 -9
  43. package/dist/commands/inspect.d.ts +2 -3
  44. package/dist/commands/inspect.js +4 -16
  45. package/dist/commands/logs.d.ts +2 -2
  46. package/dist/commands/logs.js +9 -9
  47. package/dist/commands/mcp.js +2 -2
  48. package/dist/commands/memory.js +1 -1
  49. package/dist/commands/message.d.ts +1 -1
  50. package/dist/commands/message.js +7 -7
  51. package/dist/commands/mine.d.ts +11 -8
  52. package/dist/commands/mine.js +11 -10
  53. package/dist/commands/models.js +1 -1
  54. package/dist/commands/modes.js +1 -1
  55. package/dist/commands/monitors.js +23 -6
  56. package/dist/commands/output.d.ts +7 -6
  57. package/dist/commands/output.js +11 -10
  58. package/dist/commands/packages.js +4 -4
  59. package/dist/commands/perf.js +1 -1
  60. package/dist/commands/permissions.js +49 -32
  61. package/dist/commands/plugins.d.ts +1 -1
  62. package/dist/commands/plugins.js +3 -3
  63. package/dist/commands/profiles.d.ts +6 -9
  64. package/dist/commands/profiles.js +8 -321
  65. package/dist/commands/projects.d.ts +9 -0
  66. package/dist/commands/projects.js +140 -8
  67. package/dist/commands/prune.js +5 -13
  68. package/dist/commands/refresh-rules.js +1 -1
  69. package/dist/commands/repo.d.ts +5 -7
  70. package/dist/commands/repo.js +34 -18
  71. package/dist/commands/resource-view.js +4 -0
  72. package/dist/commands/resume.d.ts +11 -7
  73. package/dist/commands/resume.js +82 -98
  74. package/dist/commands/route.d.ts +12 -0
  75. package/dist/commands/route.js +261 -0
  76. package/dist/commands/routines.d.ts +2 -3
  77. package/dist/commands/routines.js +120 -145
  78. package/dist/commands/rules.js +1 -1
  79. package/dist/commands/run-account-picker.d.ts +1 -1
  80. package/dist/commands/run-account-picker.js +2 -2
  81. package/dist/commands/run-broadcast.d.ts +21 -0
  82. package/dist/commands/run-broadcast.js +89 -0
  83. package/dist/commands/run-cloud.js +1 -1
  84. package/dist/commands/secrets-vault.d.ts +10 -0
  85. package/dist/commands/{login.js → secrets-vault.js} +34 -14
  86. package/dist/commands/secrets.d.ts +4 -4
  87. package/dist/commands/secrets.js +72 -63
  88. package/dist/commands/sessions-backfill.js +1 -1
  89. package/dist/commands/sessions-browser.d.ts +1 -1
  90. package/dist/commands/sessions-browser.js +9 -5
  91. package/dist/commands/sessions-export.js +2 -2
  92. package/dist/commands/sessions-inject.js +4 -5
  93. package/dist/commands/sessions-migrate.js +16 -27
  94. package/dist/commands/sessions-picker.d.ts +13 -0
  95. package/dist/commands/sessions-picker.js +182 -8
  96. package/dist/commands/sessions-resume.d.ts +7 -3
  97. package/dist/commands/sessions-resume.js +81 -33
  98. package/dist/commands/sessions-stats.js +2 -2
  99. package/dist/commands/sessions.d.ts +75 -68
  100. package/dist/commands/sessions.js +142 -180
  101. package/dist/commands/setup-computer.js +1 -1
  102. package/dist/commands/setup-fleet.js +3 -0
  103. package/dist/commands/setup-mine.d.ts +7 -3
  104. package/dist/commands/setup-mine.js +13 -8
  105. package/dist/commands/setup-secrets.js +2 -2
  106. package/dist/commands/setup-watchdog.js +2 -2
  107. package/dist/commands/setup.js +7 -2
  108. package/dist/commands/share.d.ts +65 -0
  109. package/dist/commands/share.js +253 -20
  110. package/dist/commands/skills.js +3 -3
  111. package/dist/commands/snapshot.d.ts +2 -2
  112. package/dist/commands/snapshot.js +9 -9
  113. package/dist/commands/ssh.d.ts +1 -1
  114. package/dist/commands/ssh.js +186 -64
  115. package/dist/commands/subagents.js +1 -1
  116. package/dist/commands/sync.js +24 -9
  117. package/dist/commands/teams.d.ts +2 -2
  118. package/dist/commands/teams.js +9 -18
  119. package/dist/commands/tmux.js +5 -1
  120. package/dist/commands/trash.js +1 -1
  121. package/dist/commands/usage.d.ts +1 -1
  122. package/dist/commands/usage.js +2 -2
  123. package/dist/commands/utils.d.ts +4 -14
  124. package/dist/commands/utils.js +6 -27
  125. package/dist/commands/versions.js +2 -2
  126. package/dist/commands/view.d.ts +9 -77
  127. package/dist/commands/view.js +23 -8
  128. package/dist/commands/watchdog.js +1 -1
  129. package/dist/commands/webhook.js +11 -25
  130. package/dist/commands/workflows.js +1 -1
  131. package/dist/index.js +1 -1
  132. package/dist/lib/account-capabilities.d.ts +39 -0
  133. package/dist/lib/account-capabilities.js +59 -0
  134. package/dist/lib/account-catalog.js +1 -1
  135. package/dist/lib/account-registry.d.ts +66 -0
  136. package/dist/lib/account-registry.js +151 -5
  137. package/dist/lib/{rotate.d.ts → accounting/rotate.d.ts} +4 -4
  138. package/dist/lib/{rotate.js → accounting/rotate.js} +8 -8
  139. package/dist/lib/{usage.d.ts → accounting/usage.d.ts} +4 -4
  140. package/dist/lib/{usage.js → accounting/usage.js} +11 -11
  141. package/dist/lib/agent-spec/provider.js +1 -1
  142. package/dist/lib/agents.d.ts +72 -4
  143. package/dist/lib/agents.js +231 -199
  144. package/dist/lib/answer-router.d.ts +2 -2
  145. package/dist/lib/ask-classifier.d.ts +1 -1
  146. package/dist/lib/ask-classifier.js +1 -1
  147. package/dist/lib/audit/log.js +1 -1
  148. package/dist/lib/auth-health.d.ts +1 -1
  149. package/dist/lib/auth-health.js +2 -2
  150. package/dist/lib/brand.js +1 -1
  151. package/dist/lib/browser/caller-identity.d.ts +28 -0
  152. package/dist/lib/browser/caller-identity.js +156 -0
  153. package/dist/lib/browser/cdp.js +1 -1
  154. package/dist/lib/browser/drivers/ssh.d.ts +1 -1
  155. package/dist/lib/browser/drivers/ssh.js +2 -2
  156. package/dist/lib/browser/hygiene.d.ts +10 -2
  157. package/dist/lib/browser/hygiene.js +7 -4
  158. package/dist/lib/browser/ipc.d.ts +22 -2
  159. package/dist/lib/browser/ipc.js +185 -21
  160. package/dist/lib/browser/profiles.d.ts +67 -3
  161. package/dist/lib/browser/profiles.js +129 -7
  162. package/dist/lib/browser/remote-control.d.ts +2 -2
  163. package/dist/lib/browser/remote-control.js +3 -3
  164. package/dist/lib/browser/runtime-state.d.ts +79 -0
  165. package/dist/lib/browser/runtime-state.js +119 -1
  166. package/dist/lib/browser/service.d.ts +113 -1
  167. package/dist/lib/browser/service.js +454 -40
  168. package/dist/lib/browser/sessions-list.d.ts +2 -1
  169. package/dist/lib/browser/sessions-list.js +4 -13
  170. package/dist/lib/browser/types.d.ts +18 -0
  171. package/dist/lib/budget/config.js +1 -1
  172. package/dist/lib/budget/ledger.js +1 -1
  173. package/dist/lib/byok-usage.js +1 -1
  174. package/dist/lib/capabilities.js +3 -15
  175. package/dist/lib/catchup.d.ts +1 -1
  176. package/dist/lib/catchup.js +1 -1
  177. package/dist/lib/cloud/dispatch.js +1 -1
  178. package/dist/lib/cloud/host.d.ts +3 -3
  179. package/dist/lib/cloud/host.js +5 -5
  180. package/dist/lib/cloud/rush.d.ts +9 -21
  181. package/dist/lib/cloud/rush.js +33 -120
  182. package/dist/lib/cloud/types.d.ts +2 -2
  183. package/dist/lib/commands.js +3 -13
  184. package/dist/lib/computer/actions.d.ts +36 -0
  185. package/dist/lib/computer/actions.js +162 -0
  186. package/dist/lib/computer/dispatch.d.ts +2 -2
  187. package/dist/lib/computer/dispatch.js +2 -2
  188. package/dist/lib/computer/sessions-list.d.ts +3 -3
  189. package/dist/lib/computer/sessions-list.js +2 -2
  190. package/dist/lib/config-keys.d.ts +2 -1
  191. package/dist/lib/config-keys.js +8 -4
  192. package/dist/lib/config-machine-keys.d.ts +4 -2
  193. package/dist/lib/config-machine-keys.js +5 -2
  194. package/dist/lib/crabbox/lease.js +9 -1
  195. package/dist/lib/crabbox/runtimes.d.ts +32 -7
  196. package/dist/lib/crabbox/runtimes.js +72 -30
  197. package/dist/lib/{daemon.d.ts → daemon/daemon.d.ts} +59 -1
  198. package/dist/lib/{daemon.js → daemon/daemon.js} +237 -49
  199. package/dist/lib/daemon-services.d.ts +1 -1
  200. package/dist/lib/daemon-services.js +5 -0
  201. package/dist/lib/daemon-ticks.d.ts +25 -0
  202. package/dist/lib/daemon-ticks.js +31 -1
  203. package/dist/lib/daemon-webhooks.d.ts +102 -0
  204. package/dist/lib/daemon-webhooks.js +210 -0
  205. package/dist/lib/device-config.d.ts +85 -75
  206. package/dist/lib/device-config.js +279 -141
  207. package/dist/lib/devices/config-migration.d.ts +29 -34
  208. package/dist/lib/devices/config-migration.js +209 -130
  209. package/dist/lib/devices/connect.d.ts +2 -2
  210. package/dist/lib/devices/connect.js +2 -2
  211. package/dist/lib/devices/discovery-policy.d.ts +30 -0
  212. package/dist/lib/devices/discovery-policy.js +101 -0
  213. package/dist/lib/devices/fleet-inventory.js +8 -3
  214. package/dist/lib/devices/harness-inventory.d.ts +1 -1
  215. package/dist/lib/devices/harness-inventory.js +12 -3
  216. package/dist/lib/devices/known-hosts.js +1 -1
  217. package/dist/lib/devices/pool.d.ts +10 -5
  218. package/dist/lib/devices/pool.js +5 -7
  219. package/dist/lib/devices/registry.d.ts +1 -1
  220. package/dist/lib/devices/registry.js +1 -1
  221. package/dist/lib/devices/resolve-profile.d.ts +2 -2
  222. package/dist/lib/devices/resolve-profile.js +2 -2
  223. package/dist/lib/devices/resolve-target.d.ts +1 -1
  224. package/dist/lib/devices/resolve-target.js +4 -4
  225. package/dist/lib/devices/self-host.d.ts +1 -1
  226. package/dist/lib/devices/self-host.js +3 -3
  227. package/dist/lib/devices/ssh-config.d.ts +1 -1
  228. package/dist/lib/devices/stats-cache.js +1 -1
  229. package/dist/lib/devices/sync.d.ts +3 -1
  230. package/dist/lib/devices/sync.js +3 -3
  231. package/dist/lib/doctor-diff.js +4 -4
  232. package/dist/lib/drift-sync.js +2 -2
  233. package/dist/lib/drift.js +2 -2
  234. package/dist/lib/event-families.d.ts +1 -1
  235. package/dist/lib/event-stream.d.ts +1 -1
  236. package/dist/lib/event-stream.js +2 -2
  237. package/dist/lib/events-ingest.js +2 -2
  238. package/dist/lib/exec.d.ts +4 -4
  239. package/dist/lib/exec.js +11 -11
  240. package/dist/lib/factory/snapshot.d.ts +1 -1
  241. package/dist/lib/factory/snapshot.js +1 -1
  242. package/dist/lib/{activity.d.ts → feed/activity.d.ts} +1 -1
  243. package/dist/lib/{activity.js → feed/activity.js} +7 -7
  244. package/dist/lib/{events.d.ts → feed/events.d.ts} +2 -2
  245. package/dist/lib/{events.js → feed/events.js} +5 -5
  246. package/dist/lib/{feed.js → feed/feed.js} +4 -4
  247. package/dist/lib/feed-outcome.d.ts +1 -1
  248. package/dist/lib/feed-policy.d.ts +1 -1
  249. package/dist/lib/feed-policy.js +1 -1
  250. package/dist/lib/feed-post.d.ts +1 -1
  251. package/dist/lib/feed-post.js +1 -1
  252. package/dist/lib/feed-ranking.d.ts +1 -1
  253. package/dist/lib/fleet/apply.d.ts +0 -6
  254. package/dist/lib/fleet/apply.js +18 -45
  255. package/dist/lib/fleet/auth-sync.d.ts +16 -35
  256. package/dist/lib/fleet/auth-sync.js +16 -75
  257. package/dist/lib/fleet/capture.js +8 -6
  258. package/dist/lib/fleet/manifest.js +23 -11
  259. package/dist/lib/fleet/types.d.ts +19 -7
  260. package/dist/lib/fleet-cache.d.ts +1 -1
  261. package/dist/lib/fleet-cache.js +1 -1
  262. package/dist/lib/format.d.ts +19 -0
  263. package/dist/lib/format.js +44 -1
  264. package/dist/lib/friction-heuristics.d.ts +1 -1
  265. package/dist/lib/git.d.ts +24 -1
  266. package/dist/lib/git.js +82 -38
  267. package/dist/lib/heal.js +3 -3
  268. package/dist/lib/hooks.d.ts +18 -0
  269. package/dist/lib/hooks.js +113 -1
  270. package/dist/lib/hosts/credentials.d.ts +30 -10
  271. package/dist/lib/hosts/credentials.js +38 -26
  272. package/dist/lib/hosts/dispatch.d.ts +3 -3
  273. package/dist/lib/hosts/dispatch.js +3 -3
  274. package/dist/lib/hosts/option.d.ts +3 -3
  275. package/dist/lib/hosts/option.js +7 -8
  276. package/dist/lib/hosts/passthrough.d.ts +17 -17
  277. package/dist/lib/hosts/passthrough.js +67 -50
  278. package/dist/lib/hosts/providers/devices.d.ts +1 -1
  279. package/dist/lib/hosts/providers/devices.js +1 -1
  280. package/dist/lib/hosts/reconcile.d.ts +1 -1
  281. package/dist/lib/hosts/reconcile.js +1 -1
  282. package/dist/lib/hosts/reconnect.d.ts +1 -1
  283. package/dist/lib/hosts/reconnect.js +2 -2
  284. package/dist/lib/hosts/registry.d.ts +5 -5
  285. package/dist/lib/hosts/registry.js +5 -5
  286. package/dist/lib/hosts/remote-cmd.d.ts +10 -10
  287. package/dist/lib/hosts/remote-cmd.js +25 -18
  288. package/dist/lib/hosts/remote-os.d.ts +4 -4
  289. package/dist/lib/hosts/remote-os.js +4 -4
  290. package/dist/lib/hosts/remote-session-id.d.ts +2 -2
  291. package/dist/lib/hosts/remote-session-id.js +2 -2
  292. package/dist/lib/hosts/routing-flag.d.ts +3 -3
  293. package/dist/lib/hosts/routing-flag.js +4 -5
  294. package/dist/lib/hosts/run-target.d.ts +4 -4
  295. package/dist/lib/hosts/run-target.js +4 -4
  296. package/dist/lib/hosts/session-index.d.ts +2 -2
  297. package/dist/lib/hosts/session-index.js +1 -1
  298. package/dist/lib/hosts/session-marker.d.ts +1 -1
  299. package/dist/lib/hosts/session-marker.js +1 -1
  300. package/dist/lib/hosts/types.d.ts +2 -2
  301. package/dist/lib/hosts/types.js +2 -2
  302. package/dist/lib/import.js +1 -1
  303. package/dist/lib/{migrate.d.ts → installations/migrate.d.ts} +13 -1
  304. package/dist/lib/{migrate.js → installations/migrate.js} +160 -40
  305. package/dist/lib/installations/resolve.js +1 -1
  306. package/dist/lib/installations/strategies.js +1 -1
  307. package/dist/lib/installations/update.js +2 -2
  308. package/dist/lib/{versions.d.ts → installations/versions.d.ts} +12 -3
  309. package/dist/lib/{versions.js → installations/versions.js} +51 -31
  310. package/dist/lib/isolation-boundary-report.js +1 -1
  311. package/dist/lib/linear-projects.d.ts +28 -0
  312. package/dist/lib/linear-projects.js +30 -0
  313. package/dist/lib/loop.js +1 -1
  314. package/dist/lib/mailbox-gc.js +1 -1
  315. package/dist/lib/mailbox.js +1 -1
  316. package/dist/lib/mcp-registry.d.ts +62 -0
  317. package/dist/lib/mcp-registry.js +177 -0
  318. package/dist/lib/mcp.d.ts +5 -0
  319. package/dist/lib/mcp.js +124 -307
  320. package/dist/lib/menubar/MenubarHelper.app/Contents/CodeResources +0 -0
  321. package/dist/lib/menubar/MenubarHelper.app/Contents/MacOS/MenubarHelper +0 -0
  322. package/dist/lib/menubar/install-menubar.d.ts +7 -0
  323. package/dist/lib/menubar/install-menubar.js +24 -6
  324. package/dist/lib/menubar/snapshot.d.ts +7 -0
  325. package/dist/lib/menubar/snapshot.js +8 -6
  326. package/dist/lib/models.js +1 -1
  327. package/dist/lib/monitors/config.d.ts +12 -0
  328. package/dist/lib/monitors/config.js +3 -0
  329. package/dist/lib/monitors/dispatch.js +26 -5
  330. package/dist/lib/monitors/engine.js +10 -0
  331. package/dist/lib/monitors/sources/webhook.d.ts +1 -1
  332. package/dist/lib/monitors/state.d.ts +42 -0
  333. package/dist/lib/monitors/state.js +30 -0
  334. package/dist/lib/notify.d.ts +1 -1
  335. package/dist/lib/observe-aliases.d.ts +2 -2
  336. package/dist/lib/observe-aliases.js +2 -11
  337. package/dist/lib/output/git-output.js +2 -2
  338. package/dist/lib/overdue.d.ts +1 -1
  339. package/dist/lib/overdue.js +1 -1
  340. package/dist/lib/permissions-registry.d.ts +65 -0
  341. package/dist/lib/permissions-registry.js +599 -0
  342. package/dist/lib/permissions.d.ts +24 -13
  343. package/dist/lib/permissions.js +52 -271
  344. package/dist/lib/picker.d.ts +16 -0
  345. package/dist/lib/picker.js +33 -3
  346. package/dist/lib/placement.d.ts +1 -1
  347. package/dist/lib/placement.js +4 -4
  348. package/dist/lib/platform/paths.d.ts +8 -0
  349. package/dist/lib/platform/paths.js +11 -0
  350. package/dist/lib/platform/posixpath.js +3 -3
  351. package/dist/lib/{plugin-marketplace.d.ts → plugins/plugin-marketplace.d.ts} +1 -1
  352. package/dist/lib/{plugin-marketplace.js → plugins/plugin-marketplace.js} +2 -2
  353. package/dist/lib/{plugins.d.ts → plugins/plugins.d.ts} +1 -1
  354. package/dist/lib/{plugins.js → plugins/plugins.js} +7 -7
  355. package/dist/lib/{skills.d.ts → plugins/skills.d.ts} +1 -1
  356. package/dist/lib/{skills.js → plugins/skills.js} +7 -7
  357. package/dist/lib/pricing/cost.d.ts +1 -1
  358. package/dist/lib/pricing/cost.js +1 -1
  359. package/dist/lib/profiles-presets.d.ts +1 -1
  360. package/dist/lib/profiles-presets.js +1 -1
  361. package/dist/lib/profiles.js +2 -2
  362. package/dist/lib/project-import.js +4 -1
  363. package/dist/lib/project-launch.d.ts +1 -1
  364. package/dist/lib/project-launch.js +3 -3
  365. package/dist/lib/project-pull.d.ts +128 -0
  366. package/dist/lib/project-pull.js +384 -0
  367. package/dist/lib/project-root.d.ts +2 -2
  368. package/dist/lib/project-root.js +2 -2
  369. package/dist/lib/project-status.js +1 -1
  370. package/dist/lib/projects.d.ts +23 -0
  371. package/dist/lib/projects.js +29 -6
  372. package/dist/lib/refresh.d.ts +12 -1
  373. package/dist/lib/refresh.js +16 -9
  374. package/dist/lib/registry.d.ts +9 -2
  375. package/dist/lib/registry.js +11 -4
  376. package/dist/lib/resources.d.ts +2 -2
  377. package/dist/lib/resources.js +2 -2
  378. package/dist/lib/routers.d.ts +81 -0
  379. package/dist/lib/routers.js +153 -0
  380. package/dist/lib/routine-context.d.ts +1 -0
  381. package/dist/lib/routine-context.js +7 -2
  382. package/dist/lib/routine-notify-owner.d.ts +1 -1
  383. package/dist/lib/routine-notify.d.ts +1 -1
  384. package/dist/lib/routine-notify.js +1 -1
  385. package/dist/lib/routine-process-cleanup.d.ts +1 -1
  386. package/dist/lib/routine-readiness.d.ts +1 -1
  387. package/dist/lib/routine-readiness.js +11 -4
  388. package/dist/lib/routines-placement.d.ts +12 -2
  389. package/dist/lib/routines-placement.js +20 -3
  390. package/dist/lib/routines-project.d.ts +1 -1
  391. package/dist/lib/routines-project.js +1 -1
  392. package/dist/lib/rules/compile.d.ts +1 -0
  393. package/dist/lib/rules/compile.js +10 -2
  394. package/dist/lib/rules/rules.js +1 -1
  395. package/dist/lib/run-notify.js +1 -1
  396. package/dist/lib/runner.d.ts +80 -2
  397. package/dist/lib/runner.js +241 -62
  398. package/dist/lib/sandbox.d.ts +1 -1
  399. package/dist/lib/scheduler.d.ts +1 -1
  400. package/dist/lib/scheduler.js +1 -1
  401. package/dist/lib/{routines.d.ts → scheduling/routines.d.ts} +54 -9
  402. package/dist/lib/{routines.js → scheduling/routines.js} +173 -14
  403. package/dist/lib/secrets/Agents CLI.app/Contents/CodeResources +0 -0
  404. package/dist/lib/secrets/Agents CLI.app/Contents/MacOS/Agents CLI +0 -0
  405. package/dist/lib/secrets/agent.js +2 -2
  406. package/dist/lib/secrets/audit.js +1 -1
  407. package/dist/lib/secrets/bundles.d.ts +3 -3
  408. package/dist/lib/secrets/bundles.js +7 -7
  409. package/dist/lib/secrets/index.js +1 -1
  410. package/dist/lib/secrets/list-filter.d.ts +1 -1
  411. package/dist/lib/secrets/list-filter.js +2 -2
  412. package/dist/lib/secrets/push.d.ts +1 -1
  413. package/dist/lib/secrets/push.js +10 -12
  414. package/dist/lib/secrets/remote.d.ts +12 -10
  415. package/dist/lib/secrets/remote.js +21 -14
  416. package/dist/lib/secrets/vault.js +2 -2
  417. package/dist/lib/self-heal/checks/shadowing.js +1 -1
  418. package/dist/lib/self-heal/checks/shims.js +1 -1
  419. package/dist/lib/self-update.d.ts +39 -4
  420. package/dist/lib/self-update.js +78 -25
  421. package/dist/lib/serve/control.d.ts +1 -1
  422. package/dist/lib/serve/control.js +4 -4
  423. package/dist/lib/serve/data.d.ts +1 -1
  424. package/dist/lib/serve/data.js +1 -1
  425. package/dist/lib/serve/stream.js +1 -1
  426. package/dist/lib/service-manifest.d.ts +29 -0
  427. package/dist/lib/service-manifest.js +80 -0
  428. package/dist/lib/session/active.d.ts +59 -7
  429. package/dist/lib/session/active.js +158 -17
  430. package/dist/lib/session/bash-command.js +1 -1
  431. package/dist/lib/session/claude-accounts.d.ts +1 -1
  432. package/dist/lib/session/claude-accounts.js +1 -1
  433. package/dist/lib/session/db.d.ts +10 -2
  434. package/dist/lib/session/db.js +25 -6
  435. package/dist/lib/session/discover.d.ts +77 -0
  436. package/dist/lib/session/discover.js +130 -25
  437. package/dist/lib/session/fork.js +1 -1
  438. package/dist/lib/session/inject.d.ts +1 -1
  439. package/dist/lib/session/insights.d.ts +1 -1
  440. package/dist/lib/session/insights.js +1 -1
  441. package/dist/lib/session/live-metadata.d.ts +15 -0
  442. package/dist/lib/session/live-metadata.js +76 -0
  443. package/dist/lib/session/migrate-targets.d.ts +1 -1
  444. package/dist/lib/session/recovery.d.ts +1 -1
  445. package/dist/lib/session/recovery.js +2 -2
  446. package/dist/lib/session/remote-active.d.ts +10 -1
  447. package/dist/lib/session/remote-active.js +8 -3
  448. package/dist/lib/session/remote-bundle.d.ts +1 -1
  449. package/dist/lib/session/remote-bundle.js +2 -2
  450. package/dist/lib/session/remote-list.d.ts +15 -4
  451. package/dist/lib/session/remote-list.js +40 -3
  452. package/dist/lib/session/remote.d.ts +5 -5
  453. package/dist/lib/session/remote.js +13 -17
  454. package/dist/lib/session/resume-command.d.ts +3 -2
  455. package/dist/lib/session/resume-command.js +4 -3
  456. package/dist/lib/session/resume-owner.d.ts +3 -3
  457. package/dist/lib/session/resume-owner.js +3 -3
  458. package/dist/lib/session/session-cache.d.ts +12 -0
  459. package/dist/lib/session/session-cache.js +2 -0
  460. package/dist/lib/session/shell-programs.js +1 -1
  461. package/dist/lib/session/state.js +5 -5
  462. package/dist/lib/session/team-filter.d.ts +1 -1
  463. package/dist/lib/session/team-filter.js +1 -1
  464. package/dist/lib/session/types.d.ts +3 -3
  465. package/dist/lib/session/width.d.ts +2 -2
  466. package/dist/lib/session/width.js +2 -2
  467. package/dist/lib/share/delete.d.ts +21 -0
  468. package/dist/lib/share/delete.js +42 -0
  469. package/dist/lib/share/publish.d.ts +82 -0
  470. package/dist/lib/share/publish.js +170 -18
  471. package/dist/lib/share/worker-template.js +172 -9
  472. package/dist/lib/shims.js +35 -7
  473. package/dist/lib/smart-launch.d.ts +4 -4
  474. package/dist/lib/smart-launch.js +6 -4
  475. package/dist/lib/snapshot.d.ts +4 -4
  476. package/dist/lib/snapshot.js +2 -2
  477. package/dist/lib/ssh-exec.d.ts +1 -1
  478. package/dist/lib/ssh-exec.js +2 -2
  479. package/dist/lib/ssh-tunnel.d.ts +10 -10
  480. package/dist/lib/ssh-tunnel.js +12 -12
  481. package/dist/lib/staleness/checkers/hooks.d.ts +1 -1
  482. package/dist/lib/staleness/checkers/hooks.js +1 -1
  483. package/dist/lib/staleness/detectors/permissions.js +0 -23
  484. package/dist/lib/staleness/detectors/plugins.js +1 -1
  485. package/dist/lib/staleness/fingerprint.js +1 -1
  486. package/dist/lib/staleness/layers.d.ts +1 -1
  487. package/dist/lib/staleness/layers.js +1 -1
  488. package/dist/lib/staleness/writers/mcp.js +3 -1
  489. package/dist/lib/staleness/writers/plugins.js +1 -1
  490. package/dist/lib/staleness/writers/types.d.ts +8 -0
  491. package/dist/lib/startup/command-registry.d.ts +5 -147
  492. package/dist/lib/startup/command-registry.js +38 -303
  493. package/dist/lib/startup/dev-build.d.ts +0 -21
  494. package/dist/lib/startup/dev-build.js +29 -8
  495. package/dist/lib/state.d.ts +19 -1
  496. package/dist/lib/state.js +120 -51
  497. package/dist/lib/subagents.js +1 -1
  498. package/dist/lib/sync-status.js +1 -1
  499. package/dist/lib/sync-umbrella.d.ts +6 -1
  500. package/dist/lib/sync-umbrella.js +9 -4
  501. package/dist/lib/teams/agents.js +2 -2
  502. package/dist/lib/teams/registry.js +1 -1
  503. package/dist/lib/terminal/backends/vscodium-agent.js +1 -1
  504. package/dist/lib/terminal/engine.js +1 -1
  505. package/dist/lib/terminal/index.d.ts +4 -0
  506. package/dist/lib/terminal/index.js +3 -0
  507. package/dist/lib/terminal/inject.d.ts +2 -2
  508. package/dist/lib/terminal/inject.js +2 -2
  509. package/dist/lib/terminal/transport.js +1 -1
  510. package/dist/lib/tmux/index.d.ts +1 -1
  511. package/dist/lib/tmux/index.js +1 -1
  512. package/dist/lib/tmux/session.d.ts +21 -5
  513. package/dist/lib/tmux/session.js +76 -22
  514. package/dist/lib/triggers/handlers.d.ts +1 -1
  515. package/dist/lib/triggers/handlers.js +2 -2
  516. package/dist/lib/triggers/webhook.d.ts +36 -2
  517. package/dist/lib/triggers/webhook.js +97 -42
  518. package/dist/lib/types.d.ts +18 -6
  519. package/dist/lib/usage-fleet.d.ts +1 -1
  520. package/dist/lib/usage-fleet.js +1 -1
  521. package/dist/lib/usage-refresh.d.ts +1 -1
  522. package/dist/lib/usage-refresh.js +3 -3
  523. package/dist/lib/version-duplicates.js +2 -2
  524. package/dist/lib/view-types.d.ts +56 -0
  525. package/dist/lib/view-types.js +1 -0
  526. package/dist/lib/watchdog/rotate.d.ts +2 -2
  527. package/dist/lib/watchdog/rotate.js +3 -3
  528. package/dist/lib/watchdog/runner.d.ts +2 -3
  529. package/dist/lib/watchdog/runner.js +3 -4
  530. package/dist/lib/workflows.js +1 -1
  531. package/package.json +2 -1
  532. package/scripts/postinstall.js +2 -2
  533. package/dist/commands/bench.d.ts +0 -2
  534. package/dist/commands/bench.js +0 -101
  535. package/dist/commands/cp.d.ts +0 -84
  536. package/dist/commands/cp.js +0 -231
  537. package/dist/commands/login.d.ts +0 -2
  538. package/dist/lib/resources/commands.d.ts +0 -46
  539. package/dist/lib/resources/commands.js +0 -211
  540. package/dist/lib/resources/hooks.d.ts +0 -16
  541. package/dist/lib/resources/hooks.js +0 -153
  542. package/dist/lib/resources/mcp.d.ts +0 -34
  543. package/dist/lib/resources/mcp.js +0 -250
  544. package/dist/lib/resources/memory.d.ts +0 -15
  545. package/dist/lib/resources/memory.js +0 -46
  546. package/dist/lib/resources/permissions.d.ts +0 -13
  547. package/dist/lib/resources/permissions.js +0 -202
  548. package/dist/lib/resources/rules.d.ts +0 -46
  549. package/dist/lib/resources/rules.js +0 -179
  550. package/dist/lib/resources/skills.d.ts +0 -37
  551. package/dist/lib/resources/skills.js +0 -247
  552. package/dist/lib/resources/subagents.d.ts +0 -46
  553. package/dist/lib/resources/subagents.js +0 -202
  554. /package/dist/lib/{feed.d.ts → feed/feed.d.ts} +0 -0
@@ -0,0 +1,599 @@
1
+ /**
2
+ * Declarative permission-target registry.
3
+ *
4
+ * Every allowlist-capable agent gets ONE entry (`PERMISSION_TARGETS`) describing
5
+ * where its permissions live and how to read that file back into the canonical
6
+ * `PermissionSet`. `agents permissions list <agent>` and the config-file import
7
+ * behind `agents permissions add <path>` used to dispatch through hand-written
8
+ * 3-arm switches while
9
+ * `applyPermissionsToVersion` wrote 13 harnesses, so permissions were written
10
+ * for cursor, antigravity, grok, kimi, droid, copilot, kiro, openclaw and
11
+ * hermes and then reported as absent for all ten (RUSH-2676).
12
+ *
13
+ * The key set is pinned to `capableAgents('allowlist')` by
14
+ * `permissions-registry.test.ts`, mirroring `SUBAGENT_TARGETS` — the pattern the
15
+ * repo's own AGENTS.md names for cross-harness capabilities. A newly added
16
+ * allowlist harness cannot be written-but-unreadable: it must land an entry here
17
+ * in the same change.
18
+ *
19
+ * This module also OWNS the canonical<->native tool vocabularies. `permissions.ts`
20
+ * imports them for the forward (canonical -> native) serializers, and the reverse
21
+ * projections below are derived from the same tables, so the two directions
22
+ * cannot drift into disagreeing about what `developer__shell` or `fs_read` means.
23
+ *
24
+ * ## Every reverse projection is lossy, and says how
25
+ *
26
+ * The forward direction discards information — several canonical tools collapse
27
+ * onto one native id (`Read`/`Grep`/`Glob` all become Kiro's `fs_read`), and
28
+ * pattern grammars differ (`git:*` becomes `git *`). Reading back therefore
29
+ * recovers a permission set that GRANTS THE SAME ACCESS, not the byte-identical
30
+ * strings that were written. Each target documents its own collapse. Callers that
31
+ * need a faithful record of what agents-cli installed should read the central
32
+ * `~/.agents/permissions/` set, not a harness's config.
33
+ */
34
+ import * as fs from 'fs';
35
+ import * as os from 'os';
36
+ import * as path from 'path';
37
+ import * as yaml from 'yaml';
38
+ import * as TOML from 'smol-toml';
39
+ // ── canonical <-> native tool vocabularies (single source of truth) ──────────
40
+ /** Canonical tool (lowercased) -> Grok's lowercase tool vocabulary. */
41
+ export const GROK_TOOL_BY_CANONICAL = {
42
+ bash: 'bash',
43
+ read: 'read',
44
+ write: 'edit',
45
+ grep: 'grep',
46
+ webfetch: 'webfetch',
47
+ };
48
+ /** Canonical tool -> Kiro CLI v3 capability id. */
49
+ export const KIRO_CAPABILITY_BY_TOOL = {
50
+ bash: 'shell',
51
+ read: 'fs_read',
52
+ grep: 'fs_read',
53
+ glob: 'fs_read',
54
+ write: 'fs_write',
55
+ edit: 'fs_write',
56
+ notebookedit: 'fs_write',
57
+ webfetch: 'web_fetch',
58
+ websearch: 'web_search',
59
+ mcp: 'mcp',
60
+ subagent: 'subagent',
61
+ skill: 'skill',
62
+ };
63
+ /** Canonical tool -> OpenClaw tool id (tool-level granularity only). */
64
+ export const CANONICAL_TO_OPENCLAW_TOOL = {
65
+ bash: 'exec',
66
+ read: 'read',
67
+ write: 'write',
68
+ edit: 'write',
69
+ webfetch: 'web_fetch',
70
+ websearch: 'web_search',
71
+ };
72
+ /** Canonical tool -> Antigravity's action namespace. */
73
+ export const ANTIGRAVITY_ACTION_BY_TOOL = {
74
+ bash: 'command',
75
+ read: 'read_file',
76
+ write: 'write_file',
77
+ webfetch: 'read_url',
78
+ };
79
+ /**
80
+ * Invert a forward map, keeping the FIRST canonical tool that maps to each
81
+ * native id. Several canonical tools collapse onto one native id, so the
82
+ * inverse must pick a representative; declaration order in the forward table is
83
+ * that choice, which is why `read` (declared before `grep`/`glob`) represents
84
+ * Kiro's `fs_read`.
85
+ */
86
+ function invertFirstWins(forward) {
87
+ const out = {};
88
+ for (const [canonical, native] of Object.entries(forward)) {
89
+ if (!native)
90
+ continue;
91
+ if (!(native in out))
92
+ out[native] = canonical;
93
+ }
94
+ return out;
95
+ }
96
+ const CANONICAL_BY_GROK_TOOL = invertFirstWins(GROK_TOOL_BY_CANONICAL);
97
+ const CANONICAL_BY_KIRO_CAPABILITY = invertFirstWins(KIRO_CAPABILITY_BY_TOOL);
98
+ const CANONICAL_BY_OPENCLAW_TOOL = invertFirstWins(CANONICAL_TO_OPENCLAW_TOOL);
99
+ const CANONICAL_BY_ANTIGRAVITY_ACTION = invertFirstWins(ANTIGRAVITY_ACTION_BY_TOOL);
100
+ /** Canonical TitleCase spelling for a lowercased canonical tool name. */
101
+ const CANONICAL_TOOL_CASE = {
102
+ bash: 'Bash',
103
+ read: 'Read',
104
+ write: 'Write',
105
+ edit: 'Edit',
106
+ grep: 'Grep',
107
+ glob: 'Glob',
108
+ notebookedit: 'NotebookEdit',
109
+ webfetch: 'WebFetch',
110
+ websearch: 'WebSearch',
111
+ mcp: 'Mcp',
112
+ subagent: 'Subagent',
113
+ skill: 'Skill',
114
+ };
115
+ function titleCaseTool(lower) {
116
+ return CANONICAL_TOOL_CASE[lower] ?? lower;
117
+ }
118
+ /**
119
+ * Inverse of the serializers' `normalizeBashPattern`: native grammars spell a
120
+ * command's arg-glob `git *`, canonical spells it `git:*`. `*` stays `*`.
121
+ */
122
+ function denormalizeBashPattern(pattern) {
123
+ if (pattern === '*' || pattern === '**')
124
+ return '*';
125
+ if (pattern.endsWith(' *'))
126
+ return `${pattern.slice(0, -2)}:*`;
127
+ return pattern;
128
+ }
129
+ /** Build a canonical rule string, collapsing a blanket pattern to the tool's wildcard. */
130
+ function canonicalRule(lowerTool, pattern) {
131
+ const tool = titleCaseTool(lowerTool);
132
+ if (pattern === null)
133
+ return lowerTool === 'bash' ? 'Bash(*)' : `${tool}(**)`;
134
+ return `${tool}(${pattern})`;
135
+ }
136
+ /** Assemble a PermissionSet, dropping empty arrays so callers can test truthiness. */
137
+ function permissionSet(allow, deny) {
138
+ const uniqueAllow = [...new Set(allow)];
139
+ const uniqueDeny = [...new Set(deny)];
140
+ if (uniqueAllow.length === 0 && uniqueDeny.length === 0)
141
+ return null;
142
+ return {
143
+ name: 'exported',
144
+ allow: uniqueAllow,
145
+ ...(uniqueDeny.length ? { deny: uniqueDeny } : {}),
146
+ };
147
+ }
148
+ // ── file readers ─────────────────────────────────────────────────────────────
149
+ /**
150
+ * Strip JSON comments for JSONC parsing, only OUTSIDE string literals.
151
+ *
152
+ * A naive `//`-to-end-of-line regex destroys
153
+ * `"$schema": "https://opencode.ai/config.json"` — which every
154
+ * opencode-generated config carries — so the file then fails to parse and its
155
+ * permissions read back as absent, the very defect this registry exists to fix.
156
+ * Exported so `permissions.ts` shares this one implementation instead of
157
+ * keeping its own copy.
158
+ */
159
+ export function stripJsonComments(content) {
160
+ let result = '';
161
+ let inString = false;
162
+ let escape = false;
163
+ let i = 0;
164
+ while (i < content.length) {
165
+ const char = content[i];
166
+ const next = content[i + 1];
167
+ if (escape) {
168
+ result += char;
169
+ escape = false;
170
+ i++;
171
+ continue;
172
+ }
173
+ if (char === '\\' && inString) {
174
+ result += char;
175
+ escape = true;
176
+ i++;
177
+ continue;
178
+ }
179
+ if (char === '"') {
180
+ inString = !inString;
181
+ result += char;
182
+ i++;
183
+ continue;
184
+ }
185
+ if (!inString) {
186
+ if (char === '/' && next === '/') {
187
+ while (i < content.length && content[i] !== '\n') {
188
+ i++;
189
+ }
190
+ continue;
191
+ }
192
+ if (char === '/' && next === '*') {
193
+ i += 2;
194
+ while (i < content.length && !(content[i] === '*' && content[i + 1] === '/')) {
195
+ i++;
196
+ }
197
+ i += 2;
198
+ continue;
199
+ }
200
+ }
201
+ result += char;
202
+ i++;
203
+ }
204
+ return result;
205
+ }
206
+ function readJson(configPath) {
207
+ if (!fs.existsSync(configPath))
208
+ return null;
209
+ try {
210
+ const raw = fs.readFileSync(configPath, 'utf-8');
211
+ const parsed = JSON.parse(configPath.endsWith('.jsonc') ? stripJsonComments(raw) : raw);
212
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
213
+ ? parsed
214
+ : null;
215
+ }
216
+ catch {
217
+ return null;
218
+ }
219
+ }
220
+ function readYaml(configPath) {
221
+ if (!fs.existsSync(configPath))
222
+ return null;
223
+ try {
224
+ const parsed = yaml.parse(fs.readFileSync(configPath, 'utf-8'));
225
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
226
+ ? parsed
227
+ : null;
228
+ }
229
+ catch {
230
+ return null;
231
+ }
232
+ }
233
+ function readToml(configPath) {
234
+ if (!fs.existsSync(configPath))
235
+ return null;
236
+ try {
237
+ return TOML.parse(fs.readFileSync(configPath, 'utf-8'));
238
+ }
239
+ catch {
240
+ return null;
241
+ }
242
+ }
243
+ /** `preferred` unless it is absent and `alternate` exists. */
244
+ function existingOr(preferred, alternate) {
245
+ return !fs.existsSync(preferred) && fs.existsSync(alternate) ? alternate : preferred;
246
+ }
247
+ /** Every string in `value` when it is a string array, else []. */
248
+ function stringList(value) {
249
+ return Array.isArray(value) ? value.filter((v) => typeof v === 'string') : [];
250
+ }
251
+ /**
252
+ * Single source of truth for where each allowlist-capable agent stores
253
+ * permissions and how to read them back. Keys MUST equal
254
+ * `capableAgents('allowlist')` — pinned by `permissions-registry.test.ts`.
255
+ */
256
+ export const PERMISSION_TARGETS = {
257
+ claude: {
258
+ home: (h) => path.join(h, '.claude', 'settings.json'),
259
+ project: (cwd) => path.join(cwd, '.claude', 'settings.json'),
260
+ lossyBecause: 'canonical Write(...) is written as Edit(...), so it reads back as Edit',
261
+ toCanonical(configPath) {
262
+ const config = readJson(configPath);
263
+ const perms = config?.permissions;
264
+ if (!perms || typeof perms !== 'object' || Array.isArray(perms))
265
+ return null;
266
+ const p = perms;
267
+ const set = permissionSet(stringList(p.allow), stringList(p.deny));
268
+ const dirs = stringList(p.additionalDirectories);
269
+ if (set && dirs.length)
270
+ set.additionalDirectories = dirs;
271
+ return set;
272
+ },
273
+ },
274
+ opencode: {
275
+ // OpenCode accepts either extension and `openCodeConfigPath` probes both, so
276
+ // an existing `opencode.json` must be found rather than shadowed by the
277
+ // `.jsonc` default.
278
+ home: (h) => existingOr(path.join(h, '.config', 'opencode', 'opencode.jsonc'), path.join(h, '.config', 'opencode', 'opencode.json')),
279
+ project: (cwd) => existingOr(path.join(cwd, 'opencode.jsonc'), path.join(cwd, 'opencode.json')),
280
+ // BOTH spellings, for home and project. The preferred one needs an entry
281
+ // too: `home('')`/`project('')` resolve it through `existingOr`, which
282
+ // probes, so leaving it out left `opencode.jsonc` detection cwd-dependent.
283
+ altSuffixes: [
284
+ path.join('.config', 'opencode', 'opencode.jsonc'),
285
+ path.join('.config', 'opencode', 'opencode.json'),
286
+ 'opencode.jsonc',
287
+ 'opencode.json',
288
+ ],
289
+ lossyBecause: 'OpenCode gates Bash only, so non-Bash rules were never written',
290
+ toCanonical(configPath) {
291
+ const config = readJson(configPath);
292
+ const permission = config?.permission;
293
+ if (!permission || typeof permission !== 'object' || Array.isArray(permission))
294
+ return null;
295
+ const bash = permission.bash;
296
+ if (!bash || typeof bash !== 'object' || Array.isArray(bash))
297
+ return null;
298
+ const allow = [];
299
+ const deny = [];
300
+ for (const [pattern, action] of Object.entries(bash)) {
301
+ if (action === 'allow')
302
+ allow.push(`Bash(${pattern})`);
303
+ else if (action === 'deny')
304
+ deny.push(`Bash(${pattern})`);
305
+ }
306
+ return permissionSet(allow, deny);
307
+ },
308
+ },
309
+ codex: {
310
+ home: (h) => path.join(h, '.codex', 'config.toml'),
311
+ project: (cwd) => path.join(cwd, '.codex', 'config.toml'),
312
+ lossyBecause: 'Codex has no rule list — its sandbox mode is widened into representative blanket grants',
313
+ toCanonical(configPath) {
314
+ const config = readToml(configPath);
315
+ if (!config)
316
+ return null;
317
+ const allow = [];
318
+ const sandboxMode = config.sandbox_mode;
319
+ if (config.approval_policy === 'never' || sandboxMode === 'danger-full-access') {
320
+ allow.push('Bash(*)', 'Read(**)', 'Write(**)', 'Edit(**)');
321
+ }
322
+ else if (sandboxMode === 'workspace-write') {
323
+ allow.push('Bash(*)', 'Read(**)');
324
+ }
325
+ const sw = config.sandbox_workspace_write;
326
+ if (sw && typeof sw === 'object' && !Array.isArray(sw) && sw.network_access) {
327
+ allow.push('WebSearch(*)', 'WebFetch(*)');
328
+ }
329
+ return permissionSet(allow, []);
330
+ },
331
+ },
332
+ cursor: {
333
+ home: (h) => path.join(h, '.cursor', 'cli-config.json'),
334
+ lossyBecause: 'canonical Bash reads back from Shell(...) and Edit was written as Write(...)',
335
+ toCanonical(configPath) {
336
+ const config = readJson(configPath);
337
+ const perms = config?.permissions;
338
+ if (!perms || typeof perms !== 'object' || Array.isArray(perms))
339
+ return null;
340
+ const p = perms;
341
+ // Cursor spells Bash as Shell(...) and canonical WebSearch as WebFetch(...).
342
+ const back = (rule) => rule.startsWith('Shell') ? rule.replace(/^Shell/, 'Bash') : rule;
343
+ return permissionSet(stringList(p.allow).map(back), stringList(p.deny).map(back));
344
+ },
345
+ },
346
+ antigravity: {
347
+ home: (h) => path.join(h, '.gemini', 'antigravity-cli', 'settings.json'),
348
+ lossyBecause: 'only command/read_file/write_file/read_url map, so other canonical tools were never written',
349
+ toCanonical(configPath) {
350
+ const config = readJson(configPath);
351
+ const perms = config?.permissions;
352
+ if (!perms || typeof perms !== 'object' || Array.isArray(perms))
353
+ return null;
354
+ const p = perms;
355
+ const back = (entries) => {
356
+ const out = [];
357
+ for (const entry of entries) {
358
+ const m = entry.match(/^(\w+)\((.*)\)$/);
359
+ if (!m)
360
+ continue;
361
+ const lowerTool = CANONICAL_BY_ANTIGRAVITY_ACTION[m[1]];
362
+ if (!lowerTool)
363
+ continue;
364
+ const pattern = lowerTool === 'bash' ? denormalizeBashPattern(m[2]) : m[2];
365
+ out.push(canonicalRule(lowerTool, pattern));
366
+ }
367
+ return out;
368
+ };
369
+ return permissionSet(back(stringList(p.allow)), back(stringList(p.deny)));
370
+ },
371
+ },
372
+ grok: {
373
+ home: (h) => path.join(h, '.grok', 'config.toml'),
374
+ lossyBecause: 'canonical Write is written as Grok `edit`, so it reads back as Edit',
375
+ toCanonical(configPath) {
376
+ const config = readToml(configPath);
377
+ const permission = config?.permission;
378
+ if (!permission || typeof permission !== 'object' || Array.isArray(permission))
379
+ return null;
380
+ const rules = permission.rules;
381
+ if (!Array.isArray(rules))
382
+ return null;
383
+ const allow = [];
384
+ const deny = [];
385
+ for (const rule of rules) {
386
+ if (!rule || typeof rule !== 'object' || Array.isArray(rule))
387
+ continue;
388
+ const r = rule;
389
+ if (typeof r.tool !== 'string')
390
+ continue;
391
+ const lowerTool = CANONICAL_BY_GROK_TOOL[r.tool];
392
+ if (!lowerTool)
393
+ continue;
394
+ const raw = typeof r.pattern === 'string' ? r.pattern : null;
395
+ const pattern = raw === null ? null : lowerTool === 'bash' ? denormalizeBashPattern(raw) : raw;
396
+ const canonical = canonicalRule(lowerTool, pattern);
397
+ if (r.action === 'deny')
398
+ deny.push(canonical);
399
+ else if (r.action === 'allow')
400
+ allow.push(canonical);
401
+ }
402
+ return permissionSet(allow, deny);
403
+ },
404
+ },
405
+ kimi: {
406
+ home: (h) => path.join(h, '.kimi-code', 'config.toml'),
407
+ lossyBecause: 'each Bash arg-glob was written as two picomatch patterns, which collapse back to one rule',
408
+ toCanonical(configPath) {
409
+ const config = readToml(configPath);
410
+ const permission = config?.permission;
411
+ if (!permission || typeof permission !== 'object' || Array.isArray(permission))
412
+ return null;
413
+ const rules = permission.rules;
414
+ if (!Array.isArray(rules))
415
+ return null;
416
+ const allow = [];
417
+ const deny = [];
418
+ for (const rule of rules) {
419
+ if (!rule || typeof rule !== 'object' || Array.isArray(rule))
420
+ continue;
421
+ const r = rule;
422
+ if (typeof r.pattern !== 'string')
423
+ continue;
424
+ const canonical = kimiPatternToCanonical(r.pattern);
425
+ if (!canonical)
426
+ continue;
427
+ if (r.decision === 'deny')
428
+ deny.push(canonical);
429
+ else if (r.decision === 'allow')
430
+ allow.push(canonical);
431
+ }
432
+ return permissionSet(allow, deny);
433
+ },
434
+ },
435
+ droid: {
436
+ home: (h) => path.join(h, '.factory', 'settings.json'),
437
+ lossyBecause: 'Droid gates shell commands only, so non-Bash rules were never written',
438
+ toCanonical(configPath) {
439
+ const config = readJson(configPath);
440
+ if (!config)
441
+ return null;
442
+ const back = (commands) => commands.map((c) => (c === '*' ? 'Bash(*)' : `Bash(${denormalizeBashPattern(c)})`));
443
+ return permissionSet(back(stringList(config.commandAllowlist)), back(stringList(config.commandDenylist)));
444
+ },
445
+ },
446
+ copilot: {
447
+ home: (h) => path.join(h, '.copilot', 'permissions-config.json'),
448
+ lossyBecause: 'approvals are per working directory and read/write are whole-tool kinds with no path',
449
+ toCanonical(configPath) {
450
+ const config = readJson(configPath);
451
+ const locations = config?.locations;
452
+ if (!locations || typeof locations !== 'object' || Array.isArray(locations))
453
+ return null;
454
+ const allow = [];
455
+ // Copilot records approvals per location; the canonical set has no location
456
+ // axis, so every location's approvals union into one allow list.
457
+ for (const location of Object.values(locations)) {
458
+ if (!location || typeof location !== 'object' || Array.isArray(location))
459
+ continue;
460
+ const approvals = location.tool_approvals;
461
+ if (!Array.isArray(approvals))
462
+ continue;
463
+ for (const approval of approvals) {
464
+ if (!approval || typeof approval !== 'object' || Array.isArray(approval))
465
+ continue;
466
+ const a = approval;
467
+ if (a.kind === 'commands') {
468
+ for (const id of stringList(a.commandIdentifiers))
469
+ allow.push(`Bash(${id})`);
470
+ }
471
+ else if (a.kind === 'read') {
472
+ allow.push('Read(**)');
473
+ }
474
+ else if (a.kind === 'write') {
475
+ allow.push('Write(**)');
476
+ }
477
+ else if (a.kind === 'mcp' && typeof a.serverName === 'string') {
478
+ allow.push(`Mcp(${typeof a.toolName === 'string' ? `${a.serverName}.${a.toolName}` : a.serverName})`);
479
+ }
480
+ }
481
+ }
482
+ // Copilot's config records approvals (grants) only — it has no deny list.
483
+ return permissionSet(allow, []);
484
+ },
485
+ },
486
+ kiro: {
487
+ home: (h) => path.join(h, '.kiro', 'settings', 'permissions.yaml'),
488
+ lossyBecause: 'Read/Grep/Glob share fs_read and Write/Edit/NotebookEdit share fs_write',
489
+ toCanonical(configPath) {
490
+ const config = readYaml(configPath);
491
+ const rules = config?.rules;
492
+ if (!Array.isArray(rules))
493
+ return null;
494
+ const allow = [];
495
+ const deny = [];
496
+ for (const rule of rules) {
497
+ if (!rule || typeof rule !== 'object' || Array.isArray(rule))
498
+ continue;
499
+ const r = rule;
500
+ if (typeof r.capability !== 'string')
501
+ continue;
502
+ const lowerTool = CANONICAL_BY_KIRO_CAPABILITY[r.capability];
503
+ if (!lowerTool)
504
+ continue;
505
+ const matches = stringList(r.match);
506
+ const canonicals = matches.length
507
+ ? matches.map((m) => canonicalRule(lowerTool, lowerTool === 'bash' ? denormalizeBashPattern(m) : m))
508
+ : [canonicalRule(lowerTool, null)];
509
+ if (r.effect === 'deny')
510
+ deny.push(...canonicals);
511
+ else if (r.effect === 'allow')
512
+ allow.push(...canonicals);
513
+ }
514
+ return permissionSet(allow, deny);
515
+ },
516
+ },
517
+ openclaw: {
518
+ home: (h) => path.join(h, '.openclaw', 'openclaw.json'),
519
+ lossyBecause: 'OpenClaw gates whole tools, so only blanket rules were written and all read back as blanket',
520
+ toCanonical(configPath) {
521
+ const config = readJson(configPath);
522
+ const tools = config?.tools;
523
+ if (!tools || typeof tools !== 'object' || Array.isArray(tools))
524
+ return null;
525
+ const t = tools;
526
+ const back = (ids) => ids.flatMap((id) => {
527
+ const lowerTool = CANONICAL_BY_OPENCLAW_TOOL[id];
528
+ return lowerTool ? [canonicalRule(lowerTool, null)] : [];
529
+ });
530
+ // `tools.allow` is OpenClaw's absolute allowlist and is never written by
531
+ // agents-cli (see convertToOpenClawFormat), so it is not read back either.
532
+ return permissionSet(back(stringList(t.alsoAllow)), back(stringList(t.deny)));
533
+ },
534
+ },
535
+ hermes: {
536
+ home: (h) => path.join(h, '.hermes', 'config.yaml'),
537
+ lossyBecause: 'Hermes gates shell commands only, so non-Bash rules were never written',
538
+ toCanonical(configPath) {
539
+ const config = readYaml(configPath);
540
+ if (!config)
541
+ return null;
542
+ const approvals = config.approvals;
543
+ const denyList = approvals && typeof approvals === 'object' && !Array.isArray(approvals)
544
+ ? stringList(approvals.deny)
545
+ : [];
546
+ const back = (commands) => commands.map((c) => (c === '*' ? 'Bash(*)' : `Bash(${denormalizeBashPattern(c)})`));
547
+ return permissionSet(back(stringList(config.command_allowlist)), back(denyList));
548
+ },
549
+ },
550
+ };
551
+ /**
552
+ * Invert `kimiBashPatterns` + `canonicalToKimiRules`.
553
+ *
554
+ * Kimi writes a bare tool name for a blanket grant (`Bash`, `Read`), and expands
555
+ * one canonical `cmd:*` into TWO picomatch patterns (`Bash(cmd*)` and
556
+ * `Bash(cmd*​/**)`) so slash-bearing arguments match. Both collapse back to the
557
+ * single canonical rule, and the caller dedupes.
558
+ */
559
+ function kimiPatternToCanonical(pattern) {
560
+ const m = pattern.match(/^([\w-]+)\((.*)\)$/);
561
+ if (!m) {
562
+ // Bare tool name — a blanket grant, or an MCP tool id Kimi matches by name.
563
+ const lower = pattern.toLowerCase();
564
+ return lower in CANONICAL_TOOL_CASE ? canonicalRule(lower, null) : pattern;
565
+ }
566
+ const lowerTool = m[1].toLowerCase();
567
+ let arg = m[2];
568
+ if (lowerTool === 'bash') {
569
+ if (arg.endsWith('*/**'))
570
+ arg = arg.slice(0, -'*/**'.length) + ':*';
571
+ else if (arg.endsWith('*'))
572
+ arg = arg.slice(0, -1) + ':*';
573
+ if (arg === ':*')
574
+ return 'Bash(*)';
575
+ }
576
+ return canonicalRule(lowerTool, arg);
577
+ }
578
+ /** The registry entry for `agent`, or undefined when it stores no permissions. */
579
+ export function permissionTarget(agent) {
580
+ return PERMISSION_TARGETS[agent];
581
+ }
582
+ /**
583
+ * Read `agent`'s permissions from `home` (a version home or the real HOME) and
584
+ * project them to canonical form. `scope: 'project'` reads the repo-local file
585
+ * for the harnesses that have one, and returns null for those that do not.
586
+ */
587
+ export function readCanonicalPermissions(agent, scope = 'user', cwd, home) {
588
+ const target = PERMISSION_TARGETS[agent];
589
+ if (!target)
590
+ return null;
591
+ if (scope === 'project') {
592
+ if (!target.project)
593
+ return null;
594
+ return target.toCanonical(target.project(cwd ?? process.cwd()));
595
+ }
596
+ // os.homedir() -- not `process.env.HOME ?? ''`, which resolved a RELATIVE
597
+ // path (`.grok/config.toml`) when HOME is unset, as it is on Windows.
598
+ return target.toCanonical(target.home(home ?? os.homedir()));
599
+ }
@@ -165,15 +165,6 @@ export declare function convertToAntigravityFormat(set: PermissionSet): {
165
165
  deny?: string[];
166
166
  };
167
167
  };
168
- export interface GoosePermissionConfig {
169
- user: {
170
- always_allow: string[];
171
- ask_before: string[];
172
- never_allow: string[];
173
- };
174
- }
175
- /** Convert canonical permissions to Goose's per-tool permission.yaml shape. */
176
- export declare function convertToGooseFormat(set: PermissionSet): GoosePermissionConfig;
177
168
  /**
178
169
  * Convert canonical permission set to Grok format.
179
170
  * Grok reads ~/.grok/config.toml with
@@ -260,11 +251,21 @@ export declare function mergeCodexSandboxWrite(existing: Record<string, unknown>
260
251
  */
261
252
  export declare function convertToCodexFormat(set: PermissionSet, cwd?: string): CodexPermissions;
262
253
  /**
263
- * Read agent permissions based on agent ID.
254
+ * Read an agent's currently installed permissions.
255
+ *
256
+ * claude/opencode/codex return their NATIVE shape, because `agents permissions
257
+ * list` renders those three specially — Codex especially, whose config records a
258
+ * sandbox mode rather than a rule list, so its own fields say more than the
259
+ * blanket grants that mode widens into.
260
+ *
261
+ * Every other allowlist-capable harness returns the canonical `PermissionSet`
262
+ * that `PERMISSION_TARGETS` reads back. Before RUSH-2676 they returned `null`,
263
+ * so permissions written for cursor, antigravity, grok, kimi, droid,
264
+ * copilot, kiro, openclaw and hermes were reported as absent.
264
265
  */
265
266
  export declare function readAgentPermissions(agentId: AgentId, scope?: 'user' | 'project', cwd?: string, options?: {
266
267
  home?: string;
267
- }): ClaudePermissions | OpenCodePermissions | CodexPermissions | null;
268
+ }): ClaudePermissions | OpenCodePermissions | CodexPermissions | PermissionSet | null;
268
269
  /**
269
270
  * Apply a permission set to Claude's settings.json.
270
271
  */
@@ -300,10 +301,20 @@ export declare function openCodeToCanonical(perms: OpenCodePermissions): Permiss
300
301
  */
301
302
  export declare function codexToCanonical(perms: CodexPermissions): PermissionSet;
302
303
  /**
303
- * Export permissions from a specific config file path to canonical format.
304
- * Auto-detects agent type from file path/name.
304
+ * Export permissions from a specific config file path to canonical format,
305
+ * auto-detecting the harness from the path.
306
+ *
307
+ * Detection walks `PERMISSION_TARGETS` and matches each harness's own declared
308
+ * filename + parent directory, so it covers all 13 rather than the three
309
+ * hardcoded `.claude`/`.opencode`/`.codex` fragments it used to know about.
305
310
  */
306
311
  export declare function exportPermissionsFromPath(filePath: string): PermissionSet | null;
312
+ /**
313
+ * Which harness owns `filePath`, by comparing against the trailing path segments
314
+ * each registry target declares. Longer (more specific) suffixes win, so
315
+ * `.kiro/settings/permissions.yaml` is never mistaken for a bare `permissions.yaml`.
316
+ */
317
+ export declare function detectPermissionAgentFromPath(filePath: string): AgentId | null;
307
318
  /**
308
319
  * Get the default permission set from central storage.
309
320
  */