@bbclaw/cli 0.1.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 (65) hide show
  1. package/dist/auth/authStore.d.ts +17 -0
  2. package/dist/auth/authStore.d.ts.map +1 -0
  3. package/dist/auth/authStore.js +40 -0
  4. package/dist/auth/authStore.js.map +1 -0
  5. package/dist/auth/client.d.ts +23 -0
  6. package/dist/auth/client.d.ts.map +1 -0
  7. package/dist/auth/client.js +50 -0
  8. package/dist/auth/client.js.map +1 -0
  9. package/dist/index.d.ts +18 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +401 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/repl/App.d.ts +10 -0
  14. package/dist/repl/App.d.ts.map +1 -0
  15. package/dist/repl/App.js +86 -0
  16. package/dist/repl/App.js.map +1 -0
  17. package/dist/repl/Input.d.ts +25 -0
  18. package/dist/repl/Input.d.ts.map +1 -0
  19. package/dist/repl/Input.js +162 -0
  20. package/dist/repl/Input.js.map +1 -0
  21. package/dist/repl/MessageList.d.ts +8 -0
  22. package/dist/repl/MessageList.d.ts.map +1 -0
  23. package/dist/repl/MessageList.js +63 -0
  24. package/dist/repl/MessageList.js.map +1 -0
  25. package/dist/repl/ToolApprovalPrompt.d.ts +10 -0
  26. package/dist/repl/ToolApprovalPrompt.d.ts.map +1 -0
  27. package/dist/repl/ToolApprovalPrompt.js +34 -0
  28. package/dist/repl/ToolApprovalPrompt.js.map +1 -0
  29. package/dist/repl/animations.d.ts +24 -0
  30. package/dist/repl/animations.d.ts.map +1 -0
  31. package/dist/repl/animations.js +79 -0
  32. package/dist/repl/animations.js.map +1 -0
  33. package/dist/repl/runRepl.d.ts +4 -0
  34. package/dist/repl/runRepl.d.ts.map +1 -0
  35. package/dist/repl/runRepl.js +44 -0
  36. package/dist/repl/runRepl.js.map +1 -0
  37. package/dist/repl/sessionStore.d.ts +31 -0
  38. package/dist/repl/sessionStore.d.ts.map +1 -0
  39. package/dist/repl/sessionStore.js +79 -0
  40. package/dist/repl/sessionStore.js.map +1 -0
  41. package/dist/repl/slashCommands.d.ts +61 -0
  42. package/dist/repl/slashCommands.d.ts.map +1 -0
  43. package/dist/repl/slashCommands.js +328 -0
  44. package/dist/repl/slashCommands.js.map +1 -0
  45. package/dist/repl/useChat.d.ts +65 -0
  46. package/dist/repl/useChat.d.ts.map +1 -0
  47. package/dist/repl/useChat.js +517 -0
  48. package/dist/repl/useChat.js.map +1 -0
  49. package/dist/tools/Bash.d.ts +11 -0
  50. package/dist/tools/Bash.d.ts.map +1 -0
  51. package/dist/tools/Bash.js +61 -0
  52. package/dist/tools/Bash.js.map +1 -0
  53. package/dist/tools/Read.d.ts +11 -0
  54. package/dist/tools/Read.d.ts.map +1 -0
  55. package/dist/tools/Read.js +39 -0
  56. package/dist/tools/Read.js.map +1 -0
  57. package/dist/tools/Write.d.ts +12 -0
  58. package/dist/tools/Write.d.ts.map +1 -0
  59. package/dist/tools/Write.js +42 -0
  60. package/dist/tools/Write.js.map +1 -0
  61. package/dist/tools/index.d.ts +15 -0
  62. package/dist/tools/index.d.ts.map +1 -0
  63. package/dist/tools/index.js +35 -0
  64. package/dist/tools/index.js.map +1 -0
  65. package/package.json +35 -0
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useApp, useInput } from 'ink';
3
+ import { useCallback, useMemo } from 'react';
4
+ import { useCountdown, useElapsedSeconds, useSpinner } from './animations.js';
5
+ import { Input } from './Input.js';
6
+ import { MessageList } from './MessageList.js';
7
+ import { dispatchSlash } from './slashCommands.js';
8
+ import { ToolApprovalPrompt } from './ToolApprovalPrompt.js';
9
+ import { useChat } from './useChat.js';
10
+ export const App = ({ registry, initialSession }) => {
11
+ const { exit } = useApp();
12
+ const chat = useChat({ registry, initialSession });
13
+ useInput((_, key) => {
14
+ if (key.ctrl && _ === 'c') {
15
+ if (chat.status !== 'idle')
16
+ chat.cancel();
17
+ else
18
+ exit();
19
+ }
20
+ });
21
+ const handleSubmit = useCallback(async (text) => {
22
+ const trimmed = text.trim();
23
+ if (!trimmed)
24
+ return;
25
+ if (trimmed.startsWith('/')) {
26
+ const ctx = {
27
+ registry,
28
+ currentProviderId: chat.providerId,
29
+ currentModel: chat.model,
30
+ setProvider: chat.setProvider,
31
+ setModel: chat.setModel,
32
+ clearLog: chat.clearLog,
33
+ addNote: chat.addNote,
34
+ retryLast: chat.retryLast,
35
+ loadState: chat.loadState,
36
+ snapshot: chat.snapshot,
37
+ alwaysAllowed: chat.alwaysAllowed,
38
+ startLoop: chat.startLoop,
39
+ stopLoop: chat.stopLoop,
40
+ isLooping: () => chat.loop !== null,
41
+ exit,
42
+ };
43
+ await dispatchSlash(trimmed, ctx);
44
+ return;
45
+ }
46
+ await chat.send(trimmed);
47
+ }, [chat, exit, registry]);
48
+ const header = useMemo(() => {
49
+ const p = chat.currentProvider;
50
+ const model = chat.model ?? p.defaultModel ?? '(no model)';
51
+ return `BBClaw · ${p.displayName} [${p.id}] · ${model}`;
52
+ }, [chat.currentProvider, chat.model]);
53
+ const usageLine = useMemo(() => {
54
+ const { inputTokens, outputTokens } = chat.usage;
55
+ if (inputTokens === 0 && outputTokens === 0)
56
+ return null;
57
+ return `↑ ${inputTokens} ↓ ${outputTokens} · session ${chat.sessionId}`;
58
+ }, [chat.usage, chat.sessionId]);
59
+ const spinner = useSpinner(chat.status !== 'idle');
60
+ const elapsed = useElapsedSeconds(chat.status === 'streaming');
61
+ const toolElapsed = useElapsedSeconds(chat.runningTool !== null);
62
+ const loopElapsed = useElapsedSeconds(chat.loop !== null);
63
+ const loopCountdown = useCountdown(chat.loop?.nextFireAt ?? null);
64
+ const statusLine = useMemo(() => {
65
+ if (chat.status === 'streaming')
66
+ return `${spinner} streaming · ${elapsed.toFixed(1)}s`;
67
+ if (chat.status === 'awaiting-approval')
68
+ return `${spinner} awaiting approval (y/n/a)`;
69
+ return '› ready';
70
+ }, [chat.status, spinner, elapsed]);
71
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { color: "yellow", bold: true, children: header }) }), _jsx(Box, { children: _jsx(Text, { color: "gray", children: "type /help \u00B7 \u2191\u2193 history \u00B7 Ctrl+J newline \u00B7 Ctrl+C cancel \u00B7 /quit to exit" }) }), usageLine && (_jsx(Box, { children: _jsx(Text, { color: "gray", children: usageLine }) })), chat.loop && (_jsx(Box, { children: _jsxs(Text, { color: "magenta", children: ["\uD83D\uDD01 Loop \u00B7 iter ", chat.loop.iteration, " \u00B7 ", formatElapsed(loopElapsed), " elapsed", loopCountdown != null && chat.status === 'idle'
72
+ ? ` · next in ${loopCountdown}s`
73
+ : '', ' · ', _jsx(Text, { color: "gray", children: "/unloop to stop" })] }) })), _jsx(MessageList, { log: chat.log }), chat.status === 'streaming' && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { children: _jsxs(Text, { color: "green", bold: true, children: [spinner, " assistant"] }) }), chat.streamingText.length > 0 ? (_jsx(Text, { children: chat.streamingText })) : (_jsx(Text, { color: "gray", italic: true, children: "thinking\u2026" }))] })), chat.runningTool && (_jsxs(Box, { marginTop: 1, children: [_jsxs(Text, { color: "yellow", children: [spinner, " running ", chat.runningTool.name, "\u2026"] }), _jsxs(Text, { color: "gray", children: [" (", toolElapsed.toFixed(1), "s)"] })] })), chat.status === 'awaiting-approval' && chat.pendingTool && (_jsx(ToolApprovalPrompt, { pending: chat.pendingTool, onRespond: chat.respondToApproval, alreadyAllowed: chat.alwaysAllowed() })), _jsx(Input, { onSubmit: handleSubmit, disabled: chat.status !== 'idle', history: chat.history }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: chat.status === 'idle' ? 'gray' : 'cyan', children: statusLine }) })] }));
74
+ };
75
+ function formatElapsed(seconds) {
76
+ if (seconds < 60)
77
+ return `${seconds.toFixed(0)}s`;
78
+ const m = Math.floor(seconds / 60);
79
+ const s = Math.floor(seconds % 60);
80
+ if (m < 60)
81
+ return s === 0 ? `${m}m` : `${m}m${s}s`;
82
+ const h = Math.floor(m / 60);
83
+ const mm = m % 60;
84
+ return mm === 0 ? `${h}h` : `${h}h${mm}m`;
85
+ }
86
+ //# sourceMappingURL=App.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/repl/App.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type FC } from 'react';
2
+ interface InputProps {
3
+ /** Called when user presses Enter on a non-empty buffer. */
4
+ onSubmit: (text: string) => void;
5
+ /** Hide the input + cursor when true (e.g. while streaming). */
6
+ disabled?: boolean;
7
+ /** Placeholder shown when buffer is empty. */
8
+ placeholder?: string;
9
+ /**
10
+ * Read-only history of past prompts, latest at the end. Up/Down arrows
11
+ * navigate through it. The current draft is stashed when entering history
12
+ * and restored when navigating past the latest entry.
13
+ */
14
+ history: string[];
15
+ }
16
+ /**
17
+ * Custom Ink input. All state is held in refs and the component force-renders
18
+ * after each mutation. This is intentional: ink-testing-library (and a fast
19
+ * typist on a real terminal) can fire multiple useInput events before React
20
+ * commits a render, and any useState/useReducer-based version was reading
21
+ * stale closure values between writes. Refs sidestep the whole problem.
22
+ */
23
+ export declare const Input: FC<InputProps>;
24
+ export {};
25
+ //# sourceMappingURL=Input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/repl/Input.tsx"],"names":[],"mappings":"AACA,OAAO,EAAsB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAA;AAGnD,UAAU,UAAU;IAClB,4DAA4D;IAC5D,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CAiLhC,CAAA"}
@@ -0,0 +1,162 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { useReducer, useRef } from 'react';
4
+ import { useBlink } from './animations.js';
5
+ /**
6
+ * Custom Ink input. All state is held in refs and the component force-renders
7
+ * after each mutation. This is intentional: ink-testing-library (and a fast
8
+ * typist on a real terminal) can fire multiple useInput events before React
9
+ * commits a render, and any useState/useReducer-based version was reading
10
+ * stale closure values between writes. Refs sidestep the whole problem.
11
+ */
12
+ export const Input = ({ onSubmit, disabled, placeholder, history }) => {
13
+ const textRef = useRef('');
14
+ const cursorRef = useRef(0);
15
+ const historyIdxRef = useRef(null);
16
+ const stashedRef = useRef('');
17
+ const historyRef = useRef(history);
18
+ historyRef.current = history;
19
+ const [, force] = useReducer((n) => n + 1, 0);
20
+ const blinkOn = useBlink(!disabled);
21
+ const insert = (ch) => {
22
+ const t = textRef.current;
23
+ const c = cursorRef.current;
24
+ textRef.current = t.slice(0, c) + ch + t.slice(c);
25
+ cursorRef.current = c + ch.length;
26
+ historyIdxRef.current = null;
27
+ force();
28
+ };
29
+ const backspace = () => {
30
+ const c = cursorRef.current;
31
+ if (c === 0)
32
+ return;
33
+ const t = textRef.current;
34
+ textRef.current = t.slice(0, c - 1) + t.slice(c);
35
+ cursorRef.current = c - 1;
36
+ historyIdxRef.current = null;
37
+ force();
38
+ };
39
+ const submit = () => {
40
+ const t = textRef.current;
41
+ const trimmed = t.replace(/\s+$/, '');
42
+ if (trimmed.length === 0)
43
+ return;
44
+ textRef.current = '';
45
+ cursorRef.current = 0;
46
+ historyIdxRef.current = null;
47
+ stashedRef.current = '';
48
+ force();
49
+ onSubmit(t);
50
+ };
51
+ const moveCursor = (delta) => {
52
+ cursorRef.current = Math.max(0, Math.min(textRef.current.length, cursorRef.current + delta));
53
+ force();
54
+ };
55
+ const navigateHistory = (direction) => {
56
+ const list = historyRef.current;
57
+ if (list.length === 0)
58
+ return;
59
+ if (historyIdxRef.current === null) {
60
+ if (direction !== -1)
61
+ return;
62
+ const idx = list.length - 1;
63
+ const entry = list[idx];
64
+ if (entry === undefined)
65
+ return;
66
+ stashedRef.current = textRef.current;
67
+ historyIdxRef.current = idx;
68
+ textRef.current = entry;
69
+ cursorRef.current = entry.length;
70
+ force();
71
+ return;
72
+ }
73
+ const next = historyIdxRef.current + direction;
74
+ if (next < 0)
75
+ return;
76
+ if (next >= list.length) {
77
+ historyIdxRef.current = null;
78
+ textRef.current = stashedRef.current;
79
+ cursorRef.current = stashedRef.current.length;
80
+ force();
81
+ return;
82
+ }
83
+ const entry = list[next];
84
+ if (entry === undefined)
85
+ return;
86
+ historyIdxRef.current = next;
87
+ textRef.current = entry;
88
+ cursorRef.current = entry.length;
89
+ force();
90
+ };
91
+ useInput((input, key) => {
92
+ if (disabled)
93
+ return;
94
+ if (key.return) {
95
+ if (textRef.current.endsWith('\\')) {
96
+ const t = textRef.current;
97
+ textRef.current = `${t.slice(0, -1)}\n`;
98
+ cursorRef.current = textRef.current.length;
99
+ historyIdxRef.current = null;
100
+ force();
101
+ return;
102
+ }
103
+ if (key.ctrl) {
104
+ insert('\n');
105
+ return;
106
+ }
107
+ submit();
108
+ return;
109
+ }
110
+ if (key.ctrl && input === 'j') {
111
+ insert('\n');
112
+ return;
113
+ }
114
+ if (key.upArrow) {
115
+ navigateHistory(-1);
116
+ return;
117
+ }
118
+ if (key.downArrow) {
119
+ navigateHistory(1);
120
+ return;
121
+ }
122
+ if (key.leftArrow) {
123
+ moveCursor(-1);
124
+ return;
125
+ }
126
+ if (key.rightArrow) {
127
+ moveCursor(1);
128
+ return;
129
+ }
130
+ if (key.backspace || key.delete) {
131
+ backspace();
132
+ return;
133
+ }
134
+ if (key.ctrl || key.meta)
135
+ return;
136
+ if (input && input.length > 0)
137
+ insert(input);
138
+ }, { isActive: !disabled });
139
+ if (disabled) {
140
+ return (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "\u2026" }) }));
141
+ }
142
+ const text = textRef.current;
143
+ const cursor = cursorRef.current;
144
+ if (text.length === 0) {
145
+ return (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "magenta", children: "\u203A " }), _jsx(Text, { color: "gray", children: placeholder ?? 'type a message, / for commands, ↑/↓ for history' }), blinkOn ? _jsx(Text, { inverse: true, children: " " }) : _jsx(Text, { children: " " })] }));
146
+ }
147
+ const before = text.slice(0, cursor);
148
+ const at = text.slice(cursor, cursor + 1) || ' ';
149
+ const after = text.slice(cursor + 1);
150
+ const beforeLines = before.split('\n');
151
+ const afterLines = after.split('\n');
152
+ const cursorChar = at === '\n' ? ' ' : at;
153
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [beforeLines.map((line, i) => {
154
+ const isLast = i === beforeLines.length - 1;
155
+ if (!isLast)
156
+ return _jsx(PromptLine, { prefix: i === 0 ? '› ' : ' ', text: line }, `b-${i}`);
157
+ const afterFirst = afterLines[0] ?? '';
158
+ return (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "magenta", children: i === 0 ? '› ' : ' ' }), _jsx(Text, { children: line }), blinkOn ? _jsx(Text, { inverse: true, children: cursorChar }) : _jsx(Text, { children: cursorChar }), _jsx(Text, { children: afterFirst })] }, `cursor-row-${i}`));
159
+ }), afterLines.slice(1).map((line, i) => (_jsx(PromptLine, { prefix: " ", text: line }, `a-${i}`)))] }));
160
+ };
161
+ const PromptLine = ({ prefix, text }) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "magenta", children: prefix }), _jsx(Text, { children: text })] }));
162
+ //# sourceMappingURL=Input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input.js","sourceRoot":"","sources":["../../src/repl/Input.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { FC } from 'react';
2
+ import type { LogEntry } from './slashCommands.js';
3
+ interface MessageListProps {
4
+ log: LogEntry[];
5
+ }
6
+ export declare const MessageList: FC<MessageListProps>;
7
+ export {};
8
+ //# sourceMappingURL=MessageList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../src/repl/MessageList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAA;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAElD,UAAU,gBAAgB;IACxB,GAAG,EAAE,QAAQ,EAAE,CAAA;CAChB;AAED,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAS5C,CAAA"}
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ export const MessageList = ({ log }) => {
4
+ if (log.length === 0)
5
+ return null;
6
+ return (_jsx(Box, { flexDirection: "column", children: log.map((entry, i) => (_jsx(LogRow, { entry: entry }, i))) }));
7
+ };
8
+ /**
9
+ * Compact noisy errors to one informative line plus a short hint. Library
10
+ * errors (Playwright especially) often include a multi-line ASCII box with
11
+ * install instructions — useful once, but every subsequent message looks
12
+ * like garbage in a chat log. We keep the first non-empty sentence and a
13
+ * single follow-up hint, if a recognizable one is present.
14
+ */
15
+ function compactErrorText(text) {
16
+ const lines = text.split('\n');
17
+ // Strip ASCII-box decorations (Playwright's `╔═══...═══╗`, etc).
18
+ const cleaned = lines
19
+ .map((l) => l.replace(/[╔╗║╚╝═╠╣╬│─┌┐└┘├┤┬┴┼]/g, '').trim())
20
+ .filter((l) => l.length > 0);
21
+ if (cleaned.length <= 2)
22
+ return cleaned.join(' ');
23
+ const first = cleaned[0] ?? '';
24
+ // Look for a `<3 something Team` signature or install hint to attach.
25
+ const hint = cleaned.find((l) => /install|run.*command|please run|<3/i.test(l));
26
+ if (hint && hint !== first)
27
+ return `${first} — hint: ${hint}`;
28
+ return first;
29
+ }
30
+ const LogRow = ({ entry }) => {
31
+ switch (entry.kind) {
32
+ case 'user':
33
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "you" }), _jsx(Text, { children: entry.text })] }));
34
+ case 'assistant':
35
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "green", bold: true, children: "assistant" }), _jsx(Text, { children: entry.text })] }));
36
+ case 'tool-use': {
37
+ let preview;
38
+ try {
39
+ preview = JSON.stringify(entry.input);
40
+ }
41
+ catch {
42
+ preview = String(entry.input);
43
+ }
44
+ if (preview.length > 120)
45
+ preview = `${preview.slice(0, 120)}…`;
46
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { color: "yellow", bold: true, children: ["\uD83D\uDD27 ", entry.name] }), _jsxs(Text, { color: "gray", children: ["input: ", preview] })] }));
47
+ }
48
+ case 'tool-result': {
49
+ const max = 400;
50
+ const out = entry.output.length <= max
51
+ ? entry.output
52
+ : `${entry.output.slice(0, max)}\n…(${entry.output.length - max} more chars)`;
53
+ const label = entry.isError ? '↳ error' : '↳ result';
54
+ const color = entry.isError ? 'red' : 'cyan';
55
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { color: color, bold: true, children: [label, " \u00B7 ", entry.toolName] }), _jsx(Text, { color: entry.isError ? 'red' : undefined, children: out })] }));
56
+ }
57
+ case 'note':
58
+ return (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: entry.text }) }));
59
+ case 'error':
60
+ return (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ["error: ", compactErrorText(entry.text)] }) }));
61
+ }
62
+ };
63
+ //# sourceMappingURL=MessageList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../src/repl/MessageList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { type FC } from 'react';
2
+ import type { ApprovalDecision, PendingTool } from './useChat.js';
3
+ interface ToolApprovalPromptProps {
4
+ pending: PendingTool;
5
+ onRespond: (decision: ApprovalDecision) => void;
6
+ alreadyAllowed: string[];
7
+ }
8
+ export declare const ToolApprovalPrompt: FC<ToolApprovalPromptProps>;
9
+ export {};
10
+ //# sourceMappingURL=ToolApprovalPrompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolApprovalPrompt.d.ts","sourceRoot":"","sources":["../../src/repl/ToolApprovalPrompt.tsx"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,EAAE,EAAE,MAAM,OAAO,CAAA;AAExC,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAEjE,UAAU,uBAAuB;IAC/B,OAAO,EAAE,WAAW,CAAA;IACpB,SAAS,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC/C,cAAc,EAAE,MAAM,EAAE,CAAA;CACzB;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CA2D1D,CAAA"}
@@ -0,0 +1,34 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { Box, Text, useInput } from 'ink';
3
+ import { useMemo } from 'react';
4
+ import { useBlink } from './animations.js';
5
+ export const ToolApprovalPrompt = ({ pending, onRespond, alreadyAllowed, }) => {
6
+ const inputJson = useMemo(() => {
7
+ try {
8
+ const pretty = JSON.stringify(pending.input, null, 2);
9
+ if (pretty.length <= 400)
10
+ return pretty;
11
+ return `${pretty.slice(0, 400)}\n…(${pretty.length - 400} more chars)`;
12
+ }
13
+ catch {
14
+ return String(pending.input);
15
+ }
16
+ }, [pending.input]);
17
+ useInput((input) => {
18
+ const key = input.toLowerCase();
19
+ if (key === 'y')
20
+ onRespond('approve');
21
+ else if (key === 'n')
22
+ onRespond('deny');
23
+ else if (key === 'a')
24
+ onRespond('allow-all');
25
+ });
26
+ // Breathing border: alternate between two yellows on ~700ms to draw the
27
+ // eye without strobing. Slower than spinners so it doesn't feel anxious.
28
+ const bright = useBlink(true, 700);
29
+ const allowHint = alreadyAllowed.length > 0
30
+ ? ` (auto-approved this session: ${alreadyAllowed.join(', ')})`
31
+ : '';
32
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: bright ? 'yellowBright' : 'yellow', paddingX: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { color: "yellow", bold: true, children: ["\uD83D\uDD27 ", pending.name] }), _jsx(Text, { color: "gray", children: " \u00B7 approval required" })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: inputJson }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "[y]" }), _jsx(Text, { children: " approve " }), _jsx(Text, { color: "red", children: "[n]" }), _jsx(Text, { children: " deny " }), _jsx(Text, { color: "green", children: "[a]" }), _jsxs(Text, { children: [" always allow ", pending.name, " this session"] }), _jsx(Text, { color: "gray", children: allowHint })] })] }));
33
+ };
34
+ //# sourceMappingURL=ToolApprovalPrompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolApprovalPrompt.js","sourceRoot":"","sources":["../../src/repl/ToolApprovalPrompt.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,EAAE,OAAO,EAAW,MAAM,OAAO,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAS1C,MAAM,CAAC,MAAM,kBAAkB,GAAgC,CAAC,EAC9D,OAAO,EACP,SAAS,EACT,cAAc,GACf,EAAE,EAAE;IACH,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;YACrD,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG;gBAAE,OAAO,MAAM,CAAA;YACvC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG,cAAc,CAAA;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAEnB,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAA;QAC/B,IAAI,GAAG,KAAK,GAAG;YAAE,SAAS,CAAC,SAAS,CAAC,CAAA;aAChC,IAAI,GAAG,KAAK,GAAG;YAAE,SAAS,CAAC,MAAM,CAAC,CAAA;aAClC,IAAI,GAAG,KAAK,GAAG;YAAE,SAAS,CAAC,WAAW,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;IAEF,wEAAwE;IACxE,yEAAyE;IACzE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAElC,MAAM,SAAS,GACb,cAAc,CAAC,MAAM,GAAG,CAAC;QACvB,CAAC,CAAC,kCAAkC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAChE,CAAC,CAAC,EAAE,CAAA;IAER,OAAO,CACL,MAAC,GAAG,IACF,aAAa,EAAC,QAAQ,EACtB,SAAS,EAAE,CAAC,EACZ,WAAW,EAAC,OAAO,EACnB,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,EAC/C,QAAQ,EAAE,CAAC,aAEX,MAAC,GAAG,eACF,MAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,IAAI,oCACnB,OAAO,CAAC,IAAI,IACX,EACP,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,2CAA6B,IAC3C,EACN,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,IAAI,cAAE,SAAS,GAAQ,GACpB,EACN,MAAC,GAAG,IAAC,SAAS,EAAE,CAAC,aACf,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,oBAAW,EAC7B,KAAC,IAAI,8BAAmB,EACxB,KAAC,IAAI,IAAC,KAAK,EAAC,KAAK,oBAAW,EAC5B,KAAC,IAAI,2BAAgB,EACrB,KAAC,IAAI,IAAC,KAAK,EAAC,OAAO,oBAAW,EAC9B,MAAC,IAAI,iCAAgB,OAAO,CAAC,IAAI,qBAAqB,EACtD,KAAC,IAAI,IAAC,KAAK,EAAC,MAAM,YAAE,SAAS,GAAQ,IACjC,IACF,CACP,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Returns a rotating character that advances every `intervalMs` while active.
3
+ * When inactive the timer is cleared, but the last frame stays so the caller
4
+ * can conditionally render it without flicker. Default 80ms — slow enough to
5
+ * read, fast enough to feel alive.
6
+ */
7
+ export declare function useSpinner(active: boolean, intervalMs?: number): string;
8
+ /**
9
+ * Returns seconds elapsed since `active` became true, updating once per
10
+ * `tickMs`. Resets to 0 when `active` flips back to false. Use to show
11
+ * "streaming · 3.2s" style live counters without leaking timers.
12
+ */
13
+ export declare function useElapsedSeconds(active: boolean, tickMs?: number): number;
14
+ /**
15
+ * Toggles between true/false on an interval. Used for cursor blink.
16
+ */
17
+ export declare function useBlink(active: boolean, intervalMs?: number): boolean;
18
+ /**
19
+ * Returns the seconds-remaining until `targetMs` (a Date.now()-aligned ms
20
+ * timestamp). Returns null when target is null or in the past. Updates every
21
+ * second so countdown displays don't tick faster than they need to.
22
+ */
23
+ export declare function useCountdown(targetMs: number | null): number | null;
24
+ //# sourceMappingURL=animations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animations.d.ts","sourceRoot":"","sources":["../../src/repl/animations.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,SAAK,GAAG,MAAM,CAUnE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,SAAM,GAAG,MAAM,CAcvE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,SAAM,GAAG,OAAO,CAWnE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAgBnE"}
@@ -0,0 +1,79 @@
1
+ import { useEffect, useState } from 'react';
2
+ /** Braille dot frames — classic terminal spinner pattern. */
3
+ const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
4
+ /**
5
+ * Returns a rotating character that advances every `intervalMs` while active.
6
+ * When inactive the timer is cleared, but the last frame stays so the caller
7
+ * can conditionally render it without flicker. Default 80ms — slow enough to
8
+ * read, fast enough to feel alive.
9
+ */
10
+ export function useSpinner(active, intervalMs = 80) {
11
+ const [frame, setFrame] = useState(0);
12
+ useEffect(() => {
13
+ if (!active)
14
+ return;
15
+ const t = setInterval(() => {
16
+ setFrame((f) => (f + 1) % SPINNER_FRAMES.length);
17
+ }, intervalMs);
18
+ return () => clearInterval(t);
19
+ }, [active, intervalMs]);
20
+ return SPINNER_FRAMES[frame] ?? SPINNER_FRAMES[0];
21
+ }
22
+ /**
23
+ * Returns seconds elapsed since `active` became true, updating once per
24
+ * `tickMs`. Resets to 0 when `active` flips back to false. Use to show
25
+ * "streaming · 3.2s" style live counters without leaking timers.
26
+ */
27
+ export function useElapsedSeconds(active, tickMs = 100) {
28
+ const [seconds, setSeconds] = useState(0);
29
+ useEffect(() => {
30
+ if (!active) {
31
+ setSeconds(0);
32
+ return;
33
+ }
34
+ const start = Date.now();
35
+ const t = setInterval(() => {
36
+ setSeconds((Date.now() - start) / 1000);
37
+ }, tickMs);
38
+ return () => clearInterval(t);
39
+ }, [active, tickMs]);
40
+ return seconds;
41
+ }
42
+ /**
43
+ * Toggles between true/false on an interval. Used for cursor blink.
44
+ */
45
+ export function useBlink(active, intervalMs = 500) {
46
+ const [on, setOn] = useState(true);
47
+ useEffect(() => {
48
+ if (!active) {
49
+ setOn(true);
50
+ return;
51
+ }
52
+ const t = setInterval(() => setOn((v) => !v), intervalMs);
53
+ return () => clearInterval(t);
54
+ }, [active, intervalMs]);
55
+ return on;
56
+ }
57
+ /**
58
+ * Returns the seconds-remaining until `targetMs` (a Date.now()-aligned ms
59
+ * timestamp). Returns null when target is null or in the past. Updates every
60
+ * second so countdown displays don't tick faster than they need to.
61
+ */
62
+ export function useCountdown(targetMs) {
63
+ const [remaining, setRemaining] = useState(null);
64
+ useEffect(() => {
65
+ if (targetMs == null) {
66
+ setRemaining(null);
67
+ return;
68
+ }
69
+ const update = () => {
70
+ const left = Math.max(0, Math.ceil((targetMs - Date.now()) / 1000));
71
+ setRemaining(left);
72
+ };
73
+ update();
74
+ const t = setInterval(update, 1000);
75
+ return () => clearInterval(t);
76
+ }, [targetMs]);
77
+ return remaining;
78
+ }
79
+ //# sourceMappingURL=animations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animations.js","sourceRoot":"","sources":["../../src/repl/animations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ProviderRegistry } from '@bbclaw/core';
2
+ import type { SessionData } from './sessionStore.js';
3
+ export declare function runRepl(registry: ProviderRegistry, initialSession?: SessionData): Promise<void>;
4
+ //# sourceMappingURL=runRepl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runRepl.d.ts","sourceRoot":"","sources":["../../src/repl/runRepl.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,wBAAsB,OAAO,CAC3B,QAAQ,EAAE,gBAAgB,EAC1B,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,IAAI,CAAC,CAsCf"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from 'ink';
3
+ import { App } from './App.js';
4
+ export async function runRepl(registry, initialSession) {
5
+ const instance = render(_jsx(App, { registry: registry, initialSession: initialSession }), {
6
+ exitOnCtrlC: false,
7
+ });
8
+ // External signals (SIGTERM from `kill`, SIGHUP from closing the terminal)
9
+ // must still clean up browser contexts and other long-lived resources. Ink's
10
+ // exitOnCtrlC=false means SIGINT delivered through the controlling TTY is
11
+ // captured by the raw-mode reader and surfaces as a Ctrl+C input event we
12
+ // already handle in App. The process-level handlers below cover the cases
13
+ // where the kernel delivers a signal directly (kill -TERM, parent shell
14
+ // hangup, IDE process termination, etc.).
15
+ let shuttingDown = false;
16
+ const shutdown = async (sig) => {
17
+ if (shuttingDown)
18
+ return;
19
+ shuttingDown = true;
20
+ try {
21
+ instance.unmount();
22
+ }
23
+ catch {
24
+ // Ink may already be unmounted.
25
+ }
26
+ await registry.closeAll().catch(() => { });
27
+ process.exit(sig === 'SIGINT' ? 130 : 143);
28
+ };
29
+ process.once('SIGTERM', shutdown);
30
+ process.once('SIGHUP', shutdown);
31
+ // SIGINT is normally consumed by ink's raw-mode input loop, but if the user
32
+ // is starting up before raw mode is established, fall back to clean exit.
33
+ process.once('SIGINT', shutdown);
34
+ try {
35
+ await instance.waitUntilExit();
36
+ }
37
+ finally {
38
+ process.removeListener('SIGTERM', shutdown);
39
+ process.removeListener('SIGHUP', shutdown);
40
+ process.removeListener('SIGINT', shutdown);
41
+ await registry.closeAll();
42
+ }
43
+ }
44
+ //# sourceMappingURL=runRepl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runRepl.js","sourceRoot":"","sources":["../../src/repl/runRepl.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAA;AAG9B,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,QAA0B,EAC1B,cAA4B;IAE5B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAC,GAAG,IAAC,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,cAAc,GAAI,EAAE;QACnF,WAAW,EAAE,KAAK;KACnB,CAAC,CAAA;IAEF,2EAA2E;IAC3E,6EAA6E;IAC7E,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,wEAAwE;IACxE,0CAA0C;IAC1C,IAAI,YAAY,GAAG,KAAK,CAAA;IACxB,MAAM,QAAQ,GAAG,KAAK,EAAE,GAAmB,EAAiB,EAAE;QAC5D,IAAI,YAAY;YAAE,OAAM;QACxB,YAAY,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC;YACH,QAAQ,CAAC,OAAO,EAAE,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;QACD,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC5C,CAAC,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IACjC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAChC,4EAA4E;IAC5E,0EAA0E;IAC1E,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAEhC,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAA;IAChC,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,cAAc,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;QAC3C,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAC1C,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;QAC1C,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAA;IAC3B,CAAC;AACH,CAAC"}