@north-light/crouter 0.3.208 → 0.3.209

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/api/client.d.ts +3 -1
  2. package/dist/api/client.js +4 -0
  3. package/dist/api/dto/broker-ops.d.ts +2 -12
  4. package/dist/api/dto/nodes.d.ts +16 -0
  5. package/dist/api/routes.d.ts +1 -0
  6. package/dist/api/routes.js +1 -0
  7. package/dist/builtin-memory/00-runtime-base.md +3 -2
  8. package/dist/builtin-memory/01-spine/00-has-manager.md +3 -2
  9. package/dist/builtin-memory/01-spine/01-no-manager.md +3 -2
  10. package/dist/builtin-memory/02-lifecycle/00-terminal.md +3 -2
  11. package/dist/builtin-memory/02-lifecycle/01-resident.md +3 -2
  12. package/dist/builtin-memory/04-base-worker.md +3 -2
  13. package/dist/builtin-memory/04-orchestration-kernel.md +3 -2
  14. package/dist/builtin-memory/05-kinds/advisor/00-base.md +3 -2
  15. package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +3 -2
  16. package/dist/builtin-memory/05-kinds/design/00-base.md +3 -2
  17. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +3 -2
  18. package/dist/builtin-memory/05-kinds/developer/00-base.md +3 -2
  19. package/dist/builtin-memory/05-kinds/developer/01-orchestrator.md +3 -2
  20. package/dist/builtin-memory/05-kinds/explore/00-base.md +3 -2
  21. package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +3 -2
  22. package/dist/builtin-memory/05-kinds/general/00-base.md +3 -2
  23. package/dist/builtin-memory/05-kinds/general/01-orchestrator.md +3 -2
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +3 -2
  25. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +3 -2
  26. package/dist/builtin-memory/05-kinds/plan/reviewers/00-base.md +3 -2
  27. package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +3 -2
  28. package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +3 -2
  29. package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +3 -2
  30. package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +3 -2
  31. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +3 -2
  32. package/dist/builtin-memory/05-kinds/review/00-base.md +3 -2
  33. package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +3 -2
  34. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +3 -2
  35. package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -2
  36. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -2
  37. package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -2
  38. package/dist/builtin-memory/advisor/council.md +0 -2
  39. package/dist/builtin-memory/design.md +3 -2
  40. package/dist/builtin-memory/development.md +3 -2
  41. package/dist/builtin-memory/insights/capture.md +1 -3
  42. package/dist/builtin-memory/insights/init.md +1 -3
  43. package/dist/builtin-memory/insights/listen.md +3 -2
  44. package/dist/builtin-memory/internal/INDEX.md +5 -4
  45. package/dist/builtin-memory/internal/agent-shaping.md +5 -4
  46. package/dist/builtin-memory/internal/examples/INDEX.md +3 -2
  47. package/dist/builtin-memory/internal/examples/imessage-assistant.md +3 -2
  48. package/dist/builtin-memory/internal/marketplaces.md +3 -2
  49. package/dist/builtin-memory/internal/memory-loading.md +31 -20
  50. package/dist/builtin-memory/internal/nodes-and-canvas.md +3 -2
  51. package/dist/builtin-memory/internal/plugins.md +7 -6
  52. package/dist/builtin-memory/internal/storage-tiers.md +3 -2
  53. package/dist/builtin-memory/plan/roadmap.md +3 -2
  54. package/dist/builtin-memory/spec/guide.md +0 -2
  55. package/dist/builtin-memory/spec/requirements.md +0 -2
  56. package/dist/builtin-memory/spec/roadmap.md +3 -2
  57. package/dist/builtin-memory/testing.md +1 -3
  58. package/dist/builtin-memory/wedged-child-on-runaway-bash.md +3 -2
  59. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +1 -1
  60. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/frontmatter-rules/index.ts +3 -3
  61. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +1 -4
  62. package/dist/clients/attach/viewer.js +366 -366
  63. package/dist/commands/memory/delete.js +3 -18
  64. package/dist/commands/memory/edit.js +23 -30
  65. package/dist/commands/memory/history.js +1 -1
  66. package/dist/commands/memory/lint.d.ts +7 -8
  67. package/dist/commands/memory/lint.js +178 -132
  68. package/dist/commands/memory/list.d.ts +0 -1
  69. package/dist/commands/memory/list.js +2 -12
  70. package/dist/commands/memory/move.d.ts +1 -0
  71. package/dist/commands/memory/move.js +195 -0
  72. package/dist/commands/memory/read.js +135 -141
  73. package/dist/commands/memory/shared.d.ts +18 -17
  74. package/dist/commands/memory/shared.js +93 -39
  75. package/dist/commands/memory/write.js +23 -33
  76. package/dist/commands/memory.js +5 -4
  77. package/dist/commands/pkg/browse/catalog.js +2 -4
  78. package/dist/commands/pkg/browse/doc-view.js +17 -11
  79. package/dist/commands/pkg/browse/model.d.ts +7 -9
  80. package/dist/commands/sys/migrate.d.ts +1 -0
  81. package/dist/commands/sys/migrate.js +106 -0
  82. package/dist/commands/sys/sync-deps.js +5 -10
  83. package/dist/commands/sys/sync-project-guidance.js +36 -16
  84. package/dist/commands/sys/sync-skills.js +8 -4
  85. package/dist/commands/sys.js +3 -2
  86. package/dist/core/__tests__/inline-memory-refs.test.js +8 -5
  87. package/dist/core/__tests__/memory-resolver-precedence.test.js +5 -4
  88. package/dist/core/__tests__/nested-store-discovery.test.js +1 -3
  89. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +3 -3
  90. package/dist/core/__tests__/on-read-dedup-resume.test.js +12 -12
  91. package/dist/core/__tests__/on-read-nested-store.test.js +23 -20
  92. package/dist/core/canvas/db.d.ts +3 -1
  93. package/dist/core/canvas/db.js +12 -2
  94. package/dist/core/memory/history.d.ts +4 -1
  95. package/dist/core/memory/history.js +1 -0
  96. package/dist/core/memory/inline-ref-inventory.d.ts +5 -4
  97. package/dist/core/memory/inline-ref-inventory.js +23 -19
  98. package/dist/core/memory-resolver.d.ts +4 -4
  99. package/dist/core/memory-resolver.js +16 -43
  100. package/dist/core/runtime/bearings.d.ts +4 -3
  101. package/dist/core/runtime/bearings.js +4 -4
  102. package/dist/core/runtime/broker-extension-render.d.ts +3 -2
  103. package/dist/core/runtime/broker-extension-render.js +3 -3
  104. package/dist/core/runtime/memory.js +2 -3
  105. package/dist/core/substrate/index.d.ts +7 -4
  106. package/dist/core/substrate/index.js +6 -4
  107. package/dist/core/substrate/injected-store.d.ts +24 -12
  108. package/dist/core/substrate/injected-store.js +80 -33
  109. package/dist/core/substrate/listings.d.ts +21 -0
  110. package/dist/core/substrate/listings.js +88 -0
  111. package/dist/core/substrate/on-read-node.d.ts +5 -5
  112. package/dist/core/substrate/on-read-node.js +4 -5
  113. package/dist/core/substrate/on-read.d.ts +25 -4
  114. package/dist/core/substrate/on-read.js +81 -102
  115. package/dist/core/substrate/render-node.d.ts +5 -2
  116. package/dist/core/substrate/render-node.js +5 -3
  117. package/dist/core/substrate/render.d.ts +9 -8
  118. package/dist/core/substrate/render.js +104 -96
  119. package/dist/core/substrate/schema.d.ts +34 -18
  120. package/dist/core/substrate/schema.js +75 -32
  121. package/dist/core/substrate/surface-match.d.ts +32 -0
  122. package/dist/core/substrate/surface-match.js +179 -0
  123. package/dist/daemon/api/handlers/nodes.js +9 -0
  124. package/dist/migrations/001-surfaces-frontmatter.d.ts +2 -0
  125. package/dist/migrations/001-surfaces-frontmatter.js +276 -0
  126. package/dist/migrations/convergent.d.ts +31 -0
  127. package/dist/migrations/convergent.js +71 -0
  128. package/dist/migrations/registry.d.ts +2 -0
  129. package/dist/migrations/registry.js +19 -0
  130. package/dist/migrations/types.d.ts +40 -0
  131. package/dist/migrations/types.js +11 -0
  132. package/dist/pi-extensions/canvas-context-intro.d.ts +2 -1
  133. package/dist/pi-extensions/canvas-doc-substrate.d.ts +2 -1
  134. package/dist/pi-extensions/canvas-doc-substrate.js +57 -34
  135. package/package.json +1 -1
  136. package/runtime.lock.json +2 -2
  137. package/dist/core/substrate/ceiling.d.ts +0 -17
  138. package/dist/core/substrate/ceiling.js +0 -67
