plasalid 0.2.0

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 (153) hide show
  1. package/LICENSE +213 -0
  2. package/README.md +176 -0
  3. package/dist/accounts/taxonomy.d.ts +31 -0
  4. package/dist/accounts/taxonomy.js +189 -0
  5. package/dist/ai/agent.d.ts +43 -0
  6. package/dist/ai/agent.js +155 -0
  7. package/dist/ai/context.d.ts +4 -0
  8. package/dist/ai/context.js +33 -0
  9. package/dist/ai/memory.d.ts +14 -0
  10. package/dist/ai/memory.js +12 -0
  11. package/dist/ai/provider.d.ts +67 -0
  12. package/dist/ai/provider.js +5 -0
  13. package/dist/ai/providers/anthropic.d.ts +5 -0
  14. package/dist/ai/providers/anthropic.js +49 -0
  15. package/dist/ai/providers/index.d.ts +2 -0
  16. package/dist/ai/providers/index.js +12 -0
  17. package/dist/ai/providers/openai-compat.d.ts +5 -0
  18. package/dist/ai/providers/openai-compat.js +147 -0
  19. package/dist/ai/providers/openai.d.ts +5 -0
  20. package/dist/ai/providers/openai.js +147 -0
  21. package/dist/ai/redactor.d.ts +2 -0
  22. package/dist/ai/redactor.js +91 -0
  23. package/dist/ai/sanitize.d.ts +14 -0
  24. package/dist/ai/sanitize.js +25 -0
  25. package/dist/ai/system-prompt.d.ts +13 -0
  26. package/dist/ai/system-prompt.js +174 -0
  27. package/dist/ai/thai-taxonomy-hint.d.ts +8 -0
  28. package/dist/ai/thai-taxonomy-hint.js +22 -0
  29. package/dist/ai/thinking-phrases.d.ts +7 -0
  30. package/dist/ai/thinking-phrases.js +15 -0
  31. package/dist/ai/thinking.d.ts +7 -0
  32. package/dist/ai/thinking.js +15 -0
  33. package/dist/ai/tools/common.d.ts +2 -0
  34. package/dist/ai/tools/common.js +83 -0
  35. package/dist/ai/tools/index.d.ts +8 -0
  36. package/dist/ai/tools/index.js +34 -0
  37. package/dist/ai/tools/ingest.d.ts +2 -0
  38. package/dist/ai/tools/ingest.js +202 -0
  39. package/dist/ai/tools/read.d.ts +2 -0
  40. package/dist/ai/tools/read.js +123 -0
  41. package/dist/ai/tools/reconcile.d.ts +2 -0
  42. package/dist/ai/tools/reconcile.js +227 -0
  43. package/dist/ai/tools/scan.d.ts +2 -0
  44. package/dist/ai/tools/scan.js +24 -0
  45. package/dist/ai/tools/types.d.ts +26 -0
  46. package/dist/ai/tools/types.js +1 -0
  47. package/dist/ai/tools.d.ts +18 -0
  48. package/dist/ai/tools.js +402 -0
  49. package/dist/cli/chat.d.ts +1 -0
  50. package/dist/cli/chat.js +28 -0
  51. package/dist/cli/commands/accounts.d.ts +1 -0
  52. package/dist/cli/commands/accounts.js +86 -0
  53. package/dist/cli/commands/data.d.ts +1 -0
  54. package/dist/cli/commands/data.js +28 -0
  55. package/dist/cli/commands/reconcile.d.ts +2 -0
  56. package/dist/cli/commands/reconcile.js +15 -0
  57. package/dist/cli/commands/revert.d.ts +1 -0
  58. package/dist/cli/commands/revert.js +68 -0
  59. package/dist/cli/commands/scan.d.ts +4 -0
  60. package/dist/cli/commands/scan.js +45 -0
  61. package/dist/cli/commands/status.d.ts +1 -0
  62. package/dist/cli/commands/status.js +22 -0
  63. package/dist/cli/commands/transactions.d.ts +8 -0
  64. package/dist/cli/commands/transactions.js +92 -0
  65. package/dist/cli/commands/undo.d.ts +1 -0
  66. package/dist/cli/commands/undo.js +38 -0
  67. package/dist/cli/commands.d.ts +14 -0
  68. package/dist/cli/commands.js +196 -0
  69. package/dist/cli/format.d.ts +8 -0
  70. package/dist/cli/format.js +109 -0
  71. package/dist/cli/index.d.ts +2 -0
  72. package/dist/cli/index.js +126 -0
  73. package/dist/cli/ink/ChatApp.d.ts +8 -0
  74. package/dist/cli/ink/ChatApp.js +94 -0
  75. package/dist/cli/ink/PromptFrame.d.ts +10 -0
  76. package/dist/cli/ink/PromptFrame.js +11 -0
  77. package/dist/cli/ink/TextInput.d.ts +13 -0
  78. package/dist/cli/ink/TextInput.js +24 -0
  79. package/dist/cli/ink/hooks/useAgent.d.ts +27 -0
  80. package/dist/cli/ink/hooks/useAgent.js +65 -0
  81. package/dist/cli/ink/hooks/useCtrlCExit.d.ts +16 -0
  82. package/dist/cli/ink/hooks/useCtrlCExit.js +43 -0
  83. package/dist/cli/ink/hooks/useFooterText.d.ts +2 -0
  84. package/dist/cli/ink/hooks/useFooterText.js +43 -0
  85. package/dist/cli/ink/hooks/useTextInput.d.ts +32 -0
  86. package/dist/cli/ink/hooks/useTextInput.js +356 -0
  87. package/dist/cli/ink/messages/AssistantMessage.d.ts +3 -0
  88. package/dist/cli/ink/messages/AssistantMessage.js +6 -0
  89. package/dist/cli/ink/messages/ErrorMessage.d.ts +4 -0
  90. package/dist/cli/ink/messages/ErrorMessage.js +6 -0
  91. package/dist/cli/ink/messages/InterruptedMessage.d.ts +1 -0
  92. package/dist/cli/ink/messages/InterruptedMessage.js +6 -0
  93. package/dist/cli/ink/messages/ThinkingLine.d.ts +12 -0
  94. package/dist/cli/ink/messages/ThinkingLine.js +23 -0
  95. package/dist/cli/ink/messages/UserMessage.d.ts +4 -0
  96. package/dist/cli/ink/messages/UserMessage.js +15 -0
  97. package/dist/cli/ink/mount.d.ts +6 -0
  98. package/dist/cli/ink/mount.js +12 -0
  99. package/dist/cli/logo.d.ts +1 -0
  100. package/dist/cli/logo.js +20 -0
  101. package/dist/cli/setup.d.ts +2 -0
  102. package/dist/cli/setup.js +210 -0
  103. package/dist/cli/ux.d.ts +38 -0
  104. package/dist/cli/ux.js +104 -0
  105. package/dist/config.d.ts +21 -0
  106. package/dist/config.js +66 -0
  107. package/dist/currency.d.ts +6 -0
  108. package/dist/currency.js +19 -0
  109. package/dist/db/connection.d.ts +5 -0
  110. package/dist/db/connection.js +45 -0
  111. package/dist/db/encryption.d.ts +11 -0
  112. package/dist/db/encryption.js +45 -0
  113. package/dist/db/helpers.d.ts +16 -0
  114. package/dist/db/helpers.js +45 -0
  115. package/dist/db/queries/account_balance.d.ts +61 -0
  116. package/dist/db/queries/account_balance.js +146 -0
  117. package/dist/db/queries/journal.d.ts +95 -0
  118. package/dist/db/queries/journal.js +204 -0
  119. package/dist/db/queries/search.d.ts +7 -0
  120. package/dist/db/queries/search.js +19 -0
  121. package/dist/db/schema.d.ts +2 -0
  122. package/dist/db/schema.js +95 -0
  123. package/dist/index.d.ts +1 -0
  124. package/dist/index.js +1 -0
  125. package/dist/parser/pdf.d.ts +14 -0
  126. package/dist/parser/pdf.js +40 -0
  127. package/dist/parser/pipeline.d.ts +44 -0
  128. package/dist/parser/pipeline.js +160 -0
  129. package/dist/parser/prompts.d.ts +8 -0
  130. package/dist/parser/prompts.js +20 -0
  131. package/dist/parser/walker.d.ts +8 -0
  132. package/dist/parser/walker.js +42 -0
  133. package/dist/reconciler/pipeline.d.ts +17 -0
  134. package/dist/reconciler/pipeline.js +45 -0
  135. package/dist/reconciler/prompts.d.ts +12 -0
  136. package/dist/reconciler/prompts.js +22 -0
  137. package/dist/scanner/password-store.d.ts +34 -0
  138. package/dist/scanner/password-store.js +83 -0
  139. package/dist/scanner/pdf-unlock.d.ts +17 -0
  140. package/dist/scanner/pdf-unlock.js +48 -0
  141. package/dist/scanner/pdf.d.ts +17 -0
  142. package/dist/scanner/pdf.js +36 -0
  143. package/dist/scanner/pipeline.d.ts +32 -0
  144. package/dist/scanner/pipeline.js +137 -0
  145. package/dist/scanner/prompts.d.ts +8 -0
  146. package/dist/scanner/prompts.js +20 -0
  147. package/dist/scanner/state-machine.d.ts +60 -0
  148. package/dist/scanner/state-machine.js +64 -0
  149. package/dist/scanner/unlock.d.ts +24 -0
  150. package/dist/scanner/unlock.js +122 -0
  151. package/dist/scanner/walker.d.ts +8 -0
  152. package/dist/scanner/walker.js +42 -0
  153. package/package.json +65 -0
