@north-light/crouter 0.3.226 → 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.
- package/dist/api/client.d.ts +5 -5
- package/dist/api/client.js +3 -3
- package/dist/api/dto/broker-ops.d.ts +8 -0
- package/dist/api/dto/memory.d.ts +8 -7
- package/dist/api/dto/memory.js +2 -2
- package/dist/builtin-memory/05-kinds/design/00-base.md +3 -4
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +4 -3
- package/dist/builtin-memory/05-kinds/design/design-contract.md +3 -6
- package/dist/builtin-memory/05-kinds/plan/00-base.md +3 -4
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +4 -5
- package/dist/builtin-memory/05-kinds/plan/plan-contract.md +5 -13
- package/dist/builtin-memory/design/guide.md +38 -16
- package/dist/builtin-memory/design/roadmap.md +4 -4
- package/dist/builtin-memory/insights/init.md +5 -5
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
- package/dist/builtin-memory/internal/memory-loading.md +6 -6
- package/dist/builtin-memory/internal/plugins.md +1 -1
- package/dist/builtin-memory/plan/guide.md +53 -0
- package/dist/builtin-memory/plan/roadmap.md +10 -8
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +50 -37
- package/dist/clients/attach/__tests__/pane-tag-successor.test.js +56 -0
- package/dist/clients/attach/__tests__/profile-files.test.js +21 -0
- package/dist/clients/attach/chrome/inbox-strip.js +11 -7
- package/dist/clients/attach/session/pane-tag.d.ts +28 -2
- package/dist/clients/attach/session/pane-tag.js +48 -22
- package/dist/clients/attach/session/profile-files.d.ts +6 -0
- package/dist/clients/attach/session/profile-files.js +44 -11
- package/dist/clients/attach/slash/dispatch.js +4 -7
- package/dist/clients/attach/viewer.js +588 -596
- package/dist/commands/__tests__/surface-reload-target.test.js +21 -0
- package/dist/commands/api-client.d.ts +3 -7
- package/dist/commands/api-client.js +7 -12
- package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +292 -0
- package/dist/commands/memory/__tests__/repository-root-lint.test.js +146 -0
- package/dist/commands/memory/delete.js +51 -24
- package/dist/commands/memory/edit.js +50 -10
- package/dist/commands/memory/find.js +105 -56
- package/dist/commands/memory/history.js +51 -31
- package/dist/commands/memory/lint.d.ts +0 -9
- package/dist/commands/memory/lint.js +78 -322
- package/dist/commands/memory/list.d.ts +12 -4
- package/dist/commands/memory/list.js +64 -25
- package/dist/commands/memory/move.js +103 -73
- package/dist/commands/memory/origin.js +35 -5
- package/dist/commands/memory/read.d.ts +4 -0
- package/dist/commands/memory/read.js +132 -80
- package/dist/commands/memory/shared.d.ts +115 -25
- package/dist/commands/memory/shared.js +331 -74
- package/dist/commands/memory/write.js +72 -21
- package/dist/commands/memory.js +2 -2
- package/dist/commands/node/lifecycle.js +2 -2
- package/dist/commands/pkg/market-manage.js +25 -24
- package/dist/commands/pkg/plugin-manage.d.ts +22 -6
- package/dist/commands/pkg/plugin-manage.js +118 -25
- package/dist/commands/pkg/shared.d.ts +8 -0
- package/dist/commands/pkg/shared.js +23 -20
- package/dist/commands/surface-reload.d.ts +5 -0
- package/dist/commands/surface-reload.js +9 -1
- package/dist/commands/sys/__tests__/migrate.test.js +1140 -22
- package/dist/commands/sys/__tests__/sync-project-guidance.test.js +218 -0
- package/dist/commands/sys/migrate.js +126 -140
- package/dist/commands/sys/panels/profiles-panel.d.ts +66 -0
- package/dist/commands/sys/panels/profiles-panel.js +599 -0
- package/dist/commands/sys/settings-shell.d.ts +4 -2
- package/dist/commands/sys/settings-shell.js +35 -4
- package/dist/commands/sys/settings.js +21 -5
- package/dist/commands/sys/sync-deps.d.ts +2 -0
- package/dist/commands/sys/sync-deps.js +26 -15
- package/dist/commands/sys/sync-project-guidance.js +228 -145
- package/dist/commands/sys/sync-skills.js +28 -17
- package/dist/commands/sys/update.js +11 -3
- package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +15 -2
- package/dist/core/__tests__/config-change-delta.test.js +106 -0
- package/dist/core/__tests__/context-intro.test.js +13 -9
- package/dist/core/__tests__/daemon-boot.test.js +22 -16
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +5 -1
- package/dist/core/__tests__/human-deliver.test.js +19 -0
- package/dist/core/__tests__/inline-memory-refs.test.js +50 -46
- package/dist/core/__tests__/{serial → integration}/broker-fork-seam.test.js +1 -1
- package/dist/core/__tests__/{serial → integration}/broker-sdk-wiring.test.js +1 -1
- package/dist/core/__tests__/{serial → integration}/broker-snapshot-history.test.js +1 -1
- package/dist/core/__tests__/{serial → integration}/command-plugins.test.js +94 -3
- package/dist/core/__tests__/{serial → integration}/deferred-no-wake.test.js +1 -1
- package/dist/core/__tests__/{serial → integration}/flagship-lifecycle.test.js +13 -27
- package/dist/core/__tests__/{serial → integration}/host-teardown-process-group.test.js +1 -1
- package/dist/core/__tests__/{serial → integration}/human-deliver-e2e.test.js +1 -1
- package/dist/core/__tests__/{live-mutation-verbs.test.js → integration/live-mutation-verbs.test.js} +22 -33
- package/dist/core/__tests__/{serial → integration}/live-mutation.test.js +21 -41
- package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/{serial → integration}/refresh-stall-recycle.test.js +1 -1
- package/dist/core/__tests__/integration/revive.test.d.ts +1 -0
- package/dist/core/__tests__/{serial → integration}/revive.test.js +38 -19
- package/dist/core/__tests__/integration/spawn-root.test.d.ts +1 -0
- package/dist/core/__tests__/{serial → integration}/spawn-root.test.js +104 -1
- package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +1 -0
- package/dist/core/__tests__/{serial → integration}/subscription-delivery.test.js +1 -1
- package/dist/core/__tests__/integration/tmux-surface.test.d.ts +1 -0
- package/dist/core/__tests__/{serial → integration}/tmux-surface.test.js +1 -1
- package/dist/core/__tests__/integration/worktree-land.test.d.ts +1 -0
- package/dist/core/__tests__/integration/worktree-land.test.js +400 -0
- package/dist/core/__tests__/integration/worktree-reap.test.d.ts +1 -0
- package/dist/core/__tests__/{serial/worktree.test.js → integration/worktree-reap.test.js} +6 -338
- package/dist/core/__tests__/kickoff.test.js +16 -5
- package/dist/core/__tests__/memory-resolver-precedence.test.js +122 -91
- package/dist/core/__tests__/nested-store-discovery.test.js +5 -3
- package/dist/core/__tests__/on-read-crouter-home-fence.test.js +2 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +39 -27
- package/dist/core/__tests__/on-read-nested-store.test.js +19 -13
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +138 -44
- package/dist/core/__tests__/repository-association.test.d.ts +1 -0
- package/dist/core/__tests__/repository-association.test.js +153 -0
- package/dist/core/__tests__/repository-root-identity.test.d.ts +1 -0
- package/dist/core/__tests__/repository-root-identity.test.js +219 -0
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +27 -11
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +1 -0
- package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +40 -0
- package/dist/core/canvas/canvas.d.ts +3 -0
- package/dist/core/canvas/canvas.js +30 -10
- package/dist/core/canvas/db.js +28 -1
- package/dist/core/canvas/paths.d.ts +4 -6
- package/dist/core/canvas/paths.js +8 -6
- package/dist/core/canvas/render-source.js +2 -2
- package/dist/core/canvas/types.d.ts +9 -13
- package/dist/core/exclusive-lock.d.ts +2 -0
- package/dist/core/exclusive-lock.js +21 -0
- package/dist/core/git.d.ts +0 -1
- package/dist/core/git.js +0 -3
- package/dist/core/human/__tests__/integration/inbox-core.test.d.ts +1 -0
- package/dist/core/human/feedback-companion.js +3 -0
- package/dist/core/human/scan.js +8 -1
- package/dist/core/keybindings/catalog.d.ts +2 -2
- package/dist/core/keybindings/catalog.js +2 -1
- package/dist/core/memory/doc-link-grammar.js +2 -2
- package/dist/core/memory/history.d.ts +24 -0
- package/dist/core/memory/history.js +66 -1
- package/dist/core/memory/identity.d.ts +65 -0
- package/dist/core/memory/identity.js +185 -0
- package/dist/core/memory/inline-ref-guidance.d.ts +1 -1
- package/dist/core/memory/inline-ref-guidance.js +1 -1
- package/dist/core/memory/inline-ref-inventory.d.ts +3 -10
- package/dist/core/memory/inline-ref-inventory.js +30 -62
- package/dist/core/memory/lint.d.ts +129 -0
- package/dist/core/memory/lint.js +517 -0
- package/dist/core/memory/project-namespace.d.ts +31 -0
- package/dist/core/memory/project-namespace.js +85 -0
- package/dist/core/memory/repository-association.d.ts +31 -0
- package/dist/core/memory/repository-association.js +129 -0
- package/dist/core/memory/tree.d.ts +39 -0
- package/dist/core/memory/tree.js +93 -0
- package/dist/core/memory-resolver.d.ts +193 -90
- package/dist/core/memory-resolver.js +461 -375
- package/dist/core/nested-stores.js +6 -13
- package/dist/core/profiles/select.d.ts +4 -1
- package/dist/core/profiles/select.js +108 -48
- package/dist/core/review/__tests__/capture-origin.test.js +2 -2
- package/dist/core/review/__tests__/stage-identity.test.js +2 -2
- package/dist/core/review/companion.js +11 -2
- package/dist/core/runtime/bearings.d.ts +2 -2
- package/dist/core/runtime/bearings.js +3 -3
- package/dist/core/runtime/broker/daemon-ops.d.ts +2 -2
- package/dist/core/runtime/broker/rebind.js +5 -0
- package/dist/core/runtime/broker-extension-render.d.ts +7 -3
- package/dist/core/runtime/broker-extension-render.js +10 -5
- package/dist/core/runtime/broker-persona-guidance.d.ts +19 -5
- package/dist/core/runtime/broker-persona-guidance.js +122 -27
- package/dist/core/runtime/deliver-live.d.ts +16 -4
- package/dist/core/runtime/deliver-live.js +29 -15
- package/dist/core/runtime/kickoff.d.ts +3 -3
- package/dist/core/runtime/kickoff.js +8 -16
- package/dist/core/runtime/lifecycle.js +2 -3
- package/dist/core/runtime/nodes.d.ts +3 -4
- package/dist/core/runtime/nodes.js +3 -4
- package/dist/core/runtime/persona.d.ts +8 -12
- package/dist/core/runtime/persona.js +24 -96
- package/dist/core/runtime/promote.d.ts +2 -2
- package/dist/core/runtime/promote.js +8 -21
- package/dist/core/runtime/revive.js +20 -17
- package/dist/core/runtime/spawn.js +18 -7
- package/dist/core/runtime/tmux-bindings.js +2 -3
- package/dist/core/runtime/warm-pool.js +3 -4
- package/dist/core/scope.js +2 -0
- package/dist/core/self-update.d.ts +0 -2
- package/dist/core/self-update.js +2 -35
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +1 -0
- package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +28 -0
- package/dist/core/substrate/index.d.ts +2 -2
- package/dist/core/substrate/index.js +1 -1
- package/dist/core/substrate/injected-store.d.ts +43 -27
- package/dist/core/substrate/injected-store.js +208 -104
- package/dist/core/substrate/listings.d.ts +19 -12
- package/dist/core/substrate/listings.js +75 -52
- package/dist/core/substrate/on-read-node.d.ts +4 -7
- package/dist/core/substrate/on-read-node.js +6 -8
- package/dist/core/substrate/on-read.d.ts +22 -25
- package/dist/core/substrate/on-read.js +103 -147
- package/dist/core/substrate/render-node.d.ts +4 -7
- package/dist/core/substrate/render-node.js +5 -7
- package/dist/core/substrate/render.d.ts +21 -3
- package/dist/core/substrate/render.js +291 -223
- package/dist/core/substrate/schema.d.ts +1 -13
- package/dist/core/substrate/schema.js +5 -40
- package/dist/core/substrate/session-cache.d.ts +14 -4
- package/dist/core/substrate/session-cache.js +40 -22
- package/dist/core/substrate/surface-match.d.ts +9 -7
- package/dist/core/substrate/surface-match.js +26 -25
- package/dist/daemon/__tests__/helpers/source-daemon.d.ts +30 -0
- package/dist/daemon/__tests__/helpers/source-daemon.js +174 -0
- package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +1 -0
- package/dist/daemon/__tests__/integration/migration-startup.test.js +97 -0
- package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +37 -9
- package/dist/daemon/api/bridge.d.ts +35 -4
- package/dist/daemon/api/bridge.js +50 -8
- package/dist/daemon/api/handlers/broker-ops.js +21 -16
- package/dist/daemon/api/handlers/memory.js +2 -0
- package/dist/daemon/crtrd.js +2 -0
- package/dist/daemon/human/finish.js +8 -1
- package/dist/daemon/manage.d.ts +0 -1
- package/dist/daemon/manage.js +7 -16
- package/dist/daemon/startup-policy.d.ts +1 -0
- package/dist/daemon/startup-policy.js +1 -0
- package/dist/migrations/001-surfaces-frontmatter.js +21 -109
- package/dist/migrations/002-profile-project-memory.js +1 -0
- package/dist/migrations/003-repository-root-memory-identity/front-door.d.ts +26 -0
- package/dist/migrations/003-repository-root-memory-identity/front-door.js +231 -0
- package/dist/migrations/003-repository-root-memory-identity/index.d.ts +2 -0
- package/dist/migrations/003-repository-root-memory-identity/index.js +513 -0
- package/dist/migrations/003-repository-root-memory-identity/references.d.ts +95 -0
- package/dist/migrations/003-repository-root-memory-identity/references.js +469 -0
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.d.ts +39 -0
- package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +349 -0
- package/dist/migrations/__tests__/activation-concurrency.test.d.ts +1 -0
- package/dist/migrations/__tests__/activation-concurrency.test.js +145 -0
- package/dist/migrations/__tests__/activation.test.d.ts +1 -0
- package/dist/migrations/__tests__/activation.test.js +149 -0
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +1 -0
- package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +149 -0
- package/dist/migrations/activation.d.ts +16 -0
- package/dist/migrations/activation.js +78 -0
- package/dist/migrations/convergent.d.ts +14 -3
- package/dist/migrations/convergent.js +21 -10
- package/dist/migrations/corpus.d.ts +78 -0
- package/dist/migrations/corpus.js +497 -0
- package/dist/migrations/frontmatter-splice.d.ts +15 -0
- package/dist/migrations/frontmatter-splice.js +176 -0
- package/dist/migrations/registry.d.ts +6 -1
- package/dist/migrations/registry.js +7 -2
- package/dist/migrations/runner.d.ts +41 -0
- package/dist/migrations/runner.js +81 -0
- package/dist/migrations/types.d.ts +148 -9
- package/dist/migrations/types.js +9 -2
- package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +225 -17
- package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +11 -3
- package/dist/pi-extensions/canvas-context-intro.d.ts +3 -5
- package/dist/pi-extensions/canvas-context-intro.js +50 -46
- package/dist/pi-extensions/canvas-doc-substrate.d.ts +1 -8
- package/dist/pi-extensions/canvas-doc-substrate.js +55 -122
- package/dist/pi-extensions/canvas-stophook.js +6 -13
- package/dist/shared/generated-context.d.ts +0 -3
- package/dist/shared/generated-context.js +0 -57
- package/dist/shared/tool-groups.js +2 -3
- package/package.json +5 -4
- package/runtime.lock.json +2 -2
- /package/dist/api/__tests__/{serial → integration}/client.test.d.ts +0 -0
- /package/dist/api/__tests__/{serial → integration}/client.test.js +0 -0
- /package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/{serial → integration}/provider-rotation.test.ts +0 -0
- /package/dist/clients/{inbox/__tests__/serial/inbox-controller.test.d.ts → attach/__tests__/pane-tag-successor.test.d.ts} +0 -0
- /package/dist/clients/{inbox/__tests__/serial/mount-panel.test.d.ts → attach/__tests__/profile-files.test.d.ts} +0 -0
- /package/dist/{core/__tests__/live-mutation-verbs.test.d.ts → clients/inbox/__tests__/integration/inbox-controller.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{serial → integration}/inbox-controller.test.js +0 -0
- /package/dist/{core/__tests__/serial/broker-fork-seam.test.d.ts → clients/inbox/__tests__/integration/mount-panel.test.d.ts} +0 -0
- /package/dist/clients/inbox/__tests__/{serial → integration}/mount-panel.test.js +0 -0
- /package/dist/{core/__tests__/serial/broker-sdk-wiring.test.d.ts → commands/__tests__/surface-reload-target.test.d.ts} +0 -0
- /package/dist/{core/__tests__/serial/broker-snapshot-history.test.d.ts → commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts} +0 -0
- /package/dist/{core/__tests__/serial/command-plugins.test.d.ts → commands/memory/__tests__/repository-root-lint.test.d.ts} +0 -0
- /package/dist/{core/__tests__/serial/deferred-no-wake.test.d.ts → commands/sys/__tests__/sync-project-guidance.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/flagship-lifecycle.test.d.ts → config-change-delta.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/host-teardown-process-group.test.d.ts → integration/broker-fork-seam.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/human-deliver-e2e.test.d.ts → integration/broker-sdk-wiring.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/live-mutation.test.d.ts → integration/broker-snapshot-history.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/refresh-stall-recycle.test.d.ts → integration/command-plugins.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/revive.test.d.ts → integration/deferred-no-wake.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/spawn-root.test.d.ts → integration/flagship-lifecycle.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/subscription-delivery.test.d.ts → integration/host-teardown-process-group.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/tmux-surface.test.d.ts → integration/human-deliver-e2e.test.d.ts} +0 -0
- /package/dist/core/__tests__/{serial/worktree.test.d.ts → integration/live-mutation-verbs.test.d.ts} +0 -0
- /package/dist/core/{human/__tests__/serial/inbox-core.test.d.ts → __tests__/integration/live-mutation.test.d.ts} +0 -0
- /package/dist/core/human/__tests__/{serial → integration}/inbox-core.test.js +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CorpusBlocker, CorpusSnapshot, FrontDoorAction } from '../types.js';
|
|
2
|
+
import type { RepositoryDecision, StorePrefixFacts } from './repository-facts.js';
|
|
3
|
+
export interface FrontDoorPlan {
|
|
4
|
+
repositoryRoot: string;
|
|
5
|
+
/** The repository-root store's key. */
|
|
6
|
+
storeKey: string;
|
|
7
|
+
rootDocPath: string;
|
|
8
|
+
rootAction: 'kept' | 'created' | 'completed';
|
|
9
|
+
/** The unique legacy front door whose workspace-open entries this run removes. It may live
|
|
10
|
+
* in a nested store of the same repository, so it carries its own store key. */
|
|
11
|
+
leafDocPath: string | null;
|
|
12
|
+
leafStoreKey: string | null;
|
|
13
|
+
/** The leaf's FINAL canonical name, for the created root body's `[[link]]`. */
|
|
14
|
+
leafCanonicalName: string | null;
|
|
15
|
+
action: FrontDoorAction;
|
|
16
|
+
}
|
|
17
|
+
export declare function planFrontDoors(repositories: readonly RepositoryDecision[], prefixes: ReadonlyMap<string, StorePrefixFacts>, corpus: CorpusSnapshot, finalNameOf: (realPath: string) => string | undefined): {
|
|
18
|
+
plans: FrontDoorPlan[];
|
|
19
|
+
blockers: CorpusBlocker[];
|
|
20
|
+
};
|
|
21
|
+
/** New repository-root INDEX.md source. `leafCanonicalName` null yields the generic minimal root body. */
|
|
22
|
+
export declare function rootIndexSource(namespace: string, leafCanonicalName: string | null): string;
|
|
23
|
+
/** Add the missing half or halves of the root front-door pair to a complete document source. */
|
|
24
|
+
export declare function completeRootFrontDoor(source: string, docPath: string): string;
|
|
25
|
+
/** Remove every workspace-open entry while preserving the body and every retained authored YAML byte. */
|
|
26
|
+
export declare function demoteLeafSurfaces(source: string, docPath: string): string;
|
|
@@ -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
|
+
}
|