@@ -1,26 +1,11 @@
1
- import { existsSync, readdirSync, rmSync, rmdirSync } from 'node:fs';
2
- import { dirname, resolve as resolvePath } from 'node:path';
1
+ import { rmSync } from 'node:fs';
2
+ import { resolve as resolvePath } from 'node:path';
3
3
  import { defineLeaf } from '../../core/command.js';
4
4
  import { CrtrError, notFound, usage } from '../../core/errors.js';
5
5
  import { readText } from '../../core/fs-utils.js';
6
6
  import { resolveMemoryDoc } from '../../core/memory-resolver.js';
7
7
  import { appendHistoryRecord, buildHistoryRecord, historyLogPathFor } from '../../core/memory/history.js';
8
- import { MEMORY_SCOPES } from './shared.js';
9
- /** Remove the file's now-empty parent directories up to (never including) the
10
- * scope's `memory/` root, so deleting the last doc under an `area/` prefix
11
- * does not orphan an empty directory. Stops at the first non-empty ancestor.
12
- * `memoryRoot` is derived by walking up one dirname per name segment: a doc
13
- * named `a/b` sits at `<root>/a/b.md`, so its root is two dirnames above. */
14
- function pruneEmptyParents(filePath, nameSegments) {
15
- let memoryRoot = filePath;
16
- for (let i = 0; i < nameSegments; i += 1)
17
- memoryRoot = dirname(memoryRoot);
18
- let dir = dirname(filePath);
19
- while (dir !== memoryRoot && dir.startsWith(memoryRoot) && existsSync(dir) && readdirSync(dir).length === 0) {
20
- rmdirSync(dir);
21
- dir = dirname(dir);
22
- }
23
- }
8
+ import { MEMORY_SCOPES, pruneEmptyParents } from './shared.js';
24
9
  export const deleteLeaf = defineLeaf({
25
10
  name: 'delete',
26
11
  description: 'delete a memory document by name',
@@ -4,12 +4,11 @@ import { parseFrontmatterGeneric } from '../../core/frontmatter.js';
4
4
  import { readText, writeText } from '../../core/fs-utils.js';
5
5
  import { resolveMemoryDoc } from '../../core/memory-resolver.js';
6
6
  import { appendHistoryRecord, buildHistoryRecord, historyLogPathFor, readHistoryRecords, } from '../../core/memory/history.js';
7
- import { DOC_RATIONALE_CONSTRAINT, GUIDE_DOC_LINKS, GUIDE_PREDICATE_VOCABULARY, GUIDE_ROUTING_LINE, GUIDE_VISIBILITY_RUNGS, MEMORY_SCOPES, coerceAppliesTo, coerceGate, coerceReadWhen, overlayParam, literalBodySegment, serializeMemoryDocLiteral, } from './shared.js';
8
- /** Frontmatter fields an overlay flag cannot express removing. `kind`, the
9
- * routing line, and the two visibility rungs are the document's contract (a
10
- * doc without them is malformed); `origin` and `last-updated` are runtime
11
- * provenance. */
12
- const CLEARABLE_FIELDS = ['short-form', 'gate', 'applies-to', 'read-when', 'slash', 'rationale'];
7
+ import { DOC_RATIONALE_CONSTRAINT, GUIDE_DOC_LINKS, GUIDE_PREDICATE_VOCABULARY, GUIDE_ROUTING_LINE, GUIDE_SURFACES, MEMORY_SCOPES, coerceGate, coerceSurface, overlayParam, literalBodySegment, serializeMemoryDocLiteral, } from './shared.js';
8
+ /** Frontmatter fields an overlay flag cannot express removing. `kind` and the
9
+ * routing line are the document's contract (a doc without them is malformed);
10
+ * `origin` and `last-updated` are runtime provenance. */
11
+ const CLEARABLE_FIELDS = ['short-form', 'gate', 'surfaces', 'unlisted', 'slash', 'rationale'];
13
12
  export const editLeaf = defineLeaf({
14
13
  name: 'edit',
15
14
  description: 'revise an existing memory document, recording why',
@@ -20,11 +19,11 @@ export const editLeaf = defineLeaf({
20
19
  guide: 'The body you pipe is saved byte for byte. Nothing between stdin and disk parses, normalizes, summarizes, or rewrites it \u2014 the frontmatter fence is prepended and the text is otherwise untouched. Relaying a person\u2019s own words is therefore safe: pass them through unchanged and mark them with --verbatim.\n\n' +
21
20
  'Two different rationales exist and they never share a flag. --rationale is why THIS REVISION is happening; it is required, it lands in the revision history, and it never touches the document text. --doc-rationale replaces the document\u2019s standing `rationale` frontmatter field \u2014 the observed gap the doc exists to close.\n\n' +
22
21
  'Omitting stdin leaves the body exactly as it stands, which is how a frontmatter-only revision is made. Piping a body REPLACES the whole body; there is no partial or append mode. Emptying a document is not an edit \u2014 that intent is `crtr memory delete`.\n\n' +
23
- 'Omitted frontmatter flags preserve their fields. --unset is the only way to REMOVE one, and it is limited to fields a doc can legitimately live without (short-form, gate, applies-to, read-when, slash, rationale). --applies-to replaces the whole route set rather than adding to it.\n\n' +
22
+ 'Omitted frontmatter flags preserve their fields. --unset is the only way to REMOVE one, and it is limited to fields a doc can legitimately live without (short-form, gate, surfaces, unlisted, slash, rationale). --surface replaces the whole surfaces list rather than adding to it.\n\n' +
24
23
  'An edit that changes nothing fails. A rationale attached to zero change is noise in the trail the history exists to build \u2014 if the doc already says what you meant, there is nothing to record.\n\n' +
25
24
  '`last-updated` is stamped on every successful edit; `origin` is preserved, so it keeps pointing at the conversation that created the doc rather than the last one to touch it.\n\n' +
26
25
  GUIDE_ROUTING_LINE + '\n\n' +
27
- GUIDE_VISIBILITY_RUNGS + '\n\n' +
26
+ GUIDE_SURFACES + '\n\n' +
28
27
  GUIDE_PREDICATE_VOCABULARY + '\n\n' +
29
28
  GUIDE_DOC_LINKS + '\n\n' +
30
29
  'Create a document that does not exist yet with `crtr memory write`. Read the revisions back with `crtr memory history`.',
@@ -35,14 +34,12 @@ export const editLeaf = defineLeaf({
35
34
  overlayParam('kind'),
36
35
  overlayParam('when-and-why-to-read'),
37
36
  overlayParam('short-form'),
38
- overlayParam('system-prompt-visibility'),
39
- overlayParam('file-read-visibility'),
37
+ overlayParam('unlisted', {}, 'Presence SETS the field; remove it with `--unset unlisted`.'),
38
+ overlayParam('surface'),
40
39
  overlayParam('gate'),
41
- overlayParam('applies-to'),
42
- overlayParam('read-when'),
43
40
  overlayParam('slash', {}, 'Presence SETS the field; remove it with `--unset slash`.'),
44
41
  { kind: 'flag', name: 'doc-rationale', type: 'string', required: false, constraint: DOC_RATIONALE_CONSTRAINT },
45
- { kind: 'flag', name: 'unset', type: 'enum', choices: [...CLEARABLE_FIELDS], required: false, repeatable: true, constraint: 'Remove a frontmatter field an overlay flag cannot express removing. One field per occurrence. `kind`, `when-and-why-to-read`, the two visibility rungs, `origin`, and `last-updated` are never clearable. Unsetting `applies-to` while file-read-visibility is not none fails on the same invariant `write` raises.' },
42
+ { kind: 'flag', name: 'unset', type: 'enum', choices: [...CLEARABLE_FIELDS], required: false, repeatable: true, constraint: 'Remove a frontmatter field an overlay flag cannot express removing. One field per occurrence. `kind`, `when-and-why-to-read`, `origin`, and `last-updated` are never clearable.' },
46
43
  { kind: 'flag', name: 'scope', type: 'enum', choices: [...MEMORY_SCOPES], required: false, constraint: 'Restrict resolution to this scope before editing. A disambiguation filter only \u2014 never a creation target, and never a way to move a doc between stores.' },
47
44
  { kind: 'stdin', name: 'body', required: false, constraint: 'Full replacement body (markdown, no frontmatter), saved byte for byte. Piped on stdin only \u2014 this leaf already claims the one positional for NAME. Absent or empty stdin leaves the existing body untouched, which is how a frontmatter-only revision is made.' },
48
45
  ],
@@ -100,31 +97,27 @@ export const editLeaf = defineLeaf({
100
97
  setIf('kind', input['kind']);
101
98
  setIf('when-and-why-to-read', input['whenAndWhyToRead']);
102
99
  setIf('short-form', input['shortForm']);
103
- setIf('system-prompt-visibility', input['systemPromptVisibility']);
104
- setIf('file-read-visibility', input['fileReadVisibility']);
100
+ if (input['unlisted'] === true)
101
+ frontmatter['unlisted'] = true;
102
+ if (input['surface'] !== undefined) {
103
+ frontmatter['surfaces'] = input['surface'].map(coerceSurface);
104
+ }
105
105
  if (input['gate'] !== undefined)
106
106
  frontmatter['gate'] = coerceGate(input['gate']);
107
- if (input['appliesTo'] !== undefined)
108
- frontmatter['applies-to'] = coerceAppliesTo(input['appliesTo']);
109
- if (input['readWhen'] !== undefined)
110
- frontmatter['read-when'] = coerceReadWhen(input['readWhen']);
111
107
  if (input['slash'] === true)
112
108
  frontmatter['slash'] = true;
113
109
  setIf('rationale', input['docRationale']);
114
110
  for (const field of input['unset'] ?? []) {
115
111
  delete frontmatter[field];
116
112
  }
117
- const applies = frontmatter['applies-to'];
118
- const routes = typeof applies === 'string'
119
- ? [applies]
120
- : Array.isArray(applies) && applies.every((value) => typeof value === 'string')
121
- ? applies
122
- : [];
123
- if (frontmatter['file-read-visibility'] !== 'none' && routes.length === 0) {
124
- throw usage(`file-read-visibility ${String(frontmatter['file-read-visibility'])} requires at least one applies-to route: pass --applies-to (use "." for project workspace/profile-open context, a real file glob for matching reads), or set --file-read-visibility none`);
125
- }
126
- if (doc.scope !== 'project' && routes.some((route) => route.trim() === '.')) {
127
- throw usage('applies-to "." is a project-store workspace mount route; use a real file glob or choose file-read-visibility none for user, profile, and node memory');
113
+ // Same invariant `write` raises: a workspace-open entry fires only when
114
+ // cwd/profile mounts the doc's project store, so outside project scope it
115
+ // is a dead route.
116
+ const surfacesVal = frontmatter['surfaces'];
117
+ if (doc.scope !== 'project' &&
118
+ Array.isArray(surfacesVal) &&
119
+ surfacesVal.some((e) => e !== null && typeof e === 'object' && e['on'] === 'workspace-open')) {
120
+ throw usage('a workspace-open surfaces entry is a project-store mount route; user, profile, and node memory cannot carry one — drop the entry');
128
121
  }
129
122
  // LITERAL SAVE: the piped bytes reach disk untransformed, one structural
130
123
  // blank line after the fence. Omitting stdin re-emits the existing body
@@ -60,7 +60,7 @@ export const historyLeaf = defineLeaf({
60
60
  help: {
61
61
  name: 'memory history',
62
62
  summary: 'list a document\u2019s revisions newest-first, with diffs or one full record on demand',
63
- guide: 'Every mutation through `crtr memory write`, `edit`, and `delete` appends one self-contained record \u2014 complete document text before and after, plus who, when, and (on an edit) why. Diffs and revision numbers are derived here at read time, never stored.\n\n' +
63
+ guide: 'Every mutation through `crtr memory write`, `edit`, `move`, and `delete` appends one self-contained record \u2014 complete document text before and after, plus who, when, and (on an edit) why. Diffs and revision numbers are derived here at read time, never stored.\n\n' +
64
64
  'A record whose `before` differs from the previous record\u2019s `after` is the evidence of an out-of-band direct file edit; nothing prevents those, and nothing detects them beyond this.\n\n' +
65
65
  'The log is a plain JSONL file at `log_path`, one JSON object per line \u2014 an external consumer reads it directly rather than through this command.',
66
66
  params: [
@@ -1,16 +1,15 @@
1
- /** The length rule. Caps are computed from the RAW rung strings — an invalid
2
- * rung already fails the schema check, so it simply matches no cap here.
1
+ /** Warn when a body short enough to inline still pays a routing line. */
2
+ export declare function lintShortPreviewBody(fm: Record<string, unknown>, body: string): string | null;
3
+ /** The length rule. Caps are computed from the parsed entries — an invalid
4
+ * entry already fails the schema check, so it simply matches no cap here.
3
5
  * `docName` is the doc's canonical resolver identity (explicit frontmatter
4
6
  * `name`, else the normalized path-derived name) — persona layers under
5
7
  * `kinds/` are recognized by it and never capped. */
6
- export declare function lintShortPreviewBody(fm: Record<string, unknown>, body: string): string | null;
7
8
  export declare function lintBodyLength(fm: Record<string, unknown>, body: string, docName: string): string | null;
8
9
  /** Schema checks for a doc living in a substrate memory dir: a memory store
9
10
  * holds ONLY substrate docs, so a missing/invalid `kind` is an authoring
10
- * error here (elsewhere it just means "not a substrate doc"). Both rungs are
11
- * REQUIRED — there is no kind default to lean on, so a missing rung is an
12
- * authoring error. Rung and gate values are checked RAW — the runtime parser
13
- * silently falls back to the neutral floor / inert gates, which is exactly the
14
- * silent tolerance this lint exists to catch at authoring time. */
11
+ * error here (elsewhere it just means "not a substrate doc"). Fields are
12
+ * checked RAW — the runtime parser silently drops invalid entries, which is
13
+ * exactly the silent tolerance this lint exists to catch at authoring time. */
15
14
  export declare function lintSubstrateSchema(fm: Record<string, unknown> | null): string | null;
16
15
  export declare const lintLeaf: import("../../core/command.js").LeafDef;