@north-light/crouter 0.3.182 → 0.3.183

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 (102) hide show
  1. package/dist/build-root.js +10 -3
  2. package/dist/builtin-memory/internal/memory-loading.md +3 -1
  3. package/dist/clients/attach/__tests__/group-activity.test.js +2 -2
  4. package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +1 -0
  5. package/dist/clients/attach/__tests__/titled-editor-paste.test.js +114 -0
  6. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +4 -1
  7. package/dist/clients/attach/input/titled-editor.d.ts +18 -0
  8. package/dist/clients/attach/input/titled-editor.js +62 -0
  9. package/dist/clients/attach/render/chat-view.d.ts +3 -0
  10. package/dist/clients/attach/render/chat-view.js +15 -6
  11. package/dist/clients/attach/render/context-message.js +2 -2
  12. package/dist/clients/attach/render/group-activity.d.ts +18 -1
  13. package/dist/clients/attach/render/group-activity.js +54 -6
  14. package/dist/clients/attach/render/group-recap.js +13 -2
  15. package/dist/clients/attach/render/{markdown-headings.d.ts → markdown-source.d.ts} +4 -4
  16. package/dist/clients/attach/render/markdown-source.js +165 -0
  17. package/dist/clients/attach/session/bindings.js +5 -2
  18. package/dist/clients/attach/viewer.js +396 -394
  19. package/dist/clients/inbox/review/keys.js +2 -9
  20. package/dist/clients/inbox/tui/keys.js +2 -9
  21. package/dist/commands/cron.js +1 -1
  22. package/dist/commands/memory/delete.js +1 -1
  23. package/dist/commands/memory/find.js +1 -1
  24. package/dist/commands/memory/lint.js +28 -3
  25. package/dist/commands/memory/list.js +1 -1
  26. package/dist/commands/memory/origin.js +1 -1
  27. package/dist/commands/memory/read.js +4 -4
  28. package/dist/commands/memory/write.js +1 -1
  29. package/dist/commands/sys/settings-shell.d.ts +0 -3
  30. package/dist/commands/sys/settings-shell.js +1 -38
  31. package/dist/commands/sys/settings.js +2 -3
  32. package/dist/commands/sys/setup-core.d.ts +2 -17
  33. package/dist/commands/sys/setup-core.js +9 -33
  34. package/dist/commands/sys/setup-wizard.d.ts +1 -3
  35. package/dist/commands/sys/setup-wizard.js +9 -39
  36. package/dist/commands/sys/setup.js +6 -6
  37. package/dist/commands/sys/sync-project-guidance.js +62 -12
  38. package/dist/core/__tests__/fault-classifier.test.js +20 -0
  39. package/dist/core/__tests__/nested-store-discovery.test.d.ts +1 -0
  40. package/dist/core/__tests__/nested-store-discovery.test.js +89 -0
  41. package/dist/core/__tests__/on-read-nested-store.test.d.ts +1 -0
  42. package/dist/core/__tests__/on-read-nested-store.test.js +117 -0
  43. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +1 -0
  44. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +38 -0
  45. package/dist/core/__tests__/serial/tmux-surface.test.js +8 -5
  46. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +34 -1
  47. package/dist/core/command.js +5 -3
  48. package/dist/core/fault-classifier.d.ts +1 -1
  49. package/dist/core/fault-classifier.js +7 -0
  50. package/dist/core/fs-utils.js +6 -1
  51. package/dist/core/keybindings/index.d.ts +1 -1
  52. package/dist/core/keybindings/index.js +1 -1
  53. package/dist/core/keybindings/match.d.ts +11 -0
  54. package/dist/core/keybindings/match.js +22 -0
  55. package/dist/core/memory/doc-link-grammar.js +3 -7
  56. package/dist/core/memory/inline-ref-guidance.js +1 -1
  57. package/dist/core/memory-resolver.d.ts +7 -1
  58. package/dist/core/memory-resolver.js +20 -7
  59. package/dist/core/nested-stores.d.ts +12 -0
  60. package/dist/core/nested-stores.js +146 -0
  61. package/dist/core/preview-registry.js +4 -2
  62. package/dist/core/runtime/bearings.d.ts +1 -1
  63. package/dist/core/runtime/bearings.js +2 -2
  64. package/dist/core/runtime/broker/fault-retry.js +23 -4
  65. package/dist/core/runtime/broker-extension-render.d.ts +1 -1
  66. package/dist/core/runtime/broker-extension-render.js +2 -2
  67. package/dist/core/runtime/broker-protocol.d.ts +1 -1
  68. package/dist/core/runtime/deliver-live.js +11 -1
  69. package/dist/core/runtime/fault.js +1 -1
  70. package/dist/core/runtime/tmux-bindings.js +42 -20
  71. package/dist/core/runtime/tool-group-summary.js +2 -6
  72. package/dist/core/substrate/injected-store.d.ts +6 -0
  73. package/dist/core/substrate/injected-store.js +19 -0
  74. package/dist/core/substrate/on-read-node.d.ts +4 -2
  75. package/dist/core/substrate/on-read-node.js +5 -3
  76. package/dist/core/substrate/on-read.d.ts +4 -2
  77. package/dist/core/substrate/on-read.js +27 -5
  78. package/dist/pi-extensions/canvas-context-intro.d.ts +1 -1
  79. package/dist/pi-extensions/canvas-context-intro.js +14 -3
  80. package/dist/pi-extensions/canvas-doc-substrate.js +13 -2
  81. package/dist/shared/generated-context.d.ts +4 -0
  82. package/dist/shared/generated-context.js +20 -1
  83. package/dist/shared/tool-groups.d.ts +3 -3
  84. package/dist/shared/tool-groups.js +1 -4
  85. package/package.json +1 -1
  86. package/runtime.lock.json +2 -2
  87. package/scripts/postinstall.mjs +1 -1
  88. package/dist/clients/attach/render/markdown-headings.js +0 -93
  89. package/dist/commands/search/answer.d.ts +0 -1
  90. package/dist/commands/search/answer.js +0 -50
  91. package/dist/commands/search/contents.d.ts +0 -1
  92. package/dist/commands/search/contents.js +0 -96
  93. package/dist/commands/search/exa.d.ts +0 -53
  94. package/dist/commands/search/exa.js +0 -157
  95. package/dist/commands/search/puremd.d.ts +0 -11
  96. package/dist/commands/search/puremd.js +0 -53
  97. package/dist/commands/search/web.d.ts +0 -1
  98. package/dist/commands/search/web.js +0 -65
  99. package/dist/commands/search.d.ts +0 -2
  100. package/dist/commands/search.js +0 -24
  101. package/dist/commands/sys/panels/keys-panel.d.ts +0 -16
  102. package/dist/commands/sys/panels/keys-panel.js +0 -60
