deepclause-sdk 0.1.2 → 0.2.1

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 (122) hide show
  1. package/README.md +45 -6
  2. package/dist/cli/config.d.ts +2 -2
  3. package/dist/cli/repl.d.ts +55 -4
  4. package/dist/cli/repl.d.ts.map +1 -1
  5. package/dist/cli/repl.js +675 -52
  6. package/dist/cli/repl.js.map +1 -1
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +3 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/prolog-src/deepclause_mi.pl +516 -2
  12. package/dist/repl/backend.d.ts +9 -0
  13. package/dist/repl/backend.d.ts.map +1 -1
  14. package/dist/repl/backend.js +62 -5
  15. package/dist/repl/backend.js.map +1 -1
  16. package/dist/repl/harness-tools.d.ts +36 -0
  17. package/dist/repl/harness-tools.d.ts.map +1 -1
  18. package/dist/repl/harness-tools.js +173 -0
  19. package/dist/repl/harness-tools.js.map +1 -1
  20. package/dist/repl/history.d.ts +29 -0
  21. package/dist/repl/history.d.ts.map +1 -1
  22. package/dist/repl/history.js +71 -0
  23. package/dist/repl/history.js.map +1 -1
  24. package/dist/repl/index.d.ts +6 -0
  25. package/dist/repl/index.d.ts.map +1 -1
  26. package/dist/repl/index.js +9 -1
  27. package/dist/repl/index.js.map +1 -1
  28. package/dist/repl/picker.d.ts +3 -0
  29. package/dist/repl/picker.d.ts.map +1 -1
  30. package/dist/repl/picker.js +132 -0
  31. package/dist/repl/picker.js.map +1 -1
  32. package/dist/repl/process-backend.d.ts +31 -0
  33. package/dist/repl/process-backend.d.ts.map +1 -0
  34. package/dist/repl/process-backend.js +10 -0
  35. package/dist/repl/process-backend.js.map +1 -0
  36. package/dist/repl/process-executor.d.ts +67 -0
  37. package/dist/repl/process-executor.d.ts.map +1 -0
  38. package/dist/repl/process-executor.js +371 -0
  39. package/dist/repl/process-executor.js.map +1 -0
  40. package/dist/repl/process-worker.d.ts +10 -0
  41. package/dist/repl/process-worker.d.ts.map +1 -0
  42. package/dist/repl/process-worker.js +210 -0
  43. package/dist/repl/process-worker.js.map +1 -0
  44. package/dist/repl/processes.d.ts +282 -0
  45. package/dist/repl/processes.d.ts.map +1 -0
  46. package/dist/repl/processes.js +557 -0
  47. package/dist/repl/processes.js.map +1 -0
  48. package/dist/repl/render.d.ts +52 -2
  49. package/dist/repl/render.d.ts.map +1 -1
  50. package/dist/repl/render.js +52 -17
  51. package/dist/repl/render.js.map +1 -1
  52. package/dist/repl/session.d.ts +135 -3
  53. package/dist/repl/session.d.ts.map +1 -1
  54. package/dist/repl/session.js +413 -4
  55. package/dist/repl/session.js.map +1 -1
  56. package/dist/repl/status.d.ts +3 -1
  57. package/dist/repl/status.d.ts.map +1 -1
  58. package/dist/repl/status.js +4 -0
  59. package/dist/repl/status.js.map +1 -1
  60. package/dist/repl/tui/autocomplete.d.ts +19 -0
  61. package/dist/repl/tui/autocomplete.d.ts.map +1 -0
  62. package/dist/repl/tui/autocomplete.js +48 -0
  63. package/dist/repl/tui/autocomplete.js.map +1 -0
  64. package/dist/repl/tui/document.d.ts +51 -0
  65. package/dist/repl/tui/document.d.ts.map +1 -0
  66. package/dist/repl/tui/document.js +160 -0
  67. package/dist/repl/tui/document.js.map +1 -0
  68. package/dist/repl/tui/harness-view.d.ts +102 -0
  69. package/dist/repl/tui/harness-view.d.ts.map +1 -0
  70. package/dist/repl/tui/harness-view.js +323 -0
  71. package/dist/repl/tui/harness-view.js.map +1 -0
  72. package/dist/repl/tui/picker.d.ts +31 -0
  73. package/dist/repl/tui/picker.d.ts.map +1 -0
  74. package/dist/repl/tui/picker.js +43 -0
  75. package/dist/repl/tui/picker.js.map +1 -0
  76. package/dist/repl/tui/renderer.d.ts +98 -0
  77. package/dist/repl/tui/renderer.d.ts.map +1 -0
  78. package/dist/repl/tui/renderer.js +289 -0
  79. package/dist/repl/tui/renderer.js.map +1 -0
  80. package/dist/repl/tui/services-panel.d.ts +35 -0
  81. package/dist/repl/tui/services-panel.d.ts.map +1 -0
  82. package/dist/repl/tui/services-panel.js +108 -0
  83. package/dist/repl/tui/services-panel.js.map +1 -0
  84. package/dist/repl/tui/status-bar.d.ts +6 -2
  85. package/dist/repl/tui/status-bar.d.ts.map +1 -1
  86. package/dist/repl/tui/status-bar.js +82 -24
  87. package/dist/repl/tui/status-bar.js.map +1 -1
  88. package/dist/repl/tui/terminal.d.ts +28 -0
  89. package/dist/repl/tui/terminal.d.ts.map +1 -0
  90. package/dist/repl/tui/terminal.js +94 -0
  91. package/dist/repl/tui/terminal.js.map +1 -0
  92. package/dist/repl/tui/theme.d.ts +60 -0
  93. package/dist/repl/tui/theme.d.ts.map +1 -1
  94. package/dist/repl/tui/theme.js +142 -0
  95. package/dist/repl/tui/theme.js.map +1 -1
  96. package/dist/repl/tui/tool-pane.d.ts +68 -0
  97. package/dist/repl/tui/tool-pane.d.ts.map +1 -0
  98. package/dist/repl/tui/tool-pane.js +261 -0
  99. package/dist/repl/tui/tool-pane.js.map +1 -0
  100. package/dist/repl/tui/working-line.d.ts +23 -0
  101. package/dist/repl/tui/working-line.d.ts.map +1 -0
  102. package/dist/repl/tui/working-line.js +58 -0
  103. package/dist/repl/tui/working-line.js.map +1 -0
  104. package/dist/repl/worker-host.d.ts +80 -0
  105. package/dist/repl/worker-host.d.ts.map +1 -0
  106. package/dist/repl/worker-host.js +305 -0
  107. package/dist/repl/worker-host.js.map +1 -0
  108. package/dist/repl/worker-protocol.d.ts +123 -0
  109. package/dist/repl/worker-protocol.d.ts.map +1 -0
  110. package/dist/repl/worker-protocol.js +9 -0
  111. package/dist/repl/worker-protocol.js.map +1 -0
  112. package/dist/runner.d.ts +24 -0
  113. package/dist/runner.d.ts.map +1 -1
  114. package/dist/runner.js +47 -0
  115. package/dist/runner.js.map +1 -1
  116. package/dist/system/assets/docs/AGENT_PROMPT.md +193 -0
  117. package/dist/system/assets/docs/DML_AUTHORING.md +21 -0
  118. package/dist/system/assets/docs/DML_REFERENCE.md +145 -0
  119. package/dist/types.d.ts +7 -0
  120. package/dist/types.d.ts.map +1 -1
  121. package/package.json +2 -1
  122. package/src/prolog-src/deepclause_mi.pl +516 -2
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Component transcript for the fullscreen TUI.
3
+ *
4
+ * The plain/readline path keeps the line-based `TranscriptComponent`; the TUI
5
+ * needs a tree, because a tool call, a streamed answer and a code fence have to
6
+ * be *components* (so markdown can be re-rendered as text arrives, a tool pane can
7
+ * expand, and `ScrollView` can scroll a bounded document).
8
+ *
9
+ * Entries are either styled text lines (rendered at the current width, so a
10
+ * resize re-wraps them) or components rendered as-is.
11
+ */
12
+ import { visibleWidth, wrapTextWithAnsi, } from '@earendil-works/pi-tui';
13
+ import { renderSteerLine, renderUserLine, STEER_LABEL } from './theme.js';
14
+ /**
15
+ * The stem and indentation a line starts with (`run │ `, ` │ `, `run │ `, or
16
+ * leading spaces), so a wrapped line keeps it.
17
+ *
18
+ * The line renderer embeds the frame prefix in the text it emits. When the document
19
+ * then wraps that text to the terminal width, the continuation lines carried no
20
+ * prefix at all — a wrapped solution read as `T = "…"` followed by an unindented
21
+ * second line, outside the tree.
22
+ */
23
+ function leadingStem(text) {
24
+ const match = /^((?:\s*(?:\w+ )?│ )?\s*)/.exec(text);
25
+ return match?.[1] ?? '';
26
+ }
27
+ /** A bounded component document: append-only, with one live (unterminated) line. */
28
+ export class TranscriptDocument {
29
+ entries = [];
30
+ pending = '';
31
+ pendingStyle;
32
+ maxEntries;
33
+ /** Called whenever content changes, so the TUI can schedule a render. */
34
+ onChange;
35
+ constructor(maxEntries = 2000) {
36
+ this.maxEntries = maxEntries;
37
+ }
38
+ trim() {
39
+ if (this.entries.length > this.maxEntries) {
40
+ this.entries.splice(0, this.entries.length - this.maxEntries);
41
+ }
42
+ }
43
+ /** Append one styled line. Consecutive blank lines collapse. */
44
+ appendText(line, style) {
45
+ const last = this.entries[this.entries.length - 1];
46
+ if (line === '' && last?.kind === 'text' && last.text === '') {
47
+ return;
48
+ }
49
+ this.entries.push({ kind: 'text', text: line, style });
50
+ this.trim();
51
+ this.onChange?.();
52
+ }
53
+ /** Alias for `appendText`, matching the line-based transcript's API. */
54
+ append(line, style) {
55
+ this.appendText(line, style);
56
+ }
57
+ /**
58
+ * Append a component (a tool pane, markdown block, status notice).
59
+ *
60
+ * Components get a blank line above them unless the document already ends in one.
61
+ * Without it a tool call, its output and the next tool call read as one wall of
62
+ * text — the transcript has no other separation once the blocks are adjacent.
63
+ */
64
+ appendComponent(component) {
65
+ const last = this.entries[this.entries.length - 1];
66
+ const atStart = this.entries.length === 0;
67
+ if (!atStart && !(last?.kind === 'text' && last.text === '')) {
68
+ this.entries.push({ kind: 'text', text: '' });
69
+ }
70
+ this.entries.push({ kind: 'component', component });
71
+ this.trim();
72
+ this.onChange?.();
73
+ }
74
+ /** Append terminal-image lines verbatim: they must not be wrapped or measured. */
75
+ appendImageLines(lines) {
76
+ for (const line of lines) {
77
+ this.entries.push({ kind: 'image', line });
78
+ }
79
+ this.trim();
80
+ this.onChange?.();
81
+ }
82
+ /** The live (not yet newline-terminated) line, as the line sink writes it. */
83
+ setPending(line, style) {
84
+ this.pending = line;
85
+ this.pendingStyle = style;
86
+ this.onChange?.();
87
+ }
88
+ /** Whether anything has been written (used to separate user turns). */
89
+ isEmpty() {
90
+ return this.entries.length === 0 && this.pending === '';
91
+ }
92
+ /**
93
+ * One string per entry. Kept for callers that only ask "is there output yet";
94
+ * the rendered text of a component is not available without a width.
95
+ */
96
+ getLines() {
97
+ return this.entries.map((entry) => entry.kind === 'text' ? entry.text : entry.kind === 'image' ? entry.line : '');
98
+ }
99
+ clear() {
100
+ this.entries = [];
101
+ this.pending = '';
102
+ this.onChange?.();
103
+ }
104
+ render(width) {
105
+ const source = this.pending
106
+ ? [...this.entries, { kind: 'text', text: this.pending, style: this.pendingStyle }]
107
+ : this.entries;
108
+ const out = [];
109
+ for (const entry of source) {
110
+ if (entry.kind === 'image') {
111
+ out.push(entry.line);
112
+ continue;
113
+ }
114
+ if (entry.kind === 'component') {
115
+ out.push(...entry.component.render(width));
116
+ continue;
117
+ }
118
+ if (width <= 0) {
119
+ out.push(entry.text);
120
+ continue;
121
+ }
122
+ // Styled blocks reserve room for their label/padding.
123
+ if (entry.style === 'user' || entry.style === 'steer') {
124
+ const wrapWidth = entry.style === 'user'
125
+ ? Math.max(1, width - 2)
126
+ : Math.max(1, width - STEER_LABEL.length);
127
+ const wrapped = visibleWidth(entry.text) <= wrapWidth
128
+ ? [entry.text]
129
+ : wrapTextWithAnsi(entry.text, wrapWidth);
130
+ wrapped.forEach((line, index) => {
131
+ if (entry.style === 'user')
132
+ out.push(renderUserLine(line, width));
133
+ else
134
+ out.push(renderSteerLine(line, width, index === 0));
135
+ });
136
+ continue;
137
+ }
138
+ // Everything else: keep the line's stem (`run │ `, or its indent) out of the
139
+ // wrap and put it back on every line. Handing the wrapper a string that already
140
+ // begins with indentation splits it wrongly — it produced a line containing
141
+ // nothing but the stem, and a leading blank line for indented text.
142
+ const stem = leadingStem(entry.text);
143
+ const body = entry.text.slice(stem.length);
144
+ const bodyWidth = Math.max(1, width - visibleWidth(stem));
145
+ const wrapped = visibleWidth(body) <= bodyWidth
146
+ ? [body]
147
+ : wrapTextWithAnsi(body, bodyWidth);
148
+ for (const line of wrapped)
149
+ out.push(`${stem}${line}`);
150
+ }
151
+ return out;
152
+ }
153
+ invalidate() {
154
+ for (const entry of this.entries) {
155
+ if (entry.kind === 'component')
156
+ entry.component.invalidate?.();
157
+ }
158
+ }
159
+ }
160
+ //# sourceMappingURL=document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../../../src/repl/tui/document.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The harness side view: watch the module change while the agent builds it.
3
+ *
4
+ * A second column beside the transcript, showing what the harness *is right now* —
5
+ * including uncommitted edits, because it reads the session module rather than the
6
+ * last commit. Each predicate gets a row with its size and what it is (entry point,
7
+ * tool, documented), and anything that changed since the previous frame is marked and
8
+ * flashes for a moment, so an edit is visible as it happens rather than only in the
9
+ * transcript.
10
+ *
11
+ * It also keeps a short history of the module's size and draws it as a sparkline: a
12
+ * harness taking shape has a shape of its own, and it is the one thing here that
13
+ * rewards watching over time.
14
+ */
15
+ import { type Component, type TuiMouseEvent, type TuiMouseEventResult } from '@earendil-works/pi-tui';
16
+ /** One predicate as the side view shows it. */
17
+ export interface HarnessPredicate {
18
+ indicator: string;
19
+ name: string;
20
+ arity: number;
21
+ clauses: number;
22
+ /** `entry` (agent_main), `tool`, `doc`, `touched` (changed in the open transaction). */
23
+ flags: string[];
24
+ }
25
+ export interface HarnessSnapshot {
26
+ predicates: HarnessPredicate[];
27
+ /** Last committed version, when history is enabled. */
28
+ version?: number;
29
+ /** True while an edit transaction is open (uncommitted edits are shown). */
30
+ transactionOpen: boolean;
31
+ /** Predicates the open transaction has touched. */
32
+ touched: string[];
33
+ lastCommit?: boolean;
34
+ }
35
+ export interface HarnessViewOptions {
36
+ /** Injectable clock, so the flash window is testable without fake timers. */
37
+ now?: () => number;
38
+ /** Ask the host for a predicate's source; answered with `setSource`. */
39
+ requestSource?: (indicator: string) => void;
40
+ /** Called when the user leaves the view, so focus can go back to the editor. */
41
+ onExit?: () => void;
42
+ }
43
+ export declare class HarnessView implements Component {
44
+ private readonly getSnapshot;
45
+ private readonly clock;
46
+ /** Which predicates changed last refresh, and when, so the marker can fade. */
47
+ private changes;
48
+ private previous;
49
+ private history;
50
+ private rows;
51
+ private removed;
52
+ private lastRefresh;
53
+ private lastNote;
54
+ /** Cursor and the predicate being drilled into. */
55
+ private selected;
56
+ private openIndicator?;
57
+ private sourceLines;
58
+ private sourceLoading;
59
+ /** Where the predicate rows start in the rendered output, for hit-testing clicks. */
60
+ private rowsStart;
61
+ constructor(getSnapshot: () => HarnessSnapshot | undefined, options?: HarnessViewOptions);
62
+ private readonly requestSource?;
63
+ private readonly onExit?;
64
+ /** The predicate under the cursor. */
65
+ get selectedIndicator(): string | undefined;
66
+ /** The predicate currently drilled into, if any. */
67
+ get open(): string | undefined;
68
+ /** The host's answer to `requestSource`. */
69
+ setSource(indicator: string, lines: string[]): void;
70
+ private openPredicate;
71
+ private closeDrilldown;
72
+ /** Keyboard: move the cursor, open a predicate, go back. */
73
+ handleInput(data: string): void;
74
+ /**
75
+ * Mouse: the alternate screen routes a click to the box under the pointer and makes
76
+ * `y` relative to this component, so the rendered line index is the hit test.
77
+ */
78
+ handleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined;
79
+ private moveCursor;
80
+ private clampSelectedToCursor;
81
+ /** Refresh from the session. Cheap enough to call after every tool call. */
82
+ refresh(): void;
83
+ /** True while a change marker is still within its flash window. */
84
+ private marker;
85
+ /**
86
+ * Rendered fresh every frame, deliberately: the output depends on the clock (a
87
+ * marker fades), so a width-keyed cache holds stale lines exactly when the change
88
+ * should be visible. A width-keyed cache is what froze the flash on screen.
89
+ */
90
+ render(width: number): string[];
91
+ private renderLines;
92
+ /** The clauses of the predicate under the cursor, indented under the view's rule. */
93
+ private drilldown;
94
+ private row;
95
+ private touchedIndicators;
96
+ /** A compact sparkline of the module's size, oldest to newest. */
97
+ private sparkline;
98
+ invalidate(): void;
99
+ }
100
+ /** Wrap a long indicator for a narrow column, so nothing is silently cut. */
101
+ export declare function wrapIndicator(indicator: string, width: number): string[];
102
+ //# sourceMappingURL=harness-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-view.d.ts","sourceRoot":"","sources":["../../../src/repl/tui/harness-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,323 @@
1
+ /**
2
+ * The harness side view: watch the module change while the agent builds it.
3
+ *
4
+ * A second column beside the transcript, showing what the harness *is right now* —
5
+ * including uncommitted edits, because it reads the session module rather than the
6
+ * last commit. Each predicate gets a row with its size and what it is (entry point,
7
+ * tool, documented), and anything that changed since the previous frame is marked and
8
+ * flashes for a moment, so an edit is visible as it happens rather than only in the
9
+ * transcript.
10
+ *
11
+ * It also keeps a short history of the module's size and draws it as a sparkline: a
12
+ * harness taking shape has a shape of its own, and it is the one thing here that
13
+ * rewards watching over time.
14
+ */
15
+ import { matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi, } from '@earendil-works/pi-tui';
16
+ import { paintToken, tuiStyle } from './theme.js';
17
+ /** How long a change keeps its marker. */
18
+ const FLASH_MS = 4000;
19
+ /** Rows of history in the sparkline. */
20
+ const SPARK_POINTS = 28;
21
+ const SPARK_CHARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
22
+ export class HarnessView {
23
+ getSnapshot;
24
+ clock;
25
+ /** Which predicates changed last refresh, and when, so the marker can fade. */
26
+ changes = new Map();
27
+ previous = new Map();
28
+ history = [];
29
+ rows = [];
30
+ removed = [];
31
+ lastRefresh = 0;
32
+ lastNote = '';
33
+ /** Cursor and the predicate being drilled into. */
34
+ selected = 0;
35
+ openIndicator;
36
+ sourceLines = [];
37
+ sourceLoading = false;
38
+ /** Where the predicate rows start in the rendered output, for hit-testing clicks. */
39
+ rowsStart = 0;
40
+ constructor(getSnapshot, options = {}) {
41
+ this.getSnapshot = getSnapshot;
42
+ this.clock = options.now ?? (() => Date.now());
43
+ this.requestSource = options.requestSource;
44
+ this.onExit = options.onExit;
45
+ }
46
+ requestSource;
47
+ onExit;
48
+ /** The predicate under the cursor. */
49
+ get selectedIndicator() {
50
+ return this.rows[this.selected]?.indicator;
51
+ }
52
+ /** The predicate currently drilled into, if any. */
53
+ get open() {
54
+ return this.openIndicator;
55
+ }
56
+ /** The host's answer to `requestSource`. */
57
+ setSource(indicator, lines) {
58
+ if (indicator !== this.openIndicator)
59
+ return;
60
+ this.sourceLines = lines.map((line) => line.replace(/\s+$/, ''));
61
+ this.sourceLoading = false;
62
+ }
63
+ openPredicate(indicator) {
64
+ if (!indicator)
65
+ return;
66
+ this.openIndicator = indicator;
67
+ this.sourceLines = [];
68
+ this.sourceLoading = true;
69
+ this.requestSource?.(indicator);
70
+ }
71
+ closeDrilldown() {
72
+ this.openIndicator = undefined;
73
+ this.sourceLines = [];
74
+ this.sourceLoading = false;
75
+ }
76
+ /** Keyboard: move the cursor, open a predicate, go back. */
77
+ handleInput(data) {
78
+ if (matchesKey(data, 'escape') || matchesKey(data, 'left')) {
79
+ if (this.openIndicator) {
80
+ this.closeDrilldown();
81
+ return;
82
+ }
83
+ this.onExit?.();
84
+ return;
85
+ }
86
+ if (matchesKey(data, 'up') || matchesKey(data, 'k')) {
87
+ this.moveCursor(-1);
88
+ return;
89
+ }
90
+ if (matchesKey(data, 'down') || matchesKey(data, 'j')) {
91
+ this.moveCursor(1);
92
+ return;
93
+ }
94
+ if (matchesKey(data, 'enter') || matchesKey(data, 'right') || matchesKey(data, 'space')) {
95
+ const indicator = this.selectedIndicator;
96
+ if (this.openIndicator === indicator)
97
+ this.closeDrilldown();
98
+ else
99
+ this.openPredicate(indicator);
100
+ }
101
+ }
102
+ /**
103
+ * Mouse: the alternate screen routes a click to the box under the pointer and makes
104
+ * `y` relative to this component, so the rendered line index is the hit test.
105
+ */
106
+ handleMouse(event) {
107
+ if (event.type === 'wheel') {
108
+ this.moveCursor((event.wheelDelta ?? 0) > 0 ? 1 : -1);
109
+ return { handled: true, render: true };
110
+ }
111
+ if (event.type !== 'press' && event.type !== 'click')
112
+ return undefined;
113
+ const index = event.y - this.rowsStart;
114
+ if (index < 0 || index >= this.rows.length) {
115
+ // Clicking the header or the sparkline drills back out.
116
+ if (this.openIndicator) {
117
+ this.closeDrilldown();
118
+ return { handled: true, render: true };
119
+ }
120
+ return undefined;
121
+ }
122
+ this.selected = index;
123
+ const indicator = this.selectedIndicator;
124
+ if (this.openIndicator === indicator)
125
+ this.closeDrilldown();
126
+ else
127
+ this.openPredicate(indicator);
128
+ return { handled: true, focus: true, render: true };
129
+ }
130
+ moveCursor(delta) {
131
+ this.selected = Math.min(Math.max(0, this.rows.length - 1), Math.max(0, this.selected + delta));
132
+ this.clampSelectedToCursor();
133
+ }
134
+ clampSelectedToCursor() {
135
+ const indicator = this.selectedIndicator;
136
+ // Moving the cursor while drilled in follows it, so the panel always describes the
137
+ // highlighted predicate rather than the one you opened.
138
+ if (this.openIndicator && indicator !== this.openIndicator)
139
+ this.openPredicate(indicator);
140
+ }
141
+ /** Refresh from the session. Cheap enough to call after every tool call. */
142
+ refresh() {
143
+ const snapshot = this.getSnapshot();
144
+ if (!snapshot)
145
+ return;
146
+ const now = this.clock();
147
+ const next = new Map(snapshot.predicates.map((predicate) => [predicate.indicator, predicate.clauses]));
148
+ // Keep recent markers visible across refreshes (a refresh happens per tool call,
149
+ // so an edit that flashed for 20ms would otherwise never be seen) and record the
150
+ // new ones.
151
+ this.changes = new Map([...this.changes].filter(([, change]) => now - change.at <= FLASH_MS));
152
+ for (const [indicator, clauses] of next) {
153
+ const before = this.previous.get(indicator);
154
+ if (before === undefined)
155
+ this.changes.set(indicator, { kind: 'added', at: now });
156
+ else if (before !== clauses)
157
+ this.changes.set(indicator, { kind: 'changed', at: now });
158
+ }
159
+ this.removed = [];
160
+ for (const indicator of this.previous.keys()) {
161
+ if (!next.has(indicator)) {
162
+ this.removed.push(indicator);
163
+ this.changes.set(indicator, { kind: 'removed', at: now });
164
+ }
165
+ }
166
+ const total = [...next.values()].reduce((sum, clauses) => sum + clauses, 0);
167
+ if (this.history.at(-1) !== total)
168
+ this.history.push(total);
169
+ if (this.history.length > SPARK_POINTS)
170
+ this.history.splice(0, this.history.length - SPARK_POINTS);
171
+ if (this.changes.size > 0) {
172
+ const [indicator, change] = [...this.changes.entries()][0] ?? [];
173
+ if (indicator && change) {
174
+ const verb = change.kind === 'added' ? 'added' : change.kind === 'changed' ? 'updated' : 'removed';
175
+ this.lastNote = `${verb} ${indicator}`;
176
+ }
177
+ }
178
+ this.previous = next;
179
+ this.rows = snapshot.predicates;
180
+ this.lastRefresh = now;
181
+ }
182
+ /** True while a change marker is still within its flash window. */
183
+ marker(indicator) {
184
+ const change = this.changes.get(indicator);
185
+ if (!change)
186
+ return undefined;
187
+ return this.clock() - change.at <= FLASH_MS ? change.kind : undefined;
188
+ }
189
+ /**
190
+ * Rendered fresh every frame, deliberately: the output depends on the clock (a
191
+ * marker fades), so a width-keyed cache holds stale lines exactly when the change
192
+ * should be visible. A width-keyed cache is what froze the flash on screen.
193
+ */
194
+ render(width) {
195
+ return this.renderLines(Math.max(12, width));
196
+ }
197
+ renderLines(width) {
198
+ const out = [];
199
+ const snapshot = this.getSnapshot();
200
+ const total = this.rows.reduce((sum, predicate) => sum + predicate.clauses, 0);
201
+ // Header: the harness, its version, and whether what you see is committed.
202
+ const version = snapshot?.version !== undefined ? ` v${snapshot.version}` : '';
203
+ const state = snapshot?.transactionOpen ? tuiStyle.warning(' ● editing') : '';
204
+ out.push(truncateToWidth(`${tuiStyle.title(`harness${version}`)}${state}`, width, '…'));
205
+ out.push(tuiStyle.dim(truncateToWidth(`${this.rows.length} predicate${this.rows.length === 1 ? '' : 's'} · ${total} clause${total === 1 ? '' : 's'}`, width, '…')));
206
+ // The size over time: the interesting part to watch.
207
+ out.push(this.sparkline(width));
208
+ const rule = tuiStyle.borderMuted('─'.repeat(Math.max(0, width)));
209
+ out.push(rule);
210
+ if (this.openIndicator) {
211
+ // The rows are not on screen while drilled in, so no click can land on one; a
212
+ // click anywhere is "go back".
213
+ this.rowsStart = Number.POSITIVE_INFINITY;
214
+ out.push(...this.drilldown(width));
215
+ return out;
216
+ }
217
+ this.rowsStart = out.length;
218
+ if (this.rows.length === 0) {
219
+ out.push(tuiStyle.dim('(empty — nothing defined yet)'));
220
+ }
221
+ this.rows.forEach((predicate, index) => {
222
+ out.push(this.row(predicate, width, index === this.selected));
223
+ });
224
+ for (const indicator of this.removed) {
225
+ const change = this.marker(indicator);
226
+ if (!change)
227
+ continue;
228
+ out.push(truncateToWidth(`${tuiStyle.error('−')} ${tuiStyle.dim(strikethrough(indicator))}`, width, '…'));
229
+ }
230
+ out.push('');
231
+ out.push(tuiStyle.dim(truncateToWidth('↑↓ move · enter open · click a row', width, '…')));
232
+ // The most recent change, so the view says what just happened.
233
+ if (this.lastNote && this.clock() - this.lastRefresh < FLASH_MS) {
234
+ out.push('');
235
+ out.push(truncateToWidth(tuiStyle.dim(this.lastNote), width, '…'));
236
+ }
237
+ return out;
238
+ }
239
+ /** The clauses of the predicate under the cursor, indented under the view's rule. */
240
+ drilldown(width) {
241
+ const out = [];
242
+ out.push(tuiStyle.title(truncateToWidth(this.openIndicator ?? '', width, '…')));
243
+ out.push(tuiStyle.dim(truncateToWidth('esc to go back', width, '…')));
244
+ out.push(tuiStyle.borderMuted('─'.repeat(Math.max(0, width))));
245
+ if (this.sourceLoading) {
246
+ out.push(tuiStyle.dim('loading…'));
247
+ return out;
248
+ }
249
+ const lines = this.sourceLines.filter((line) => line.trim() !== '');
250
+ const budget = 40;
251
+ for (const line of lines.slice(0, budget)) {
252
+ // Indent the source so it reads as belonging to the drilled-in predicate, and
253
+ // wrap rather than cut: a truncated clause body is worse than a wrapped one.
254
+ const wrapped = wrapTextWithAnsi(line, Math.max(8, width - 2));
255
+ for (const piece of wrapped)
256
+ out.push(tuiStyle.output(` ${piece}`));
257
+ }
258
+ if (lines.length > budget) {
259
+ out.push(tuiStyle.dim(` … ${lines.length - budget} more lines`));
260
+ }
261
+ return out;
262
+ }
263
+ row(predicate, width, cursor) {
264
+ const change = this.marker(predicate.indicator);
265
+ const marker = change === 'added'
266
+ ? tuiStyle.success('+')
267
+ : change === 'changed'
268
+ ? tuiStyle.warning('~')
269
+ : change === 'removed'
270
+ ? tuiStyle.error('−')
271
+ : ' ';
272
+ const touchable = this.touchedIndicators().has(predicate.indicator);
273
+ const name = change ? paintToken('title', predicate.indicator, { bold: true })
274
+ : touchable ? tuiStyle.accent(predicate.indicator)
275
+ : predicate.indicator;
276
+ const badges = [];
277
+ if (predicate.flags.includes('entry'))
278
+ badges.push(tuiStyle.accent('entry'));
279
+ if (predicate.flags.includes('tool'))
280
+ badges.push(tuiStyle.success('tool'));
281
+ if (predicate.flags.includes('doc'))
282
+ badges.push(tuiStyle.dim('doc'));
283
+ badges.push(tuiStyle.dim(`${predicate.clauses}c`));
284
+ const pointer = cursor ? tuiStyle.accent('❯') : ' ';
285
+ const left = `${pointer}${marker} ${name}`;
286
+ const right = badges.join(' ');
287
+ const gap = Math.max(1, width - visibleWidth(left) - visibleWidth(right));
288
+ return truncateToWidth(`${left}${' '.repeat(gap)}${right}`, width, '…');
289
+ }
290
+ touchedIndicators() {
291
+ const snapshot = this.getSnapshot();
292
+ return new Set(snapshot?.touched ?? []);
293
+ }
294
+ /** A compact sparkline of the module's size, oldest to newest. */
295
+ sparkline(width) {
296
+ // With a single sample there is no shape to draw yet, but a row of dots reads as
297
+ // "broken". Draw the level instead, so the row is meaningful from the first frame.
298
+ const values = this.history.slice(-Math.max(2, Math.min(SPARK_POINTS, width)));
299
+ const padded = this.history.length === 1 ? [values[0] ?? 0, values[0] ?? 0] : values;
300
+ const min = Math.min(...padded);
301
+ const max = Math.max(...padded);
302
+ const span = max - min || 1;
303
+ const text = padded
304
+ .map((value) => {
305
+ const level = Math.round(((value - min) / span) * (SPARK_CHARS.length - 1));
306
+ return SPARK_CHARS[level] ?? '▁';
307
+ })
308
+ .join('');
309
+ return truncateToWidth(paintToken('output', text), width, '…');
310
+ }
311
+ invalidate() {
312
+ // Nothing cached by choice; see `render`.
313
+ }
314
+ }
315
+ /** Strike-through without pulling a colour helper in for one glyph. */
316
+ function strikethrough(text) {
317
+ return `\u001b[9m${text}\u001b[0m`;
318
+ }
319
+ /** Wrap a long indicator for a narrow column, so nothing is silently cut. */
320
+ export function wrapIndicator(indicator, width) {
321
+ return visibleWidth(indicator) <= width ? [indicator] : wrapTextWithAnsi(indicator, width);
322
+ }
323
+ //# sourceMappingURL=harness-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness-view.js","sourceRoot":"","sources":["../../../src/repl/tui/harness-view.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * A chooser overlay: a titled list the user picks from.
3
+ *
4
+ * Used for the model and the reasoning-display setting. It is a plain component so
5
+ * the host can place it with `tui.showOverlay`; `onSelect`/`onCancel` tell the host
6
+ * when to take it down. Keys are the list's own (up/down, enter, escape), which is
7
+ * what pi's pickers use, so nothing has to be re-taught.
8
+ */
9
+ import { type Component, type SelectItem } from '@earendil-works/pi-tui';
10
+ export interface ChoicePickerOptions {
11
+ /** Heading, e.g. "Model" or "Reasoning". */
12
+ title: string;
13
+ items: SelectItem[];
14
+ /** `value` of the item to start on. */
15
+ current?: string;
16
+ /** Shown under the title, e.g. what the choice affects. */
17
+ hint?: string;
18
+ onSelect: (item: SelectItem) => void;
19
+ onCancel: () => void;
20
+ }
21
+ export declare class ChoicePicker implements Component {
22
+ private readonly options;
23
+ private readonly list;
24
+ constructor(options: ChoicePickerOptions);
25
+ /** The visible lines, so a host can size the overlay to its content. */
26
+ get contentHeight(): number;
27
+ render(width: number): string[];
28
+ handleInput(data: string): void;
29
+ invalidate(): void;
30
+ }
31
+ //# sourceMappingURL=picker.d.ts.map