@crouton-kit/crouter 0.3.28 → 0.3.30
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/build-root.d.ts +15 -7
- package/dist/build-root.js +48 -34
- package/dist/builtin-memory/crouter-development/marketplaces.md +7 -6
- package/dist/builtin-memory/crouter-development/personas/base-prompt.md +1 -1
- package/dist/builtin-memory/crouter-development/personas/orchestrator-prompt.md +1 -1
- package/dist/builtin-memory/crouter-development/personas.md +1 -1
- package/dist/builtin-memory/crouter-development/plugins.md +20 -18
- package/dist/builtin-memory/design.md +1 -1
- package/dist/builtin-memory/development.md +1 -1
- package/dist/builtin-memory/internal/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/INDEX.md +1 -1
- package/dist/builtin-memory/internal/examples/imessage-assistant.md +2 -2
- package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-memory/planning.md +1 -1
- package/dist/builtin-memory/spec.md +6 -4
- package/dist/builtin-personas/orchestration-kernel.md +4 -5
- package/dist/builtin-personas/runtime-base.md +5 -4
- package/dist/builtin-personas/spec/PERSONA.md +8 -4
- package/dist/builtin-personas/spec/orchestrator.md +5 -3
- package/dist/builtin-personas/spec/requirements/PERSONA.md +10 -0
- package/dist/builtin-views/canvas/core.mjs +586 -0
- package/dist/builtin-views/canvas/text.mjs +58 -0
- package/dist/builtin-views/canvas/tui.mjs +165 -0
- package/dist/builtin-views/canvas/web.jsx +120 -0
- package/dist/builtin-views/git-pr/core.mjs +673 -0
- package/dist/builtin-views/git-pr/text.mjs +84 -0
- package/dist/builtin-views/git-pr/tui.mjs +302 -0
- package/dist/builtin-views/git-pr/web.jsx +216 -0
- package/dist/builtin-views/inbox/_lib/render.mjs +1 -3
- package/dist/builtin-views/inbox/core.mjs +1273 -0
- package/dist/builtin-views/inbox/text.mjs +73 -0
- package/dist/builtin-views/inbox/tui.mjs +312 -0
- package/dist/builtin-views/inbox/web.jsx +188 -0
- package/dist/builtin-views/linkedin/core.mjs +906 -0
- package/dist/builtin-views/linkedin/text.mjs +69 -0
- package/dist/builtin-views/linkedin/tui.mjs +427 -0
- package/dist/builtin-views/linkedin/web.jsx +206 -0
- package/dist/builtin-views/workspace-sidebar/core.mjs +621 -0
- package/dist/builtin-views/workspace-sidebar/text.mjs +53 -0
- package/dist/builtin-views/workspace-sidebar/tui.mjs +142 -0
- package/dist/builtin-views/workspace-sidebar/web.jsx +109 -0
- package/dist/cli.js +22 -17
- package/dist/clients/attach/__tests__/action-parity.test.js +48 -0
- package/dist/clients/attach/__tests__/clipboard-image.test.js +76 -0
- package/dist/clients/attach/__tests__/editor-newline.test.js +57 -0
- package/dist/clients/attach/__tests__/git-info.test.js +31 -0
- package/dist/clients/attach/__tests__/onrequest-wired.test.js +20 -0
- package/dist/clients/attach/__tests__/slash-quit-copy.test.js +42 -0
- package/dist/clients/attach/__tests__/titled-editor.test.js +39 -0
- package/dist/clients/attach/attach-cmd.js +282 -46
- package/dist/clients/attach/auth-pickers.d.ts +9 -0
- package/dist/clients/attach/auth-pickers.js +194 -0
- package/dist/clients/attach/canvas-panels.d.ts +4 -2
- package/dist/clients/attach/canvas-panels.js +45 -17
- package/dist/clients/attach/chat-view.d.ts +27 -2
- package/dist/clients/attach/chat-view.js +98 -9
- package/dist/clients/attach/clipboard-image.d.ts +47 -8
- package/dist/clients/attach/clipboard-image.js +150 -26
- package/dist/clients/attach/clipboard-text.d.ts +3 -0
- package/dist/clients/attach/clipboard-text.js +39 -0
- package/dist/clients/attach/config-load.d.ts +54 -7
- package/dist/clients/attach/config-load.js +99 -3
- package/dist/clients/attach/context-message.d.ts +12 -0
- package/dist/clients/attach/context-message.js +72 -0
- package/dist/clients/attach/git-info.d.ts +20 -0
- package/dist/clients/attach/git-info.js +44 -0
- package/dist/clients/attach/graph-overlay.d.ts +13 -4
- package/dist/clients/attach/graph-overlay.js +59 -19
- package/dist/clients/attach/input-controller.d.ts +75 -13
- package/dist/clients/attach/input-controller.js +305 -67
- package/dist/clients/attach/pickers.d.ts +58 -0
- package/dist/clients/attach/pickers.js +171 -0
- package/dist/clients/attach/slash-commands.d.ts +22 -0
- package/dist/clients/attach/slash-commands.js +91 -25
- package/dist/clients/attach/titled-editor.d.ts +33 -0
- package/dist/clients/attach/titled-editor.js +84 -0
- package/dist/clients/attach/view-socket.d.ts +18 -1
- package/dist/clients/attach/view-socket.js +70 -1
- package/dist/clients/web/dev-server.d.ts +7 -0
- package/dist/clients/web/dev-server.js +59 -0
- package/dist/clients/web/events.d.ts +14 -0
- package/dist/clients/web/events.js +151 -0
- package/dist/clients/web/server.d.ts +18 -0
- package/dist/clients/web/server.js +450 -0
- package/dist/clients/web/web-cmd.d.ts +2 -0
- package/dist/clients/web/web-cmd.js +120 -0
- package/dist/commands/canvas.js +1 -2
- package/dist/commands/chord.js +4 -25
- package/dist/commands/dashboard.js +5 -1
- package/dist/commands/memory/__tests__/lint-schema.test.js +6 -6
- package/dist/commands/memory/lint.js +14 -2
- package/dist/commands/memory/read.js +2 -2
- package/dist/commands/memory/shared.d.ts +7 -1
- package/dist/commands/memory/shared.js +18 -3
- package/dist/commands/memory/write.js +8 -4
- package/dist/commands/memory.js +4 -4
- package/dist/commands/node.d.ts +1 -1
- package/dist/commands/node.js +64 -65
- package/dist/commands/pkg.js +1 -2
- package/dist/commands/revive.js +11 -3
- package/dist/commands/sys/sync.d.ts +1 -0
- package/dist/commands/sys/sync.js +187 -0
- package/dist/commands/sys.js +3 -2
- package/dist/commands/view-cycle.js +2 -2
- package/dist/commands/view-list.js +8 -8
- package/dist/commands/view-new.js +21 -17
- package/dist/commands/view-pick.js +1 -1
- package/dist/commands/view-run.js +35 -14
- package/dist/commands/view.js +8 -6
- package/dist/commands/workspace.d.ts +2 -0
- package/dist/commands/workspace.js +161 -0
- package/dist/core/__tests__/broker-double-spawn.test.d.ts +1 -0
- package/dist/core/__tests__/broker-double-spawn.test.js +143 -0
- package/dist/core/__tests__/broker-fork-seam.test.d.ts +1 -0
- package/dist/core/__tests__/broker-fork-seam.test.js +102 -0
- package/dist/core/__tests__/broker-sdk-wiring.test.js +2 -0
- package/dist/core/__tests__/child-death-wake.test.js +56 -111
- package/dist/core/__tests__/close.test.js +14 -20
- package/dist/core/__tests__/context-intro.test.js +19 -19
- package/dist/core/__tests__/daemon-boot.test.js +30 -23
- package/dist/core/__tests__/draw-style.test.js +1 -1
- package/dist/core/__tests__/error-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/error-stall-recycle.test.js +141 -0
- package/dist/core/__tests__/fixtures/fake-engine.d.ts +17 -1
- package/dist/core/__tests__/fixtures/fake-engine.js +22 -2
- package/dist/core/__tests__/fixtures/fake-pi-host.js +2 -2
- package/dist/core/__tests__/focuses.test.js +25 -13
- package/dist/core/__tests__/fork.test.js +22 -5
- package/dist/core/__tests__/full/broker-control-preempt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-control-preempt.test.js +61 -0
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-model-changed-broadcast.test.js +57 -0
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +80 -0
- package/dist/core/__tests__/full/broker-pane-resolution.test.js +90 -0
- package/dist/core/__tests__/full/cascade-close.test.js +22 -8
- package/dist/core/__tests__/full/detach-focus.test.js +66 -169
- package/dist/core/__tests__/helpers/harness.d.ts +6 -9
- package/dist/core/__tests__/helpers/harness.js +19 -36
- package/dist/core/__tests__/human-node-not-supervised.test.d.ts +1 -0
- package/dist/core/__tests__/human-node-not-supervised.test.js +83 -0
- package/dist/core/__tests__/lifecycle.test.js +1 -19
- package/dist/core/__tests__/listing-completeness.test.js +2 -2
- package/dist/core/__tests__/live-mutation-verbs.test.js +5 -5
- package/dist/core/__tests__/memory-resolver.test.js +1 -1
- package/dist/core/__tests__/on-read-dedup-resume.test.js +2 -2
- package/dist/core/__tests__/refresh-stall-recycle.test.d.ts +1 -0
- package/dist/core/__tests__/refresh-stall-recycle.test.js +88 -0
- package/dist/core/__tests__/relaunch-root.test.d.ts +1 -0
- package/dist/core/__tests__/relaunch-root.test.js +114 -0
- package/dist/core/__tests__/reset.test.js +19 -79
- package/dist/core/__tests__/steer-note.test.js +9 -7
- package/dist/core/__tests__/tmux-surface.test.js +13 -7
- package/dist/core/bootstrap.d.ts +0 -3
- package/dist/core/bootstrap.js +1 -143
- package/dist/core/canvas/browse/__tests__/model.test.js +86 -1
- package/dist/core/canvas/browse/__tests__/render.test.js +2 -1
- package/dist/core/canvas/browse/app.js +131 -8
- package/dist/core/canvas/browse/model.d.ts +23 -5
- package/dist/core/canvas/browse/model.js +68 -13
- package/dist/core/canvas/browse/render.d.ts +7 -1
- package/dist/core/canvas/browse/render.js +178 -47
- package/dist/core/canvas/canvas.js +1 -1
- package/dist/core/canvas/focuses.d.ts +4 -4
- package/dist/core/canvas/focuses.js +7 -7
- package/dist/core/canvas/nav-model.js +8 -7
- package/dist/core/canvas/render.d.ts +68 -9
- package/dist/core/canvas/render.js +195 -61
- package/dist/core/canvas/types.d.ts +16 -23
- package/dist/core/config.js +1 -4
- package/dist/core/memory-resolver.js +43 -5
- package/dist/core/runtime/bearings.d.ts +1 -1
- package/dist/core/runtime/bearings.js +8 -8
- package/dist/core/runtime/branded-host.d.ts +16 -0
- package/dist/core/runtime/branded-host.js +127 -0
- package/dist/core/runtime/broker-protocol.d.ts +212 -6
- package/dist/core/runtime/broker.d.ts +4 -1
- package/dist/core/runtime/broker.js +494 -58
- package/dist/core/runtime/close.d.ts +12 -2
- package/dist/core/runtime/close.js +37 -16
- package/dist/core/runtime/front-door.js +6 -14
- package/dist/core/runtime/host.d.ts +14 -34
- package/dist/core/runtime/host.js +14 -50
- package/dist/core/runtime/launch.d.ts +12 -9
- package/dist/core/runtime/launch.js +27 -15
- package/dist/core/runtime/lifecycle.d.ts +1 -1
- package/dist/core/runtime/lifecycle.js +15 -19
- package/dist/core/runtime/nodes.d.ts +0 -55
- package/dist/core/runtime/nodes.js +6 -74
- package/dist/core/runtime/placement.d.ts +91 -335
- package/dist/core/runtime/placement.js +291 -858
- package/dist/core/runtime/promote.d.ts +2 -0
- package/dist/core/runtime/promote.js +24 -6
- package/dist/core/runtime/recap.d.ts +8 -0
- package/dist/core/runtime/recap.js +107 -0
- package/dist/core/runtime/recycle.js +25 -61
- package/dist/core/runtime/reset.d.ts +43 -37
- package/dist/core/runtime/reset.js +131 -218
- package/dist/core/runtime/revive.d.ts +9 -29
- package/dist/core/runtime/revive.js +40 -139
- package/dist/core/runtime/spawn.d.ts +15 -16
- package/dist/core/runtime/spawn.js +165 -194
- package/dist/core/runtime/surface-bg.d.ts +11 -0
- package/dist/core/runtime/surface-bg.js +68 -0
- package/dist/core/runtime/tmux.d.ts +15 -52
- package/dist/core/runtime/tmux.js +35 -99
- package/dist/core/scope.d.ts +1 -2
- package/dist/core/scope.js +1 -5
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.d.ts +1 -0
- package/dist/core/skill-sync/__tests__/dry-run-wrote-count.test.js +57 -0
- package/dist/core/skill-sync/builtins.d.ts +42 -0
- package/dist/core/skill-sync/builtins.js +112 -0
- package/dist/core/skill-sync/claude-plugins.d.ts +23 -0
- package/dist/core/skill-sync/claude-plugins.js +71 -0
- package/dist/core/skill-sync/engine.d.ts +42 -0
- package/dist/core/skill-sync/engine.js +633 -0
- package/dist/core/skill-sync/export.d.ts +23 -0
- package/dist/core/skill-sync/export.js +86 -0
- package/dist/core/skill-sync/manifest.d.ts +64 -0
- package/dist/core/skill-sync/manifest.js +181 -0
- package/dist/core/skill-sync/profile.d.ts +76 -0
- package/dist/core/skill-sync/profile.js +173 -0
- package/dist/core/skill-sync/snapshot.d.ts +57 -0
- package/dist/core/skill-sync/snapshot.js +120 -0
- package/dist/core/substrate/index.d.ts +1 -1
- package/dist/core/substrate/index.js +1 -1
- package/dist/core/substrate/injected-store.js +3 -3
- package/dist/core/substrate/on-read.js +68 -6
- package/dist/core/substrate/render.d.ts +8 -11
- package/dist/core/substrate/render.js +29 -43
- package/dist/core/substrate/schema.d.ts +10 -3
- package/dist/core/substrate/schema.js +6 -3
- package/dist/core/tui/host.d.ts +12 -4
- package/dist/core/tui/host.js +280 -149
- package/dist/core/view/bridge.d.ts +10 -0
- package/dist/core/view/bridge.js +31 -0
- package/dist/core/view/chrome.d.ts +9 -0
- package/dist/core/view/chrome.js +22 -0
- package/dist/core/view/contract.d.ts +171 -0
- package/dist/core/view/contract.js +23 -0
- package/dist/core/view/loader.d.ts +31 -0
- package/dist/core/view/loader.js +188 -0
- package/dist/core/view/transport-local.d.ts +7 -0
- package/dist/core/view/transport-local.js +70 -0
- package/dist/core/view/transport.d.ts +4 -0
- package/dist/core/view/transport.js +15 -0
- package/dist/daemon/crtrd.d.ts +38 -27
- package/dist/daemon/crtrd.js +303 -376
- package/dist/daemon/manage.js +6 -1
- package/dist/index.js +1 -1
- package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +28 -20
- package/dist/pi-extensions/canvas-context-intro.js +4 -4
- package/dist/pi-extensions/canvas-doc-substrate.js +16 -16
- package/dist/pi-extensions/canvas-nav.js +5 -0
- package/dist/pi-extensions/canvas-recap.d.ts +37 -0
- package/dist/pi-extensions/canvas-recap.js +236 -0
- package/dist/pi-extensions/canvas-resume.js +2 -1
- package/dist/pi-extensions/canvas-stophook.d.ts +14 -12
- package/dist/pi-extensions/canvas-stophook.js +87 -101
- package/dist/pi-extensions/canvas-view.js +2 -1
- package/dist/pi-extensions/widget-order-bus.d.ts +6 -0
- package/dist/pi-extensions/widget-order-bus.js +34 -0
- package/dist/prompts/view.d.ts +2 -2
- package/dist/prompts/view.js +145 -73
- package/dist/types.d.ts +1 -6
- package/dist/types.js +1 -3
- package/dist/web/ViewChrome.d.ts +7 -0
- package/dist/web/ViewChrome.js +28 -0
- package/dist/web/ViewPane.d.ts +39 -0
- package/dist/web/ViewPane.js +48 -0
- package/dist/web/index.d.ts +6 -0
- package/dist/web/index.js +16 -0
- package/dist/web/runtime.d.ts +39 -0
- package/dist/web/runtime.js +133 -0
- package/dist/web/states.d.ts +24 -0
- package/dist/web/states.js +24 -0
- package/dist/web/transport-http.d.ts +5 -0
- package/dist/web/transport-http.js +28 -0
- package/dist/web-client/assets/index-BUvQb4hR.css +2 -0
- package/dist/web-client/assets/index-ClLQXYAE.js +10 -0
- package/dist/web-client/index.html +13 -0
- package/package.json +20 -6
- package/dist/builtin-views/canvas/client.mjs +0 -303
- package/dist/builtin-views/canvas/view.mjs +0 -576
- package/dist/builtin-views/git-pr/client.mjs +0 -440
- package/dist/builtin-views/git-pr/view.mjs +0 -675
- package/dist/builtin-views/inbox/sources/gmail.mjs +0 -965
- package/dist/builtin-views/inbox/sources/linkedin.mjs +0 -427
- package/dist/builtin-views/inbox/view.mjs +0 -889
- package/dist/builtin-views/linkedin/client.mjs +0 -610
- package/dist/builtin-views/linkedin/view.mjs +0 -1171
- package/dist/commands/pkg/bridge.d.ts +0 -1
- package/dist/commands/pkg/bridge.js +0 -137
- package/dist/commands/skill/author.d.ts +0 -3
- package/dist/commands/skill/author.js +0 -140
- package/dist/commands/skill/shared.d.ts +0 -3
- package/dist/commands/skill/shared.js +0 -19
- package/dist/commands/skill.d.ts +0 -2
- package/dist/commands/skill.js +0 -21
- package/dist/commands/tmux-spread.d.ts +0 -2
- package/dist/commands/tmux-spread.js +0 -144
- package/dist/core/__tests__/full/daemon-liveness-pane.full.test.js +0 -292
- package/dist/core/__tests__/full/placement-focus.test.js +0 -309
- package/dist/core/__tests__/full/placement-reconcile.test.js +0 -212
- package/dist/core/__tests__/full/placement-revive.test.js +0 -238
- package/dist/core/__tests__/full/placement-teardown.test.js +0 -297
- package/dist/core/__tests__/home-session.test.js +0 -186
- package/dist/core/__tests__/relaunch.test.js +0 -335
- package/dist/core/bridge-map.d.ts +0 -19
- package/dist/core/bridge-map.js +0 -73
- package/dist/core/tui/contract.d.ts +0 -83
- package/dist/core/tui/contract.js +0 -8
- package/dist/core/tui/loader.d.ts +0 -16
- package/dist/core/tui/loader.js +0 -94
- package/dist/prompts/skill.d.ts +0 -2
- package/dist/prompts/skill.js +0 -650
- /package/dist/{core/__tests__/full/daemon-liveness-pane.full.test.d.ts → clients/attach/__tests__/action-parity.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-focus.test.d.ts → clients/attach/__tests__/clipboard-image.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-reconcile.test.d.ts → clients/attach/__tests__/editor-newline.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-revive.test.d.ts → clients/attach/__tests__/git-info.test.d.ts} +0 -0
- /package/dist/{core/__tests__/full/placement-teardown.test.d.ts → clients/attach/__tests__/onrequest-wired.test.d.ts} +0 -0
- /package/dist/{core/__tests__/home-session.test.d.ts → clients/attach/__tests__/slash-quit-copy.test.d.ts} +0 -0
- /package/dist/{core/__tests__/relaunch.test.d.ts → clients/attach/__tests__/titled-editor.test.d.ts} +0 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { defineLeaf } from '../core/command.js';
|
|
9
9
|
import { InputError } from '../core/io.js';
|
|
10
10
|
import { getNode, listNodes } from '../core/canvas/index.js';
|
|
11
|
-
import { renderTree, renderForest, dashboardRows, dashboardRowsAll } from '../core/canvas/render.js';
|
|
11
|
+
import { renderTree, renderForest, dashboardRows, dashboardRowsAll, enrichRows } from '../core/canvas/render.js';
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
// dashboard show — the main leaf
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
@@ -57,7 +57,11 @@ export const dashboardLeaf = defineLeaf({
|
|
|
57
57
|
}
|
|
58
58
|
// Full forest: all nodes on the canvas.
|
|
59
59
|
const allNodes = listNodes();
|
|
60
|
+
// dashboardRowsAll is the cheap-boot builder: ctx_tokens/asks are 0 and `name`
|
|
61
|
+
// is the handle only until enriched. The JSON consumer wants the real values,
|
|
62
|
+
// so fold the deferred fields in before emitting (the rendered TREE is unaffected).
|
|
60
63
|
const rows = dashboardRowsAll();
|
|
64
|
+
enrichRows(rows);
|
|
61
65
|
return {
|
|
62
66
|
tree: renderForest(),
|
|
63
67
|
nodes: allNodes.length,
|
|
@@ -11,22 +11,22 @@ import { lintSubstrateSchema } from '../lint.js';
|
|
|
11
11
|
const ROUTING = 'When you are X, this reference should be read because Y';
|
|
12
12
|
const RUNGS = { 'system-prompt-visibility': 'name', 'file-read-visibility': 'none' };
|
|
13
13
|
test('lint rejects a doc still carrying the retired `when` key', () => {
|
|
14
|
-
const err = lintSubstrateSchema({ kind: '
|
|
14
|
+
const err = lintSubstrateSchema({ kind: 'knowledge', when: 'when X' });
|
|
15
15
|
assert.ok(err !== null, 'old-shape `when` must produce a finding');
|
|
16
16
|
assert.match(err, /when-and-why-to-read/, 'the message points at the new field');
|
|
17
17
|
});
|
|
18
18
|
test('lint rejects a doc still carrying the retired `why` key', () => {
|
|
19
|
-
const err = lintSubstrateSchema({ kind: '
|
|
19
|
+
const err = lintSubstrateSchema({ kind: 'knowledge', why: 'because Y' });
|
|
20
20
|
assert.ok(err !== null, 'old-shape `why` must produce a finding');
|
|
21
21
|
assert.match(err, /when-and-why-to-read/, 'the message points at the new field');
|
|
22
22
|
});
|
|
23
23
|
test('lint rejects a substrate doc missing the merged routing field', () => {
|
|
24
|
-
const err = lintSubstrateSchema({ kind: '
|
|
24
|
+
const err = lintSubstrateSchema({ kind: 'knowledge' });
|
|
25
25
|
assert.ok(err !== null, 'a substrate doc must carry when-and-why-to-read');
|
|
26
26
|
assert.match(err, /when-and-why-to-read/);
|
|
27
27
|
});
|
|
28
28
|
test('lint accepts the merged new-shape frontmatter', () => {
|
|
29
|
-
assert.equal(lintSubstrateSchema({ kind: '
|
|
29
|
+
assert.equal(lintSubstrateSchema({ kind: 'knowledge', 'when-and-why-to-read': ROUTING, ...RUNGS }), null);
|
|
30
30
|
});
|
|
31
31
|
// Visibility is a required, case-by-case authoring call — there is no kind
|
|
32
32
|
// default. lint must reject a doc that omits either rung (the runtime parser
|
|
@@ -34,7 +34,7 @@ test('lint accepts the merged new-shape frontmatter', () => {
|
|
|
34
34
|
// gate exists to catch at authoring time).
|
|
35
35
|
test('lint rejects a substrate doc missing system-prompt-visibility', () => {
|
|
36
36
|
const err = lintSubstrateSchema({
|
|
37
|
-
kind: '
|
|
37
|
+
kind: 'knowledge',
|
|
38
38
|
'when-and-why-to-read': ROUTING,
|
|
39
39
|
'file-read-visibility': 'none',
|
|
40
40
|
});
|
|
@@ -43,7 +43,7 @@ test('lint rejects a substrate doc missing system-prompt-visibility', () => {
|
|
|
43
43
|
});
|
|
44
44
|
test('lint rejects a substrate doc missing file-read-visibility', () => {
|
|
45
45
|
const err = lintSubstrateSchema({
|
|
46
|
-
kind: '
|
|
46
|
+
kind: 'knowledge',
|
|
47
47
|
'when-and-why-to-read': ROUTING,
|
|
48
48
|
'system-prompt-visibility': 'name',
|
|
49
49
|
});
|
|
@@ -24,9 +24,9 @@ const RUNG_FIELDS = ['system-prompt-visibility', 'file-read-visibility'];
|
|
|
24
24
|
* silent tolerance this lint exists to catch at authoring time. */
|
|
25
25
|
export function lintSubstrateSchema(fm) {
|
|
26
26
|
if (fm === null)
|
|
27
|
-
return 'missing frontmatter: a memory store doc requires `kind:
|
|
27
|
+
return 'missing frontmatter: a memory store doc requires `kind: knowledge|preference`';
|
|
28
28
|
if (!isDocKind(fm.kind)) {
|
|
29
|
-
return `invalid kind: ${JSON.stringify(fm.kind)} (expected
|
|
29
|
+
return `invalid kind: ${JSON.stringify(fm.kind)} (expected knowledge|preference)`;
|
|
30
30
|
}
|
|
31
31
|
// The retired `when`/`why` pair was merged into one read-routing field. The
|
|
32
32
|
// hard cut is enforced HERE: an old-shape doc must fail, never be silently
|
|
@@ -56,6 +56,18 @@ export function lintSubstrateSchema(fm) {
|
|
|
56
56
|
!(Array.isArray(appliesTo) && appliesTo.every((g) => typeof g === 'string'))) {
|
|
57
57
|
return `invalid applies-to: ${JSON.stringify(appliesTo)} (expected a glob or glob list)`;
|
|
58
58
|
}
|
|
59
|
+
// read-when (Stream A on-read frontmatter trigger): same well-formed-object
|
|
60
|
+
// contract as gate — a non-object is inert (never fires), so catch it here.
|
|
61
|
+
const readWhen = fm['read-when'];
|
|
62
|
+
if (readWhen !== undefined && (readWhen === null || typeof readWhen !== 'object' || Array.isArray(readWhen))) {
|
|
63
|
+
return `invalid read-when: ${JSON.stringify(readWhen)} (expected a field→matcher object)`;
|
|
64
|
+
}
|
|
65
|
+
// A dead on-read trigger: an explicit applies-to/read-when with nothing to
|
|
66
|
+
// surface (file-read-visibility none) can never fire — flag it loudly rather
|
|
67
|
+
// than store a silent no-op.
|
|
68
|
+
if (fm['file-read-visibility'] === 'none' && (appliesTo !== undefined || readWhen !== undefined)) {
|
|
69
|
+
return 'dead on-read trigger: applies-to/read-when is set but file-read-visibility is `none` — raise the rung or drop the trigger';
|
|
70
|
+
}
|
|
59
71
|
return null;
|
|
60
72
|
}
|
|
61
73
|
/** Strict-parse one file; push a finding on a YAML error, then run the
|
|
@@ -18,7 +18,7 @@ export const readLeaf = defineLeaf({
|
|
|
18
18
|
],
|
|
19
19
|
output: [
|
|
20
20
|
{ name: 'name', type: 'string', required: true, constraint: 'Resolved document name.' },
|
|
21
|
-
{ name: 'kind', type: 'string', required: true, constraint: 'Resolved kind:
|
|
21
|
+
{ name: 'kind', type: 'string', required: true, constraint: 'Resolved kind: knowledge or preference.' },
|
|
22
22
|
{ name: 'scope', type: 'string', required: true, constraint: 'Scope the document was resolved from: project, user, or builtin.' },
|
|
23
23
|
{ name: 'path', type: 'string', required: true, constraint: 'Absolute path to the document on disk.' },
|
|
24
24
|
{ name: 'content', type: 'string', required: true, constraint: 'Document body. Frontmatter stripped unless --frontmatter is set.' },
|
|
@@ -48,7 +48,7 @@ export const readLeaf = defineLeaf({
|
|
|
48
48
|
? sub.kind
|
|
49
49
|
: typeof doc.frontmatter?.['kind'] === 'string'
|
|
50
50
|
? doc.frontmatter['kind']
|
|
51
|
-
: '
|
|
51
|
+
: 'knowledge';
|
|
52
52
|
// --kind asserts the resolved kind; a mismatch falls through to not-found.
|
|
53
53
|
if (kindFilter === undefined || kind === kindFilter) {
|
|
54
54
|
const content = includeFrontmatter ? readText(doc.path) : doc.body;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Scope } from '../../types.js';
|
|
2
|
-
export declare const MEMORY_KINDS: readonly ["
|
|
2
|
+
export declare const MEMORY_KINDS: readonly ["knowledge", "preference"];
|
|
3
3
|
export declare const VISIBILITY_RUNGS: readonly ["none", "name", "preview", "content"];
|
|
4
4
|
export declare const MEMORY_SCOPES: readonly ["user", "project"];
|
|
5
5
|
/** Scope sort weight matching resolution precedence (project > user > builtin).
|
|
@@ -17,6 +17,12 @@ export declare function resolveWriteTarget(scopeArg: string | undefined): {
|
|
|
17
17
|
* memory dir, guarding against traversal/absolute escapes. */
|
|
18
18
|
export declare function memoryFilePath(memoryDir: string, name: string): string;
|
|
19
19
|
export declare function coerceGate(raw: string): Record<string, unknown>;
|
|
20
|
+
/** Coerce a `--read-when` string into a predicate tree. Like `--gate`, the
|
|
21
|
+
* read-when field MUST be a YAML/JSON object (the field→matcher map the schema
|
|
22
|
+
* expects, evaluated against a read file's own frontmatter). A scalar/array
|
|
23
|
+
* read-when is inert (never matches), so passing one is always a mistake and is
|
|
24
|
+
* caught at authoring time rather than stored. */
|
|
25
|
+
export declare function coerceReadWhen(raw: string): Record<string, unknown>;
|
|
20
26
|
/** Coerce a `--applies-to` string to the schema's glob form: a comma-separated
|
|
21
27
|
* list becomes an array, a single glob stays a string. */
|
|
22
28
|
export declare function coerceAppliesTo(raw: string): unknown;
|
|
@@ -7,9 +7,10 @@ import { join } from 'node:path';
|
|
|
7
7
|
import { stringify as yamlStringify, parse as yamlParse } from 'yaml';
|
|
8
8
|
import { usage } from '../../core/errors.js';
|
|
9
9
|
import { scopeMemoryDir, projectScopeRoot, ensureProjectScopeRoot, } from '../../core/scope.js';
|
|
10
|
-
// The
|
|
11
|
-
//
|
|
12
|
-
|
|
10
|
+
// The two memory kinds — knowledge (consult: procedural playbooks + factual
|
|
11
|
+
// references merged) vs preference (behave: standing directives). Used as the
|
|
12
|
+
// `--kind` enum choices everywhere.
|
|
13
|
+
export const MEMORY_KINDS = ['knowledge', 'preference'];
|
|
13
14
|
// Visibility rungs — how much of a document surfaces (none → name → preview →
|
|
14
15
|
// content). Shared by --system-prompt-visibility and --file-read-visibility.
|
|
15
16
|
export const VISIBILITY_RUNGS = ['none', 'name', 'preview', 'content'];
|
|
@@ -76,6 +77,19 @@ export function coerceGate(raw) {
|
|
|
76
77
|
}
|
|
77
78
|
return result;
|
|
78
79
|
}
|
|
80
|
+
/** Coerce a `--read-when` string into a predicate tree. Like `--gate`, the
|
|
81
|
+
* read-when field MUST be a YAML/JSON object (the field→matcher map the schema
|
|
82
|
+
* expects, evaluated against a read file's own frontmatter). A scalar/array
|
|
83
|
+
* read-when is inert (never matches), so passing one is always a mistake and is
|
|
84
|
+
* caught at authoring time rather than stored. */
|
|
85
|
+
export function coerceReadWhen(raw) {
|
|
86
|
+
const result = parseYamlObject(raw);
|
|
87
|
+
if (typeof result === 'string') {
|
|
88
|
+
throw usage(`--read-when must be a YAML/JSON object (field→matcher map over a read file's frontmatter): ${result}. ` +
|
|
89
|
+
`Example: --read-when '{tags: {contains: security}}'`);
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
79
93
|
/** Coerce a `--applies-to` string to the schema's glob form: a comma-separated
|
|
80
94
|
* list becomes an array, a single glob stays a string. */
|
|
81
95
|
export function coerceAppliesTo(raw) {
|
|
@@ -97,6 +111,7 @@ const FRONTMATTER_ORDER = [
|
|
|
97
111
|
'file-read-visibility',
|
|
98
112
|
'gate',
|
|
99
113
|
'applies-to',
|
|
114
|
+
'read-when',
|
|
100
115
|
];
|
|
101
116
|
/** Serialize a substrate frontmatter record + body into a complete `.md`
|
|
102
117
|
* document. Frontmatter is emitted as a `---` fenced YAML block (the `yaml`
|
|
@@ -2,18 +2,18 @@ import { defineLeaf } from '../../core/command.js';
|
|
|
2
2
|
import { usage } from '../../core/errors.js';
|
|
3
3
|
import { parseFrontmatterGeneric } from '../../core/frontmatter.js';
|
|
4
4
|
import { readText, writeText, pathExists } from '../../core/fs-utils.js';
|
|
5
|
-
import { MEMORY_KINDS, MEMORY_SCOPES, VISIBILITY_RUNGS, resolveWriteTarget, memoryFilePath, coerceGate, coerceAppliesTo, serializeMemoryDoc, } from './shared.js';
|
|
5
|
+
import { MEMORY_KINDS, MEMORY_SCOPES, VISIBILITY_RUNGS, resolveWriteTarget, memoryFilePath, coerceGate, coerceAppliesTo, coerceReadWhen, serializeMemoryDoc, } from './shared.js';
|
|
6
6
|
export const writeLeaf = defineLeaf({
|
|
7
7
|
name: 'write',
|
|
8
8
|
description: 'create or update a memory document',
|
|
9
|
-
whenToUse: 'you are recording a new
|
|
9
|
+
whenToUse: 'you are recording a new knowledge document or preference — or revising one that already exists. Writes memory/<name>.md at the resolved scope from the frontmatter flags plus a body piped on stdin. Identity is path-derived: if <name> already exists at the scope it is updated in place, otherwise it is created.',
|
|
10
10
|
help: {
|
|
11
11
|
name: 'memory write',
|
|
12
12
|
summary: 'create or update memory/<name>.md at the resolved scope from frontmatter flags + a stdin body',
|
|
13
13
|
guide: 'The body is the easy part; the craft is ROUTING — every frontmatter flag decides who sees this doc, when, and at what context cost. Each rung up is paid by every future agent at every boot or read, forever, so default each rung DOWN.\n\n' +
|
|
14
|
-
'Pick the kind.
|
|
14
|
+
'Pick the kind. knowledge = anything you CONSULT \u2014 how to DO something (a repeatable procedure/playbook) OR what is TRUE / how something WORKS (a fact about the user, a system\u2019s behavior, code docs); preference = how to BEHAVE (a directive, a standing correction). The test that splits them: does it DIRECT behavior ("always lint after authoring" \u2192 preference) or INFORM what you know ("Silas likes chicken", "the daemon never reloads dist/" \u2192 knowledge)? A correction yields a preference; a learned fact or a repeatable procedure yields knowledge.\n\n' +
|
|
15
15
|
'Set the rungs \u2014 BOTH --system-prompt-visibility (boot) and --file-read-visibility (on-read) are REQUIRED on create. There is no default: the right rung is a case-by-case call, never a function of kind. The ladder, lowest to highest: `none` for niche docs almost nothing should pull into context; `name` for the common case \u2014 references and skills that are relatively uncommon but an agent (or the user, by name) may reach for; `preview` for docs important enough that their routing line is worth its token cost every session (preferences usually land here); `content` (full body injected) for a doc that would be `preview` except its body is already so short you may as well inline it whole. `content` is rare \u2014 when a `content` doc grows past a bullet or two, downgrade it to `preview`. Each axis is independent: usually one carries a real rung and the other is `none` (see the hook paragraph next).\n\n' +
|
|
16
|
-
'Choose the hook \u2014 boot vs file-read. There are exactly two moments a doc can surface. Behavior and procedure
|
|
16
|
+
'Choose the hook \u2014 boot vs file-read. There are exactly two moments a doc can surface. Behavior (preferences) and how-to procedure are relevant whatever file is open \u2192 surface at boot. Knowledge about code belongs NEXT TO the code: put the file in that directory\u2019s .crouter/memory/ and it fires positionally when files there are read, costing nothing at boot. The exception that matters: a knowledge doc about a PERSON or PROCESS has no code directory to anchor to, so on-read triggering is meaningless \u2014 set --system-prompt-visibility preview so its routing line surfaces at boot instead.\n\n' +
|
|
17
17
|
'Write the routing line (--when-and-why-to-read) FIRST, before storing anything: "When <circumstance the agent is in>, this <kind> should be read because <what the read buys>." The test: can a stranger mid-task decide from that one line alone whether to spend the read? If you cannot name the concrete situation that triggers it, you do not yet understand the memory \u2014 ask the user ONE sharp question instead of improvising. ("Remember I like chicken" routes cleanly \u2192 food/meal decisions; "be careful with the API" does not \u2192 which API, careful how, against what failure?) And NEVER paraphrase the advice in the routing line \u2014 a preview that gives away the gist makes every future agent skip the real read. BAD: "\u2026because it carries the placement policy \u2014 -h first, memory only for dev-mode material." GOOD: "\u2026because it carries the standing placement policy."\n\n' +
|
|
18
18
|
'Find before write. `crtr memory find <topic>` first; grow ONE doc per recurring circumstance rather than minting near-duplicates \u2014 extend `food-preferences`, do not create `likes-chicken`. Group related docs with path names (area/topic). Do not store what is already recorded (code structure, git history, CLAUDE.md) or what only matters to this conversation.\n\n' +
|
|
19
19
|
'Body: write for a STRANGER \u2014 a future session that shares none of this conversation. State current truth, not the history of getting there (no "as discussed"). Keep the reasoning behind a rule and cut everything else; dense beats complete, since every line costs a mid-task reader.\n\n' +
|
|
@@ -27,6 +27,7 @@ export const writeLeaf = defineLeaf({
|
|
|
27
27
|
{ kind: 'flag', name: 'file-read-visibility', type: 'enum', choices: [...VISIBILITY_RUNGS], required: false, constraint: 'Rung controlling how much of this document surfaces when it is read off disk. Required when creating — there is no kind default; pick a rung explicitly.' },
|
|
28
28
|
{ kind: 'flag', name: 'gate', type: 'string', required: false, constraint: 'Frontmatter gate — expression/condition that determines when this document applies.' },
|
|
29
29
|
{ kind: 'flag', name: 'applies-to', type: 'string', required: false, constraint: 'Frontmatter applies-to — glob/path scope the document applies to.' },
|
|
30
|
+
{ kind: 'flag', name: 'read-when', type: 'string', required: false, constraint: 'Frontmatter read-when — a condition (field→matcher object) over a READ FILE’s own frontmatter that surfaces this doc on-read (a native rule). Same predicate vocabulary as --gate. Example: \'{tags: {contains: security}}\'.' },
|
|
30
31
|
{ kind: 'flag', name: 'scope', type: 'enum', choices: [...MEMORY_SCOPES], required: false, constraint: 'Target scope. Default: project when inside a project, else user.' },
|
|
31
32
|
{ kind: 'stdin', name: 'body', required: true, constraint: 'Document body (markdown, no frontmatter). Piped on stdin, or passed as the bare positional after <name>.' },
|
|
32
33
|
],
|
|
@@ -86,6 +87,9 @@ export const writeLeaf = defineLeaf({
|
|
|
86
87
|
if (input['appliesTo'] !== undefined) {
|
|
87
88
|
frontmatter['applies-to'] = coerceAppliesTo(input['appliesTo']);
|
|
88
89
|
}
|
|
90
|
+
if (input['readWhen'] !== undefined) {
|
|
91
|
+
frontmatter['read-when'] = coerceReadWhen(input['readWhen']);
|
|
92
|
+
}
|
|
89
93
|
writeText(path, serializeMemoryDoc(frontmatter, body));
|
|
90
94
|
return {
|
|
91
95
|
name,
|
package/dist/commands/memory.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `crtr memory` subtree — the document substrate (
|
|
1
|
+
// `crtr memory` subtree — the document substrate (knowledge and
|
|
2
2
|
// preferences) accessed via the CLI. Four flat leaves: list, read, find, write.
|
|
3
3
|
// SKELETON ONLY (task B1): the `-h` contracts here are final; the leaf handlers
|
|
4
4
|
// are stubs that B2 fills in. Mirrors `skill.ts` minus the loaded-skills
|
|
@@ -13,13 +13,13 @@ export function registerMemory() {
|
|
|
13
13
|
return defineBranch({
|
|
14
14
|
name: 'memory',
|
|
15
15
|
rootEntry: {
|
|
16
|
-
concept: 'a memory document you read on demand —
|
|
16
|
+
concept: 'a memory document you read on demand — knowledge or a preference',
|
|
17
17
|
desc: 'list, read, search, and write memory documents',
|
|
18
|
-
useWhen: 'a task matches
|
|
18
|
+
useWhen: 'a task matches stored knowledge or a preference — read it before improvising. `crtr memory read <name>` loads one by name; `crtr memory list` browses the inventory; `crtr memory find` searches by topic when you do not yet know the name. Names are path-derived crtr identifiers, not file paths — never cat or find the markdown off disk.',
|
|
19
19
|
},
|
|
20
20
|
help: {
|
|
21
21
|
name: 'memory',
|
|
22
|
-
summary: 'list, read, search, and write memory documents —
|
|
22
|
+
summary: 'list, read, search, and write memory documents — knowledge and preferences',
|
|
23
23
|
model: '`list` for a human inventory of what is stored — one line per document, the only surface that shows short-form. `read` (leaf) loads one document body by name, resolved project > user > builtin with leaf-name fallback; --frontmatter keeps the YAML header. `find` when you do not yet know which document applies — it ranks by relevance over name/when/why/short-form, --body to also weigh bodies, --grep for an exact regex over bodies. `write` creates or updates memory/<name>.md at a scope from frontmatter flags + a body piped on stdin. `lint` strict-parses the whole bounded corpus and fails on any invalid frontmatter — run it after authoring. A directory may carry an `INDEX.md` with the same frontmatter schema as any doc; the dir then renders as one entry at the INDEX\'s rung, and that rung is a ceiling for its whole subtree (`none` hides the dir) — when a doc mysteriously is not surfacing, check its ancestors\' INDEX rungs and its gate. Append `-h` at any leaf for its full schema, and `crtr memory write -h` for the authoring guide.',
|
|
24
24
|
},
|
|
25
25
|
children: [listLeaf, readLeaf, findLeaf, writeLeaf, lintLeaf],
|
package/dist/commands/node.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare function childFollowUp(spawnerId: string | undefined): string;
|
|
|
7
7
|
/** The live node "in front of you" in a tmux pane, HOST-AGNOSTIC. Defaults to
|
|
8
8
|
* $TMUX_PANE / the caller's current pane when `pane` is omitted — shared by
|
|
9
9
|
* `node recycle` / `node demote` / `node lifecycle` / `node close` / `node
|
|
10
|
-
* cycle`, and the `canvas chord`
|
|
10
|
+
* cycle`, and the `canvas chord` leaf.
|
|
11
11
|
*
|
|
12
12
|
* Two resolutions, tried in order:
|
|
13
13
|
* 1. VIEWER pane (broker host): a `crtr attach` viewer self-tags its pane with
|