@@ -1,7 +1,7 @@
1
- /** Style ATX headings with a scan-friendly terminal hierarchy. The Markdown
2
- * markers are syntax, not content, so omit them from the rendered line.
3
- * Fenced examples remain literal Markdown, never decorated terminal output. */
4
- export declare function styleAttachMarkdownHeadings(markdown: string): string;
1
+ /** Decorate a Markdown block for terminal rendering: heading hierarchy and XML
2
+ * tag lines. Fenced examples remain literal Markdown, never decorated
3
+ * terminal output. */
4
+ export declare function styleAttachMarkdownSource(markdown: string): string;
5
5
  /** Copy a pi message for terminal rendering and decorate only Markdown-bearing
6
6
  * text/thinking blocks. The broker's source event is never mutated. */
7
7
  export declare function styleAttachMessageMarkdown<T>(message: T): T;
@@ -0,0 +1,165 @@
1
+ // Source-text transforms the attach viewer applies before pi-tui parses a
2
+ // Markdown block. Every transform here rewrites the DISPLAY copy only —
3
+ // persisted messages and copied text stay ordinary Markdown without terminal
4
+ // escape sequences.
5
+ //
6
+ // HEADINGS. pi-tui's MarkdownTheme exposes one `heading(text)` callback without
7
+ // the heading depth. Its renderer does know the depth, but does not pass it to
8
+ // the theme, so every heading otherwise receives the same yellow mdHeading
9
+ // paint. Decorate only the source text of H3–H6: pi still owns parsing,
10
+ // wrapping, inline formatting, and H1/H2's established styling.
11
+ //
12
+ // XML TAG LINES. crouter's own context is XML-framed (`<crtr-bearings>`,
13
+ // `<memory …>`, `<environment …>`), and agents quote XML in replies. A line
14
+ // that is nothing but a tag opens a CommonMark HTML block, which runs to the
15
+ // next blank line and renders as undecorated raw text — so `# Heading` on the
16
+ // line after `<memory …>` came out as literal text with its `#`, and a closing
17
+ // tag hanging off a list got absorbed into the last list item. Painting the tag
18
+ // line means it no longer starts with `<`, so no HTML block opens and the
19
+ // Markdown inside the envelope parses normally; a blank line on each side keeps
20
+ // the tag from joining the paragraph or list beside it.
21
+ //
22
+ // GLYPHS. Private-use `U+XXXX` references become their glyphs (see
23
+ // glyph-codepoints.ts), so an agent that cannot type a Nerd Font character can
24
+ // still put one on screen.
25
+ import { expandGlyphCodepoints } from './glyph-codepoints.js';
26
+ const ATX_HEADING = /^(\s{0,3})(#{3,6})(?:[ \t]+|$)(.*?)([ \t]+#+[ \t]*)?$/;
27
+ const FENCE_OPEN = /^\s{0,3}(`{3,}|~{3,})/;
28
+ /** A line holding one tag and nothing else: `<name …>`, `</name>`, `<name/>`.
29
+ * Attribute text may not contain angle brackets, so a tag whose value carries
30
+ * a literal `>` stays untouched rather than being mis-split. */
31
+ const XML_TAG_LINE = /^([ \t]{0,3})(<\/?)([A-Za-z][\w.:-]*)((?:[ \t]+[^<>]*?)?)(\/?)>[ \t]*$/;
32
+ const XML_ATTRIBUTE = /([^\s=]+)(?:=("[^"]*"|'[^']*'|[^\s]*))?/g;
33
+ /** Tags the HTML allowlist owns (see html-markdown.ts). A `<details>` block
34
+ * that reaches this pass is one that failed validation there and is meant to
35
+ * stay literal. */
36
+ const HTML_ALLOWLIST_TAGS = new Set(['details', 'summary', 'kbd', 'mark']);
37
+ // A constant-lightness ramp from warm yellow to cool blue, with saturation
38
+ // deliberately reduced at each step so the hierarchy recedes rather than
39
+ // becoming a tour of unrelated accent colors.
40
+ const HEADING_COLORS = [
41
+ [232, 194, 104],
42
+ [207, 194, 145],
43
+ [181, 184, 174],
44
+ [157, 170, 180],
45
+ [135, 153, 164],
46
+ [116, 135, 147],
47
+ ];
48
+ // Structural framing, not content. The hue relationships mirror the XML
49
+ // highlighting pi already applies inside fenced code — blue tag name, duller
50
+ // blue attribute, warm quoted value — at a lower brightness, because an
51
+ // envelope tag wrapping prose should be scannable without competing with the
52
+ // prose the way a code block does.
53
+ const XML_PUNCTUATION = [104, 112, 124];
54
+ const XML_NAME = [138, 166, 196];
55
+ const XML_ATTRIBUTE_NAME = [124, 146, 164];
56
+ const XML_VALUE = [168, 142, 118];
57
+ /** Paint a fragment with a foreground color and restore only the foreground,
58
+ * so a surrounding message style (background, weight) survives. */
59
+ function paint(color, text) {
60
+ return `\x1b[38;2;${color[0]};${color[1]};${color[2]}m${text}\x1b[39m`;
61
+ }
62
+ function headingColor(level) {
63
+ const [r, g, b] = HEADING_COLORS[level - 1];
64
+ return (text) => `\x1b[1;38;2;${r};${g};${b}m${text}\x1b[22;39m`;
65
+ }
66
+ /** Style one ATX H3–H6 line. The Markdown markers are syntax, not content, so
67
+ * omit them from the rendered line. */
68
+ function styleHeadingLine(line) {
69
+ const match = ATX_HEADING.exec(line);
70
+ if (!match)
71
+ return undefined;
72
+ const [, indent, hashes, body] = match;
73
+ if (body === '')
74
+ return undefined;
75
+ return `${indent}${headingColor(hashes.length)(body)}`;
76
+ }
77
+ function styleAttributes(attributes) {
78
+ return attributes.replace(XML_ATTRIBUTE, (whole, name, value) => (value === undefined
79
+ ? paint(XML_ATTRIBUTE_NAME, whole)
80
+ : `${paint(XML_ATTRIBUTE_NAME, name)}${paint(XML_PUNCTUATION, '=')}${paint(XML_VALUE, value)}`));
81
+ }
82
+ /** Style a line that is exactly one XML tag, or return undefined to leave it. */
83
+ function styleXmlTagLine(line) {
84
+ const match = XML_TAG_LINE.exec(line);
85
+ if (!match)
86
+ return undefined;
87
+ const [, indent, open, name, attributes, selfClose] = match;
88
+ if (HTML_ALLOWLIST_TAGS.has(name.toLowerCase()))
89
+ return undefined;
90
+ return indent
91
+ + paint(XML_PUNCTUATION, open)
92
+ + paint(XML_NAME, name)
93
+ + styleAttributes(attributes)
94
+ + paint(XML_PUNCTUATION, `${selfClose}>`);
95
+ }
96
+ /** Decorate a Markdown block for terminal rendering: heading hierarchy and XML
97
+ * tag lines. Fenced examples remain literal Markdown, never decorated
98
+ * terminal output. */
99
+ export function styleAttachMarkdownSource(markdown) {
100
+ const lines = markdown.split('\n');
101
+ const out = [];
102
+ let fence;
103
+ for (let index = 0; index < lines.length; index++) {
104
+ const line = lines[index];
105
+ const fenceMatch = FENCE_OPEN.exec(line);
106
+ if (fence !== undefined) {
107
+ if (fenceMatch?.[1][0] === fence)
108
+ fence = undefined;
109
+ out.push(line);
110
+ continue;
111
+ }
112
+ if (fenceMatch) {
113
+ fence = fenceMatch[1][0];
114
+ out.push(line);
115
+ continue;
116
+ }
117
+ const tag = styleXmlTagLine(line);
118
+ if (tag !== undefined) {
119
+ if (out.length > 0 && out[out.length - 1].trim() !== '')
120
+ out.push('');
121
+ out.push(tag);
122
+ if (lines[index + 1] !== undefined && lines[index + 1].trim() !== '')
123
+ out.push('');
124
+ continue;
125
+ }
126
+ out.push(styleHeadingLine(line) ?? line);
127
+ }
128
+ return out.join('\n');
129
+ }
130
+ /** Every source-text transform the viewer applies to a Markdown-bearing block,
131
+ * in one place: heading and XML syntax, then glyph expansion. */
132
+ function renderableText(markdown) {
133
+ return expandGlyphCodepoints(styleAttachMarkdownSource(markdown));
134
+ }
135
+ /** Copy a pi message for terminal rendering and decorate only Markdown-bearing
136
+ * text/thinking blocks. The broker's source event is never mutated. */
137
+ export function styleAttachMessageMarkdown(message) {
138
+ if (typeof message !== 'object' || message === null || !('content' in message))
139
+ return message;
140
+ const candidate = message;
141
+ if (typeof candidate.content === 'string') {
142
+ return { ...candidate, content: renderableText(candidate.content) };
143
+ }
144
+ if (!Array.isArray(candidate.content))
145
+ return message;
146
+ return {
147
+ ...candidate,
148
+ content: candidate.content.map((part) => {
149
+ if (typeof part !== 'object' || part === null)
150
+ return part;
151
+ const block = part;
152
+ if (block.type === 'text' && typeof block.text === 'string') {
153
+ return { ...block, text: renderableText(block.text) };
154
+ }
155
+ if (block.type === 'thinking' && typeof block.thinking === 'string') {
156
+ return { ...block, thinking: renderableText(block.thinking) };
157
+ }
158
+ return part;
159
+ }),
160
+ };
161
+ }
162
+ /** Copy an expanded pi summary without changing its persisted source. */
163
+ export function styleAttachSummaryMarkdown(message) {
164
+ return { ...message, summary: renderableText(message.summary) };
165
+ }
@@ -5,7 +5,7 @@
5
5
  // tmux installer binds from (`core/keybindings`), never from ad-hoc key
6
6
  // literals, so a user's rebind is honored by the viewer and tmux alike.
7
7
  import { matchesKey } from '@earendil-works/pi-tui';
8
- import { ATTACH_CONTROL_BINDINGS, formatBinding, matchesPiTuiInput, } from '../../../core/keybindings/index.js';
8
+ import { ATTACH_CONTROL_BINDINGS, formatBinding, matchesPiTuiInput, normalizeShiftedMeta, } from '../../../core/keybindings/index.js';
9
9
  export const ATTACH_VIEWPORT_BINDINGS = [
10
10
  'crtr.attach.scroll.up', 'crtr.attach.scroll.down',
11
11
  'crtr.attach.scroll.page-up', 'crtr.attach.scroll.page-down',
@@ -15,7 +15,10 @@ export const ATTACH_VIEWPORT_BINDINGS = [
15
15
  ];
16
16
  export { inboxOpenHint } from '../../../core/keybindings/index.js';
17
17
  export function matchesAttachBinding(bindings, id, data) {
18
- return matchesPiTuiInput(bindings, id, data, (input, gesture) => matchesKey(input, gesture));
18
+ // Match the normalized chunk, never the raw one: a terminal that sends Option
19
+ // as a meta prefix spells Alt+Shift+M in a form pi-tui rejects. Only matching
20
+ // reads the rewrite — unclaimed input reaches the editor exactly as typed.
21
+ return matchesPiTuiInput(bindings, id, normalizeShiftedMeta(data), (input, gesture) => matchesKey(input, gesture));
19
22
  }
20
23
  export function dispatchAttachAction(id, actions) {
21
24
  actions[id]();