@north-light/crouter 0.3.227 → 0.3.229
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/04-base-worker.md +1 -1
- package/dist/builtin-memory/insights/init.md +5 -5
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/agent-shaping.md +11 -11
- 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-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/create.d.ts +1 -1
- package/dist/commands/node/create.js +1 -1
- package/dist/commands/node/inspect.js +1 -1
- package/dist/commands/node/lifecycle.js +5 -5
- 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__/review-model-floor.test.js +12 -4
- 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/config.d.ts +3 -3
- package/dist/core/config.js +3 -3
- 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/launch.js +1 -1
- 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 +21 -5
- 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/dist/types.d.ts +8 -11
- package/dist/types.js +4 -31
- package/package.json +5 -4
- package/runtime.lock.json +2 -2
- package/dist/builtin-memory/05-kinds/design/00-base.md +0 -17
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +0 -15
- package/dist/builtin-memory/05-kinds/design/design-contract.md +0 -19
- package/dist/builtin-memory/05-kinds/developer/00-base.md +0 -17
- package/dist/builtin-memory/05-kinds/developer/01-orchestrator.md +0 -15
- package/dist/builtin-memory/05-kinds/plan/00-base.md +0 -17
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +0 -17
- package/dist/builtin-memory/05-kinds/plan/plan-contract.md +0 -28
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +0 -15
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +0 -15
- package/dist/builtin-memory/05-kinds/plan/reviewers/lens-contract.md +0 -13
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +0 -17
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +0 -17
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +0 -17
- package/dist/builtin-memory/05-kinds/spec/00-base.md +0 -17
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +0 -15
- package/dist/builtin-memory/05-kinds/spec/requirements.md +0 -15
- package/dist/builtin-memory/design/guide.md +0 -35
- package/dist/builtin-memory/design/roadmap.md +0 -21
- package/dist/builtin-memory/development.md +0 -113
- package/dist/builtin-memory/plan/roadmap.md +0 -25
- package/dist/builtin-memory/spec/guide.md +0 -53
- package/dist/builtin-memory/spec/requirements.md +0 -29
- package/dist/builtin-memory/spec/roadmap.md +0 -36
- package/dist/builtin-memory/testing.md +0 -39
- /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
|
@@ -113,13 +113,13 @@ export interface NodeIdentity {
|
|
|
113
113
|
kind: string;
|
|
114
114
|
mode: Mode;
|
|
115
115
|
lifecycle: Lifecycle;
|
|
116
|
-
/** The last
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* it here. */
|
|
116
|
+
/** The last {kind,mode,lifecycle} whose context delivery was acknowledged.
|
|
117
|
+
* Meta-only (not a db column). Born equal to the initial persona; later
|
|
118
|
+
* changes advance only after a baseline or provider-gated transition is
|
|
119
|
+
* durably registered. Historical rows may omit `kind`; reads resolve it to
|
|
120
|
+
* the current kind so they do not fabricate a transition. */
|
|
122
121
|
persona_ack?: {
|
|
122
|
+
kind?: string;
|
|
123
123
|
mode: Mode;
|
|
124
124
|
lifecycle: Lifecycle;
|
|
125
125
|
};
|
|
@@ -130,14 +130,10 @@ export interface NodeIdentity {
|
|
|
130
130
|
* `parent` so an INDEPENDENT root (parent=null) still records its lineage.
|
|
131
131
|
* Audit only; null for a user-opened root. Defaults to `parent` for a child. */
|
|
132
132
|
spawned_by?: string | null;
|
|
133
|
-
/**
|
|
134
|
-
* spawn (the node id / session path / pi session uuid the caller passed). pi
|
|
135
|
-
* COPIED that conversation into this node's first session, so the node boots
|
|
136
|
-
* carrying the SOURCE's first-person history. Persisted here so the boot
|
|
137
|
-
* intro can assert this node's OWN identity over that inherited narrative
|
|
138
|
-
* (without it a fork impersonates its source). Undefined for a fresh node;
|
|
139
|
-
* identity/audit only. */
|
|
133
|
+
/** Raw `--fork-from` operand retained for identity framing and audit. */
|
|
140
134
|
fork_from?: string | null;
|
|
135
|
+
/** Resolved absolute source session file used for every pre-bind fork retry. */
|
|
136
|
+
fork_source_file?: string | null;
|
|
141
137
|
/** Immutable review-companion binding. Undefined for ordinary nodes. */
|
|
142
138
|
review_binding?: ReviewBinding | null;
|
|
143
139
|
/** New subscriptions this node opens default to passive when true. */
|
package/dist/core/config.d.ts
CHANGED
|
@@ -147,7 +147,7 @@ export interface MergedLaunchConfig {
|
|
|
147
147
|
* follow-up fix this parameterization exists for). */
|
|
148
148
|
export declare function readMergedLaunchConfig(targetCwd?: string, targetProfileId?: string | null): MergedLaunchConfig;
|
|
149
149
|
/** The effective `KindConfig` for one full kind string (top-level, e.g.
|
|
150
|
-
* `developer`, or sub-kind, e.g. `
|
|
150
|
+
* `developer`, or sub-kind, e.g. `audit/security`), across
|
|
151
151
|
* project > user > builtin precedence. Returns `undefined` for a kind no
|
|
152
152
|
* scope registers — existence is deliberately NOT validated here (kind
|
|
153
153
|
* existence/launch-menu enumeration is a caller concern); this only
|
|
@@ -160,8 +160,8 @@ export declare function resolveKindConfig(kind: string): KindConfig | undefined;
|
|
|
160
160
|
export declare function assertInstalledKind(kind: string): void;
|
|
161
161
|
/** The sub-kinds available to spawn FROM a given top-level kind — every
|
|
162
162
|
* registered sub-kind (full path contains `/`) whose `availableTo` (default:
|
|
163
|
-
* its own top-level ancestor, e.g. `
|
|
164
|
-
* `['
|
|
163
|
+
* its own top-level ancestor, e.g. `audit/security` defaults to
|
|
164
|
+
* `['audit']`) includes `kind` or `'*'`. The single source both `sys
|
|
165
165
|
* prompt-review --list`'s `subPersonas` metadata and the live sub-persona
|
|
166
166
|
* spawn-menu splice (`core/substrate/render.ts`) read, so the two can never
|
|
167
167
|
* drift apart. Sorted by full kind name for stable rendering. */
|
package/dist/core/config.js
CHANGED
|
@@ -796,7 +796,7 @@ export function readMergedLaunchConfig(targetCwd = process.cwd(), targetProfileI
|
|
|
796
796
|
return { kinds, modelLadders, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), spawnEnv };
|
|
797
797
|
}
|
|
798
798
|
/** The effective `KindConfig` for one full kind string (top-level, e.g.
|
|
799
|
-
* `developer`, or sub-kind, e.g. `
|
|
799
|
+
* `developer`, or sub-kind, e.g. `audit/security`), across
|
|
800
800
|
* project > user > builtin precedence. Returns `undefined` for a kind no
|
|
801
801
|
* scope registers — existence is deliberately NOT validated here (kind
|
|
802
802
|
* existence/launch-menu enumeration is a caller concern); this only
|
|
@@ -820,8 +820,8 @@ export function assertInstalledKind(kind) {
|
|
|
820
820
|
}
|
|
821
821
|
/** The sub-kinds available to spawn FROM a given top-level kind — every
|
|
822
822
|
* registered sub-kind (full path contains `/`) whose `availableTo` (default:
|
|
823
|
-
* its own top-level ancestor, e.g. `
|
|
824
|
-
* `['
|
|
823
|
+
* its own top-level ancestor, e.g. `audit/security` defaults to
|
|
824
|
+
* `['audit']`) includes `kind` or `'*'`. The single source both `sys
|
|
825
825
|
* prompt-review --list`'s `subPersonas` metadata and the live sub-persona
|
|
826
826
|
* spawn-menu splice (`core/substrate/render.ts`) read, so the two can never
|
|
827
827
|
* drift apart. Sorted by full kind name for stable rendering. */
|
|
@@ -12,3 +12,5 @@ export interface ExclusiveLockOptions {
|
|
|
12
12
|
* however long its operation runs.
|
|
13
13
|
*/
|
|
14
14
|
export declare function withExclusiveDirectoryLock<T>(path: string, operation: () => T, options?: ExclusiveLockOptions): T;
|
|
15
|
+
/** Run an awaited operation under the same token-checked directory lock. */
|
|
16
|
+
export declare function withExclusiveDirectoryLockAsync<T>(path: string, operation: () => Promise<T>, options?: ExclusiveLockOptions): Promise<T>;
|
|
@@ -5,6 +5,7 @@ const POLL_MS = 10;
|
|
|
5
5
|
const DEFAULT_STALE_MS = 30_000;
|
|
6
6
|
const DEFAULT_TIMEOUT_MS = 5_000;
|
|
7
7
|
function pause(ms) { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms); }
|
|
8
|
+
function pauseAsync(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }
|
|
8
9
|
function markerPath(path, token) { return `${path}/${MARKER_PREFIX}${token}`; }
|
|
9
10
|
function observedMarkerToken(path) {
|
|
10
11
|
try {
|
|
@@ -122,3 +123,23 @@ export function withExclusiveDirectoryLock(path, operation, options = {}) {
|
|
|
122
123
|
rmSync(lock.path, { recursive: true, force: true });
|
|
123
124
|
}
|
|
124
125
|
}
|
|
126
|
+
/** Run an awaited operation under the same token-checked directory lock. */
|
|
127
|
+
export async function withExclusiveDirectoryLockAsync(path, operation, options = {}) {
|
|
128
|
+
const staleMs = options.staleMs ?? DEFAULT_STALE_MS;
|
|
129
|
+
const deadline = Date.now() + (options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
130
|
+
let lock = tryAcquire(path, staleMs);
|
|
131
|
+
while (lock === null) {
|
|
132
|
+
if (Date.now() >= deadline) {
|
|
133
|
+
throw options.timeoutError?.() ?? new Error(`timed out waiting for the exclusive lock: ${path}`);
|
|
134
|
+
}
|
|
135
|
+
await pauseAsync(Math.min(POLL_MS, Math.max(0, deadline - Date.now())));
|
|
136
|
+
lock = tryAcquire(path, staleMs);
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
return await operation();
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
if (existsSync(markerPath(lock.path, lock.token)))
|
|
143
|
+
rmSync(lock.path, { recursive: true, force: true });
|
|
144
|
+
}
|
|
145
|
+
}
|
package/dist/core/git.d.ts
CHANGED
|
@@ -13,7 +13,6 @@ export declare function clone(url: string, dest: string, opts?: {
|
|
|
13
13
|
ref?: string;
|
|
14
14
|
depth?: number;
|
|
15
15
|
}): GitResult;
|
|
16
|
-
export declare function pull(cwd: string): GitResult;
|
|
17
16
|
export declare function fetch(cwd: string, ref?: string): GitResult;
|
|
18
17
|
export declare function lsRemote(url: string): GitResult;
|
|
19
18
|
export declare function currentSha(cwd: string): string | null;
|
package/dist/core/git.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -16,6 +16,7 @@ import { headlessBrokerHost } from '../runtime/host.js';
|
|
|
16
16
|
import { spawnNode } from '../runtime/nodes.js';
|
|
17
17
|
import { reviveNode } from '../runtime/revive.js';
|
|
18
18
|
import { materializeSessionBranchAt } from '../runtime/session-branch.js';
|
|
19
|
+
import { initializeForkContextExposure } from '../substrate/injected-store.js';
|
|
19
20
|
import { pagePath } from './convention.js';
|
|
20
21
|
export function feedbackCompanionBranchPath(dir) { return `${dir}/companion-branch.jsonl`; }
|
|
21
22
|
/** Hex sha256 of the ticket's page document, recorded at first comment so the
|
|
@@ -73,6 +74,7 @@ export async function realizeFeedbackCompanion(args) {
|
|
|
73
74
|
parent: args.senderNodeId,
|
|
74
75
|
subscribe: false,
|
|
75
76
|
forkFrom: branchFile,
|
|
77
|
+
forkSourceFile: branchFile,
|
|
76
78
|
modelOverride: capture.modelSpec,
|
|
77
79
|
reviewBinding: {
|
|
78
80
|
kind: 'page_feedback',
|
|
@@ -85,6 +87,7 @@ export async function realizeFeedbackCompanion(args) {
|
|
|
85
87
|
launch,
|
|
86
88
|
});
|
|
87
89
|
try {
|
|
90
|
+
initializeForkContextExposure(node.node_id, args.senderNodeId);
|
|
88
91
|
reviveNode(node.node_id, { resume: false });
|
|
89
92
|
if (!await awaitCompanionBind(node.node_id, COMPANION_BIND_DEADLINE_MS)) {
|
|
90
93
|
throw new Error(`feedback companion did not bind within ${COMPANION_BIND_DEADLINE_MS}ms`);
|
package/dist/core/human/scan.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readdirSync, statSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readdirSync, statSync } from 'node:fs';
|
|
2
2
|
import { basename, join } from 'node:path';
|
|
3
3
|
import { claimPath, isResolved, pageManifestPath, reviewPath } from './convention.js';
|
|
4
4
|
import { readJsonOrNull } from '../fs-utils.js';
|
|
@@ -27,6 +27,13 @@ function reviewSummary(dir, id) {
|
|
|
27
27
|
return { dir, id, kind: 'review', title: review.title, subtitle: review.subtitle, file: review.file, output: review.output, source: review.source, blockedSince: review.blockedSince, claim: claimSummary(dir) };
|
|
28
28
|
}
|
|
29
29
|
function pageSummary(dir, id) {
|
|
30
|
+
// The tickets root IS the canvas node root, so all but a handful of these
|
|
31
|
+
// directories hold no page at all. Gate on the manifest's presence with one
|
|
32
|
+
// stat instead of letting `parsePage` throw: a thrown ENOENT carries a V8
|
|
33
|
+
// stack capture, which over thousands of node directories is the whole cost
|
|
34
|
+
// of a scan.
|
|
35
|
+
if (!existsSync(pageManifestPath(dir)))
|
|
36
|
+
return null;
|
|
30
37
|
let manifest;
|
|
31
38
|
try {
|
|
32
39
|
manifest = parsePage(dir);
|
|
@@ -4,12 +4,12 @@ type TmuxMenuAction = 'open' | 'attach' | 'show' | 'view-settings' | 'fold-tools
|
|
|
4
4
|
type TmuxMenuEntryAction = Exclude<TmuxMenuAction, 'open' | 'attach'> | `issue.${'idea' | 'bug'}`;
|
|
5
5
|
type GraphAction = 'down' | 'up' | 'first' | 'last' | 'collapse-or-manager' | 'expand-or-child' | 'focus' | 'revive' | 'focus-manager' | 'close-subtree' | 'dismiss';
|
|
6
6
|
type BrowseAction = 'quit' | 'down' | 'up' | 'first' | 'last' | 'expand-or-child' | 'collapse-or-parent' | 'toggle-fold' | 'tab-next' | 'tab-previous' | `tab.${1 | 2 | 3 | 4 | 5}` | 'close-subtree' | 'confirm-close' | 'sort' | 'scope' | 'profile' | 'residents' | 'preview' | 'search' | 'revive-now' | 'focus' | 'focus-background' | 'yank-id';
|
|
7
|
-
type ProfileMenuAction = 'up' | 'down' | 'select' | 'accept-default' | 'abort' | `slot.${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` | 'create' | 'search-existing' | 'use-root' | 'set-default' | 'add-directory' | 'unpin';
|
|
7
|
+
type ProfileMenuAction = 'up' | 'down' | 'select' | 'accept-default' | 'abort' | `slot.${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` | 'create' | 'search-existing' | 'use-root' | 'set-default' | 'add-directory' | 'unpin' | 'manage';
|
|
8
8
|
type SetupAction = 'cancel' | 'tab-next' | 'tab-previous' | 'open' | 'list-down' | 'list-up' | 'toggle' | 'details' | 'advance' | 'cell-previous' | 'cell-next';
|
|
9
9
|
type SetupKeybindingAction = 'edit' | 'commit-edit' | 'cancel-edit' | 'unbind' | 'reset-row' | 'reset-all' | 'save' | 'discard' | 'page-up' | 'page-down' | 'filter' | 'filter-delete' | 'filter-clear';
|
|
10
10
|
type SetupModelsAction = 'open' | 'commit' | 'cancel' | 'scope-next';
|
|
11
11
|
export type BindingId = `crtr.tmux.menu.${TmuxMenuAction}` | `crtr.tmux.menu.issue.${'idea' | 'bug'}` | AttachMenuBindingId | `crtr.tmux.menu-global.${TmuxMenuEntryAction}` | `crtr.tmux.node.${'next' | 'previous'}` | 'crtr.tmux.inbox.toggle' | `crtr.attach.scroll.${'up' | 'down' | 'page-up' | 'page-down' | 'live'}` | 'crtr.attach.mouse.toggle' | 'crtr.attach.copy.message' | 'crtr.attach.help.toggle' | `crtr.attach.search.${'next' | 'previous' | 'edit' | 'close'}` | AttachBindingId | `crtr.graph.${GraphAction}` | `crtr.graph.confirm.${'accept' | 'cancel'}` | `crtr.inspector.${'force-quit' | 'down' | 'up' | 'section-next' | 'section-prev' | 'page-down' | 'page-up' | 'toggle-detail' | 'cancel-item' | 'open-log' | 'confirm' | 'dismiss' | 'retarget' | 'refresh' | 'quit'}` | `crtr.browse.${BrowseAction}` | `crtr.browse.search.${'cancel' | 'commit' | 'delete' | 'quit'}` | `crtr.profile.menu.${ProfileMenuAction}` | `crtr.profile.search.${'up' | 'down' | 'pick' | 'back' | 'delete' | 'abort'}` | `crtr.setup.${SetupAction}` | `crtr.setup.confirm.${'accept' | 'back'}` | `crtr.setup.keybindings.${SetupKeybindingAction}` | `crtr.setup.models.${SetupModelsAction}`;
|
|
12
|
-
export declare const BINDING_CATALOG: readonly [BindingDefinition<"crtr.tmux.menu.open">, BindingDefinition<"crtr.tmux.menu.attach">, ...(BindingDefinition<BindingId> | BindingDefinition<"crtr.tmux.node.next"> | BindingDefinition<"crtr.tmux.node.previous"> | BindingDefinition<"crtr.tmux.inbox.toggle"> | BindingDefinition<"crtr.attach.scroll.up"> | BindingDefinition<"crtr.attach.scroll.down"> | BindingDefinition<"crtr.attach.scroll.page-up"> | BindingDefinition<"crtr.attach.scroll.page-down"> | BindingDefinition<"crtr.attach.scroll.live"> | BindingDefinition<"crtr.attach.mouse.toggle"> | BindingDefinition<"crtr.attach.copy.message"> | BindingDefinition<"crtr.attach.search.next"> | BindingDefinition<"crtr.attach.search.previous"> | BindingDefinition<"crtr.attach.search.edit"> | BindingDefinition<"crtr.attach.search.close"> | BindingDefinition<"crtr.graph.down"> | BindingDefinition<"crtr.graph.up"> | BindingDefinition<"crtr.graph.first"> | BindingDefinition<"crtr.graph.last"> | BindingDefinition<"crtr.graph.collapse-or-manager"> | BindingDefinition<"crtr.graph.expand-or-child"> | BindingDefinition<"crtr.graph.focus"> | BindingDefinition<"crtr.graph.revive"> | BindingDefinition<"crtr.graph.focus-manager"> | BindingDefinition<"crtr.graph.close-subtree"> | BindingDefinition<"crtr.graph.dismiss"> | BindingDefinition<"crtr.graph.confirm.accept"> | BindingDefinition<"crtr.graph.confirm.cancel"> | BindingDefinition<"crtr.inspector.force-quit"> | BindingDefinition<"crtr.inspector.down"> | BindingDefinition<"crtr.inspector.up"> | BindingDefinition<"crtr.inspector.section-next"> | BindingDefinition<"crtr.inspector.section-prev"> | BindingDefinition<"crtr.inspector.page-down"> | BindingDefinition<"crtr.inspector.page-up"> | BindingDefinition<"crtr.inspector.toggle-detail"> | BindingDefinition<"crtr.inspector.cancel-item"> | BindingDefinition<"crtr.inspector.open-log"> | BindingDefinition<"crtr.inspector.confirm"> | BindingDefinition<"crtr.inspector.dismiss"> | BindingDefinition<"crtr.inspector.retarget"> | BindingDefinition<"crtr.inspector.refresh"> | BindingDefinition<"crtr.inspector.quit"> | BindingDefinition<"crtr.browse.quit"> | BindingDefinition<"crtr.browse.down"> | BindingDefinition<"crtr.browse.up"> | BindingDefinition<"crtr.browse.first"> | BindingDefinition<"crtr.browse.last"> | BindingDefinition<"crtr.browse.expand-or-child"> | BindingDefinition<"crtr.browse.collapse-or-parent"> | BindingDefinition<"crtr.browse.toggle-fold"> | BindingDefinition<"crtr.browse.tab-next"> | BindingDefinition<"crtr.browse.tab-previous"> | BindingDefinition<"crtr.browse.tab.2" | "crtr.browse.tab.1" | "crtr.browse.tab.3" | "crtr.browse.tab.4" | "crtr.browse.tab.5"> | BindingDefinition<"crtr.browse.close-subtree"> | BindingDefinition<"crtr.browse.confirm-close"> | BindingDefinition<"crtr.browse.sort"> | BindingDefinition<"crtr.browse.scope"> | BindingDefinition<"crtr.browse.profile"> | BindingDefinition<"crtr.browse.residents"> | BindingDefinition<"crtr.browse.preview"> | BindingDefinition<"crtr.browse.search"> | BindingDefinition<"crtr.browse.revive-now"> | BindingDefinition<"crtr.browse.focus"> | BindingDefinition<"crtr.browse.focus-background"> | BindingDefinition<"crtr.browse.yank-id"> | BindingDefinition<"crtr.browse.search.cancel"> | BindingDefinition<"crtr.browse.search.commit"> | BindingDefinition<"crtr.browse.search.delete"> | BindingDefinition<"crtr.browse.search.quit"> | BindingDefinition<"crtr.profile.menu.up"> | BindingDefinition<"crtr.profile.menu.down"> | BindingDefinition<"crtr.profile.menu.select"> | BindingDefinition<"crtr.profile.menu.accept-default"> | BindingDefinition<"crtr.profile.menu.abort"> | BindingDefinition<"crtr.profile.menu.slot.2" | "crtr.profile.menu.slot.1" | "crtr.profile.menu.slot.3" | "crtr.profile.menu.slot.4" | "crtr.profile.menu.slot.5" | "crtr.profile.menu.slot.6" | "crtr.profile.menu.slot.7" | "crtr.profile.menu.slot.8" | "crtr.profile.menu.slot.9">)[], BindingDefinition<"crtr.profile.menu.create">, BindingDefinition<"crtr.profile.menu.search-existing">, BindingDefinition<"crtr.profile.menu.use-root">, BindingDefinition<"crtr.profile.menu.set-default">, BindingDefinition<"crtr.profile.menu.add-directory">, BindingDefinition<"crtr.profile.menu.unpin">, BindingDefinition<"crtr.profile.search.up">, BindingDefinition<"crtr.profile.search.down">, BindingDefinition<"crtr.profile.search.pick">, BindingDefinition<"crtr.profile.search.back">, BindingDefinition<"crtr.profile.search.delete">, BindingDefinition<"crtr.profile.search.abort">, BindingDefinition<"crtr.setup.cancel">, BindingDefinition<"crtr.setup.tab-next">, BindingDefinition<"crtr.setup.tab-previous">, BindingDefinition<"crtr.setup.open">, BindingDefinition<"crtr.setup.list-down">, BindingDefinition<"crtr.setup.list-up">, BindingDefinition<"crtr.setup.toggle">, BindingDefinition<"crtr.setup.details">, BindingDefinition<"crtr.setup.advance">, BindingDefinition<"crtr.setup.confirm.accept">, BindingDefinition<"crtr.setup.confirm.back">, BindingDefinition<"crtr.setup.keybindings.edit">, BindingDefinition<"crtr.setup.keybindings.commit-edit">, BindingDefinition<"crtr.setup.keybindings.cancel-edit">, BindingDefinition<"crtr.setup.keybindings.unbind">, BindingDefinition<"crtr.setup.keybindings.reset-row">, BindingDefinition<"crtr.setup.keybindings.reset-all">, BindingDefinition<"crtr.setup.keybindings.save">, BindingDefinition<"crtr.setup.keybindings.discard">, BindingDefinition<"crtr.setup.keybindings.page-up">, BindingDefinition<"crtr.setup.keybindings.page-down">, BindingDefinition<"crtr.setup.keybindings.filter">, BindingDefinition<"crtr.setup.keybindings.filter-delete">, BindingDefinition<"crtr.setup.keybindings.filter-clear">, BindingDefinition<"crtr.setup.cell-previous">, BindingDefinition<"crtr.setup.cell-next">, BindingDefinition<"crtr.setup.models.open">, BindingDefinition<"crtr.setup.models.scope-next">, BindingDefinition<"crtr.setup.models.commit">, BindingDefinition<"crtr.setup.models.cancel">];
|
|
12
|
+
export declare const BINDING_CATALOG: readonly [BindingDefinition<"crtr.tmux.menu.open">, BindingDefinition<"crtr.tmux.menu.attach">, ...(BindingDefinition<BindingId> | BindingDefinition<"crtr.tmux.node.next"> | BindingDefinition<"crtr.tmux.node.previous"> | BindingDefinition<"crtr.tmux.inbox.toggle"> | BindingDefinition<"crtr.attach.scroll.up"> | BindingDefinition<"crtr.attach.scroll.down"> | BindingDefinition<"crtr.attach.scroll.page-up"> | BindingDefinition<"crtr.attach.scroll.page-down"> | BindingDefinition<"crtr.attach.scroll.live"> | BindingDefinition<"crtr.attach.mouse.toggle"> | BindingDefinition<"crtr.attach.copy.message"> | BindingDefinition<"crtr.attach.search.next"> | BindingDefinition<"crtr.attach.search.previous"> | BindingDefinition<"crtr.attach.search.edit"> | BindingDefinition<"crtr.attach.search.close"> | BindingDefinition<"crtr.graph.down"> | BindingDefinition<"crtr.graph.up"> | BindingDefinition<"crtr.graph.first"> | BindingDefinition<"crtr.graph.last"> | BindingDefinition<"crtr.graph.collapse-or-manager"> | BindingDefinition<"crtr.graph.expand-or-child"> | BindingDefinition<"crtr.graph.focus"> | BindingDefinition<"crtr.graph.revive"> | BindingDefinition<"crtr.graph.focus-manager"> | BindingDefinition<"crtr.graph.close-subtree"> | BindingDefinition<"crtr.graph.dismiss"> | BindingDefinition<"crtr.graph.confirm.accept"> | BindingDefinition<"crtr.graph.confirm.cancel"> | BindingDefinition<"crtr.inspector.force-quit"> | BindingDefinition<"crtr.inspector.down"> | BindingDefinition<"crtr.inspector.up"> | BindingDefinition<"crtr.inspector.section-next"> | BindingDefinition<"crtr.inspector.section-prev"> | BindingDefinition<"crtr.inspector.page-down"> | BindingDefinition<"crtr.inspector.page-up"> | BindingDefinition<"crtr.inspector.toggle-detail"> | BindingDefinition<"crtr.inspector.cancel-item"> | BindingDefinition<"crtr.inspector.open-log"> | BindingDefinition<"crtr.inspector.confirm"> | BindingDefinition<"crtr.inspector.dismiss"> | BindingDefinition<"crtr.inspector.retarget"> | BindingDefinition<"crtr.inspector.refresh"> | BindingDefinition<"crtr.inspector.quit"> | BindingDefinition<"crtr.browse.quit"> | BindingDefinition<"crtr.browse.down"> | BindingDefinition<"crtr.browse.up"> | BindingDefinition<"crtr.browse.first"> | BindingDefinition<"crtr.browse.last"> | BindingDefinition<"crtr.browse.expand-or-child"> | BindingDefinition<"crtr.browse.collapse-or-parent"> | BindingDefinition<"crtr.browse.toggle-fold"> | BindingDefinition<"crtr.browse.tab-next"> | BindingDefinition<"crtr.browse.tab-previous"> | BindingDefinition<"crtr.browse.tab.2" | "crtr.browse.tab.1" | "crtr.browse.tab.3" | "crtr.browse.tab.4" | "crtr.browse.tab.5"> | BindingDefinition<"crtr.browse.close-subtree"> | BindingDefinition<"crtr.browse.confirm-close"> | BindingDefinition<"crtr.browse.sort"> | BindingDefinition<"crtr.browse.scope"> | BindingDefinition<"crtr.browse.profile"> | BindingDefinition<"crtr.browse.residents"> | BindingDefinition<"crtr.browse.preview"> | BindingDefinition<"crtr.browse.search"> | BindingDefinition<"crtr.browse.revive-now"> | BindingDefinition<"crtr.browse.focus"> | BindingDefinition<"crtr.browse.focus-background"> | BindingDefinition<"crtr.browse.yank-id"> | BindingDefinition<"crtr.browse.search.cancel"> | BindingDefinition<"crtr.browse.search.commit"> | BindingDefinition<"crtr.browse.search.delete"> | BindingDefinition<"crtr.browse.search.quit"> | BindingDefinition<"crtr.profile.menu.up"> | BindingDefinition<"crtr.profile.menu.down"> | BindingDefinition<"crtr.profile.menu.select"> | BindingDefinition<"crtr.profile.menu.accept-default"> | BindingDefinition<"crtr.profile.menu.abort"> | BindingDefinition<"crtr.profile.menu.slot.2" | "crtr.profile.menu.slot.1" | "crtr.profile.menu.slot.3" | "crtr.profile.menu.slot.4" | "crtr.profile.menu.slot.5" | "crtr.profile.menu.slot.6" | "crtr.profile.menu.slot.7" | "crtr.profile.menu.slot.8" | "crtr.profile.menu.slot.9">)[], BindingDefinition<"crtr.profile.menu.create">, BindingDefinition<"crtr.profile.menu.search-existing">, BindingDefinition<"crtr.profile.menu.use-root">, BindingDefinition<"crtr.profile.menu.set-default">, BindingDefinition<"crtr.profile.menu.add-directory">, BindingDefinition<"crtr.profile.menu.unpin">, BindingDefinition<"crtr.profile.menu.manage">, BindingDefinition<"crtr.profile.search.up">, BindingDefinition<"crtr.profile.search.down">, BindingDefinition<"crtr.profile.search.pick">, BindingDefinition<"crtr.profile.search.back">, BindingDefinition<"crtr.profile.search.delete">, BindingDefinition<"crtr.profile.search.abort">, BindingDefinition<"crtr.setup.cancel">, BindingDefinition<"crtr.setup.tab-next">, BindingDefinition<"crtr.setup.tab-previous">, BindingDefinition<"crtr.setup.open">, BindingDefinition<"crtr.setup.list-down">, BindingDefinition<"crtr.setup.list-up">, BindingDefinition<"crtr.setup.toggle">, BindingDefinition<"crtr.setup.details">, BindingDefinition<"crtr.setup.advance">, BindingDefinition<"crtr.setup.confirm.accept">, BindingDefinition<"crtr.setup.confirm.back">, BindingDefinition<"crtr.setup.keybindings.edit">, BindingDefinition<"crtr.setup.keybindings.commit-edit">, BindingDefinition<"crtr.setup.keybindings.cancel-edit">, BindingDefinition<"crtr.setup.keybindings.unbind">, BindingDefinition<"crtr.setup.keybindings.reset-row">, BindingDefinition<"crtr.setup.keybindings.reset-all">, BindingDefinition<"crtr.setup.keybindings.save">, BindingDefinition<"crtr.setup.keybindings.discard">, BindingDefinition<"crtr.setup.keybindings.page-up">, BindingDefinition<"crtr.setup.keybindings.page-down">, BindingDefinition<"crtr.setup.keybindings.filter">, BindingDefinition<"crtr.setup.keybindings.filter-delete">, BindingDefinition<"crtr.setup.keybindings.filter-clear">, BindingDefinition<"crtr.setup.cell-previous">, BindingDefinition<"crtr.setup.cell-next">, BindingDefinition<"crtr.setup.models.open">, BindingDefinition<"crtr.setup.models.scope-next">, BindingDefinition<"crtr.setup.models.commit">, BindingDefinition<"crtr.setup.models.cancel">];
|
|
13
13
|
export declare const BINDING_IDS: ReadonlySet<string>;
|
|
14
14
|
/** True for an action whose direct gesture is handled inside an attach viewer.
|
|
15
15
|
* Tmux menu selectors and root shortcuts are chrome, not pane input. */
|
|
@@ -77,7 +77,7 @@ export const BINDING_CATALOG = Object.freeze([
|
|
|
77
77
|
...attachEntry('crtr.tmux.menu.attach.model-ladder.previous', 'crtr.attach.model-ladder.previous', 'Previous model', 'Move to the previous model ladder rung.', ['['], ['alt+shift+m']),
|
|
78
78
|
...attachEntry('crtr.tmux.menu.attach.command.inspect', 'crtr.attach.command.inspect', 'Inspect loaded command', 'Open the loaded slash command’s expanded prompt.', ['h'], ['alt+shift+h']),
|
|
79
79
|
...attachEntry('crtr.tmux.menu.attach.file-review', 'crtr.attach.file-review', 'Review a file', 'Open a line-anchored review of a file named in the transcript.', [], ['alt+shift+r']),
|
|
80
|
-
...attachEntry('crtr.tmux.menu.attach.profile-files', 'crtr.attach.profile-files', 'Search profile files', '
|
|
80
|
+
...attachEntry('crtr.tmux.menu.attach.profile-files', 'crtr.attach.profile-files', 'Search profile files', 'Fuzzy-match path segments across the node family’s working directories, profile projects and memory, and ancestor crouter memory stores; Ctrl+Y copies a selected path.', ['f'], ['ctrl+f']),
|
|
81
81
|
...attachEntry('crtr.tmux.menu.attach.search', 'crtr.attach.search', 'Search transcript', 'Search the transcript as it is currently displayed — folded tool output is not searched until it is unfolded.', ['/'], ['alt+/']),
|
|
82
82
|
...attachEntry('crtr.tmux.menu.attach.whip', 'crtr.attach.whip', 'Whip agent', 'Interrupt the agent and send a playful command.', ['w'], []),
|
|
83
83
|
b('crtr.attach.scroll.up', 'Attach', 'Scroll up', 'Scroll the transcript one line up.', ['shift+up'], 'terminal', ATTACH_CONTEXTS),
|
|
@@ -171,6 +171,7 @@ function profileBindings() {
|
|
|
171
171
|
b('crtr.profile.menu.set-default', 'Profiles', 'Set default', 'Set the selected profile as default.', ['d'], 'terminal', [menu]),
|
|
172
172
|
b('crtr.profile.menu.add-directory', 'Profiles', 'Add directory', 'Add a directory to the profile.', ['a'], 'terminal', [menu]),
|
|
173
173
|
b('crtr.profile.menu.unpin', 'Profiles', 'Unpin directory', 'Unpin the selected directory.', ['u'], 'terminal', [menu]),
|
|
174
|
+
b('crtr.profile.menu.manage', 'Profiles', 'Manage profiles', 'Open the profiles settings page in a popup.', ['v'], 'terminal', [menu]),
|
|
174
175
|
b('crtr.profile.search.up', 'Profiles', 'Move up', 'Move to the previous search result.', ['up', 'ctrl+p'], 'terminal', [search]),
|
|
175
176
|
b('crtr.profile.search.down', 'Profiles', 'Move down', 'Move to the next search result.', ['down', 'ctrl+n'], 'terminal', [search]),
|
|
176
177
|
b('crtr.profile.search.pick', 'Profiles', 'Pick profile', 'Pick the highlighted profile.', ['enter'], 'terminal', [search]),
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
// This module never resolves anything: `findDocLinks` returns candidate links;
|
|
17
17
|
// a caller decides a link is live by testing `name` against the corpus of
|
|
18
18
|
// resolvable canonical names.
|
|
19
|
-
// A canonical doc name: one or more `[A-Za-z0-
|
|
19
|
+
// A canonical doc name: one or more `[A-Za-z0-9._-]+` segments joined by `/`.
|
|
20
20
|
// Anything else between `[[` `]]` (spaces, `|` aliases, empty segments) is NOT
|
|
21
21
|
// a doc link — the grammar has no alias/label form, by design.
|
|
22
|
-
const NAME_RE = /^[A-Za-z0-
|
|
22
|
+
const NAME_RE = /^[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)*$/;
|
|
23
23
|
const LINK_RE = /\[\[([^\[\]\n]+)\]\]/g;
|
|
24
24
|
/** Is `name` a well-formed canonical doc-link name? */
|
|
25
25
|
export function isDocLinkName(name) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { MemoryDoc } from '../memory-resolver.js';
|
|
1
2
|
/** Sidecar tree name under a store's `memory/` dir. Dot-prefixed and holding
|
|
2
3
|
* only `.jsonl`, so every substrate scan (which filters to `*.md`, and in
|
|
3
4
|
* `lint`'s case skips dot-dirs outright) passes it over without an exclusion
|
|
@@ -37,6 +38,29 @@ export declare function buildHistoryRecord(input: {
|
|
|
37
38
|
before: string;
|
|
38
39
|
after: string;
|
|
39
40
|
}): HistoryRecord;
|
|
41
|
+
/** Derive a live document's sidecar from its descriptor. The descriptor's
|
|
42
|
+
* physical path is authoritative: canonical names carry a project namespace,
|
|
43
|
+
* while sidecars remain in the owning store's physical tree. */
|
|
44
|
+
export declare function historyLogPathForDoc(doc: Pick<MemoryDoc, 'root' | 'path'>): string;
|
|
45
|
+
export interface DeletedHistoryCandidate {
|
|
46
|
+
path: string;
|
|
47
|
+
representation: 'directory-index' | 'leaf-file';
|
|
48
|
+
winner: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface DeletedHistoryResolution {
|
|
51
|
+
logPath: string;
|
|
52
|
+
candidates: readonly DeletedHistoryCandidate[];
|
|
53
|
+
collision?: {
|
|
54
|
+
paths: readonly string[];
|
|
55
|
+
winner: string;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** Resolve a deleted document's physical history without reintroducing a
|
|
59
|
+
* canonical-name fallback. `localName` is already stripped of the selected
|
|
60
|
+
* project's exact namespace. The directory-index sidecar is deliberately
|
|
61
|
+
* probed first, and therefore wins deterministically if both physical forms
|
|
62
|
+
* survive; callers can expose `candidates`/`collision` for diagnostics. */
|
|
63
|
+
export declare function resolveDeletedHistoryLogPath(storeRoot: string, localName: string): DeletedHistoryResolution | null;
|
|
40
64
|
/** Append one record. Single write of one line — concurrent appends interleave
|
|
41
65
|
* whole records, and every record stands alone, so no lock is needed. */
|
|
42
66
|
export declare function appendHistoryRecord(logPath: string, record: HistoryRecord): void;
|
|
@@ -10,11 +10,12 @@
|
|
|
10
10
|
// The raw file is the consumer contract: an external reader (a product surface
|
|
11
11
|
// reading a store off disk) parses one JSON object per line and computes its
|
|
12
12
|
// own diffs. Nothing here shells out to git.
|
|
13
|
-
import { appendFileSync } from 'node:fs';
|
|
13
|
+
import { appendFileSync, readdirSync } from 'node:fs';
|
|
14
14
|
import { dirname, join, relative } from 'node:path';
|
|
15
15
|
import { ensureDir, pathExists, readText } from '../fs-utils.js';
|
|
16
16
|
import { general } from '../errors.js';
|
|
17
17
|
import { parseFrontmatterGeneric } from '../frontmatter.js';
|
|
18
|
+
import { normalizeNameSegment } from './identity.js';
|
|
18
19
|
/** Sidecar tree name under a store's `memory/` dir. Dot-prefixed and holding
|
|
19
20
|
* only `.jsonl`, so every substrate scan (which filters to `*.md`, and in
|
|
20
21
|
* `lint`'s case skips dot-dirs outright) passes it over without an exclusion
|
|
@@ -48,6 +49,70 @@ export function buildHistoryRecord(input) {
|
|
|
48
49
|
};
|
|
49
50
|
return record;
|
|
50
51
|
}
|
|
52
|
+
/** Derive a live document's sidecar from its descriptor. The descriptor's
|
|
53
|
+
* physical path is authoritative: canonical names carry a project namespace,
|
|
54
|
+
* while sidecars remain in the owning store's physical tree. */
|
|
55
|
+
export function historyLogPathForDoc(doc) {
|
|
56
|
+
return historyLogPathFor(doc.root, doc.path);
|
|
57
|
+
}
|
|
58
|
+
function matchingDirs(parent, segment) {
|
|
59
|
+
let entries;
|
|
60
|
+
try {
|
|
61
|
+
entries = readdirSync(parent, { withFileTypes: true });
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
return entries
|
|
67
|
+
.filter((entry) => entry.isDirectory() && normalizeNameSegment(entry.name) === segment)
|
|
68
|
+
.sort((a, b) => (a.name === segment ? -1 : b.name === segment ? 1 : a.name.localeCompare(b.name)))
|
|
69
|
+
.map((entry) => join(parent, entry.name));
|
|
70
|
+
}
|
|
71
|
+
function matchingFiles(parent, stem) {
|
|
72
|
+
let entries;
|
|
73
|
+
try {
|
|
74
|
+
entries = readdirSync(parent, { withFileTypes: true });
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
return entries
|
|
80
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.jsonl') && normalizeNameSegment(entry.name.slice(0, -'.jsonl'.length)) === stem)
|
|
81
|
+
.sort((a, b) => (a.name === `${stem}.jsonl` ? -1 : b.name === `${stem}.jsonl` ? 1 : a.name.localeCompare(b.name)))
|
|
82
|
+
.map((entry) => join(parent, entry.name));
|
|
83
|
+
}
|
|
84
|
+
function historyFilesForSegments(historyDir, segments, stem) {
|
|
85
|
+
let parents = [historyDir];
|
|
86
|
+
for (const segment of segments) {
|
|
87
|
+
parents = parents.flatMap((parent) => matchingDirs(parent, segment));
|
|
88
|
+
if (parents.length === 0)
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return parents.flatMap((parent) => matchingFiles(parent, stem));
|
|
92
|
+
}
|
|
93
|
+
/** Resolve a deleted document's physical history without reintroducing a
|
|
94
|
+
* canonical-name fallback. `localName` is already stripped of the selected
|
|
95
|
+
* project's exact namespace. The directory-index sidecar is deliberately
|
|
96
|
+
* probed first, and therefore wins deterministically if both physical forms
|
|
97
|
+
* survive; callers can expose `candidates`/`collision` for diagnostics. */
|
|
98
|
+
export function resolveDeletedHistoryLogPath(storeRoot, localName) {
|
|
99
|
+
const segments = localName.split('/').filter((segment) => segment !== '').map(normalizeNameSegment);
|
|
100
|
+
const historyDir = join(storeRoot, HISTORY_DIR);
|
|
101
|
+
const indexPaths = historyFilesForSegments(historyDir, segments, 'INDEX');
|
|
102
|
+
const leafPaths = segments.length === 0 ? [] : historyFilesForSegments(historyDir, segments.slice(0, -1), segments[segments.length - 1]);
|
|
103
|
+
const candidates = [
|
|
104
|
+
...indexPaths.map((path) => ({ path, representation: 'directory-index', winner: false })),
|
|
105
|
+
...leafPaths.map((path) => ({ path, representation: 'leaf-file', winner: false })),
|
|
106
|
+
];
|
|
107
|
+
if (candidates.length === 0)
|
|
108
|
+
return null;
|
|
109
|
+
candidates[0].winner = true;
|
|
110
|
+
return {
|
|
111
|
+
logPath: candidates[0].path,
|
|
112
|
+
candidates,
|
|
113
|
+
...(candidates.length > 1 ? { collision: { paths: candidates.map((candidate) => candidate.path), winner: candidates[0].path } } : {}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
51
116
|
/** Append one record. Single write of one line — concurrent appends interleave
|
|
52
117
|
* whole records, and every record stands alone, so no lock is needed. */
|
|
53
118
|
export function appendHistoryRecord(logPath, record) {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** The filename (and path segment) whose document fronts its directory. */
|
|
2
|
+
export declare const INDEX_SEGMENT = "INDEX";
|
|
3
|
+
/** Strip an optional `NN-` ordering prefix from ONE segment. */
|
|
4
|
+
export declare function normalizeNameSegment(segment: string): string;
|
|
5
|
+
/** Slugify one authored or filesystem label into a canonical segment. */
|
|
6
|
+
export declare function slugCanonicalSegment(raw: string): string;
|
|
7
|
+
/** Slugify a derived label into canonical path segments. Empty segments are
|
|
8
|
+
* intentionally dropped; owner paths use slugCanonicalSegment directly. */
|
|
9
|
+
export declare function slugCanonicalPath(raw: string): string;
|
|
10
|
+
/** Strip the ordering prefix from EVERY segment of a slash-separated name:
|
|
11
|
+
* `01-spine/00-has-manager` -> `spine/has-manager`. */
|
|
12
|
+
export declare function normalizeDocName(name: string): string;
|
|
13
|
+
/** Split a name into segments, dropping empties from `//`, a leading `/`, or an
|
|
14
|
+
* empty name. */
|
|
15
|
+
export declare function canonicalSegments(name: string): string[];
|
|
16
|
+
/** The canonical directory containing `name`, or `''` at the top. */
|
|
17
|
+
export declare function canonicalParent(name: string): string;
|
|
18
|
+
/** Remove EXACTLY ONE trailing `INDEX` segment. `a/INDEX` -> `a`; `INDEX` ->
|
|
19
|
+
* `''` (a store root); `a/INDEX/INDEX` -> `a/INDEX` (the inner segment is an
|
|
20
|
+
* ordinary directory name). */
|
|
21
|
+
export declare function collapseTrailingIndex(name: string): string;
|
|
22
|
+
export type DocRepresentation = 'leaf-file' | 'directory-index';
|
|
23
|
+
/** Which form a store-relative markdown path takes. */
|
|
24
|
+
export declare function representationForPath(physicalRelativePath: string): DocRepresentation;
|
|
25
|
+
/** Store-local name derived from a store-relative markdown path: ordering
|
|
26
|
+
* prefixes stripped from every segment and one trailing `INDEX` collapsed.
|
|
27
|
+
* Empty only for a store root `INDEX.md`. */
|
|
28
|
+
export declare function localNameFromPath(physicalRelativePath: string): string;
|
|
29
|
+
/** The store-relative markdown path a local name occupies in a given form.
|
|
30
|
+
* Both forms are checked before any create or move, so occupancy never depends
|
|
31
|
+
* on which one a store happens to use. */
|
|
32
|
+
export declare function physicalRelativePathFor(localName: string, representation: DocRepresentation): string;
|
|
33
|
+
/** A document's explicit frontmatter `name` as a local name — normalized with
|
|
34
|
+
* one trailing `INDEX` collapsed — or `null` when it carries none. */
|
|
35
|
+
export declare function explicitLocalName(fm: Record<string, unknown> | null | undefined): string | null;
|
|
36
|
+
/** A document's store-local name: its explicit frontmatter `name` when present,
|
|
37
|
+
* else the path-derived local name. Explicit names are local to their store —
|
|
38
|
+
* they never carry the store's namespace. */
|
|
39
|
+
export declare function resolveLocalName(fm: Record<string, unknown> | null | undefined, pathDerivedLocalName: string): string;
|
|
40
|
+
/** namespace ⊕ local — the only address. Composition is unconditional: a local
|
|
41
|
+
* name that already looks namespace-prefixed is composed anyway, so identity
|
|
42
|
+
* never depends on string coincidence. An empty result means a namespace-less
|
|
43
|
+
* store root, which has no valid canonical identity. */
|
|
44
|
+
export declare function composeCanonicalName(namespace: string, localName: string): string;
|
|
45
|
+
/** The canonical directory a document's `./` memory-read entries match against:
|
|
46
|
+
* a directory document anchors at its own name, an ordinary leaf at its
|
|
47
|
+
* canonical parent. */
|
|
48
|
+
export declare function routingAnchorFor(canonicalName: string, representation: DocRepresentation): string;
|
|
49
|
+
/** The local name a canonical name has inside `namespace`, or `null` when it
|
|
50
|
+
* falls outside it. Exact on segment boundaries: `a/bc` is not inside `a/b`.
|
|
51
|
+
* The namespace itself yields `''` — the store root document. */
|
|
52
|
+
export declare function stripNamespace(canonicalName: string, namespace: string): string | null;
|
|
53
|
+
export type IdentityValidation = {
|
|
54
|
+
ok: true;
|
|
55
|
+
} | {
|
|
56
|
+
ok: false;
|
|
57
|
+
reason: string;
|
|
58
|
+
};
|
|
59
|
+
/** A project store's declared namespace, or an installed plugin's mount prefix:
|
|
60
|
+
* one or more normalized segments, never ending in `INDEX`. */
|
|
61
|
+
export declare function validateNamespace(namespace: string): IdentityValidation;
|
|
62
|
+
/** An explicit non-root `name:`: a non-empty local name, never ending in
|
|
63
|
+
* `INDEX` (its directory name is the identity) and never carrying its own
|
|
64
|
+
* store's namespace. */
|
|
65
|
+
export declare function validateExplicitLocalName(localName: string, namespace?: string): IdentityValidation;
|