@north-light/crouter 0.3.352 → 0.3.354

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 (616) hide show
  1. package/dist/api/client.d.ts +35 -25
  2. package/dist/api/client.js +2 -2
  3. package/dist/api/dto/broker-ops.d.ts +2 -36
  4. package/dist/api/dto/canvas.d.ts +8 -13
  5. package/dist/api/dto/config.d.ts +4 -0
  6. package/dist/api/dto/delivery.d.ts +61 -0
  7. package/dist/api/dto/docs.d.ts +133 -0
  8. package/dist/api/dto/docs.js +1 -0
  9. package/dist/api/dto/health.d.ts +26 -79
  10. package/dist/api/dto/node-outcomes.d.ts +1 -3
  11. package/dist/api/dto/nodes.d.ts +5 -26
  12. package/dist/api/dto/objects.d.ts +167 -0
  13. package/dist/api/dto/objects.js +1 -0
  14. package/dist/api/dto/profiles.d.ts +14 -8
  15. package/dist/api/dto/reports.d.ts +9 -7
  16. package/dist/api/dto/reviews.d.ts +9 -3
  17. package/dist/api/dto/worktree.d.ts +1 -1
  18. package/dist/api/index.d.ts +0 -1
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +14 -12
  21. package/dist/api/routes.js +1 -1
  22. package/dist/build-root.js +1 -1
  23. package/dist/builtin-memory/00-runtime-base/00-authoring.md +10 -5
  24. package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
  25. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -1
  26. package/dist/builtin-memory/05-kinds/explore/00-base.md +2 -2
  27. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +2 -2
  28. package/dist/builtin-memory/crouter-concepts/INDEX.md +2 -2
  29. package/dist/builtin-memory/crouter-concepts/lifecycle-and-wakes.md +1 -1
  30. package/dist/builtin-memory/crouter-concepts/memory.md +15 -15
  31. package/dist/builtin-memory/crouter-concepts/nodes-and-the-canvas.md +1 -1
  32. package/dist/builtin-memory/crouter-concepts/profiles-kinds-and-modes.md +5 -5
  33. package/dist/builtin-memory/crouter-concepts/scopes-and-trust.md +1 -1
  34. package/dist/builtin-memory/crouter-concepts/why-a-daemon.md +1 -1
  35. package/dist/builtin-memory/crouter-sdk/INDEX.md +2 -2
  36. package/dist/builtin-memory/crouter-sdk/README.md +5 -6
  37. package/dist/builtin-memory/crouter-sdk/errors.md +0 -13
  38. package/dist/builtin-memory/crouter-sdk/guides/README.md +0 -1
  39. package/dist/builtin-memory/crouter-sdk/guides/event-driven-assistant.md +2 -2
  40. package/dist/builtin-memory/crouter-sdk/nodes.md +0 -2
  41. package/dist/builtin-memory/crouter-sdk/resources.md +0 -1
  42. package/dist/builtin-memory/explore/exploration-doc.md +4 -4
  43. package/dist/builtin-memory/insights/capture.md +6 -6
  44. package/dist/builtin-memory/insights/init.md +14 -14
  45. package/dist/builtin-memory/internal/INDEX.md +4 -4
  46. package/dist/builtin-memory/internal/agent-shaping.md +20 -20
  47. package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
  48. package/dist/builtin-memory/internal/marketplaces.md +2 -2
  49. package/dist/builtin-memory/internal/memory-loading.md +31 -30
  50. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  51. package/dist/builtin-memory/internal/plugins.md +16 -14
  52. package/dist/builtin-memory/internal/storage-tiers.md +4 -4
  53. package/dist/builtin-memory/memory-read-orientation.md +1 -1
  54. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +32 -40
  55. package/dist/clients/attach/input/controller.js +1 -1
  56. package/dist/clients/attach/input/ref-autocomplete.js +1 -1
  57. package/dist/clients/attach/input/titled-editor.js +1 -1
  58. package/dist/clients/attach/render/chat-view.js +1 -1
  59. package/dist/clients/attach/render/crtr-output.d.ts +1 -2
  60. package/dist/clients/attach/render/crtr-output.js +17 -17
  61. package/dist/clients/attach/render/group-activity.d.ts +8 -8
  62. package/dist/clients/attach/render/group-activity.js +2 -2
  63. package/dist/clients/attach/render/group-recap.js +1 -1
  64. package/dist/clients/attach/render/tool-calls.d.ts +1 -1
  65. package/dist/clients/attach/session/profile-files.js +1 -1
  66. package/dist/clients/attach/slash/dispatch.js +1 -1
  67. package/dist/clients/attach/viewer.js +806 -1553
  68. package/dist/commands/api-client.d.ts +2 -0
  69. package/dist/commands/api-client.js +3 -3
  70. package/dist/commands/canvas/edges.d.ts +2 -0
  71. package/dist/commands/canvas/edges.js +2 -0
  72. package/dist/commands/canvas/list.d.ts +4 -0
  73. package/dist/commands/canvas/list.js +3 -0
  74. package/dist/commands/canvas/read.d.ts +8 -0
  75. package/dist/commands/canvas/read.js +5 -0
  76. package/dist/commands/canvas/search.d.ts +2 -0
  77. package/dist/commands/canvas/search.js +3 -0
  78. package/dist/commands/canvas/unwatch.d.ts +2 -0
  79. package/dist/commands/canvas/unwatch.js +1 -0
  80. package/dist/commands/canvas/watch.d.ts +3 -0
  81. package/dist/commands/canvas/watch.js +1 -0
  82. package/dist/commands/canvas-analytics.js +1 -1
  83. package/dist/commands/canvas-history/grep.js +4 -4
  84. package/dist/commands/canvas-history/read.js +2 -2
  85. package/dist/commands/canvas-history/search.js +7 -7
  86. package/dist/commands/canvas-history/shared.d.ts +0 -1
  87. package/dist/commands/canvas-history/shared.js +1 -1
  88. package/dist/commands/canvas-history/stats.js +2 -2
  89. package/dist/commands/canvas-history.js +1 -1
  90. package/dist/commands/canvas.js +1 -1
  91. package/dist/commands/doc/delete.d.ts +2 -0
  92. package/dist/commands/doc/delete.js +1 -0
  93. package/dist/commands/doc/edit.d.ts +2 -0
  94. package/dist/commands/doc/edit.js +1 -0
  95. package/dist/commands/doc/history.d.ts +2 -0
  96. package/dist/commands/doc/history.js +2 -0
  97. package/dist/commands/doc/lint.d.ts +2 -0
  98. package/dist/commands/doc/lint.js +2 -0
  99. package/dist/commands/doc/list.d.ts +2 -0
  100. package/dist/commands/doc/list.js +1 -0
  101. package/dist/commands/doc/move.d.ts +2 -0
  102. package/dist/commands/doc/move.js +1 -0
  103. package/dist/commands/doc/read.d.ts +2 -0
  104. package/dist/commands/doc/read.js +1 -0
  105. package/dist/commands/doc/shared.d.ts +25 -0
  106. package/dist/commands/doc/shared.js +2 -0
  107. package/dist/commands/doc/write.d.ts +2 -0
  108. package/dist/commands/doc/write.js +1 -0
  109. package/dist/commands/{memory.d.ts → doc.d.ts} +1 -1
  110. package/dist/commands/doc.js +1 -0
  111. package/dist/commands/human/review.js +1 -1
  112. package/dist/commands/node/bash.js +2 -2
  113. package/dist/commands/node/create.js +1 -1
  114. package/dist/commands/node/inspect.js +10 -10
  115. package/dist/commands/node/lifecycle.js +2 -2
  116. package/dist/commands/node/outcome.js +1 -1
  117. package/dist/commands/node/subscription.js +1 -1
  118. package/dist/commands/node-context.js +2 -2
  119. package/dist/commands/pkg/browse/catalog.js +1 -1
  120. package/dist/commands/pkg/browse/doc-view.js +1 -1
  121. package/dist/commands/pkg/browse/model.d.ts +9 -17
  122. package/dist/commands/pkg/plugin-inspect.js +1 -1
  123. package/dist/commands/pkg/plugin-manage.d.ts +4 -8
  124. package/dist/commands/pkg/plugin-manage.js +15 -17
  125. package/dist/commands/profile/list.js +1 -1
  126. package/dist/commands/profile/new.js +1 -1
  127. package/dist/commands/profile/project.js +1 -1
  128. package/dist/commands/profile/show.js +1 -1
  129. package/dist/commands/push.js +3 -3
  130. package/dist/commands/sys/config.js +1 -1
  131. package/dist/commands/sys/context/admin/actions.d.ts +18 -43
  132. package/dist/commands/sys/context/admin/actions.js +1 -2
  133. package/dist/commands/sys/context/admin/detail-panel.d.ts +17 -25
  134. package/dist/commands/sys/context/admin/detail-panel.js +2 -1
  135. package/dist/commands/sys/context/admin/docs-panel.d.ts +7 -6
  136. package/dist/commands/sys/context/admin/docs-panel.js +1 -1
  137. package/dist/commands/sys/context/admin/list-view.d.ts +12 -12
  138. package/dist/commands/sys/context/admin/list-view.js +1 -1
  139. package/dist/commands/sys/context/admin/model.d.ts +96 -69
  140. package/dist/commands/sys/context/admin/model.js +1 -1
  141. package/dist/commands/sys/context/admin/rail-panel.d.ts +7 -5
  142. package/dist/commands/sys/context/admin/rail-panel.js +1 -1
  143. package/dist/commands/sys/context/admin/read-view.d.ts +10 -14
  144. package/dist/commands/sys/context/admin/read-view.js +1 -2
  145. package/dist/commands/sys/context/admin/shell.d.ts +26 -31
  146. package/dist/commands/sys/context/admin/shell.js +1 -1
  147. package/dist/commands/sys/context/admin.js +2 -2
  148. package/dist/commands/sys/context/doc.js +2 -3
  149. package/dist/commands/sys/context/expose.js +2 -2
  150. package/dist/commands/sys/context/prompt-review.js +4 -4
  151. package/dist/commands/sys/context/resolve.d.ts +92 -65
  152. package/dist/commands/sys/context/resolve.js +7 -9
  153. package/dist/commands/sys/context.js +1 -1
  154. package/dist/commands/sys/doctor.js +1 -1
  155. package/dist/commands/sys/migrate.js +1 -1
  156. package/dist/commands/sys/panels/profiles-panel.d.ts +3 -1
  157. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  158. package/dist/commands/sys/sync-deps.d.ts +6 -11
  159. package/dist/commands/sys/sync-deps.js +7 -8
  160. package/dist/commands/sys/sync-project-guidance.js +5 -4
  161. package/dist/commands/sys/sync-shared.d.ts +41 -4
  162. package/dist/commands/sys/sync-shared.js +1 -1
  163. package/dist/commands/sys/sync-skills.js +2 -2
  164. package/dist/commands/sys/sync.js +1 -1
  165. package/dist/core/bash-job-supervisor.d.ts +2 -3
  166. package/dist/core/bash-job-supervisor.js +3 -3
  167. package/dist/core/bash-jobs.d.ts +0 -5
  168. package/dist/core/bash-jobs.js +7 -7
  169. package/dist/core/bootstrap.js +2 -2
  170. package/dist/core/canvas/canvas.d.ts +6 -50
  171. package/dist/core/canvas/canvas.js +16 -21
  172. package/dist/core/canvas/db.d.ts +4 -1
  173. package/dist/core/canvas/db.js +2 -2
  174. package/dist/core/canvas/history.d.ts +11 -39
  175. package/dist/core/canvas/history.js +9 -20
  176. package/dist/core/canvas/install-id.d.ts +2 -2
  177. package/dist/core/canvas/install-id.js +1 -1
  178. package/dist/core/canvas/memory-reads.d.ts +5 -0
  179. package/dist/core/canvas/memory-reads.js +1 -1
  180. package/dist/core/canvas/migrations.js +215 -41
  181. package/dist/core/canvas/node-agent-paths.js +1 -1
  182. package/dist/core/canvas/node-tokens.js +1 -1
  183. package/dist/core/canvas/paths.d.ts +0 -4
  184. package/dist/core/canvas/paths.js +1 -1
  185. package/dist/core/canvas/remote-canvas-source.d.ts +0 -1
  186. package/dist/core/canvas/remote-canvas-source.js +1 -1
  187. package/dist/core/canvas/render-source.d.ts +9 -6
  188. package/dist/core/canvas/render-source.js +6 -6
  189. package/dist/core/canvas/sessions.js +2 -2
  190. package/dist/core/canvas/source.d.ts +6 -0
  191. package/dist/core/canvas/tree.d.ts +29 -0
  192. package/dist/core/canvas/tree.js +12 -0
  193. package/dist/core/canvas/types.d.ts +0 -20
  194. package/dist/core/command-plugins/bundle.js +1 -1
  195. package/dist/core/config.d.ts +1 -1
  196. package/dist/core/conversation-store/listener.js +4 -2
  197. package/dist/core/feed/feed.d.ts +9 -7
  198. package/dist/core/feed/feed.js +3 -7
  199. package/dist/core/feed/inbox.d.ts +3 -5
  200. package/dist/core/feed/inbox.js +1 -10
  201. package/dist/core/feed/messages.d.ts +33 -6
  202. package/dist/core/feed/messages.js +10 -7
  203. package/dist/core/feed/reports.d.ts +10 -0
  204. package/dist/core/feed/reports.js +2 -0
  205. package/dist/core/grants/remove.js +1 -1
  206. package/dist/core/graph/access.d.ts +24 -0
  207. package/dist/core/graph/access.js +8 -0
  208. package/dist/core/graph/bodies.d.ts +6 -0
  209. package/dist/core/graph/bodies.js +1 -0
  210. package/dist/core/graph/deletion.d.ts +9 -0
  211. package/dist/core/graph/deletion.js +5 -0
  212. package/dist/core/graph/diff.d.ts +4 -0
  213. package/dist/core/graph/diff.js +4 -0
  214. package/dist/core/graph/documents.d.ts +160 -0
  215. package/dist/core/graph/documents.js +7 -0
  216. package/dist/core/graph/edges.d.ts +24 -0
  217. package/dist/core/graph/edges.js +1 -0
  218. package/dist/core/graph/events.d.ts +26 -0
  219. package/dist/core/graph/events.js +6 -0
  220. package/dist/core/graph/exposures.d.ts +53 -0
  221. package/dist/core/graph/exposures.js +4 -0
  222. package/dist/core/graph/jobs.d.ts +31 -0
  223. package/dist/core/graph/jobs.js +2 -0
  224. package/dist/core/graph/names.d.ts +28 -0
  225. package/dist/core/graph/names.js +3 -0
  226. package/dist/core/graph/objects.d.ts +55 -0
  227. package/dist/core/graph/objects.js +9 -0
  228. package/dist/core/graph/package-docs.d.ts +31 -0
  229. package/dist/core/graph/package-docs.js +5 -0
  230. package/dist/core/graph/package-files.d.ts +20 -0
  231. package/dist/core/graph/package-files.js +2 -0
  232. package/dist/core/graph/reader.d.ts +21 -0
  233. package/dist/core/graph/reader.js +3 -0
  234. package/dist/core/graph/repo-sync/exchange.d.ts +34 -0
  235. package/dist/core/graph/repo-sync/exchange.js +2 -0
  236. package/dist/core/graph/repo-sync/identity.d.ts +30 -0
  237. package/dist/core/graph/repo-sync/identity.js +1 -0
  238. package/dist/core/graph/repo-sync/index.d.ts +4 -0
  239. package/dist/core/graph/repo-sync/index.js +1 -0
  240. package/dist/core/graph/repo-sync/mirror.d.ts +30 -0
  241. package/dist/core/graph/repo-sync/mirror.js +6 -0
  242. package/dist/core/graph/repo-sync/ref-format.d.ts +76 -0
  243. package/dist/core/graph/repo-sync/ref-format.js +2 -0
  244. package/dist/core/graph/repo-sync/repos.d.ts +17 -0
  245. package/dist/core/graph/repo-sync/repos.js +3 -0
  246. package/dist/core/graph/repo-sync/sync.d.ts +42 -0
  247. package/dist/core/graph/repo-sync/sync.js +2 -0
  248. package/dist/core/graph/rules.d.ts +26 -0
  249. package/dist/core/graph/rules.js +3 -0
  250. package/dist/core/graph/spaces/app.d.ts +3 -0
  251. package/dist/core/graph/spaces/app.js +1 -0
  252. package/dist/core/graph/spaces/index.d.ts +19 -0
  253. package/dist/core/graph/spaces/index.js +1 -0
  254. package/dist/core/graph/spaces/person.d.ts +5 -0
  255. package/dist/core/graph/spaces/person.js +2 -0
  256. package/dist/core/graph/spaces/repo.d.ts +4 -0
  257. package/dist/core/graph/spaces/repo.js +1 -0
  258. package/dist/core/graph/types.d.ts +75 -0
  259. package/dist/core/graph/types.js +1 -0
  260. package/dist/core/graph/watches.d.ts +62 -0
  261. package/dist/core/graph/watches.js +18 -0
  262. package/dist/core/human/feedback-companion.js +1 -1
  263. package/dist/core/human/requests.d.ts +3 -1
  264. package/dist/core/human/requests.js +6 -6
  265. package/dist/core/inspector/model.js +2 -2
  266. package/dist/core/io.js +5 -5
  267. package/dist/core/layout-migrate/index.d.ts +24 -1
  268. package/dist/core/layout-migrate/index.js +4 -4
  269. package/dist/core/layout-migrate/paths.d.ts +4 -0
  270. package/dist/core/layout-migrate/paths.js +1 -1
  271. package/dist/core/layout-migrate/stored-paths.d.ts +7 -0
  272. package/dist/core/layout-migrate/stored-paths.js +11 -11
  273. package/dist/core/layout-migrate/stores.d.ts +19 -6
  274. package/dist/core/layout-migrate/stores.js +3 -4
  275. package/dist/core/manifest.d.ts +0 -2
  276. package/dist/core/manifest.js +1 -1
  277. package/dist/core/{memory/extensions.d.ts → plugin-extensions.d.ts} +9 -10
  278. package/dist/core/plugin-extensions.js +1 -0
  279. package/dist/core/preview-registry.d.ts +1 -1
  280. package/dist/core/preview-registry.js +3 -2
  281. package/dist/core/profiles/manifest.d.ts +7 -7
  282. package/dist/core/profiles/manifest.js +1 -1
  283. package/dist/core/profiles/select.js +3 -3
  284. package/dist/core/review/birth.js +1 -1
  285. package/dist/core/review/companion.js +1 -1
  286. package/dist/core/review/stage.d.ts +12 -1
  287. package/dist/core/review/stage.js +1 -1
  288. package/dist/core/review/store.d.ts +2 -0
  289. package/dist/core/review/store.js +1 -1
  290. package/dist/core/review/types.d.ts +7 -1
  291. package/dist/core/runs/events.js +1 -1
  292. package/dist/core/runs/operations.js +5 -5
  293. package/dist/core/runs/questions.js +2 -2
  294. package/dist/core/runtime/bearings-render.d.ts +13 -7
  295. package/dist/core/runtime/bearings-render.js +12 -12
  296. package/dist/core/runtime/bearings.d.ts +8 -18
  297. package/dist/core/runtime/bearings.js +7 -7
  298. package/dist/core/runtime/broker/daemon-ops.d.ts +7 -12
  299. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  300. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  301. package/dist/core/runtime/broker/fault-retry.js +1 -1
  302. package/dist/core/runtime/broker/frame-dispatch.d.ts +1 -1
  303. package/dist/core/runtime/broker/frame-memory-refs.d.ts +7 -2
  304. package/dist/core/runtime/broker/frame-memory-refs.js +1 -1
  305. package/dist/core/runtime/broker/inbox.d.ts +1 -4
  306. package/dist/core/runtime/broker/inbox.js +1 -10
  307. package/dist/core/runtime/broker/rebind.js +1 -1
  308. package/dist/core/runtime/broker/retry-card-elision.d.ts +7 -0
  309. package/dist/core/runtime/broker/retry-card-elision.js +1 -0
  310. package/dist/core/runtime/broker-extension-render.d.ts +0 -13
  311. package/dist/core/runtime/broker-extension-render.js +2 -4
  312. package/dist/core/runtime/broker-persona-guidance.js +3 -3
  313. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  314. package/dist/core/runtime/broker.js +1 -1
  315. package/dist/core/runtime/close.d.ts +9 -4
  316. package/dist/core/runtime/close.js +1 -1
  317. package/dist/core/runtime/deliver-live.js +1 -1
  318. package/dist/core/runtime/kickoff.js +17 -19
  319. package/dist/core/runtime/launch-target.d.ts +7 -0
  320. package/dist/core/runtime/launch-target.js +1 -1
  321. package/dist/core/runtime/ledger.d.ts +10 -0
  322. package/dist/core/runtime/ledger.js +3 -0
  323. package/dist/core/runtime/lifecycle.js +2 -2
  324. package/dist/core/runtime/nodes.d.ts +10 -2
  325. package/dist/core/runtime/nodes.js +1 -1
  326. package/dist/core/runtime/outcome-document.d.ts +2 -2
  327. package/dist/core/runtime/outcome-document.js +1 -1
  328. package/dist/core/runtime/persona.js +2 -2
  329. package/dist/core/runtime/placement.js +1 -1
  330. package/dist/core/runtime/promote.d.ts +2 -2
  331. package/dist/core/runtime/promote.js +1 -1
  332. package/dist/core/runtime/prospective-inventory-cli.js +2 -2
  333. package/dist/core/runtime/recycle.js +1 -1
  334. package/dist/core/runtime/reopen.js +1 -1
  335. package/dist/core/runtime/revive.js +2 -2
  336. package/dist/core/runtime/roadmap.d.ts +17 -9
  337. package/dist/core/runtime/roadmap.js +4 -4
  338. package/dist/core/runtime/spawn-env.js +1 -1
  339. package/dist/core/runtime/spawn.d.ts +5 -3
  340. package/dist/core/runtime/spawn.js +2 -2
  341. package/dist/core/runtime/structured-output.d.ts +3 -1
  342. package/dist/core/runtime/structured-output.js +4 -4
  343. package/dist/core/scope.d.ts +1 -32
  344. package/dist/core/scope.js +1 -1
  345. package/dist/core/scoped-state/db.js +2 -1
  346. package/dist/core/scoped-state/migrate.js +2 -2
  347. package/dist/core/scoped-state/profiles.d.ts +11 -0
  348. package/dist/core/scoped-state/profiles.js +1 -1
  349. package/dist/core/scoped-state/schema.d.ts +1 -1
  350. package/dist/core/scoped-state/schema.js +7 -5
  351. package/dist/core/spaces/permissions.d.ts +0 -14
  352. package/dist/core/spaces/permissions.js +1 -1
  353. package/dist/core/spaces/stop.d.ts +13 -0
  354. package/dist/core/spaces/stop.js +2 -2
  355. package/dist/core/storage/tables.d.ts +1 -1
  356. package/dist/core/substrate/delivery/corpus.d.ts +21 -0
  357. package/dist/core/substrate/delivery/corpus.js +3 -0
  358. package/dist/core/substrate/delivery/deliver.d.ts +76 -0
  359. package/dist/core/substrate/delivery/deliver.js +6 -0
  360. package/dist/core/substrate/delivery/listings.d.ts +27 -0
  361. package/dist/core/substrate/delivery/listings.js +4 -0
  362. package/dist/core/substrate/delivery/match.d.ts +28 -0
  363. package/dist/core/substrate/delivery/match.js +1 -0
  364. package/dist/core/substrate/delivery/plan.d.ts +67 -0
  365. package/dist/core/substrate/delivery/plan.js +3 -0
  366. package/dist/core/substrate/delivery/render-boot.d.ts +20 -0
  367. package/dist/core/substrate/delivery/render-boot.js +54 -0
  368. package/dist/core/substrate/delivery/render-event.d.ts +47 -0
  369. package/dist/core/substrate/delivery/render-event.js +6 -0
  370. package/dist/core/substrate/delivery/sub-persona-menu.d.ts +2 -0
  371. package/dist/core/substrate/delivery/sub-persona-menu.js +6 -0
  372. package/dist/core/substrate/delivery/types.d.ts +30 -0
  373. package/dist/core/substrate/delivery/types.js +0 -0
  374. package/dist/core/substrate/gate-explain.d.ts +0 -13
  375. package/dist/core/substrate/gate-explain.js +1 -1
  376. package/dist/core/substrate/schema.d.ts +11 -139
  377. package/dist/core/substrate/schema.js +1 -1
  378. package/dist/core/substrate/subject-fields.d.ts +3 -0
  379. package/dist/core/substrate/subject.d.ts +2 -1
  380. package/dist/core/substrate/subject.js +1 -1
  381. package/dist/daemon/api/app-listener.js +11 -11
  382. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  383. package/dist/daemon/api/handlers/bash-jobs.js +1 -2
  384. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  385. package/dist/daemon/api/handlers/canvas.js +5 -5
  386. package/dist/daemon/api/handlers/daemon.js +1 -1
  387. package/dist/daemon/api/handlers/delivery.d.ts +2 -0
  388. package/dist/daemon/api/handlers/delivery.js +1 -0
  389. package/dist/daemon/api/handlers/{memory.d.ts → docs.d.ts} +1 -1
  390. package/dist/daemon/api/handlers/docs.js +1 -0
  391. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  392. package/dist/daemon/api/handlers/messages.js +2 -2
  393. package/dist/daemon/api/handlers/modelauth.d.ts +3 -0
  394. package/dist/daemon/api/handlers/modelauth.js +1 -1
  395. package/dist/daemon/api/handlers/node-records.js +2 -2
  396. package/dist/daemon/api/handlers/nodes.js +1 -1
  397. package/dist/daemon/api/handlers/objects.d.ts +2 -0
  398. package/dist/daemon/api/handlers/objects.js +5 -0
  399. package/dist/daemon/api/handlers/package-docs.d.ts +2 -0
  400. package/dist/daemon/api/handlers/package-docs.js +1 -0
  401. package/dist/daemon/api/handlers/profiles.js +1 -1
  402. package/dist/daemon/api/handlers/reports.d.ts +2 -2
  403. package/dist/daemon/api/handlers/reports.js +4 -4
  404. package/dist/daemon/api/handlers/reviews.js +1 -1
  405. package/dist/daemon/api/handlers/vendor-status.d.ts +8 -0
  406. package/dist/daemon/api/handlers/vendor-status.js +1 -0
  407. package/dist/daemon/api/map.d.ts +2 -2
  408. package/dist/daemon/api/map.js +2 -2
  409. package/dist/daemon/api/operations.d.ts +1 -1
  410. package/dist/daemon/api/operations.js +1 -1
  411. package/dist/daemon/api/principal.d.ts +5 -0
  412. package/dist/daemon/api/principal.js +1 -1
  413. package/dist/daemon/api/reader.d.ts +17 -0
  414. package/dist/daemon/api/reader.js +1 -0
  415. package/dist/daemon/api/server.js +1 -1
  416. package/dist/daemon/control.d.ts +2 -3
  417. package/dist/daemon/crtrd.js +8 -6
  418. package/dist/daemon/fleet.js +4 -4
  419. package/dist/daemon/reconcilers/bash-deadline.d.ts +11 -1
  420. package/dist/daemon/reconcilers/bash-deadline.js +2 -1
  421. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  422. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  423. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  424. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  425. package/dist/daemon/reconcilers/storage-maintenance.d.ts +1 -0
  426. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  427. package/dist/daemon/review/deliver.js +2 -2
  428. package/dist/daemon/review/finish.js +1 -1
  429. package/dist/hook-authoring.d.ts +0 -1
  430. package/dist/hook-authoring.js +3 -3
  431. package/dist/migrations/004-canvas-documents/apply.d.ts +10 -0
  432. package/dist/migrations/004-canvas-documents/apply.js +1 -0
  433. package/dist/migrations/004-canvas-documents/fields.d.ts +24 -0
  434. package/dist/migrations/004-canvas-documents/fields.js +2 -0
  435. package/dist/migrations/004-canvas-documents/index.d.ts +16 -0
  436. package/dist/migrations/004-canvas-documents/index.js +2 -0
  437. package/dist/migrations/004-canvas-documents/legacy/discover.d.ts +16 -0
  438. package/dist/migrations/004-canvas-documents/legacy/discover.js +1 -0
  439. package/dist/migrations/004-canvas-documents/legacy/history.d.ts +5 -0
  440. package/dist/migrations/004-canvas-documents/legacy/history.js +2 -0
  441. package/dist/migrations/004-canvas-documents/legacy/nested.d.ts +7 -0
  442. package/dist/migrations/004-canvas-documents/legacy/nested.js +1 -0
  443. package/dist/migrations/004-canvas-documents/legacy/parse.d.ts +14 -0
  444. package/dist/migrations/004-canvas-documents/legacy/parse.js +1 -0
  445. package/dist/migrations/004-canvas-documents/legacy/types.d.ts +91 -0
  446. package/dist/migrations/004-canvas-documents/legacy/types.js +0 -0
  447. package/dist/migrations/004-canvas-documents/legacy-edges.d.ts +6 -0
  448. package/dist/migrations/004-canvas-documents/legacy-edges.js +18 -0
  449. package/dist/migrations/004-canvas-documents/plan.d.ts +102 -0
  450. package/dist/migrations/004-canvas-documents/plan.js +3 -0
  451. package/dist/migrations/004-canvas-documents/pointers.d.ts +23 -0
  452. package/dist/migrations/004-canvas-documents/pointers.js +4 -0
  453. package/dist/migrations/activation.d.ts +9 -18
  454. package/dist/migrations/activation.js +2 -2
  455. package/dist/pi-extensions/broker-local.d.ts +2 -2
  456. package/dist/pi-extensions/broker-local.js +2 -2
  457. package/dist/pi-extensions/canvas-bash-valve.js +5 -4
  458. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  459. package/dist/pi-extensions/canvas-doc-substrate.d.ts +0 -1
  460. package/dist/pi-extensions/canvas-doc-substrate.js +6 -6
  461. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  462. package/dist/pi-extensions/canvas-passive-context.js +1 -1
  463. package/dist/pi-extensions/canvas-recap.js +2 -2
  464. package/dist/pi-extensions/canvas-stophook.d.ts +1 -1
  465. package/dist/pi-extensions/canvas-stophook.js +1 -1
  466. package/dist/prompts/review.js +3 -3
  467. package/dist/shared/env.d.ts +5 -0
  468. package/dist/shared/env.js +1 -1
  469. package/dist/shared/generated-context.js +2 -10
  470. package/dist/shared/inbox-entry-body.d.ts +22 -0
  471. package/dist/shared/inbox-entry-body.js +10 -0
  472. package/dist/{core/memory → shared}/inline-ref-guidance.d.ts +2 -2
  473. package/dist/shared/inline-ref-guidance.js +2 -0
  474. package/dist/types.d.ts +3 -1
  475. package/docs/cli/memory-and-preferences.md +12 -14
  476. package/docs/concepts/README.md +1 -1
  477. package/docs/concepts/lifecycle-and-wakes.md +1 -1
  478. package/docs/concepts/memory.md +15 -15
  479. package/docs/concepts/nodes-and-the-canvas.md +1 -1
  480. package/docs/concepts/profiles-kinds-and-modes.md +5 -5
  481. package/docs/concepts/scopes-and-trust.md +1 -1
  482. package/docs/concepts/why-a-daemon.md +1 -1
  483. package/docs/sdk/README.md +5 -6
  484. package/docs/sdk/errors.md +0 -13
  485. package/docs/sdk/guides/README.md +0 -1
  486. package/docs/sdk/nodes.md +0 -2
  487. package/docs/sdk/resources.md +0 -1
  488. package/package.json +2 -2
  489. package/packages/crouter-identity/package.json +1 -1
  490. package/runtime.lock.json +11 -11
  491. package/dist/api/dto/memory.d.ts +0 -171
  492. package/dist/api/dto/memory.js +0 -1
  493. package/dist/builtin-memory/crouter-sdk/guides/app-memory.md +0 -73
  494. package/dist/builtin-memory/crouter-sdk/memory.md +0 -87
  495. package/dist/commands/broker-permissions.d.ts +0 -2
  496. package/dist/commands/broker-permissions.js +0 -1
  497. package/dist/commands/memory/client.d.ts +0 -11
  498. package/dist/commands/memory/client.js +0 -1
  499. package/dist/commands/memory/delete.d.ts +0 -1
  500. package/dist/commands/memory/delete.js +0 -1
  501. package/dist/commands/memory/edit.d.ts +0 -1
  502. package/dist/commands/memory/edit.js +0 -21
  503. package/dist/commands/memory/find.d.ts +0 -1
  504. package/dist/commands/memory/find.js +0 -1
  505. package/dist/commands/memory/history.d.ts +0 -1
  506. package/dist/commands/memory/history.js +0 -5
  507. package/dist/commands/memory/lint.d.ts +0 -1
  508. package/dist/commands/memory/lint.js +0 -1
  509. package/dist/commands/memory/list.d.ts +0 -1
  510. package/dist/commands/memory/list.js +0 -1
  511. package/dist/commands/memory/move.d.ts +0 -1
  512. package/dist/commands/memory/move.js +0 -1
  513. package/dist/commands/memory/origin.d.ts +0 -1
  514. package/dist/commands/memory/origin.js +0 -1
  515. package/dist/commands/memory/read.d.ts +0 -1
  516. package/dist/commands/memory/read.js +0 -6
  517. package/dist/commands/memory/shared.d.ts +0 -22
  518. package/dist/commands/memory/shared.js +0 -1
  519. package/dist/commands/memory/write.d.ts +0 -1
  520. package/dist/commands/memory/write.js +0 -13
  521. package/dist/commands/memory.js +0 -1
  522. package/dist/commands/node-inspect-artifacts.d.ts +0 -1
  523. package/dist/commands/node-inspect-artifacts.js +0 -8
  524. package/dist/core/help/memory-extensions.d.ts +0 -3
  525. package/dist/core/help/memory-extensions.js +0 -2
  526. package/dist/core/memory/cli-selector.d.ts +0 -13
  527. package/dist/core/memory/cli-selector.js +0 -1
  528. package/dist/core/memory/doc-link-grammar.d.ts +0 -20
  529. package/dist/core/memory/doc-link-grammar.js +0 -2
  530. package/dist/core/memory/extensions.js +0 -1
  531. package/dist/core/memory/history.d.ts +0 -87
  532. package/dist/core/memory/history.js +0 -6
  533. package/dist/core/memory/identity.d.ts +0 -65
  534. package/dist/core/memory/identity.js +0 -1
  535. package/dist/core/memory/inline-ref-guidance.js +0 -2
  536. package/dist/core/memory/inline-ref-inventory.d.ts +0 -9
  537. package/dist/core/memory/inline-ref-inventory.js +0 -1
  538. package/dist/core/memory/lint.d.ts +0 -163
  539. package/dist/core/memory/lint.js +0 -2
  540. package/dist/core/memory/mutation-domain.d.ts +0 -113
  541. package/dist/core/memory/mutation-domain.js +0 -12
  542. package/dist/core/memory/mutations.d.ts +0 -74
  543. package/dist/core/memory/mutations.js +0 -1
  544. package/dist/core/memory/project-namespace.d.ts +0 -31
  545. package/dist/core/memory/project-namespace.js +0 -2
  546. package/dist/core/memory/repository-association.d.ts +0 -31
  547. package/dist/core/memory/repository-association.js +0 -1
  548. package/dist/core/memory/service.d.ts +0 -145
  549. package/dist/core/memory/service.js +0 -2
  550. package/dist/core/memory/tree.d.ts +0 -39
  551. package/dist/core/memory/tree.js +0 -1
  552. package/dist/core/memory-resolver.d.ts +0 -280
  553. package/dist/core/memory-resolver.js +0 -2
  554. package/dist/core/nested-stores.d.ts +0 -18
  555. package/dist/core/nested-stores.js +0 -1
  556. package/dist/core/runtime/memory.d.ts +0 -3
  557. package/dist/core/runtime/memory.js +0 -1
  558. package/dist/core/substrate/frontmatter-validation.d.ts +0 -11
  559. package/dist/core/substrate/frontmatter-validation.js +0 -1
  560. package/dist/core/substrate/gate.d.ts +0 -16
  561. package/dist/core/substrate/gate.js +0 -1
  562. package/dist/core/substrate/index.d.ts +0 -18
  563. package/dist/core/substrate/index.js +0 -1
  564. package/dist/core/substrate/injected-store.d.ts +0 -75
  565. package/dist/core/substrate/injected-store.js +0 -2
  566. package/dist/core/substrate/listings.d.ts +0 -28
  567. package/dist/core/substrate/listings.js +0 -1
  568. package/dist/core/substrate/memory-events.d.ts +0 -6
  569. package/dist/core/substrate/memory-events.js +0 -1
  570. package/dist/core/substrate/on-read-node.d.ts +0 -6
  571. package/dist/core/substrate/on-read-node.js +0 -1
  572. package/dist/core/substrate/on-read.d.ts +0 -101
  573. package/dist/core/substrate/on-read.js +0 -9
  574. package/dist/core/substrate/plan.d.ts +0 -94
  575. package/dist/core/substrate/plan.js +0 -1
  576. package/dist/core/substrate/render-node.d.ts +0 -12
  577. package/dist/core/substrate/render-node.js +0 -1
  578. package/dist/core/substrate/render.d.ts +0 -41
  579. package/dist/core/substrate/render.js +0 -65
  580. package/dist/core/substrate/session-cache.d.ts +0 -27
  581. package/dist/core/substrate/session-cache.js +0 -1
  582. package/dist/core/substrate/surface-match.d.ts +0 -73
  583. package/dist/core/substrate/surface-match.js +0 -1
  584. package/dist/daemon/api/handlers/memory.js +0 -5
  585. package/dist/migrations/001-surfaces-frontmatter.d.ts +0 -2
  586. package/dist/migrations/001-surfaces-frontmatter.js +0 -1
  587. package/dist/migrations/002-profile-project-memory.d.ts +0 -2
  588. package/dist/migrations/002-profile-project-memory.js +0 -1
  589. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +0 -26
  590. package/dist/migrations/003-repository-root-memory-identity/front-door.js +0 -11
  591. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +0 -2
  592. package/dist/migrations/003-repository-root-memory-identity/index.js +0 -5
  593. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +0 -95
  594. package/dist/migrations/003-repository-root-memory-identity/references.js +0 -5
  595. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +0 -39
  596. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +0 -3
  597. package/dist/migrations/convergent.d.ts +0 -43
  598. package/dist/migrations/convergent.js +0 -2
  599. package/dist/migrations/corpus.d.ts +0 -75
  600. package/dist/migrations/corpus.js +0 -3
  601. package/dist/migrations/frontmatter-splice.d.ts +0 -15
  602. package/dist/migrations/frontmatter-splice.js +0 -8
  603. package/dist/migrations/profile-manifests.d.ts +0 -30
  604. package/dist/migrations/profile-manifests.js +0 -2
  605. package/dist/migrations/registry.d.ts +0 -7
  606. package/dist/migrations/registry.js +0 -1
  607. package/dist/migrations/runner.d.ts +0 -43
  608. package/dist/migrations/runner.js +0 -1
  609. package/dist/migrations/types.d.ts +0 -211
  610. package/dist/shared/birth-announcement.d.ts +0 -12
  611. package/dist/shared/birth-announcement.js +0 -1
  612. package/docs/sdk/guides/app-memory.md +0 -22
  613. package/docs/sdk/memory.md +0 -85
  614. /package/dist/{migrations/types.js → api/dto/delivery.js} +0 -0
  615. /package/dist/{core/memory → shared}/inline-ref-grammar.d.ts +0 -0
  616. /package/dist/{core/memory → shared}/inline-ref-grammar.js +0 -0
