@north-light/crouter 0.3.349 → 0.3.350

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 (629) hide show
  1. package/bin/crtr-launcher +4 -0
  2. package/bin/runtime-generation-manifest.mjs +12 -2
  3. package/dist/api/client.d.ts +50 -7
  4. package/dist/api/client.js +2 -2
  5. package/dist/api/dto/analytics.d.ts +184 -0
  6. package/dist/api/dto/analytics.js +0 -0
  7. package/dist/api/dto/broker-ops.d.ts +43 -1
  8. package/dist/api/dto/config.d.ts +11 -0
  9. package/dist/api/dto/grants.d.ts +14 -0
  10. package/dist/api/dto/grants.js +0 -0
  11. package/dist/api/dto/human-requests.d.ts +14 -0
  12. package/dist/api/dto/memory.d.ts +6 -0
  13. package/dist/api/dto/modelauth.d.ts +35 -0
  14. package/dist/api/dto/node-records.d.ts +35 -0
  15. package/dist/api/dto/node-records.js +0 -0
  16. package/dist/api/dto/nodes.d.ts +5 -0
  17. package/dist/api/dto/profiles.d.ts +38 -3
  18. package/dist/api/dto/worktree.d.ts +11 -0
  19. package/dist/api/errors.d.ts +23 -1
  20. package/dist/api/errors.js +1 -1
  21. package/dist/api/index.d.ts +2 -0
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/node-transport.js +1 -1
  24. package/dist/api/routes.d.ts +22 -0
  25. package/dist/api/routes.js +1 -1
  26. package/dist/build-root.d.ts +6 -1
  27. package/dist/build-root.js +1 -1
  28. package/dist/builtin-memory/crouter-sdk/client.md +34 -0
  29. package/dist/builtin-memory/crouter-sdk/errors.md +2 -0
  30. package/dist/builtin-memory/crouter-sdk/memory.md +2 -2
  31. package/dist/builtin-memory/crouter-sdk/streaming.md +21 -0
  32. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/claude-plugin-commands.ts +8 -4
  33. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +39 -118
  34. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +6 -1
  35. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +41 -27
  36. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +52 -29
  37. package/dist/cli.js +9 -8
  38. package/dist/clients/attach/chrome/inbox-strip.js +1 -1
  39. package/dist/clients/attach/chrome/roster.js +1 -1
  40. package/dist/clients/attach/config.js +1 -1
  41. package/dist/clients/attach/overlays/auth.js +2 -2
  42. package/dist/clients/attach/overlays/graph.js +1 -1
  43. package/dist/clients/attach/render/tool-calls.js +3 -3
  44. package/dist/clients/attach/session/connection.js +1 -1
  45. package/dist/clients/attach/session/profile-files.js +1 -1
  46. package/dist/clients/attach/viewer.js +1569 -816
  47. package/dist/commands/api-client.js +3 -3
  48. package/dist/commands/broker-permissions.d.ts +2 -0
  49. package/dist/commands/broker-permissions.js +1 -0
  50. package/dist/commands/canvas-analytics/chart.d.ts +52 -0
  51. package/dist/commands/canvas-analytics/chart.js +1 -0
  52. package/dist/commands/canvas-analytics/drilldown.d.ts +34 -0
  53. package/dist/commands/canvas-analytics/drilldown.js +1 -0
  54. package/dist/commands/canvas-analytics/format.d.ts +29 -0
  55. package/dist/commands/canvas-analytics/format.js +1 -0
  56. package/dist/commands/canvas-analytics/graph-detail.d.ts +2 -0
  57. package/dist/commands/canvas-analytics/graph-detail.js +2 -0
  58. package/dist/commands/canvas-analytics/graphs.d.ts +9 -0
  59. package/dist/commands/canvas-analytics/graphs.js +1 -0
  60. package/dist/commands/canvas-analytics/memory.d.ts +2 -0
  61. package/dist/commands/canvas-analytics/memory.js +1 -0
  62. package/dist/commands/canvas-analytics/overview.d.ts +2 -0
  63. package/dist/commands/canvas-analytics/overview.js +1 -0
  64. package/dist/commands/canvas-analytics/shell.d.ts +60 -0
  65. package/dist/commands/canvas-analytics/shell.js +2 -0
  66. package/dist/commands/canvas-analytics/time.d.ts +2 -0
  67. package/dist/commands/canvas-analytics/time.js +1 -0
  68. package/dist/commands/canvas-analytics/usage.d.ts +2 -0
  69. package/dist/commands/canvas-analytics/usage.js +1 -0
  70. package/dist/commands/canvas-analytics/view.d.ts +85 -0
  71. package/dist/commands/canvas-analytics/view.js +1 -0
  72. package/dist/commands/canvas-analytics.d.ts +2 -0
  73. package/dist/commands/canvas-analytics.js +1 -0
  74. package/dist/commands/canvas-prune.js +1 -1
  75. package/dist/commands/canvas.js +1 -1
  76. package/dist/commands/cron.js +5 -5
  77. package/dist/commands/human/components.d.ts +2 -0
  78. package/dist/commands/human/components.js +2 -2
  79. package/dist/commands/human/prompts.js +1 -1
  80. package/dist/commands/human/queue.js +1 -1
  81. package/dist/commands/memory/client.d.ts +11 -0
  82. package/dist/commands/memory/client.js +1 -0
  83. package/dist/commands/memory/delete.js +1 -1
  84. package/dist/commands/memory/edit.js +3 -3
  85. package/dist/commands/memory/find.js +1 -1
  86. package/dist/commands/memory/history.js +4 -4
  87. package/dist/commands/memory/lint.js +1 -1
  88. package/dist/commands/memory/list.d.ts +0 -2
  89. package/dist/commands/memory/list.js +1 -1
  90. package/dist/commands/memory/move.js +1 -1
  91. package/dist/commands/memory/origin.js +1 -1
  92. package/dist/commands/memory/read.d.ts +0 -5
  93. package/dist/commands/memory/read.js +3 -3
  94. package/dist/commands/memory/shared.d.ts +0 -178
  95. package/dist/commands/memory/shared.js +1 -12
  96. package/dist/commands/memory/write.js +5 -5
  97. package/dist/commands/node/bash.js +5 -5
  98. package/dist/commands/node/create.d.ts +0 -17
  99. package/dist/commands/node/create.js +2 -3
  100. package/dist/commands/node/inspect.js +6 -6
  101. package/dist/commands/node/lifecycle.js +2 -2
  102. package/dist/commands/node-context.js +2 -2
  103. package/dist/commands/node-inspect-artifacts.js +6 -6
  104. package/dist/commands/pkg/browse/catalog.js +1 -1
  105. package/dist/commands/pkg/browse/model.d.ts +1 -1
  106. package/dist/commands/pkg/market-manage.js +1 -1
  107. package/dist/commands/pkg/plugin-manage.js +10 -10
  108. package/dist/commands/profile/daemon-profiles.d.ts +13 -0
  109. package/dist/commands/profile/daemon-profiles.js +4 -0
  110. package/dist/commands/profile/delete.js +1 -1
  111. package/dist/commands/profile/env.d.ts +6 -0
  112. package/dist/commands/profile/env.js +2 -2
  113. package/dist/commands/profile/kind.js +1 -2
  114. package/dist/commands/profile/list.js +1 -1
  115. package/dist/commands/profile/meta.js +1 -1
  116. package/dist/commands/profile/new.js +1 -1
  117. package/dist/commands/profile/pause.js +1 -1
  118. package/dist/commands/profile/project.js +1 -1
  119. package/dist/commands/profile/rename.js +1 -1
  120. package/dist/commands/profile/show.js +1 -1
  121. package/dist/commands/profile.js +1 -1
  122. package/dist/commands/push.js +3 -3
  123. package/dist/commands/surface-inspect.js +1 -1
  124. package/dist/commands/sys/branch.js +1 -1
  125. package/dist/commands/sys/config.js +1 -1
  126. package/dist/commands/sys/connect.js +3 -3
  127. package/dist/commands/sys/context/admin/actions.js +1 -1
  128. package/dist/commands/sys/context/admin/model.d.ts +1 -0
  129. package/dist/commands/sys/context/admin/model.js +1 -1
  130. package/dist/commands/sys/context/admin.js +1 -1
  131. package/dist/commands/sys/context/expose.js +2 -1
  132. package/dist/commands/sys/context/prompt-review.js +2 -2
  133. package/dist/commands/sys/context/resolve.js +7 -7
  134. package/dist/commands/sys/context/sysprompt.js +1 -1
  135. package/dist/commands/sys/join.d.ts +1 -0
  136. package/dist/commands/sys/join.js +1 -0
  137. package/dist/commands/sys/migrate.js +1 -1
  138. package/dist/commands/sys/panels/models-panel.js +1 -1
  139. package/dist/commands/sys/panels/profiles-panel.d.ts +0 -1
  140. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  141. package/dist/commands/sys/provider-login.js +6 -6
  142. package/dist/commands/sys/setup-core.d.ts +1 -1
  143. package/dist/commands/sys/setup-core.js +6 -6
  144. package/dist/commands/sys/setup-settings-runner.js +1 -1
  145. package/dist/commands/sys/setup.js +1 -1
  146. package/dist/commands/sys/spaces.d.ts +1 -0
  147. package/dist/commands/sys/spaces.js +2 -0
  148. package/dist/commands/sys/sync-deps.js +2 -2
  149. package/dist/commands/sys/sync-project-guidance.js +4 -4
  150. package/dist/commands/sys/sync-skills.js +2 -2
  151. package/dist/commands/sys/worktrees.d.ts +1 -0
  152. package/dist/commands/sys/worktrees.js +1 -1
  153. package/dist/commands/sys.js +1 -1
  154. package/dist/core/auth-file.js +2 -2
  155. package/dist/core/bash-job-supervisor.d.ts +6 -0
  156. package/dist/core/bash-job-supervisor.js +4 -0
  157. package/dist/core/bash-jobs.d.ts +13 -6
  158. package/dist/core/bash-jobs.js +8 -7
  159. package/dist/core/broker-client/transport-relay.d.ts +6 -3
  160. package/dist/core/broker-client/transport-relay.js +1 -1
  161. package/dist/core/broker-client/transport-socket.d.ts +6 -1
  162. package/dist/core/broker-client/transport-socket.js +1 -1
  163. package/dist/core/canvas/canvas.d.ts +39 -18
  164. package/dist/core/canvas/canvas.js +21 -20
  165. package/dist/core/canvas/context-strip.d.ts +20 -0
  166. package/dist/core/canvas/context-strip.js +5 -0
  167. package/dist/core/canvas/crons.d.ts +12 -20
  168. package/dist/core/canvas/crons.js +15 -13
  169. package/dist/core/canvas/db.js +2 -2
  170. package/dist/core/canvas/deliveries.d.ts +4 -1
  171. package/dist/core/canvas/deliveries.js +1 -1
  172. package/dist/core/canvas/executions.js +1 -1
  173. package/dist/core/canvas/history.d.ts +2 -1
  174. package/dist/core/canvas/history.js +17 -18
  175. package/dist/core/canvas/memory-reads.d.ts +19 -0
  176. package/dist/core/canvas/memory-reads.js +1 -0
  177. package/dist/core/canvas/migrations.d.ts +0 -4
  178. package/dist/core/canvas/migrations.js +99 -32
  179. package/dist/core/canvas/nav-render.js +1 -1
  180. package/dist/core/canvas/node-agent-paths.d.ts +8 -0
  181. package/dist/core/canvas/node-agent-paths.js +1 -0
  182. package/dist/core/canvas/node-recap.d.ts +2 -2
  183. package/dist/core/canvas/node-recap.js +2 -2
  184. package/dist/core/canvas/node-tokens.d.ts +24 -0
  185. package/dist/core/canvas/node-tokens.js +5 -0
  186. package/dist/core/canvas/paths.d.ts +16 -19
  187. package/dist/core/canvas/paths.js +1 -1
  188. package/dist/core/canvas/render-source.d.ts +2 -2
  189. package/dist/core/canvas/render-source.js +6 -9
  190. package/dist/core/canvas/sessions.d.ts +18 -0
  191. package/dist/core/canvas/sessions.js +4 -1
  192. package/dist/core/canvas/types.d.ts +22 -6
  193. package/dist/core/command-hooks/compose.js +1 -1
  194. package/dist/core/command-hooks/discovery.d.ts +15 -1
  195. package/dist/core/command-hooks/discovery.js +1 -1
  196. package/dist/core/command-hooks/help.d.ts +2 -2
  197. package/dist/core/command-hooks/lifecycle-create.d.ts +1 -1
  198. package/dist/core/command-hooks/lifecycle-create.js +1 -1
  199. package/dist/core/command-hooks/transport/exec-invoke.d.ts +2 -0
  200. package/dist/core/command-hooks/transport/exec-invoke.js +1 -1
  201. package/dist/core/command-hooks/transport/exec-lifecycle.d.ts +1 -0
  202. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  203. package/dist/core/command-hooks/transport/plan.d.ts +3 -0
  204. package/dist/core/command-hooks/transport/plan.js +1 -0
  205. package/dist/core/command-plugins/discovery.js +1 -1
  206. package/dist/core/command.d.ts +6 -2
  207. package/dist/core/command.js +6 -6
  208. package/dist/core/config.d.ts +8 -5
  209. package/dist/core/config.js +1 -1
  210. package/dist/core/conversation-store/client-worker.d.ts +1 -0
  211. package/dist/core/conversation-store/client-worker.js +1 -0
  212. package/dist/core/conversation-store/client.d.ts +2 -0
  213. package/dist/core/conversation-store/client.js +2 -0
  214. package/dist/core/conversation-store/file-store.d.ts +37 -0
  215. package/dist/core/conversation-store/file-store.js +9 -0
  216. package/dist/core/conversation-store/index.d.ts +50 -0
  217. package/dist/core/conversation-store/index.js +1 -0
  218. package/dist/core/conversation-store/listener.d.ts +4 -0
  219. package/dist/core/conversation-store/listener.js +3 -0
  220. package/dist/core/conversation-store/patch.d.ts +1 -0
  221. package/dist/core/conversation-store/patch.js +1 -0
  222. package/dist/core/directory/join.d.ts +27 -0
  223. package/dist/core/directory/join.js +1 -0
  224. package/dist/core/disk-usage.d.ts +4 -0
  225. package/dist/core/disk-usage.js +1 -0
  226. package/dist/core/events/emit.d.ts +2 -0
  227. package/dist/core/events/emit.js +3 -1
  228. package/dist/core/feed/feed.js +4 -4
  229. package/dist/core/feed/messages.d.ts +3 -0
  230. package/dist/core/feed/messages.js +6 -6
  231. package/dist/core/fs-utils.d.ts +2 -0
  232. package/dist/core/fs-utils.js +3 -3
  233. package/dist/core/grants/local.d.ts +4 -0
  234. package/dist/core/grants/local.js +1 -0
  235. package/dist/core/grants/mirror.d.ts +44 -0
  236. package/dist/core/grants/mirror.js +4 -0
  237. package/dist/core/grants/on-sync.d.ts +22 -0
  238. package/dist/core/grants/on-sync.js +1 -0
  239. package/dist/core/grants/remove.d.ts +7 -0
  240. package/dist/core/grants/remove.js +1 -0
  241. package/dist/core/grants/sandboxes.d.ts +7 -0
  242. package/dist/core/grants/sandboxes.js +1 -0
  243. package/dist/core/grants/sync.d.ts +12 -0
  244. package/dist/core/grants/sync.js +1 -0
  245. package/dist/core/help/memory-extensions.d.ts +3 -0
  246. package/dist/core/help/memory-extensions.js +2 -0
  247. package/dist/core/help.d.ts +14 -0
  248. package/dist/core/help.js +7 -7
  249. package/dist/core/host-exports/builtins.js +3 -3
  250. package/dist/core/host-exports/export.js +3 -3
  251. package/dist/core/human/action-binding.d.ts +2 -0
  252. package/dist/core/human/action-binding.js +1 -1
  253. package/dist/core/human/feedback-companion.d.ts +0 -1
  254. package/dist/core/human/feedback-companion.js +1 -1
  255. package/dist/core/human/page-schema.d.ts +1 -1
  256. package/dist/core/inspector/core.d.ts +2 -0
  257. package/dist/core/inspector/core.js +1 -1
  258. package/dist/core/inspector/tui.js +2 -2
  259. package/dist/core/installed-plugins.js +1 -1
  260. package/dist/core/io.js +6 -6
  261. package/dist/core/keybindings/catalog.d.ts +1 -1
  262. package/dist/core/keybindings/catalog.js +1 -1
  263. package/dist/core/layout-migrate/index.d.ts +15 -0
  264. package/dist/core/layout-migrate/index.js +4 -0
  265. package/dist/core/layout-migrate/paths.d.ts +26 -0
  266. package/dist/core/layout-migrate/paths.js +1 -0
  267. package/dist/core/layout-migrate/stored-paths.d.ts +2 -0
  268. package/dist/core/layout-migrate/stored-paths.js +11 -0
  269. package/dist/core/layout-migrate/stores.d.ts +17 -0
  270. package/dist/core/layout-migrate/stores.js +4 -0
  271. package/dist/core/layout.d.ts +26 -0
  272. package/dist/core/layout.js +2 -0
  273. package/dist/core/llm/run.d.ts +60 -0
  274. package/dist/core/llm/run.js +4 -0
  275. package/dist/core/memory/cli-selector.d.ts +13 -0
  276. package/dist/core/memory/cli-selector.js +1 -0
  277. package/dist/core/memory/history.d.ts +5 -4
  278. package/dist/core/memory/history.js +6 -6
  279. package/dist/core/memory/inline-ref-inventory.d.ts +2 -1
  280. package/dist/core/memory/inline-ref-inventory.js +1 -1
  281. package/dist/core/memory/lint.js +2 -2
  282. package/dist/core/memory/mutation-domain.d.ts +2 -2
  283. package/dist/core/memory/mutation-domain.js +8 -7
  284. package/dist/core/memory/mutations.js +1 -1
  285. package/dist/core/memory/service.d.ts +5 -0
  286. package/dist/core/memory/service.js +2 -2
  287. package/dist/core/memory-resolver.d.ts +11 -7
  288. package/dist/core/memory-resolver.js +2 -2
  289. package/dist/core/model-auth/daemon-login.d.ts +13 -0
  290. package/dist/core/model-auth/daemon-login.js +1 -0
  291. package/dist/core/model-auth/flows.d.ts +45 -0
  292. package/dist/core/model-auth/flows.js +1 -0
  293. package/dist/core/model-auth/handoff-jti.d.ts +4 -0
  294. package/dist/core/model-auth/handoff-jti.js +1 -0
  295. package/dist/core/model-routes.js +1 -1
  296. package/dist/core/nested-stores.d.ts +2 -1
  297. package/dist/core/nested-stores.js +1 -2
  298. package/dist/core/preview-registry.js +2 -2
  299. package/dist/core/profiles/env-store.js +2 -2
  300. package/dist/core/profiles/manifest.d.ts +16 -5
  301. package/dist/core/profiles/manifest.js +1 -1
  302. package/dist/core/provider-management.js +1 -1
  303. package/dist/core/review/birth.js +1 -1
  304. package/dist/core/review/companion.d.ts +0 -2
  305. package/dist/core/review/companion.js +1 -1
  306. package/dist/core/review/fork.js +2 -2
  307. package/dist/core/review/realize.js +1 -1
  308. package/dist/core/review/stage.d.ts +1 -1
  309. package/dist/core/review/stage.js +1 -1
  310. package/dist/core/review/types.d.ts +1 -1
  311. package/dist/core/runs/events.d.ts +34 -0
  312. package/dist/core/runs/events.js +1 -0
  313. package/dist/core/runs/operations.d.ts +43 -0
  314. package/dist/core/runs/operations.js +12 -0
  315. package/dist/core/runtime/bearings-render.d.ts +2 -2
  316. package/dist/core/runtime/bearings-render.js +11 -11
  317. package/dist/core/runtime/bearings.js +2 -2
  318. package/dist/core/runtime/broker/cli-relay.d.ts +5 -0
  319. package/dist/core/runtime/broker/cli-relay.js +1 -0
  320. package/dist/core/runtime/broker/client-registry.d.ts +0 -5
  321. package/dist/core/runtime/broker/client-registry.js +1 -1
  322. package/dist/core/runtime/broker/daemon-ops.d.ts +28 -1
  323. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  324. package/dist/core/runtime/broker/engine-drive.d.ts +0 -2
  325. package/dist/core/runtime/broker/engine-drive.js +1 -1
  326. package/dist/core/runtime/broker/fault-retry.d.ts +9 -0
  327. package/dist/core/runtime/broker/fault-retry.js +1 -1
  328. package/dist/core/runtime/broker/frame-dispatch.d.ts +5 -9
  329. package/dist/core/runtime/broker/frame-dispatch.js +1 -1
  330. package/dist/core/runtime/broker/frame-engine-control.d.ts +3 -2
  331. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  332. package/dist/core/runtime/broker/frame-memory-refs.d.ts +4 -3
  333. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  334. package/dist/core/runtime/broker/frame-read.js +1 -1
  335. package/dist/core/runtime/broker/frame-session.js +1 -1
  336. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -1
  337. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  338. package/dist/core/runtime/broker/inbox.d.ts +1 -2
  339. package/dist/core/runtime/broker/inbox.js +7 -10
  340. package/dist/core/runtime/broker/model-adapter.d.ts +9 -0
  341. package/dist/core/runtime/broker/model-adapter.js +2 -0
  342. package/dist/core/runtime/broker/node-token.d.ts +3 -0
  343. package/dist/core/runtime/broker/node-token.js +1 -0
  344. package/dist/core/runtime/broker/read-ops.js +1 -1
  345. package/dist/core/runtime/broker/rebind.d.ts +2 -0
  346. package/dist/core/runtime/broker/rebind.js +1 -1
  347. package/dist/core/runtime/broker/tool-groups.js +1 -1
  348. package/dist/core/runtime/broker/turn-ignition.d.ts +3 -3
  349. package/dist/core/runtime/broker/turn-ignition.js +1 -1
  350. package/dist/core/runtime/broker-cli.js +3 -3
  351. package/dist/core/runtime/broker-extension-render.d.ts +2 -5
  352. package/dist/core/runtime/broker-extension-render.js +4 -4
  353. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  354. package/dist/core/runtime/broker-protocol.d.ts +7 -8
  355. package/dist/core/runtime/broker.js +1 -1
  356. package/dist/core/runtime/canvas-extensions.d.ts +1 -0
  357. package/dist/core/runtime/canvas-extensions.js +1 -1
  358. package/dist/core/runtime/close.d.ts +9 -0
  359. package/dist/core/runtime/close.js +1 -1
  360. package/dist/core/runtime/deliver-live.js +1 -1
  361. package/dist/core/runtime/fleet.d.ts +1 -1
  362. package/dist/core/runtime/front-door-login.js +1 -1
  363. package/dist/core/runtime/front-door.js +2 -2
  364. package/dist/core/runtime/headless-pi.d.ts +1 -1
  365. package/dist/core/runtime/headless-pi.js +1 -1
  366. package/dist/core/runtime/host.d.ts +1 -1
  367. package/dist/core/runtime/host.js +3 -1
  368. package/dist/core/runtime/invocation.d.ts +3 -0
  369. package/dist/core/runtime/kickoff.d.ts +1 -0
  370. package/dist/core/runtime/kickoff.js +16 -16
  371. package/dist/core/runtime/launch-target.d.ts +1 -1
  372. package/dist/core/runtime/launch-target.js +1 -1
  373. package/dist/core/runtime/launch.d.ts +10 -35
  374. package/dist/core/runtime/launch.js +1 -1
  375. package/dist/core/runtime/lifecycle.js +2 -2
  376. package/dist/core/runtime/memory.d.ts +1 -1
  377. package/dist/core/runtime/memory.js +1 -1
  378. package/dist/core/runtime/model-registry.js +1 -1
  379. package/dist/core/runtime/model-swap.d.ts +17 -19
  380. package/dist/core/runtime/model-swap.js +1 -1
  381. package/dist/core/runtime/node-read.js +3 -2
  382. package/dist/core/runtime/nodes.d.ts +7 -0
  383. package/dist/core/runtime/nodes.js +1 -1
  384. package/dist/core/runtime/outcome-document.js +1 -1
  385. package/dist/core/runtime/package-health.js +2 -2
  386. package/dist/core/runtime/persona.js +2 -2
  387. package/dist/core/runtime/pi-vendored.js +1 -1
  388. package/dist/core/runtime/placement-tmux.d.ts +1 -1
  389. package/dist/core/runtime/placement-tmux.js +1 -1
  390. package/dist/core/runtime/placement.js +1 -1
  391. package/dist/core/runtime/promote.js +1 -1
  392. package/dist/core/runtime/provider-credential-gate.js +2 -2
  393. package/dist/core/runtime/recovery-hold.d.ts +2 -0
  394. package/dist/core/runtime/recovery-hold.js +1 -0
  395. package/dist/core/runtime/recycle.js +1 -1
  396. package/dist/core/runtime/reopen.js +1 -1
  397. package/dist/core/runtime/reset.js +1 -1
  398. package/dist/core/runtime/revive.d.ts +1 -1
  399. package/dist/core/runtime/revive.js +2 -3
  400. package/dist/core/runtime/roadmap.js +4 -4
  401. package/dist/core/runtime/run-command.d.ts +6 -0
  402. package/dist/core/runtime/run-command.js +1 -1
  403. package/dist/core/runtime/session-branch.d.ts +2 -8
  404. package/dist/core/runtime/session-branch.js +1 -1
  405. package/dist/core/runtime/session-list-cache.d.ts +6 -22
  406. package/dist/core/runtime/session-list-cache.js +1 -1
  407. package/dist/core/runtime/situational-context.js +2 -2
  408. package/dist/core/runtime/spawn-env.d.ts +6 -6
  409. package/dist/core/runtime/spawn-env.js +1 -1
  410. package/dist/core/runtime/spawn.d.ts +5 -0
  411. package/dist/core/runtime/spawn.js +2 -2
  412. package/dist/core/runtime/stop-guard.js +2 -2
  413. package/dist/core/runtime/stop-signals.d.ts +2 -2
  414. package/dist/core/runtime/stop-signals.js +1 -1
  415. package/dist/core/runtime/structured-output.d.ts +10 -4
  416. package/dist/core/runtime/structured-output.js +4 -4
  417. package/dist/core/runtime/tmux-bindings.js +3 -3
  418. package/dist/core/runtime/tmux-driver.d.ts +4 -0
  419. package/dist/core/runtime/tmux-driver.js +7 -7
  420. package/dist/core/runtime/view-socket.d.ts +9 -2
  421. package/dist/core/runtime/view-socket.js +1 -1
  422. package/dist/core/runtime/warm-pool.js +1 -1
  423. package/dist/core/scope.d.ts +3 -2
  424. package/dist/core/scope.js +1 -1
  425. package/dist/core/scoped-state/db.js +1 -1
  426. package/dist/core/scoped-state/migrate.js +3 -3
  427. package/dist/core/scoped-state/profiles.d.ts +2 -1
  428. package/dist/core/scoped-state/profiles.js +1 -1
  429. package/dist/core/scoped-state/schema.d.ts +2 -1
  430. package/dist/core/scoped-state/schema.js +4 -4
  431. package/dist/core/scopes.d.ts +2 -2
  432. package/dist/core/scopes.js +1 -1
  433. package/dist/core/secrets.d.ts +1 -0
  434. package/dist/core/secrets.js +2 -2
  435. package/dist/core/spaces/mounts.d.ts +32 -0
  436. package/dist/core/spaces/mounts.js +1 -0
  437. package/dist/core/spaces/open-beneath.d.ts +71 -0
  438. package/dist/core/spaces/open-beneath.js +1 -0
  439. package/dist/core/spaces/permissions.d.ts +46 -0
  440. package/dist/core/spaces/permissions.js +1 -0
  441. package/dist/core/spaces/process.d.ts +27 -0
  442. package/dist/core/spaces/process.js +1 -0
  443. package/dist/core/spaces/space.d.ts +8 -0
  444. package/dist/core/spaces/space.js +2 -0
  445. package/dist/core/spaces/stop.d.ts +8 -0
  446. package/dist/core/spaces/stop.js +2 -0
  447. package/dist/core/spaces/users.d.ts +19 -0
  448. package/dist/core/spaces/users.js +1 -0
  449. package/dist/core/subscription-state.d.ts +2 -0
  450. package/dist/core/subscription-state.js +3 -3
  451. package/dist/core/substrate/frontmatter-validation.js +1 -1
  452. package/dist/core/substrate/injected-store.d.ts +28 -3
  453. package/dist/core/substrate/injected-store.js +2 -1
  454. package/dist/core/substrate/listings.js +1 -1
  455. package/dist/core/substrate/memory-events.d.ts +6 -0
  456. package/dist/core/substrate/memory-events.js +1 -0
  457. package/dist/core/substrate/on-read-node.js +1 -1
  458. package/dist/core/substrate/on-read.d.ts +6 -6
  459. package/dist/core/substrate/on-read.js +5 -5
  460. package/dist/core/substrate/plan.js +1 -1
  461. package/dist/core/substrate/render-node.js +1 -1
  462. package/dist/core/substrate/render.d.ts +4 -3
  463. package/dist/core/substrate/render.js +38 -38
  464. package/dist/core/substrate/schema.d.ts +6 -0
  465. package/dist/core/substrate/schema.js +1 -1
  466. package/dist/core/tui/panel.js +1 -1
  467. package/dist/core/user-settings.d.ts +12 -0
  468. package/dist/core/user-settings.js +1 -1
  469. package/dist/core/worktree-mutation-async.js +5 -5
  470. package/dist/core/worktree-quarantine.js +1 -1
  471. package/dist/core/worktree-remove.d.ts +15 -0
  472. package/dist/core/worktree-remove.js +1 -0
  473. package/dist/core/worktree-sweep.js +6 -6
  474. package/dist/daemon/analytics/compute.d.ts +37 -0
  475. package/dist/daemon/analytics/compute.js +1 -0
  476. package/dist/daemon/analytics/scan-worker.d.ts +1 -0
  477. package/dist/daemon/analytics/scan-worker.js +2 -0
  478. package/dist/daemon/analytics/scan.d.ts +37 -0
  479. package/dist/daemon/analytics/scan.js +1 -0
  480. package/dist/daemon/api/app-listener.d.ts +11 -0
  481. package/dist/daemon/api/app-listener.js +21 -0
  482. package/dist/daemon/api/bridge.js +5 -5
  483. package/dist/daemon/api/handlers/analytics.d.ts +2 -0
  484. package/dist/daemon/api/handlers/analytics.js +1 -0
  485. package/dist/daemon/api/handlers/attach.js +1 -1
  486. package/dist/daemon/api/handlers/bash-jobs.js +2 -2
  487. package/dist/daemon/api/handlers/bash.js +1 -1
  488. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  489. package/dist/daemon/api/handlers/canvas.d.ts +1 -1
  490. package/dist/daemon/api/handlers/canvas.js +6 -6
  491. package/dist/daemon/api/handlers/crons.js +1 -1
  492. package/dist/daemon/api/handlers/files.d.ts +1 -1
  493. package/dist/daemon/api/handlers/files.js +1 -1
  494. package/dist/daemon/api/handlers/health.js +2 -2
  495. package/dist/daemon/api/handlers/hook-exec.d.ts +2 -0
  496. package/dist/daemon/api/handlers/hook-exec.js +1 -0
  497. package/dist/daemon/api/handlers/human-requests.js +1 -1
  498. package/dist/daemon/api/handlers/inbox.js +1 -1
  499. package/dist/daemon/api/handlers/llm.d.ts +2 -0
  500. package/dist/daemon/api/handlers/llm.js +3 -0
  501. package/dist/daemon/api/handlers/memory-reads.d.ts +4 -0
  502. package/dist/daemon/api/handlers/memory-reads.js +1 -0
  503. package/dist/daemon/api/handlers/memory.js +5 -1
  504. package/dist/daemon/api/handlers/messages.js +2 -2
  505. package/dist/daemon/api/handlers/modelauth.js +1 -1
  506. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  507. package/dist/daemon/api/handlers/node-records.d.ts +2 -0
  508. package/dist/daemon/api/handlers/node-records.js +3 -0
  509. package/dist/daemon/api/handlers/nodes.d.ts +1 -1
  510. package/dist/daemon/api/handlers/nodes.js +1 -1
  511. package/dist/daemon/api/handlers/profiles.d.ts +4 -1
  512. package/dist/daemon/api/handlers/profiles.js +1 -1
  513. package/dist/daemon/api/handlers/reports.js +5 -3
  514. package/dist/daemon/api/handlers/reviews.d.ts +1 -1
  515. package/dist/daemon/api/handlers/reviews.js +1 -1
  516. package/dist/daemon/api/handlers/run-routes.d.ts +2 -0
  517. package/dist/daemon/api/handlers/run-routes.js +1 -0
  518. package/dist/daemon/api/handlers/runs.d.ts +9 -0
  519. package/dist/daemon/api/handlers/runs.js +1 -0
  520. package/dist/daemon/api/handlers/subscriptions.js +1 -1
  521. package/dist/daemon/api/handlers/worktree.js +1 -1
  522. package/dist/daemon/api/map.d.ts +10 -4
  523. package/dist/daemon/api/map.js +2 -2
  524. package/dist/daemon/api/operations.d.ts +18 -0
  525. package/dist/daemon/api/operations.js +1 -0
  526. package/dist/daemon/api/principal.d.ts +42 -0
  527. package/dist/daemon/api/principal.js +1 -0
  528. package/dist/daemon/api/router.d.ts +27 -3
  529. package/dist/daemon/api/router.js +1 -1
  530. package/dist/daemon/api/server.d.ts +4 -0
  531. package/dist/daemon/api/server.js +1 -1
  532. package/dist/daemon/api/vendor-signin.d.ts +7 -0
  533. package/dist/daemon/api/vendor-signin.js +77 -0
  534. package/dist/daemon/api/viewer-presence.d.ts +3 -0
  535. package/dist/daemon/api/viewer-presence.js +1 -0
  536. package/dist/daemon/cron/armed-context.d.ts +4 -0
  537. package/dist/daemon/cron/armed-context.js +1 -1
  538. package/dist/daemon/cron/escalation.js +3 -3
  539. package/dist/daemon/cron/lease-recovery.js +1 -1
  540. package/dist/daemon/cron/sinks.js +2 -2
  541. package/dist/daemon/cron-run.d.ts +5 -5
  542. package/dist/daemon/cron-run.js +1 -1
  543. package/dist/daemon/crtrd.js +8 -7
  544. package/dist/daemon/delivery/run-delivery.d.ts +4 -0
  545. package/dist/daemon/delivery/run-delivery.js +1 -1
  546. package/dist/daemon/fleet.d.ts +1 -1
  547. package/dist/daemon/fleet.js +6 -6
  548. package/dist/daemon/human/finish.js +7 -7
  549. package/dist/daemon/joined-owner.d.ts +5 -0
  550. package/dist/daemon/joined-owner.js +1 -0
  551. package/dist/daemon/manage.js +2 -2
  552. package/dist/daemon/messaging/node-message.js +1 -1
  553. package/dist/daemon/park-activity.js +1 -1
  554. package/dist/daemon/reconcilers/bash-deadline.js +1 -1
  555. package/dist/daemon/reconcilers/broker-supervision.d.ts +1 -1
  556. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  557. package/dist/daemon/reconcilers/delivery-lane.js +1 -1
  558. package/dist/daemon/reconcilers/live-obligation.d.ts +7 -0
  559. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  560. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  561. package/dist/daemon/reconcilers/storage-maintenance.d.ts +20 -1
  562. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  563. package/dist/daemon/runs/append-section.d.ts +6 -0
  564. package/dist/daemon/runs/append-section.js +2 -0
  565. package/dist/daemon/runs/observer.d.ts +5 -0
  566. package/dist/daemon/runs/observer.js +4 -0
  567. package/dist/launcher/bwrap.d.ts +4 -0
  568. package/dist/launcher/bwrap.js +2 -0
  569. package/dist/launcher/client.d.ts +2 -0
  570. package/dist/launcher/client.js +3 -0
  571. package/dist/launcher/main.d.ts +1 -0
  572. package/dist/launcher/main.js +3 -0
  573. package/dist/launcher/netrule.d.ts +1 -0
  574. package/dist/launcher/netrule.js +1 -0
  575. package/dist/launcher/seccomp.d.ts +1 -0
  576. package/dist/launcher/seccomp.js +1 -0
  577. package/dist/launcher/spec.d.ts +88 -0
  578. package/dist/launcher/spec.js +1 -0
  579. package/dist/launcher/users.d.ts +18 -0
  580. package/dist/launcher/users.js +7 -0
  581. package/dist/launcher/validate.d.ts +22 -0
  582. package/dist/launcher/validate.js +1 -0
  583. package/dist/migrations/corpus.js +3 -3
  584. package/dist/migrations/runner.js +1 -1
  585. package/dist/native/linux/addon.node +0 -0
  586. package/dist/native/linux.d.ts +29 -0
  587. package/dist/native/linux.js +1 -0
  588. package/dist/pi-extensions/broker-local.js +2 -2
  589. package/dist/pi-extensions/canvas-bash-valve.d.ts +1 -3
  590. package/dist/pi-extensions/canvas-bash-valve.js +4 -7
  591. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -2
  592. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  593. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  594. package/dist/pi-extensions/canvas-inbox-watcher.d.ts +2 -1
  595. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -1
  596. package/dist/pi-extensions/canvas-passive-context.d.ts +1 -1
  597. package/dist/pi-extensions/canvas-passive-context.js +11 -11
  598. package/dist/pi-extensions/canvas-recap.js +6 -6
  599. package/dist/pi-extensions/canvas-stophook.js +1 -1
  600. package/dist/pi-extensions/canvas-structured-output.js +4 -4
  601. package/dist/pi-extensions/canvas-tool-guide.js +1 -1
  602. package/dist/pi-extensions/system-prompt-entry.d.ts +15 -0
  603. package/dist/pi-extensions/system-prompt-entry.js +1 -0
  604. package/dist/shared/env.d.ts +5 -1
  605. package/dist/shared/env.js +1 -1
  606. package/dist/shared/strip-cd-prefix.d.ts +1 -0
  607. package/dist/shared/strip-cd-prefix.js +1 -0
  608. package/dist/types.d.ts +31 -15
  609. package/docs/cli/memory-and-preferences.md +3 -1
  610. package/docs/sdk/client.md +34 -0
  611. package/docs/sdk/errors.md +2 -0
  612. package/docs/sdk/memory.md +2 -2
  613. package/docs/sdk/streaming.md +21 -0
  614. package/package.json +18 -4
  615. package/packages/crouter-identity/dist/index.d.ts +54 -0
  616. package/packages/crouter-identity/dist/index.js +166 -0
  617. package/packages/crouter-identity/package.json +33 -0
  618. package/runtime.lock.json +34 -8
  619. package/scripts/build-native-linux.mjs +16 -0
  620. package/scripts/install-runtime.mjs +9 -7
  621. package/scripts/lib/isolation-env.mjs +42 -0
  622. package/scripts/runtime-smoke.mjs +49 -0
  623. package/src/native/linux/addon.c +249 -0
  624. package/dist/core/profiles/state-block.d.ts +0 -4
  625. package/dist/core/profiles/state-block.js +0 -3
  626. package/dist/core/runtime/broker/auth-reload.d.ts +0 -41
  627. package/dist/core/runtime/broker/auth-reload.js +0 -1
  628. package/dist/core/substrate/cli-context-delivery.d.ts +0 -22
  629. package/dist/core/substrate/cli-context-delivery.js +0 -1