@@ -0,0 +1,356 @@
1
+ import { useEffect, useRef, useState, useCallback } from "react";
2
+ import { useStdin } from "ink";
3
+ const EMPTY_BUFFER = { lines: [""], row: 0, col: 0 };
4
+ /** Key bytes we care about. */
5
+ const CTRL_A = 1;
6
+ const CTRL_C = 3;
7
+ const CTRL_D = 4;
8
+ const CTRL_E = 5;
9
+ const CTRL_K = 11;
10
+ const CTRL_U = 21;
11
+ const CTRL_W = 23;
12
+ const ENTER = 13;
13
+ const BACKSPACE = 127;
14
+ const BACKSPACE_ALT = 8;
15
+ const ESC = 27;
16
+ function cloneBuf(b) {
17
+ return { lines: [...b.lines], row: b.row, col: b.col };
18
+ }
19
+ function wordLeft(line, col) {
20
+ let p = col;
21
+ while (p > 0 && line[p - 1] === " ")
22
+ p--;
23
+ while (p > 0 && line[p - 1] !== " ")
24
+ p--;
25
+ return p;
26
+ }
27
+ function wordRight(line, col) {
28
+ let p = col;
29
+ while (p < line.length && line[p] !== " ")
30
+ p++;
31
+ while (p < line.length && line[p] === " ")
32
+ p++;
33
+ return p;
34
+ }
35
+ function insertText(buf, text) {
36
+ const pieces = text.split("\n");
37
+ const lines = [...buf.lines];
38
+ const cur = lines[buf.row];
39
+ const before = cur.slice(0, buf.col);
40
+ const after = cur.slice(buf.col);
41
+ if (pieces.length === 1) {
42
+ lines[buf.row] = before + pieces[0] + after;
43
+ return { lines, row: buf.row, col: buf.col + pieces[0].length };
44
+ }
45
+ const first = pieces[0];
46
+ const last = pieces[pieces.length - 1];
47
+ const middle = pieces.slice(1, -1);
48
+ const newLines = [
49
+ ...lines.slice(0, buf.row),
50
+ before + first,
51
+ ...middle,
52
+ last + after,
53
+ ...lines.slice(buf.row + 1),
54
+ ];
55
+ return {
56
+ lines: newLines,
57
+ row: buf.row + pieces.length - 1,
58
+ col: last.length,
59
+ };
60
+ }
61
+ function backspace(buf) {
62
+ if (buf.col > 0) {
63
+ const lines = [...buf.lines];
64
+ const cur = lines[buf.row];
65
+ lines[buf.row] = cur.slice(0, buf.col - 1) + cur.slice(buf.col);
66
+ return { lines, row: buf.row, col: buf.col - 1 };
67
+ }
68
+ if (buf.row > 0) {
69
+ const lines = [...buf.lines];
70
+ const prev = lines[buf.row - 1];
71
+ const cur = lines[buf.row];
72
+ lines[buf.row - 1] = prev + cur;
73
+ lines.splice(buf.row, 1);
74
+ return { lines, row: buf.row - 1, col: prev.length };
75
+ }
76
+ return buf;
77
+ }
78
+ function deleteWordLeft(buf) {
79
+ const cur = buf.lines[buf.row];
80
+ if (buf.col === 0)
81
+ return backspace(buf);
82
+ const target = wordLeft(cur, buf.col);
83
+ const lines = [...buf.lines];
84
+ lines[buf.row] = cur.slice(0, target) + cur.slice(buf.col);
85
+ return { lines, row: buf.row, col: target };
86
+ }
87
+ function moveLeft(buf) {
88
+ if (buf.col > 0)
89
+ return { ...buf, col: buf.col - 1 };
90
+ if (buf.row > 0) {
91
+ const prev = buf.lines[buf.row - 1];
92
+ return { ...buf, row: buf.row - 1, col: prev.length };
93
+ }
94
+ return buf;
95
+ }
96
+ function moveRight(buf) {
97
+ const cur = buf.lines[buf.row];
98
+ if (buf.col < cur.length)
99
+ return { ...buf, col: buf.col + 1 };
100
+ if (buf.row < buf.lines.length - 1)
101
+ return { ...buf, row: buf.row + 1, col: 0 };
102
+ return buf;
103
+ }
104
+ function moveUp(buf) {
105
+ if (buf.row === 0)
106
+ return buf;
107
+ const target = buf.lines[buf.row - 1];
108
+ return { ...buf, row: buf.row - 1, col: Math.min(buf.col, target.length) };
109
+ }
110
+ function moveDown(buf) {
111
+ if (buf.row === buf.lines.length - 1)
112
+ return buf;
113
+ const target = buf.lines[buf.row + 1];
114
+ return { ...buf, row: buf.row + 1, col: Math.min(buf.col, target.length) };
115
+ }
116
+ function moveWordLeft(buf) {
117
+ const cur = buf.lines[buf.row];
118
+ if (buf.col === 0)
119
+ return moveLeft(buf);
120
+ return { ...buf, col: wordLeft(cur, buf.col) };
121
+ }
122
+ function moveWordRight(buf) {
123
+ const cur = buf.lines[buf.row];
124
+ if (buf.col === cur.length)
125
+ return moveRight(buf);
126
+ return { ...buf, col: wordRight(cur, buf.col) };
127
+ }
128
+ function toString(buf) {
129
+ return buf.lines.join("\n");
130
+ }
131
+ /**
132
+ * Raw-stdin driven keystroke state machine that owns a multiline buffer and
133
+ * exposes its current state plus reset/insert helpers. Purely stateful — Ink
134
+ * re-renders whenever the buffer changes via setBuffer.
135
+ *
136
+ * Handles: Enter/submit, Backspace, Ctrl+A/E/K/U/W, arrow keys, Option+←/→,
137
+ * Option+B/F, Option+Backspace, Kitty Cmd+Backspace, Shift+Enter (newline),
138
+ * bracketed paste.
139
+ */
140
+ export function useTextInput(opts) {
141
+ const [buffer, setBuffer] = useState(EMPTY_BUFFER);
142
+ const bufferRef = useRef(buffer);
143
+ bufferRef.current = buffer;
144
+ const optsRef = useRef(opts);
145
+ optsRef.current = opts;
146
+ const { stdin, setRawMode, isRawModeSupported } = useStdin();
147
+ const apply = useCallback((fn) => {
148
+ setBuffer(prev => {
149
+ const next = fn(prev);
150
+ optsRef.current.onChange?.(next);
151
+ return next;
152
+ });
153
+ }, []);
154
+ const reset = useCallback(() => {
155
+ setBuffer(EMPTY_BUFFER);
156
+ optsRef.current.onChange?.(EMPTY_BUFFER);
157
+ }, []);
158
+ useEffect(() => {
159
+ if (!isRawModeSupported || !stdin)
160
+ return;
161
+ setRawMode(true);
162
+ // Enable bracketed paste
163
+ process.stdout.write("\x1b[?2004h");
164
+ let pasteBuffer = null;
165
+ const onData = (data) => {
166
+ const chunk = data.toString("utf8");
167
+ // If we're inside a bracketed paste, accumulate until we see the end marker
168
+ if (pasteBuffer !== null) {
169
+ const endIdx = chunk.indexOf("\x1b[201~");
170
+ if (endIdx === -1) {
171
+ pasteBuffer += chunk;
172
+ return;
173
+ }
174
+ pasteBuffer += chunk.slice(0, endIdx);
175
+ const pasted = pasteBuffer;
176
+ pasteBuffer = null;
177
+ apply(b => insertText(b, pasted));
178
+ // Process any bytes after the end marker
179
+ const after = chunk.slice(endIdx + "\x1b[201~".length);
180
+ if (after.length > 0)
181
+ handleChunk(after);
182
+ return;
183
+ }
184
+ // Detect start-of-paste marker anywhere in the chunk
185
+ const startIdx = chunk.indexOf("\x1b[200~");
186
+ if (startIdx !== -1) {
187
+ const before = chunk.slice(0, startIdx);
188
+ if (before.length > 0)
189
+ handleChunk(before);
190
+ const rest = chunk.slice(startIdx + "\x1b[200~".length);
191
+ const endIdx = rest.indexOf("\x1b[201~");
192
+ if (endIdx === -1) {
193
+ pasteBuffer = rest;
194
+ return;
195
+ }
196
+ const pasted = rest.slice(0, endIdx);
197
+ apply(b => insertText(b, pasted));
198
+ const after = rest.slice(endIdx + "\x1b[201~".length);
199
+ if (after.length > 0)
200
+ handleChunk(after);
201
+ return;
202
+ }
203
+ handleChunk(chunk);
204
+ };
205
+ const handleChunk = (chunk) => {
206
+ for (let i = 0; i < chunk.length; i++) {
207
+ const code = chunk.charCodeAt(i);
208
+ const raw = chunk[i];
209
+ // Let custom handlers intercept first
210
+ if (optsRef.current.onKey?.({ code, raw }) === true)
211
+ continue;
212
+ if (code === CTRL_C) {
213
+ optsRef.current.onCtrlC(bufferRef.current.lines.length === 1 && bufferRef.current.lines[0] === "");
214
+ continue;
215
+ }
216
+ if (code === CTRL_D) {
217
+ // Treat as exit request when buffer empty; otherwise ignore
218
+ const b = bufferRef.current;
219
+ if (b.lines.length === 1 && b.lines[0] === "") {
220
+ optsRef.current.onCtrlC(true);
221
+ }
222
+ continue;
223
+ }
224
+ if (code === CTRL_A) {
225
+ apply(b => ({ ...b, col: 0 }));
226
+ continue;
227
+ }
228
+ if (code === CTRL_E) {
229
+ apply(b => ({ ...b, col: b.lines[b.row].length }));
230
+ continue;
231
+ }
232
+ if (code === CTRL_K) {
233
+ apply(b => {
234
+ const lines = [...b.lines];
235
+ lines[b.row] = lines[b.row].slice(0, b.col);
236
+ return { lines, row: b.row, col: b.col };
237
+ });
238
+ continue;
239
+ }
240
+ if (code === CTRL_U) {
241
+ apply(b => {
242
+ const lines = [...b.lines];
243
+ lines[b.row] = lines[b.row].slice(b.col);
244
+ return { lines, row: b.row, col: 0 };
245
+ });
246
+ continue;
247
+ }
248
+ if (code === CTRL_W) {
249
+ apply(deleteWordLeft);
250
+ continue;
251
+ }
252
+ if (code === ENTER) {
253
+ optsRef.current.onSubmit(toString(bufferRef.current));
254
+ setBuffer(EMPTY_BUFFER);
255
+ optsRef.current.onChange?.(EMPTY_BUFFER);
256
+ continue;
257
+ }
258
+ if (code === BACKSPACE || code === BACKSPACE_ALT) {
259
+ apply(backspace);
260
+ continue;
261
+ }
262
+ if (code === ESC) {
263
+ // Option+Backspace (ESC + DEL)
264
+ if (i + 1 < chunk.length && chunk.charCodeAt(i + 1) === 127) {
265
+ i++;
266
+ apply(deleteWordLeft);
267
+ continue;
268
+ }
269
+ // Option+b / Option+f
270
+ if (i + 1 < chunk.length && chunk[i + 1] === "b") {
271
+ i++;
272
+ apply(moveWordLeft);
273
+ continue;
274
+ }
275
+ if (i + 1 < chunk.length && chunk[i + 1] === "f") {
276
+ i++;
277
+ apply(moveWordRight);
278
+ continue;
279
+ }
280
+ // CSI sequence: ESC [ ... final
281
+ if (i + 1 < chunk.length && chunk[i + 1] === "[") {
282
+ i += 2;
283
+ let seq = "";
284
+ while (i < chunk.length && chunk.charCodeAt(i) < 64) {
285
+ seq += chunk[i];
286
+ i++;
287
+ }
288
+ if (i < chunk.length) {
289
+ const final = chunk[i];
290
+ const isWordMod = seq === "1;3" || seq === "1;5" || seq === "1;9";
291
+ if (final === "D") {
292
+ apply(isWordMod ? moveWordLeft : moveLeft);
293
+ }
294
+ else if (final === "C") {
295
+ apply(isWordMod ? moveWordRight : moveRight);
296
+ }
297
+ else if (final === "A") {
298
+ apply(moveUp);
299
+ }
300
+ else if (final === "B") {
301
+ apply(moveDown);
302
+ }
303
+ else if (final === "H") {
304
+ apply(b => ({ ...b, col: 0 }));
305
+ }
306
+ else if (final === "F") {
307
+ apply(b => ({ ...b, col: b.lines[b.row].length }));
308
+ }
309
+ else if (final === "u") {
310
+ // Kitty keyboard protocol: ESC [ codepoint ; modifier u
311
+ const parts = seq.split(";");
312
+ const codepoint = parseInt(parts[0], 10);
313
+ const mod = parts.length > 1 ? parseInt(parts[1], 10) : 1;
314
+ const hasShift = ((mod - 1) & 1) !== 0;
315
+ const hasCtrl = ((mod - 1) & 4) !== 0;
316
+ const hasCmd = ((mod - 1) & 8) !== 0;
317
+ if (codepoint === 13 && hasShift) {
318
+ // Shift+Enter → insert newline
319
+ apply(b => insertText(b, "\n"));
320
+ }
321
+ else if (codepoint === 127 && (hasCmd || hasCtrl)) {
322
+ // Cmd/Ctrl+Backspace → delete to line start
323
+ apply(b => {
324
+ const lines = [...b.lines];
325
+ lines[b.row] = lines[b.row].slice(b.col);
326
+ return { lines, row: b.row, col: 0 };
327
+ });
328
+ }
329
+ }
330
+ }
331
+ continue;
332
+ }
333
+ // Lone ESC / unknown — ignore
334
+ continue;
335
+ }
336
+ // Printable (and tab)
337
+ if (code >= 32 || code === 9) {
338
+ apply(b => insertText(b, raw));
339
+ continue;
340
+ }
341
+ }
342
+ };
343
+ stdin.on("data", onData);
344
+ return () => {
345
+ stdin.removeListener("data", onData);
346
+ process.stdout.write("\x1b[?2004l");
347
+ setRawMode(false);
348
+ };
349
+ }, [stdin, setRawMode, isRawModeSupported, apply]);
350
+ return {
351
+ buffer,
352
+ reset,
353
+ insert: (text) => apply(b => insertText(b, text)),
354
+ isEmpty: buffer.lines.length === 1 && buffer.lines[0] === "",
355
+ };
356
+ }
@@ -0,0 +1,3 @@
1
+ export declare function AssistantMessage({ text }: {
2
+ text: string;
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { formatResponse } from "../../format.js";
4
+ export function AssistantMessage({ text }) {
5
+ return (_jsx(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: _jsx(Text, { children: formatResponse(text) }) }));
6
+ }
@@ -0,0 +1,4 @@
1
+ export declare function ErrorMessage({ error, context }: {
2
+ error: unknown;
3
+ context?: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { formatError } from "../../format.js";
4
+ export function ErrorMessage({ error, context }) {
5
+ return (_jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { children: formatError(error, context) }) }));
6
+ }
@@ -0,0 +1 @@
1
+ export declare function InterruptedMessage(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import chalk from "chalk";
4
+ export function InterruptedMessage() {
5
+ return (_jsx(Box, { marginTop: 1, marginBottom: 1, children: _jsx(Text, { children: chalk.dim("(interrupted)") }) }));
6
+ }
@@ -0,0 +1,12 @@
1
+ export interface ThinkingState {
2
+ phrase: string;
3
+ progress?: {
4
+ toolName?: string;
5
+ toolCount: number;
6
+ elapsedMs: number;
7
+ phase: "tool" | "responding";
8
+ };
9
+ }
10
+ export declare function ThinkingLine({ state }: {
11
+ state: ThinkingState;
12
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import Spinner from "ink-spinner";
4
+ import chalk from "chalk";
5
+ import { TOOL_LABELS } from "../../../ai/tools/index.js";
6
+ import { formatDuration } from "../../format.js";
7
+ export function ThinkingLine({ state }) {
8
+ const text = buildText(state);
9
+ return (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { children: [" ", text] })] }));
10
+ }
11
+ function buildText(state) {
12
+ const { phrase, progress } = state;
13
+ if (!progress)
14
+ return phrase;
15
+ const { phase, toolName, toolCount, elapsedMs } = progress;
16
+ const label = phase === "tool" && toolName
17
+ ? (TOOL_LABELS[toolName] || toolName)
18
+ : "Composing response";
19
+ const suffix = toolCount > 0
20
+ ? chalk.dim(` (${toolCount} ${toolCount === 1 ? "tool" : "tools"}, ${formatDuration(elapsedMs)})`)
21
+ : "";
22
+ return `${label}...${suffix}`;
23
+ }
@@ -0,0 +1,4 @@
1
+ /** Gray-background, full-width echo of a submitted user message. */
2
+ export declare function UserMessage({ text }: {
3
+ text: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text, useStdout } from "ink";
3
+ /** Gray-background, full-width echo of a submitted user message. */
4
+ export function UserMessage({ text }) {
5
+ const { stdout } = useStdout();
6
+ const cols = stdout?.columns || 80;
7
+ const line = `❯ ${text}`;
8
+ const pad = Math.max(0, cols - visibleLength(line));
9
+ return _jsx(Text, { backgroundColor: "gray", color: "white", children: line + " ".repeat(pad) });
10
+ }
11
+ function visibleLength(s) {
12
+ // Rough approximation — ignores combining characters and wide glyphs.
13
+ // Ink pads within its own width calc so this is only for right-edge filler.
14
+ return [...s].length;
15
+ }
@@ -0,0 +1,6 @@
1
+ import type Database from "libsql";
2
+ /** Mounts the chat UI and resolves when the user exits. */
3
+ export declare function runChatApp(opts: {
4
+ db: Database.Database;
5
+ onboardingPrompt?: string;
6
+ }): Promise<void>;
@@ -0,0 +1,12 @@
1
+ import { render } from "ink";
2
+ import { createElement } from "react";
3
+ import { ChatApp } from "./ChatApp.js";
4
+ /** Mounts the chat UI and resolves when the user exits. */
5
+ export async function runChatApp(opts) {
6
+ if (!process.stdin.isTTY) {
7
+ console.error("plasalid chat requires an interactive TTY.");
8
+ return;
9
+ }
10
+ const instance = render(createElement(ChatApp, opts));
11
+ await instance.waitUntilExit();
12
+ }
@@ -0,0 +1 @@
1
+ export declare function printLogo(): void;
@@ -0,0 +1,20 @@
1
+ import chalk from "chalk";
2
+ const FISH = [
3
+ " ",
4
+ " ",
5
+ " ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑ ",
6
+ " ↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑↑↑ ",
7
+ " ↑↑↑↑↑ ↑↑↑ ↑↑↑↑↑↑ ↑↑↑↑↑↑ ",
8
+ " ↑↑↑↑↑↑↑↑ ↑↑↑ ↑↑↑↑↑ ↑↑↑↑↑↑ ",
9
+ " ↑↑↑ ↑↑ ↑↑↑ ↑↑↑↑↑↑↑ ",
10
+ " ↑↑↑ ↑↑↑ ↑↑↑↑↑↑↑↑↑ ",
11
+ " ↑↑↑↑ ↑↑↑ ↑↑↑↑↑↑↑ ↑↑↑↑↑↑↑ ",
12
+ " ↑↑↑↑↑↑↑ ↑↑↑ ↑↑↑↑↑↑↑↑ ↑↑↑↑↑↑ ",
13
+ " ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑↑↑↑↑ ",
14
+ " ↑↑↑↑↑↑↑↑↑↑↑↑ ↑↑ ",
15
+ " ",
16
+ " ",
17
+ ].join("\n");
18
+ export function printLogo() {
19
+ console.log(chalk.bold(FISH));
20
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runSetup(): Promise<void>;
2
+ export declare function ensureConfigured(): void;