@@ -1,9 +1,9 @@
1
- var g=Object.defineProperty;var i=(e,r)=>g(e,"name",{value:r,configurable:!0});import{envNodeId as y}from"../shared/env.js";import{defineBranch as b,defineLeaf as u}from"../core/command.js";import{InputError as d,readStdinRaw as c}from"../core/io.js";import{ApiError as _}from"../api/index.js";import{cliClient as h,rethrowAsCliError as l}from"./api-client.js";function p(){const e=y();if(e===void 0||e.trim()==="")throw new d({error:"no_node_context",message:"CRTR_NODE_ID is not set \u2014 push runs inside a canvas node.",next:"Run push from a node process spawned by the runtime."});return e.trim()}i(p,"requireCallerNode");const f={update:"report progress to subscribers",final:"finish: write the canonical result, mark the node done, close its window"},k={update:"you have progress worth surfacing to your managers while work remains in flight. Use normal delivery unless it can wait for their next real wake (--tier deferred) or needs immediate attention (--tier urgent); use push final only when the work is actually done.",final:"the work this node was spawned to do is complete and you are ready to hand back the canonical result \u2014 this writes that result, marks the node done, and closes its window, so it is the LAST thing you do here, not a progress note. Use push update while work is still in flight, and do not reach for final on a node working directly with the user: it has no manager to report up to and would close mid-conversation (the guard blocks it unless you pass --force after the user confirms)."};function v(){return u({name:"result",description:"answer a pending structured-output request with the required JSON result, or decline it",whenToUse:'your system prompt names a pending structured-output request you must answer. The value is validated against the required schema server-side; a mismatch rejects with field errors and records nothing, so fix and rerun. When the schema cannot be honestly satisfied (blocked, unavailable, bad input), pass `--decline "<reason>" --code <token>` (plus `--retryable` when the same request could succeed later) instead of inventing a value; your requester names the code tokens it accepts. For a terminal request either path IS how the node finishes \u2014 never call `crtr push final` alongside it.',help:{name:"push result",summary:"answer a pending structured-output request",params:[{kind:"stdin",name:"value",required:!1,constraint:"The JSON result. Pipe it from a single-quoted heredoc (`<<'EOF'`) to preserve literal bytes. Required unless `--decline` is passed."},{kind:"flag",name:"decline",type:"string",required:!1,constraint:"Decline instead of answering: one plain sentence on why the schema cannot be honestly satisfied (blocked, unavailable, bad input). Requires `--code`. Records a failure outcome with reason `declined` carrying the reason, code, and retryable flag, and clears the request; for a terminal request this finishes the node."},{kind:"flag",name:"code",type:"string",required:!1,constraint:"With `--decline`: one whitespace-free token (\u2264 64 chars) naming the decline class. crouter carries it verbatim; the requester validates it against the tokens it documented for you."},{kind:"flag",name:"retryable",type:"bool",required:!1,default:!1,constraint:"With `--decline`: the same request could succeed if issued again later (a transient block). Omit when the decline is final for this input."}],output:[{name:"mode",type:"string",required:!0,constraint:"Which request this answered: `terminal` finished the node; `oneoff` left it working."},{name:"result_path",type:"string",required:!0,constraint:"Absolute path of the recorded artifact: the result JSON, or the declined marker when `--decline` was passed."},{name:"declined",type:"object",required:!1,constraint:"Present only when the request was declined: { reason, code, retryable } as recorded."},{name:"report_path",type:"string",required:!0,constraint:"Absolute path of the report pushed alongside the result."},{name:"notified",type:"string[]",required:!0,constraint:"Subscriber node ids that received an inbox pointer."},{name:"transitioned",type:"object",required:!1,constraint:"Present only for a terminal request that flipped the node \u2014 { from, to } lifecycle-status transition applied server-side."}],outputKind:"object",effects:["Validates the value against the pending schema server-side; a mismatch records nothing and the request stays pending.","Writes the accepted result to nodes/<nodeId>/context/result.json (or the decline to context/declined.json) and clears the pending request.","A terminal decline records a `failure` outcome with reason `declined` whose `declined` field carries { reason, code, retryable }; the requester sees no value.","Pushes the mode-matched report: final for a terminal request (the node finishes \u2014 same effects as `push final`), update for a one-off request (the node keeps working)."]},run:i(async e=>{const r=p(),s=typeof e.decline=="string"?e.decline.trim():"",o=typeof e.code=="string"?e.code.trim():"";let a;if(s!==""){if(o==="")throw new d({error:"missing_decline_code",message:"a decline needs a code",field:"code",next:"Pass `--code <token>` \u2014 the whitespace-free token your requester documented for this decline class."});a={decline:s,code:o,retryable:e.retryable===!0}}else{if(o!==""||e.retryable===!0)throw new d({error:"decline_flags_without_decline",message:"--code and --retryable only apply with --decline",next:'Pass `--decline "<reason>"` alongside them, or drop them and submit the JSON result.'});let t=typeof e.value=="string"?e.value.trim():"";if(t===""&&(t=(await c()).trim()),t==="")throw new d({error:"missing_value",message:"no result value",field:"value",next:'Pass the JSON result as an argument or on stdin, or `--decline "<reason>" --code <token>` when the schema cannot be honestly satisfied.'});let n;try{n=JSON.parse(t)}catch(w){throw new d({error:"bad_result_json",message:`the result is not valid JSON: ${w.message}`,field:"value",next:"Pass one valid JSON value matching the requested schema."})}a={value:n}}try{const t=await h().submitResult(r,a);return{mode:t.mode,result_path:t.result_path,report_path:t.report_path,notified:t.notified,...t.declined===void 0?{}:{declined:t.declined},...t.transitioned!==void 0?{transitioned:t.transitioned}:{},...t.worktree_auto_dropped===!0?{worktree_auto_dropped:!0,worktree_auto_dropped_path:t.worktree_auto_dropped_path}:{}}}catch(t){l(t)}},"run"),render:i(e=>{const r=e.declined,s=e.mode==="terminal"?`${r?"Decline recorded":"Result recorded"} \u2014 node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.`:`${r?"One-off request declined":"One-off result recorded"} and pushed \u2014 the structured-output gate is cleared; continue working normally.`,o=r===void 0?"":`
1
+ var g=Object.defineProperty;var i=(e,r)=>g(e,"name",{value:r,configurable:!0});import{envNodeId as y}from"../shared/env.js";import{defineBranch as b,defineLeaf as u}from"../core/command.js";import{InputError as d,readStdinRaw as c}from"../core/io.js";import{ApiError as k}from"../api/index.js";import{cliClient as h,rethrowAsCliError as l}from"./api-client.js";function p(){const e=y();if(e===void 0||e.trim()==="")throw new d({error:"no_node_context",message:"CRTR_NODE_ID is not set \u2014 push runs inside a canvas node.",next:"Run push from a node process spawned by the runtime."});return e.trim()}i(p,"requireCallerNode");const f={update:"report progress to subscribers",final:"finish: write the canonical result, mark the node done, close its window"},_={update:"you have progress worth surfacing to your managers while work remains in flight. Use normal delivery unless it can wait for their next real wake (--tier deferred) or needs immediate attention (--tier urgent); use push final only when the work is actually done.",final:"the work this node was spawned to do is complete and you are ready to hand back the canonical result \u2014 this writes that result, marks the node done, and closes its window, so it is the LAST thing you do here, not a progress note. Use push update while work is still in flight, and do not reach for final on a node working directly with the user: it has no manager to report up to and would close mid-conversation (the guard blocks it unless you pass --force after the user confirms)."};function v(){return u({name:"result",description:"answer a pending structured-output request with the required JSON result, or decline it",whenToUse:'your system prompt names a pending structured-output request you must answer. The value is validated against the required schema server-side; a mismatch rejects with field errors and records nothing, so fix and rerun. When the schema cannot be honestly satisfied (blocked, unavailable, bad input), pass `--decline "<reason>" --code <token>` (plus `--retryable` when the same request could succeed later) instead of inventing a value; your requester names the code tokens it accepts. For a terminal request either path IS how the node finishes \u2014 never call `crtr push final` alongside it.',help:{name:"push result",summary:"answer a pending structured-output request",params:[{kind:"stdin",name:"value",required:!1,constraint:"The JSON result. Pipe it from a single-quoted heredoc (`<<'EOF'`) to preserve literal bytes. Required unless `--decline` is passed."},{kind:"flag",name:"decline",type:"string",required:!1,constraint:"Decline instead of answering: one plain sentence on why the schema cannot be honestly satisfied (blocked, unavailable, bad input). Requires `--code`. Records a failure outcome with reason `declined` carrying the reason, code, and retryable flag, and clears the request; for a terminal request this finishes the node."},{kind:"flag",name:"code",type:"string",required:!1,constraint:"With `--decline`: one whitespace-free token (\u2264 64 chars) naming the decline class. crouter carries it verbatim; the requester validates it against the tokens it documented for you."},{kind:"flag",name:"retryable",type:"bool",required:!1,default:!1,constraint:"With `--decline`: the same request could succeed if issued again later (a transient block). Omit when the decline is final for this input."}],output:[{name:"mode",type:"string",required:!0,constraint:"Which request this answered: `terminal` finished the node; `oneoff` left it working."},{name:"result_path",type:"string",required:!0,constraint:"Absolute path of the recorded artifact: the result JSON, or the declined marker when `--decline` was passed."},{name:"declined",type:"object",required:!1,constraint:"Present only when the request was declined: { reason, code, retryable } as recorded."},{name:"report",type:"string",required:!0,constraint:"Name of the report document pushed alongside the result, `<node-id>/reports/<name>`."},{name:"notified",type:"string[]",required:!0,constraint:"Subscriber node ids that received an inbox pointer."},{name:"transitioned",type:"object",required:!1,constraint:"Present only for a terminal request that flipped the node \u2014 { from, to } lifecycle-status transition applied server-side."}],outputKind:"object",effects:["Validates the value against the pending schema server-side; a mismatch records nothing and the request stays pending.","Writes the accepted result to nodes/<nodeId>/context/result.json (or the decline to context/declined.json) and clears the pending request.","A terminal decline records a `failure` outcome with reason `declined` whose `declined` field carries { reason, code, retryable }; the requester sees no value.","Pushes the mode-matched report: final for a terminal request (the node finishes \u2014 same effects as `push final`), update for a one-off request (the node keeps working)."]},run:i(async e=>{const r=p(),s=typeof e.decline=="string"?e.decline.trim():"",o=typeof e.code=="string"?e.code.trim():"";let a;if(s!==""){if(o==="")throw new d({error:"missing_decline_code",message:"a decline needs a code",field:"code",next:"Pass `--code <token>` \u2014 the whitespace-free token your requester documented for this decline class."});a={decline:s,code:o,retryable:e.retryable===!0}}else{if(o!==""||e.retryable===!0)throw new d({error:"decline_flags_without_decline",message:"--code and --retryable only apply with --decline",next:'Pass `--decline "<reason>"` alongside them, or drop them and submit the JSON result.'});let t=typeof e.value=="string"?e.value.trim():"";if(t===""&&(t=(await c()).trim()),t==="")throw new d({error:"missing_value",message:"no result value",field:"value",next:'Pass the JSON result as an argument or on stdin, or `--decline "<reason>" --code <token>` when the schema cannot be honestly satisfied.'});let n;try{n=JSON.parse(t)}catch(w){throw new d({error:"bad_result_json",message:`the result is not valid JSON: ${w.message}`,field:"value",next:"Pass one valid JSON value matching the requested schema."})}a={value:n}}try{const t=await h().submitResult(r,a);return{mode:t.mode,result_path:t.result_path,report:t.report,notified:t.notified,...t.declined===void 0?{}:{declined:t.declined},...t.transitioned!==void 0?{transitioned:t.transitioned}:{},...t.worktree_auto_dropped===!0?{worktree_auto_dropped:!0,worktree_auto_dropped_path:t.worktree_auto_dropped_path}:{}}}catch(t){l(t)}},"run"),render:i(e=>{const r=e.declined,s=e.mode==="terminal"?`${r?"Decline recorded":"Result recorded"} \u2014 node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.`:`${r?"One-off request declined":"One-off result recorded"} and pushed \u2014 the structured-output gate is cleared; continue working normally.`,o=r===void 0?"":`
2
2
  - code: ${r.code} (${r.retryable?"retryable":"not retryable"})`;return`${s}
3
3
 
4
4
  - ${r?"declined":"result"}: ${e.result_path}${o}
5
- - report: ${e.report_path}`},"render")})}i(v,"makeResultLeaf");function m(e){return u({name:e,description:f[e],whenToUse:k[e],help:{name:`push ${e}`,summary:f[e],params:[{kind:"stdin",name:"body",required:!0,constraint:"Report body (markdown). Pipe it from a single-quoted heredoc (`<<'EOF'`) to preserve literal bytes."},...e==="update"?[{kind:"flag",name:"tier",type:"enum",choices:["deferred","normal","urgent"],required:!1,default:"normal",constraint:"Delivery urgency: deferred holds for the receiver\u2019s next non-deferred wake; normal wakes normally; urgent steers a live receiver and wakes an idle receiver."}]:[{kind:"flag",name:"force",type:"bool",required:!1,default:!1,constraint:"Override the guard that blocks `push final` on a node the user is attending (a resident with no one to report up to). Only pass this after the user explicitly confirms they want this node finished."}]],output:[{name:"report_path",type:"string",required:!0,constraint:"Absolute path of the written report."},{name:"notified",type:"string[]",required:!0,constraint:"Subscriber node ids that received an inbox pointer."},...e==="final"?[{name:"transitioned",type:"object",required:!1,constraint:"Present only for a final that flipped the node \u2014 { from, to } lifecycle-status transition applied server-side."},{name:"worktree_auto_dropped",type:"boolean",required:!1,constraint:"Present only when the server closed this node\u2019s managed-worktree record without requiring `node worktree close`; cleanup of an existing checkout remains pending (see worktree_auto_dropped_path)."},{name:"worktree_auto_dropped_path",type:"string",required:!1,constraint:"Present only alongside worktree_auto_dropped: the closed worktree path; an existing checkout remains until pending cleanup."}]:[]],outputKind:"object",effects:["Writes nodes/<nodeId>/reports/<ts>-<kind>.md (server-side).","Appends one inbox pointer per subscriber.",...e==="final"?["Marks the node done (status + intent) server-side; its engine shuts down on next stop.","When this node owns a clean managed worktree already contained in its local base, the server closes its record with cleanup pending instead of blocking on `node worktree close`. A clean worktree whose exact tip exists on any branch on origin may also finalize while retaining its branch and checkout; uncommitted changes or a tip absent from origin still block with open_managed_worktree."]:[]]},run:i(async r=>{const s=p();let o=typeof r.body=="string"?r.body.trim():"";if(o===""&&(o=(await c()).trim()),o==="")throw new d({error:"missing_body",message:"no report body",field:"body",next:"Pass the body as an argument or on stdin."});const a=h();if(e==="final"&&r.force!==!0){let t=null;try{t=await a.getNode(s)}catch(n){n instanceof _&&n.status===404||l(n)}if(t!==null&&t.lifecycle==="resident"&&t.edges.subscribers.length===0)throw new d({error:"no_final_recipient",message:"This node is working directly with the user \u2014 it has no manager to submit a final result to. `push final` would end the conversation mid-stream.",next:'You almost certainly do NOT need to finish here \u2014 just keep working with the user. If the user has explicitly asked you to finish and close this node, confirm with them first, then rerun with `crtr push final --force "<result>"`.'})}try{const t=r.tier,n=await a.pushReport(s,{tier:e,body:o,...t===void 0?{}:{delivery_tier:t}});return{report_path:n.report_path,notified:n.notified,...n.transitioned!==void 0?{transitioned:n.transitioned}:{},...n.worktree_auto_dropped===!0?{worktree_auto_dropped:!0,worktree_auto_dropped_path:n.worktree_auto_dropped_path}:{}}}catch(t){l(t)}},"run"),render:i(r=>{const s=Array.isArray(r.notified)?r.notified.length:0,o=e==="final"?'Result recorded \u2014 node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.':`Progress report fanned to ${s} subscriber(s).`,a=r.worktree_auto_dropped===!0?`
5
+ - report: ${e.report}`},"render")})}i(v,"makeResultLeaf");function m(e){return u({name:e,description:f[e],whenToUse:_[e],help:{name:`push ${e}`,summary:f[e],params:[{kind:"stdin",name:"body",required:!0,constraint:"Report body (markdown). Pipe it from a single-quoted heredoc (`<<'EOF'`) to preserve literal bytes."},...e==="update"?[{kind:"flag",name:"tier",type:"enum",choices:["deferred","normal","urgent"],required:!1,default:"normal",constraint:"Delivery urgency: deferred holds for the receiver\u2019s next non-deferred wake; normal wakes normally; urgent steers a live receiver and wakes an idle receiver."}]:[{kind:"flag",name:"force",type:"bool",required:!1,default:!1,constraint:"Override the guard that blocks `push final` on a node the user is attending (a resident with no one to report up to). Only pass this after the user explicitly confirms they want this node finished."}]],output:[{name:"report",type:"string",required:!0,constraint:"Name of the written report document, `<node-id>/reports/<name>`."},{name:"notified",type:"string[]",required:!0,constraint:"Subscriber node ids that received an inbox pointer."},...e==="final"?[{name:"transitioned",type:"object",required:!1,constraint:"Present only for a final that flipped the node \u2014 { from, to } lifecycle-status transition applied server-side."},{name:"worktree_auto_dropped",type:"boolean",required:!1,constraint:"Present only when the server closed this node\u2019s managed-worktree record without requiring `node worktree close`; cleanup of an existing checkout remains pending (see worktree_auto_dropped_path)."},{name:"worktree_auto_dropped_path",type:"string",required:!1,constraint:"Present only alongside worktree_auto_dropped: the closed worktree path; an existing checkout remains until pending cleanup."}]:[]],outputKind:"object",effects:["Creates the report document `<node-id>/reports/<compact-ts>-<uuid8>-<kind>` (server-side).","Appends one inbox pointer per subscriber.",...e==="final"?["Marks the node done (status + intent) server-side; its engine shuts down on next stop.","When this node owns a clean managed worktree already contained in its local base, the server closes its record with cleanup pending instead of blocking on `node worktree close`. A clean worktree whose exact tip exists on any branch on origin may also finalize while retaining its branch and checkout; uncommitted changes or a tip absent from origin still block with open_managed_worktree."]:[]]},run:i(async r=>{const s=p();let o=typeof r.body=="string"?r.body.trim():"";if(o===""&&(o=(await c()).trim()),o==="")throw new d({error:"missing_body",message:"no report body",field:"body",next:"Pass the body as an argument or on stdin."});const a=h();if(e==="final"&&r.force!==!0){let t=null;try{t=await a.getNode(s)}catch(n){n instanceof k&&n.status===404||l(n)}if(t!==null&&t.lifecycle==="resident"&&t.edges.subscribers.length===0)throw new d({error:"no_final_recipient",message:"This node is working directly with the user \u2014 it has no manager to submit a final result to. `push final` would end the conversation mid-stream.",next:'You almost certainly do NOT need to finish here \u2014 just keep working with the user. If the user has explicitly asked you to finish and close this node, confirm with them first, then rerun with `crtr push final --force "<result>"`.'})}try{const t=r.tier,n=await a.pushReport(s,{tier:e,body:o,...t===void 0?{}:{delivery_tier:t}});return{report:n.report,notified:n.notified,...n.transitioned!==void 0?{transitioned:n.transitioned}:{},...n.worktree_auto_dropped===!0?{worktree_auto_dropped:!0,worktree_auto_dropped_path:n.worktree_auto_dropped_path}:{}}}catch(t){l(t)}},"run"),render:i(r=>{const s=Array.isArray(r.notified)?r.notified.length:0,o=e==="final"?'Result recorded \u2014 node finished; its engine shuts down on next stop. Nothing more to do here: STOP your turn immediately. Reply with just "Done." and nothing else.':`Progress report fanned to ${s} subscriber(s).`,a=r.worktree_auto_dropped===!0?`
6
6
 
7
7
  Closed a clean managed-worktree record at ${String(r.worktree_auto_dropped_path)} \u2014 nothing to land; cleanup remains pending if the checkout still exists.`:"";return`${o}
8
8
 
9
- - report: ${r.report_path}${a}`},"render")})}i(m,"makePushLeaf");function R(){return b({name:"push",rootEntry:{concept:"the one verb up the graph \u2014 a node reports to whoever subscribes to it",desc:"push an update or final report to your subscribers",useWhen:"sharing progress, raising an alert, or finishing your work"},help:{name:"push",summary:"push a report to your subscribers",model:"A push writes a markdown report to the node's reports/ history and fans a lightweight pointer to every subscriber's inbox. Delivery inlines reports under 1,000 characters; each report ref is read with `crtr canvas history read <ref>`. Nothing is pushed automatically \u2014 the feed contains only what a node pushes explicitly, so push whenever you want a manager to see something. Pipe markdown via a single-quoted heredoc so it reaches the report literally. `push final` is how ANY node finishes: write the canonical result, mark done, close the window."},children:[m("update"),m("final"),v()]})}i(R,"registerPush");export{R as registerPush};
9
+ - report: ${r.report}${a}`},"render")})}i(m,"makePushLeaf");function R(){return b({name:"push",rootEntry:{concept:"the one verb up the graph \u2014 a node reports to whoever subscribes to it",desc:"push an update or final report to your subscribers",useWhen:"sharing progress, raising an alert, or finishing your work"},help:{name:"push",summary:"push a report to your subscribers",model:"A push writes a report document the node owns and fans a lightweight pointer to every subscriber's inbox. Delivery inlines reports under 1,000 characters; a longer report is read with `crtr canvas read <name>`. Point at documents you wrote as `[[<node-id>/<name>]]`, never as a file path. Nothing is pushed automatically \u2014 the feed contains only what a node pushes explicitly, so push whenever you want a manager to see something. Pipe markdown via a single-quoted heredoc so it reaches the report literally. `push final` is how ANY node finishes: write the canonical result, mark done, close the window."},children:[m("update"),m("final"),v()]})}i(R,"registerPush");export{R as registerPush};
@@ -1 +1 @@
1
- var j=Object.defineProperty;var i=(t,e)=>j(t,"name",{value:e,configurable:!0});import{defineBranch as T,defineLeaf as u}from"../../core/command.js";import{requirePersonCli as p}from"../broker-permissions.js";import{InvalidRawSettingsError as q,readConfig as g,readRawSettingsForTarget as L,replaceRawSettingsForTarget as R,updateConfig as P,persistModelLadders as N,configPath as _}from"../../core/config.js";import{usage as o,notFound as h}from"../../core/errors.js";import{requireScopeRoot as O}from"../../core/scope.js";import{resolveScope as m}from"./shared.js";import{resolveProfileOperand as C}from"../../core/profiles/manifest.js";import{SettingsRevisionConflictError as E}from"../../core/scoped-state/settings.js";import{InputError as f}from"../../core/io.js";import{SCOPE_CONFIG_KEYS as U,USER_SETTINGS as $,findUserSetting as y}from"../../core/user-settings.js";const J=U.join(", "),M=$.map(t=>`${t.key} (${t.valueConstraint})`).join(", "),I=new Set(["anthropic","openai"]),x=new Set(["ultra","strong","medium","light"]);function w(t){return I.has(t)}i(w,"isModelProvider");function A(t){return x.has(t)}i(A,"isModelStrength");function b(t,e){const n=e.split(".");let r=t;for(const s of n){if(r===null||typeof r!="object")return;r=r[s]}return r}i(b,"getNestedValue");function F(t){return t==="true"?!0:t==="false"?!1:/^-?\d+$/.test(t)?parseInt(t,10):t}i(F,"parseConfigValue");function v(t,e){if(t.split(".",1)[0]==="brokerThresholds"&&e!=="user")throw o("brokerThresholds are available only in user scope")}i(v,"assertUserScopeBrokerThresholds");function k(t,e){if(t.split(".",1)[0]==="lifecycle"&&e!=="user")throw o("lifecycle settings are available only in user scope")}i(k,"assertUserScopeLifecycle");function K(t,e){if(t==="working_gerunds"&&e!=="user")throw o("working_gerunds is available only in user scope")}i(K,"assertWorkingGerundsScope");function D(t,e){if(t==="whip_messages"&&e!=="user")throw o("whip_messages are available only in user scope")}i(D,"assertWhipMessagesScope");function G(t,e){if(y(t)!==void 0&&e!=="user")throw o(`${t} is available only in user scope`)}i(G,"assertUserSettingScope");function Q(t,e){const n=t.split(".");if(n[0]!=="modelLadders")return null;if(n.length===2&&n[1]==="defaultProvider"){if(!w(e))throw o("modelLadders.defaultProvider must be anthropic or openai");return{defaultProvider:e}}if(n.length===3){const r=n[1],s=n[2];if(!w(r))throw o("modelLadders provider must be anthropic or openai");if(!A(s))throw o("modelLadders strength must be ultra, strong, medium, or light");if(e.trim()==="")throw o(`modelLadders.${r}.${s} cannot be empty`);return{[r]:{[s]:e}}}throw o(`unsupported key path for set: ${t}`)}i(Q,"modelLadderPatch");function S(t){const e=t.scope;if(e==="project")throw o("project settings remain a JSON file; use `crtr sys config set` or `crtr sys config path --scope project`.");const n=t.profile;if(e==="user"){if(n!==void 0)throw o("--profile is available only with --scope profile.");return{scope:"user"}}if(n===void 0)throw o("--profile is required with --scope profile.");return{scope:"profile",profileId:C(n).profileId}}i(S,"rawSettingsTarget");function W(t){let e;try{e=JSON.parse(t)}catch{throw new f({error:"invalid_request",message:"stdin must be valid JSON",field:"stdin",next:"Pipe one complete JSON object on stdin."})}if(e===null||typeof e!="object"||Array.isArray(e))throw new f({error:"invalid_request",message:"stdin must be a JSON object",field:"stdin",next:"Pipe one complete JSON object on stdin."});return e}i(W,"parseRawSettings");function B(t,e,n,r){const s=e.split("."),c=s[0];if(e==="working_gerunds"||e==="whip_messages"){let a;try{a=JSON.parse(n)}catch{throw o(`${e} must be a JSON array of non-empty strings`)}if(!Array.isArray(a)||a.length===0||!a.every(d=>typeof d=="string"&&d.trim()!==""))throw o(`${e} must be a non-empty JSON array of non-empty strings`);t[e]=a.map(d=>d.trim());return}if(c==="keybindings")throw o("keybindings are edited only through `crtr sys settings`");if(c==="modelLadders")throw o("modelLadders keys are written through persistModelLadders, not this path");const l=y(e);if(l!==void 0){const a=l.setFromString(t,n);if(a!==null)throw o(a);return}if(c==="brokerThresholds"){if(s.length!==2||s[1]!=="warning"&&s[1]!=="automaticReviveCap")throw o("brokerThresholds key must be warning or automaticReviveCap");if(typeof r!="number"||!Number.isFinite(r)||r<1)throw o(`brokerThresholds.${s[1]} must be an integer >= 1`);const a=Math.floor(r);if(s[1]==="warning"&&a>t.brokerThresholds.automaticReviveCap)throw o("brokerThresholds.warning must be <= brokerThresholds.automaticReviveCap");if(s[1]==="automaticReviveCap"&&a<t.brokerThresholds.warning)throw o("brokerThresholds.automaticReviveCap must be >= brokerThresholds.warning");t.brokerThresholds[s[1]]=a;return}if(c==="lifecycle"){if(s.length!==2||s[1]!=="unattendedParkMs")throw o("lifecycle key must be unattendedParkMs");if(typeof r!="number"||!Number.isFinite(r)||r<1)throw o("lifecycle.unattendedParkMs must be an integer >= 1");t.lifecycle.unattendedParkMs=Math.floor(r);return}throw o(`unsupported key path for set: ${e}`)}i(B,"setNestedValue");const H=u({name:"get",description:"read a config value by key",whenToUse:"you want to inspect one config value \u2014 including the whole user keybindings object \u2014 optionally from a specific scope. Use sys settings to edit keybindings and sys config set for supported scalar settings.",help:{name:"sys config get",summary:"read a config value by dotted key",params:[{kind:"positional",name:"key",type:"string",required:!0,constraint:`Dotted key path. Top-level keys: ${J}. brokerThresholds and lifecycle are user-only; keybindings is readable only as the whole user-scope object and editable only through sys settings.`},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Scope to read from. Default: user."}],output:[{name:"key",type:"string",required:!0,constraint:"Echo of input key."},{name:"value",type:"unknown",required:!0,constraint:"The resolved value. Type depends on the key."},{name:"scope",type:"string",required:!0,constraint:"Scope the value was read from."}],outputKind:"object",effects:["None. Read-only."]},run:i(async t=>{p();const e=t.key,n=m(t.scope);if(v(e,n),k(e,n),e.startsWith("keybindings.")||e==="keybindings"&&n!=="user")throw h("keybindings are available only as the whole user-scope object");const r=g(n),s=b(r,e);if(s===void 0)throw h(`config key not found: ${e}`);return{key:e,value:s,scope:n}},"run")}),V=u({name:"set",description:"write a config value by key",whenToUse:"you want to change a supported crtr setting in user or project scope. Use sys settings instead for keybindings, and sys config get to inspect values.",help:{name:"sys config set",summary:"write a config value by dotted key",params:[{kind:"positional",name:"key",type:"string",required:!0,constraint:`Dotted key path. User-scope scalar settings: ${M}. Also supported: working_gerunds and whip_messages (non-empty JSON string arrays), brokerThresholds.warning and brokerThresholds.automaticReviveCap (user scope; integer >= 1), lifecycle.unattendedParkMs (user scope; integer ms >= 1), modelLadders.defaultProvider, and modelLadders.<anthropic|openai>.<ultra|strong|medium|light>. Keybindings are edited only through sys settings. For arbitrary raw user or profile documents, use sys config get-raw and set-raw.`},{kind:"flag",name:"value",type:"string",required:!0,constraint:"value VALUE \u2014 string, required. working_gerunds and whip_messages accept JSON arrays; other values are stored as-is if quoted and coerced to number or boolean when unambiguous."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Scope to write to. Default: user. Project scope is supported only for modelLadders."}],output:[{name:"value",type:"unknown",required:!0,constraint:"Resolved value as written after parsing and setting-specific coercion."},{name:"scope",type:"string",required:!0,constraint:"Scope the value was written to."}],outputKind:"object",effects:["Writes the updated value through the target scope\u2019s configuration storage."]},run:i(async t=>{p();const e=t.key,n=t.value,r=m(t.scope);v(e,r),k(e,r),K(e,r),D(e,r),G(e,r);const s=F(n),c=Q(e,n),l=c!==null?(N(O(r),c),g(r)):P(r,d=>B(d,e,n,s));return{value:b(l,e),scope:r}},"run")}),z=u({name:"get-raw",description:"read one raw SQL-backed settings document and revision",whenToUse:"you need the exact stored user or profile settings document before replacing it with set-raw.",help:{name:"sys config get-raw",summary:"read one raw user or profile settings document",params:[{kind:"flag",name:"scope",type:"enum",choices:["user","profile","project"],required:!0,constraint:"SQL-backed target: user or profile. project is rejected because its settings remain a JSON file."},{kind:"flag",name:"profile",type:"string",required:!1,constraint:"Profile id or name to target. Required with --scope profile; rejected with --scope user or project."}],output:[{name:"revision",type:"string",required:!0,constraint:"Opaque revision token for set-raw. absent means the settings row does not exist."},{name:"settings",type:"object | null",required:!0,constraint:"Exact stored settings document, or null when no row exists."}],outputKind:"object",effects:["None. Read-only."]},run:i(async t=>(p(),L(S(t))),"run")}),Y=u({name:"set-raw",description:"replace one raw SQL-backed settings document at a revision",whenToUse:"you have a complete user or profile settings document from get-raw and must replace it without losing a concurrent change.",help:{name:"sys config set-raw",summary:"atomically replace one raw user or profile settings document",params:[{kind:"flag",name:"scope",type:"enum",choices:["user","profile","project"],required:!0,constraint:"SQL-backed target: user or profile. project is rejected because its settings remain a JSON file."},{kind:"flag",name:"profile",type:"string",required:!1,constraint:"Profile id or name to target. Required with --scope profile; rejected with --scope user or project."},{kind:"flag",name:"if-revision",type:"string",required:!0,constraint:"Revision returned by get-raw. Required; use absent only when get-raw reported no settings row."},{kind:"stdin",name:"settings",required:!0,allowPositional:!1,constraint:"One complete JSON object. It replaces the document exactly; values are not normalized or merged."}],output:[{name:"revision",type:"string",required:!0,constraint:"Revision token of the stored document after this operation."},{name:"changed",type:"boolean",required:!0,constraint:"Whether the stored document changed."}],outputKind:"object",effects:["Atomically replaces the SQL-backed settings document only when --if-revision matches its current revision."]},run:i(async t=>{p();const e=S(t),n=W(t.settings);try{return R(e,n,t.ifRevision)}catch(r){throw r instanceof E?new f({error:"settings_revision_conflict",message:"settings changed since the supplied revision",field:"if_revision",next:"Run `crtr sys config get-raw` again, reapply the intended transformation, and retry with its revision."}):r instanceof q?new f({error:"invalid_settings",message:r.message,field:"stdin",next:"Correct the document so crouter can merge it into resolved settings, then retry with a fresh revision."}):r}},"run")}),X=u({name:"path",description:"print the project config.json path",whenToUse:"you need the project config.json path for inspection or backup. User and profile settings use get-raw and set-raw instead.",help:{name:"sys config path",summary:"print the project config.json path",params:[{kind:"flag",name:"scope",type:"enum",choices:["project","user","profile"],required:!1,constraint:"Project is the only path-backed settings scope. user and profile are rejected because they use SQL-backed get-raw and set-raw. Default: project."}],output:[{name:"paths",type:"object[]",required:!0,constraint:'One {scope: "project", path} entry when the current project has a config file; otherwise empty.'}],outputKind:"object",effects:["None. Read-only."]},run:i(async t=>{p();const e=t.scope;if(e==="user"||e==="profile")throw o(`${e} settings are SQL-backed; use \`crtr sys config get-raw --scope ${e}\` instead.`);const n=_("project");return{paths:n===null?[]:[{scope:"project",path:n}]}},"run")}),ue=T({name:"config",description:"read and write configuration",whenToUse:"inspecting crtr settings, changing supported scalar values, replacing complete raw user or profile settings documents, or locating a project config.json. Keybinding changes belong in sys settings.",help:{name:"sys config",summary:"read and write crtr configuration, including model ladders and raw SQL-backed user/profile settings",model:"get and set resolve individual settings. get-raw and set-raw read and replace complete user or profile documents with a revision precondition. path applies only to project config.json."},children:[H,V,z,Y,X]});export{ue as configBranch};
1
+ var S=Object.defineProperty;var i=(t,e)=>S(t,"name",{value:e,configurable:!0});import{defineBranch as j,defineLeaf as u}from"../../core/command.js";import{InvalidRawSettingsError as T,readConfig as f,readRawSettingsForTarget as q,replaceRawSettingsForTarget as L,updateConfig as R,persistModelLadders as P,configPath as N}from"../../core/config.js";import{usage as o,notFound as g}from"../../core/errors.js";import{requireScopeRoot as _}from"../../core/scope.js";import{resolveScope as h}from"./shared.js";import{resolveProfileOperand as O}from"../../core/profiles/manifest.js";import{SettingsRevisionConflictError as E}from"../../core/scoped-state/settings.js";import{InputError as l}from"../../core/io.js";import{SCOPE_CONFIG_KEYS as C,USER_SETTINGS as U,findUserSetting as m}from"../../core/user-settings.js";const $=C.join(", "),J=U.map(t=>`${t.key} (${t.valueConstraint})`).join(", "),M=new Set(["anthropic","openai"]),I=new Set(["ultra","strong","medium","light"]);function y(t){return M.has(t)}i(y,"isModelProvider");function x(t){return I.has(t)}i(x,"isModelStrength");function w(t,e){const n=e.split(".");let r=t;for(const s of n){if(r===null||typeof r!="object")return;r=r[s]}return r}i(w,"getNestedValue");function A(t){return t==="true"?!0:t==="false"?!1:/^-?\d+$/.test(t)?parseInt(t,10):t}i(A,"parseConfigValue");function b(t,e){if(t.split(".",1)[0]==="brokerThresholds"&&e!=="user")throw o("brokerThresholds are available only in user scope")}i(b,"assertUserScopeBrokerThresholds");function v(t,e){if(t.split(".",1)[0]==="lifecycle"&&e!=="user")throw o("lifecycle settings are available only in user scope")}i(v,"assertUserScopeLifecycle");function F(t,e){if(t==="working_gerunds"&&e!=="user")throw o("working_gerunds is available only in user scope")}i(F,"assertWorkingGerundsScope");function K(t,e){if(t==="whip_messages"&&e!=="user")throw o("whip_messages are available only in user scope")}i(K,"assertWhipMessagesScope");function D(t,e){if(m(t)!==void 0&&e!=="user")throw o(`${t} is available only in user scope`)}i(D,"assertUserSettingScope");function G(t,e){const n=t.split(".");if(n[0]!=="modelLadders")return null;if(n.length===2&&n[1]==="defaultProvider"){if(!y(e))throw o("modelLadders.defaultProvider must be anthropic or openai");return{defaultProvider:e}}if(n.length===3){const r=n[1],s=n[2];if(!y(r))throw o("modelLadders provider must be anthropic or openai");if(!x(s))throw o("modelLadders strength must be ultra, strong, medium, or light");if(e.trim()==="")throw o(`modelLadders.${r}.${s} cannot be empty`);return{[r]:{[s]:e}}}throw o(`unsupported key path for set: ${t}`)}i(G,"modelLadderPatch");function k(t){const e=t.scope;if(e==="project")throw o("project settings remain a JSON file; use `crtr sys config set` or `crtr sys config path --scope project`.");const n=t.profile;if(e==="user"){if(n!==void 0)throw o("--profile is available only with --scope profile.");return{scope:"user"}}if(n===void 0)throw o("--profile is required with --scope profile.");return{scope:"profile",profileId:O(n).profileId}}i(k,"rawSettingsTarget");function Q(t){let e;try{e=JSON.parse(t)}catch{throw new l({error:"invalid_request",message:"stdin must be valid JSON",field:"stdin",next:"Pipe one complete JSON object on stdin."})}if(e===null||typeof e!="object"||Array.isArray(e))throw new l({error:"invalid_request",message:"stdin must be a JSON object",field:"stdin",next:"Pipe one complete JSON object on stdin."});return e}i(Q,"parseRawSettings");function W(t,e,n,r){const s=e.split("."),c=s[0];if(e==="working_gerunds"||e==="whip_messages"){let a;try{a=JSON.parse(n)}catch{throw o(`${e} must be a JSON array of non-empty strings`)}if(!Array.isArray(a)||a.length===0||!a.every(d=>typeof d=="string"&&d.trim()!==""))throw o(`${e} must be a non-empty JSON array of non-empty strings`);t[e]=a.map(d=>d.trim());return}if(c==="keybindings")throw o("keybindings are edited only through `crtr sys settings`");if(c==="modelLadders")throw o("modelLadders keys are written through persistModelLadders, not this path");const p=m(e);if(p!==void 0){const a=p.setFromString(t,n);if(a!==null)throw o(a);return}if(c==="brokerThresholds"){if(s.length!==2||s[1]!=="warning"&&s[1]!=="automaticReviveCap")throw o("brokerThresholds key must be warning or automaticReviveCap");if(typeof r!="number"||!Number.isFinite(r)||r<1)throw o(`brokerThresholds.${s[1]} must be an integer >= 1`);const a=Math.floor(r);if(s[1]==="warning"&&a>t.brokerThresholds.automaticReviveCap)throw o("brokerThresholds.warning must be <= brokerThresholds.automaticReviveCap");if(s[1]==="automaticReviveCap"&&a<t.brokerThresholds.warning)throw o("brokerThresholds.automaticReviveCap must be >= brokerThresholds.warning");t.brokerThresholds[s[1]]=a;return}if(c==="lifecycle"){if(s.length!==2||s[1]!=="unattendedParkMs")throw o("lifecycle key must be unattendedParkMs");if(typeof r!="number"||!Number.isFinite(r)||r<1)throw o("lifecycle.unattendedParkMs must be an integer >= 1");t.lifecycle.unattendedParkMs=Math.floor(r);return}throw o(`unsupported key path for set: ${e}`)}i(W,"setNestedValue");const B=u({name:"get",description:"read a config value by key",whenToUse:"you want to inspect one config value \u2014 including the whole user keybindings object \u2014 optionally from a specific scope. Use sys settings to edit keybindings and sys config set for supported scalar settings.",help:{name:"sys config get",summary:"read a config value by dotted key",params:[{kind:"positional",name:"key",type:"string",required:!0,constraint:`Dotted key path. Top-level keys: ${$}. brokerThresholds and lifecycle are user-only; keybindings is readable only as the whole user-scope object and editable only through sys settings.`},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Scope to read from. Default: user."}],output:[{name:"key",type:"string",required:!0,constraint:"Echo of input key."},{name:"value",type:"unknown",required:!0,constraint:"The resolved value. Type depends on the key."},{name:"scope",type:"string",required:!0,constraint:"Scope the value was read from."}],outputKind:"object",effects:["None. Read-only."]},run:i(async t=>{const e=t.key,n=h(t.scope);if(b(e,n),v(e,n),e.startsWith("keybindings.")||e==="keybindings"&&n!=="user")throw g("keybindings are available only as the whole user-scope object");const r=f(n),s=w(r,e);if(s===void 0)throw g(`config key not found: ${e}`);return{key:e,value:s,scope:n}},"run")}),H=u({name:"set",description:"write a config value by key",whenToUse:"you want to change a supported crtr setting in user or project scope. Use sys settings instead for keybindings, and sys config get to inspect values.",help:{name:"sys config set",summary:"write a config value by dotted key",params:[{kind:"positional",name:"key",type:"string",required:!0,constraint:`Dotted key path. User-scope scalar settings: ${J}. Also supported: working_gerunds and whip_messages (non-empty JSON string arrays), brokerThresholds.warning and brokerThresholds.automaticReviveCap (user scope; integer >= 1), lifecycle.unattendedParkMs (user scope; integer ms >= 1), modelLadders.defaultProvider, and modelLadders.<anthropic|openai>.<ultra|strong|medium|light>. Keybindings are edited only through sys settings. For arbitrary raw user or profile documents, use sys config get-raw and set-raw.`},{kind:"flag",name:"value",type:"string",required:!0,constraint:"value VALUE \u2014 string, required. working_gerunds and whip_messages accept JSON arrays; other values are stored as-is if quoted and coerced to number or boolean when unambiguous."},{kind:"flag",name:"scope",type:"enum",choices:["user","project"],required:!1,constraint:"Scope to write to. Default: user. Project scope is supported only for modelLadders."}],output:[{name:"value",type:"unknown",required:!0,constraint:"Resolved value as written after parsing and setting-specific coercion."},{name:"scope",type:"string",required:!0,constraint:"Scope the value was written to."}],outputKind:"object",effects:["Writes the updated value through the target scope\u2019s configuration storage."]},run:i(async t=>{const e=t.key,n=t.value,r=h(t.scope);b(e,r),v(e,r),F(e,r),K(e,r),D(e,r);const s=A(n),c=G(e,n),p=c!==null?(P(_(r),c),f(r)):R(r,d=>W(d,e,n,s));return{value:w(p,e),scope:r}},"run")}),V=u({name:"get-raw",description:"read one raw SQL-backed settings document and revision",whenToUse:"you need the exact stored user or profile settings document before replacing it with set-raw.",help:{name:"sys config get-raw",summary:"read one raw user or profile settings document",params:[{kind:"flag",name:"scope",type:"enum",choices:["user","profile","project"],required:!0,constraint:"SQL-backed target: user or profile. project is rejected because its settings remain a JSON file."},{kind:"flag",name:"profile",type:"string",required:!1,constraint:"Profile id or name to target. Required with --scope profile; rejected with --scope user or project."}],output:[{name:"revision",type:"string",required:!0,constraint:"Opaque revision token for set-raw. absent means the settings row does not exist."},{name:"settings",type:"object | null",required:!0,constraint:"Exact stored settings document, or null when no row exists."}],outputKind:"object",effects:["None. Read-only."]},run:i(async t=>q(k(t)),"run")}),z=u({name:"set-raw",description:"replace one raw SQL-backed settings document at a revision",whenToUse:"you have a complete user or profile settings document from get-raw and must replace it without losing a concurrent change.",help:{name:"sys config set-raw",summary:"atomically replace one raw user or profile settings document",params:[{kind:"flag",name:"scope",type:"enum",choices:["user","profile","project"],required:!0,constraint:"SQL-backed target: user or profile. project is rejected because its settings remain a JSON file."},{kind:"flag",name:"profile",type:"string",required:!1,constraint:"Profile id or name to target. Required with --scope profile; rejected with --scope user or project."},{kind:"flag",name:"if-revision",type:"string",required:!0,constraint:"Revision returned by get-raw. Required; use absent only when get-raw reported no settings row."},{kind:"stdin",name:"settings",required:!0,allowPositional:!1,constraint:"One complete JSON object. It replaces the document exactly; values are not normalized or merged."}],output:[{name:"revision",type:"string",required:!0,constraint:"Revision token of the stored document after this operation."},{name:"changed",type:"boolean",required:!0,constraint:"Whether the stored document changed."}],outputKind:"object",effects:["Atomically replaces the SQL-backed settings document only when --if-revision matches its current revision."]},run:i(async t=>{const e=k(t),n=Q(t.settings);try{return L(e,n,t.ifRevision)}catch(r){throw r instanceof E?new l({error:"settings_revision_conflict",message:"settings changed since the supplied revision",field:"if_revision",next:"Run `crtr sys config get-raw` again, reapply the intended transformation, and retry with its revision."}):r instanceof T?new l({error:"invalid_settings",message:r.message,field:"stdin",next:"Correct the document so crouter can merge it into resolved settings, then retry with a fresh revision."}):r}},"run")}),Y=u({name:"path",description:"print the project config.json path",whenToUse:"you need the project config.json path for inspection or backup. User and profile settings use get-raw and set-raw instead.",help:{name:"sys config path",summary:"print the project config.json path",params:[{kind:"flag",name:"scope",type:"enum",choices:["project","user","profile"],required:!1,constraint:"Project is the only path-backed settings scope. user and profile are rejected because they use SQL-backed get-raw and set-raw. Default: project."}],output:[{name:"paths",type:"object[]",required:!0,constraint:'One {scope: "project", path} entry when the current project has a config file; otherwise empty.'}],outputKind:"object",effects:["None. Read-only."]},run:i(async t=>{const e=t.scope;if(e==="user"||e==="profile")throw o(`${e} settings are SQL-backed; use \`crtr sys config get-raw --scope ${e}\` instead.`);const n=N("project");return{paths:n===null?[]:[{scope:"project",path:n}]}},"run")}),ce=j({name:"config",description:"read and write configuration",whenToUse:"inspecting crtr settings, changing supported scalar values, replacing complete raw user or profile settings documents, or locating a project config.json. Keybinding changes belong in sys settings.",help:{name:"sys config",summary:"read and write crtr configuration, including model ladders and raw SQL-backed user/profile settings",model:"get and set resolve individual settings. get-raw and set-raw read and replace complete user or profile documents with a revision precondition. path applies only to project config.json."},children:[B,H,V,z,Y]});export{ce as configBranch};
@@ -1,48 +1,23 @@
1
- import type { DeliveryRecord } from '../../../../core/substrate/plan.js';
2
- import type { Rung, SurfaceEntry } from '../../../../core/substrate/schema.js';
1
+ import { type AdminDoc, type AdminRecord, type AdminRule } from './model.js';
3
2
  export interface ActionOutcome {
4
3
  ok: boolean;
5
4
  message: string;
6
- /** Canonical name the document answers to after the action — the new name
7
- * after a move. Absent when the action changed no document. */
5
+ /** The name the document answers to after the action — the new name after a
6
+ * move. Absent when the action changed no document. */
8
7
  name?: string;
9
8
  }
10
- /** The notice a mutating action shows instead of writing, or null when the
11
- * record is writable. The dossier marks a refusing record read-only so the
12
- * refusal is never a surprise. */
13
- export declare function readOnlyReason(record: DeliveryRecord, profileId: string | null): string | null;
14
- /** Replace one document's whole surfaces list — refused when the list on disk
15
- * holds more than the parsed list can carry back. */
16
- export declare function writeSurfaces(record: DeliveryRecord, profileId: string | null, surfaces: SurfaceEntry[], success: string): Promise<ActionOutcome>;
17
- /** The body exactly as it sits after the frontmatter fence, which is what the
18
- * revision path saves back. The PARSED body eats the blank line the fence opens
19
- * with, so seeding an editor from it would rewrite every doc it touched. */
20
- export declare function readBody(record: DeliveryRecord): string;
21
- /** Replace one document's whole body. */
22
- export declare function writeBody(record: DeliveryRecord, profileId: string | null, body: string): Promise<ActionOutcome>;
23
- /** Set or clear the document-level gate. An empty predicate clears it. */
24
- export declare function writeGate(record: DeliveryRecord, profileId: string | null, gate: string): Promise<ActionOutcome>;
25
- export declare function toggleFlag(record: DeliveryRecord, profileId: string | null, field: 'unlisted' | 'slash'): Promise<ActionOutcome>;
26
- export declare function writeRoutingLine(record: DeliveryRecord, profileId: string | null, line: string): Promise<ActionOutcome>;
27
- export declare function writeShortForm(record: DeliveryRecord, profileId: string | null, text: string): Promise<ActionOutcome>;
28
- /** Rename or relocate a document inside its own store. */
29
- export declare function moveDoc(record: DeliveryRecord, profileId: string | null, to: string): Promise<ActionOutcome>;
30
- /** The profile project entry whose ceiling reaches a document's store, or null
31
- * when the store carries the neutral ceiling because no entry covers it.
32
- *
33
- * Mirrors `resolveProjectScopeRoots`: pointers are walked in manifest order
34
- * and the FIRST entry whose ancestor walk reaches the store's SCOPE root — the
35
- * `.crouter/` dir one level above the `memory/` store — owns the ceiling, so
36
- * cycling any other entry would move a number the store never reads. */
37
- export declare function capOwnerFor(record: DeliveryRecord, profileId: string | null): {
38
- path: string;
39
- memory: Rung;
40
- } | null;
41
- export interface CapChange {
42
- path: string;
43
- memory: Rung;
44
- }
45
- /** Move a project relationship's automatic-delivery ceiling. */
46
- export declare function writeCap(profileId: string, path: string, memory: Rung): ActionOutcome & {
47
- change?: CapChange;
48
- };
9
+ /** The notice a write shows instead of writing, or null when the document is
10
+ * writable here. A shipped document belongs to its package and is replaced,
11
+ * not edited. */
12
+ export declare function readOnlyReason(record: AdminRecord): string | null;
13
+ /** Replace the document's whole rule list. An empty list clears it. */
14
+ export declare function writeRules(record: AdminRecord, rules: AdminRule[], success: string): Promise<ActionOutcome>;
15
+ export declare function toggleUnlisted(record: AdminRecord): Promise<ActionOutcome>;
16
+ export declare function writePreview(record: AdminRecord, line: string): Promise<ActionOutcome>;
17
+ /** The document's current body, read the way `crtr canvas read` reads it —
18
+ * which also records the read the following edit is based on. */
19
+ export declare function readBody(doc: AdminDoc): Promise<string>;
20
+ /** Replace the whole body. */
21
+ export declare function writeBody(record: AdminRecord, body: string): Promise<ActionOutcome>;
22
+ /** Rename a document under its own owner. */
23
+ export declare function moveDoc(record: AdminRecord, to: string): Promise<ActionOutcome>;
@@ -1,2 +1 @@
1
- var h=Object.defineProperty;var a=(e,n)=>h(e,"name",{value:n,configurable:!0});import{dirname as d}from"node:path";import{editLeaf as p}from"../../../memory/edit.js";import{literalBodySegment as g}from"../../../../core/memory/mutation-domain.js";import{moveLeaf as y}from"../../../memory/move.js";import{addProfileProject as $,loadProfileManifest as w}from"../../../../core/profiles/manifest.js";import{findProjectScopeRoots as k}from"../../../../core/scope.js";import{readText as x,realpathOrSelf as l}from"../../../../core/fs-utils.js";import{parseSubstrateFrontmatter as R}from"../../../../core/substrate/schema.js";import{surfaceEntryToFlag as b}from"./model.js";const A="editor";function f(e,n){if(e.doc.plugin!==void 0)return{refusal:`${e.name} belongs to the plugin \u201C${e.doc.plugin}\u201D and is read-only here \u2014 override it with \`crtr memory write ${e.name}\`.`};if(e.scope==="builtin")return{refusal:`${e.name} is a builtin document and is read-only here \u2014 override it with \`crtr memory write ${e.name}\`.`};if(e.scope==="project"){const t=e.source.store.ownerDir;return t===void 0?{refusal:`${e.name} resolves from a project store with no owning directory, which this page cannot address \u2014 edit it with \`crtr memory edit ${e.name} --dir <dir>\`.`}:{selector:{dir:t}}}return e.scope==="profile"?{selector:n===null?{scope:"profile"}:{scope:"profile",profile:n}}:e.scope==="user"||e.scope==="node"?{selector:{scope:e.scope}}:{refusal:`${e.name} resolves from the ${e.scope} scope, which this page cannot address.`}}a(f,"storeAddress");function F(e,n){const t=f(e,n);return"refusal"in t?t.refusal:null}a(F,"readOnlyReason");function m(e){return{ok:!1,message:e instanceof Error?e.message:String(e)}}a(m,"failure");async function i(e,n,t,r){const o=f(e,n);if("refusal"in o)return{ok:!1,message:o.refusal};const s=t.surfaces,u=[...t.unset??[]];s!==void 0&&s.length===0&&!u.includes("surfaces")&&u.push("surfaces");try{return await p.run({name:e.name,rationale:A,...o.selector,...s!==void 0&&s.length>0?{surface:s.map(b)}:{},...t.body===void 0?{}:{body:t.body},...t.gate===void 0?{}:{gate:t.gate},...t.unlisted===void 0?{}:{unlisted:!0},...t.slash===void 0?{}:{slash:!0},...t.whenAndWhyToRead===void 0?{}:{whenAndWhyToRead:t.whenAndWhyToRead},...t.shortForm===void 0?{}:{shortForm:t.shortForm},...u.length>0?{unset:u}:{}}),{ok:!0,message:r,name:e.name}}catch(c){return m(c)}}a(i,"runEdit");function G(e,n,t,r){const o=F(e,n)??j(e);return o!==null?Promise.resolve({ok:!1,message:o}):i(e,n,{surfaces:t},r)}a(G,"writeSurfaces");function j(e){const n=e.source.frontmatter?.surfaces;if(n==null)return null;const t=`a write replaces the whole list, so fix ${e.storePath} first`;if(!Array.isArray(n))return`The \`surfaces\` field of ${e.name} is not a list of entries \u2014 ${t}.`;for(const[r,o]of n.entries()){const s=S(e.kind,o);if(s!==null)return`Entry ${r+1} of ${e.name} ${s} \u2014 ${t}.`}return null}a(j,"unwritableSurfaces");const v={on:"on",at:"at",match:"match","match-frontmatter":"matchFrontmatter",gate:"gate"};function S(e,n){if(n===null||typeof n!="object"||Array.isArray(n))return"is not an entry object";const t=n,r=R({kind:e,surfaces:[t]})?.surfaces[0];if(r===void 0)return`(on ${JSON.stringify(t.on??null)}) is malformed and the parser drops it`;for(const o of Object.keys(t)){if(t[o]===void 0)continue;const s=v[o];if(s===void 0)return`carries an unknown key \`${o}\``;if(r[s]===void 0)return`carries a \`${o}\` the parser drops`}return null}a(S,"entryLoss");function J(e){const n=g(x(e.storePath));return n.startsWith(`
2
- `)?n.slice(1):n}a(J,"readBody");function M(e,n,t){return t.trim()===""?Promise.resolve({ok:!1,message:`An empty body is not an edit \u2014 remove ${e.name} with \`crtr memory delete\` instead.`}):i(e,n,{body:t},`Rewrote the body of ${e.name}.`)}a(M,"writeBody");function Y(e,n,t){const r=t.trim();return r===""?i(e,n,{unset:["gate"]},`Cleared the gate on ${e.name}.`):i(e,n,{gate:r},`Gated ${e.name} on ${r}.`)}a(Y,"writeGate");function _(e,n,t){return(t==="unlisted"?e.doc.unlisted:e.doc.slash)?i(e,n,{unset:[t]},`${e.name} is no longer ${t}.`):i(e,n,t==="unlisted"?{unlisted:!0}:{slash:!0},`${e.name} is now ${t}.`)}a(_,"toggleFlag");function z(e,n,t){const r=t.trim();return r===""?Promise.resolve({ok:!1,message:"A routing line cannot be empty \u2014 it is the document\u2019s contract."}):i(e,n,{whenAndWhyToRead:r},`Rewrote the routing line on ${e.name}.`)}a(z,"writeRoutingLine");function H(e,n,t){const r=t.trim();return r===""?i(e,n,{unset:["short-form"]},`Cleared the short form on ${e.name}.`):i(e,n,{shortForm:r},`Rewrote the short form on ${e.name}.`)}a(H,"writeShortForm");async function K(e,n,t){const r=t.trim();if(r==="")return{ok:!1,message:"Type the new canonical name."};const o=f(e,n);if("refusal"in o)return{ok:!1,message:o.refusal};try{const s=await y.run({name:e.name,to:r,...o.selector}),u=typeof s?.name=="string"?s.name:r;return{ok:!0,message:`${e.name} now answers to ${u}.`,name:u}}catch(s){return m(s)}}a(K,"moveDoc");function Q(e,n){if(n===null||e.scope!=="project")return null;const t=l(d(e.source.store.storeRoot));let r;try{r=w(n).manifest}catch{return null}for(const o of r.projects)if(k(o.path,null).some(s=>l(s)===t))return{path:o.path,memory:o.memory};return null}a(Q,"capOwnerFor");function U(e,n,t){try{return $(e,n,{memory:t}),{ok:!0,message:`${n} discloses up to "${t}".`,change:{path:n,memory:t}}}catch(r){return m(r)}}a(U,"writeCap");export{Q as capOwnerFor,K as moveDoc,J as readBody,F as readOnlyReason,_ as toggleFlag,M as writeBody,U as writeCap,Y as writeGate,z as writeRoutingLine,H as writeShortForm,G as writeSurfaces};
1
+ var u=Object.defineProperty;var n=(e,t)=>u(e,"name",{value:t,configurable:!0});import{ApiError as l}from"../../../../api/index.js";import{cliClient as a}from"../../../api-client.js";import{ruleToDTO as c}from"./model.js";const f="editor";function d(e){const t=e.doc;return t.shipped?`${t.displayName} ships with the plugin \u201C${t.ownerHandle}\u201D and is read-only here \u2014 override it with \`crtr doc write ${t.name} --owner user\`.`:null}n(d,"readOnlyReason");function m(e){return e instanceof l?{ok:!1,message:e.message}:{ok:!1,message:e instanceof Error?e.message:String(e)}}n(m,"failure");async function s(e,t,r){const i=d(e);if(i!==null)return{ok:!1,message:i};try{return await a().docs.edit(e.doc.object.id,{rationale:f,...t}),{ok:!0,message:r,name:e.doc.displayName}}catch(o){return m(o)}}n(s,"runEdit");function h(e,t,r){return s(e,t.length===0?{unset:["rules"]}:{rules:t.map(c)},r)}n(h,"writeRules");function v(e){const t=e.doc.displayName;return e.doc.unlisted?s(e,{unset:["unlisted"]},`${t} is listed again.`):s(e,{unlisted:!0},`${t} is now unlisted.`)}n(v,"toggleUnlisted");function $(e,t){const r=t.trim();return r===""?Promise.resolve({ok:!1,message:"A preview cannot be empty \u2014 it is what a reader decides to open the document on."}):s(e,{preview:r},`Rewrote the preview of ${e.doc.displayName}.`)}n($,"writePreview");async function N(e){const t=await a().objects.read(e.object.id);if(t.state!=="object"||t.type!=="document")throw new Error(`${e.displayName} is no longer a readable document.`);if(t.needs_merge)throw new Error(`${e.displayName} has diverged heads; merge them with \`crtr doc edit\` first.`);return t.bodies[0]??""}n(N,"readBody");function b(e,t){return t.trim()===""?Promise.resolve({ok:!1,message:`An empty body is not an edit \u2014 remove ${e.doc.displayName} with \`crtr doc delete\` instead.`}):s(e,{body:t},`Rewrote the body of ${e.doc.displayName}.`)}n(b,"writeBody");async function k(e,t){const r=t.trim();if(r==="")return{ok:!1,message:"Type the new name."};const i=d(e);if(i!==null)return{ok:!1,message:i};try{const o=await a().docs.move(e.doc.object.id,{new_name:r});return{ok:!0,message:`${e.doc.displayName} now answers to ${o.name}.`,name:o.name}}catch(o){return m(o)}}n(k,"moveDoc");export{k as moveDoc,N as readBody,d as readOnlyReason,v as toggleUnlisted,b as writeBody,$ as writePreview,h as writeRules};
@@ -1,38 +1,29 @@
1
- import type { SurfaceEvent } from '../../../../core/substrate/schema.js';
2
- import type { DeliveryRecord } from '../../../../core/substrate/plan.js';
3
1
  import type { NodeConfigSubject } from '../../../../core/substrate/subject-fields.js';
4
- import { type CapOwner } from './read-view.js';
2
+ import type { PlannedEvent } from '../resolve.js';
3
+ import { type AdminRecord } from './model.js';
5
4
  import type { DocRow } from './docs-panel.js';
6
- export type { CapOwner } from './read-view.js';
7
- /** A field of the focused document the shell can write. `entry` carries an
8
- * index into the document's whole surfaces list, not the focused event's
9
- * subset, because that list is what a write replaces. */
5
+ type SurfaceEvent = PlannedEvent;
6
+ /** A field of the focused document the shell can write. `rule` carries an
7
+ * index into the document's whole rule list, not the focused event's subset,
8
+ * because that list is what a write replaces. */
10
9
  export type DetailRow = {
11
- kind: 'entry';
10
+ kind: 'rule';
12
11
  at: number;
13
12
  } | {
14
- kind: 'add-entry';
13
+ kind: 'add-rule';
15
14
  } | {
16
- kind: 'gate';
15
+ kind: 'preview';
17
16
  } | {
18
17
  kind: 'unlisted';
19
- } | {
20
- kind: 'slash';
21
- } | {
22
- kind: 'routing';
23
- } | {
24
- kind: 'short-form';
25
18
  } | {
26
19
  kind: 'body';
27
- } | {
28
- kind: 'cap';
29
20
  } | {
30
21
  kind: 'move';
31
22
  };
32
23
  export declare class ContextDetailPanel {
33
24
  private row;
34
25
  private event;
35
- private capOwner;
26
+ private body;
36
27
  private readOnly;
37
28
  private subject;
38
29
  private rows;
@@ -44,14 +35,14 @@ export declare class ContextDetailPanel {
44
35
  * measure against real content rather than a counter nobody can see. */
45
36
  private lastLines;
46
37
  private lastHeight;
47
- setContext(row: DocRow | undefined, event: SurfaceEvent, capOwner: CapOwner | null, readOnly: string | null, subject: NodeConfigSubject | null): void;
38
+ setContext(row: DocRow | undefined, event: SurfaceEvent, readOnly: string | null, subject: NodeConfigSubject | null, body: string | undefined): void;
48
39
  /** True while the field list owns the pane, so the shell routes the write
49
40
  * letters and teaches them in the footer. */
50
41
  get editing(): boolean;
51
42
  get bodyOpen(): boolean;
52
43
  get selected(): DetailRow | undefined;
53
- /** The entry index a rung cycle or a removal would act on. */
54
- get selectedEntry(): number | undefined;
44
+ /** The rule index a level cycle or a removal would act on. */
45
+ get selectedRule(): number | undefined;
55
46
  /** `j`/`k`: a line of the read face, a field of the edit face. */
56
47
  move(delta: number): void;
57
48
  /** `ctrl-d`/`ctrl-u`: half a pane, so a long body is crossed in jumps a
@@ -59,8 +50,8 @@ export declare class ContextDetailPanel {
59
50
  page(direction: 1 | -1): void;
60
51
  /** `g`/`G`. */
61
52
  jump(to: 'top' | 'bottom'): void;
62
- /** `enter`: the document's own text, in place. False when there is no body,
63
- * so the shell leaves the key alone. */
53
+ /** `enter`: the document's own text, in place. The body is not in the plan,
54
+ * so the shell fetches it and hands it over through `setContext`. */
64
55
  openBody(): boolean;
65
56
  /** `e`: the field list. */
66
57
  edit(): void;
@@ -78,4 +69,5 @@ export declare class ContextDetailPanel {
78
69
  private editLines;
79
70
  }
80
71
  /** The editable rows for one document, in the order the panel draws them. */
81
- export declare function buildDetailRows(record: DeliveryRecord): DetailRow[];
72
+ export declare function buildDetailRows(record: AdminRecord): DetailRow[];
73
+ export {};
@@ -1 +1,2 @@
1
- var k=Object.defineProperty;var f=(a,t)=>k(a,"name",{value:t,configurable:!0});import{truncateToWidth as p,visibleWidth as v}from"@earendil-works/pi-tui";import{padAnsi as M,theme as s,wrapText as w}from"../../../../core/tui/panel.js";import{describeSurfaceEntry as D,plural as L}from"./model.js";import{bodyLineCount as b,renderDossierDelivery as S,renderDossierHeader as H,renderDossierRead as j}from"./read-view.js";class I{static{f(this,"ContextDetailPanel")}row;event="boot";capOwner=null;readOnly=null;subject=null;rows=[];index=0;face="read";open=!1;scroll=0;lastLines=1;lastHeight=1;setContext(t,e,i,c,r){const h=t?.key!==this.row?.key;this.row=t,this.event=e,this.capOwner=i,this.readOnly=c,this.subject=r,this.rows=t===void 0?[]:E(t.anchor),h&&(this.index=0,this.scroll=0,this.open=!1,this.face="read"),this.index=Math.max(0,Math.min(this.index,this.rows.length-1))}get editing(){return this.face==="edit"}get bodyOpen(){return this.open}get selected(){return this.face==="edit"?this.rows[this.index]:void 0}get selectedEntry(){const t=this.selected;return t?.kind==="entry"?t.at:void 0}move(t){if(this.face==="edit"){this.index=Math.max(0,Math.min(this.rows.length-1,this.index+t));return}this.scrollBy(t)}page(t){this.face!=="edit"&&this.scrollBy(t*Math.max(1,Math.floor(this.lastHeight/2)))}jump(t){this.face!=="edit"&&(this.scroll=t==="top"?0:this.maxScroll())}openBody(){return this.face==="edit"||this.row===void 0||b(this.record().doc.body)===0?!1:(this.open=!0,this.scroll=0,!0)}edit(){this.row!==void 0&&(this.face="edit",this.scroll=0)}back(){return this.face==="edit"?(this.face="read",this.scroll=0,!0):this.open?(this.open=!1,this.scroll=0,!0):!1}scrollBy(t){this.scroll=Math.max(0,Math.min(this.scroll+t,this.maxScroll()))}maxScroll(){return Math.max(0,this.lastLines-this.lastHeight)}record(){const t=this.row;return t.records.get(this.event)??t.anchor}context(){return{event:this.event,records:this.row?.records??new Map,capOwner:this.capOwner,readOnly:this.readOnly!==null,subject:this.subject}}render(t,e,i){if(this.row===void 0)return this.lastLines=1,this.lastHeight=e,$([s.fg("dim"," Select a document.")],e);const c=this.record(),r=this.face==="read"?{lines:j(c,this.context(),t,this.open),cursor:void 0}:this.editLines(c,t,i),h=r.lines,o=h.length>e,n=Math.max(1,o?e-1:e);this.lastLines=h.length,this.lastHeight=n;let d;r.cursor===void 0?(this.scroll=Math.max(0,Math.min(this.scroll,Math.max(0,h.length-n))),d=this.scroll):d=Math.min(Math.max(0,r.cursor-Math.floor(n/3)),Math.max(0,h.length-n));const l=$(h.slice(d,d+n),n);return o&&l.push(B(d+1,Math.min(h.length,d+n),h.length,t)),l}editLines(t,e,i){const c=this.context(),r=[...H(t,c,e),...S(t,c,e),""];let h=0;const o=f((l,m,y)=>{const O=[m,...l===this.index&&y!==void 0?T(y,e):[]];l===this.index&&(h=r.length);for(const x of O)r.push(l===this.index&&i?s.bg("selectedBg",M(p(x,e),e)):l===this.index?`${s.fg("accent","\u258C")}${p(x,Math.max(0,e-1))}`:` ${p(x,Math.max(0,e-1))}`)},"push");let n=0;r.push(s.fg("dim"," SURFACES"));const d=t.doc.surfaces;d.length===0&&r.push(s.fg("dim"," no entries \u2014 this document only appears in its listing"));for(const l of d){const m=D(l);o(n++,l.on===this.event?m:s.fg("dim",m))}return o(n++,s.fg("success","+ add a surface entry")),r.push(""),r.push(s.fg("dim"," DOCUMENT")),o(n++,u("gate",t.doc.gate===void 0?s.fg("dim","none"):JSON.stringify(t.doc.gate),e)),o(n++,u("unlisted",t.doc.unlisted?"yes":s.fg("dim","no"),e)),o(n++,u("slash",t.doc.slash?"yes":s.fg("dim","no"),e)),o(n++,u("routing",t.doc.whenAndWhyToRead,e)),o(n++,u("short form",t.doc.shortForm===""?s.fg("dim","none"):t.doc.shortForm,e)),o(n++,u("body",s.fg("dim",L(b(t.doc.body),"line","lines")),e),"opens in $EDITOR"),o(n++,u("profile cap",this.capOwner===null?s.fg("dim","uncapped"):`${this.capOwner.memory} ${s.fg("dim",this.capOwner.path)}`,e),this.capOwner===null?"no profile project governs this store":"the highest rung any document from this store can deliver at"),o(n++,u("canonical name",t.name,e)),r.push(` ${u("store path",s.fg("dim",t.storePath),Math.max(0,e-1))}`),{lines:r,cursor:h}}}function E(a){return[...a.doc.surfaces.map((e,i)=>({kind:"entry",at:i})),{kind:"add-entry"},{kind:"gate"},{kind:"unlisted"},{kind:"slash"},{kind:"routing"},{kind:"short-form"},{kind:"body"},{kind:"cap"},{kind:"move"}]}f(E,"buildDetailRows");const g=15;function u(a,t,e){const i=Math.max(1,e-g-2);return`${M(s.fg("dim",a),g)} ${p(t,i)}`}f(u,"field");function T(a,t){const e=Math.max(1,t-g-2);return w(`\u2014 ${a}`,e).map(i=>`${" ".repeat(g+1)}${s.fg("dim",i)}`)}f(T,"tailLines");function B(a,t,e,i){const c=`${a}\u2013${t} / ${e}`;return s.fg("dim",`${" ".repeat(Math.max(0,i-c.length))}${c}`)}f(B,"badge");function $(a,t){const e=[...a];for(;e.length<t;)e.push("");return e.slice(0,t).map(i=>v(i)===0?"":i)}f($,"fit");export{I as ContextDetailPanel,E as buildDetailRows};
1
+ var $=Object.defineProperty;var u=(r,e)=>$(r,"name",{value:e,configurable:!0});import{truncateToWidth as p,visibleWidth as w}from"@earendil-works/pi-tui";import{padAnsi as y,theme as n,wrapText as k}from"../../../../core/tui/panel.js";import{describeRule as D,plural as L}from"./model.js";import{renderDossierDelivery as H,renderDossierHeader as j,renderDossierRead as O}from"./read-view.js";class U{static{u(this,"ContextDetailPanel")}row;event="boot";body;readOnly=null;subject=null;rows=[];index=0;face="read";open=!1;scroll=0;lastLines=1;lastHeight=1;setContext(e,t,s,a,i){const l=e?.key!==this.row?.key;this.row=e,this.event=t,this.body=i,this.readOnly=s,this.subject=a,this.rows=e===void 0?[]:R(e.anchor),l&&(this.index=0,this.scroll=0,this.open=!1,this.face="read"),this.index=Math.max(0,Math.min(this.index,this.rows.length-1))}get editing(){return this.face==="edit"}get bodyOpen(){return this.open}get selected(){return this.face==="edit"?this.rows[this.index]:void 0}get selectedRule(){const e=this.selected;return e?.kind==="rule"?e.at:void 0}move(e){if(this.face==="edit"){this.index=Math.max(0,Math.min(this.rows.length-1,this.index+e));return}this.scrollBy(e)}page(e){this.face!=="edit"&&this.scrollBy(e*Math.max(1,Math.floor(this.lastHeight/2)))}jump(e){this.face!=="edit"&&(this.scroll=e==="top"?0:this.maxScroll())}openBody(){return this.face==="edit"||this.row===void 0?!1:(this.open=!0,this.scroll=0,!0)}edit(){this.row!==void 0&&(this.face="edit",this.scroll=0)}back(){return this.face==="edit"?(this.face="read",this.scroll=0,!0):this.open?(this.open=!1,this.scroll=0,!0):!1}scrollBy(e){this.scroll=Math.max(0,Math.min(this.scroll+e,this.maxScroll()))}maxScroll(){return Math.max(0,this.lastLines-this.lastHeight)}record(){const e=this.row;return e.records.get(this.event)??e.anchor}context(){return{event:this.event,records:this.row?.records??new Map,readOnly:this.readOnly!==null,body:this.body,subject:this.subject}}render(e,t,s){if(this.row===void 0)return this.lastLines=1,this.lastHeight=t,b([n.fg("dim"," Select a document.")],t);const a=this.record(),i=this.face==="read"?{lines:O(a,this.context(),e,this.open),cursor:void 0}:this.editLines(a,e,s),l=i.lines,d=l.length>t,o=Math.max(1,d?t-1:t);this.lastLines=l.length,this.lastHeight=o;let c;i.cursor===void 0?(this.scroll=Math.max(0,Math.min(this.scroll,Math.max(0,l.length-o))),c=this.scroll):c=Math.min(Math.max(0,i.cursor-Math.floor(o/3)),Math.max(0,l.length-o));const h=b(l.slice(c,c+o),o);return d&&h.push(T(c+1,Math.min(l.length,c+o),l.length,e)),h}editLines(e,t,s){const a=this.context(),i=[...j(e,a,t),...H(e,a,t),""];let l=0;const d=u((h,m,M)=>{const v=[m,...h===this.index&&M!==void 0?S(M,t):[]];h===this.index&&(l=i.length);for(const g of v)i.push(h===this.index&&s?n.bg("selectedBg",y(p(g,t),t)):h===this.index?`${n.fg("accent","\u258C")}${p(g,Math.max(0,t-1))}`:` ${p(g,Math.max(0,t-1))}`)},"push");let o=0;i.push(n.fg("dim"," RULES"));const c=e.doc.rules;c.length===0&&i.push(n.fg("dim"," no rules \u2014 this document only appears in its listing"));for(const h of c){const m=D(h);d(o++,h.on===this.event?m:n.fg("dim",m))}return d(o++,n.fg("success","+ add a delivery rule")),i.push(""),i.push(n.fg("dim"," DOCUMENT")),d(o++,f("preview",e.doc.preview===""?n.fg("dim","none"):e.doc.preview,t)),d(o++,f("unlisted",e.doc.unlisted?"yes":n.fg("dim","no"),t)),d(o++,f("body",n.fg("dim",this.body===void 0?"not read yet":L(B(this.body),"line","lines")),t),"opens in $EDITOR"),d(o++,f("name",e.doc.displayName,t),"renames the document under its own owner"),i.push(` ${f("owner",n.fg("dim",e.doc.ownerHandle),Math.max(0,t-1))}`),i.push(` ${f("object",n.fg("dim",e.doc.object.id),Math.max(0,t-1))}`),{lines:i,cursor:l}}}function R(r){return[...r.doc.rules.map((t,s)=>({kind:"rule",at:s})),{kind:"add-rule"},{kind:"preview"},{kind:"unlisted"},{kind:"body"},{kind:"move"}]}u(R,"buildDetailRows");function B(r){const e=r.replace(/\n+$/,"");return e===""?0:e.split(`
2
+ `).length}u(B,"bodyLines");const x=15;function f(r,e,t){const s=Math.max(1,t-x-2);return`${y(n.fg("dim",r),x)} ${p(e,s)}`}u(f,"field");function S(r,e){const t=Math.max(1,e-x-2);return k(`\u2014 ${r}`,t).map(s=>`${" ".repeat(x+1)}${n.fg("dim",s)}`)}u(S,"tailLines");function T(r,e,t,s){const a=`${r}\u2013${e} / ${t}`;return n.fg("dim",`${" ".repeat(Math.max(0,s-a.length))}${a}`)}u(T,"badge");function b(r,e){const t=[...r];for(;t.length<e;)t.push("");return t.slice(0,e).map(s=>w(s)===0?"":s)}u(b,"fit");export{U as ContextDetailPanel,R as buildDetailRows};
@@ -1,6 +1,6 @@
1
- import { type SurfaceEvent } from '../../../../core/substrate/schema.js';
2
- import type { EffectiveDeliveryRecord } from '../resolve.js';
3
- import { PlanSet } from './model.js';
1
+ import { type PlannedEvent } from '../resolve.js';
2
+ import { PlanSet, type AdminRecord } from './model.js';
3
+ type SurfaceEvent = PlannedEvent;
4
4
  import { type Filters } from './list-view.js';
5
5
  /** One physical document across every event. `records` is sparse: an event
6
6
  * whose corpus never reaches this document has no record for it, and an event
@@ -11,8 +11,8 @@ export interface DocRow {
11
11
  /** The record for the focused event, or the first one any event carries —
12
12
  * every panel needs a document to describe even when the focused event's
13
13
  * corpus excludes it. */
14
- anchor: EffectiveDeliveryRecord;
15
- records: Map<SurfaceEvent, EffectiveDeliveryRecord>;
14
+ anchor: AdminRecord;
15
+ records: Map<SurfaceEvent, AdminRecord>;
16
16
  /** Present only in an event other than the focused one. */
17
17
  offEvent: boolean;
18
18
  }
@@ -53,10 +53,11 @@ export declare class ContextDocsPanel {
53
53
  private relayout;
54
54
  render(width: number, height: number, focused: boolean): string[];
55
55
  /** A directory header: a pure rollup of its whole subtree — how many of its
56
- * documents load, and what they cost together. */
56
+ * documents load. */
57
57
  private groupLine;
58
58
  private docLine;
59
59
  /** Pad rather than trim: this column sets the length of the divider drawn
60
60
  * beside it. */
61
61
  private fit;
62
62
  }
63
+ export {};
@@ -1 +1 @@
1
- var v=Object.defineProperty;var u=(r,t)=>v(r,"name",{value:t,configurable:!0});import{truncateToWidth as l,visibleWidth as k}from"@earendil-works/pi-tui";import{padAnsi as p,theme as o,visibleRange as M}from"../../../../core/tui/panel.js";import{SURFACE_EVENTS as T}from"../../../../core/substrate/schema.js";import{deliveryStateOf as S,formatCost as L,plural as N,stateLabel as D}from"./model.js";import{NO_FILTERS as E,buildListView as I,groupKeysOf as O}from"./list-view.js";function G(r,t){const e=new Map,i=[],n=u(s=>{const d=r.peek(s);if(d!==void 0)for(const h of d.docs){const c=h.storePath,a=e.get(c);if(a===void 0){e.set(c,{key:c,name:h.name,anchor:h,records:new Map([[s,h]]),offEvent:s!==t}),i.push(c);continue}a.records.set(s,h),s===t&&(a.anchor=h,a.offEvent=!1)}},"absorb");n(t);for(const s of T)s!==t&&n(s);return i.map(s=>e.get(s))}u(G,"buildRows");const m=10,b=6,C=2;class H{static{u(this,"ContextDocsPanel")}onChange;rows=[];filters=E;event="boot";lines=[];index=0;expanded=new Set;constructor(t){this.onChange=t}get selected(){const t=this.lines[this.index];if(t!==void 0)return t.kind==="doc"?t.row:t.first}get visibleCount(){return this.lines.reduce((t,e)=>t+(e.kind==="group"&&e.depth===0?e.docs:0),0)}get loadedCount(){return this.lines.reduce((t,e)=>t+(e.kind==="group"&&e.depth===0?e.rungs.content+e.rungs.preview+e.rungs.name:0),0)}setRows(t,e){this.rows=t,this.event=e;const i=O(t);for(const n of this.expanded)i.has(n)||this.expanded.delete(n);this.relayout()}setFilters(t){this.filters=t,this.relayout()}move(t){this.lines.length!==0&&(this.index=Math.max(0,Math.min(this.lines.length-1,this.index+t)),this.onChange())}get onGroup(){return this.lines[this.index]?.kind==="group"}toggleGroup(){const t=this.lines[this.index];t?.kind==="group"&&(this.expanded.has(t.key)?this.expanded.delete(t.key):this.expanded.add(t.key),this.relayout(),this.onChange())}relayout(){const t=this.lines[this.index];this.lines=I(this.rows,this.filters,this.expanded,this.event);const e=t===void 0?-1:this.lines.findIndex(i=>i.kind===t.kind&&i.key===t.key);this.index=e>=0?e:Math.max(0,Math.min(this.index,this.lines.length-1))}render(t,e,i){const n=[],s=Math.max(1,t-m-b-3),d=this.filters.query===""?"DOCUMENTS":`/${this.filters.query}`,h=this.filters.query===""?`${this.loadedCount} of ${this.visibleCount} load on ${this.event}`:N(this.visibleCount,"match","matches"),c=`${o.fg("accent",o.bold(d))} ${o.fg("dim",h)}`;if(n.push(` ${p(l(c,s),s)} ${g(o.fg("dim","loads"),m)} ${g(o.fg("dim","tokens"),b)}`),this.lines.length===0)return n.push("",o.fg("dim",' Nothing matches this question \u2014 cycle a facet back to "any".')),this.fit(n,e);const a=Math.max(1,e-n.length),y=M(this.lines.length,this.index,a);for(let f=y.start;f<y.end;f+=1){const x=this.lines[f],$=x.kind==="group"?this.groupLine(x,s):this.docLine(x,s);n.push(f===this.index&&i?o.bg("selectedBg",p($,t)):f===this.index?`${o.fg("accent","\u258C")}${l($.slice(1),Math.max(0,t-1))}`:$)}return this.fit(n,e)}groupLine(t,e){const i=t.expanded?"\u25BE":"\u25B8",n=`${" ".repeat(t.depth*C)}${i} ${o.bold(t.label)}`,s=t.rungs.content+t.rungs.preview+t.rungs.name,d=o.fg(s>0?"success":"dim",`${s} of ${t.docs}`);return` ${p(l(n,e),e)} ${g(d,m)} ${w(t.cost)}`}docLine(t,e){const i=l(`${" ".repeat(t.depth*C)}${t.label}`,e),n=t.row.records.get(this.event),s=D(n,S(n)),d=s.text===""?"":o.fg(s.tone,s.text);return` ${p(i,e)} ${g(d,m)} ${w(t.cost)}`}fit(t,e){for(;t.length<e;)t.push("");return t.slice(0,e).map(i=>k(i)===0?"":i)}}function g(r,t){const e=k(r);return e>=t?l(r,t):`${" ".repeat(t-e)}${r}`}u(g,"field");function w(r){return g(o.fg("dim",L(r)),b)}u(w,"cost");export{H as ContextDocsPanel,G as buildRows};
1
+ var w=Object.defineProperty;var l=(r,t)=>w(r,"name",{value:t,configurable:!0});import{truncateToWidth as f,visibleWidth as y}from"@earendil-works/pi-tui";import{padAnsi as p,theme as o,visibleRange as C}from"../../../../core/tui/panel.js";import{PLANNED_EVENTS as v}from"../resolve.js";import{deliveryStateOf as M,plural as N,stateLabel as L}from"./model.js";import{NO_FILTERS as T,buildListView as S,groupKeysOf as D}from"./list-view.js";function W(r,t){const e=new Map,i=[],n=l(s=>{const d=r.peek(s);if(d!==void 0)for(const h of d.docs){const c=h.doc.object.id,a=e.get(c);if(a===void 0){e.set(c,{key:c,name:h.doc.displayName,anchor:h,records:new Map([[s,h]]),offEvent:s!==t}),i.push(c);continue}a.records.set(s,h),s===t&&(a.anchor=h,a.offEvent=!1)}},"absorb");n(t);for(const s of v)s!==t&&n(s);return i.map(s=>e.get(s))}l(W,"buildRows");const g=10,k=2;class _{static{l(this,"ContextDocsPanel")}onChange;rows=[];filters=T;event="boot";lines=[];index=0;expanded=new Set;constructor(t){this.onChange=t}get selected(){const t=this.lines[this.index];if(t!==void 0)return t.kind==="doc"?t.row:t.first}get visibleCount(){return this.lines.reduce((t,e)=>t+(e.kind==="group"&&e.depth===0?e.docs:0),0)}get loadedCount(){return this.lines.reduce((t,e)=>t+(e.kind==="group"&&e.depth===0?e.rungs.content+e.rungs.preview+e.rungs.name:0),0)}setRows(t,e){this.rows=t,this.event=e;const i=D(t);for(const n of this.expanded)i.has(n)||this.expanded.delete(n);this.relayout()}setFilters(t){this.filters=t,this.relayout()}move(t){this.lines.length!==0&&(this.index=Math.max(0,Math.min(this.lines.length-1,this.index+t)),this.onChange())}get onGroup(){return this.lines[this.index]?.kind==="group"}toggleGroup(){const t=this.lines[this.index];t?.kind==="group"&&(this.expanded.has(t.key)?this.expanded.delete(t.key):this.expanded.add(t.key),this.relayout(),this.onChange())}relayout(){const t=this.lines[this.index];this.lines=S(this.rows,this.filters,this.expanded,this.event);const e=t===void 0?-1:this.lines.findIndex(i=>i.kind===t.kind&&i.key===t.key);this.index=e>=0?e:Math.max(0,Math.min(this.index,this.lines.length-1))}render(t,e,i){const n=[],s=Math.max(1,t-g-2),d=this.filters.query===""?"DOCUMENTS":`/${this.filters.query}`,h=this.filters.query===""?`${this.loadedCount} of ${this.visibleCount} load on ${this.event}`:N(this.visibleCount,"match","matches"),c=`${o.fg("accent",o.bold(d))} ${o.fg("dim",h)}`;if(n.push(` ${p(f(c,s),s)} ${$(o.fg("dim","loads"),g)}`),this.lines.length===0)return n.push("",o.fg("dim",' Nothing matches this question \u2014 cycle a facet back to "any".')),this.fit(n,e);const a=Math.max(1,e-n.length),b=C(this.lines.length,this.index,a);for(let u=b.start;u<b.end;u+=1){const m=this.lines[u],x=m.kind==="group"?this.groupLine(m,s):this.docLine(m,s);n.push(u===this.index&&i?o.bg("selectedBg",p(x,t)):u===this.index?`${o.fg("accent","\u258C")}${f(x.slice(1),Math.max(0,t-1))}`:x)}return this.fit(n,e)}groupLine(t,e){const i=t.expanded?"\u25BE":"\u25B8",n=`${" ".repeat(t.depth*k)}${i} ${o.bold(t.label)}`,s=t.rungs.content+t.rungs.preview+t.rungs.name,d=o.fg(s>0?"success":"dim",`${s} of ${t.docs}`);return` ${p(f(n,e),e)} ${$(d,g)}`}docLine(t,e){const i=f(`${" ".repeat(t.depth*k)}${t.label}`,e),n=t.row.records.get(this.event),s=L(n,M(n)),d=s.text===""?"":o.fg(s.tone,s.text);return` ${p(i,e)} ${$(d,g)}`}fit(t,e){for(;t.length<e;)t.push("");return t.slice(0,e).map(i=>y(i)===0?"":i)}}function $(r,t){const e=y(r);return e>=t?f(r,t):`${" ".repeat(t-e)}${r}`}l($,"field");export{_ as ContextDocsPanel,W as buildRows};
@@ -1,10 +1,14 @@
1
- import type { MemoryScope } from '../../../../core/memory-resolver.js';
2
- import type { DocKind, Rung, SurfaceEvent } from '../../../../core/substrate/schema.js';
1
+ import type { DocKind, Rung } from '../../../../core/substrate/schema.js';
2
+ import type { PlannedEvent } from '../resolve.js';
3
3
  import type { DocRow } from './docs-panel.js';
4
+ import type { AdminRecord } from './model.js';
5
+ type SurfaceEvent = PlannedEvent;
6
+ /** The owner types a document can belong to. */
7
+ export declare const OWNER_TYPES: readonly ["node", "user", "profile", "repo", "app"];
4
8
  export type RungFacet = 'any' | Exclude<Rung, 'none'> | 'silent';
5
- export type OriginFacet = 'any' | MemoryScope;
9
+ export type OriginFacet = 'any' | (typeof OWNER_TYPES)[number];
6
10
  export type KindFacet = 'any' | DocKind;
7
- export type StateFacet = 'any' | 'delivering' | 'gated' | 'shadowed' | 'no-entry';
11
+ export type StateFacet = 'any' | 'delivering' | 'gated' | 'shadowed' | 'no-rule';
8
12
  /** The question the page is asking. Rung asks what arrives, state asks why it
9
13
  * does not, and the two compose. Every facet is "any" by default, so the page
10
14
  * opens on the whole corpus. */
@@ -18,7 +22,7 @@ export interface Filters {
18
22
  }
19
23
  export declare const NO_FILTERS: Filters;
20
24
  /** One drawn line. A group carries what its whole subtree adds up to, so a
21
- * collapsed list still states where the corpus and its cost sit. `depth` is
25
+ * collapsed list still states where the corpus and its deliveries sit. `depth` is
22
26
  * how many name segments sit above the line, which the renderer spends on
23
27
  * indent. */
24
28
  export type ListLine = {
@@ -28,7 +32,6 @@ export type ListLine = {
28
32
  depth: number;
29
33
  docs: number;
30
34
  rungs: Record<Exclude<Rung, 'none'>, number>;
31
- cost: number;
32
35
  expanded: boolean;
33
36
  /** The document the dossier describes while the cursor rests on the
34
37
  * header: this directory's own document when it has one, else the first
@@ -41,7 +44,6 @@ export type ListLine = {
41
44
  row: DocRow;
42
45
  label: string;
43
46
  depth: number;
44
- cost: number;
45
47
  };
46
48
  /** Every group key the rows can produce — one per proper name prefix, since a
47
49
  * prefix exists only because something sits under it — so collapse state can
@@ -55,8 +57,6 @@ export declare function groupKeysOf(rows: readonly DocRow[]): Set<string>;
55
57
  * ancestor chain of every surviving match, without touching `expanded` — so
56
58
  * clearing the query restores what the user collapsed. */
57
59
  export declare function buildListView(rows: readonly DocRow[], filters: Filters, expanded: ReadonlySet<string>, event: SurfaceEvent): ListLine[];
58
- /** What the whole filtered set costs, split by the rung it arrives at. */
59
- export declare function costTotals(rows: readonly DocRow[], event: SurfaceEvent): {
60
- total: number;
61
- byRung: Record<Exclude<Rung, 'none'>, number>;
62
- };
60
+ /** `user` is the person owner; every other facet is the owner object's type. */
61
+ export declare function ownerTypeOf(record: AdminRecord): string;
62
+ export {};
@@ -1 +1 @@
1
- var w=Object.defineProperty;var f=(n,o)=>w(n,"name",{value:o,configurable:!0});import{fuzzyMatch as v}from"../../../../core/tui/fuzzy.js";import{deliveredCost as g,rungCostsOf as R}from"./model.js";const z={rung:"any",origin:"any",kind:"any",state:"any",query:""},h="",L="top level";function A(n){const o=new Set,e=[];for(const t of n)if(t.name.includes("/"))for(let r=t.name.indexOf("/");r>=0;r=t.name.indexOf("/",r+1))o.add(t.name.slice(0,r));else e.push(t.name);return e.some(t=>!o.has(t))&&o.add(h),o}f(A,"groupKeysOf");function G(n,o,e,t){const r={key:"",segment:"",depth:-1,children:new Map,selves:[]};for(const u of n){if(!x(u,u.records.get(t),o))continue;let i=r;for(const d of u.name.split("/")){let l=i.children.get(d);l===void 0&&(l={key:i.depth<0?d:`${i.key}/${d}`,segment:d,depth:i.depth+1,children:new Map,selves:[]},i.children.set(d,l)),i=l}i.selves.push(u)}const s=[],a=[];for(const u of r.children.values())u.children.size===0?s.push(...u.selves):a.push(u);const c=[];if(s.length>0){const u=o.query!==""||e.has(h);if(c.push({kind:"group",key:h,label:L,depth:0,...k(s,t),expanded:u,first:s[0]}),u)for(const i of s)c.push(p(i,i.name,1,t))}for(const u of a)m(u,o,e,t,c);return c}f(G,"buildListView");function y(n,o=[]){o.push(...n.selves);for(const e of n.children.values())y(e,o);return o}f(y,"subtree");function m(n,o,e,t,r){if(n.children.size===0){for(const c of n.selves)r.push(p(c,n.segment,n.depth,t));return}const s=y(n),a=o.query!==""||e.has(n.key);if(r.push({kind:"group",key:n.key,label:`${n.segment}/`,depth:n.depth,...k(s,t),expanded:a,first:s[0]}),!!a){for(const c of n.selves)r.push(p(c,n.segment,n.depth+1,t));for(const c of n.children.values())m(c,o,e,t,r)}}f(m,"emit");function p(n,o,e,t){return{kind:"doc",key:n.key,row:n,label:o,depth:e,cost:g(n.records.get(t))}}f(p,"docLine");function k(n,o){const e={name:0,preview:0,content:0};let t=0;for(const r of n){const s=r.records.get(o);s!==void 0&&s.finalRung!=="none"&&(e[s.finalRung]+=1),t+=g(s)}return{docs:n.length,rungs:e,cost:t}}f(k,"rollup");function I(n,o){const e={name:0,preview:0,content:0};let t=0;for(const r of n){const s=r.records.get(o);if(s===void 0||s.finalRung==="none")continue;const a=R(s)[s.finalRung];e[s.finalRung]+=a,t+=a}return{total:t,byRung:e}}f(I,"costTotals");function x(n,o,e){if(e.rung!=="any"){const t=o?.finalRung??"none";if(e.rung==="silent"?t!=="none":t!==e.rung)return!1}return!(e.origin!=="any"&&n.anchor.scope!==e.origin||e.kind!=="any"&&n.anchor.kind!==e.kind||e.state!=="any"&&!E(o,e.state)||e.query!==""&&!v(e.query,n.name))}f(x,"passes");function E(n,o){if(n===void 0)return o==="no-entry";switch(o){case"delivering":return n.finalRung!=="none";case"gated":return!n.docGate.pass;case"shadowed":return n.shadowedBy!==null;case"no-entry":return n.authoredEntries.length===0}}f(E,"inState");export{z as NO_FILTERS,G as buildListView,I as costTotals,A as groupKeysOf};
1
+ var k=Object.defineProperty;var a=(e,n)=>k(e,"name",{value:n,configurable:!0});import{fuzzyMatch as w}from"../../../../core/tui/fuzzy.js";const q=["node","user","profile","repo","app"],b={rung:"any",origin:"any",kind:"any",state:"any",query:""},p="",v="top level";function z(e){const n=new Set,o=[];for(const t of e)if(t.name.includes("/"))for(let s=t.name.indexOf("/");s>=0;s=t.name.indexOf("/",s+1))n.add(t.name.slice(0,s));else o.push(t.name);return o.some(t=>!n.has(t))&&n.add(p),n}a(z,"groupKeysOf");function G(e,n,o,t){const s={key:"",segment:"",depth:-1,children:new Map,selves:[]};for(const u of e){if(!R(u,u.records.get(t),n))continue;let c=s;for(const l of u.name.split("/")){let h=c.children.get(l);h===void 0&&(h={key:c.depth<0?l:`${c.key}/${l}`,segment:l,depth:c.depth+1,children:new Map,selves:[]},c.children.set(l,h)),c=h}c.selves.push(u)}const f=[],i=[];for(const u of s.children.values())u.children.size===0?f.push(...u.selves):i.push(u);const r=[];if(f.length>0){const u=n.query!==""||o.has(p);if(r.push({kind:"group",key:p,label:v,depth:0,...m(f,t),expanded:u,first:f[0]}),u)for(const c of f)r.push(d(c,c.name,1,t))}for(const u of i)y(u,n,o,t,r);return r}a(G,"buildListView");function g(e,n=[]){n.push(...e.selves);for(const o of e.children.values())g(o,n);return n}a(g,"subtree");function y(e,n,o,t,s){if(e.children.size===0){for(const r of e.selves)s.push(d(r,e.segment,e.depth,t));return}const f=g(e),i=n.query!==""||o.has(e.key);if(s.push({kind:"group",key:e.key,label:`${e.segment}/`,depth:e.depth,...m(f,t),expanded:i,first:f[0]}),!!i){for(const r of e.selves)s.push(d(r,e.segment,e.depth+1,t));for(const r of e.children.values())y(r,n,o,t,s)}}a(y,"emit");function d(e,n,o,t){return{kind:"doc",key:e.key,row:e,label:n,depth:o}}a(d,"docLine");function m(e,n){const o={name:0,preview:0,content:0};for(const t of e){const s=t.records.get(n);s!==void 0&&s.finalRung!=="none"&&(o[s.finalRung]+=1)}return{docs:e.length,rungs:o}}a(m,"rollup");function R(e,n,o){if(o.rung!=="any"){const t=n?.finalRung??"none";if(o.rung==="silent"?t!=="none":t!==o.rung)return!1}return!(o.origin!=="any"&&x(e.anchor)!==o.origin||o.kind!=="any"&&e.anchor.doc.kind!==o.kind||o.state!=="any"&&!E(n,o.state)||o.query!==""&&!w(o.query,e.name))}a(R,"passes");function x(e){return e.doc.owner.type==="person"?"user":e.doc.owner.type}a(x,"ownerTypeOf");function E(e,n){if(e===void 0)return n==="no-rule";switch(n){case"delivering":return e.finalRung!=="none";case"gated":return e.matchedRule===null&&e.ruleGate!==null&&!e.ruleGate.pass;case"shadowed":return e.shadowedBy!==null;case"no-rule":return e.authoredRules.length===0}}a(E,"inState");export{b as NO_FILTERS,q as OWNER_TYPES,G as buildListView,z as groupKeysOf,x as ownerTypeOf};