@@ -1,17 +1,17 @@
1
- var Ie=Object.defineProperty;var d=(e,t)=>Ie(e,"name",{value:t,configurable:!0});import{envProfileId as De}from"../../shared/env.js";import{dirname as re,join as h,resolve as q,isAbsolute as Ne,relative as D,sep as Ue}from"node:path";import{chmodSync as Fe,renameSync as w,writeFileSync as V}from"node:fs";import{createHash as Ve}from"node:crypto";import{defineLeaf as N}from"../../core/command.js";import{notFound as g,usage as $,general as f,network as We}from"../../core/errors.js";import{findMarketplaceByName as Oe,findPluginByName as L,listAllPlugins as ae}from"../../core/resolver.js";import{NEUTRAL_PROJECT_MEMORY as ze,pluginsDir as Ge,ensureProjectScopeRoot as Q,userScopeRoot as T,resolveScopeArg as se,projectScopeRoot as le,requireScopeRoot as H}from"../../core/scope.js";import{readConfig as Ke,readState as Ye,updateConfig as B,updateState as U,ensureScopeInitialized as W,invalidPluginKindsReasons as Je,invalidPluginBinReasons as Qe,invalidPluginRequiresReasons as Xe,normalizeRequires as Ze}from"../../core/config.js";import{withExclusiveDirectoryLockAsync as en}from"../../core/exclusive-lock.js";import{bundleSwapLockPath as ce}from"../../core/plugin-swap-lock.js";import{invalidPageComponentsReasons as nn}from"../../core/human/page-catalog.js";import{pathExists as k,ensureDir as j,removePath as S,nowIso as F,linkOrCopy as de,isSymlink as O,readSymlinkTarget as tn,atomicWriteJson as on,readText as rn,realpathOrSelf as ue,walkFiles as an}from"../../core/fs-utils.js";import{clone as z,deriveNameFromUrl as sn,currentSha as _,gitSync as pe,isGitRepo as X}from"../../core/git.js";import{readMarketplaceManifest as me,readPluginManifest as E,validatePluginManifestMemoryExtensions as ln}from"../../core/manifest.js";import{memoryExtensionValidationCatalog as cn,validateMemoryExtensionValues as dn}from"../../core/memory/extensions.js";import{lintMemoryStore as un,MEMORY_LINT_IDENTITY_RULES as pn}from"../../core/memory/lint.js";import{buildCorpusSnapshot as mn,loadCorpusSnapshots as fn,parseFailureBlockers as hn,runCorpusMigrations as gn}from"../../migrations/corpus.js";import{lintSubstrateFrontmatter as yn}from"../../core/substrate/frontmatter-validation.js";import{parseFrontmatterGeneric as vn}from"../../core/frontmatter.js";import{validatePluginCommands as Z,validateEffectiveCommandPlugins as kn}from"../../core/command-plugins/discovery.js";import{normalizeEndpoint as wn,validateEndpoint as bn,validateHttpPluginTransport as $n}from"../../core/command-plugins/endpoint.js";import{buildBrokerEnv as jn,resolvePathExecutable as Pn}from"../../core/runtime/spawn-env.js";import{validatePluginBundle as xn}from"../../core/command-plugins/bundle.js";import{compileHookRegistry as fe,discoverCandidateHookRegistry as Sn,discoverCandidateHookRegistryForCandidates as Rn,discoverHookRegistry as En}from"../../core/command-hooks/discovery.js";import{hasDeclaredHooks as he,hookReport as ge}from"../../core/command-hooks/report.js";import{fetchHttpPluginBundle as ye}from"../../core/command-plugins/transport/http-fetch.js";import{SUBTREE_NAMES as G,coreCommandPaths as K,coreHookCatalog as ve,extensibleCoreBranches as Y}from"../../build-root.js";import{isGitUrl as ke,resolvePluginConfigTarget as Tn,setPluginEnabled as we,resolveInstallScope as Mn}from"./shared.js";async function ee(e,t){const n=L(e,t);if(n===null||typeof n.manifest.commands!="string"||n.manifest.commands.length===0)return;const i=new Set(G),[o,r]=await Promise.all([K(),Y()]),a=kn(i,void 0,void 0,o,r).find(s=>s.plugin.root===n.root)??Z(n,i,o,r);return{mounts:[...a.contributions.map(s=>s.node.name),...a.coreMounts.map(s=>[...s.parent,s.node.name].join(" "))],issues:a.issues}}d(ee,"commandReport");const qn=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;function be(e,t,n){if(typeof e!="string"||!qn.test(e))throw $("invalid --name: expected a lowercase kebab-case plugin handle");const i=bn(t);if(!i.isValid)throw $(`invalid --endpoint: ${i.errors.join("; ")}`);const o=wn(t),r=$n({kind:"http",endpoint:o,...n!==void 0?{authEnv:n}:{}});if(r.transport===void 0)throw $(`invalid HTTP plugin transport: ${r.errors.join("; ")}`);return r.transport}d(be,"validateHttpInstall");function J(e,t){const n=t.map(i=>`- ${i.code}${i.path!==void 0?` at ${i.path}`:""}: ${i.message} (received ${JSON.stringify(i.received)}, expected ${i.expected})`);return f(`${e}:
1
+ var Ne=Object.defineProperty;var d=(e,t)=>Ne(e,"name",{value:t,configurable:!0});import{envProfileId as Ue}from"../../shared/env.js";import{requirePersonCli as N}from"../broker-permissions.js";import{dirname as se,join as h,resolve as M,isAbsolute as Fe,relative as U,sep as Ve}from"node:path";import{chmodSync as We,renameSync as w,writeFileSync as O}from"node:fs";import{createHash as Oe}from"node:crypto";import{defineLeaf as F}from"../../core/command.js";import{notFound as g,usage as $,general as f,network as ze}from"../../core/errors.js";import{findMarketplaceByName as Ge,findPluginByName as H,listAllPlugins as le}from"../../core/resolver.js";import{NEUTRAL_PROJECT_MEMORY as Ke,pluginsDir as _,ensureProjectScopeRoot as Z,userScopeRoot as T,resolveScopeArg as ce,projectScopeRoot as de,requireScopeRoot as B}from"../../core/scope.js";import{readConfig as Ye,readState as Je,updateConfig as I,updateState as V,ensureScopeInitialized as z,invalidPluginKindsReasons as Qe,invalidPluginBinReasons as Xe,invalidPluginRequiresReasons as Ze,normalizeRequires as en}from"../../core/config.js";import{withExclusiveDirectoryLockAsync as nn}from"../../core/exclusive-lock.js";import{bundleSwapLockPath as ue}from"../../core/plugin-swap-lock.js";import{invalidPageComponentsReasons as tn}from"../../core/human/page-catalog.js";import{pathExists as k,ensureDir as j,removePath as S,nowIso as W,linkOrCopy as pe,isSymlink as G,readSymlinkTarget as on,atomicWriteJson as rn,readText as an,realpathOrSelf as me,walkFiles as sn}from"../../core/fs-utils.js";import{clone as K,deriveNameFromUrl as ln,currentSha as C,gitSync as fe,isGitRepo as ee}from"../../core/git.js";import{readMarketplaceManifest as he,readPluginManifest as E,validatePluginManifestMemoryExtensions as cn}from"../../core/manifest.js";import{memoryExtensionValidationCatalog as dn,validateMemoryExtensionValues as un}from"../../core/memory/extensions.js";import{lintMemoryStore as pn,MEMORY_LINT_IDENTITY_RULES as mn}from"../../core/memory/lint.js";import{buildCorpusSnapshot as fn,loadCorpusSnapshots as hn,parseFailureBlockers as gn,runCorpusMigrations as yn}from"../../migrations/corpus.js";import{lintSubstrateFrontmatter as vn}from"../../core/substrate/frontmatter-validation.js";import{parseFrontmatterGeneric as kn}from"../../core/frontmatter.js";import{validatePluginCommands as ne,validateEffectiveCommandPlugins as wn}from"../../core/command-plugins/discovery.js";import{normalizeEndpoint as bn,validateEndpoint as $n,validateHttpPluginTransport as jn}from"../../core/command-plugins/endpoint.js";import{buildBrokerEnv as Pn,resolvePathExecutable as xn}from"../../core/runtime/spawn-env.js";import{validatePluginBundle as Sn}from"../../core/command-plugins/bundle.js";import{compileHookRegistry as ge,discoverCandidateHookRegistry as Rn,discoverCandidateHookRegistryForCandidates as En,discoverHookRegistry as Tn}from"../../core/command-hooks/discovery.js";import{hasDeclaredHooks as ye,hookReport as ve}from"../../core/command-hooks/report.js";import{fetchHttpPluginBundle as ke}from"../../core/command-plugins/transport/http-fetch.js";import{SUBTREE_NAMES as Y,coreCommandPaths as J,coreHookCatalog as we,extensibleCoreBranches as Q}from"../../build-root.js";import{isGitUrl as be,resolvePluginConfigTarget as qn,setPluginEnabled as $e,resolveInstallScope as Mn}from"./shared.js";async function te(e,t){const n=H(e,t);if(n===null||typeof n.manifest.commands!="string"||n.manifest.commands.length===0)return;const i=new Set(Y),[o,r]=await Promise.all([J(),Q()]),a=wn(i,void 0,void 0,o,r).find(s=>s.plugin.root===n.root)??ne(n,i,o,r);return{mounts:[...a.contributions.map(s=>s.node.name),...a.coreMounts.map(s=>[...s.parent,s.node.name].join(" "))],issues:a.issues}}d(te,"commandReport");const _n=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;function je(e,t,n){if(typeof e!="string"||!_n.test(e))throw $("invalid --name: expected a lowercase kebab-case plugin handle");const i=$n(t);if(!i.isValid)throw $(`invalid --endpoint: ${i.errors.join("; ")}`);const o=bn(t),r=jn({kind:"http",endpoint:o,...n!==void 0?{authEnv:n}:{}});if(r.transport===void 0)throw $(`invalid HTTP plugin transport: ${r.errors.join("; ")}`);return r.transport}d(je,"validateHttpInstall");function X(e,t){const n=t.map(i=>`- ${i.code}${i.path!==void 0?` at ${i.path}`:""}: ${i.message} (received ${JSON.stringify(i.received)}, expected ${i.expected})`);return f(`${e}:
2
2
  ${n.join(`
3
- `)}`,{issues:t,...t.length>0?{next:t[0].next}:{}})}d(J,"invalidBundleError");function _n(e,t){if(e.kinds===void 0)return;const n=Je(e.kinds);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid kinds block:
3
+ `)}`,{issues:t,...t.length>0?{next:t[0].next}:{}})}d(X,"invalidBundleError");function Cn(e,t){if(e.kinds===void 0)return;const n=Qe(e.kinds);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid kinds block:
4
4
  ${n.map(i=>`- ${i}`).join(`
