@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
|
@@ -5,29 +5,9 @@
|
|
|
5
5
|
// (registered in CANVAS_EXTENSIONS, src/core/runtime/launch.ts). INERT when
|
|
6
6
|
// CRTR_NODE_ID is absent (a plain pi session or legacy job agent loads it as a no-op).
|
|
7
7
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
// `<memory kind="preference">` block (memory-usage guidance + preferences)
|
|
12
|
-
// into `event.systemPrompt`, right after pi's native "Available tools" list
|
|
13
|
-
// (before the `\n\nGuidelines:` anchor), so the substrate's standing
|
|
14
|
-
// directives sit in the tool-selection frame the agent reads while choosing
|
|
15
|
-
// a capability. Falls back to appending when the anchor is absent. (The `<memory kind="knowledge">`
|
|
16
|
-
// catalog rides the bearings message instead — see core/substrate/render.ts.)
|
|
17
|
-
//
|
|
18
|
-
// 2. tool_result (gated on `read` and `bash`) — the EVENT half. For each
|
|
19
|
-
// non-error `read`, evaluates the read file against every doc's `read`
|
|
20
|
-
// surfaces entries across the resolved corpus and any project stores
|
|
21
|
-
// enclosing the read file; for each non-error `bash`, evaluates the
|
|
22
|
-
// executed command string against every doc's `command` entries. Matches
|
|
23
|
-
// render at their matched rung in `<auto-loaded-context>` before the
|
|
24
|
-
// tool output. A transcript-scoped (realpath → rung) map deduplicates
|
|
25
|
-
// repeated deliveries and resumed broker processes.
|
|
26
|
-
//
|
|
27
|
-
// Both handler bodies are wrapped in try/catch and degrade to INERT on error —
|
|
28
|
-
// a substrate bug must never brick node boot or break a `read`, only quietly
|
|
29
|
-
// stop surfacing docs. The pure render lives in core/substrate/ (render.ts +
|
|
30
|
-
// on-read.ts); this file is only the pi-hook plumbing.
|
|
8
|
+
// before_agent_start splices the context's frozen preference snapshot after the
|
|
9
|
+
// native tool list. Successful read/bash results append matching memory through
|
|
10
|
+
// the shared context exposure state. Pure rendering lives in core/substrate/.
|
|
31
11
|
//
|
|
32
12
|
// Plain TS-with-types — NO imports from @earendil-works/* (a local structural
|
|
33
13
|
// PiLike interface stands in), so it compiles inside crouter's own tsc build
|
|
@@ -38,7 +18,7 @@ import { brokerExtensionState } from '../core/runtime/broker/daemon-ops.js';
|
|
|
38
18
|
import { renderPreferencesFromState } from '../core/runtime/broker-extension-render.js';
|
|
39
19
|
import { renderOnCommandDocsForSubject, renderOnReadDocsForSubject } from '../core/substrate/on-read.js';
|
|
40
20
|
import { clearSessionCache } from '../core/substrate/session-cache.js';
|
|
41
|
-
import {
|
|
21
|
+
import { cloneContextExposureState, exposureTarget, freezePreferenceSnapshot, loadContextExposureState, mergeContextExposureState, replaceContextExposureState, saveContextExposureState, sharedContextExposureState, } from '../core/substrate/injected-store.js';
|
|
42
22
|
import { autoLoadedContextInner, mergeAutoLoadedContext } from './envelope-merge.js';
|
|
43
23
|
// ---------------------------------------------------------------------------
|
|
44
24
|
// Extension
|
|
@@ -48,120 +28,73 @@ import { autoLoadedContextInner, mergeAutoLoadedContext } from './envelope-merge
|
|
|
48
28
|
* to reach for while reading the tools, so memory docs/preferences must sit
|
|
49
29
|
* there, not far below. Falls back to appending if absent. */
|
|
50
30
|
const TOOLS_ANCHOR = '\n\nGuidelines:';
|
|
51
|
-
/**
|
|
52
|
-
* Register the document substrate's pi hooks on `pi`.
|
|
53
|
-
*
|
|
54
|
-
* Returns immediately (inert) when CRTR_NODE_ID is absent — a non-canvas pi
|
|
55
|
-
* session gets no hooks. Each handler is independently wrapped so a failure
|
|
56
|
-
* degrades to a no-op (boot proceeds, the read returns) rather than bricking.
|
|
57
|
-
*/
|
|
58
31
|
export function registerCanvasDocSubstrate(pi) {
|
|
59
32
|
const nodeId = process.env['CRTR_NODE_ID'];
|
|
60
33
|
if (nodeId === undefined || nodeId.trim() === '')
|
|
61
34
|
return; // not a canvas node — inert
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
// the set is REHYDRATED from disk at process start (not started empty) and is
|
|
66
|
-
// NOT cleared on session_start — a resume continues the transcript, so the
|
|
67
|
-
// dedup must carry forward. The one launch path that begins a FRESH transcript
|
|
68
|
-
// (reviveNode with resume=false) deletes the file, so a new conversation
|
|
69
|
-
// rehydrates empty here. See core/substrate/injected-store.ts.
|
|
70
|
-
//
|
|
71
|
-
// The set is the PROCESS-SHARED instance (sharedInjectedDocs), so the
|
|
72
|
-
// context-intro extension's workspace-open render grows the same set this
|
|
73
|
-
// hook dedups against — a front door delivered at boot never re-delivers on
|
|
74
|
-
// a later read beneath its store.
|
|
75
|
-
const injectedDocs = sharedInjectedDocs(nodeId);
|
|
35
|
+
// One in-place state object is shared with context-intro and rehydrated on a
|
|
36
|
+
// strict resume. New-context launch paths clear it before baseline assembly.
|
|
37
|
+
const contextExposure = sharedContextExposureState(nodeId);
|
|
76
38
|
pi.on('session_start', () => {
|
|
77
|
-
// Only the per-session substrate PARSE cache resets each session (so the
|
|
78
|
-
// corpus is re-scanned, picking up memory writes). injectedDocs is
|
|
79
|
-
// transcript-scoped, not session-scoped — deliberately NOT cleared here.
|
|
80
39
|
clearSessionCache();
|
|
81
40
|
});
|
|
82
|
-
// 1. BOOT system-prompt half — splice the `<memory kind="preference">` block
|
|
83
|
-
// (memory-usage guidance + preferences). The guidance frame is always
|
|
84
|
-
// present for a canvas node (the memory system always exists), so the block
|
|
85
|
-
// is never empty even when no preference is eligible. (The knowledge catalog
|
|
86
|
-
// does not enter the system prompt — it rides the bearings message via
|
|
87
|
-
// renderKnowledgeBlock.)
|
|
88
41
|
pi.on('before_agent_start', async (event) => {
|
|
89
|
-
|
|
42
|
+
mergeContextExposureState(contextExposure, loadContextExposureState(nodeId));
|
|
43
|
+
let block = contextExposure.preferenceSnapshot;
|
|
44
|
+
if (block === null) {
|
|
90
45
|
const state = await brokerExtensionState(nodeId);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
mergeInjectedDocs(injectedDocs, loadInjectedDocs(nodeId));
|
|
96
|
-
const block = renderPreferencesFromState(state, injectedDocs);
|
|
97
|
-
saveInjectedDocs(nodeId, injectedDocs);
|
|
98
|
-
if (block === '')
|
|
99
|
-
return; // nothing eligible — leave the prompt untouched
|
|
100
|
-
const idx = event.systemPrompt.indexOf(TOOLS_ANCHOR);
|
|
101
|
-
if (idx === -1) {
|
|
102
|
-
return { systemPrompt: `${event.systemPrompt}\n\n${block}` };
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
systemPrompt: `${event.systemPrompt.slice(0, idx)}\n\n${block}${event.systemPrompt.slice(idx)}`,
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
return; // inert on error — never brick node boot
|
|
46
|
+
const next = cloneContextExposureState(contextExposure);
|
|
47
|
+
block = freezePreferenceSnapshot(next, renderPreferencesFromState(state, exposureTarget(next, 'system')));
|
|
48
|
+
saveContextExposureState(nodeId, next);
|
|
49
|
+
replaceContextExposureState(contextExposure, next);
|
|
110
50
|
}
|
|
51
|
+
if (block === '')
|
|
52
|
+
return;
|
|
53
|
+
const idx = event.systemPrompt.indexOf(TOOLS_ANCHOR);
|
|
54
|
+
if (idx === -1)
|
|
55
|
+
return { systemPrompt: `${event.systemPrompt}\n\n${block}` };
|
|
56
|
+
return {
|
|
57
|
+
systemPrompt: `${event.systemPrompt.slice(0, idx)}\n\n${block}${event.systemPrompt.slice(idx)}`,
|
|
58
|
+
};
|
|
111
59
|
});
|
|
112
|
-
// 2. EVENT half — augment a non-error `read` with docs matched by the read
|
|
113
|
-
// file, and a non-error `bash` with docs matched by the command string.
|
|
114
60
|
pi.on('tool_result', async (event, ctx) => {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
// Resolve to an absolute path (renderOnReadDocsForSubject realpaths it).
|
|
125
|
-
// pi's read tool expands a leading `~`, but event.input keeps the raw
|
|
126
|
-
// form, so expand it ourselves before resolving against the session cwd.
|
|
127
|
-
const cwd = typeof ctx?.cwd === 'string' && ctx.cwd !== '' ? ctx.cwd : process.cwd();
|
|
128
|
-
const expanded = rawPath.startsWith('~') ? join(homedir(), rawPath.slice(1)) : rawPath;
|
|
129
|
-
const absFile = resolve(cwd, expanded);
|
|
130
|
-
const state = await brokerExtensionState(nodeId);
|
|
131
|
-
// Merge the on-disk set: an out-of-process delivery (the daemon's
|
|
132
|
-
// warm-spare claim pushes bearings — including workspace-open docs —
|
|
133
|
-
// into the live session and persists what it delivered) must dedup here
|
|
134
|
-
// too. Cheap: one tiny JSON read per tool result.
|
|
135
|
-
mergeInjectedDocs(injectedDocs, loadInjectedDocs(nodeId));
|
|
136
|
-
injected = renderOnReadDocsForSubject(state.subject, absFile, injectedDocs);
|
|
137
|
-
}
|
|
138
|
-
else if (event.toolName === 'bash') {
|
|
139
|
-
const input = event.input;
|
|
140
|
-
const command = input?.command;
|
|
141
|
-
if (typeof command !== 'string' || command.trim() === '')
|
|
142
|
-
return;
|
|
143
|
-
const state = await brokerExtensionState(nodeId);
|
|
144
|
-
mergeInjectedDocs(injectedDocs, loadInjectedDocs(nodeId));
|
|
145
|
-
injected = renderOnCommandDocsForSubject(state.subject, command, injectedDocs);
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
61
|
+
if (event.isError === true)
|
|
62
|
+
return;
|
|
63
|
+
let readFile = null;
|
|
64
|
+
let command = null;
|
|
65
|
+
if (event.toolName === 'read') {
|
|
66
|
+
const input = event.input;
|
|
67
|
+
const rawPath = input?.path ?? input?.file_path;
|
|
68
|
+
if (rawPath === undefined || rawPath === '')
|
|
148
69
|
return;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
// otherwise prepend one quiet block ahead of the tool output.
|
|
157
|
-
const inner = autoLoadedContextInner(injected);
|
|
158
|
-
if (inner === null)
|
|
70
|
+
const cwd = typeof ctx?.cwd === 'string' && ctx.cwd !== '' ? ctx.cwd : process.cwd();
|
|
71
|
+
const expanded = rawPath.startsWith('~') ? join(homedir(), rawPath.slice(1)) : rawPath;
|
|
72
|
+
readFile = resolve(cwd, expanded);
|
|
73
|
+
}
|
|
74
|
+
else if (event.toolName === 'bash') {
|
|
75
|
+
const input = event.input;
|
|
76
|
+
if (typeof input?.command !== 'string' || input.command.trim() === '')
|
|
159
77
|
return;
|
|
160
|
-
|
|
78
|
+
command = input.command;
|
|
161
79
|
}
|
|
162
|
-
|
|
163
|
-
return;
|
|
80
|
+
else {
|
|
81
|
+
return;
|
|
164
82
|
}
|
|
83
|
+
const state = await brokerExtensionState(nodeId);
|
|
84
|
+
mergeContextExposureState(contextExposure, loadContextExposureState(nodeId));
|
|
85
|
+
const next = cloneContextExposureState(contextExposure);
|
|
86
|
+
const target = exposureTarget(next, 'transcript');
|
|
87
|
+
const injected = readFile !== null
|
|
88
|
+
? renderOnReadDocsForSubject(state.subject, readFile, target)
|
|
89
|
+
: renderOnCommandDocsForSubject(state.subject, command, target);
|
|
90
|
+
if (injected === '')
|
|
91
|
+
return;
|
|
92
|
+
const inner = autoLoadedContextInner(injected);
|
|
93
|
+
if (inner === null)
|
|
94
|
+
throw new Error('substrate renderer returned an invalid auto-loaded context block');
|
|
95
|
+
saveContextExposureState(nodeId, next);
|
|
96
|
+
replaceContextExposureState(contextExposure, next);
|
|
97
|
+
return { content: mergeAutoLoadedContext([inner], event.content) };
|
|
165
98
|
});
|
|
166
99
|
}
|
|
167
100
|
export default registerCanvasDocSubstrate;
|
|
@@ -25,9 +25,8 @@ import { join } from 'node:path';
|
|
|
25
25
|
import { contextDir, jobDir } from '../core/canvas/paths.js';
|
|
26
26
|
import { markBusy, clearBusy, touchBusy } from '../core/runtime/busy.js';
|
|
27
27
|
import { clearFault } from '../core/runtime/fault.js';
|
|
28
|
-
import { personaDriftFromBrokerState } from '../core/runtime/broker-persona-guidance.js';
|
|
29
28
|
import { clearStopSignals, consumeStopSignals } from '../core/runtime/stop-signals.js';
|
|
30
|
-
import { bindBrokerSession, brokerExtensionState,
|
|
29
|
+
import { bindBrokerSession, brokerExtensionState, relaunchBrokerRoot, settleBroker } from '../core/runtime/broker/daemon-ops.js';
|
|
31
30
|
import { emitEvent } from '../core/events/emit.js';
|
|
32
31
|
import { activeBackgroundBashJobs } from '../core/bash-jobs.js';
|
|
33
32
|
import { CONTEXT_NUDGE_CUSTOM_TYPE, formatCard } from '../shared/generated-context.js';
|
|
@@ -376,6 +375,7 @@ export function registerCanvasStophook(pi) {
|
|
|
376
375
|
fields: { operation: 'relaunch_root' },
|
|
377
376
|
});
|
|
378
377
|
});
|
|
378
|
+
return;
|
|
379
379
|
}
|
|
380
380
|
}
|
|
381
381
|
catch (error) {
|
|
@@ -584,7 +584,8 @@ export function registerCanvasStophook(pi) {
|
|
|
584
584
|
// is a ~2-token uncached delta each turn), so the bands were unreachable and
|
|
585
585
|
// the nudge never fired.
|
|
586
586
|
try {
|
|
587
|
-
const
|
|
587
|
+
const state = await brokerExtensionState(nodeId);
|
|
588
|
+
const node = state.node;
|
|
588
589
|
const at = contextTokens !== null ? steerBand(contextTokens) : null;
|
|
589
590
|
if (at !== null && !firedBands.has(at)) {
|
|
590
591
|
firedBands.add(at);
|
|
@@ -596,17 +597,9 @@ export function registerCanvasStophook(pi) {
|
|
|
596
597
|
pi.sendMessage({ customType: CONTEXT_NUDGE_CUSTOM_TYPE, content: note, display: true }, { deliverAs: 'nextTurn' });
|
|
597
598
|
}
|
|
598
599
|
}
|
|
599
|
-
// Persona-transition steering. The daemon read snapshots both the
|
|
600
|
-
// expected ack and current persona; its guarded ack below can only commit
|
|
601
|
-
// exactly the transition this broker just described.
|
|
602
|
-
const drift = personaDriftFromBrokerState(node);
|
|
603
|
-
if (drift !== null) {
|
|
604
|
-
pi.sendUserMessage(formatCard('persona-transition', {}, drift.guidance), { deliverAs: 'steer' });
|
|
605
|
-
await commitBrokerPersonaAck(nodeId, { from: drift.from, to: drift.to });
|
|
606
|
-
}
|
|
607
600
|
}
|
|
608
|
-
catch {
|
|
609
|
-
|
|
601
|
+
catch (error) {
|
|
602
|
+
emitDaemonOperationFailure('turn_boundary', error);
|
|
610
603
|
}
|
|
611
604
|
});
|
|
612
605
|
// Pi may emit several agent_end attempts while it compacts, retries, and
|
|
@@ -6,8 +6,6 @@ export declare const SITUATIONAL_CONTEXT_CUSTOM_TYPE = "crtr-situational-context
|
|
|
6
6
|
export declare const CONTEXT_NUDGE_CUSTOM_TYPE = "crtr-context-nudge";
|
|
7
7
|
/** Custom message that opens a review companion's visible transcript. */
|
|
8
8
|
export declare const REVIEW_BOUNDARY_CUSTOM_TYPE = "crtr-review-boundary";
|
|
9
|
-
/** Opening text of a pre-envelope fresh-revive kickoff user message. */
|
|
10
|
-
export declare const REVIVE_KICKOFF_SENTINEL = "You have been revived fresh after a context refresh";
|
|
11
9
|
/** Generic completion mandate issued by the terminal-node stop guard. */
|
|
12
10
|
export declare const STALL_REPROMPT: string;
|
|
13
11
|
/** Static recovery prompts shared by the broker producer and display classifier. */
|
|
@@ -69,4 +67,3 @@ export declare function formatDataCard(kind: string, facts: Record<string, strin
|
|
|
69
67
|
export declare function parseCard(message: GeneratedContextMessageLike): GeneratedCard | null;
|
|
70
68
|
/** Format a complete inbox card from report bodies resolved by the caller. */
|
|
71
69
|
export declare function formatInboxCard(sections: readonly InboxCardSection[]): string;
|
|
72
|
-
export declare function isLegacyRuntimeText(text: string): boolean;
|
|
@@ -10,8 +10,6 @@ export const SITUATIONAL_CONTEXT_CUSTOM_TYPE = 'crtr-situational-context';
|
|
|
10
10
|
export const CONTEXT_NUDGE_CUSTOM_TYPE = 'crtr-context-nudge';
|
|
11
11
|
/** Custom message that opens a review companion's visible transcript. */
|
|
12
12
|
export const REVIEW_BOUNDARY_CUSTOM_TYPE = 'crtr-review-boundary';
|
|
13
|
-
/** Opening text of a pre-envelope fresh-revive kickoff user message. */
|
|
14
|
-
export const REVIVE_KICKOFF_SENTINEL = 'You have been revived fresh after a context refresh';
|
|
15
13
|
/** Generic completion mandate issued by the terminal-node stop guard. */
|
|
16
14
|
export const STALL_REPROMPT = "You've stopped but you're not waiting on anyone and haven't finished. " +
|
|
17
15
|
"Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human send` if you are blocked or need the user.";
|
|
@@ -212,58 +210,3 @@ export function formatInboxCard(sections) {
|
|
|
212
210
|
}).join('\n');
|
|
213
211
|
return formatCard('inbox', {}, body);
|
|
214
212
|
}
|
|
215
|
-
// LEGACY — landed 2026-08-14. Pre-envelope runtime text, kept ONLY so old
|
|
216
|
-
// scrollback is not attributed to the person. Delete this section and its
|
|
217
|
-
// callers one week after that date; after deletion, pre-cut scrollback
|
|
218
|
-
// misattributes and that cost is accepted.
|
|
219
|
-
const LEGACY_RESTART_CONTINUATION = '<runtime-restart-continuation>\ncontinue\n</runtime-restart-continuation>';
|
|
220
|
-
const CONTEXT_NUDGE_PREFIX = '[crtr] Context ~';
|
|
221
|
-
const PERSONA_TRANSITION_OPEN = '<persona-transition>';
|
|
222
|
-
const PERSONA_TRANSITION_CLOSE = '</persona-transition>';
|
|
223
|
-
const INBOX_SENDER_ID = '[a-z0-9]+(?:-[a-z0-9]+)+';
|
|
224
|
-
const INBOX_HEADER_RE = new RegExp(`^From (?:(.+?) \\[(${INBOX_SENDER_ID})\\]|(${INBOX_SENDER_ID}|system|human|crtrd)) — (\\d+) update`, 'm');
|
|
225
|
-
function isPersonaTransition(body) {
|
|
226
|
-
return body.startsWith(`${PERSONA_TRANSITION_OPEN}\n`) && body.endsWith(`\n${PERSONA_TRANSITION_CLOSE}`);
|
|
227
|
-
}
|
|
228
|
-
function isReviewApproval(body) {
|
|
229
|
-
return body.startsWith(`${REVIEW_APPROVAL_OPEN}\n`) && body.endsWith(`\n${REVIEW_APPROVAL_CLOSE}`);
|
|
230
|
-
}
|
|
231
|
-
function isStructuredOutputReprompt(body) {
|
|
232
|
-
if (!body.startsWith(STRUCTURED_OUTPUT_REPROMPT_PREFIX) || !body.endsWith(STRUCTURED_OUTPUT_REPROMPT_SUFFIX)) {
|
|
233
|
-
return false;
|
|
234
|
-
}
|
|
235
|
-
const schema = body.slice(STRUCTURED_OUTPUT_REPROMPT_PREFIX.length, -STRUCTURED_OUTPUT_REPROMPT_SUFFIX.length);
|
|
236
|
-
try {
|
|
237
|
-
JSON.parse(schema);
|
|
238
|
-
return true;
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
const MODEL_CREDENTIAL_RECOVERY_RE = /^The previous model \([^\n]+\) had no usable provider credential, so you were automatically switched to [^\n]+\. Continue the task from where the failed turn left off\.$/;
|
|
245
|
-
const MODEL_NOT_FOUND_RECOVERY_RE = /^The previous model \([^\n]+\) was unavailable \(provider 404 not_found\), so you were automatically switched to [^\n]+\. Continue the task from where the failed turn left off\.$/;
|
|
246
|
-
function isModelFallbackRecovery(body) {
|
|
247
|
-
if (!body.startsWith(`${MODEL_FALLBACK_RECOVERY_OPEN}\n`) || !body.endsWith(`\n${MODEL_FALLBACK_RECOVERY_CLOSE}`)) {
|
|
248
|
-
return false;
|
|
249
|
-
}
|
|
250
|
-
const guidance = body.slice(MODEL_FALLBACK_RECOVERY_OPEN.length + 1, -(MODEL_FALLBACK_RECOVERY_CLOSE.length + 1));
|
|
251
|
-
return MODEL_CREDENTIAL_RECOVERY_RE.test(guidance) || MODEL_NOT_FOUND_RECOVERY_RE.test(guidance);
|
|
252
|
-
}
|
|
253
|
-
function isRecoveryBody(body) {
|
|
254
|
-
return body === AUTH_FAULT_RECOVERY_BODY
|
|
255
|
-
|| body === CONNECTION_FAULT_RECOVERY_BODY
|
|
256
|
-
|| body === PROVIDER_FAULT_RECOVERY_BODY
|
|
257
|
-
|| body === LEGACY_RESTART_CONTINUATION
|
|
258
|
-
|| isModelFallbackRecovery(body);
|
|
259
|
-
}
|
|
260
|
-
export function isLegacyRuntimeText(text) {
|
|
261
|
-
return text.startsWith(REVIVE_KICKOFF_SENTINEL)
|
|
262
|
-
|| text.startsWith(CONTEXT_NUDGE_PREFIX)
|
|
263
|
-
|| INBOX_HEADER_RE.test(text)
|
|
264
|
-
|| isReviewApproval(text)
|
|
265
|
-
|| isPersonaTransition(text)
|
|
266
|
-
|| text === STALL_REPROMPT
|
|
267
|
-
|| isStructuredOutputReprompt(text)
|
|
268
|
-
|| isRecoveryBody(text);
|
|
269
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Shared transcript-boundary rules for broker-owned tool-group summaries.
|
|
2
2
|
// Keep this independent of renderer state: both live event tracking and snapshot
|
|
3
3
|
// reconstruction must agree on which prose closes a run of tools.
|
|
4
|
-
import { generatedContextText,
|
|
4
|
+
import { generatedContextText, parseCard } from './generated-context.js';
|
|
5
5
|
/** Card kinds that close a run of tools instead of joining one. The broker
|
|
6
6
|
* segments and the viewer folds on the same seams, so this one answer is shared;
|
|
7
7
|
* everything else about a card is the display's own business. */
|
|
@@ -60,6 +60,5 @@ export function assistantVisibleText(message) {
|
|
|
60
60
|
/** A person-authored user message closes the preceding group. Runtime-generated
|
|
61
61
|
* user context retains role=user for delivery semantics but is not human prose. */
|
|
62
62
|
export function isTrueUserMessage(message) {
|
|
63
|
-
|
|
64
|
-
return message.role === 'user' && parseCard(message) === null && !isLegacyRuntimeText(text);
|
|
63
|
+
return message.role === 'user' && parseCard(message) === null;
|
|
65
64
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -62,7 +62,7 @@ export interface PluginManifest {
|
|
|
62
62
|
source?: string;
|
|
63
63
|
owner?: OwnerRef;
|
|
64
64
|
/** Kind-registry contributions, keyed by full kind string (top-level e.g.
|
|
65
|
-
* `applet-builder`, or sub-kind e.g. `
|
|
65
|
+
* `applet-builder`, or sub-kind e.g. `audit/security`). Each entry
|
|
66
66
|
* is any subset of `KindConfig` fields: it FIELD-MERGES over a kind a lower
|
|
67
67
|
* layer already defines (`whenToUse` included — overriding just the spawn
|
|
68
68
|
* guidance never strips the kind's model tier), and defines a NEW kind when
|
|
@@ -202,14 +202,14 @@ export interface ModelRoutingConfig {
|
|
|
202
202
|
strengthFallback?: ModelStrength[];
|
|
203
203
|
}
|
|
204
204
|
/** Launch metadata for one kind (a top-level kind like `developer`, or a full
|
|
205
|
-
* sub-kind string like `
|
|
205
|
+
* sub-kind string like `audit/security`) — the settings-file
|
|
206
206
|
* replacement for per-kind persona frontmatter. `model`/`tools`/`extensions`
|
|
207
207
|
* are launch knobs consumed by `buildLaunchSpec`; `whenToUse` is the
|
|
208
208
|
* one-line gloss shown in `node new -h` / `node promote -h`. `availableTo` is
|
|
209
209
|
* VISIBILITY-ONLY (never launch validation): the list of top-level kind names
|
|
210
210
|
* whose spawn menus surface this sub-kind, `'*'` meaning every kind; omitted
|
|
211
211
|
* defaults to the sub-kind's own top-level ancestor (e.g.
|
|
212
|
-
* `
|
|
212
|
+
* `audit/security` defaults to `['audit']`). A direct launch by full kind
|
|
213
213
|
* string is always valid regardless of `availableTo`. */
|
|
214
214
|
export interface KindConfig {
|
|
215
215
|
model?: string;
|
|
@@ -320,7 +320,7 @@ export interface ScopeConfig {
|
|
|
320
320
|
modelRouting?: ModelRoutingConfig;
|
|
321
321
|
/** The kind registry (spec §1.5): kind existence + launch knobs, keyed by
|
|
322
322
|
* full kind string (top-level e.g. `developer`, or sub-kind e.g.
|
|
323
|
-
* `
|
|
323
|
+
* `audit/security`). Builtins ship a default registry via
|
|
324
324
|
* `defaultScopeConfig()`; user/project `config.json` adds or shadows
|
|
325
325
|
* entries at the same scope precedence as the rest of `ScopeConfig`. */
|
|
326
326
|
kinds: Record<string, KindConfig>;
|
|
@@ -483,13 +483,10 @@ export declare function defaultScopeConfig(): ScopeConfig;
|
|
|
483
483
|
/** No remote canvas targets are configured out of the box — every one is
|
|
484
484
|
* registered via `crtr canvas config add` (see `RemoteCanvasConfig`). */
|
|
485
485
|
export declare function defaultRemoteCanvasConfig(): RemoteCanvasConfig;
|
|
486
|
-
/** The builtin kind registry (spec §1.5):
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
* an orchestrator-gated memory doc keyed to the kind, not baked into the
|
|
491
|
-
* registry entry. Sub-persona `availableTo` is omitted where it only
|
|
492
|
-
* reproduces the default (its own top-level ancestor). */
|
|
486
|
+
/** The builtin kind registry (spec §1.5): core role discovery and launch
|
|
487
|
+
* defaults. `whenToUse`/`model` are the base-worker defaults;
|
|
488
|
+
* `orchestratorModel` optionally raises the default for a coordinating
|
|
489
|
+
* persona. Optional plugins contribute their own specialist sub-personas. */
|
|
493
490
|
export declare function defaultKindsConfig(): Record<string, KindConfig>;
|
|
494
491
|
export declare function defaultModelLaddersConfig(): ModelLaddersConfig;
|
|
495
492
|
export declare function defaultScopeState(): ScopeState;
|
package/dist/types.js
CHANGED
|
@@ -111,13 +111,10 @@ export function defaultScopeConfig() {
|
|
|
111
111
|
export function defaultRemoteCanvasConfig() {
|
|
112
112
|
return { targets: {} };
|
|
113
113
|
}
|
|
114
|
-
/** The builtin kind registry (spec §1.5):
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* an orchestrator-gated memory doc keyed to the kind, not baked into the
|
|
119
|
-
* registry entry. Sub-persona `availableTo` is omitted where it only
|
|
120
|
-
* reproduces the default (its own top-level ancestor). */
|
|
114
|
+
/** The builtin kind registry (spec §1.5): core role discovery and launch
|
|
115
|
+
* defaults. `whenToUse`/`model` are the base-worker defaults;
|
|
116
|
+
* `orchestratorModel` optionally raises the default for a coordinating
|
|
117
|
+
* persona. Optional plugins contribute their own specialist sub-personas. */
|
|
121
118
|
export function defaultKindsConfig() {
|
|
122
119
|
return {
|
|
123
120
|
general: {
|
|
@@ -156,34 +153,10 @@ export function defaultKindsConfig() {
|
|
|
156
153
|
whenToUse: 'Debug failures, investigate why something is broken or misbehaving, diagnose live/runtime issues, or give engineering advice and second opinions — reason from evidence and recommend the next move. Use advisor (not explore) whenever the task is to find out what is going wrong.',
|
|
157
154
|
model: 'anthropic/strong',
|
|
158
155
|
},
|
|
159
|
-
'plan/reviewers/requirements-coverage': {
|
|
160
|
-
whenToUse: 'every requirement and design constraint maps to a concrete plan task, classified Covered/Partial/Missing; flags only blocking gaps',
|
|
161
|
-
model: 'medium',
|
|
162
|
-
},
|
|
163
|
-
'plan/reviewers/pattern-consistency': {
|
|
164
|
-
whenToUse: "the plan honors the codebase's real conventions; reads actual source and cites the pattern each finding deviates from; owns contract-level conflicts between parts",
|
|
165
|
-
model: 'medium',
|
|
166
|
-
},
|
|
167
|
-
'plan/reviewers/code-smells': {
|
|
168
|
-
whenToUse: 'nullability mismatches, type conflicts across parts, hidden N+1s, over-fetching, missing error boundaries, leaky abstractions; owns file-level conflicts between parts',
|
|
169
|
-
model: 'medium',
|
|
170
|
-
},
|
|
171
|
-
'plan/reviewers/security': {
|
|
172
|
-
whenToUse: 'input validation, injection surfaces, auth/authz gaps, data exposure, races; reports only validated concrete exploit paths and asks the user about material unknown threat-model assumptions',
|
|
173
|
-
model: 'medium',
|
|
174
|
-
},
|
|
175
156
|
'review/companion': {
|
|
176
157
|
whenToUse: 'Born by the daemon for one human review; never spawned by an agent.',
|
|
177
158
|
availableTo: [],
|
|
178
159
|
},
|
|
179
|
-
'plan/reviewers/architecture-fit': {
|
|
180
|
-
whenToUse: "proposed files/modules/abstractions fit the system's existing decomposition; flags new units that duplicate existing ones or cross layer boundaries",
|
|
181
|
-
model: 'medium',
|
|
182
|
-
},
|
|
183
|
-
'spec/requirements': {
|
|
184
|
-
whenToUse: 'Derive testable EARS requirements from a finished, approved design — in isolation, from the rendered design text alone.',
|
|
185
|
-
model: 'medium',
|
|
186
|
-
},
|
|
187
160
|
};
|
|
188
161
|
}
|
|
189
162
|
export function defaultModelLaddersConfig() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.229",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -81,10 +81,11 @@
|
|
|
81
81
|
"dev": "tsx --conditions=crtr-src src/cli.ts",
|
|
82
82
|
"link": "npm link",
|
|
83
83
|
"prepublishOnly": "npm run build",
|
|
84
|
-
"test": "node --conditions=crtr-src --import tsx/esm --test --test-concurrency
|
|
85
|
-
"test:
|
|
84
|
+
"test": "node --conditions=crtr-src --import tsx/esm --test --test-force-exit --test-concurrency=$(node -p 'Math.max(4, require(`node:os`).availableParallelism() - 1)') --test-timeout=10000 'src/**/__tests__/*.test.ts'",
|
|
85
|
+
"test:integration": "node --conditions=crtr-src --import tsx/esm --test --test-concurrency=$(node -p 'Math.min(8, Math.max(2, require(`node:os`).availableParallelism() - 1))') --test-timeout=60000 'src/**/__tests__/integration/*.test.ts'",
|
|
86
86
|
"test:seam": "npm run build && npm run test:seam:built",
|
|
87
|
-
"test:seam:built": "node --test --test-concurrency=
|
|
87
|
+
"test:seam:built": "node --test --test-concurrency=4 --test-timeout=180000 'dist/**/__tests__/seam/*.test.js'",
|
|
88
|
+
"test:all": "npm test && npm run test:integration && npm run test:seam"
|
|
88
89
|
},
|
|
89
90
|
"overrides": {
|
|
90
91
|
"@earendil-works/pi-ai": "0.84.1",
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.229",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.229",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
kind: preference
|
|
3
|
-
when-and-why-to-read: When a node is spawned as kind design in base mode, this preference should be read so implementers inherit one coherent architecture instead of reopening load-bearing decisions.
|
|
4
|
-
gate: {kind: design, mode: base}
|
|
5
|
-
rationale: >-
|
|
6
|
-
senior-engineer architecture thinking — cross-service, high-level decisions (performance, db design, patterns) worked out interactively with the user, deliberately not taking the most obvious solution. Distinct from plan, which is a crutch for model intelligence (steps a dumber model can mindlessly execute); design decides how it SHOULD be put together. Schema/key-field definitions belong; verbatim controller code does not, unless naming a template pattern others will replicate.
|
|
7
|
-
surfaces:
|
|
8
|
-
- on: boot
|
|
9
|
-
at: content
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## When designing a bounded system
|
|
13
|
-
You are a design agent. Given a bounded design task — a component, subsystem, or interaction surface — you produce one design document an implementer can build from without re-deciding anything you left open. That, not emitting a document, is the bar for done. When a decision turns on judgment the user should own — a performance tradeoff, a data-model shape, which pattern to adopt — work it out with them via `crtr human send` rather than picking the obvious option alone, because the obvious option is usually not the right one.
|
|
14
|
-
|
|
15
|
-
Read your task for the scope, the constraints, and the interface contracts you must honor. Write the design to `design-<subject>.md` in your context dir, in the standard shape: Context & constraints, Architecture (lead with a diagram, then prose), Components & responsibilities, Interfaces & contracts, Data model, Key flows, Decisions, Open risks. Two things make it a design rather than a description: every decision that closes a real option is captured in Decisions with the alternatives you rejected and why — resolve the choice, never hand the implementer a branch to pick; and every interface is concrete enough that both sides can build to it without negotiating.
|
|
16
|
-
|
|
17
|
-
Deliver the design file path plus a tight summary — one sentence per decision, what was chosen and what it closed off. Promote into a design orchestrator only when settled boundaries expose independent design surfaces; tightly coupled architecture stays base across yields so one mind owns its coherence.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
kind: preference
|
|
3
|
-
when-and-why-to-read: When a node is spawned as kind design in orchestrator mode, this preference should be read so parallel sub-designs compose across their interfaces instead of producing a fragmented or contradictory architecture.
|
|
4
|
-
gate: {kind: design, mode: orchestrator}
|
|
5
|
-
surfaces:
|
|
6
|
-
- on: boot
|
|
7
|
-
at: content
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Coordinating a design effort
|
|
11
|
-
You are a **design orchestrator** — you own a design effort whose independent surfaces make parallel design worthwhile, and you deliver one coherent result by delegating each bounded sub-design to a `design` child and integrating what returns into a unified artifact.
|
|
12
|
-
|
|
13
|
-
Before you shape the roadmap, read `crtr memory read design/roadmap` for the decomposition discipline. Your first act after reading it is to define the shared interface contracts between the sub-designs and write them to `design-contracts.md` in your context dir before any child starts — those contracts are the seams that let parallel sub-designs compose instead of collide. Each child gets the overall architecture framing, the contracts doc, and the explicit scope of its piece.
|
|
14
|
-
|
|
15
|
-
Integration is the work, not a formality: read every sub-design, verify each contract is honored on *both* sides, reconcile the inconsistencies that only surface with the whole picture loaded, and synthesize a single document that reads as one voice — not a concatenation of pieces with the decision rationale lost between them. The design is done only when an implementer could build any piece from it without discovering that two pieces disagree.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
kind: preference
|
|
3
|
-
when-and-why-to-read: When a node is spawned as kind design, this preference should be read so the design closes the expensive decisions at the right altitude instead of drifting into implementation or over-specifying what the implementer could safely decide.
|
|
4
|
-
gate: {kind: design}
|
|
5
|
-
rationale: >-
|
|
6
|
-
The design personas described how to write the artifact but routed to no design guidance, so a base design node booted with no altitude rule and no bound on over-specification. Gates on the kind with no mode so design orchestrators load it too. Carries the contract only — the artifact shape and the decomposition decision stay in the docs it points at.
|
|
7
|
-
surfaces:
|
|
8
|
-
- on: boot
|
|
9
|
-
at: content
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## What a design must settle
|
|
13
|
-
A design fixes the load-bearing structure before anyone writes code: component boundaries and responsibilities, interface contracts and data models, key flows, and the decisions that close real options with their rationale and rejected alternatives.
|
|
14
|
-
|
|
15
|
-
It is not requirements — those state the behavior the system must satisfy, while the design states how it is structured to produce that behavior. It is not a plan — plans order implementation work against the design. The altitude ceiling: a planner reading the design has no design questions left, and a coder reading it still has implementation choices to make. No function bodies, no algorithm walkthroughs, no library calls, no ordering of implementation steps; anything that could be pasted into source belongs downstream.
|
|
16
|
-
|
|
17
|
-
Design enough to unblock parallelism and close the decisions that are expensive to reverse, and no further. Over-specification is as harmful as under-specification — it creates brittleness and deferred rework when reality does not match the paper — so leave the implementer what they can decide without risk. Name a genuinely unclear sub-section that is off the critical path as open rather than filling it with a plausible guess.
|
|
18
|
-
|
|
19
|
-
Read `crtr memory read design/guide` for what each section of the artifact must contain and the top-down versus bottom-up call.
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
kind: preference
|
|
3
|
-
when-and-why-to-read: When a node is spawned as kind developer in base mode, this preference should be read so implementation is proven against the requested behavior rather than declared done at compile time.
|
|
4
|
-
gate: {kind: developer, mode: base}
|
|
5
|
-
rationale: >-
|
|
6
|
-
Agents treated polish as a completion dependency, spending long iterations on nits while their parents could not advance the larger build. The developer needs to prove and report the first sound end-to-end path early, while retaining its existing done-bar for the final result. External critique works because agents can't self-audit; the reviewer must be primed neutrally — "review this", never "find what fails", which biases toward false positives.
|
|
7
|
-
surfaces:
|
|
8
|
-
- on: boot
|
|
9
|
-
at: content
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## When implementing
|
|
13
|
-
Work directly. Read the relevant files before editing, match the existing code style and module conventions, and keep your delegation shallow — a focused exploration or a review pass is worth handing off, but most of the work is yours. Throw errors early; no silent fallbacks. Break things correctly rather than patching them badly. Compatibility is governed by the approved spec or migration decision.
|
|
14
|
-
|
|
15
|
-
Done means **provably correct against the spec's acceptance criteria** — not "it builds," not "the tests pass." Green output proves the code ran, not that it does what was asked; check the result against each acceptance criterion yourself. On a load-bearing change, get it critiqued by something other than you before calling it done — spawn a reviewer on the diff and fold in what it finds. Every Critical, Major, or acceptance-violating finding is fixed, always — keep the fix net-neutral-or-simpler, never bolt on complexity to patch it. A Minor or cosmetic finding that doesn't affect acceptance is fixed when the fix is net-neutral-or-simpler, or else closed with a one-line reason — closing is a resolution, not a deferral. But validate judiciously: a delegate's green report is settled evidence — don't re-run a suite or re-read a diff that already cleared its gate; check only what changed since. Promote into a developer orchestrator only when the change splits into genuinely independent implementation lanes; a long or tightly coupled build stays base across yields.
|
|
16
|
-
|
|
17
|
-
When a working steel thread proves the task's end-to-end path and the remaining work cannot change its interface or acceptance outcome, report that readiness before polishing — name what is proven, what remains, and that whoever waits on this gate may advance. Then use judgment: finish net-simple polish in this window, but do not let nits or other non-blocking refinements hold the larger build. The final result still clears the full done-bar.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
kind: preference
|
|
3
|
-
when-and-why-to-read: When a node is spawned as kind developer in orchestrator mode, this preference should be read so feature-sized builds move coherently from implementation through independent review and end-to-end validation.
|
|
4
|
-
gate: {kind: developer, mode: orchestrator}
|
|
5
|
-
rationale: >-
|
|
6
|
-
Developer orchestrators need fact-dependent decisions sequenced behind shared evidence without blocking independent work. They also turned post-implementation “lenses” into mandatory parallel reviewers and then sought a fresh PASS after fixes, helping review dominate the canvas; one independent review assignment must own all relevant lenses, and changed behavior closes through evidence.
|
|
7
|
-
surfaces:
|
|
8
|
-
- on: boot
|
|
9
|
-
at: content
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
## When shaping a software roadmap
|
|
13
|
-
Before you shape a software roadmap, read `crtr memory read development` for development styles, roadmap shapes, and exit criteria that fit the goal's risk.
|
|
14
|
-
|
|
15
|
-
Treat implementation as complete only when it is **provably correct against the spec's acceptance criteria**, not merely when it compiles.
|