@north-light/crouter 0.3.227 → 0.3.228

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 (286) hide show
  1. package/dist/api/client.d.ts +5 -5
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/dto/broker-ops.d.ts +8 -0
  4. package/dist/api/dto/memory.d.ts +8 -7
  5. package/dist/api/dto/memory.js +2 -2
  6. package/dist/builtin-memory/05-kinds/design/00-base.md +3 -4
  7. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +4 -3
  8. package/dist/builtin-memory/05-kinds/design/design-contract.md +3 -6
  9. package/dist/builtin-memory/05-kinds/plan/00-base.md +3 -4
  10. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +4 -5
  11. package/dist/builtin-memory/05-kinds/plan/plan-contract.md +5 -13
  12. package/dist/builtin-memory/design/guide.md +38 -16
  13. package/dist/builtin-memory/design/roadmap.md +4 -4
  14. package/dist/builtin-memory/insights/init.md +5 -5
  15. package/dist/builtin-memory/internal/INDEX.md +1 -1
  16. package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
  17. package/dist/builtin-memory/internal/memory-loading.md +6 -6
  18. package/dist/builtin-memory/internal/plugins.md +1 -1
  19. package/dist/builtin-memory/plan/guide.md +53 -0
  20. package/dist/builtin-memory/plan/roadmap.md +10 -8
  21. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +50 -37
  22. package/dist/clients/attach/__tests__/pane-tag-successor.test.js +56 -0
  23. package/dist/clients/attach/__tests__/profile-files.test.js +21 -0
  24. package/dist/clients/attach/chrome/inbox-strip.js +11 -7
  25. package/dist/clients/attach/session/pane-tag.d.ts +28 -2
  26. package/dist/clients/attach/session/pane-tag.js +48 -22
  27. package/dist/clients/attach/session/profile-files.d.ts +6 -0
  28. package/dist/clients/attach/session/profile-files.js +44 -11
  29. package/dist/clients/attach/slash/dispatch.js +4 -7
  30. package/dist/clients/attach/viewer.js +588 -596
  31. package/dist/commands/__tests__/surface-reload-target.test.js +21 -0
  32. package/dist/commands/api-client.d.ts +3 -7
  33. package/dist/commands/api-client.js +7 -12
  34. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +292 -0
  35. package/dist/commands/memory/__tests__/repository-root-lint.test.js +146 -0
  36. package/dist/commands/memory/delete.js +51 -24
  37. package/dist/commands/memory/edit.js +50 -10
  38. package/dist/commands/memory/find.js +105 -56
  39. package/dist/commands/memory/history.js +51 -31
  40. package/dist/commands/memory/lint.d.ts +0 -9
  41. package/dist/commands/memory/lint.js +78 -322
  42. package/dist/commands/memory/list.d.ts +12 -4
  43. package/dist/commands/memory/list.js +64 -25
  44. package/dist/commands/memory/move.js +103 -73
  45. package/dist/commands/memory/origin.js +35 -5
  46. package/dist/commands/memory/read.d.ts +4 -0
  47. package/dist/commands/memory/read.js +132 -80
  48. package/dist/commands/memory/shared.d.ts +115 -25
  49. package/dist/commands/memory/shared.js +331 -74
  50. package/dist/commands/memory/write.js +72 -21
  51. package/dist/commands/memory.js +2 -2
  52. package/dist/commands/node/lifecycle.js +2 -2
  53. package/dist/commands/pkg/market-manage.js +25 -24
  54. package/dist/commands/pkg/plugin-manage.d.ts +22 -6
  55. package/dist/commands/pkg/plugin-manage.js +118 -25
  56. package/dist/commands/pkg/shared.d.ts +8 -0
  57. package/dist/commands/pkg/shared.js +23 -20
  58. package/dist/commands/surface-reload.d.ts +5 -0
  59. package/dist/commands/surface-reload.js +9 -1
  60. package/dist/commands/sys/__tests__/migrate.test.js +1140 -22
  61. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +218 -0
  62. package/dist/commands/sys/migrate.js +126 -140
  63. package/dist/commands/sys/panels/profiles-panel.d.ts +66 -0
  64. package/dist/commands/sys/panels/profiles-panel.js +599 -0
  65. package/dist/commands/sys/settings-shell.d.ts +4 -2
  66. package/dist/commands/sys/settings-shell.js +35 -4
  67. package/dist/commands/sys/settings.js +21 -5
  68. package/dist/commands/sys/sync-deps.d.ts +2 -0
  69. package/dist/commands/sys/sync-deps.js +26 -15
  70. package/dist/commands/sys/sync-project-guidance.js +228 -145
  71. package/dist/commands/sys/sync-skills.js +28 -17
  72. package/dist/commands/sys/update.js +11 -3
  73. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +15 -2
  74. package/dist/core/__tests__/config-change-delta.test.js +106 -0
  75. package/dist/core/__tests__/context-intro.test.js +13 -9
  76. package/dist/core/__tests__/daemon-boot.test.js +22 -16
  77. package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +5 -1
  78. package/dist/core/__tests__/human-deliver.test.js +19 -0
  79. package/dist/core/__tests__/inline-memory-refs.test.js +50 -46
  80. package/dist/core/__tests__/{serial → integration}/broker-fork-seam.test.js +1 -1
  81. package/dist/core/__tests__/{serial → integration}/broker-sdk-wiring.test.js +1 -1
  82. package/dist/core/__tests__/{serial → integration}/broker-snapshot-history.test.js +1 -1
  83. package/dist/core/__tests__/{serial → integration}/command-plugins.test.js +94 -3
  84. package/dist/core/__tests__/{serial → integration}/deferred-no-wake.test.js +1 -1
  85. package/dist/core/__tests__/{serial → integration}/flagship-lifecycle.test.js +13 -27
  86. package/dist/core/__tests__/{serial → integration}/host-teardown-process-group.test.js +1 -1
  87. package/dist/core/__tests__/{serial → integration}/human-deliver-e2e.test.js +1 -1
  88. package/dist/core/__tests__/{live-mutation-verbs.test.js → integration/live-mutation-verbs.test.js} +22 -33
  89. package/dist/core/__tests__/{serial → integration}/live-mutation.test.js +21 -41
  90. package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +1 -0
  91. package/dist/core/__tests__/{serial → integration}/refresh-stall-recycle.test.js +1 -1
  92. package/dist/core/__tests__/integration/revive.test.d.ts +1 -0
  93. package/dist/core/__tests__/{serial → integration}/revive.test.js +38 -19
  94. package/dist/core/__tests__/integration/spawn-root.test.d.ts +1 -0
  95. package/dist/core/__tests__/{serial → integration}/spawn-root.test.js +104 -1
  96. package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +1 -0
  97. package/dist/core/__tests__/{serial → integration}/subscription-delivery.test.js +1 -1
  98. package/dist/core/__tests__/integration/tmux-surface.test.d.ts +1 -0
  99. package/dist/core/__tests__/{serial → integration}/tmux-surface.test.js +1 -1
  100. package/dist/core/__tests__/integration/worktree-land.test.d.ts +1 -0
  101. package/dist/core/__tests__/integration/worktree-land.test.js +400 -0
  102. package/dist/core/__tests__/integration/worktree-reap.test.d.ts +1 -0
  103. package/dist/core/__tests__/{serial/worktree.test.js → integration/worktree-reap.test.js} +6 -338
  104. package/dist/core/__tests__/kickoff.test.js +16 -5
  105. package/dist/core/__tests__/memory-resolver-precedence.test.js +122 -91
  106. package/dist/core/__tests__/nested-store-discovery.test.js +5 -3
  107. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
  108. package/dist/core/__tests__/on-read-dedup-resume.test.js +39 -27
  109. package/dist/core/__tests__/on-read-nested-store.test.js +19 -13
  110. package/dist/core/__tests__/profile-project-memory-delivery.test.js +138 -44
  111. package/dist/core/__tests__/repository-association.test.d.ts +1 -0
  112. package/dist/core/__tests__/repository-association.test.js +153 -0
  113. package/dist/core/__tests__/repository-root-identity.test.d.ts +1 -0
  114. package/dist/core/__tests__/repository-root-identity.test.js +219 -0
  115. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +27 -11
  116. package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +1 -0
  117. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +40 -0
  118. package/dist/core/canvas/canvas.d.ts +3 -0
  119. package/dist/core/canvas/canvas.js +30 -10
  120. package/dist/core/canvas/db.js +28 -1
  121. package/dist/core/canvas/paths.d.ts +4 -6
  122. package/dist/core/canvas/paths.js +8 -6
  123. package/dist/core/canvas/render-source.js +2 -2
  124. package/dist/core/canvas/types.d.ts +9 -13
  125. package/dist/core/exclusive-lock.d.ts +2 -0
  126. package/dist/core/exclusive-lock.js +21 -0
  127. package/dist/core/git.d.ts +0 -1
  128. package/dist/core/git.js +0 -3
  129. package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +1 -0
  130. package/dist/core/human/feedback-companion.js +3 -0
  131. package/dist/core/human/scan.js +8 -1
  132. package/dist/core/keybindings/catalog.d.ts +2 -2
  133. package/dist/core/keybindings/catalog.js +2 -1
  134. package/dist/core/memory/doc-link-grammar.js +2 -2
  135. package/dist/core/memory/history.d.ts +24 -0
  136. package/dist/core/memory/history.js +66 -1
  137. package/dist/core/memory/identity.d.ts +65 -0
  138. package/dist/core/memory/identity.js +185 -0
  139. package/dist/core/memory/inline-ref-guidance.d.ts +1 -1
  140. package/dist/core/memory/inline-ref-guidance.js +1 -1
  141. package/dist/core/memory/inline-ref-inventory.d.ts +3 -10
  142. package/dist/core/memory/inline-ref-inventory.js +30 -62
  143. package/dist/core/memory/lint.d.ts +129 -0
  144. package/dist/core/memory/lint.js +517 -0
  145. package/dist/core/memory/project-namespace.d.ts +31 -0
  146. package/dist/core/memory/project-namespace.js +85 -0
  147. package/dist/core/memory/repository-association.d.ts +31 -0
  148. package/dist/core/memory/repository-association.js +129 -0
  149. package/dist/core/memory/tree.d.ts +39 -0
  150. package/dist/core/memory/tree.js +93 -0
  151. package/dist/core/memory-resolver.d.ts +193 -90
  152. package/dist/core/memory-resolver.js +461 -375
  153. package/dist/core/nested-stores.js +6 -13
  154. package/dist/core/profiles/select.d.ts +4 -1
  155. package/dist/core/profiles/select.js +108 -48
  156. package/dist/core/review/__tests__/capture-origin.test.js +2 -2
  157. package/dist/core/review/__tests__/stage-identity.test.js +2 -2
  158. package/dist/core/review/companion.js +11 -2
  159. package/dist/core/runtime/bearings.d.ts +2 -2
  160. package/dist/core/runtime/bearings.js +3 -3
  161. package/dist/core/runtime/broker/daemon-ops.d.ts +2 -2
  162. package/dist/core/runtime/broker/rebind.js +5 -0
  163. package/dist/core/runtime/broker-extension-render.d.ts +7 -3
  164. package/dist/core/runtime/broker-extension-render.js +10 -5
  165. package/dist/core/runtime/broker-persona-guidance.d.ts +19 -5
  166. package/dist/core/runtime/broker-persona-guidance.js +122 -27
  167. package/dist/core/runtime/deliver-live.d.ts +16 -4
  168. package/dist/core/runtime/deliver-live.js +29 -15
  169. package/dist/core/runtime/kickoff.d.ts +3 -3
  170. package/dist/core/runtime/kickoff.js +8 -16
  171. package/dist/core/runtime/lifecycle.js +2 -3
  172. package/dist/core/runtime/nodes.d.ts +3 -4
  173. package/dist/core/runtime/nodes.js +3 -4
  174. package/dist/core/runtime/persona.d.ts +8 -12
  175. package/dist/core/runtime/persona.js +24 -96
  176. package/dist/core/runtime/promote.d.ts +2 -2
  177. package/dist/core/runtime/promote.js +8 -21
  178. package/dist/core/runtime/revive.js +20 -17
  179. package/dist/core/runtime/spawn.js +18 -7
  180. package/dist/core/runtime/tmux-bindings.js +2 -3
  181. package/dist/core/runtime/warm-pool.js +3 -4
  182. package/dist/core/scope.js +2 -0
  183. package/dist/core/self-update.d.ts +0 -2
  184. package/dist/core/self-update.js +2 -35
  185. package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +1 -0
  186. package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +28 -0
  187. package/dist/core/substrate/index.d.ts +2 -2
  188. package/dist/core/substrate/index.js +1 -1
  189. package/dist/core/substrate/injected-store.d.ts +43 -27
  190. package/dist/core/substrate/injected-store.js +208 -104
  191. package/dist/core/substrate/listings.d.ts +19 -12
  192. package/dist/core/substrate/listings.js +75 -52
  193. package/dist/core/substrate/on-read-node.d.ts +4 -7
  194. package/dist/core/substrate/on-read-node.js +6 -8
  195. package/dist/core/substrate/on-read.d.ts +22 -25
  196. package/dist/core/substrate/on-read.js +103 -147
  197. package/dist/core/substrate/render-node.d.ts +4 -7
  198. package/dist/core/substrate/render-node.js +5 -7
  199. package/dist/core/substrate/render.d.ts +21 -3
  200. package/dist/core/substrate/render.js +291 -223
  201. package/dist/core/substrate/schema.d.ts +1 -13
  202. package/dist/core/substrate/schema.js +5 -40
  203. package/dist/core/substrate/session-cache.d.ts +14 -4
  204. package/dist/core/substrate/session-cache.js +40 -22
  205. package/dist/core/substrate/surface-match.d.ts +9 -7
  206. package/dist/core/substrate/surface-match.js +26 -25
  207. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +30 -0
  208. package/dist/daemon/__tests__/helpers/source-daemon.js +174 -0
  209. package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +1 -0
  210. package/dist/daemon/__tests__/integration/migration-startup.test.js +97 -0
  211. package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +21 -5
  212. package/dist/daemon/api/handlers/broker-ops.js +21 -16
  213. package/dist/daemon/api/handlers/memory.js +2 -0
  214. package/dist/daemon/crtrd.js +2 -0
  215. package/dist/daemon/human/finish.js +8 -1
  216. package/dist/daemon/manage.d.ts +0 -1
  217. package/dist/daemon/manage.js +7 -16
  218. package/dist/daemon/startup-policy.d.ts +1 -0
  219. package/dist/daemon/startup-policy.js +1 -0
  220. package/dist/migrations/001-surfaces-frontmatter.js +21 -109
  221. package/dist/migrations/002-profile-project-memory.js +1 -0
  222. package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +26 -0
  223. package/dist/migrations/003-repository-root-memory-identity/front-door.js +231 -0
  224. package/dist/migrations/003-repository-root-memory-identity/index.d.ts +2 -0
  225. package/dist/migrations/003-repository-root-memory-identity/index.js +513 -0
  226. package/dist/migrations/003-repository-root-memory-identity/references.d.ts +95 -0
  227. package/dist/migrations/003-repository-root-memory-identity/references.js +469 -0
  228. package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +39 -0
  229. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +349 -0
  230. package/dist/migrations/__tests__/activation-concurrency.test.d.ts +1 -0
  231. package/dist/migrations/__tests__/activation-concurrency.test.js +145 -0
  232. package/dist/migrations/__tests__/activation.test.d.ts +1 -0
  233. package/dist/migrations/__tests__/activation.test.js +149 -0
  234. package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +1 -0
  235. package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +149 -0
  236. package/dist/migrations/activation.d.ts +16 -0
  237. package/dist/migrations/activation.js +78 -0
  238. package/dist/migrations/convergent.d.ts +14 -3
  239. package/dist/migrations/convergent.js +21 -10
  240. package/dist/migrations/corpus.d.ts +78 -0
  241. package/dist/migrations/corpus.js +497 -0
  242. package/dist/migrations/frontmatter-splice.d.ts +15 -0
  243. package/dist/migrations/frontmatter-splice.js +176 -0
  244. package/dist/migrations/registry.d.ts +6 -1
  245. package/dist/migrations/registry.js +7 -2
  246. package/dist/migrations/runner.d.ts +41 -0
  247. package/dist/migrations/runner.js +81 -0
  248. package/dist/migrations/types.d.ts +148 -9
  249. package/dist/migrations/types.js +9 -2
  250. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +225 -17
  251. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +11 -3
  252. package/dist/pi-extensions/canvas-context-intro.d.ts +3 -5
  253. package/dist/pi-extensions/canvas-context-intro.js +50 -46
  254. package/dist/pi-extensions/canvas-doc-substrate.d.ts +1 -8
  255. package/dist/pi-extensions/canvas-doc-substrate.js +55 -122
  256. package/dist/pi-extensions/canvas-stophook.js +6 -13
  257. package/dist/shared/generated-context.d.ts +0 -3
  258. package/dist/shared/generated-context.js +0 -57
  259. package/dist/shared/tool-groups.js +2 -3
  260. package/package.json +5 -4
  261. package/runtime.lock.json +2 -2
  262. /package/dist/api/__tests__/{serial → integration}/client.test.d.ts +0 -0
  263. /package/dist/api/__tests__/{serial → integration}/client.test.js +0 -0
  264. /package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{serial → integration}/provider-rotation.test.ts +0 -0
  265. /package/dist/clients/{inbox/__tests__/serial/inbox-controller.test.d.ts → attach/__tests__/pane-tag-successor.test.d.ts} +0 -0
  266. /package/dist/clients/{inbox/__tests__/serial/mount-panel.test.d.ts → attach/__tests__/profile-files.test.d.ts} +0 -0
  267. /package/dist/{core/__tests__/live-mutation-verbs.test.d.ts → clients/inbox/__tests__/integration/inbox-controller.test.d.ts} +0 -0
  268. /package/dist/clients/inbox/__tests__/{serial → integration}/inbox-controller.test.js +0 -0
  269. /package/dist/{core/__tests__/serial/broker-fork-seam.test.d.ts → clients/inbox/__tests__/integration/mount-panel.test.d.ts} +0 -0
  270. /package/dist/clients/inbox/__tests__/{serial → integration}/mount-panel.test.js +0 -0
  271. /package/dist/{core/__tests__/serial/broker-sdk-wiring.test.d.ts → commands/__tests__/surface-reload-target.test.d.ts} +0 -0
  272. /package/dist/{core/__tests__/serial/broker-snapshot-history.test.d.ts → commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts} +0 -0
  273. /package/dist/{core/__tests__/serial/command-plugins.test.d.ts → commands/memory/__tests__/repository-root-lint.test.d.ts} +0 -0
  274. /package/dist/{core/__tests__/serial/deferred-no-wake.test.d.ts → commands/sys/__tests__/sync-project-guidance.test.d.ts} +0 -0
  275. /package/dist/core/__tests__/{serial/flagship-lifecycle.test.d.ts → config-change-delta.test.d.ts} +0 -0
  276. /package/dist/core/__tests__/{serial/host-teardown-process-group.test.d.ts → integration/broker-fork-seam.test.d.ts} +0 -0
  277. /package/dist/core/__tests__/{serial/human-deliver-e2e.test.d.ts → integration/broker-sdk-wiring.test.d.ts} +0 -0
  278. /package/dist/core/__tests__/{serial/live-mutation.test.d.ts → integration/broker-snapshot-history.test.d.ts} +0 -0
  279. /package/dist/core/__tests__/{serial/refresh-stall-recycle.test.d.ts → integration/command-plugins.test.d.ts} +0 -0
  280. /package/dist/core/__tests__/{serial/revive.test.d.ts → integration/deferred-no-wake.test.d.ts} +0 -0
  281. /package/dist/core/__tests__/{serial/spawn-root.test.d.ts → integration/flagship-lifecycle.test.d.ts} +0 -0
  282. /package/dist/core/__tests__/{serial/subscription-delivery.test.d.ts → integration/host-teardown-process-group.test.d.ts} +0 -0
  283. /package/dist/core/__tests__/{serial/tmux-surface.test.d.ts → integration/human-deliver-e2e.test.d.ts} +0 -0
  284. /package/dist/core/__tests__/{serial/worktree.test.d.ts → integration/live-mutation-verbs.test.d.ts} +0 -0
  285. /package/dist/core/{human/__tests__/serial/inbox-core.test.d.ts → __tests__/integration/live-mutation.test.d.ts} +0 -0
  286. /package/dist/core/human/__tests__/{serial → integration}/inbox-core.test.js +0 -0
