@marifold/tui 0.60.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 (104) hide show
  1. package/LICENSE +674 -0
  2. package/dist/core/appState.d.ts +158 -0
  3. package/dist/core/appState.d.ts.map +1 -0
  4. package/dist/core/appState.js +167 -0
  5. package/dist/core/appState.js.map +1 -0
  6. package/dist/core/commands.d.ts +70 -0
  7. package/dist/core/commands.d.ts.map +1 -0
  8. package/dist/core/commands.js +227 -0
  9. package/dist/core/commands.js.map +1 -0
  10. package/dist/core/displayPaths.d.ts +5 -0
  11. package/dist/core/displayPaths.d.ts.map +1 -0
  12. package/dist/core/displayPaths.js +14 -0
  13. package/dist/core/displayPaths.js.map +1 -0
  14. package/dist/core/eventView.d.ts +10 -0
  15. package/dist/core/eventView.d.ts.map +1 -0
  16. package/dist/core/eventView.js +77 -0
  17. package/dist/core/eventView.js.map +1 -0
  18. package/dist/core/inputGrammar.d.ts +29 -0
  19. package/dist/core/inputGrammar.d.ts.map +1 -0
  20. package/dist/core/inputGrammar.js +30 -0
  21. package/dist/core/inputGrammar.js.map +1 -0
  22. package/dist/core/skills.d.ts +2 -0
  23. package/dist/core/skills.d.ts.map +1 -0
  24. package/dist/core/skills.js +2 -0
  25. package/dist/core/skills.js.map +1 -0
  26. package/dist/core/transcriptWindow.d.ts.map +1 -0
  27. package/dist/core/transcriptWindow.js.map +1 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +2 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/runTui.d.ts +18 -0
  33. package/dist/runTui.d.ts.map +1 -0
  34. package/dist/runTui.js +146 -0
  35. package/dist/runTui.js.map +1 -0
  36. package/dist/ui/App.d.ts +23 -0
  37. package/dist/ui/App.d.ts.map +1 -0
  38. package/dist/ui/App.js +991 -0
  39. package/dist/ui/App.js.map +1 -0
  40. package/dist/ui/ApprovalModal.d.ts +12 -0
  41. package/dist/ui/ApprovalModal.d.ts.map +1 -0
  42. package/dist/ui/ApprovalModal.js +62 -0
  43. package/dist/ui/ApprovalModal.js.map +1 -0
  44. package/dist/ui/Header.d.ts +12 -0
  45. package/dist/ui/Header.d.ts.map +1 -0
  46. package/dist/ui/Header.js +15 -0
  47. package/dist/ui/Header.js.map +1 -0
  48. package/dist/ui/InfoPanel.d.ts +11 -0
  49. package/dist/ui/InfoPanel.d.ts.map +1 -0
  50. package/dist/ui/InfoPanel.js +16 -0
  51. package/dist/ui/InfoPanel.js.map +1 -0
  52. package/dist/ui/InputBox.d.ts +31 -0
  53. package/dist/ui/InputBox.d.ts.map +1 -0
  54. package/dist/ui/InputBox.js +410 -0
  55. package/dist/ui/InputBox.js.map +1 -0
  56. package/dist/ui/Markdown.d.ts +12 -0
  57. package/dist/ui/Markdown.d.ts.map +1 -0
  58. package/dist/ui/Markdown.js +111 -0
  59. package/dist/ui/Markdown.js.map +1 -0
  60. package/dist/ui/QuestionModal.d.ts +11 -0
  61. package/dist/ui/QuestionModal.d.ts.map +1 -0
  62. package/dist/ui/QuestionModal.js +211 -0
  63. package/dist/ui/QuestionModal.js.map +1 -0
  64. package/dist/ui/RunStatus.d.ts +17 -0
  65. package/dist/ui/RunStatus.d.ts.map +1 -0
  66. package/dist/ui/RunStatus.js +46 -0
  67. package/dist/ui/RunStatus.js.map +1 -0
  68. package/dist/ui/SelectList.d.ts +18 -0
  69. package/dist/ui/SelectList.d.ts.map +1 -0
  70. package/dist/ui/SelectList.js +54 -0
  71. package/dist/ui/SelectList.js.map +1 -0
  72. package/dist/ui/Spinner.d.ts +6 -0
  73. package/dist/ui/Spinner.d.ts.map +1 -0
  74. package/dist/ui/Spinner.js +14 -0
  75. package/dist/ui/Spinner.js.map +1 -0
  76. package/dist/ui/StatusLine.d.ts +6 -0
  77. package/dist/ui/StatusLine.d.ts.map +1 -0
  78. package/dist/ui/StatusLine.js +32 -0
  79. package/dist/ui/StatusLine.js.map +1 -0
  80. package/dist/ui/Transcript.d.ts +17 -0
  81. package/dist/ui/Transcript.d.ts.map +1 -0
  82. package/dist/ui/Transcript.js +58 -0
  83. package/dist/ui/Transcript.js.map +1 -0
  84. package/dist/ui/appHelpers.d.ts +16 -0
  85. package/dist/ui/appHelpers.d.ts.map +1 -0
  86. package/dist/ui/appHelpers.js +59 -0
  87. package/dist/ui/appHelpers.js.map +1 -0
  88. package/dist/ui/text.d.ts +7 -0
  89. package/dist/ui/text.d.ts.map +1 -0
  90. package/dist/ui/text.js +16 -0
  91. package/dist/ui/text.js.map +1 -0
  92. package/dist/ui/theme.d.ts +12 -0
  93. package/dist/ui/theme.d.ts.map +1 -0
  94. package/dist/ui/theme.js +12 -0
  95. package/dist/ui/theme.js.map +1 -0
  96. package/dist/ui/useResizing.d.ts +14 -0
  97. package/dist/ui/useResizing.d.ts.map +1 -0
  98. package/dist/ui/useResizing.js +37 -0
  99. package/dist/ui/useResizing.js.map +1 -0
  100. package/dist/ui/useTerminalSize.d.ts +8 -0
  101. package/dist/ui/useTerminalSize.d.ts.map +1 -0
  102. package/dist/ui/useTerminalSize.js +23 -0
  103. package/dist/ui/useTerminalSize.js.map +1 -0
  104. package/package.json +32 -0