5
- `)}`,{issues:n})}d(_n,"assertManifestKindsValid");function Cn(e,t){if(e.bin===void 0)return;const n=Qe(e.bin);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid bin block:
5
+ `)}`,{issues:n})}d(Cn,"assertManifestKindsValid");function An(e,t){if(e.bin===void 0)return;const n=Xe(e.bin);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid bin block:
6
6
  ${n.map(i=>`- ${i}`).join(`
7
- `)}`,{issues:n})}d(Cn,"assertManifestBinValid");function An(e,t){if(e.requires===void 0)return;const n=Xe(e.requires);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid requires block:
7
+ `)}`,{issues:n})}d(An,"assertManifestBinValid");function Ln(e,t){if(e.requires===void 0)return;const n=Ze(e.requires);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid requires block:
8
8
  ${n.map(i=>`- ${i}`).join(`
9
- `)}`,{issues:n})}d(An,"assertManifestRequiresValid");function $e(e){if(e.requires===void 0)return[];const t=jn({argv:[],env:{CRTR_NODE_CWD:process.cwd(),CRTR_PROFILE_ID:De()??""}});return Object.entries(Ze(e.requires)).filter(([n])=>Pn(n,t,process.cwd())===null).map(([n,i])=>`Warning: plugin "${e.name}" requires "${n}" on PATH \u2014 ${i}`)}d($e,"missingRequirementWarnings");function Ln(e,t){if(e.page_components===void 0)return;const n=nn(e.page_components);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid page_components block:
9
+ `)}`,{issues:n})}d(Ln,"assertManifestRequiresValid");function Pe(e){if(e.requires===void 0)return[];const t=Pn({argv:[],env:{CRTR_NODE_CWD:process.cwd(),CRTR_PROFILE_ID:Ue()??""}});return Object.entries(en(e.requires)).filter(([n])=>xn(n,t,process.cwd())===null).map(([n,i])=>`Warning: plugin "${e.name}" requires "${n}" on PATH \u2014 ${i}`)}d(Pe,"missingRequirementWarnings");function Hn(e,t){if(e.page_components===void 0)return;const n=tn(e.page_components);if(n.length>0)throw f(`plugin manifest at ${t} declares an invalid page_components block:
10
10
  ${n.map(i=>`- ${i}`).join(`
11
- `)}`,{issues:n})}d(Ln,"assertManifestPageComponentsValid");async function ne(e,t){const n=L(e,t);if(n===null||!he(n.manifest))return;const i=await ve(),o=En(i),r=o.validations.find(a=>a.plugin.root===n.root);if(r===void 0){const a=fe(i,[n]);return ge(a.validations[0])}return ge(r,o.issues.filter(a=>a.plugin===n.name&&a.scope===n.scope))}d(ne,"hookLifecycleReport");async function Hn(e,t,n,i,o,r){if(!he(e))return;const a={name:e.name,scope:n,root:t,manifest:e,enabled:!0},s=r??[{plugin:a,scopeRoot:i}],c=await ve(),l=r===void 0?Sn(c,a,i):Rn(c,s),v=l.validations.find(u=>u.plugin.root===t)===void 0?fe(c,[a]).issues:l.issues.filter(u=>u.plugin===a.name&&u.scope===a.scope);if(v.length>0)throw J(`plugin hook behavior at ${o} is invalid`,v)}d(Hn,"assertManifestHooksValid");function je(e,t,n){return{scope:t,storeRoot:n,namespace:e,plugin:e,mountStatus:"ready",projectMemory:ze}}d(je,"pluginCandidateStore");function te(e,t){const n=D(e,t);return n===""?e:n}d(te,"storeRelative");function Bn(e,t,n,i,o){const r=i.map(a=>`- ${a.kind}${a.path===void 0?"":` at ${te(n,a.path)}`}: ${a.message}`);return f(`plugin "${e}" memory corpus at ${t} cannot be migrated to exact canonical identity:
11
+ `)}`,{issues:n})}d(Hn,"assertManifestPageComponentsValid");async function ie(e,t){const n=H(e,t);if(n===null||!ye(n.manifest))return;const i=await we(),o=Tn(i),r=o.validations.find(a=>a.plugin.root===n.root);if(r===void 0){const a=ge(i,[n]);return ve(a.validations[0])}return ve(r,o.issues.filter(a=>a.plugin===n.name&&a.scope===n.scope))}d(ie,"hookLifecycleReport");async function Bn(e,t,n,i,o,r){if(!ye(e))return;const a={name:e.name,scope:n,root:t,manifest:e,enabled:!0},s=r??[{plugin:a,scopeRoot:i}],c=await we(),l=r===void 0?Rn(c,a,i):En(c,s),v=l.validations.find(u=>u.plugin.root===t)===void 0?ge(c,[a]).issues:l.issues.filter(u=>u.plugin===a.name&&u.scope===a.scope);if(v.length>0)throw X(`plugin hook behavior at ${o} is invalid`,v)}d(Bn,"assertManifestHooksValid");function xe(e,t,n){return{scope:t,storeRoot:n,namespace:e,plugin:e,mountStatus:"ready",projectMemory:Ke}}d(xe,"pluginCandidateStore");function oe(e,t){const n=U(e,t);return n===""?e:n}d(oe,"storeRelative");function In(e,t,n,i,o){const r=i.map(a=>`- ${a.kind}${a.path===void 0?"":` at ${oe(n,a.path)}`}: ${a.message}`);return f(`plugin "${e}" memory corpus at ${t} cannot be migrated to exact canonical identity:
12
12
  ${r.join(`
13
- `)}`,{blockers:i,next:o===0?`Correct the package's memory corpus, then retry \u2014 nothing was written and "${e}" was not activated.`:`Correct the package's memory corpus, then re-run \u2014 the rewrite is on disk but failed verification, and "${e}" was not activated.`})}d(Bn,"corpusBlockedError");function In(e,t,n,i,o){const r=h(t,"memory");if(!k(r))return;const a={roots:[{reason:"plugin",root:r,boundary:"store",detail:e.name}],stores:[{key:ue(r),descriptor:je(e.name,n,r),discovery:[{reason:"plugin",root:r}],targets:[],writable:!0}],targets:[],blockers:[]},s=d(()=>{const{snapshots:m,skipped:y}=fn(a);return{corpus:mn(a,m),blockers:hn(y)}},"load"),c=s(),l=gn(c.corpus,{blockers:c.blockers,rebuild:d(()=>s().corpus,"rebuild")}),p=l.wrote.consumers.length+l.wrote.identities.length;if(l.blocked)throw Bn(e.name,i,r,l.blockers,p);const v=un(je(e.name,n,r)),u=v.errors.filter(m=>pn.has(m.rule));if(u.length>0){const m=u.map(y=>`- ${y.rule} at ${te(r,y.path)}: ${y.message}`);throw f(`plugin "${e.name}" memory corpus at ${i} is incompatible with exact canonical identity:
13
+ `)}`,{blockers:i,next:o===0?`Correct the package's memory corpus, then retry \u2014 nothing was written and "${e}" was not activated.`:`Correct the package's memory corpus, then re-run \u2014 the rewrite is on disk but failed verification, and "${e}" was not activated.`})}d(In,"corpusBlockedError");function Dn(e,t,n,i,o){const r=h(t,"memory");if(!k(r))return;const a={roots:[{reason:"plugin",root:r,boundary:"store",detail:e.name}],stores:[{key:me(r),descriptor:xe(e.name,n,r),discovery:[{reason:"plugin",root:r}],targets:[],writable:!0}],targets:[],blockers:[]},s=d(()=>{const{snapshots:m,skipped:y}=hn(a);return{corpus:fn(a,m),blockers:gn(y)}},"load"),c=s(),l=yn(c.corpus,{blockers:c.blockers,rebuild:d(()=>s().corpus,"rebuild")}),p=l.wrote.consumers.length+l.wrote.identities.length;if(l.blocked)throw In(e.name,i,r,l.blockers,p);const v=pn(xe(e.name,n,r)),u=v.errors.filter(m=>mn.has(m.rule));if(u.length>0){const m=u.map(y=>`- ${y.rule} at ${oe(r,y.path)}: ${y.message}`);throw f(`plugin "${e.name}" memory corpus at ${i} is incompatible with exact canonical identity:
14
14
  ${m.join(`
15
- `)}`,{issues:u,next:`Correct the package's memory documents, then retry \u2014 "${e.name}" was not activated.`})}return{docs:v.documents,migrated:[...new Set([...l.wrote.consumers,...l.wrote.identities])].map(m=>te(r,m)).sort(),...o==="linked"?{linkedSource:ue(r)}:{}}}d(In,"migratePluginMemory");async function R(e,t,n,i,o,r,a="package"){try{ln(e)}catch(u){const m=u instanceof Error?u.message:String(u);throw f(`plugin manifest at ${o} declares invalid memory_extensions: ${m}`)}_n(e,o),Ln(e,o),Cn(e,o),An(e,o);const[s,c]=await Promise.all([K(),Y()]),l=Z({name:e.name,scope:n,root:t,manifest:e,enabled:!0},new Set(G),s,c);if(l.issues.length>0)throw J(`plugin command behavior at ${o} is invalid`,l.issues);await Hn(e,t,n,i,o,r);const p=h(t,"memory"),v=h(i,"memory","__plugin_candidate__.md");for(const u of an(p,m=>m.endsWith(".md"),m=>m.startsWith("."))){let m;try{m=vn(rn(u)).data}catch(b){throw f(`plugin memory document ${D(t,u)} has invalid YAML frontmatter: ${b instanceof Error?b.message.split(`
16
- `)[0]:String(b)}`)}const y=yn(m);if(y!==null)throw f(`plugin memory document ${D(t,u)} is invalid: ${y}`);for(const b of dn(m?.extensions,cn({scope:n,path:v},{candidate:e})))throw f(`plugin memory document ${D(t,u)} is invalid: ${b.path}: ${b.message}`)}return In(e,t,n,o,a)}d(R,"assertPluginCandidateValid");function Dn(e){return{kind:"http",endpoint:new URL(e.endpoint).origin,...e.authEnv!==void 0?{authEnv:e.authEnv}:{}}}d(Dn,"invocationTransport");function C(e,t){const n=q(e,t);if(n===e||!n.startsWith(e+Ue))throw f(`bundle member path escapes the staging directory: ${t}`);return n}d(C,"stagedPath");function Nn(e,t,n){on(C(e,".crouter-plugin/plugin.json"),t);for(const i of n.directories)j(C(e,i.path));V(C(e,"commands.json"),n.commandsBytes);for(const i of n.memory){const o=C(e,i.path);j(q(o,"..")),V(o,i.bytes)}if(n.hooks!==void 0){V(C(e,"hooks.json"),n.hooks.manifest);for(const i of n.hooks.files){const o=C(e,i.path);j(q(o,"..")),V(o,i.bytes)}Fe(C(e,"hooks/dispatch"),493)}}d(Nn,"writeStagedBundle");async function Un(e,t,n,i,o){const r=await R(o,n,t,i,`${n}/.crouter-plugin/plugin.json`),a={name:e,scope:t,root:n,manifest:o,enabled:!0},[s,c]=await Promise.all([K(),Y()]),l=Z(a,new Set(G),s,c);if(l.issues.length>0)throw J(`bundle staged package for "${e}" is invalid`,l.issues);return r}d(Un,"validateStagedBundle");function Pe(e){return e.sourceMarketplace!==void 0||X(e.root)||O(e.root)}d(Pe,"isSourceInstalled");function xe(e){throw f(`HTTP plugin "${e}" uses the removed commands-only endpoint format`,{next:`Run \`crtr pkg plugin remove ${e}\`, then reinstall it with \`crtr pkg plugin install --name ${e} --endpoint <archive-url>\`.`})}d(xe,"rejectLegacyHttpPlugin");function Fn(e,t,n){if(!k(n))return;const i=L(e,t);if(i?.manifest.bundle!==void 0)return i;throw i?.manifest.transport?.kind==="http"&&i!==void 0&&!Pe(i)&&xe(e),f(`plugin "${e}" already exists at ${n}; run \`crtr pkg plugin remove ${e}\` before installing the archive plugin.`)}d(Fn,"existingBundleRoot");function Se(e,t,n,i){const o=be(e,t.endpoint,t.authEnv),r={endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},a=h(i,"plugins",e);return Fn(e,n,a),{bundle:r,transport:Dn(r),scopeRootPath:i,root:a}}d(Se,"resolveBundleTarget");function Re(e,t){return{name:e,endpoint:t.endpoint,...t.authEnv!==void 0?{authEnv:t.authEnv}:{}}}d(Re,"fetchTarget");const Vn=6e4,Wn=1e4;async function Ee(e,t,n,i){const o=t==="project"?Q():T();return j(h(o,"tmp")),en(ce(o,e),()=>i(o),{timeoutMs:n,timeoutError:d(()=>f(`timed out waiting for another crtr process to finish replacing plugin "${e}"`,{next:`Re-run once that process has finished, or check for a stalled crtr holding ${ce(o,e)}.`}),"timeoutError")})}d(Ee,"withBundleSwapLock");async function Te(e,t,n,i){return Ee(e,n,Vn,async o=>{const r=Se(e,t,n,o),a=await ye(Re(e,r.bundle));if(a.status!==200){const s=`HTTP plugin bundle fetch failed for "${e}": ${a.message}`;throw a.status==="auth_env_missing"?$(s):a.status==="cli_unreachable"?We(s):f(s)}return _e(e,n,r,a.raw,a.etag,i)})}d(Te,"replaceBundlePlugin");async function Tt(e,t,n,i){return Ee(e,n,Wn,async o=>{try{const r=Se(e,t,n,o),a=i.conditional?Ye(n).plugins[e]?.etag:void 0,s={...a!==void 0?{ifNoneMatch:a}:{},...i.timeoutMs!==void 0?{timeoutMs:i.timeoutMs}:{}},c=await ye(Re(e,r.bundle),s);if(c.status===304)return;if(c.status!==200)throw f(`HTTP plugin bundle revalidation failed for "${e}": ${c.message}`);const l=qe(c.raw);if(zn(e,n,r.root,l)){Me(n,e,c.etag,{swapped:!1});return}return await _e(e,n,r,c.raw,c.etag,i,l)}finally{On(n,e)}})}d(Tt,"revalidateBundlePlugin");function On(e,t){U(e,n=>{n.plugins[t]===void 0&&(n.plugins[t]={}),n.plugins[t].checked_at=F()})}d(On,"recordPluginCheck");function Me(e,t,n,i){U(e,o=>{o.plugins[t]===void 0&&(o.plugins[t]={}),i.swapped&&(o.plugins[t].last_updated=F()),o.plugins[t].checked_at=F(),n===void 0?delete o.plugins[t].etag:o.plugins[t].etag=n})}d(Me,"recordCheckedGeneration");function qe(e){return Ve("sha256").update(e).digest("hex").slice(0,12)}d(qe,"bundleVersion");function zn(e,t,n,i){return Ke(t).plugins[e]?.version!==i?!1:k(h(n,"commands.json"))}d(zn,"isInstalledGeneration");async function _e(e,t,n,i,o,r,a){const{bundle:s,transport:c,scopeRootPath:l,root:p}=n,[v,u]=await Promise.all([K(),Y()]),m=await xn(i,{reservedCoreNames:new Set(G),coreCommandPaths:v,extensibleCoreBranches:u});if(m.bundle===void 0)throw J(`HTTP plugin bundle for "${e}" is invalid`,m.issues);const y=a??qe(i),b={name:e,version:y,commands:"commands.json",transport:c,bundle:s,...m.bundle.kinds!==void 0?{kinds:m.bundle.kinds}:{},...m.bundle.page_components!==void 0?{page_components:m.bundle.page_components}:{},...m.bundle.memory_extensions!==void 0?{memory_extensions:m.bundle.memory_extensions}:{},...m.bundle.hooks!==void 0?{hooks:"hooks.json",hookExecutable:"hooks/dispatch"}:{}},P=h(l,"tmp"),x=h(P,`${e}.${process.pid}`),M=`${x}.prev`;if(k(M))throw f(`cannot replace plugin "${e}": prior interrupted replacement remains at ${M}`);j(P),j(h(l,"plugins")),S(x);let I;try{j(x),Nn(x,b,m.bundle),I=await Un(e,t,x,l,b);let A=!1;k(p)&&(w(p,M),A=!0);try{w(x,p)}catch(Be){throw A&&w(M,p),Be}A&&S(M)}finally{S(x)}W(t,l),B(t,A=>{A.plugins[e]={enabled:r.enable?!0:A.plugins[e]?.enabled??!0,version:y}}),Me(t,e,o,{swapped:!0});const ie=await ee(e,t);if(ie===void 0)throw f(`bundle plugin "${e}" has no staged command report`);const oe=await ne(e,t);return{name:e,scope:t,path:p,transport:"http",version:y,docs:m.bundle.memory.length,kinds:Object.keys(m.bundle.kinds??{}).length,pageComponents:(m.bundle.page_components??[]).length,commands:ie,...oe!==void 0?{hooks:oe}:{},...I!==void 0?{memory:I}:{}}}d(_e,"applyBundleArchive");async function Gn(e,t,n,i){const o=be(e,t,n);return Te(e,{endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},i,{enable:!0})}d(Gn,"installHttpPlugin");function Kn(e){if(e.startsWith("./")||e.startsWith("../")||e.startsWith("/"))return{kind:"local",value:e};if(ke(e))return{kind:"git",value:e};const t=e.split("/");if(t.length===2&&t[0]!==""&&t[1]!=="")return{kind:"marketplace",value:{marketplace:t[0],plugin:t[1]}};throw $(`invalid plugin install ref: ${e}
17
- Accepted forms: marketplace/plugin, git URL (https://, ssh://, git@, file://, or *.git), or local path starting ./, ../, or /. Bare plugin names are not install refs.`)}d(Kn,"classifyInstallRef");function Ce(e){return e.startsWith("./")||e.startsWith("../")||!Ne(e)&&!ke(e)}d(Ce,"isMarketplaceRelativeSource");async function Ae(e,t,n){const i=t.get(e);if(i!==void 0)return i;const o=Oe(e);if(o===null){if(n.strict)throw g(`marketplace not found: ${e}`);return null}const r=me(o.root);if(r===null)throw g(`marketplace manifest not found: ${o.root}/.crouter-marketplace/marketplace.json`);if(!X(o.root)){const l={marketplace:o,manifest:r,pull:{updated:!1,sha:_(o.root)??""}};return t.set(e,l),l}const a=_(o.root),s=h(re(o.root),`.${e}.${process.pid}.${Date.now()}.candidate`),c=`${s}.previous`;try{z(o.url,s,{ref:o.ref,depth:1});const l=me(s);if(l===null)throw g(`marketplace manifest not found in candidate checkout: ${s}/.crouter-marketplace/marketplace.json`);const p=ae().filter(u=>u.sourceMarketplace===e&&O(u.root));for(const u of p){const m=l.plugins.find(I=>I.name===u.name);if(m===void 0||!Ce(m.source))throw f(`marketplace candidate removes relative-source plugin "${u.name}" while it is installed`);const y=tn(u.root);if(y===null)throw f(`installed marketplace plugin "${u.name}" has no readable symlink target`);const b=D(o.root,q(re(u.root),y)),P=q(s,m.source);if(P!==q(s,b))throw f(`marketplace candidate moves installed relative-source plugin "${u.name}" from ${b} to ${m.source}`);if(!k(P))throw g(`marketplace candidate source path does not exist for plugin "${u.name}": ${P}`);const x=E(P);if(x===null)throw g(`plugin manifest not found in marketplace candidate: ${P}/.crouter-plugin/plugin.json`);const M=u.scope==="project"?H("project"):T();await R(x,P,u.scope,M,`${P}/.crouter-plugin/plugin.json`)}w(o.root,c);try{w(s,o.root)}catch(u){throw w(c,o.root),u}S(c);for(const u of p){const m=l.plugins.find(y=>y.name===u.name);Le(u.scope,u.name,m.version??u.manifest.version)}U(o.scope,u=>{u.marketplaces[e]===void 0&&(u.marketplaces[e]={}),u.marketplaces[e].last_updated=F()});const v={marketplace:o,manifest:l,pull:{updated:a!==_(o.root),sha:_(o.root)??""}};return t.set(e,v),v}finally{S(s),k(c)&&!k(o.root)&&w(c,o.root)}}d(Ae,"refreshMarketplace");function Le(e,t,n){B(e,i=>{const o=i.plugins[t];o!==void 0?n!==void 0&&(o.version=n):i.plugins[t]={enabled:!0,version:n}}),U(e,i=>{i.plugins[t]===void 0&&(i.plugins[t]={}),i.plugins[t].last_updated=F()})}d(Le,"updatePluginVersion");async function Yn(e,t,n){const i=n==="project"?Q():T();W(n,i);const o=h(i,"plugins"),r=sn(e),a=h(i,"tmp",`${r}.${process.pid}.${Date.now()}`);j(h(i,"tmp"));try{z(e,a,{ref:t,depth:1});const s=E(a);if(s===null)throw f(`cloned repo does not contain a valid .crouter-plugin/plugin.json: ${e}`);const c=await R(s,a,n,i,`${e}/.crouter-plugin/plugin.json`),l=h(o,s.name);if(k(l))throw f(`plugin "${s.name}" is already installed at ${l}`);return j(o),w(a,l),B(n,p=>{p.plugins[s.name]={enabled:!0,version:s.version}}),{name:s.name,scope:n,path:l,...c!==void 0?{memory:c}:{}}}finally{S(a)}}d(Yn,"installFromGit");async function Jn(e,t){const n=q(e),i=E(n);if(i===null)throw g(`plugin manifest not found at ${n}/.crouter-plugin/plugin.json`);const o=t==="project"?Q():T(),r=await R(i,n,t,o,`${n}/.crouter-plugin/plugin.json`,void 0,"linked");W(t,o);const a=h(o,"plugins",i.name);if(k(a))throw f(`plugin "${i.name}" is already installed at ${a}`);return de(n,a),B(t,s=>{s.plugins[i.name]={enabled:!0,version:i.version}}),{name:i.name,scope:t,path:a,...r!==void 0?{memory:r}:{}}}d(Jn,"installFromLocal");async function Qn(e,t){const n=await Ae(e.marketplace,new Map,{strict:!0});if(n===null)throw g(`marketplace not found: ${e.marketplace}`);const i=n.manifest.plugins.find(l=>l.name===e.plugin);if(i===void 0)throw g(`plugin "${e.plugin}" not found in marketplace "${e.marketplace}"`);const o=H(t);W(t,o);const r=h(o,"plugins",e.plugin);if(k(r))throw f(`plugin "${e.plugin}" is already installed at ${r}`);let a,s;if(Ce(i.source)){const l=h(n.marketplace.root,i.source);if(!k(l))throw g(`plugin source path does not exist: ${l}`);const p=E(l);if(p===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);s=await R(p,l,t,o,`${l}/.crouter-plugin/plugin.json`,void 0,"linked"),de(l,r),a=p}else{const l=h(o,"tmp",`${e.plugin}.${process.pid}.${Date.now()}`);j(h(o,"tmp"));try{z(i.source,l,{depth:1});const p=E(l);if(p===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);s=await R(p,l,t,o,`${l}/.crouter-plugin/plugin.json`),j(h(o,"plugins")),w(l,r),a=p}finally{S(l)}}const c=i.version??a.version;return B(t,l=>{const p={enabled:!0,source_marketplace:e.marketplace};c!==void 0&&(p.version=c),l.plugins[e.plugin]=p}),{name:e.plugin,scope:t,path:r,...s!==void 0?{memory:s}:{}}}d(Qn,"installFromMarketplace");async function Xn(e){if(O(e.root)){const s=E(e.root);if(s===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?H("project"):T(),l=await R(s,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`,void 0,"linked");return{updated:!1,sha:_(e.root)??"",manifest:s,...l!==void 0?{memory:l}:{}}}if(!X(e.root)){const s=E(e.root);if(s===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?H("project"):T(),l=await R(s,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`);return{updated:!1,sha:"",manifest:s,...l!==void 0?{memory:l}:{}}}const t=pe(["config","--get","remote.origin.url"],e.root).stdout.trim();if(t==="")throw f(`plugin "${e.name}" has no origin remote to stage an update from`);const n=pe(["symbolic-ref","--short","HEAD"],e.root).stdout.trim();if(n==="")throw f(`plugin "${e.name}" is detached at its installed revision and has no tracked branch to update`);const i=e.scope==="project"?H("project"):T(),o=h(i,"tmp",`${e.name}.${process.pid}.${Date.now()}.candidate`),r=`${o}.previous`,a=_(e.root);j(h(i,"tmp"));try{z(t,o,{ref:n,depth:1});const s=E(o);if(s===null)throw g(`plugin manifest not found in update candidate: ${o}/.crouter-plugin/plugin.json`);const c=await R(s,o,e.scope,i,`${o}/.crouter-plugin/plugin.json`);w(e.root,r);try{w(o,e.root)}catch(p){throw w(r,e.root),p}S(r);const l=_(e.root)??"";return{updated:a!==l,sha:l,manifest:s,...c!==void 0?{memory:c}:{}}}finally{S(o),k(r)&&!k(e.root)&&w(r,e.root)}}d(Xn,"updateGitPluginCandidate");async function He(e,t,n){const i=Pe(e);if(!i&&e.manifest.bundle!==void 0){const p=await Te(e.name,e.manifest.bundle,e.scope,{enable:e.enabled});return{name:e.name,transport:"http",updated:!0,version:p.version,docs:p.docs,kinds:p.kinds,pageComponents:p.pageComponents,commands:p.commands,...p.hooks!==void 0?{hooks:p.hooks}:{},...p.memory!==void 0?{memory:p.memory}:{}}}e.manifest.transport?.kind==="http"&&!i&&xe(e.name);let o,r=!1;if(e.sourceMarketplace!==void 0){const p=await Ae(e.sourceMarketplace,t,n);p!==null&&(o=p.manifest.plugins.find(u=>u.name===e.name)?.version,r=p.pull.updated)}const a=await Xn(e);Le(e.scope,e.name,o??a.manifest.version);const s=await ee(e.name,e.scope),c=await ne(e.name,e.scope),l=$e(a.manifest);return{name:e.name,...e.manifest.transport!==void 0?{transport:e.manifest.transport.kind}:{},updated:r||a.updated,sha:a.sha,...s!==void 0?{commands:s}:{},...c!==void 0?{hooks:c}:{},...a.memory!==void 0?{memory:a.memory}:{},...l.length>0?{warnings:l}:{}}}d(He,"updateOnePlugin");const Mt=N({name:"install",description:"install from a ref or HTTP endpoint",whenToUse:"installing one plugin from a marketplace ref, git URL, local path, or an HTTP directory-archive endpoint",help:{name:"pkg plugin install",summary:"install a plugin from a ref or HTTP endpoint",params:[{kind:"positional",name:"install-ref",type:"string",required:!1,constraint:"Plugin install ref. Provide exactly one of INSTALL-REF or --endpoint. Accepted ref forms: marketplace/plugin; git URL starting https://, ssh://, git@, file://, or ending .git; local path starting ./, ../, or /."},{kind:"flag",name:"endpoint",type:"string",required:!1,constraint:"HTTP plugin directory-archive endpoint. Provide exactly one of --endpoint or INSTALL-REF. Must be an absolute https: URL; http: is permitted only for localhost, 127.0.0.1, [::1], ::1, or host.docker.internal. Credentials and fragments are rejected."},{kind:"flag",name:"name",type:"string",required:!1,constraint:"Required with --endpoint and rejected without it. Lowercase kebab-case plugin handle."},{kind:"flag",name:"auth-env",type:"string",required:!1,constraint:"Optional environment variable holding the HTTP bearer token. Accepted only with --endpoint; its value is never stored."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: project if available, else user."},{kind:"flag",name:"ref",type:"string",required:!1,constraint:"Git ref (branch/tag) for git URL installs. Rejected with --endpoint; ignored for marketplace and local path refs."}],output:[{name:"name",type:"string",required:!0,constraint:"Plugin name as installed."},{name:"scope",type:"string",required:!0,constraint:"Scope the plugin was installed into."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the installed plugin directory."},{name:"transport",type:"string",required:!1,constraint:"exec or http when the plugin declares commands. Always http for an --endpoint install."},{name:"version",type:"string",required:!1,constraint:"First 12 hex characters of the fetched archive SHA-256 for an --endpoint install."},{name:"docs",type:"integer",required:!1,constraint:"Memory document count written from an --endpoint archive."},{name:"kinds",type:"integer",required:!1,constraint:"Kind-registry entry count declared by an --endpoint archive\u2019s bundle.json."},{name:"pageComponents",type:"integer",required:!1,constraint:"Page-component registration count declared by an --endpoint archive\u2019s bundle.json."},{name:"commands",type:"object",required:!1,constraint:"Present only when the plugin declares a command manifest. {mounts: string[] (accepted command paths now live for the next invocation), issues: object[] (typed validation issues that rejected a contribution \u2014 {code, path?, message, received, expected, next})}. Validated statically; commands are never executed."},{name:"hooks",type:"object",required:!1,constraint:"Present only when the plugin declares hooks. {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}. Command targets, lifecycle events, and replacement collisions are validated statically; hook executables are never run."},{name:"warnings",type:"string[]",required:!1,constraint:"Advisory missing PATH executable requirements declared by the installed plugin. The install still succeeds and leaves the plugin enabled."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only when the install keeps that directory as a live link)}."}],outputKind:"object",effects:["A ref install clones, links, or copies the plugin into the scope plugins directory and registers it with enabled=true. Marketplace installs refresh the source marketplace before resolving the plugin entry.","An --endpoint install fetches and validates one authenticated uncompressed tar archive before writing. It replaces the complete plugin directory with synthesized provenance and invocation metadata, commands.json, memory docs, and, when declared, hooks.json plus the hooks/ tree; it also copies any kind-registry entries the bundle.json declares (they join the launch registry below this scope\u2019s own config.json kinds), and any page components it declares (they join the active page-component catalog alongside the user config entries); a fetch or validation failure preserves the prior package.","If the plugin declares a command manifest, its commands go live on the next crtr invocation. Exec commands run trusted local code only when explicitly invoked; HTTP commands call their declared endpoint only when explicitly invoked.","Plugin command hooks go live on the next crtr invocation. They run implicitly with caller authority, may receive normalized inputs and after results, may block or replace declared targets, and may transmit received data. Lifecycle hooks run unprompted at every declared event before node launch and may transmit node identity and resolved paths. Hook executables are never run during install or update validation.","A plugin manifest `requires` declaration is checked against the PATH a node bash receives after install. Missing executables emit a warning with the declared install hint but never fail the install, disable the plugin, or remove its bare-binary contributions.","Before activation the candidate\u2019s memory corpus is migrated to exact canonical identity and refused if it cannot mount. A staged candidate is migrated in staging and rolls back with the package; a local path or marketplace-relative source stays a live link, so its own directory is rewritten in place, keeps that rewrite whether or not the install completes, and is named as `memory.linkedSource`. A refused corpus writes nothing and installs nothing."]},run:d(async e=>{const t=e.installRef,n=e.endpoint,i=e.name,o=e.authEnv,r=e.scope,a=e.ref,s=Mn(r);if(t===void 0==(n===void 0))throw $("provide exactly one of INSTALL-REF or --endpoint");if(n!==void 0){if(i===void 0)throw $("--name is required with --endpoint");if(a!==void 0)throw $("--ref is only valid with a git INSTALL-REF, not --endpoint");return Gn(i,n,o,s)}if(i!==void 0)throw $("--name is only valid with --endpoint");if(o!==void 0)throw $("--auth-env is only valid with --endpoint");const c=Kn(t),l=c.kind==="marketplace"?await Qn(c.value,s):c.kind==="local"?await Jn(c.value,s):await Yn(c.value,a,s),p=L(l.name,l.scope),v=await ee(l.name,l.scope),u=await ne(l.name,l.scope),m=p===null?[]:$e(p.manifest);return{...l,...p?.manifest.transport!==void 0?{transport:p.manifest.transport.kind}:{},...v!==void 0?{commands:v}:{},...u!==void 0?{hooks:u}:{},...m.length>0?{warnings:m}:{}}},"run")}),qt=N({name:"remove",description:"remove plugin and directory",whenToUse:"uninstalling a plugin: deletes its directory and removes it from config",help:{name:"pkg plugin remove",summary:"remove a plugin and its directory from the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to remove."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: searches every scope."}],output:[{name:"scopes",type:"string[]",required:!0,constraint:"Scopes the plugin was removed from."}],outputKind:"object",effects:["Deletes the plugin directory. Removes the plugin entry from config.json."]},run:d(async e=>{const t=e.name,n=e.scope;if(t==="crtr")throw $('cannot remove builtin plugin "crtr" \u2014 it ships with the binary');let i;if(n!==void 0){const r=se(n);if(r==="builtin")throw $("cannot remove plugins from builtin scope");i=r==="all"?["project","user"].filter(a=>a!=="project"||le()!==null):[r]}else i=["project","user"].filter(r=>r!=="project"||le()!==null);const o=[];for(const r of i){const a=Ge(r);if(a===null)continue;const s=h(a,t);k(s)&&(S(s),B(r,c=>{delete c.plugins[t]}),U(r,c=>{delete c.plugins[t]}),o.push(r))}if(o.length===0)throw g(`plugin not found: ${t}`);return{scopes:o}},"run")}),_t=N({name:"enable",description:"enable a plugin",whenToUse:"reactivating a plugin that was previously disabled so its memory docs resolve again",help:{name:"pkg plugin enable",summary:"enable a plugin in the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to enable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only for a symlinked install)}."}],outputKind:"object",effects:["Validates the installed package before any config change: its memory corpus is migrated to exact canonical identity and refused if it cannot mount. A refusal leaves the plugin disabled.","Sets plugin enabled=true in config.json."]},run:d(async e=>{const t=e.name,n=Tn(t,e.scope);if(n===null)throw g(`plugin not found: ${t}`);const i=E(n.root);if(i===null)throw g(`plugin manifest not found at ${n.root}/.crouter-plugin/plugin.json`);const o=n.scope==="project"?H("project"):T(),r=await R(i,n.root,n.scope,o,`${n.root}/.crouter-plugin/plugin.json`,void 0,O(n.root)?"linked":"package");return{scope:(await we(e,!0)).scope,...r!==void 0?{memory:r}:{}}},"run")}),Ct=N({name:"disable",description:"disable without removing",whenToUse:"hiding a plugin from resolution without deleting it, so you can re-enable it later",help:{name:"pkg plugin disable",summary:"disable a plugin (keeps files, hides from resolution)",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to disable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."}],outputKind:"object",effects:["Sets plugin enabled=false in config.json."]},run:d(async e=>({scope:(await we(e,!1)).scope}),"run")}),At=N({name:"update",description:"update installed plugin content",whenToUse:"refreshing one named plugin or all installed plugins: archive plugins replace their complete package, while source-installed plugins retain their source update behavior",help:{name:"pkg plugin update",summary:"refresh one or all installed plugins",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Plugin name to update. Omit to update all installed plugins."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Narrows resolution."}],output:[{name:"updated",type:"object[]",required:!0,constraint:"One entry per plugin processed: {name, transport?, updated, sha?, version?, docs?, kinds?, pageComponents?, commands?, hooks?, memory?, warnings?, error?}. memory is present for a plugin shipping a memory store and reports the same corpus migration install performs: {docs, migrated, linkedSource?}. Archive plugins report transport=http and replace their complete directory after an authenticated refetch; version is the archive content identifier, docs is the written memory-document count, kinds is the declared kind-registry entry count, and pageComponents is the declared page-component registration count. sha is present for git updates. A bulk update reports and skips a failed archive plugin. commands is present for validated command plugins: {mounts: string[] (accepted command paths), issues: object[]}. hooks is present for plugins declaring hooks: {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}; it is static and never executes hooks. warnings lists advisory PATH requirements that remain absent after update."}],outputKind:"object",effects:["Archive plugins unconditionally re-fetch, validate, and replace their complete package; a named failure exits nonzero and preserves the prior package. Bulk update reports a failed archive plugin and continues. Source-installed plugins retain their source update, version, and last_updated behavior.","Each candidate passes the same pre-activation memory-corpus migration install performs, with the same linked-source rewrite semantics for a symlinked install."]},run:d(async e=>{const t=e.name,n=e.scope,i=n===void 0?void 0:se(n),o=new Map;if(t!==void 0){const s=i===void 0||i==="all"||i==="builtin"?L(t):L(t,i);if(s===null)throw g(`plugin not found: ${t}${i===void 0||i==="all"||i==="builtin"?"":` (scope: ${i})`}`);return{updated:[await He(s,o,{strict:!0})]}}const r=ae().filter(s=>s.scope!=="builtin"&&(i===void 0||i==="all"||s.scope===i)),a=[];for(const s of r)try{a.push(await He(s,o,{strict:!1}))}catch(c){a.push({name:s.name,...s.manifest.transport!==void 0?{transport:s.manifest.transport.kind}:{},updated:!1,error:c instanceof Error?c.message:String(c)})}return{updated:a}},"run")});export{R as assertPluginCandidateValid,Qn as installFromMarketplace,Ce as isMarketplaceRelativeSource,Ct as pluginDisable,_t as pluginEnable,Mt as pluginInstall,qt as pluginRemove,At as pluginUpdate,Tt as revalidateBundlePlugin};
15
+ `)}`,{issues:u,next:`Correct the package's memory documents, then retry \u2014 "${e.name}" was not activated.`})}return{docs:v.documents,migrated:[...new Set([...l.wrote.consumers,...l.wrote.identities])].map(m=>oe(r,m)).sort(),...o==="linked"?{linkedSource:me(r)}:{}}}d(Dn,"migratePluginMemory");async function R(e,t,n,i,o,r,a="package"){try{cn(e)}catch(u){const m=u instanceof Error?u.message:String(u);throw f(`plugin manifest at ${o} declares invalid memory_extensions: ${m}`)}Cn(e,o),Hn(e,o),An(e,o),Ln(e,o);const[s,c]=await Promise.all([J(),Q()]),l=ne({name:e.name,scope:n,root:t,manifest:e,enabled:!0},new Set(Y),s,c);if(l.issues.length>0)throw X(`plugin command behavior at ${o} is invalid`,l.issues);await Bn(e,t,n,i,o,r);const p=h(t,"memory"),v=h(i,"memory","__plugin_candidate__.md");for(const u of sn(p,m=>m.endsWith(".md"),m=>m.startsWith("."))){let m;try{m=kn(an(u)).data}catch(b){throw f(`plugin memory document ${U(t,u)} has invalid YAML frontmatter: ${b instanceof Error?b.message.split(`
16
+ `)[0]:String(b)}`)}const y=vn(m);if(y!==null)throw f(`plugin memory document ${U(t,u)} is invalid: ${y}`);for(const b of un(m?.extensions,dn({scope:n,path:v},{candidate:e})))throw f(`plugin memory document ${U(t,u)} is invalid: ${b.path}: ${b.message}`)}return Dn(e,t,n,o,a)}d(R,"assertPluginCandidateValid");function Nn(e){return{kind:"http",endpoint:new URL(e.endpoint).origin,...e.authEnv!==void 0?{authEnv:e.authEnv}:{}}}d(Nn,"invocationTransport");function A(e,t){const n=M(e,t);if(n===e||!n.startsWith(e+Ve))throw f(`bundle member path escapes the staging directory: ${t}`);return n}d(A,"stagedPath");function Un(e,t,n){rn(A(e,".crouter-plugin/plugin.json"),t);for(const i of n.directories)j(A(e,i.path));O(A(e,"commands.json"),n.commandsBytes);for(const i of n.memory){const o=A(e,i.path);j(M(o,"..")),O(o,i.bytes)}if(n.hooks!==void 0){O(A(e,"hooks.json"),n.hooks.manifest);for(const i of n.hooks.files){const o=A(e,i.path);j(M(o,"..")),O(o,i.bytes)}We(A(e,"hooks/dispatch"),493)}}d(Un,"writeStagedBundle");async function Fn(e,t,n,i,o){const r=await R(o,n,t,i,`${n}/.crouter-plugin/plugin.json`),a={name:e,scope:t,root:n,manifest:o,enabled:!0},[s,c]=await Promise.all([J(),Q()]),l=ne(a,new Set(Y),s,c);if(l.issues.length>0)throw X(`bundle staged package for "${e}" is invalid`,l.issues);return r}d(Fn,"validateStagedBundle");function Se(e){return e.sourceMarketplace!==void 0||ee(e.root)||G(e.root)}d(Se,"isSourceInstalled");function Re(e){throw f(`HTTP plugin "${e}" uses the removed commands-only endpoint format`,{next:`Run \`crtr pkg plugin remove ${e}\`, then reinstall it with \`crtr pkg plugin install --name ${e} --endpoint <archive-url>\`.`})}d(Re,"rejectLegacyHttpPlugin");function Vn(e,t,n){if(!k(n))return;const i=H(e,t);if(i?.manifest.bundle!==void 0)return i;throw i?.manifest.transport?.kind==="http"&&i!==void 0&&!Se(i)&&Re(e),f(`plugin "${e}" already exists at ${n}; run \`crtr pkg plugin remove ${e}\` before installing the archive plugin.`)}d(Vn,"existingBundleRoot");function Ee(e,t,n,i){const o=je(e,t.endpoint,t.authEnv),r={endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},a=h(_(n),e);return Vn(e,n,a),{bundle:r,transport:Nn(r),scopeRootPath:i,root:a}}d(Ee,"resolveBundleTarget");function Te(e,t){return{name:e,endpoint:t.endpoint,...t.authEnv!==void 0?{authEnv:t.authEnv}:{}}}d(Te,"fetchTarget");const Wn=6e4,On=1e4;async function qe(e,t,n,i){const o=t==="project"?Z():T();return j(h(o,"tmp")),nn(ue(o,e),()=>i(o),{timeoutMs:n,timeoutError:d(()=>f(`timed out waiting for another crtr process to finish replacing plugin "${e}"`,{next:`Re-run once that process has finished, or check for a stalled crtr holding ${ue(o,e)}.`}),"timeoutError")})}d(qe,"withBundleSwapLock");async function Me(e,t,n,i){return qe(e,n,Wn,async o=>{const r=Ee(e,t,n,o),a=await ke(Te(e,r.bundle));if(a.status!==200){const s=`HTTP plugin bundle fetch failed for "${e}": ${a.message}`;throw a.status==="auth_env_missing"?$(s):a.status==="cli_unreachable"?ze(s):f(s)}return Ae(e,n,r,a.raw,a.etag,i)})}d(Me,"replaceBundlePlugin");async function Mt(e,t,n,i){return qe(e,n,On,async o=>{try{const r=Ee(e,t,n,o),a=i.conditional?Je(n).plugins[e]?.etag:void 0,s={...a!==void 0?{ifNoneMatch:a}:{},...i.timeoutMs!==void 0?{timeoutMs:i.timeoutMs}:{}},c=await ke(Te(e,r.bundle),s);if(c.status===304)return;if(c.status!==200)throw f(`HTTP plugin bundle revalidation failed for "${e}": ${c.message}`);const l=Ce(c.raw);if(Gn(e,n,r.root,l)){_e(n,e,c.etag,{swapped:!1});return}return await Ae(e,n,r,c.raw,c.etag,i,l)}finally{zn(n,e)}})}d(Mt,"revalidateBundlePlugin");function zn(e,t){V(e,n=>{n.plugins[t]===void 0&&(n.plugins[t]={}),n.plugins[t].checked_at=W()})}d(zn,"recordPluginCheck");function _e(e,t,n,i){V(e,o=>{o.plugins[t]===void 0&&(o.plugins[t]={}),i.swapped&&(o.plugins[t].last_updated=W()),o.plugins[t].checked_at=W(),n===void 0?delete o.plugins[t].etag:o.plugins[t].etag=n})}d(_e,"recordCheckedGeneration");function Ce(e){return Oe("sha256").update(e).digest("hex").slice(0,12)}d(Ce,"bundleVersion");function Gn(e,t,n,i){return Ye(t).plugins[e]?.version!==i?!1:k(h(n,"commands.json"))}d(Gn,"isInstalledGeneration");async function Ae(e,t,n,i,o,r,a){const{bundle:s,transport:c,scopeRootPath:l,root:p}=n,[v,u]=await Promise.all([J(),Q()]),m=await Sn(i,{reservedCoreNames:new Set(Y),coreCommandPaths:v,extensibleCoreBranches:u});if(m.bundle===void 0)throw X(`HTTP plugin bundle for "${e}" is invalid`,m.issues);const y=a??Ce(i),b={name:e,version:y,commands:"commands.json",transport:c,bundle:s,...m.bundle.kinds!==void 0?{kinds:m.bundle.kinds}:{},...m.bundle.page_components!==void 0?{page_components:m.bundle.page_components}:{},...m.bundle.memory_extensions!==void 0?{memory_extensions:m.bundle.memory_extensions}:{},...m.bundle.hooks!==void 0?{hooks:"hooks.json",hookExecutable:"hooks/dispatch"}:{}},P=h(l,"tmp"),x=h(P,`${e}.${process.pid}`),q=`${x}.prev`;if(k(q))throw f(`cannot replace plugin "${e}": prior interrupted replacement remains at ${q}`);j(P),j(_(t)),S(x);let D;try{j(x),Un(x,b,m.bundle),D=await Fn(e,t,x,l,b);let L=!1;k(p)&&(w(p,q),L=!0);try{w(x,p)}catch(De){throw L&&w(q,p),De}L&&S(q)}finally{S(x)}z(t,l),I(t,L=>{L.plugins[e]={enabled:r.enable?!0:L.plugins[e]?.enabled??!0,version:y}}),_e(t,e,o,{swapped:!0});const re=await te(e,t);if(re===void 0)throw f(`bundle plugin "${e}" has no staged command report`);const ae=await ie(e,t);return{name:e,scope:t,path:p,transport:"http",version:y,docs:m.bundle.memory.length,kinds:Object.keys(m.bundle.kinds??{}).length,pageComponents:(m.bundle.page_components??[]).length,commands:re,...ae!==void 0?{hooks:ae}:{},...D!==void 0?{memory:D}:{}}}d(Ae,"applyBundleArchive");async function Kn(e,t,n,i){const o=je(e,t,n);return Me(e,{endpoint:o.endpoint,...o.authEnv!==void 0?{authEnv:o.authEnv}:{}},i,{enable:!0})}d(Kn,"installHttpPlugin");function Yn(e){if(e.startsWith("./")||e.startsWith("../")||e.startsWith("/"))return{kind:"local",value:e};if(be(e))return{kind:"git",value:e};const t=e.split("/");if(t.length===2&&t[0]!==""&&t[1]!=="")return{kind:"marketplace",value:{marketplace:t[0],plugin:t[1]}};throw $(`invalid plugin install ref: ${e}
17
+ Accepted forms: marketplace/plugin, git URL (https://, ssh://, git@, file://, or *.git), or local path starting ./, ../, or /. Bare plugin names are not install refs.`)}d(Yn,"classifyInstallRef");function Le(e){return e.startsWith("./")||e.startsWith("../")||!Fe(e)&&!be(e)}d(Le,"isMarketplaceRelativeSource");async function He(e,t,n){const i=t.get(e);if(i!==void 0)return i;const o=Ge(e);if(o===null){if(n.strict)throw g(`marketplace not found: ${e}`);return null}const r=he(o.root);if(r===null)throw g(`marketplace manifest not found: ${o.root}/.crouter-marketplace/marketplace.json`);if(!ee(o.root)){const l={marketplace:o,manifest:r,pull:{updated:!1,sha:C(o.root)??""}};return t.set(e,l),l}const a=C(o.root),s=h(se(o.root),`.${e}.${process.pid}.${Date.now()}.candidate`),c=`${s}.previous`;try{K(o.url,s,{ref:o.ref,depth:1});const l=he(s);if(l===null)throw g(`marketplace manifest not found in candidate checkout: ${s}/.crouter-marketplace/marketplace.json`);const p=le().filter(u=>u.sourceMarketplace===e&&G(u.root));for(const u of p){const m=l.plugins.find(D=>D.name===u.name);if(m===void 0||!Le(m.source))throw f(`marketplace candidate removes relative-source plugin "${u.name}" while it is installed`);const y=on(u.root);if(y===null)throw f(`installed marketplace plugin "${u.name}" has no readable symlink target`);const b=U(o.root,M(se(u.root),y)),P=M(s,m.source);if(P!==M(s,b))throw f(`marketplace candidate moves installed relative-source plugin "${u.name}" from ${b} to ${m.source}`);if(!k(P))throw g(`marketplace candidate source path does not exist for plugin "${u.name}": ${P}`);const x=E(P);if(x===null)throw g(`plugin manifest not found in marketplace candidate: ${P}/.crouter-plugin/plugin.json`);const q=u.scope==="project"?B("project"):T();await R(x,P,u.scope,q,`${P}/.crouter-plugin/plugin.json`)}w(o.root,c);try{w(s,o.root)}catch(u){throw w(c,o.root),u}S(c);for(const u of p){const m=l.plugins.find(y=>y.name===u.name);Be(u.scope,u.name,m.version??u.manifest.version)}V(o.scope,u=>{u.marketplaces[e]===void 0&&(u.marketplaces[e]={}),u.marketplaces[e].last_updated=W()});const v={marketplace:o,manifest:l,pull:{updated:a!==C(o.root),sha:C(o.root)??""}};return t.set(e,v),v}finally{S(s),k(c)&&!k(o.root)&&w(c,o.root)}}d(He,"refreshMarketplace");function Be(e,t,n){I(e,i=>{const o=i.plugins[t];o!==void 0?n!==void 0&&(o.version=n):i.plugins[t]={enabled:!0,version:n}}),V(e,i=>{i.plugins[t]===void 0&&(i.plugins[t]={}),i.plugins[t].last_updated=W()})}d(Be,"updatePluginVersion");async function Jn(e,t,n){const i=n==="project"?Z():T();z(n,i);const o=_(n),r=ln(e),a=h(i,"tmp",`${r}.${process.pid}.${Date.now()}`);j(h(i,"tmp"));try{K(e,a,{ref:t,depth:1});const s=E(a);if(s===null)throw f(`cloned repo does not contain a valid .crouter-plugin/plugin.json: ${e}`);const c=await R(s,a,n,i,`${e}/.crouter-plugin/plugin.json`),l=h(o,s.name);if(k(l))throw f(`plugin "${s.name}" is already installed at ${l}`);return j(o),w(a,l),I(n,p=>{p.plugins[s.name]={enabled:!0,version:s.version}}),{name:s.name,scope:n,path:l,...c!==void 0?{memory:c}:{}}}finally{S(a)}}d(Jn,"installFromGit");async function Qn(e,t){const n=M(e),i=E(n);if(i===null)throw g(`plugin manifest not found at ${n}/.crouter-plugin/plugin.json`);const o=t==="project"?Z():T(),r=await R(i,n,t,o,`${n}/.crouter-plugin/plugin.json`,void 0,"linked");z(t,o);const a=h(_(t),i.name);if(k(a))throw f(`plugin "${i.name}" is already installed at ${a}`);return pe(n,a),I(t,s=>{s.plugins[i.name]={enabled:!0,version:i.version}}),{name:i.name,scope:t,path:a,...r!==void 0?{memory:r}:{}}}d(Qn,"installFromLocal");async function Xn(e,t){const n=await He(e.marketplace,new Map,{strict:!0});if(n===null)throw g(`marketplace not found: ${e.marketplace}`);const i=n.manifest.plugins.find(l=>l.name===e.plugin);if(i===void 0)throw g(`plugin "${e.plugin}" not found in marketplace "${e.marketplace}"`);const o=B(t);z(t,o);const r=h(_(t),e.plugin);if(k(r))throw f(`plugin "${e.plugin}" is already installed at ${r}`);let a,s;if(Le(i.source)){const l=h(n.marketplace.root,i.source);if(!k(l))throw g(`plugin source path does not exist: ${l}`);const p=E(l);if(p===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);s=await R(p,l,t,o,`${l}/.crouter-plugin/plugin.json`,void 0,"linked"),pe(l,r),a=p}else{const l=h(o,"tmp",`${e.plugin}.${process.pid}.${Date.now()}`);j(h(o,"tmp"));try{K(i.source,l,{depth:1});const p=E(l);if(p===null)throw g(`plugin manifest not found at ${l}/.crouter-plugin/plugin.json`);s=await R(p,l,t,o,`${l}/.crouter-plugin/plugin.json`),j(_(t)),w(l,r),a=p}finally{S(l)}}const c=i.version??a.version;return I(t,l=>{const p={enabled:!0,source_marketplace:e.marketplace};c!==void 0&&(p.version=c),l.plugins[e.plugin]=p}),{name:e.plugin,scope:t,path:r,...s!==void 0?{memory:s}:{}}}d(Xn,"installFromMarketplace");async function Zn(e){if(G(e.root)){const s=E(e.root);if(s===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?B("project"):T(),l=await R(s,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`,void 0,"linked");return{updated:!1,sha:C(e.root)??"",manifest:s,...l!==void 0?{memory:l}:{}}}if(!ee(e.root)){const s=E(e.root);if(s===null)throw g(`plugin manifest not found at ${e.root}/.crouter-plugin/plugin.json`);const c=e.scope==="project"?B("project"):T(),l=await R(s,e.root,e.scope,c,`${e.root}/.crouter-plugin/plugin.json`);return{updated:!1,sha:"",manifest:s,...l!==void 0?{memory:l}:{}}}const t=fe(["config","--get","remote.origin.url"],e.root).stdout.trim();if(t==="")throw f(`plugin "${e.name}" has no origin remote to stage an update from`);const n=fe(["symbolic-ref","--short","HEAD"],e.root).stdout.trim();if(n==="")throw f(`plugin "${e.name}" is detached at its installed revision and has no tracked branch to update`);const i=e.scope==="project"?B("project"):T(),o=h(i,"tmp",`${e.name}.${process.pid}.${Date.now()}.candidate`),r=`${o}.previous`,a=C(e.root);j(h(i,"tmp"));try{K(t,o,{ref:n,depth:1});const s=E(o);if(s===null)throw g(`plugin manifest not found in update candidate: ${o}/.crouter-plugin/plugin.json`);const c=await R(s,o,e.scope,i,`${o}/.crouter-plugin/plugin.json`);w(e.root,r);try{w(o,e.root)}catch(p){throw w(r,e.root),p}S(r);const l=C(e.root)??"";return{updated:a!==l,sha:l,manifest:s,...c!==void 0?{memory:c}:{}}}finally{S(o),k(r)&&!k(e.root)&&w(r,e.root)}}d(Zn,"updateGitPluginCandidate");async function Ie(e,t,n){const i=Se(e);if(!i&&e.manifest.bundle!==void 0){const p=await Me(e.name,e.manifest.bundle,e.scope,{enable:e.enabled});return{name:e.name,transport:"http",updated:!0,version:p.version,docs:p.docs,kinds:p.kinds,pageComponents:p.pageComponents,commands:p.commands,...p.hooks!==void 0?{hooks:p.hooks}:{},...p.memory!==void 0?{memory:p.memory}:{}}}e.manifest.transport?.kind==="http"&&!i&&Re(e.name);let o,r=!1;if(e.sourceMarketplace!==void 0){const p=await He(e.sourceMarketplace,t,n);p!==null&&(o=p.manifest.plugins.find(u=>u.name===e.name)?.version,r=p.pull.updated)}const a=await Zn(e);Be(e.scope,e.name,o??a.manifest.version);const s=await te(e.name,e.scope),c=await ie(e.name,e.scope),l=Pe(a.manifest);return{name:e.name,...e.manifest.transport!==void 0?{transport:e.manifest.transport.kind}:{},updated:r||a.updated,sha:a.sha,...s!==void 0?{commands:s}:{},...c!==void 0?{hooks:c}:{},...a.memory!==void 0?{memory:a.memory}:{},...l.length>0?{warnings:l}:{}}}d(Ie,"updateOnePlugin");const _t=F({name:"install",description:"install from a ref or HTTP endpoint",whenToUse:"installing one plugin from a marketplace ref, git URL, local path, or an HTTP directory-archive endpoint",help:{name:"pkg plugin install",summary:"install a plugin from a ref or HTTP endpoint",params:[{kind:"positional",name:"install-ref",type:"string",required:!1,constraint:"Plugin install ref. Provide exactly one of INSTALL-REF or --endpoint. Accepted ref forms: marketplace/plugin; git URL starting https://, ssh://, git@, file://, or ending .git; local path starting ./, ../, or /."},{kind:"flag",name:"endpoint",type:"string",required:!1,constraint:"HTTP plugin directory-archive endpoint. Provide exactly one of --endpoint or INSTALL-REF. Must be an absolute https: URL; http: is permitted only for localhost, 127.0.0.1, [::1], ::1, or host.docker.internal. Credentials and fragments are rejected."},{kind:"flag",name:"name",type:"string",required:!1,constraint:"Required with --endpoint and rejected without it. Lowercase kebab-case plugin handle."},{kind:"flag",name:"auth-env",type:"string",required:!1,constraint:"Optional environment variable holding the HTTP bearer token. Accepted only with --endpoint; its value is never stored."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: project if available, else user."},{kind:"flag",name:"ref",type:"string",required:!1,constraint:"Git ref (branch/tag) for git URL installs. Rejected with --endpoint; ignored for marketplace and local path refs."}],output:[{name:"name",type:"string",required:!0,constraint:"Plugin name as installed."},{name:"scope",type:"string",required:!0,constraint:"Scope the plugin was installed into."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the installed plugin directory."},{name:"transport",type:"string",required:!1,constraint:"exec or http when the plugin declares commands. Always http for an --endpoint install."},{name:"version",type:"string",required:!1,constraint:"First 12 hex characters of the fetched archive SHA-256 for an --endpoint install."},{name:"docs",type:"integer",required:!1,constraint:"Memory document count written from an --endpoint archive."},{name:"kinds",type:"integer",required:!1,constraint:"Kind-registry entry count declared by an --endpoint archive\u2019s bundle.json."},{name:"pageComponents",type:"integer",required:!1,constraint:"Page-component registration count declared by an --endpoint archive\u2019s bundle.json."},{name:"commands",type:"object",required:!1,constraint:"Present only when the plugin declares a command manifest. {mounts: string[] (accepted command paths now live for the next invocation), issues: object[] (typed validation issues that rejected a contribution \u2014 {code, path?, message, received, expected, next})}. Validated statically; commands are never executed."},{name:"hooks",type:"object",required:!1,constraint:"Present only when the plugin declares hooks. {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}. Command targets, lifecycle events, and replacement collisions are validated statically; hook executables are never run."},{name:"warnings",type:"string[]",required:!1,constraint:"Advisory missing PATH executable requirements declared by the installed plugin. The install still succeeds and leaves the plugin enabled."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only when the install keeps that directory as a live link)}."}],outputKind:"object",effects:["A ref install clones, links, or copies the plugin into the scope plugins directory and registers it with enabled=true. Marketplace installs refresh the source marketplace before resolving the plugin entry.","An --endpoint install fetches and validates one authenticated uncompressed tar archive before writing. It replaces the complete plugin directory with synthesized provenance and invocation metadata, commands.json, memory docs, and, when declared, hooks.json plus the hooks/ tree; it also copies any kind-registry entries the bundle.json declares (they join the launch registry below this scope\u2019s own config.json kinds), and any page components it declares (they join the active page-component catalog alongside the user config entries); a fetch or validation failure preserves the prior package.","If the plugin declares a command manifest, its commands go live on the next crtr invocation. Exec commands run trusted local code only when explicitly invoked; HTTP commands call their declared endpoint only when explicitly invoked.","Plugin command hooks go live on the next crtr invocation. They run implicitly with caller authority, may receive normalized inputs and after results, may block or replace declared targets, and may transmit received data. Lifecycle hooks run unprompted at every declared event before node launch and may transmit node identity and resolved paths. Hook executables are never run during install or update validation.","A plugin manifest `requires` declaration is checked against the PATH a node bash receives after install. Missing executables emit a warning with the declared install hint but never fail the install, disable the plugin, or remove its bare-binary contributions.","Before activation the candidate\u2019s memory corpus is migrated to exact canonical identity and refused if it cannot mount. A staged candidate is migrated in staging and rolls back with the package; a local path or marketplace-relative source stays a live link, so its own directory is rewritten in place, keeps that rewrite whether or not the install completes, and is named as `memory.linkedSource`. A refused corpus writes nothing and installs nothing."]},run:d(async e=>{N();const t=e.installRef,n=e.endpoint,i=e.name,o=e.authEnv,r=e.scope,a=e.ref,s=Mn(r);if(t===void 0==(n===void 0))throw $("provide exactly one of INSTALL-REF or --endpoint");if(n!==void 0){if(i===void 0)throw $("--name is required with --endpoint");if(a!==void 0)throw $("--ref is only valid with a git INSTALL-REF, not --endpoint");return Kn(i,n,o,s)}if(i!==void 0)throw $("--name is only valid with --endpoint");if(o!==void 0)throw $("--auth-env is only valid with --endpoint");const c=Yn(t),l=c.kind==="marketplace"?await Xn(c.value,s):c.kind==="local"?await Qn(c.value,s):await Jn(c.value,a,s),p=H(l.name,l.scope),v=await te(l.name,l.scope),u=await ie(l.name,l.scope),m=p===null?[]:Pe(p.manifest);return{...l,...p?.manifest.transport!==void 0?{transport:p.manifest.transport.kind}:{},...v!==void 0?{commands:v}:{},...u!==void 0?{hooks:u}:{},...m.length>0?{warnings:m}:{}}},"run")}),Ct=F({name:"remove",description:"remove plugin and directory",whenToUse:"uninstalling a plugin: deletes its directory and removes it from config",help:{name:"pkg plugin remove",summary:"remove a plugin and its directory from the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to remove."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: searches every scope."}],output:[{name:"scopes",type:"string[]",required:!0,constraint:"Scopes the plugin was removed from."}],outputKind:"object",effects:["Deletes the plugin directory. Removes the plugin entry from config.json."]},run:d(async e=>{N();const t=e.name,n=e.scope;if(t==="crtr")throw $('cannot remove builtin plugin "crtr" \u2014 it ships with the binary');let i;if(n!==void 0){const r=ce(n);if(r==="builtin")throw $("cannot remove plugins from builtin scope");i=r==="all"?["project","user"].filter(a=>a!=="project"||de()!==null):[r]}else i=["project","user"].filter(r=>r!=="project"||de()!==null);const o=[];for(const r of i){const a=_(r);if(a===null)continue;const s=h(a,t);k(s)&&(S(s),I(r,c=>{delete c.plugins[t]}),V(r,c=>{delete c.plugins[t]}),o.push(r))}if(o.length===0)throw g(`plugin not found: ${t}`);return{scopes:o}},"run")}),At=F({name:"enable",description:"enable a plugin",whenToUse:"reactivating a plugin that was previously disabled so its memory docs resolve again",help:{name:"pkg plugin enable",summary:"enable a plugin in the given scope",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to enable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."},{name:"memory",type:"object",required:!1,constraint:"Present only when the plugin ships a memory store. {docs: integer (documents checked), migrated: string[] (store-relative documents rewritten to reach exact canonical identity), linkedSource?: string (the caller-owned directory converged in place, present only for a symlinked install)}."}],outputKind:"object",effects:["Validates the installed package before any config change: its memory corpus is migrated to exact canonical identity and refused if it cannot mount. A refusal leaves the plugin disabled.","Sets plugin enabled=true in config.json."]},run:d(async e=>{N();const t=e.name,n=qn(t,e.scope);if(n===null)throw g(`plugin not found: ${t}`);const i=E(n.root);if(i===null)throw g(`plugin manifest not found at ${n.root}/.crouter-plugin/plugin.json`);const o=n.scope==="project"?B("project"):T(),r=await R(i,n.root,n.scope,o,`${n.root}/.crouter-plugin/plugin.json`,void 0,G(n.root)?"linked":"package");return{scope:(await $e(e,!0)).scope,...r!==void 0?{memory:r}:{}}},"run")}),Lt=F({name:"disable",description:"disable without removing",whenToUse:"hiding a plugin from resolution without deleting it, so you can re-enable it later",help:{name:"pkg plugin disable",summary:"disable a plugin (keeps files, hides from resolution)",params:[{kind:"positional",name:"name",type:"string",required:!0,constraint:"Plugin name to disable."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Default: scope where the plugin is installed."}],output:[{name:"scope",type:"string",required:!0,constraint:"Scope the change was applied in."}],outputKind:"object",effects:["Sets plugin enabled=false in config.json."]},run:d(async e=>(N(),{scope:(await $e(e,!1)).scope}),"run")}),Ht=F({name:"update",description:"update installed plugin content",whenToUse:"refreshing one named plugin or all installed plugins: archive plugins replace their complete package, while source-installed plugins retain their source update behavior",help:{name:"pkg plugin update",summary:"refresh one or all installed plugins",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Plugin name to update. Omit to update all installed plugins."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Narrows resolution."}],output:[{name:"updated",type:"object[]",required:!0,constraint:"One entry per plugin processed: {name, transport?, updated, sha?, version?, docs?, kinds?, pageComponents?, commands?, hooks?, memory?, warnings?, error?}. memory is present for a plugin shipping a memory store and reports the same corpus migration install performs: {docs, migrated, linkedSource?}. Archive plugins report transport=http and replace their complete directory after an authenticated refetch; version is the archive content identifier, docs is the written memory-document count, kinds is the declared kind-registry entry count, and pageComponents is the declared page-component registration count. sha is present for git updates. A bulk update reports and skips a failed archive plugin. commands is present for validated command plugins: {mounts: string[] (accepted command paths), issues: object[]}. hooks is present for plugins declaring hooks: {manifestPath?, executablePath?, declarations: {target, phase, op, description, effects}[], lifecycle?: {event, phase, op, description, effects}[], issues: object[], trust: string}; it is static and never executes hooks. warnings lists advisory PATH requirements that remain absent after update."}],outputKind:"object",effects:["Archive plugins unconditionally re-fetch, validate, and replace their complete package; a named failure exits nonzero and preserves the prior package. Bulk update reports a failed archive plugin and continues. Source-installed plugins retain their source update, version, and last_updated behavior.","Each candidate passes the same pre-activation memory-corpus migration install performs, with the same linked-source rewrite semantics for a symlinked install."]},run:d(async e=>{N();const t=e.name,n=e.scope,i=n===void 0?void 0:ce(n),o=new Map;if(t!==void 0){const s=i===void 0||i==="all"||i==="builtin"?H(t):H(t,i);if(s===null)throw g(`plugin not found: ${t}${i===void 0||i==="all"||i==="builtin"?"":` (scope: ${i})`}`);return{updated:[await Ie(s,o,{strict:!0})]}}const r=le().filter(s=>s.scope!=="builtin"&&(i===void 0||i==="all"||s.scope===i)),a=[];for(const s of r)try{a.push(await Ie(s,o,{strict:!1}))}catch(c){a.push({name:s.name,...s.manifest.transport!==void 0?{transport:s.manifest.transport.kind}:{},updated:!1,error:c instanceof Error?c.message:String(c)})}return{updated:a}},"run")});export{R as assertPluginCandidateValid,Xn as installFromMarketplace,Le as isMarketplaceRelativeSource,Lt as pluginDisable,At as pluginEnable,_t as pluginInstall,Ct as pluginRemove,Ht as pluginUpdate,Mt as revalidateBundlePlugin};
@@ -0,0 +1,13 @@
1
+ import type { ProfileDTO } from '../../api/dto/profiles.js';
2
+ /** Resolve a `--profile` / profile operand against the caller's visible
3
+ * profiles: exact id or name, else the closest name (reported on stderr). */
4
+ export declare function resolveProfileViaDaemon(operand: string): Promise<ProfileDTO>;
5
+ /** A `<profiles count=N>` state element — one `<profile_id> — <name>` line per
6
+ * profile the daemon lists for the caller. */
7
+ export declare function profilesStateBlock(): Promise<string>;
8
+ /** A `<kinds count=N>` state element — one `<kind> — <whenToUse>` line per
9
+ * top-level kind the daemon accepts. Sub-kinds (e.g. `audit/security`) are
10
+ * offered to their own top-level ancestor by default, and this block has no
11
+ * single ancestor to check against, so only a sub-kind available to `*` is
12
+ * listed; a create naming a full sub-kind is valid regardless. */
13
+ export declare function kindsStateBlock(): Promise<string>;
@@ -0,0 +1,4 @@
1
+ var a=Object.defineProperty;var i=(t,n)=>a(t,"name",{value:n,configurable:!0});import{stateBlock as r}from"../../core/help.js";import{matchProfileOperand as f}from"../../core/profiles/manifest.js";import{localClient as m}from"../../api/node-transport.js";import{cliClient as p}from"../api-client.js";const c=i(()=>m({autostart:!1}),"helpClient"),u=i(t=>({profileId:t.id,name:t.name}),"profileKey");async function k(t){return f(await p().listProfiles(),t,u)}i(k,"resolveProfileViaDaemon");async function x(){const t=await c().listProfiles(),n=20,l=t.slice(0,n).map(e=>`${e.id} \u2014 ${e.name}`).join(`
2
+ `),o=t.length>n?`${l}
3
+ \u2026 ${t.length-n} more; use crtr profile list`:l;return r("profiles",{count:t.length},o)}i(x,"profilesStateBlock");async function P(){const{kinds:t}=await c().listKinds(),n=t.filter(({kind:o,available_to:e})=>{const s=o.indexOf("/");return s===-1||(e??[o.slice(0,s)]).includes("*")}),l=n.map(({kind:o,when_to_use:e})=>e?`${o} \u2014 ${e}`:o).join(`
4
+ `);return r("kinds",{count:n.length},l)}i(P,"kindsStateBlock");export{P as kindsStateBlock,x as profilesStateBlock,k as resolveProfileViaDaemon};
@@ -1 +1 @@
1
- var n=Object.defineProperty;var t=(e,r)=>n(e,"name",{value:r,configurable:!0});import{envNodeId as o}from"../../shared/env.js";import{defineLeaf as i}from"../../core/command.js";import{cliClient as a,rethrowAsCliError as d}from"../api-client.js";const u=i({name:"delete",description:"force-delete a profile and its owned runtime state",whenToUse:"a profile is no longer needed and you intend either to remove every node and schedule pinned to it, or to preserve that state while detaching the profile identity",help:{name:"profile delete",summary:"force-delete a profile and its owned state, or detach that state before removing the profile",params:[{kind:"positional",name:"profile",required:!0,constraint:"Exact profile id, or a unique manifest name. Deletion never guesses at a near miss \u2014 unlike every other profile verb, an unrecognized value fails."},{kind:"flag",name:"force",type:"bool",required:!0,constraint:"Required confirmation for this irreversible operation."},{kind:"flag",name:"detach",type:"bool",required:!1,constraint:"Preserve nodes and inbox/review history; clear their profile identity and globalize matching crons before removing the profile."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"The removed profile\u2019s stable id."},{name:"name",type:"string",required:!0,constraint:"The removed profile\u2019s manifest name."},{name:"mode",type:"string",required:!0,constraint:"`deleted` for the destructive cascade; `detached` when --detach preserved nodes and history."},{name:"nodes",type:"number",required:!0,constraint:"Nodes hard-deleted or detached."},{name:"crons",type:"number",required:!0,constraint:"Crons deleted or globalized."},{name:"tickets",type:"number",required:!0,constraint:"Originating inbox ticket directories removed; zero in detach mode."},{name:"reviews",type:"number",required:!0,constraint:"Originating daemon review records removed; zero in detach mode."},{name:"default_pins",type:"number",required:!0,constraint:"Per-directory default profile pins cleared."},{name:"accepted",type:"boolean",required:!1,constraint:"True when the invoking node belongs to the profile and teardown begins after this result settles."},{name:"grace_ms",type:"number",required:!1,constraint:"Acknowledgement grace before an accepted self-deletion begins."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next action."}],outputKind:"object",effects:["Always clears every per-directory default pin for the profile and removes the profile directory last. Blocks before mutation while any matching node owns an open managed worktree.","Without --detach: tears down and hard-deletes every node whose profile_id matches, deletes matching or anchored crons and their in-flight runs, and removes originating inbox tickets plus review records. Cross-profile children are preserved.","With --detach: preserves nodes, conversations, topology, inbox tickets, and reviews; rewrites node profile_id to null, restarts active brokers without the profile, and rewrites matching crons to global scope."]},run:t(async e=>{const r=await a().deleteProfile(e.profile,{force:e.force,detach:e.detach,caller_node_id:o()??null}).catch(d);return{...r,follow_up:r.accepted===!0?"The deletion was accepted; this node will stop after its result settles.":"Run `crtr profile list` to see remaining profiles."}},"run")});export{u as deleteLeaf};
1
+ var n=Object.defineProperty;var t=(e,r)=>n(e,"name",{value:r,configurable:!0});import{envNodeId as o}from"../../shared/env.js";import{defineLeaf as a}from"../../core/command.js";import{cliClient as d,rethrowAsCliError as s}from"../api-client.js";const u=a({name:"delete",description:"force-delete a profile and its owned runtime state",whenToUse:"a profile is no longer needed and you intend either to remove every node and schedule pinned to it, or to preserve that state while detaching the profile identity",help:{name:"profile delete",summary:"force-delete a profile and its owned state, or detach that state before removing the profile",params:[{kind:"positional",name:"profile",required:!0,constraint:"Exact profile id, or a unique manifest name. Deletion never guesses at a near miss \u2014 unlike every other profile verb, an unrecognized value fails."},{kind:"flag",name:"force",type:"bool",required:!0,constraint:"Required confirmation for this irreversible operation."},{kind:"flag",name:"detach",type:"bool",required:!1,constraint:"Preserve nodes and inbox/review history; clear their profile identity and globalize matching crons before removing the profile."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"The removed profile\u2019s stable id."},{name:"name",type:"string",required:!0,constraint:"The removed profile\u2019s manifest name."},{name:"mode",type:"string",required:!0,constraint:"`deleted` for the destructive cascade; `detached` when --detach preserved nodes and history."},{name:"nodes",type:"number",required:!0,constraint:"Nodes hard-deleted or detached."},{name:"crons",type:"number",required:!0,constraint:"Crons deleted or globalized."},{name:"tickets",type:"number",required:!0,constraint:"Originating inbox ticket directories removed; zero in detach mode."},{name:"reviews",type:"number",required:!0,constraint:"Originating daemon review records removed; zero in detach mode."},{name:"default_pins",type:"number",required:!0,constraint:"Per-directory default profile pins cleared."},{name:"accepted",type:"boolean",required:!1,constraint:"True when the invoking node belongs to the profile and teardown begins after this result settles."},{name:"grace_ms",type:"number",required:!1,constraint:"Acknowledgement grace before an accepted self-deletion begins."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next action."}],outputKind:"object",effects:["Always clears every per-directory default pin for the profile and removes the profile directory last. Blocks before mutation while any matching node owns an open managed worktree.","Without --detach: tears down and hard-deletes every node whose profile_id matches, deletes matching or anchored crons and their in-flight runs, and removes originating inbox tickets plus review records. Cross-profile children are preserved.","With --detach: preserves nodes, conversations, topology, inbox tickets, and reviews; rewrites node profile_id to null, restarts active brokers without the profile, and rewrites matching crons to global scope."]},run:t(async e=>{const r=await d().deleteProfile(e.profile,{force:e.force,detach:e.detach,caller_node_id:o()??null}).catch(i=>s(i,"List profiles with `crtr profile list`."));return{...r,follow_up:r.accepted===!0?"The deletion was accepted; this node will stop after its result settles.":"Run `crtr profile list` to see remaining profiles."}},"run")});export{u as deleteLeaf};
@@ -1,2 +1,8 @@
1
1
  import type { BranchDef } from '../../core/command.js';
2
+ /** Strips exactly one trailing line ending (`\r\n` or `\n`) — the one
3
+ * documented byte the piped-value contract trims — and leaves every other
4
+ * byte (leading/trailing spaces, tabs, embedded newlines) untouched. A
5
+ * single-quoted heredoc (`<<'EOF'`) always appends exactly one such
6
+ * terminator; anything beyond that is content the caller wrote on purpose. */
7
+ export declare function stripSingleTrailingLineEnding(raw: string): string;
2
8
  export declare const envBranch: BranchDef;
@@ -1,3 +1,3 @@
1
- var u=Object.defineProperty;var t=(e,n)=>u(e,"name",{value:n,configurable:!0});import{defineLeaf as a,defineBranch as v}from"../../core/command.js";import{InputError as s}from"../../core/io.js";import{resolveProfileOperand as i}from"../../core/profiles/manifest.js";import{validateEnvVarName as p}from"../../core/env-name.js";import{listProfileEnvNames as c,setProfileEnvVar as m,removeProfileEnvVar as f}from"../../core/profiles/env-store.js";function h(e){return e.endsWith(`\r
1
+ var v=Object.defineProperty;var t=(e,n)=>v(e,"name",{value:n,configurable:!0});import{defineLeaf as i,defineBranch as p}from"../../core/command.js";import{InputError as l}from"../../core/io.js";import{validateEnvVarName as c}from"../../core/env-name.js";import{cliClient as a}from"../api-client.js";import{resolveProfileViaDaemon as s}from"./daemon-profiles.js";function m(e){return e.endsWith(`\r
2
2
  `)?e.slice(0,-2):e.endsWith(`
3
- `)?e.slice(0,-1):e}t(h,"stripSingleTrailingLineEnding");function l(e){const n=p(e);if(!n.isValid)throw new s({error:"invalid_name",message:`invalid --name: ${n.errors.join("; ")}`,field:"name",received:e,next:"Use an env-var-shaped name: starts with a letter or underscore, followed by letters, digits, or underscores."})}t(l,"requireValidName");const y=a({name:"set",description:"store one env var for a profile, value piped on stdin",whenToUse:"a profile needs a credential or config value injected directly into every broker launched under it \u2014 e.g. a HTTP-transport plugin\u2019s `auth-env` token. Setting it here crosses the broker spawn boundary with no separate `spawnEnv.allow` entry required; re-running with the same name overwrites the value.",help:{name:"profile env set",summary:"write (or overwrite) one env var in a profile\u2019s 0600 env store",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"name",type:"string",required:!0,constraint:"Env var name. Must start with a letter or underscore, followed by letters, digits, or underscores (e.g. NL_CORE_TOKEN)."},{kind:"stdin",name:"value",required:!0,constraint:"The raw value, piped on stdin \u2014 never as an argv value, to keep it out of shell history. Pipe from a single-quoted heredoc (`<<'EOF'`) or `echo -n \"$VALUE\" |` to preserve exact bytes; trailing newline is trimmed."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"created",type:"boolean",required:!0,constraint:"true when this name was newly added, false when it replaced an existing value."},{name:"follow_up",type:"string",required:!0,constraint:"The effect on already-running nodes."}],outputKind:"object",effects:["Writes {name: value} to the profile\u2019s 0600 env.json, replacing any prior value under the same name.","Every broker launched under this profile from now on injects this value directly into its process env \u2014 independent of the daemon\u2019s ambient env, no `spawnEnv.allow` entry needed. Already-running brokers keep whatever env they launched with; a running node picks up a new/changed value only on its next revive."]},run:t(async e=>{const n=e.name;l(n);const{profileId:r}=i(e.profile),o=h(e.value??"");if(o==="")throw new s({error:"empty_value",message:"env var value is empty",field:"value",next:"Pipe a non-empty value on stdin."});const d=m(r,n,o);return{profile_id:r,created:d,follow_up:"A running node under this profile picks up the change on its next revive."}},"run")}),g=a({name:"list",description:"inventory a profile\u2019s stored env var NAMES \u2014 never values",whenToUse:"you want to know which env vars a profile has set, without exposing any value. Values never leave the 0600 store \u2014 there is no leaf that reads one back.",help:{name:"profile env list",summary:"the sorted list of env var names stored for a profile",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"names",type:"string[]",required:!0,constraint:"Every stored env var name, sorted. Empty when nothing is stored."},{name:"count",type:"int",required:!0,constraint:"names.length."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands."}],outputKind:"object",effects:["None. Read-only \u2014 and value-blind by construction: this leaf never reads the stored values."]},run:t(async e=>{const{profileId:n}=i(e.profile),r=c(n);return{profile_id:n,names:r,count:r.length,follow_up:r.length>0?`Remove one with \`crtr profile env remove ${n} --name <name>\`.`:`Set one with \`crtr profile env set ${n} --name <name>\`.`}},"run")}),w=a({name:"remove",description:"delete one stored env var from a profile",whenToUse:"an env var a profile owns is no longer needed \u2014 remove it so future brokers launched under this profile stop receiving it. No-op-shaped success (`removed: false`) if it was never set.",help:{name:"profile env remove",summary:"delete one env var from a profile\u2019s 0600 env store",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"name",type:"string",required:!0,constraint:"Env var name. Must start with a letter or underscore, followed by letters, digits, or underscores (e.g. NL_CORE_TOKEN)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"removed",type:"boolean",required:!0,constraint:"true when a value existed and was removed; false when nothing was stored under this name."}],outputKind:"object",effects:["Deletes {name} from the profile\u2019s 0600 env.json, if present.","Already-running brokers keep whatever env they launched with; a running node stops receiving this value only on its next revive."]},run:t(async e=>{const{profileId:n}=i(e.profile),r=e.name;l(r);const o=f(n,r);return{profile_id:n,removed:o}},"run")}),T=v({name:"env",description:"manage a profile-scoped store of env vars injected into its brokers",whenToUse:"a profile needs a credential or config value available directly to every broker (and thus every node) launched under it \u2014 e.g. a HTTP-transport plugin\u2019s `auth-env` token \u2014 without exporting it into the daemon\u2019s own ambient shell or granting a `spawnEnv.allow` passthrough.",help:{name:"profile env",summary:"a profile\u2019s own 0600 store of env vars, injected directly into every broker launched under it",model:"Values are write-only from this surface: `set` stores one (value piped on stdin, never argv), `remove` deletes one, `list` reports NAMES only \u2014 no leaf ever reads a value back. `buildBrokerEnv` (`core/runtime/spawn-env.ts`) reads the store straight off disk at every broker launch and injects each value directly into that broker\u2019s process env, independent of the daemon\u2019s own ambient env or any `.envrc`/`.env` a node\u2019s cwd carries. Setting a value here IS the operator\u2019s consent to cross the spawn boundary \u2014 it needs no matching `spawnEnv.allow` entry. A change only reaches an already-running node on its next revive."},children:[y,g,w]});export{T as envBranch};
3
+ `)?e.slice(0,-1):e}t(m,"stripSingleTrailingLineEnding");function d(e){const n=c(e);if(!n.isValid)throw new l({error:"invalid_name",message:`invalid --name: ${n.errors.join("; ")}`,field:"name",received:e,next:"Use an env-var-shaped name: starts with a letter or underscore, followed by letters, digits, or underscores."})}t(d,"requireValidName");const f=i({name:"set",description:"store one env var for a profile, value piped on stdin",whenToUse:"a profile needs a credential or config value injected directly into every broker launched under it \u2014 e.g. a HTTP-transport plugin\u2019s `auth-env` token. Setting it here crosses the broker spawn boundary with no separate `spawnEnv.allow` entry required; re-running with the same name overwrites the value.",help:{name:"profile env set",summary:"write (or overwrite) one env var in a profile\u2019s 0600 env store",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"name",type:"string",required:!0,constraint:"Env var name. Must start with a letter or underscore, followed by letters, digits, or underscores (e.g. NL_CORE_TOKEN)."},{kind:"stdin",name:"value",required:!0,constraint:"The raw value, piped on stdin \u2014 never as an argv value, to keep it out of shell history. Pipe from a single-quoted heredoc (`<<'EOF'`) or `echo -n \"$VALUE\" |` to preserve exact bytes; trailing newline is trimmed."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"created",type:"boolean",required:!0,constraint:"true when this name was newly added, false when it replaced an existing value."},{name:"follow_up",type:"string",required:!0,constraint:"The effect on already-running nodes."}],outputKind:"object",effects:["Writes {name: value} to the profile\u2019s 0600 environment store, replacing any prior value under the same name.","Every broker launched under this profile from now on injects this value directly into its process env \u2014 independent of the daemon\u2019s ambient env, no `spawnEnv.allow` entry needed. Already-running brokers keep whatever env they launched with; a running node picks up a new/changed value only on its next revive."]},run:t(async e=>{const n=e.name;d(n);const{id:r}=await s(e.profile),o=m(e.value??"");if(o==="")throw new l({error:"empty_value",message:"env var value is empty",field:"value",next:"Pipe a non-empty value on stdin."});const{changed:u}=await a().setProfileEnv(r,n,o);return{profile_id:r,created:u,follow_up:"A running node under this profile picks up the change on its next revive."}},"run")}),h=i({name:"list",description:"inventory a profile\u2019s stored env var NAMES \u2014 never values",whenToUse:"you want to know which env vars a profile has set, without exposing any value. Values never leave the 0600 store \u2014 there is no leaf that reads one back.",help:{name:"profile env list",summary:"the sorted list of env var names stored for a profile",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"names",type:"string[]",required:!0,constraint:"Every stored env var name, sorted. Empty when nothing is stored."},{name:"count",type:"int",required:!0,constraint:"names.length."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands."}],outputKind:"object",effects:["None. Read-only \u2014 and value-blind by construction: this leaf never reads the stored values."]},run:t(async e=>{const{id:n}=await s(e.profile),{names:r}=await a().listProfileEnv(n);return{profile_id:n,names:r,count:r.length,follow_up:r.length>0?`Remove one with \`crtr profile env remove ${n} --name <name>\`.`:`Set one with \`crtr profile env set ${n} --name <name>\`.`}},"run")}),w=i({name:"remove",description:"delete one stored env var from a profile",whenToUse:"an env var a profile owns is no longer needed \u2014 remove it so future brokers launched under this profile stop receiving it. No-op-shaped success (`removed: false`) if it was never set.",help:{name:"profile env remove",summary:"delete one env var from a profile\u2019s 0600 env store",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"name",type:"string",required:!0,constraint:"Env var name. Must start with a letter or underscore, followed by letters, digits, or underscores (e.g. NL_CORE_TOKEN)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"removed",type:"boolean",required:!0,constraint:"true when a value existed and was removed; false when nothing was stored under this name."}],outputKind:"object",effects:["Deletes {name} from the profile\u2019s 0600 environment store, if present.","Already-running brokers keep whatever env they launched with; a running node stops receiving this value only on its next revive."]},run:t(async e=>{const n=e.name;d(n);const{id:r}=await s(e.profile),{changed:o}=await a().removeProfileEnv(r,n);return{profile_id:r,removed:o}},"run")}),_=p({name:"env",description:"manage a profile-scoped store of env vars injected into its brokers",whenToUse:"a profile needs a credential or config value available directly to every broker (and thus every node) launched under it \u2014 e.g. a HTTP-transport plugin\u2019s `auth-env` token \u2014 without exporting it into the daemon\u2019s own ambient shell or granting a `spawnEnv.allow` passthrough.",help:{name:"profile env",summary:"a profile\u2019s own 0600 store of env vars, injected directly into every broker launched under it",model:"Values are write-only from this surface: `set` stores one (value piped on stdin, never argv), `remove` deletes one, `list` reports NAMES only \u2014 no leaf ever reads a value back. `buildBrokerEnv` (`core/runtime/spawn-env.ts`) reads the store straight off disk at every broker launch and injects each value directly into that broker\u2019s process env, independent of the daemon\u2019s own ambient env or any `.envrc`/`.env` a node\u2019s cwd carries. Setting a value here IS the operator\u2019s consent to cross the spawn boundary \u2014 it needs no matching `spawnEnv.allow` entry. A change only reaches an already-running node on its next revive."},children:[f,h,w]});export{_ as envBranch,m as stripSingleTrailingLineEnding};
@@ -1,2 +1 @@
1
- var o=Object.defineProperty;var n=(e,t)=>o(e,"name",{value:t,configurable:!0});import{defineLeaf as s}from"../../core/command.js";import{assertInstalledKind as a,readMergedLaunchConfig as r}from"../../core/config.js";import{resolveProfileOperand as d,setProfileDefaultKind as l}from"../../core/profiles/manifest.js";import{stateBlock as f}from"../../core/help.js";function u(){return f("kinds",{count:Object.keys(r().kinds).length},Object.keys(r().kinds).sort().join(`
2
- `))}n(u,"kindsStateBlock");const b=s({name:"kind",description:"set a profile's default node kind",whenToUse:"nodes created under a profile without `--kind` should use a persona other than `general`.",help:{name:"profile kind",summary:"set a profile's manifest `default_kind` for creates that omit --kind",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"positional",name:"kind",required:!0,constraint:"Installed persona kind to use by default. The live <kinds> list below is the accepted value set."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."}],dynamicState:u,outputKind:"object",effects:["Sets the profile manifest's `default_kind`. Future node creates under the profile that omit --kind resolve to it server-side."]},run:n(async e=>{const t=e.kind;a(t);const{profileId:i}=d(e.profile),{manifest:p}=l(i,t);return{profile_id:i}},"run")});export{b as kindLeaf};
1
+ var r=Object.defineProperty;var i=(e,t)=>r(e,"name",{value:t,configurable:!0});import{defineLeaf as o}from"../../core/command.js";import{cliClient as n}from"../api-client.js";import{kindsStateBlock as a,resolveProfileViaDaemon as d}from"./daemon-profiles.js";const u=o({name:"kind",description:"set a profile's default node kind",whenToUse:"nodes created under a profile without `--kind` should use a persona other than `general`.",help:{name:"profile kind",summary:"set a profile's manifest `default_kind` for creates that omit --kind",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"positional",name:"kind",required:!0,constraint:"Installed persona kind to use by default. The live <kinds> list below is the accepted value set."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."}],outputKind:"object",effects:["Sets the profile manifest's `default_kind`. Future node creates under the profile that omit --kind resolve to it server-side."]},helpState:{leaf:a},run:i(async e=>{const{id:t}=await d(e.profile);return await n().updateProfile(t,{default_kind:e.kind}),{profile_id:t}},"run")});export{u as kindLeaf};
@@ -1 +1 @@
1
- var s=Object.defineProperty;var n=(r,t)=>s(r,"name",{value:t,configurable:!0});import{defineLeaf as a}from"../../core/command.js";import{emitLine as i}from"../../core/io.js";import{listProfiles as l}from"../../core/profiles/manifest.js";const c=a({name:"list",description:"inventory every profile and its project relationships",whenToUse:"browse every profile that exists \u2014 one line each with its id, name, explicit project relationships, home directory, paused state, and last-used time. Reach for `profile show` once you have picked one, for its full manifest.",help:{name:"profile list",summary:"every profile as JSONL, one line each, sorted by name then profile_id",output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects_count",type:"int",required:!0,constraint:"Number of `{path, memory}` project relationships on the manifest."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path, memory}` relationships in manifest order. `path` defines profile purview; `memory` caps automatic boot and workspace-open disclosure."},{name:"home",type:"string | null",required:!0,constraint:"Directory the profile\u2019s nodes are pinned to, or null when it owns no projects."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string | null",required:!0,constraint:"Stored default node kind, or null when creates default to general."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."}],outputKind:"jsonl",effects:["None. Read-only."]},run:n(async()=>{const r=l().sort((t,e)=>{const o=t.manifest.name.localeCompare(e.manifest.name);return o!==0?o:t.profileId.localeCompare(e.profileId)});for(const{profileId:t,manifest:e}of r)i({profile_id:t,name:e.name,projects_count:e.projects.length,projects:e.projects,home:e.home,paused_at:e.paused_at,default_kind:e.default_kind??null,last_used_at:e.last_used_at});i({follow_up:"Show one in full with `crtr profile show <profile>`."})},"run")});export{c as listLeaf};
1
+ var a=Object.defineProperty;var n=(t,e)=>a(t,"name",{value:e,configurable:!0});import{defineLeaf as s}from"../../core/command.js";import{emitLine as o}from"../../core/io.js";import{cliClient as p}from"../api-client.js";const m=s({name:"list",description:"inventory every profile visible to you and its project relationships",whenToUse:"browse every profile that exists \u2014 one line each with its id, name, explicit project relationships, owning app, paused state, and last-used time. Reach for `profile show` once you have picked one, for its full manifest.",help:{name:"profile list",summary:"every profile the daemon shows the caller (its own app's, plus any another app shared) as JSONL, sorted by name then profile_id",output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects_count",type:"int",required:!0,constraint:"Number of `{path, memory}` project relationships on the manifest."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path, memory}` relationships in manifest order. `path` defines profile purview; `memory` caps automatic boot and workspace-open disclosure."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string",required:!0,constraint:"Default node kind for creates that omit --kind; `general` when none is stored."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."}],outputKind:"jsonl",effects:["None. Read-only."]},run:n(async()=>{const t=(await p().listProfiles()).sort((e,r)=>{const i=e.name.localeCompare(r.name);return i!==0?i:e.id.localeCompare(r.id)});for(const e of t)o({profile_id:e.id,name:e.name,projects_count:e.projects.length,projects:e.projects,app:e.app,paused_at:e.paused_at,default_kind:e.default_kind,last_used_at:e.last_used_at});o({follow_up:"Show one in full with `crtr profile show <profile>`."})},"run")});export{m as listLeaf};
@@ -1 +1 @@
1
- var p=Object.defineProperty;var o=(e,t)=>p(e,"name",{value:t,configurable:!0});import{defineLeaf as m}from"../../core/command.js";import{InputError as i}from"../../core/io.js";import{resolveProfileOperand as l,updateProfileMetadata as d}from"../../core/profiles/manifest.js";function f(e,t){const a=Array.isArray(e)?e.map(String):typeof e=="string"&&e!==""?[e]:[],n=Object.create(null);for(const r of a){const s=r.indexOf("=");if(s<=0)throw new i({error:"bad_meta",message:`"${r}" is not KEY=VALUE`,field:t,next:`Pass --${t} KEY=VALUE (repeat the flag per entry).`});n[r.slice(0,s)]=r.slice(s+1)}return n}o(f,"resolveMetaPairs");function u(e){return Array.isArray(e)?e.map(String):typeof e=="string"&&e!==""?[e]:[]}o(u,"resolveNames");const E=m({name:"meta",description:"set or remove entries in a profile's metadata map",whenToUse:"a profile should carry (or stop carrying) identity facts \u2014 a display name, role, description \u2014 that every node launched under it reads from its env as `CRTR_PROFILE_META_<KEY>`. For secrets, use `profile env` instead: metadata is readable back from every projection.",help:{name:"profile meta",summary:"merge entries into (or drop entries from) a profile manifest's `metadata` map",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"set",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE to merge over the stored map (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`; an existing key is overwritten."},{kind:"flag",name:"unset",type:"string",required:!1,repeatable:!0,constraint:"KEY to remove (repeat per entry). Removing an absent key is a no-op."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"metadata",type:"object",required:!0,constraint:"The full resulting metadata map."}],outputKind:"object",effects:["Rewrites the profile manifest's `metadata` map (omitted entirely when the result is empty).","Every broker launched under this profile from now on sees each entry as `CRTR_PROFILE_META_<KEY>` (key uppercased, non-alphanumeric runs \u2192 `_`). Already-running nodes pick up changes on their next revive."]},run:o(async e=>{const t=f(e.set,"set"),a=u(e.unset);if(Object.keys(t).length===0&&a.length===0)throw new i({error:"nothing_to_do",message:"pass at least one --set KEY=VALUE or --unset KEY",next:"Repeat --set/--unset per entry."});const{profileId:n}=l(e.profile),{manifest:r}=d(n,t,a);return{profile_id:n,metadata:r.metadata??{}}},"run")});export{E as metaLeaf,f as resolveMetaPairs};
1
+ var p=Object.defineProperty;var o=(e,t)=>p(e,"name",{value:t,configurable:!0});import{defineLeaf as m}from"../../core/command.js";import{InputError as s}from"../../core/io.js";import{cliClient as d}from"../api-client.js";import{resolveProfileViaDaemon as l}from"./daemon-profiles.js";function f(e,t){const a=Array.isArray(e)?e.map(String):typeof e=="string"&&e!==""?[e]:[],n=Object.create(null);for(const r of a){const i=r.indexOf("=");if(i<=0)throw new s({error:"bad_meta",message:`"${r}" is not KEY=VALUE`,field:t,next:`Pass --${t} KEY=VALUE (repeat the flag per entry).`});n[r.slice(0,i)]=r.slice(i+1)}return n}o(f,"resolveMetaPairs");function u(e){return Array.isArray(e)?e.map(String):typeof e=="string"&&e!==""?[e]:[]}o(u,"resolveNames");const v=m({name:"meta",description:"set or remove entries in a profile's metadata map",whenToUse:"a profile should carry (or stop carrying) identity facts \u2014 a display name, role, description \u2014 that every node launched under it reads from its env as `CRTR_PROFILE_META_<KEY>`. For secrets, use `profile env` instead: metadata is readable back from every projection.",help:{name:"profile meta",summary:"merge entries into (or drop entries from) a profile manifest's `metadata` map",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"set",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE to merge over the stored map (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`; an existing key is overwritten."},{kind:"flag",name:"unset",type:"string",required:!1,repeatable:!0,constraint:"KEY to remove (repeat per entry). Removing an absent key is a no-op."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"metadata",type:"object",required:!0,constraint:"The full resulting metadata map."}],outputKind:"object",effects:["Rewrites the profile manifest's `metadata` map (omitted entirely when the result is empty).","Every broker launched under this profile from now on sees each entry as `CRTR_PROFILE_META_<KEY>` (key uppercased, non-alphanumeric runs \u2192 `_`). Already-running nodes pick up changes on their next revive."]},run:o(async e=>{const t=f(e.set,"set"),a=u(e.unset);if(Object.keys(t).length===0&&a.length===0)throw new s({error:"nothing_to_do",message:"pass at least one --set KEY=VALUE or --unset KEY",next:"Repeat --set/--unset per entry."});const{id:n}=await l(e.profile),r=await d().updateProfileMetadata(n,{set:t,unset:a});return{profile_id:r.id,metadata:r.metadata}},"run")});export{v as metaLeaf,f as resolveMetaPairs};
@@ -1 +1 @@
1
- var c=Object.defineProperty;var m=(e,t)=>c(e,"name",{value:t,configurable:!0});import{defineLeaf as u}from"../../core/command.js";import{usage as d}from"../../core/errors.js";import{assertInstalledKind as h}from"../../core/config.js";import{createProfile as y,ensureRootProfile as w,profileRoot as f}from"../../core/profiles/manifest.js";import{PROFILE_PROJECT_MEMORY_VALUES as g}from"../../api/dto/profiles.js";import{resolveMetaPairs as b}from"./meta.js";const x=u({name:"new",description:"create a new profile",whenToUse:"you are establishing a new agent identity \u2014 a stable id, a display name, and its own memory store. Pass at most one initial project directory here (the parser has no repeatable-flag support); use `profile project add` afterward for every additional one. Use `--root` (no name) to provision the canonical stable root profile \u2014 the default identity a home falls back to \u2014 idempotently, without spawning a node.",help:{name:"profile new",summary:"create a profile: `<profiles-root>/<slug>-<id>/` with a manifest + its own `memory/` store",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Display name for the profile. Also slugified into the stable profile id \u2014 the id never changes on later rename. Required unless `--root` is given; mutually exclusive with `--root`."},{kind:"flag",name:"root",type:"bool",required:!1,constraint:"Provision the canonical stable root profile (fixed id `root-00000000`, name `root`) \u2014 the fallback default identity for a home \u2014 instead of a fresh named one. Idempotent: re-running returns the existing root. Node-free (no `node new --root` needed). Mutually exclusive with `--name`/`--project`/`--memory`/`--default-kind`/`--meta`."},{kind:"flag",name:"project",type:"path",required:!1,constraint:"One initial project directory. Must already exist and be a directory; resolved to its absolute real path before storing. Creates a purview relationship and becomes the profile's home \u2014 where its nodes are pinned. Requires paired `--memory`; singular \u2014 add more with `crtr profile project add` after creation."},{kind:"flag",name:"memory",type:"enum",choices:[...g],required:!1,constraint:"Required with `--project`; invalid without it. Maximum automatic memory disclosure from this project at boot and workspace-open: `none`, `name`, `preview`, or `content`. Does not change purview or explicit `crtr memory read` access."},{kind:"flag",name:"default-kind",type:"string",required:!1,constraint:"Installed persona kind for node creates under this profile that omit --kind. Defaults to general when omitted; validated against the installed kind registry."},{kind:"flag",name:"meta",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE metadata entry (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`. Each entry reaches every broker launched under the profile as `CRTR_PROFILE_META_<KEY>` env; readable back via `profile show` \u2014 not for secrets (those go to `profile env`)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id (`<slug>-<shortid>`). Pass this, or the name, to every other `profile` verb and to `--profile` elsewhere."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the profile directory."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path, memory}` project relationships in manifest order. `path` defines purview; `memory` caps automatic boot and workspace-open disclosure. Empty when --project was omitted."},{name:"home",type:"string | null",required:!0,constraint:"Directory the profile\u2019s nodes are pinned to \u2014 the initial project, or null when none was given."},{name:"default_kind",type:"string | null",required:!0,constraint:"Stored default persona kind, or null when node creates default to general."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map; empty when --meta was omitted."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."}],outputKind:"object",effects:["Creates `<profile-dir>/profile.json` and `<profile-dir>/memory/` (the fixed root dir when `--root`)."]},run:m(async e=>{const t=e.name,a=e.project,i=e.memory,n=e.defaultKind,s=b(e.meta,"meta");if(e.root===!0){if(t!==void 0||a!==void 0||i!==void 0||n!==void 0||Object.keys(s).length>0)throw d("`--root` provisions the canonical stable root profile and takes no `--name`/`--project`/`--memory`/`--default-kind`/`--meta`.");const{profileId:p,manifest:o}=w();return{profile_id:p,path:f(p),projects:o.projects,home:o.home,default_kind:o.default_kind??null,metadata:o.metadata??{},created_at:o.created_at}}if(t===void 0)throw d("provide `--name <name>` to create a profile, or `--root` to provision the stable root profile.");if(a===void 0!=(i===void 0))throw d("`--project` and `--memory` must be supplied together: `--project` establishes purview and `--memory` sets its automatic boot and workspace-open disclosure cap.");n!==void 0&&h(n);const{profileId:l,manifest:r}=y(t,a!==void 0&&i!==void 0?[{path:a,memory:i}]:[],{defaultKind:n,...Object.keys(s).length>0?{metadata:s}:{}});return{profile_id:l,path:f(l),projects:r.projects,home:r.home,default_kind:r.default_kind??null,metadata:r.metadata??{},created_at:r.created_at}},"run")});export{x as newLeaf};
1
+ var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,configurable:!0});import{defineLeaf as m}from"../../core/command.js";import{usage as s}from"../../core/errors.js";import{resolve as c}from"node:path";import{cliClient as d}from"../api-client.js";import{PROFILE_PROJECT_MEMORY_VALUES as f}from"../../api/dto/profiles.js";import{resolveMetaPairs as u}from"./meta.js";const _=m({name:"new",description:"create a new profile",whenToUse:"you are establishing a new agent identity \u2014 a stable id, a display name, and its own memory store. Pass at most one initial project directory here (the parser has no repeatable-flag support); use `profile project add` afterward for every additional one. Use `--root` (no name) to provision the canonical stable root profile \u2014 the default identity a home falls back to \u2014 idempotently, without spawning a node.",help:{name:"profile new",summary:"create a profile of the caller's app in the scoped store and its app memory folder",params:[{kind:"flag",name:"name",type:"string",required:!1,constraint:"Display name for the profile. Also slugified into the stable profile id \u2014 the id never changes on later rename. Required unless `--root` is given; mutually exclusive with `--root`."},{kind:"flag",name:"root",type:"bool",required:!1,constraint:"Provision the canonical stable root profile (fixed id `root-00000000`, name `root`) \u2014 the fallback default identity for a home \u2014 instead of a fresh named one. Idempotent: re-running returns the existing root. Node-free (no `node new --root` needed). Mutually exclusive with `--name`/`--project`/`--memory`/`--default-kind`/`--meta`."},{kind:"flag",name:"project",type:"path",required:!1,constraint:"One initial project directory. Must already exist and be a directory; resolved to its absolute real path before storing. Creates a purview relationship. Requires paired `--memory`; singular \u2014 add more with `crtr profile project add` after creation."},{kind:"flag",name:"memory",type:"enum",choices:[...f],required:!1,constraint:"Required with `--project`; invalid without it. Maximum automatic memory disclosure from this project at boot and workspace-open: `none`, `name`, `preview`, or `content`. Does not change purview or explicit `crtr memory read` access."},{kind:"flag",name:"default-kind",type:"string",required:!1,constraint:"Installed persona kind for node creates under this profile that omit --kind. Defaults to general when omitted; the daemon validates it against its installed kind registry."},{kind:"flag",name:"meta",type:"string",required:!1,repeatable:!0,constraint:"KEY=VALUE metadata entry (repeat per entry). KEY starts with a letter or digit, followed by letters, digits, `_`, or `-`. Each entry reaches every broker launched under the profile as `CRTR_PROFILE_META_<KEY>` env; readable back via `profile show` \u2014 not for secrets (those go to `profile env`)."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id (`<slug>-<shortid>`). Pass this, or the name, to every other `profile` verb and to `--profile` elsewhere."},{name:"memory_path",type:"string",required:!0,constraint:"Absolute path to the profile memory directory."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path, memory}` project relationships in manifest order. `path` defines purview; `memory` caps automatic boot and workspace-open disclosure. Empty when --project was omitted."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"default_kind",type:"string",required:!0,constraint:"Default persona kind for node creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map; empty when --meta was omitted."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."}],outputKind:"object",effects:["Creates a profile row owned by the caller's app (the terminal app for a person) and its memory directory under that app's space. A name the caller's app already holds is refused."]},run:n(async e=>{const t=e.name,r=e.project,o=e.memory,a=e.defaultKind,i=u(e.meta,"meta");if(e.root===!0){if(t!==void 0||r!==void 0||o!==void 0||a!==void 0||Object.keys(i).length>0)throw s("`--root` provisions the canonical stable root profile and takes no `--name`/`--project`/`--memory`/`--default-kind`/`--meta`.");return l(await d().ensureProfile("root"))}if(t===void 0)throw s("provide `--name <name>` to create a profile, or `--root` to provision the stable root profile.");if(r===void 0!=(o===void 0))throw s("`--project` and `--memory` must be supplied together: `--project` establishes purview and `--memory` sets its automatic boot and workspace-open disclosure cap.");return l(await d().createProfile({name:t,...r!==void 0&&o!==void 0?{projects:[{path:c(r),memory:o}]}:{},...a!==void 0?{default_kind:a}:{},...Object.keys(i).length>0?{metadata:i}:{}}))},"run")});function l(e){return{profile_id:e.id,memory_path:e.memory_path,projects:e.projects,app:e.app,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at}}n(l,"newProfileOutput");export{_ as newLeaf};
@@ -1 +1 @@
1
- var u=Object.defineProperty;var a=(e,r)=>u(e,"name",{value:r,configurable:!0});import{defineLeaf as i}from"../../core/command.js";import{resolveProfileOperand as n}from"../../core/profiles/manifest.js";import{cliClient as o,rethrowAsCliError as s}from"../api-client.js";const d={kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},f=i({name:"pause",description:"make a profile inert",whenToUse:"all work under a profile must stop now while in-flight bash commands continue under their detached supervisors.",help:{name:"profile pause",summary:"pause a profile so it creates and revives no nodes",params:[d],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"paused_at",type:"string",required:!0,constraint:"ISO 8601 timestamp when the profile became inert."}],outputKind:"object",effects:["Writes `paused_at`, SIGTERMs every live broker under the profile so its foreground bash hands off to its detached supervisor, and holds cron, deadline, revive, and inbox delivery until resume."]},run:a(async e=>{const{profileId:r}=n(e.profile);try{return{...await o().pauseProfile(r)}}catch(t){s(t)}},"run")}),h=i({name:"resume",description:"make a paused profile active",whenToUse:"nodes under a paused profile may create and revive again, including queued inbox delivery.",help:{name:"profile resume",summary:"resume a profile so it may create and revive nodes again",params:[d],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"paused_at",type:"null",required:!0,constraint:"Always null after resume; null means active."}],outputKind:"object",effects:["Clears `paused_at`, credits active node deadlines for the paused interval, and lets retained inbox mail, due crons, and interrupted turns resume."]},run:a(async e=>{const{profileId:r}=n(e.profile);try{return{...await o().resumeProfile(r)}}catch(t){s(t)}},"run")});export{f as pauseLeaf,h as resumeLeaf};
1
+ var u=Object.defineProperty;var t=(e,r)=>u(e,"name",{value:r,configurable:!0});import{defineLeaf as i}from"../../core/command.js";import{cliClient as n,rethrowAsCliError as o}from"../api-client.js";import{resolveProfileViaDaemon as s}from"./daemon-profiles.js";const d={kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},f=i({name:"pause",description:"make a profile inert",whenToUse:"all work under a profile must stop now while in-flight bash commands continue under their detached supervisors.",help:{name:"profile pause",summary:"pause a profile so it creates and revives no nodes",params:[d],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"paused_at",type:"string",required:!0,constraint:"ISO 8601 timestamp when the profile became inert."}],outputKind:"object",effects:["Writes `paused_at`, SIGTERMs every live broker under the profile so its foreground bash hands off to its detached supervisor, and holds cron, deadline, revive, and inbox delivery until resume."]},run:t(async e=>{const{id:r}=await s(e.profile);try{return{...await n().pauseProfile(r)}}catch(a){o(a)}},"run")}),h=i({name:"resume",description:"make a paused profile active",whenToUse:"nodes under a paused profile may create and revive again, including queued inbox delivery.",help:{name:"profile resume",summary:"resume a profile so it may create and revive nodes again",params:[d],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"paused_at",type:"null",required:!0,constraint:"Always null after resume; null means active."}],outputKind:"object",effects:["Clears `paused_at`, credits active node deadlines for the paused interval, and lets retained inbox mail, due crons, and interrupted turns resume."]},run:t(async e=>{const{id:r}=await s(e.profile);try{return{...await n().resumeProfile(r)}}catch(a){o(a)}},"run")});export{f as pauseLeaf,h as resumeLeaf};
@@ -1 +1 @@
1
- var n=Object.defineProperty;var t=(e,r)=>n(e,"name",{value:r,configurable:!0});import{defineLeaf as i,defineBranch as s}from"../../core/command.js";import{addProfileProject as p,removeProfileProject as d,resolveProfileOperand as a}from"../../core/profiles/manifest.js";import{PROFILE_PROJECT_MEMORY_VALUES as m}from"../../api/dto/profiles.js";const c=i({name:"add",description:"add or update a project's purview relationship",whenToUse:"a profile needs purview over another project directory, or its automatic memory disclosure cap needs changing \u2014 extend or update the relationship after creation. Also the way to re-point the profile's home, with --home.",help:{name:"profile project add",summary:"add or update a project relationship in a profile's manifest, deduped by real path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"dir",type:"path",required:!0,constraint:"Directory to add. Must exist and be a directory; resolved to its absolute real path before storing. A path already on the manifest keeps its position and updates its `memory` value."},{kind:"flag",name:"memory",type:"enum",choices:[...m],required:!0,constraint:"Maximum automatic memory disclosure from this project at boot and workspace-open: `none`, `name`, `preview`, or `content`. Does not change the profile\u2019s purview or explicit `crtr memory read` access."},{kind:"flag",name:"home",type:"bool",required:!1,constraint:"Also make this directory the profile's home \u2014 where a node under it runs when its create names no directory. Defaults to the first project dir; pass this on an already-listed dir to re-point it."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"The updated `{path, memory}` relationships in manifest order. `path` defines purview; `memory` caps automatic boot and workspace-open disclosure."},{name:"home",type:"string | null",required:!0,constraint:"The profile's home directory after the change."}],outputKind:"object",effects:["Appends a new project relationship or updates an existing relationship\u2019s `memory` in the profile manifest, and rewrites `home` when --home is given. Purview follows `path`; `memory` caps automatic boot and workspace-open disclosure. Invalidates the process scope cache."]},run:t(async e=>{const{profileId:r}=a(e.profile),{manifest:o}=p(r,e.dir,{memory:e.memory,home:e.home===!0});return{profile_id:r,projects:o.projects,home:o.home}},"run")}),l=i({name:"remove",description:"remove a project relationship from a profile's purview",whenToUse:"a profile no longer needs purview over one of its listed project directories \u2014 narrow it back. Works even if the directory itself was since deleted.",help:{name:"profile project remove",summary:"remove a project directory from a profile's manifest",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"dir",type:"path",required:!0,constraint:"Directory to remove, matched against the stored project `path`. Does not require the directory to still exist on disk. Removing the home dir re-points the home at the first remaining project."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"The updated `{path, memory}` relationships in manifest order."},{name:"home",type:"string | null",required:!0,constraint:"The profile's home directory after the change."}],outputKind:"object",effects:["Removes a project relationship from the profile manifest, re-pointing `home` when that entry was it. This narrows purview and removes its automatic memory disclosure cap. Invalidates the process scope cache."]},run:t(async e=>{const{profileId:r}=a(e.profile),{manifest:o}=d(r,e.dir);return{profile_id:r,projects:o.projects,home:o.home}},"run")}),v=s({name:"project",description:"manage a profile's project purview and automatic memory disclosure",whenToUse:"changing a profile\u2019s project purview or one relationship\u2019s automatic memory disclosure cap after creation \u2014 add, update, or remove one.",help:{name:"profile project",summary:"manage project purview and automatic memory disclosure caps",model:"Each `{path, memory}` relationship widens purview: the profile resolves memory and config from `path`. Its `memory` value separately caps only automatic boot and workspace-open delivery; explicit reads remain available through purview. `add` appends a new real path or updates an existing relationship\u2019s cap without moving it, and can re-point `home`; `remove` narrows purview and re-points `home` when needed. Purview and automatic disclosure are both independent of a per-cwd default pin (`crtr profile default`)."},children:[c,l]});export{v as projectBranch};
1
+ var p=Object.defineProperty;var t=(e,r)=>p(e,"name",{value:r,configurable:!0});import{defineLeaf as i,defineBranch as d}from"../../core/command.js";import{resolve as a}from"node:path";import{cliClient as n}from"../api-client.js";import{resolveProfileViaDaemon as s}from"./daemon-profiles.js";import{PROFILE_PROJECT_MEMORY_VALUES as c}from"../../api/dto/profiles.js";const m=i({name:"add",description:"add or update a project's purview relationship",whenToUse:"a profile needs purview over another project directory, or its automatic memory disclosure cap needs changing \u2014 extend or update the relationship after creation.",help:{name:"profile project add",summary:"add or update a project relationship in a profile's manifest, deduped by real path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"dir",type:"path",required:!0,constraint:"Directory to add. Must exist and be a directory; resolved to its absolute real path before storing. A path already on the manifest keeps its position and updates its `memory` value."},{kind:"flag",name:"memory",type:"enum",choices:[...c],required:!0,constraint:"Maximum automatic memory disclosure from this project at boot and workspace-open: `none`, `name`, `preview`, or `content`. Does not change the profile\u2019s purview or explicit `crtr memory read` access."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"The updated `{path, memory}` relationships in profile order. `path` defines purview; `memory` caps automatic boot and workspace-open disclosure."}],outputKind:"object",effects:["Appends a new project relationship or updates an existing relationship\u2019s `memory` in the profile row. Purview follows `path`; `memory` caps automatic boot and workspace-open disclosure. Running brokers discover the updated projects on their next scope read."]},run:t(async e=>{const{id:r}=await s(e.profile),o=await n().updateProfile(r,{add_project:{path:a(e.dir),memory:e.memory}});return{profile_id:o.id,projects:o.projects}},"run")}),l=i({name:"remove",description:"remove a project relationship from a profile's purview",whenToUse:"a profile no longer needs purview over one of its listed project directories \u2014 narrow it back. Works even if the directory itself was since deleted.",help:{name:"profile project remove",summary:"remove a project directory from a profile's manifest",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"dir",type:"path",required:!0,constraint:"Directory to remove, matched against the stored project `path`. Does not require the directory to still exist on disk. The profile's app home does not change."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"The updated `{path, memory}` relationships in profile order."}],outputKind:"object",effects:["Removes a project relationship from the profile row. This narrows purview and removes its automatic memory disclosure cap. Running brokers discover the updated projects on their next scope read."]},run:t(async e=>{const{id:r}=await s(e.profile),o=await n().updateProfile(r,{remove_project:a(e.dir)});return{profile_id:o.id,projects:o.projects}},"run")}),j=d({name:"project",description:"manage a profile's project purview and automatic memory disclosure",whenToUse:"changing a profile\u2019s project purview or one relationship\u2019s automatic memory disclosure cap after creation \u2014 add, update, or remove one.",help:{name:"profile project",summary:"manage project purview and automatic memory disclosure caps",model:"Each `{path, memory}` relationship widens purview: the profile resolves memory and config from `path`. Its `memory` value separately caps only automatic boot and workspace-open delivery; explicit reads remain available through purview. `add` appends a new real path or updates an existing relationship\u2019s cap without moving it; `remove` narrows purview. Purview and automatic disclosure are both independent of a per-cwd default pin (`crtr profile default`)."},children:[m,l]});export{j as projectBranch};
@@ -1 +1 @@
1
- var a=Object.defineProperty;var r=(e,n)=>a(e,"name",{value:n,configurable:!0});import{defineLeaf as i}from"../../core/command.js";import{resolveProfileOperand as t,renameProfile as o}from"../../core/profiles/manifest.js";const m=i({name:"rename",description:"change a profile's display name",whenToUse:"you want the profile to appear under a new name in bearings, listings, and `profile` subject gates. The profile id (its directory) never changes.",help:{name:"profile rename",summary:"change a profile's manifest `name` only \u2014 the profile_id is stable and never changes",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name (the CURRENT name, before this rename); a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"name",type:"string",required:!0,constraint:"New display name."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id \u2014 unchanged by this leaf."}],outputKind:"object",effects:["Changes the profile manifest's `name` field. Invalidates the process scope cache."]},run:r(async e=>{const{profileId:n}=t(e.profile),{manifest:s}=o(n,e.name);return{profile_id:n}},"run")});export{m as renameLeaf};
1
+ var a=Object.defineProperty;var r=(e,n)=>a(e,"name",{value:n,configurable:!0});import{defineLeaf as i}from"../../core/command.js";import{cliClient as t}from"../api-client.js";import{resolveProfileViaDaemon as o}from"./daemon-profiles.js";const p=i({name:"rename",description:"change a profile's display name",whenToUse:"you want the profile to appear under a new name in bearings, listings, and `profile` subject gates. The profile id (its directory) never changes.",help:{name:"profile rename",summary:"change a profile's manifest `name` only \u2014 the profile_id is stable and never changes",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name (the CURRENT name, before this rename); a close-enough name resolves to the nearest profile, reported on stderr."},{kind:"flag",name:"name",type:"string",required:!0,constraint:"New display name."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id \u2014 unchanged by this leaf."}],outputKind:"object",effects:["Changes the profile manifest's `name` field."]},run:r(async e=>{const{id:n}=await o(e.profile);return await t().updateProfile(n,{name:e.name}),{profile_id:n}},"run")});export{p as renameLeaf};
@@ -1 +1 @@
1
- var n=Object.defineProperty;var i=(r,e)=>n(r,"name",{value:e,configurable:!0});import{defineLeaf as a}from"../../core/command.js";import{resolveProfileOperand as o,profileRoot as s,sanitizeProfileMetadata as p}from"../../core/profiles/manifest.js";const u=a({name:"show",description:"one profile's manifest in full",whenToUse:"you need a profile's full project list, home directory, id, and timestamps \u2014 after `profile list` narrows to a name, to find where its nodes will run, or to inspect what a node's bearings named as its profile.",help:{name:"profile show",summary:"print one profile's manifest and on-disk path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path, memory}` relationships in manifest order. `path` defines profile purview; `memory` caps automatic boot and workspace-open disclosure without limiting explicit reads."},{name:"home",type:"string | null",required:!0,constraint:"Where a node under this profile runs when its create names no directory at all \u2014 an explicit --cwd and the directory a root is launched from both win over it. Defaults to the first project; re-point it with `profile project add --home`. Null when the profile owns no projects (the root profile)."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string | null",required:!0,constraint:"Stored default node kind, or null when creates default to general."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map \u2014 each entry reaches brokers launched under the profile as `CRTR_PROFILE_META_<KEY>` env. Empty when none."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."},{name:"path",type:"string",required:!0,constraint:"Absolute path to the profile directory."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands, including the SQL-backed raw settings surface."}],outputKind:"object",effects:["None. Read-only."]},run:i(async r=>{const{profileId:e,manifest:t}=o(r.profile);return{profile_id:e,name:t.name,projects:t.projects,home:t.home,paused_at:t.paused_at,default_kind:t.default_kind??null,metadata:p(t.metadata),created_at:t.created_at,last_used_at:t.last_used_at,path:s(e),follow_up:t.paused_at===null?`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${e}\`; manage its purview with \`crtr profile project add ${e} --dir <path> --memory <none|name|preview|content>\`, pause it with \`crtr profile pause ${e}\`, or set its default kind with \`crtr profile kind ${e} <kind>\`.`:`Inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${e}\`; manage its purview with \`crtr profile project add ${e} --dir <path> --memory <none|name|preview|content>\`, or resume it with \`crtr profile resume ${e}\`.`}},"run")});export{u as showLeaf};
1
+ var a=Object.defineProperty;var i=(r,e)=>a(r,"name",{value:e,configurable:!0});import{defineLeaf as n}from"../../core/command.js";import{resolveProfileViaDaemon as o}from"./daemon-profiles.js";const l=n({name:"show",description:"one profile's manifest in full",whenToUse:"you need a profile's full project list, owning app, id, and timestamps \u2014 after `profile list` narrows to a name, to find where its nodes will run, or to inspect what a node's bearings named as its profile.",help:{name:"profile show",summary:"print one profile's settings and memory path",params:[{kind:"positional",name:"profile",required:!0,constraint:"Profile id or manifest name; a close-enough name resolves to the nearest profile, reported on stderr. A name shared by several profiles fails listing every matching id."}],output:[{name:"profile_id",type:"string",required:!0,constraint:"Stable directory id."},{name:"name",type:"string",required:!0,constraint:"Manifest name."},{name:"projects",type:"ProfileProject[]",required:!0,constraint:"Explicit `{path, memory}` relationships in manifest order. `path` defines profile purview; `memory` caps automatic boot and workspace-open disclosure without limiting explicit reads."},{name:"app",type:"string",required:!0,constraint:"The app that owns this profile."},{name:"paused_at",type:"string | null",required:!0,constraint:"ISO 8601 pause timestamp, or null when the profile is active."},{name:"default_kind",type:"string",required:!0,constraint:"Default node kind for creates that omit --kind; `general` when none is stored."},{name:"metadata",type:"object",required:!0,constraint:"Stored metadata map \u2014 each entry reaches brokers launched under the profile as `CRTR_PROFILE_META_<KEY>` env. Empty when none."},{name:"created_at",type:"string",required:!0,constraint:"ISO 8601 creation timestamp."},{name:"last_used_at",type:"string | null",required:!0,constraint:"ISO 8601 timestamp of the most recent selection, or null if never selected."},{name:"memory_path",type:"string",required:!0,constraint:"Absolute path to the profile memory directory."},{name:"follow_up",type:"string",required:!0,constraint:"Concrete next commands, including the SQL-backed raw settings surface."}],outputKind:"object",effects:["None. Read-only."]},run:i(async r=>{const e=await o(r.profile),t=e.id;return{profile_id:t,name:e.name,projects:e.projects,app:e.app,paused_at:e.paused_at,default_kind:e.default_kind,metadata:e.metadata,created_at:e.created_at,last_used_at:e.last_used_at,memory_path:e.memory_path,follow_up:e.paused_at===null?`From the person's terminal, inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path> --memory <none|name|preview|content>\`, pause it with \`crtr profile pause ${t}\`, or set its default kind with \`crtr profile kind ${t} <kind>\`.`:`From the person's terminal, inspect its SQL-backed settings with \`crtr sys config get-raw --scope profile --profile ${t}\`; manage its purview with \`crtr profile project add ${t} --dir <path> --memory <none|name|preview|content>\`, or resume it with \`crtr profile resume ${t}\`.`}},"run")});export{l as showLeaf};
@@ -1 +1 @@
1
- var n=Object.defineProperty;var e=(r,t)=>n(r,"name",{value:t,configurable:!0});import{defineBranch as o}from"../core/command.js";import{newLeaf as i}from"./profile/new.js";import{listLeaf as a}from"./profile/list.js";import{showLeaf as s}from"./profile/show.js";import{renameLeaf as d}from"./profile/rename.js";import{deleteLeaf as l}from"./profile/delete.js";import{pauseLeaf as c,resumeLeaf as m}from"./profile/pause.js";import{kindLeaf as p}from"./profile/kind.js";import{metaLeaf as f}from"./profile/meta.js";import{projectBranch as h}from"./profile/project.js";import{defaultBranch as u}from"./profile/default.js";import{envBranch as w}from"./profile/env.js";function S(){return o({name:"profile",rootEntry:{concept:"an agent identity defined at the user root \u2014 a manifest naming project directories and the home its nodes run in, plus its own memory store",desc:"create, inspect, and manage profiles",useWhen:"creating a new agent identity, inspecting or listing existing ones, changing a profile\u2019s project purview, pinning which profile a directory defaults to at startup, or managing a profile\u2019s stored env vars. Selecting a profile for a one-off run (`--profile`) lives elsewhere."},help:{name:"profile",summary:"create, inspect, and manage profiles \u2014 agent identities with their own project purview and memory store",model:"A profile owns a `home` \u2014 the first of its project dirs unless `project add --home` re-points it \u2014 which is where a node under the profile runs when its create names no directory at all. A node lands in the directory it was launched from when there is one: `node new --cwd`, an inherited spawner directory (notably inside a managed worktree), or the directory a root was started in. So one profile can cover many working directories \u2014 cwd selects the identity, and the launch decides where the work happens. `new` creates one from a name (+ at most one initial `--project`, which becomes its home). `list` inventories every profile as JSONL. `show` prints one manifest in full. `rename` changes only the manifest name \u2014 the profile_id is stable across a rename. `delete --force` removes the profile after cascading through its nodes, matching schedules, originating inbox/review state, and default pins; `--detach --force` instead preserves nodes and human history while clearing the profile identity and globalizing its schedules. Both modes block while a matching node owns an open managed worktree and never touch the project directories the profile pointed at. `project` widens/narrows a profile\u2019s project purview (the dirs it resolves memory + config from). `default` pins which profile a directory defaults to at startup so the chooser stops asking \u2014 directory-scoped, independent of purview. `env` manages a profile-scoped 0600 store of env vars injected directly into every broker launched under that profile \u2014 set on stdin, list names only (never values), or remove one; no `spawnEnv.allow` entry needed. `meta` edits the manifest\u2019s readable metadata map \u2014 identity facts each broker under the profile sees as `CRTR_PROFILE_META_<KEY>` env (secrets stay in `env`). Every manifest verb but `new`/`list` takes <profile> as an exact id, a manifest name, or a close-enough name that resolves to the nearest profile (reported on stderr); a name shared by several profiles, or one equally close to several, fails listing every matching id. `delete` alone never guesses \u2014 an irreversible verb requires an exact id or name."},children:[i,a,s,d,c,m,p,f,l,h,u,w]})}e(S,"registerProfile");export{S as registerProfile};
1
+ var t=Object.defineProperty;var e=(r,o)=>t(r,"name",{value:o,configurable:!0});import{defineBranch as n}from"../core/command.js";import{newLeaf as i}from"./profile/new.js";import{listLeaf as a}from"./profile/list.js";import{showLeaf as s}from"./profile/show.js";import{renameLeaf as d}from"./profile/rename.js";import{deleteLeaf as l}from"./profile/delete.js";import{pauseLeaf as p,resumeLeaf as c}from"./profile/pause.js";import{kindLeaf as f}from"./profile/kind.js";import{metaLeaf as m}from"./profile/meta.js";import{projectBranch as h}from"./profile/project.js";import{defaultBranch as u}from"./profile/default.js";import{envBranch as w}from"./profile/env.js";function S(){return n({name:"profile",rootEntry:{concept:"an agent identity defined at the user root \u2014 a scoped-state row naming project directories, plus its own memory store",desc:"create, inspect, and manage profiles",useWhen:"creating a new agent identity, inspecting or listing existing ones, changing a profile\u2019s project purview, pinning which profile a directory defaults to at startup, or managing a profile\u2019s stored env vars. Selecting a profile for a one-off run (`--profile`) lives elsewhere."},help:{name:"profile",summary:"create, inspect, and manage profiles \u2014 agent identities with their own project purview and memory store",model:"A node\u2019s app owns its home; the profile does not select it. A node lands in the directory it was launched from when there is one: `node new --cwd`, an inherited spawner directory (notably inside a managed worktree), or the directory a root was started in. So one profile can cover many working directories \u2014 cwd selects the identity, and the launch decides where the work happens. `new` creates one from a name (+ at most one initial `--project`). `list` inventories every profile as JSONL. `show` prints one profile definition in full. `rename` changes only the profile name \u2014 the profile_id is stable across a rename. `delete --force` removes the profile after cascading through its nodes, matching schedules, originating inbox/review state, and default pins; `--detach --force` instead preserves nodes and human history while clearing the profile identity and globalizing its schedules. Both modes block while a matching node owns an open managed worktree and never touch the project directories the profile pointed at. `project` widens/narrows a profile\u2019s project purview (the dirs it resolves memory + config from). `default` pins which profile a directory defaults to at startup so the chooser stops asking \u2014 directory-scoped, independent of purview. `env` manages a profile-scoped 0600 store of env vars injected directly into every broker launched under that profile \u2014 set on stdin, list names only (never values), or remove one; no `spawnEnv.allow` entry needed. `meta` edits the profile\u2019s readable metadata map \u2014 identity facts each broker under the profile sees as `CRTR_PROFILE_META_<KEY>` env (secrets stay in `env`). Every manifest verb but `new`/`list` takes <profile> as an exact id, a profile name, or a close-enough name that resolves to the nearest profile (reported on stderr); a name shared by several profiles, or one equally close to several, fails listing every matching id. `delete` alone never guesses \u2014 an irreversible verb requires an exact id or name."},children:[i,a,s,d,p,c,f,m,l,h,u,w]})}e(S,"registerProfile");export{S as registerProfile};