@@ -0,0 +1,231 @@
1
+ import { join, relative } from 'node:path';
2
+ import { parse as parseYaml, stringify } from 'yaml';
3
+ import { realpathOrSelf } from '../../core/fs-utils.js';
4
+ import { parseFrontmatterGeneric } from '../../core/frontmatter.js';
5
+ import { localNameFromPath } from '../../core/memory/identity.js';
6
+ import { appendRenderedKey, dropSequenceItems, dropTopLevelKeys, proveFrontmatterRoundTrip, rebuildDocSource, splitDocSource, } from '../frontmatter-splice.js';
7
+ function record(value) {
8
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
9
+ ? value
10
+ : null;
11
+ }
12
+ function surfaceEntries(frontmatter) {
13
+ const raw = frontmatter?.['surfaces'];
14
+ if (raw === undefined)
15
+ return [];
16
+ if (!Array.isArray(raw))
17
+ return null;
18
+ return raw.map(record).filter((entry) => entry !== null);
19
+ }
20
+ function matchIncludesOwnerTree(match) {
21
+ return match === './**' || (Array.isArray(match) && match.includes('./**'));
22
+ }
23
+ function hasWorkspaceOpen(entries) {
24
+ return entries.some((entry) => entry['on'] === 'workspace-open' && entry['at'] === 'content');
25
+ }
26
+ function hasOwnerRead(entries) {
27
+ return entries.some((entry) => entry['on'] === 'read'
28
+ && entry['at'] === 'content'
29
+ && matchIncludesOwnerTree(entry['match']));
30
+ }
31
+ function hasCompleteFrontDoor(frontmatter) {
32
+ const entries = surfaceEntries(frontmatter);
33
+ return entries !== null && hasWorkspaceOpen(entries) && hasOwnerRead(entries);
34
+ }
35
+ function conflictingRootWorkspaceOpen(frontmatter) {
36
+ const entries = surfaceEntries(frontmatter);
37
+ if (entries === null)
38
+ return true;
39
+ return entries.some((entry) => {
40
+ if (entry['on'] !== 'workspace-open')
41
+ return false;
42
+ return entry['at'] !== 'content'
43
+ || Object.hasOwn(entry, 'match')
44
+ || Object.hasOwn(entry, 'gate')
45
+ || Object.hasOwn(entry, 'match-frontmatter');
46
+ });
47
+ }
48
+ function rootStoreKey(repositoryRoot, prefixes) {
49
+ for (const [storeKey, facts] of prefixes) {
50
+ if (facts.repositoryRoot === repositoryRoot && facts.ownerRelativePath === '')
51
+ return storeKey;
52
+ }
53
+ return realpathOrSelf(join(repositoryRoot, '.crouter', 'memory'));
54
+ }
55
+ function repositoryRelativePath(repositoryRoot, filePath) {
56
+ return relative(repositoryRoot, filePath).replace(/\\/g, '/');
57
+ }
58
+ function frontDoorBlocker(message, paths, repositoryRoot) {
59
+ return {
60
+ kind: 'front-door',
61
+ message,
62
+ storeRoot: join(repositoryRoot, '.crouter', 'memory'),
63
+ ...(paths.length === 1 ? { path: paths[0] } : {}),
64
+ paths: [...paths],
65
+ };
66
+ }
67
+ export function planFrontDoors(repositories, prefixes, corpus, finalNameOf) {
68
+ const plans = [];
69
+ const blockers = [];
70
+ for (const repository of repositories) {
71
+ const rootDocPath = join(repository.repositoryRoot, '.crouter', 'memory', 'INDEX.md');
72
+ const rootRealPath = realpathOrSelf(rootDocPath);
73
+ const rootKey = rootStoreKey(repository.repositoryRoot, prefixes);
74
+ let rootDoc = null;
75
+ const workspaceOpenDocs = new Map();
76
+ const candidates = new Map();
77
+ for (const storeKey of repository.storeKeys) {
78
+ const facts = prefixes.get(storeKey);
79
+ if (facts === undefined || facts.repositoryRoot !== repository.repositoryRoot)
80
+ continue;
81
+ const store = facts.store ?? corpus.store(storeKey);
82
+ if (store === undefined || !store.writable)
83
+ continue;
84
+ if (store.descriptor.scope !== 'project' || store.descriptor.plugin !== undefined)
85
+ continue;
86
+ for (const doc of store.snapshot.docs) {
87
+ const docRealPath = realpathOrSelf(doc.path);
88
+ if (docRealPath === rootRealPath) {
89
+ rootDoc = doc;
90
+ continue;
91
+ }
92
+ if (facts.nestedDeclarationAction === 'synthetic-index-removed'
93
+ && localNameFromPath(doc.relPath) === '')
94
+ continue;
95
+ const entry = { doc, storeKey, realPath: docRealPath };
96
+ const entries = surfaceEntries(doc.frontmatter);
97
+ if (entries?.some((surface) => surface['on'] === 'workspace-open' && surface['at'] === 'content')) {
98
+ workspaceOpenDocs.set(docRealPath, entry);
99
+ }
100
+ if (!hasCompleteFrontDoor(doc.frontmatter))
101
+ continue;
102
+ candidates.set(docRealPath, entry);
103
+ }
104
+ }
105
+ const leaves = [...candidates.values()];
106
+ const repositoryBlockers = [];
107
+ if (leaves.length > 1) {
108
+ const paths = leaves.map((leaf) => leaf.doc.path);
109
+ repositoryBlockers.push(frontDoorBlocker(`repository ${repository.repositoryRoot} has more than one non-root document carrying the complete workspace front door (${paths.join(', ')}) — keep one source guide as the transfer source, remove the other workspace-open entries, and re-run`, paths, repository.repositoryRoot));
110
+ }
111
+ const incompleteWorkspaceOpenDocs = [...workspaceOpenDocs.values()]
112
+ .filter((entry) => !candidates.has(entry.realPath));
113
+ if (incompleteWorkspaceOpenDocs.length > 0) {
114
+ const paths = incompleteWorkspaceOpenDocs.map((entry) => entry.doc.path);
115
+ repositoryBlockers.push(frontDoorBlocker(`repository ${repository.repositoryRoot} has non-root workspace-open documents without the complete owner-read pair (${paths.join(', ')}) — complete exactly one legacy front door or remove these workspace-open entries, then re-run`, paths, repository.repositoryRoot));
116
+ }
117
+ if (rootDoc !== null && conflictingRootWorkspaceOpen(rootDoc.frontmatter)) {
118
+ const paths = [rootDoc.path, ...leaves.map((leaf) => leaf.doc.path)];
119
+ repositoryBlockers.push(frontDoorBlocker(`repository-root guide ${rootDoc.path} carries a workspace-open route that migration cannot make authoritative without changing its predicate — make every root workspace-open entry exactly {on: workspace-open, at: content} and re-run`, paths, repository.repositoryRoot));
120
+ }
121
+ const leaf = leaves.length === 1 ? leaves[0] : null;
122
+ const leafCanonicalName = leaf === null ? null : finalNameOf(leaf.realPath);
123
+ if (leaf !== null && leafCanonicalName === undefined) {
124
+ repositoryBlockers.push(frontDoorBlocker(`legacy workspace front door ${leaf.doc.path} has no provable final canonical name — repair its identity blocker and re-run`, [leaf.doc.path], repository.repositoryRoot));
125
+ }
126
+ if (repositoryBlockers.length > 0) {
127
+ blockers.push(...repositoryBlockers);
128
+ continue;
129
+ }
130
+ const rootComplete = rootDoc !== null && hasCompleteFrontDoor(rootDoc.frontmatter);
131
+ const rootAction = rootDoc === null
132
+ ? 'created'
133
+ : rootComplete
134
+ ? 'kept'
135
+ : 'completed';
136
+ const relativeLeafPath = leaf === null
137
+ ? null
138
+ : repositoryRelativePath(repository.repositoryRoot, leaf.doc.path);
139
+ const action = relativeLeafPath !== null
140
+ ? `transferred-from:${relativeLeafPath}`
141
+ : rootComplete
142
+ ? 'kept-root'
143
+ : 'created-root';
144
+ plans.push({
145
+ repositoryRoot: repository.repositoryRoot,
146
+ storeKey: rootKey,
147
+ rootDocPath,
148
+ rootAction,
149
+ leafDocPath: leaf?.doc.path ?? null,
150
+ leafStoreKey: leaf?.storeKey ?? null,
151
+ leafCanonicalName: leafCanonicalName ?? null,
152
+ action,
153
+ });
154
+ }
155
+ return { plans, blockers };
156
+ }
157
+ /** New repository-root INDEX.md source. `leafCanonicalName` null yields the generic minimal root body. */
158
+ export function rootIndexSource(namespace, leafCanonicalName) {
159
+ const label = namespace.split('/').at(-1) ?? namespace;
160
+ const body = leafCanonicalName === null
161
+ ? `# ${label}\n\nThis project's memory store. Every document here answers at \`${namespace}/<local name>\`.\n`
162
+ : `# ${label}\n\nThis project's memory store. Every document here answers at \`${namespace}/<local name>\`. Read [[${leafCanonicalName}]] for the detailed project guide.\n`;
163
+ return [
164
+ '---',
165
+ `namespace: ${JSON.stringify(namespace)}`,
166
+ 'kind: knowledge',
167
+ `when-and-why-to-read: When working in \`${namespace}\`, this knowledge should be read because it names the namespace every document in this repository answers under.`,
168
+ 'surfaces:',
169
+ ' - on: workspace-open',
170
+ ' at: content',
171
+ ' - on: read',
172
+ ' match: "./**"',
173
+ ' at: content',
174
+ '---',
175
+ '',
176
+ body,
177
+ ].join('\n');
178
+ }
179
+ function sourceWithFrontmatter(source) {
180
+ return parseFrontmatterGeneric(source).data === null ? `---\n\n---\n${source}` : source;
181
+ }
182
+ function parsedYamlRecord(rawYaml, docPath) {
183
+ let parsed;
184
+ try {
185
+ parsed = parseYaml(rawYaml === '' ? '{}' : rawYaml);
186
+ }
187
+ catch (error) {
188
+ throw new Error(`front-door migration: unparseable frontmatter in ${docPath}`, { cause: error });
189
+ }
190
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
191
+ throw new Error(`front-door migration: frontmatter is not a mapping in ${docPath}`);
192
+ }
193
+ return parsed;
194
+ }
195
+ /** Add the missing half or halves of the root front-door pair to a complete document source. */
196
+ export function completeRootFrontDoor(source, docPath) {
197
+ const withFrontmatter = sourceWithFrontmatter(source);
198
+ const { rawYaml } = splitDocSource(withFrontmatter, docPath);
199
+ const before = parsedYamlRecord(rawYaml, docPath);
200
+ const rawSurfaces = before['surfaces'];
201
+ if (rawSurfaces !== undefined && !Array.isArray(rawSurfaces)) {
202
+ throw new Error(`front-door migration: surfaces is not a sequence in ${docPath}`);
203
+ }
204
+ const surfaces = rawSurfaces === undefined
205
+ ? []
206
+ : rawSurfaces.map((entry) => record(entry) ?? entry);
207
+ const entries = surfaces.filter((entry) => record(entry) !== null);
208
+ const merged = [...surfaces];
209
+ if (!hasWorkspaceOpen(entries))
210
+ merged.push({ on: 'workspace-open', at: 'content' });
211
+ if (!hasOwnerRead(entries))
212
+ merged.push({ on: 'read', match: './**', at: 'content' });
213
+ if (merged.length === surfaces.length)
214
+ return withFrontmatter;
215
+ let newYaml = rawYaml;
216
+ if (rawSurfaces !== undefined)
217
+ newYaml = dropTopLevelKeys(newYaml, ['surfaces'], docPath);
218
+ newYaml = newYaml === ''
219
+ ? stringify({ surfaces: merged }, { lineWidth: 0 }).replace(/\r?\n$/, '')
220
+ : appendRenderedKey(newYaml, 'surfaces', merged, docPath);
221
+ proveFrontmatterRoundTrip(newYaml, { ...before, surfaces: merged }, docPath);
222
+ return rebuildDocSource(withFrontmatter, newYaml, docPath);
223
+ }
224
+ /** Remove every workspace-open entry while preserving the body and every retained authored YAML byte. */
225
+ export function demoteLeafSurfaces(source, docPath) {
226
+ if (parseFrontmatterGeneric(source).data === null)
227
+ return source;
228
+ const { rawYaml } = splitDocSource(source, docPath);
229
+ const newYaml = dropSequenceItems(rawYaml, 'surfaces', (item) => record(item)?.['on'] === 'workspace-open', docPath);
230
+ return newYaml === rawYaml ? source : rebuildDocSource(source, newYaml, docPath);
231
+ }
@@ -0,0 +1,2 @@
1
+ import type { CorpusMigration } from '../types.js';
2
+ export declare const repositoryRootMemoryIdentityMigration: CorpusMigration;