@@ -0,0 +1,211 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useMemo, useState } from 'react';
3
+ import { Box, Text, useInput } from 'ink';
4
+ import { ACCENT, ATTACHMENT, DIM } from './theme.js';
5
+ /** Keyboard-first counterpart to the Web question sheet. Questions are
6
+ * batched and the run resumes only after one complete submission. */
7
+ export function QuestionModal({ request, onSubmit, onCancel }) {
8
+ const [questionIndex, setQuestionIndex] = useState(0);
9
+ const [cursor, setCursor] = useState(0);
10
+ const [drafts, setDrafts] = useState({});
11
+ const [editingCustom, setEditingCustom] = useState(false);
12
+ useEffect(() => {
13
+ setQuestionIndex(0);
14
+ setCursor(0);
15
+ setDrafts({});
16
+ setEditingCustom(false);
17
+ }, [request.id]);
18
+ const complete = useMemo(() => request.questions.every(question => isComplete(question, drafts[question.id])), [drafts, request.questions]);
19
+ function moveTo(index) {
20
+ const next = Math.max(0, Math.min(request.questions.length - 1, index));
21
+ setQuestionIndex(next);
22
+ setEditingCustom(false);
23
+ const question = request.questions[next];
24
+ const answer = drafts[question.id];
25
+ if (answer?.kind === 'option') {
26
+ setCursor(Math.max(0, question.options.findIndex(option => option.id === answer.optionId)));
27
+ }
28
+ else if (answer?.kind === 'custom') {
29
+ setCursor(question.options.length);
30
+ }
31
+ else if (answer?.kind === 'multiple') {
32
+ const selected = question.options.findIndex(option => answer.optionIds.includes(option.id));
33
+ setCursor(selected >= 0 ? selected : answer.customText !== undefined ? question.options.length : 0);
34
+ }
35
+ else {
36
+ setCursor(0);
37
+ }
38
+ }
39
+ function advance() {
40
+ const nextUnanswered = request.questions.findIndex((question, index) => index > questionIndex && !isComplete(question, drafts[question.id]));
41
+ if (nextUnanswered !== -1)
42
+ moveTo(nextUnanswered);
43
+ }
44
+ function submit() {
45
+ if (!complete)
46
+ return;
47
+ onSubmit({
48
+ answers: request.questions.map((question) => {
49
+ const answer = drafts[question.id];
50
+ if (question.multiple) {
51
+ if (answer.kind !== 'multiple')
52
+ throw new Error('Incomplete multi-select answer.');
53
+ return {
54
+ questionId: question.id,
55
+ optionIds: answer.optionIds,
56
+ ...(answer.customText !== undefined ? { customText: answer.customText.trim() } : {}),
57
+ };
58
+ }
59
+ if (answer.kind === 'option')
60
+ return { questionId: question.id, optionId: answer.optionId };
61
+ if (answer.kind === 'custom') {
62
+ return { questionId: question.id, customText: answer.text.trim() };
63
+ }
64
+ throw new Error('Incomplete single-select answer.');
65
+ }),
66
+ });
67
+ }
68
+ useInput((input, key) => {
69
+ const question = request.questions[questionIndex];
70
+ const customIndex = question.options.length;
71
+ if (editingCustom) {
72
+ const current = drafts[question.id];
73
+ const text = current?.kind === 'custom'
74
+ ? current.text
75
+ : current?.kind === 'multiple'
76
+ ? current.customText ?? ''
77
+ : '';
78
+ const updateText = (next) => setDrafts(value => {
79
+ if (question.multiple) {
80
+ return {
81
+ ...value,
82
+ [question.id]: { ...asMultiple(value[question.id]), customText: next },
83
+ };
84
+ }
85
+ return { ...value, [question.id]: { kind: 'custom', text: next } };
86
+ });
87
+ if (key.escape) {
88
+ setEditingCustom(false);
89
+ }
90
+ else if (key.return) {
91
+ if (text.trim()) {
92
+ setEditingCustom(false);
93
+ advance();
94
+ }
95
+ }
96
+ else if (key.backspace || key.delete) {
97
+ updateText(text.slice(0, -1));
98
+ }
99
+ else if (input && !key.ctrl && !key.meta && text.length < 2000) {
100
+ updateText(text + input);
101
+ }
102
+ return;
103
+ }
104
+ if (key.escape)
105
+ onCancel();
106
+ else if (key.upArrow)
107
+ setCursor(value => (value - 1 + customIndex + 1) % (customIndex + 1));
108
+ else if (key.downArrow)
109
+ setCursor(value => (value + 1) % (customIndex + 1));
110
+ else if (key.leftArrow)
111
+ moveTo(questionIndex - 1);
112
+ else if (key.rightArrow || key.tab)
113
+ moveTo(questionIndex + 1);
114
+ else if (question.multiple && input === ' ') {
115
+ if (cursor === customIndex) {
116
+ setDrafts(value => {
117
+ const previous = asMultiple(value[question.id]);
118
+ return {
119
+ ...value,
120
+ [question.id]: previous.customText === undefined
121
+ ? { ...previous, customText: '' }
122
+ : { kind: 'multiple', optionIds: previous.optionIds },
123
+ };
124
+ });
125
+ }
126
+ else {
127
+ setDrafts(value => ({
128
+ ...value,
129
+ [question.id]: toggleMultipleOption(value[question.id], question.options[cursor].id),
130
+ }));
131
+ }
132
+ }
133
+ else if (key.return) {
134
+ if (cursor === customIndex) {
135
+ setDrafts(value => {
136
+ const current = value[question.id];
137
+ return {
138
+ ...value,
139
+ [question.id]: question.multiple
140
+ ? {
141
+ ...asMultiple(current),
142
+ customText: current?.kind === 'multiple' ? current.customText ?? '' : '',
143
+ }
144
+ : current?.kind === 'custom' ? current : { kind: 'custom', text: '' },
145
+ };
146
+ });
147
+ setEditingCustom(true);
148
+ }
149
+ else if (question.multiple) {
150
+ setDrafts(value => ({
151
+ ...value,
152
+ [question.id]: toggleMultipleOption(value[question.id], question.options[cursor].id),
153
+ }));
154
+ }
155
+ else {
156
+ setDrafts(value => ({
157
+ ...value,
158
+ [question.id]: { kind: 'option', optionId: question.options[cursor].id },
159
+ }));
160
+ advance();
161
+ }
162
+ }
163
+ else if (input.toLowerCase() === 's')
164
+ submit();
165
+ });
166
+ return (_jsxs(Box, { borderStyle: "round", borderColor: ACCENT, flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: ACCENT, children: "A few details before I continue" }), request.questions.map((question, index) => {
167
+ const active = index === questionIndex;
168
+ const answer = drafts[question.id];
169
+ const customEditing = active && editingCustom;
170
+ const customSelected = question.multiple
171
+ ? answer?.kind === 'multiple' && answer.customText !== undefined
172
+ : answer?.kind === 'custom';
173
+ const customText = answer?.kind === 'multiple'
174
+ ? answer.customText
175
+ : answer?.kind === 'custom'
176
+ ? answer.text
177
+ : undefined;
178
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { bold: active, color: active ? ATTACHMENT : undefined, children: [active ? '› ' : ' ', question.header ? `${question.header}: ` : '', question.question, question.multiple ? _jsx(Text, { dimColor: true, children: " (select all that apply)" }) : null] }), question.options.map((option, optionIndex) => {
179
+ const selected = question.multiple
180
+ ? answer?.kind === 'multiple' && answer.optionIds.includes(option.id)
181
+ : answer?.kind === 'option' && answer.optionId === option.id;
182
+ const focused = active && !editingCustom && cursor === optionIndex;
183
+ return (_jsxs(Text, { color: focused ? ACCENT : DIM, children: [focused ? ' › ' : ' ', question.multiple ? `[${selected ? 'x' : ' '}]` : selected ? '●' : '○', " ", option.label, option.description ? _jsxs(Text, { dimColor: true, children: [" \u2014 ", option.description] }) : null] }, option.id));
184
+ }), _jsxs(Text, { color: active && cursor === question.options.length ? ACCENT : DIM, children: [active && cursor === question.options.length ? ' › ' : ' ', question.multiple ? `[${customSelected ? 'x' : ' '}]` : customSelected ? '●' : '○', " Something else", customText ? ` — ${customText}${customEditing ? '▌' : ''}` : customEditing ? ' — ▌' : ''] })] }, question.id));
185
+ }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: DIM, children: request.questions[questionIndex].multiple
186
+ ? '↑↓ move · Space/Enter toggle · ←→ question · '
187
+ : '↑↓ choose · ←→ question · Enter select · ' }), _jsx(Text, { bold: true, color: complete ? ACCENT : DIM, children: "[s]ubmit" }), _jsx(Text, { color: DIM, children: " \u00B7 Esc cancel" })] }), _jsx(Text, { color: complete ? ATTACHMENT : DIM, children: complete ? 'All answers ready.' : 'Answer every question before submitting.' })] }));
188
+ }
189
+ function asMultiple(answer) {
190
+ return answer?.kind === 'multiple' ? answer : { kind: 'multiple', optionIds: [] };
191
+ }
192
+ function toggleMultipleOption(answer, optionId) {
193
+ const previous = asMultiple(answer);
194
+ return {
195
+ ...previous,
196
+ optionIds: previous.optionIds.includes(optionId)
197
+ ? previous.optionIds.filter(id => id !== optionId)
198
+ : [...previous.optionIds, optionId],
199
+ };
200
+ }
201
+ function isComplete(question, answer) {
202
+ if (question.multiple) {
203
+ if (answer?.kind !== 'multiple')
204
+ return false;
205
+ if (answer.customText !== undefined && !answer.customText.trim())
206
+ return false;
207
+ return answer.optionIds.length > 0 || answer.customText !== undefined;
208
+ }
209
+ return answer?.kind === 'option' || (answer?.kind === 'custom' && answer.text.trim().length > 0);
210
+ }
211
+ //# sourceMappingURL=QuestionModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionModal.js","sourceRoot":"","sources":["../../src/ui/QuestionModal.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ /**
3
+ * Transient run line shown above the input while a task is active: a verb,
4
+ * elapsed time, the think/effort hint, any queued steering, and the cancel
5
+ * hint. The `startedAt` anchor is owned by App so the elapsed clock keeps
6
+ * counting even when this component unmounts/remounts during a resize burst.
7
+ *
8
+ * Token counts are intentionally omitted — they are not part of the
9
+ * renderer-agnostic AgentEvent contract today.
10
+ */
11
+ export declare function RunStatus({ startedAt, activity, think, steeringQueued, }: {
12
+ startedAt: number;
13
+ activity?: string;
14
+ think: boolean;
15
+ steeringQueued: number;
16
+ }): React.ReactElement;
17
+ //# sourceMappingURL=RunStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunStatus.d.ts","sourceRoot":"","sources":["../../src/ui/RunStatus.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAYnD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,cAAc,GACf,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;CACxB,GAAG,KAAK,CAAC,YAAY,CAuBrB"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Box, Text } from 'ink';
4
+ import { ACCENT, DIM } from './theme.js';
5
+ /** Whimsical placeholders for the generic thinking phase, in the spirit of
6
+ * Claude Code's activity words. A specific tool name takes precedence. */
7
+ const VERBS = [
8
+ 'Pondering', 'Drizzling', 'Percolating', 'Noodling', 'Simmering',
9
+ 'Conjuring', 'Tinkering', 'Brewing', 'Mulling', 'Whirring',
10
+ 'Marinating', 'Ruminating',
11
+ ];
12
+ /**
13
+ * Transient run line shown above the input while a task is active: a verb,
14
+ * elapsed time, the think/effort hint, any queued steering, and the cancel
15
+ * hint. The `startedAt` anchor is owned by App so the elapsed clock keeps
16
+ * counting even when this component unmounts/remounts during a resize burst.
17
+ *
18
+ * Token counts are intentionally omitted — they are not part of the
19
+ * renderer-agnostic AgentEvent contract today.
20
+ */
21
+ export function RunStatus({ startedAt, activity, think, steeringQueued, }) {
22
+ const start = startedAt;
23
+ const [, tick] = useState(0);
24
+ useEffect(() => {
25
+ const timer = setInterval(() => tick(n => n + 1), 1000);
26
+ return () => clearInterval(timer);
27
+ }, []);
28
+ const verb = labelFor(activity, start);
29
+ const detail = [formatElapsed(Date.now() - start), think ? 'thinking' : null]
30
+ .filter(Boolean)
31
+ .join(' · ');
32
+ return (_jsx(Box, { paddingX: 1, children: _jsxs(Text, { children: [_jsxs(Text, { color: ACCENT, children: ["\u00B7 ", verb, "\u2026"] }), _jsxs(Text, { color: DIM, children: [" (", detail, ")"] }), steeringQueued > 0 ? _jsxs(Text, { color: DIM, children: [" \u00B7 ", steeringQueued, " steering queued"] }) : null, _jsx(Text, { color: DIM, children: " \u00B7 esc to cancel" })] }) }));
33
+ }
34
+ function labelFor(activity, seed) {
35
+ if (activity && activity !== 'thinking' && activity !== 'working') {
36
+ return activity.charAt(0).toUpperCase() + activity.slice(1);
37
+ }
38
+ return VERBS[Math.floor(seed / 1000) % VERBS.length];
39
+ }
40
+ function formatElapsed(ms) {
41
+ const total = Math.floor(ms / 1000);
42
+ const minutes = Math.floor(total / 60);
43
+ const seconds = total % 60;
44
+ return minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
45
+ }
46
+ //# sourceMappingURL=RunStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunStatus.js","sourceRoot":"","sources":["../../src/ui/RunStatus.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEzC;0EAC0E;AAC1E,MAAM,KAAK,GAAG;IACZ,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW;IAChE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU;IAC1D,YAAY,EAAE,YAAY;CAC3B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,KAAK,EACL,cAAc,GAMf;IACC,MAAM,KAAK,GAAG,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;SAC1E,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,KAAK,CAAC,CAAC;IAEf,OAAO,CACL,KAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,YACd,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,wBAAK,IAAI,cAAS,EACrC,MAAC,IAAI,IAAC,KAAK,EAAE,GAAG,mBAAK,MAAM,SAAS,EACnC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,MAAC,IAAI,IAAC,KAAK,EAAE,GAAG,yBAAM,cAAc,wBAAwB,CAAC,CAAC,CAAC,IAAI,EACzF,KAAC,IAAI,IAAC,KAAK,EAAE,GAAG,sCAAyB,IACpC,GACH,CACP,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,QAA4B,EAAE,IAAY;IAC1D,IAAI,QAAQ,IAAI,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAClE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,aAAa,CAAC,EAAU;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,KAAK,GAAG,EAAE,CAAC;IAC3B,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC;AACjE,CAAC"}
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ export interface SelectItem {
3
+ label: string;
4
+ value: string;
5
+ hint?: string;
6
+ }
7
+ /** Arrow-key list: Enter selects, Esc cancels, Del removes (when onDelete set). */
8
+ export declare function SelectList({ title, items, onSelect, onCancel, onDelete, maxRows, emptyHint, }: {
9
+ title: string;
10
+ items: SelectItem[];
11
+ onSelect: (value: string) => void;
12
+ onCancel: () => void;
13
+ onDelete?: (value: string) => void;
14
+ maxRows?: number;
15
+ /** Extra dim lines shown under "(none)" when the list is empty. */
16
+ emptyHint?: string[];
17
+ }): React.ReactElement;
18
+ //# sourceMappingURL=SelectList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectList.d.ts","sourceRoot":"","sources":["../../src/ui/SelectList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAKxC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,KAAK,CAAC,YAAY,CAmErB"}
@@ -0,0 +1,54 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Box, Text, useInput, useStdout } from 'ink';
4
+ import { ACCENT, DIM } from './theme.js';
5
+ import { padTo, truncate } from './text.js';
6
+ /** Arrow-key list: Enter selects, Esc cancels, Del removes (when onDelete set). */
7
+ export function SelectList({ title, items, onSelect, onCancel, onDelete, maxRows, emptyHint, }) {
8
+ const [index, setIndex] = useState(0);
9
+ const clamped = Math.min(index, Math.max(0, items.length - 1));
10
+ const { stdout } = useStdout();
11
+ const columns = stdout?.columns ?? 80;
12
+ // Window items around the selection so a long list never overflows the frame
13
+ // (reserve rows for border, title, and the footer hint). Also cap to a fixed
14
+ // comfortable maximum so a long list still windows (with a scroll counter) on
15
+ // very tall terminals, where `maxRows - 5` would otherwise exceed the list.
16
+ const MAX_VISIBLE = 12;
17
+ const cap = Math.min(maxRows ? Math.max(1, maxRows - 5) : items.length, MAX_VISIBLE);
18
+ const start = Math.min(Math.max(0, clamped - Math.floor(cap / 2)), Math.max(0, items.length - cap));
19
+ const windowed = items.slice(start, start + cap);
20
+ const above = start;
21
+ const below = Math.max(0, items.length - (start + cap));
22
+ useInput((_input, key) => {
23
+ if (key.escape) {
24
+ onCancel();
25
+ return;
26
+ }
27
+ if (items.length === 0)
28
+ return;
29
+ if (key.upArrow)
30
+ setIndex(i => (i <= 0 ? items.length - 1 : i - 1));
31
+ else if (key.downArrow)
32
+ setIndex(i => (i >= items.length - 1 ? 0 : i + 1));
33
+ else if (key.return)
34
+ onSelect(items[clamped].value);
35
+ else if (onDelete && (key.delete || key.backspace))
36
+ onDelete(items[clamped].value);
37
+ });
38
+ return (_jsxs(Box, { borderStyle: "round", borderColor: ACCENT, flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: ACCENT, children: title }), items.length === 0 ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "(none)" }), emptyHint?.map((line, i) => _jsx(Text, { dimColor: true, children: line }, i))] })) : ((() => {
39
+ // Align hints into a column: pad each label to the widest (capped),
40
+ // then clip the hint to the remaining inner width (terminal − border(2)
41
+ // − padding(2)) so every row stays a single, non-wrapping line.
42
+ const labelCol = Math.min(28, Math.max(...windowed.map(it => it.label.length)));
43
+ const hintMax = columns - 4 /*border+padding*/ - 2 /*prefix*/ - labelCol - 2 /*gap*/ - 1;
44
+ return windowed.map((item, i) => {
45
+ const actual = start + i;
46
+ const selected = actual === clamped;
47
+ const prefix = selected ? '› ' : ' ';
48
+ const label = padTo(truncate(item.label, labelCol), labelCol);
49
+ const hint = item.hint ? truncate(item.hint, hintMax) : '';
50
+ return (_jsxs(Box, { children: [_jsxs(Text, { color: selected ? ACCENT : undefined, bold: selected, children: [prefix, label] }), hint ? _jsxs(Text, { color: DIM, children: [' ', hint] }) : null] }, item.value));
51
+ });
52
+ })()), above > 0 || below > 0 ? (_jsxs(Text, { dimColor: true, children: [above > 0 ? `↑ ${above} ` : '', below > 0 ? `↓ ${below}` : ''] })) : null, _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\u2191/\u2193 move \u00B7 Enter select", onDelete ? ' · Del remove' : '', " \u00B7 Esc cancel"] }) })] }));
53
+ }
54
+ //# sourceMappingURL=SelectList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectList.js","sourceRoot":"","sources":["../../src/ui/SelectList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ /** Tiny braille spinner — no external dependency, advances on a timer. */
3
+ export declare function Spinner({ color }: {
4
+ color?: string;
5
+ }): React.ReactElement;
6
+ //# sourceMappingURL=Spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/ui/Spinner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,0EAA0E;AAC1E,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAOzE"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { Text } from 'ink';
4
+ const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
5
+ /** Tiny braille spinner — no external dependency, advances on a timer. */
6
+ export function Spinner({ color }) {
7
+ const [frame, setFrame] = useState(0);
8
+ useEffect(() => {
9
+ const timer = setInterval(() => setFrame(f => (f + 1) % FRAMES.length), 80);
10
+ return () => clearInterval(timer);
11
+ }, []);
12
+ return _jsx(Text, { color: color, children: FRAMES[frame] });
13
+ }
14
+ //# sourceMappingURL=Spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../src/ui/Spinner.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAE3B,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAElE,0EAA0E;AAC1E,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAsB;IACnD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACtC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,YAAG,MAAM,CAAC,KAAK,CAAC,GAAQ,CAAC;AACpD,CAAC"}
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { AppState } from '../core/appState.js';
3
+ export declare function StatusLine({ state }: {
4
+ state: AppState;
5
+ }): React.ReactElement;
6
+ //# sourceMappingURL=StatusLine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusLine.d.ts","sourceRoot":"","sources":["../../src/ui/StatusLine.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAyBpD,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAc7E"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import * as path from 'path';
4
+ import { DIM } from './theme.js';
5
+ /**
6
+ * Persistent identity line pinned below the input: working-dir basename,
7
+ * profile, mode, and provider/model on the left; the input-grammar hint on
8
+ * the right. Run activity lives in the transient {@link RunStatus} line above
9
+ * the input, so this line stays stable across a run.
10
+ */
11
+ /** Compact token count: 16000 → "16K", 9900 → "9.9K", 940 → "940". */
12
+ function shortTokens(n) {
13
+ if (n < 1000)
14
+ return String(n);
15
+ const k = n / 1000;
16
+ return `${k >= 10 ? Math.round(k) : k.toFixed(1)}K`;
17
+ }
18
+ /** `ctx 62% · 9.9K/16K` once a budget is set; `ctx –/16K` before the first measured turn. */
19
+ function contextGauge(state) {
20
+ if (state.maxContextTokens == null || state.maxContextTokens <= 0)
21
+ return undefined;
22
+ const budget = shortTokens(state.maxContextTokens);
23
+ if (state.contextTokens == null)
24
+ return `ctx –/${budget}`;
25
+ const pct = Math.round((state.contextTokens / state.maxContextTokens) * 100);
26
+ return `ctx ${pct}% · ${shortTokens(state.contextTokens)}/${budget}`;
27
+ }
28
+ export function StatusLine({ state }) {
29
+ const gauge = contextGauge(state);
30
+ return (_jsxs(Box, { justifyContent: "space-between", paddingX: 1, children: [_jsxs(Text, { children: [_jsx(Text, { bold: true, children: path.basename(state.cwd) }), _jsx(Text, { color: DIM, children: " | " }), _jsx(Text, { bold: true, children: state.profile }), _jsxs(Text, { color: DIM, children: [" \u00B7 ", state.mode, " \u00B7 ", state.provider, "/", state.model] }), gauge ? _jsxs(Text, { color: DIM, children: [" \u00B7 ", gauge] }) : null] }), _jsx(Text, { color: DIM, children: "$skill \u00B7 /command" })] }));
31
+ }
32
+ //# sourceMappingURL=StatusLine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusLine.js","sourceRoot":"","sources":["../../src/ui/StatusLine.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC;;;;;GAKG;AACH,sEAAsE;AACtE,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACnB,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;AACtD,CAAC;AAED,6FAA6F;AAC7F,SAAS,YAAY,CAAC,KAAe;IACnC,IAAI,KAAK,CAAC,gBAAgB,IAAI,IAAI,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACpF,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACnD,IAAI,KAAK,CAAC,aAAa,IAAI,IAAI;QAAE,OAAO,SAAS,MAAM,EAAE,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,CAAC;IAC7E,OAAO,OAAO,GAAG,OAAO,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,MAAM,EAAE,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAuB;IACvD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,OAAO,CACL,MAAC,GAAG,IAAC,cAAc,EAAC,eAAe,EAAC,QAAQ,EAAE,CAAC,aAC7C,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,IAAI,kBAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAQ,EAC5C,KAAC,IAAI,IAAC,KAAK,EAAE,GAAG,oBAAY,EAC5B,KAAC,IAAI,IAAC,IAAI,kBAAE,KAAK,CAAC,OAAO,GAAQ,EACjC,MAAC,IAAI,IAAC,KAAK,EAAE,GAAG,yBAAM,KAAK,CAAC,IAAI,cAAK,KAAK,CAAC,QAAQ,OAAG,KAAK,CAAC,KAAK,IAAQ,EACxE,KAAK,CAAC,CAAC,CAAC,MAAC,IAAI,IAAC,KAAK,EAAE,GAAG,yBAAM,KAAK,IAAQ,CAAC,CAAC,CAAC,IAAI,IAC9C,EACP,KAAC,IAAI,IAAC,KAAK,EAAE,GAAG,uCAA0B,IACtC,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import type { TranscriptItem } from '../core/appState.js';
3
+ /**
4
+ * Vertical rhythm for the transcript: one blank line separates two adjacent
5
+ * items of different kind, while a run of same-kind items (e.g. a stream of
6
+ * tool request/result lines) stays tight as one visual block. `prevKind` is
7
+ * the kind of the row above — pass `'banner'` for the header, `undefined` when
8
+ * there is no row above.
9
+ */
10
+ export declare function topGap(kind: string, prevKind: string | undefined): 0 | 1;
11
+ export declare function TranscriptRow({ item }: {
12
+ item: TranscriptItem;
13
+ }): React.ReactElement | null;
14
+ export declare function Transcript({ items }: {
15
+ items: TranscriptItem[];
16
+ }): React.ReactElement;
17
+ //# sourceMappingURL=Transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Transcript.d.ts","sourceRoot":"","sources":["../../src/ui/Transcript.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAc,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAUtE;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,CAAC,GAAG,CAAC,CAExE;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAgF3F;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,CAUrF"}
@@ -0,0 +1,58 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from 'ink';
3
+ import { Markdown } from './Markdown.js';
4
+ import { DIM_ACCENT, COMMAND, DIM, SKILL } from './theme.js';
5
+ const NOTICE_COLOR = {
6
+ info: 'gray',
7
+ warn: 'yellow',
8
+ error: 'red',
9
+ };
10
+ /**
11
+ * Vertical rhythm for the transcript: one blank line separates two adjacent
12
+ * items of different kind, while a run of same-kind items (e.g. a stream of
13
+ * tool request/result lines) stays tight as one visual block. `prevKind` is
14
+ * the kind of the row above — pass `'banner'` for the header, `undefined` when
15
+ * there is no row above.
16
+ */
17
+ export function topGap(kind, prevKind) {
18
+ return prevKind !== undefined && prevKind !== kind ? 1 : 0;
19
+ }
20
+ export function TranscriptRow({ item }) {
21
+ switch (item.kind) {
22
+ case 'user': {
23
+ // The submitted input is the divider between turns: framed with top and
24
+ // bottom accent rules. A `/command` and a `$skill` echo in their own
25
+ // colors; a plain message keeps the `>` prompt.
26
+ const command = item.text.startsWith('/');
27
+ const skill = item.text.startsWith('$');
28
+ // For a skill, color only the `$name` head; the args stay default white.
29
+ const sp = item.text.indexOf(' ');
30
+ const head = sp === -1 ? item.text : item.text.slice(0, sp);
31
+ const rest = sp === -1 ? '' : item.text.slice(sp);
32
+ return (_jsx(Box, { borderStyle: "single", borderColor: DIM_ACCENT, borderLeft: false, borderRight: false, width: "100%", children: command ? (_jsx(Text, { color: COMMAND, bold: true, children: item.text })) : skill ? (_jsxs(Text, { children: [_jsx(Text, { color: SKILL, bold: true, children: head }), rest] })) : (_jsxs(_Fragment, { children: [_jsx(Box, { width: 2, flexShrink: 0, children: _jsx(Text, { color: DIM_ACCENT, bold: true, children: '> ' }) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, children: _jsx(Text, { children: item.text }) })] })) }));
33
+ }
34
+ case 'assistant':
35
+ return _jsx(Markdown, { text: item.text, muted: item.muted });
36
+ case 'notice':
37
+ return _jsx(Text, { color: NOTICE_COLOR[item.tone], children: item.text });
38
+ case 'plan':
39
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "Plan" }), item.steps.map(step => (_jsxs(Text, { dimColor: true, children: [step.status === 'completed' ? '✓' : step.status === 'in_progress' ? '▶' : '•', " ", step.text] }, step.id)))] }));
40
+ case 'tool': {
41
+ const arrow = item.phase === 'request' ? '→' : item.isError ? '✗' : '←';
42
+ const color = item.isError ? 'red' : 'gray';
43
+ return (_jsxs(Text, { color: color, children: [arrow, " ", item.tool, item.toolKind ? ` [${item.toolKind}]` : '', ": ", item.summary] }));
44
+ }
45
+ case 'verification':
46
+ return (_jsxs(Text, { color: item.passed ? 'green' : 'yellow', children: [item.passed ? '✓ verified' : '⚠ not verified', ": ", item.notes] }));
47
+ case 'info':
48
+ // The `/command` echo above already labels this block, so the title is
49
+ // not repeated — just the lines.
50
+ return (_jsx(Box, { flexDirection: "column", children: item.lines.map((line, i) => (_jsx(Text, { color: DIM, children: line }, i))) }));
51
+ default:
52
+ return null;
53
+ }
54
+ }
55
+ export function Transcript({ items }) {
56
+ return (_jsx(Box, { flexDirection: "column", paddingX: 1, children: items.map((item, i) => (_jsx(Box, { marginTop: topGap(item.kind, items[i - 1]?.kind), children: _jsx(TranscriptRow, { item: item }) }, item.id))) }));
57
+ }
58
+ //# sourceMappingURL=Transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Transcript.js","sourceRoot":"","sources":["../../src/ui/Transcript.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AgentUsage } from '@marifold/core';
2
+ /** Echo text for a skill turn: `$name arg1 arg2…` (or just `$name` with no args). */
3
+ export declare function skillInvocation(name: string, args: string[]): string;
4
+ /** Strip one pair of matching surrounding quotes/backticks from a path argument
5
+ * — users wrap or paste paths in `…`, "…", or '…'. */
6
+ export declare function unwrapPath(value: string): string;
7
+ export declare function errorText(error: unknown): string;
8
+ /** A parenthetical run summary: elapsed time always, token count when the
9
+ * provider reported it, and cost only when a (cloud) provider reported one —
10
+ * e.g. `(9.1s, 919 tokens)`. */
11
+ export declare function runSummary(elapsedMs: number, usage?: AgentUsage): string;
12
+ /** Copy text to the system clipboard via the platform's CLI utility. Used by
13
+ * /copy to grab a response's original (un-wrapped) text, since selecting from
14
+ * the terminal captures Ink's hard line wraps. */
15
+ export declare function copyToClipboard(text: string): Promise<void>;
16
+ //# sourceMappingURL=appHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appHelpers.d.ts","sourceRoot":"","sources":["../../src/ui/appHelpers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,qFAAqF;AACrF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEpE;AAED;sDACsD;AACtD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED;;gCAEgC;AAChC,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAoBxE;AAED;;kDAEkD;AAClD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa3D"}