@townco/ui 0.1.79 → 0.1.82

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 (93) hide show
  1. package/dist/core/hooks/use-chat-messages.d.ts +8 -8
  2. package/dist/core/hooks/use-chat-session.d.ts +1 -1
  3. package/dist/core/hooks/use-tool-calls.d.ts +155 -7
  4. package/dist/core/schemas/chat.d.ts +28 -28
  5. package/dist/core/schemas/tool-call.d.ts +34 -34
  6. package/dist/gui/components/AppSidebar.d.ts +1 -1
  7. package/dist/gui/components/AppSidebar.js +7 -1
  8. package/dist/gui/components/Button.d.ts +2 -2
  9. package/dist/gui/components/ChatEmptyState.js +9 -1
  10. package/dist/gui/components/ChatInput.js +4 -2
  11. package/dist/gui/components/ChatInputCommandMenu.js +5 -1
  12. package/dist/gui/components/ChatLayout.js +13 -6
  13. package/dist/gui/components/ChatPanelTabContent.js +17 -2
  14. package/dist/gui/components/ChatSecondaryPanel.js +5 -2
  15. package/dist/gui/components/ChatView.d.ts +1 -1
  16. package/dist/gui/components/ChatView.js +38 -6
  17. package/dist/gui/components/ContextUsageButton.js +41 -3
  18. package/dist/gui/components/Conversation.js +4 -1
  19. package/dist/gui/components/Dialog.d.ts +8 -8
  20. package/dist/gui/components/Dialog.js +6 -1
  21. package/dist/gui/components/DropdownMenu.d.ts +4 -4
  22. package/dist/gui/components/DropdownMenu.js +6 -3
  23. package/dist/gui/components/FileSystemItem.d.ts +1 -1
  24. package/dist/gui/components/FileSystemItem.js +7 -3
  25. package/dist/gui/components/FileSystemView.d.ts +1 -1
  26. package/dist/gui/components/HeightTransition.d.ts +1 -1
  27. package/dist/gui/components/HookNotification.js +39 -3
  28. package/dist/gui/components/Input.d.ts +1 -1
  29. package/dist/gui/components/MarkdownRenderer.d.ts +1 -1
  30. package/dist/gui/components/Message.d.ts +2 -2
  31. package/dist/gui/components/MessageContent.d.ts +2 -2
  32. package/dist/gui/components/MessageContent.js +3 -2
  33. package/dist/gui/components/Reasoning.d.ts +1 -1
  34. package/dist/gui/components/Reasoning.js +10 -3
  35. package/dist/gui/components/Select.js +9 -4
  36. package/dist/gui/components/SessionHistory.d.ts +1 -1
  37. package/dist/gui/components/SessionHistory.js +10 -3
  38. package/dist/gui/components/SessionHistoryItem.js +10 -2
  39. package/dist/gui/components/Sheet.d.ts +9 -9
  40. package/dist/gui/components/Sheet.js +6 -1
  41. package/dist/gui/components/Sidebar.d.ts +5 -6
  42. package/dist/gui/components/Sidebar.js +12 -5
  43. package/dist/gui/components/SidebarToggle.d.ts +1 -1
  44. package/dist/gui/components/Sonner.d.ts +1 -3
  45. package/dist/gui/components/SourceListItem.js +7 -1
  46. package/dist/gui/components/SubAgentDetails.d.ts +1 -1
  47. package/dist/gui/components/SubAgentDetails.js +15 -3
  48. package/dist/gui/components/Task.js +5 -1
  49. package/dist/gui/components/Textarea.d.ts +1 -1
  50. package/dist/gui/components/ThemeProvider.d.ts +1 -1
  51. package/dist/gui/components/ThemeToggle.js +7 -1
  52. package/dist/gui/components/ThinkingBlock.d.ts +2 -2
  53. package/dist/gui/components/ThinkingBlock.js +9 -2
  54. package/dist/gui/components/TodoList.js +5 -1
  55. package/dist/gui/components/TodoListItem.js +4 -2
  56. package/dist/gui/components/TodoSubline.js +2 -1
  57. package/dist/gui/components/ToolCallList.d.ts +1 -1
  58. package/dist/gui/components/ToolCallList.js +5 -1
  59. package/dist/gui/components/ToolOperation.d.ts +1 -1
  60. package/dist/gui/components/ToolOperation.js +75 -17
  61. package/dist/gui/components/WorkProgress.d.ts +1 -1
  62. package/dist/gui/components/resizable.d.ts +34 -2
  63. package/dist/gui/components/resizable.js +3 -1
  64. package/dist/sdk/schemas/agent.d.ts +4 -4
  65. package/dist/sdk/schemas/message.d.ts +13 -13
  66. package/dist/sdk/schemas/session.d.ts +46 -46
  67. package/dist/sdk/transports/http.d.ts +0 -10
  68. package/dist/tui/components/ChatView.js +3 -1
  69. package/dist/tui/components/GameOfLife.js +4 -2
  70. package/dist/tui/components/InputBox.d.ts +1 -1
  71. package/dist/tui/components/InputBox.js +8 -1
  72. package/dist/tui/components/MessageList.js +3 -1
  73. package/dist/tui/components/MultiSelect.d.ts +1 -1
  74. package/dist/tui/components/MultiSelect.js +5 -3
  75. package/dist/tui/components/ReadlineInput.d.ts +1 -1
  76. package/dist/tui/components/ReadlineInput.js +4 -2
  77. package/dist/tui/components/SimpleTextInput.d.ts +1 -1
  78. package/dist/tui/components/SimpleTextInput.js +4 -2
  79. package/dist/tui/components/SingleSelect.d.ts +1 -1
  80. package/dist/tui/components/SingleSelect.js +5 -3
  81. package/dist/tui/components/StatusBar.d.ts +1 -1
  82. package/dist/tui/components/StatusBar.js +8 -3
  83. package/dist/tui/components/ToolCall.js +3 -1
  84. package/dist/tui/components/ToolCallList.js +5 -1
  85. package/package.json +7 -7
  86. package/dist/gui/components/InvokingGroup.d.ts +0 -9
  87. package/dist/gui/components/InvokingGroup.js +0 -16
  88. package/dist/gui/components/SubagentStream.d.ts +0 -23
  89. package/dist/gui/components/SubagentStream.js +0 -98
  90. package/dist/gui/components/ToolCall.d.ts +0 -8
  91. package/dist/gui/components/ToolCall.js +0 -234
  92. package/dist/gui/components/ToolCallGroup.d.ts +0 -8
  93. package/dist/gui/components/ToolCallGroup.js +0 -29
@@ -4,12 +4,12 @@ import { z } from "zod";
4
4
  */
5
5
  export declare const SessionStatus: z.ZodEnum<{
6
6
  active: "active";
7
+ connected: "connected";
8
+ connecting: "connecting";
9
+ disconnected: "disconnected";
7
10
  error: "error";
8
11
  idle: "idle";
9
- connecting: "connecting";
10
- connected: "connected";
11
12
  streaming: "streaming";
12
- disconnected: "disconnected";
13
13
  }>;
14
14
  export type SessionStatus = z.infer<typeof SessionStatus>;
15
15
  /**
@@ -41,12 +41,12 @@ export declare const Session: z.ZodObject<{
41
41
  id: z.ZodString;
42
42
  status: z.ZodEnum<{
43
43
  active: "active";
44
+ connected: "connected";
45
+ connecting: "connecting";
46
+ disconnected: "disconnected";
44
47
  error: "error";
45
48
  idle: "idle";
46
- connecting: "connecting";
47
- connected: "connected";
48
49
  streaming: "streaming";
49
- disconnected: "disconnected";
50
50
  }>;
51
51
  config: z.ZodObject<{
52
52
  agentPath: z.ZodString;
@@ -65,10 +65,10 @@ export declare const Session: z.ZodObject<{
65
65
  messages: z.ZodArray<z.ZodObject<{
66
66
  id: z.ZodString;
67
67
  role: z.ZodEnum<{
68
- user: "user";
69
68
  assistant: "assistant";
70
69
  system: "system";
71
70
  tool: "tool";
71
+ user: "user";
72
72
  }>;
73
73
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
74
74
  type: z.ZodLiteral<"text">;
@@ -79,9 +79,9 @@ export declare const Session: z.ZodObject<{
79
79
  source: z.ZodOptional<z.ZodObject<{
80
80
  type: z.ZodLiteral<"base64">;
81
81
  media_type: z.ZodEnum<{
82
+ "image/gif": "image/gif";
82
83
  "image/jpeg": "image/jpeg";
83
84
  "image/png": "image/png";
84
- "image/gif": "image/gif";
85
85
  "image/webp": "image/webp";
86
86
  }>;
87
87
  data: z.ZodString;
@@ -117,20 +117,20 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
117
117
  sessionId: z.ZodString;
118
118
  status: z.ZodOptional<z.ZodEnum<{
119
119
  active: "active";
120
+ connected: "connected";
121
+ connecting: "connecting";
122
+ disconnected: "disconnected";
120
123
  error: "error";
121
124
  idle: "idle";
122
- connecting: "connecting";
123
- connected: "connected";
124
125
  streaming: "streaming";
125
- disconnected: "disconnected";
126
126
  }>>;
127
127
  message: z.ZodOptional<z.ZodObject<{
128
128
  id: z.ZodString;
129
129
  role: z.ZodEnum<{
130
- user: "user";
131
130
  assistant: "assistant";
132
131
  system: "system";
133
132
  tool: "tool";
133
+ user: "user";
134
134
  }>;
135
135
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
136
136
  type: z.ZodLiteral<"text">;
@@ -141,9 +141,9 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
141
141
  source: z.ZodOptional<z.ZodObject<{
142
142
  type: z.ZodLiteral<"base64">;
143
143
  media_type: z.ZodEnum<{
144
+ "image/gif": "image/gif";
144
145
  "image/jpeg": "image/jpeg";
145
146
  "image/png": "image/png";
146
- "image/gif": "image/gif";
147
147
  "image/webp": "image/webp";
148
148
  }>;
149
149
  data: z.ZodString;
@@ -185,22 +185,22 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
185
185
  }, z.core.$strip>>;
186
186
  subline: z.ZodOptional<z.ZodString>;
187
187
  kind: z.ZodEnum<{
188
- read: "read";
189
- edit: "edit";
190
188
  delete: "delete";
191
- move: "move";
192
- search: "search";
189
+ edit: "edit";
193
190
  execute: "execute";
194
- think: "think";
195
191
  fetch: "fetch";
196
- switch_mode: "switch_mode";
192
+ move: "move";
197
193
  other: "other";
194
+ read: "read";
195
+ search: "search";
196
+ switch_mode: "switch_mode";
197
+ think: "think";
198
198
  }>;
199
199
  status: z.ZodEnum<{
200
- pending: "pending";
201
- in_progress: "in_progress";
202
200
  completed: "completed";
203
201
  failed: "failed";
202
+ in_progress: "in_progress";
203
+ pending: "pending";
204
204
  }>;
205
205
  contentPosition: z.ZodOptional<z.ZodNumber>;
206
206
  locations: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -267,10 +267,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
267
267
  prettyName: z.ZodOptional<z.ZodString>;
268
268
  icon: z.ZodOptional<z.ZodString>;
269
269
  status: z.ZodEnum<{
270
- pending: "pending";
271
- in_progress: "in_progress";
272
270
  completed: "completed";
273
271
  failed: "failed";
272
+ in_progress: "in_progress";
273
+ pending: "pending";
274
274
  }>;
275
275
  content: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
276
276
  type: z.ZodLiteral<"content">;
@@ -312,10 +312,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
312
312
  prettyName: z.ZodOptional<z.ZodString>;
313
313
  icon: z.ZodOptional<z.ZodString>;
314
314
  status: z.ZodEnum<{
315
- pending: "pending";
316
- in_progress: "in_progress";
317
315
  completed: "completed";
318
316
  failed: "failed";
317
+ in_progress: "in_progress";
318
+ pending: "pending";
319
319
  }>;
320
320
  content: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
321
321
  type: z.ZodLiteral<"content">;
@@ -356,20 +356,20 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
356
356
  sessionId: z.ZodString;
357
357
  status: z.ZodOptional<z.ZodEnum<{
358
358
  active: "active";
359
+ connected: "connected";
360
+ connecting: "connecting";
361
+ disconnected: "disconnected";
359
362
  error: "error";
360
363
  idle: "idle";
361
- connecting: "connecting";
362
- connected: "connected";
363
364
  streaming: "streaming";
364
- disconnected: "disconnected";
365
365
  }>>;
366
366
  message: z.ZodOptional<z.ZodObject<{
367
367
  id: z.ZodString;
368
368
  role: z.ZodEnum<{
369
- user: "user";
370
369
  assistant: "assistant";
371
370
  system: "system";
372
371
  tool: "tool";
372
+ user: "user";
373
373
  }>;
374
374
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
375
375
  type: z.ZodLiteral<"text">;
@@ -380,9 +380,9 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
380
380
  source: z.ZodOptional<z.ZodObject<{
381
381
  type: z.ZodLiteral<"base64">;
382
382
  media_type: z.ZodEnum<{
383
+ "image/gif": "image/gif";
383
384
  "image/jpeg": "image/jpeg";
384
385
  "image/png": "image/png";
385
- "image/gif": "image/gif";
386
386
  "image/webp": "image/webp";
387
387
  }>;
388
388
  data: z.ZodString;
@@ -414,10 +414,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
414
414
  toolCallUpdate: z.ZodObject<{
415
415
  id: z.ZodString;
416
416
  status: z.ZodOptional<z.ZodEnum<{
417
- pending: "pending";
418
- in_progress: "in_progress";
419
417
  completed: "completed";
420
418
  failed: "failed";
419
+ in_progress: "in_progress";
420
+ pending: "pending";
421
421
  }>>;
422
422
  title: z.ZodOptional<z.ZodString>;
423
423
  prettyName: z.ZodOptional<z.ZodString>;
@@ -475,10 +475,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
475
475
  prettyName: z.ZodOptional<z.ZodString>;
476
476
  icon: z.ZodOptional<z.ZodString>;
477
477
  status: z.ZodEnum<{
478
- pending: "pending";
479
- in_progress: "in_progress";
480
478
  completed: "completed";
481
479
  failed: "failed";
480
+ in_progress: "in_progress";
481
+ pending: "pending";
482
482
  }>;
483
483
  content: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
484
484
  type: z.ZodLiteral<"content">;
@@ -520,10 +520,10 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
520
520
  prettyName: z.ZodOptional<z.ZodString>;
521
521
  icon: z.ZodOptional<z.ZodString>;
522
522
  status: z.ZodEnum<{
523
- pending: "pending";
524
- in_progress: "in_progress";
525
523
  completed: "completed";
526
524
  failed: "failed";
525
+ in_progress: "in_progress";
526
+ pending: "pending";
527
527
  }>;
528
528
  content: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
529
529
  type: z.ZodLiteral<"content">;
@@ -574,20 +574,20 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
574
574
  sessionId: z.ZodString;
575
575
  status: z.ZodOptional<z.ZodEnum<{
576
576
  active: "active";
577
+ connected: "connected";
578
+ connecting: "connecting";
579
+ disconnected: "disconnected";
577
580
  error: "error";
578
581
  idle: "idle";
579
- connecting: "connecting";
580
- connected: "connected";
581
582
  streaming: "streaming";
582
- disconnected: "disconnected";
583
583
  }>>;
584
584
  message: z.ZodOptional<z.ZodObject<{
585
585
  id: z.ZodString;
586
586
  role: z.ZodEnum<{
587
- user: "user";
588
587
  assistant: "assistant";
589
588
  system: "system";
590
589
  tool: "tool";
590
+ user: "user";
591
591
  }>;
592
592
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
593
593
  type: z.ZodLiteral<"text">;
@@ -598,9 +598,9 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
598
598
  source: z.ZodOptional<z.ZodObject<{
599
599
  type: z.ZodLiteral<"base64">;
600
600
  media_type: z.ZodEnum<{
601
+ "image/gif": "image/gif";
601
602
  "image/jpeg": "image/jpeg";
602
603
  "image/png": "image/png";
603
- "image/gif": "image/gif";
604
604
  "image/webp": "image/webp";
605
605
  }>;
606
606
  data: z.ZodString;
@@ -639,20 +639,20 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
639
639
  sessionId: z.ZodString;
640
640
  status: z.ZodOptional<z.ZodEnum<{
641
641
  active: "active";
642
+ connected: "connected";
643
+ connecting: "connecting";
644
+ disconnected: "disconnected";
642
645
  error: "error";
643
646
  idle: "idle";
644
- connecting: "connecting";
645
- connected: "connected";
646
647
  streaming: "streaming";
647
- disconnected: "disconnected";
648
648
  }>>;
649
649
  message: z.ZodOptional<z.ZodObject<{
650
650
  id: z.ZodString;
651
651
  role: z.ZodEnum<{
652
- user: "user";
653
652
  assistant: "assistant";
654
653
  system: "system";
655
654
  tool: "tool";
655
+ user: "user";
656
656
  }>;
657
657
  content: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
658
658
  type: z.ZodLiteral<"text">;
@@ -663,9 +663,9 @@ export declare const SessionUpdate: z.ZodUnion<readonly [z.ZodObject<{
663
663
  source: z.ZodOptional<z.ZodObject<{
664
664
  type: z.ZodLiteral<"base64">;
665
665
  media_type: z.ZodEnum<{
666
+ "image/gif": "image/gif";
666
667
  "image/jpeg": "image/jpeg";
667
668
  "image/png": "image/png";
668
- "image/gif": "image/gif";
669
669
  "image/webp": "image/webp";
670
670
  }>;
671
671
  data: z.ZodString;
@@ -67,18 +67,8 @@ export declare class HttpTransport implements Transport {
67
67
  description: string;
68
68
  }>;
69
69
  };
70
- /**
71
- * Send an ACP RPC request to the server
72
- */
73
70
  private sendRpcRequest;
74
- /**
75
- * Connect to the SSE event stream
76
- * Uses fetch-based SSE to support custom headers (X-Session-ID)
77
- */
78
71
  private connectSSE;
79
- /**
80
- * Handle SSE disconnection with automatic reconnection
81
- */
82
72
  private handleSSEDisconnect;
83
73
  /**
84
74
  * Handle an incoming SSE message
@@ -25,7 +25,9 @@ export function ChatView({ client }) {
25
25
  setIsStreaming(false);
26
26
  }
27
27
  };
28
- return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [_jsx(Box, { flexGrow: 1, flexDirection: "column", children: _jsx(MessageList, { messages: messages }) }), _jsx(InputBox, { value: value, isSubmitting: isSubmitting, attachedFiles: attachedFiles, onChange: onChange, onSubmit: onSubmit, onEscape: handleEscape })] }));
28
+ return (_jsxs(Box, { flexDirection: "column", height: "100%", children: [
29
+ _jsx(Box, { flexGrow: 1, flexDirection: "column", children: _jsx(MessageList, { messages: messages }) }), _jsx(InputBox, { value: value, isSubmitting: isSubmitting, attachedFiles: attachedFiles, onChange: onChange, onSubmit: onSubmit, onEscape: handleEscape })
30
+ ] }));
29
31
  }
30
32
  // Export helper to render status content separately
31
33
  export function ChatViewStatus({ client }) {
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text } from "ink";
3
3
  import { useEffect, useState } from "react";
4
4
  const ROWS = 12;
@@ -46,5 +46,7 @@ export function GameOfLife() {
46
46
  }, 150);
47
47
  return () => clearInterval(interval);
48
48
  }, []);
49
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsxs(Text, { color: "gray", italic: true, children: ["Conway's Game of Life (generation ", generation, ")"] }), grid.map((row, i) => (_jsx(Text, { color: "green", children: row.map((cell) => (cell ? "█" : " ")).join("") }, rowIds[i]))), _jsx(Text, { color: "gray", italic: true, children: "Start typing to begin..." })] }));
49
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [
50
+ _jsxs(Text, { color: "gray", italic: true, children: ["Conway's Game of Life (generation ", generation, ")"] }), grid.map((row, i) => (_jsx(Text, { color: "green", children: row.map((cell) => (cell ? "█" : " ")).join("") }, rowIds[i]))), _jsx(Text, { color: "gray", italic: true, children: "Start typing to begin..." })
51
+ ] }));
50
52
  }
@@ -10,4 +10,4 @@ export interface InputBoxProps {
10
10
  onSubmit: () => void;
11
11
  onEscape?: () => void;
12
12
  }
13
- export declare function InputBox({ value, isSubmitting, attachedFiles, onChange, onSubmit, onEscape, }: InputBoxProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function InputBox({ value, isSubmitting, attachedFiles, onChange, onSubmit, onEscape }: InputBoxProps): import("react/jsx-runtime").JSX.Element;
@@ -23,7 +23,14 @@ export function InputBox({ value, isSubmitting, attachedFiles, onChange, onSubmi
23
23
  // Split value into lines for display
24
24
  const lines = value.split("\n");
25
25
  const _hasMultipleLines = lines.length > 1;
26
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "blue", children: "─".repeat(terminalWidth) }), attachedFiles.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "Attached files:" }), attachedFiles.map((file) => (_jsxs(Box, { children: [_jsxs(Text, { color: "cyan", children: [" ", file.name] }), _jsxs(Text, { dimColor: true, children: [" (", formatFileSize(file.size), ")"] })] }, file.path)))] })), _jsx(Box, { paddingY: 1, flexDirection: "column", children: _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { bold: true, color: "blue", children: "> " }), _jsx(Box, { flexGrow: 1, children: isSubmitting ? (_jsx(Text, { color: "gray", italic: true, children: "Sending..." })) : (_jsx(SimpleTextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "Type your message... (\\ or Shift+Enter for newline)" })) })] }) })] }));
26
+ return (_jsxs(Box, { flexDirection: "column", children: [
27
+ _jsx(Text, { color: "blue", children: "─".repeat(terminalWidth) }), attachedFiles.length > 0 && (_jsxs(Box, { flexDirection: "column", children: [
28
+ _jsx(Text, { dimColor: true, children: "Attached files:" }), attachedFiles.map((file) => (_jsxs(Box, { children: [
29
+ _jsxs(Text, { color: "cyan", children: [" ", file.name] }), _jsxs(Text, { dimColor: true, children: [" (", formatFileSize(file.size), ")"] })
30
+ ] }, file.path)))] })), _jsx(Box, { paddingY: 1, flexDirection: "column", children: _jsxs(Box, { flexDirection: "row", children: [
31
+ _jsx(Text, { bold: true, color: "blue", children: "> " }), _jsx(Box, { flexGrow: 1, children: isSubmitting ? (_jsx(Text, { color: "gray", italic: true, children: "Sending..." })) : (_jsx(SimpleTextInput, { value: value, onChange: onChange, onSubmit: onSubmit, placeholder: "Type your message... (\\ or Shift+Enter for newline)" })) })
32
+ ] }) })
33
+ ] }));
27
34
  }
28
35
  function formatFileSize(bytes) {
29
36
  if (bytes < 1024)
@@ -15,5 +15,7 @@ function Message({ message }) {
15
15
  const trimmedContent = message.content?.trim() || "";
16
16
  return (_jsxs(Box, { flexDirection: "column", marginY: 1, children: [message.role === "assistant" &&
17
17
  message.toolCalls &&
18
- message.toolCalls.length > 0 && (_jsx(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: message.toolCalls.map((toolCall) => (_jsx(ToolCall, { toolCall: toolCall }, toolCall.id))) })), _jsxs(Box, { children: [_jsxs(Text, { bold: true, color: roleColor, children: [roleSymbol, " "] }), message.role === "user" ? (_jsx(Text, { backgroundColor: "gray", children: trimmedContent })) : (_jsx(Text, { children: trimmedContent }))] })] }));
18
+ message.toolCalls.length > 0 && (_jsx(Box, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: message.toolCalls.map((toolCall) => (_jsx(ToolCall, { toolCall: toolCall }, toolCall.id))) })), _jsxs(Box, { children: [
19
+ _jsxs(Text, { bold: true, color: roleColor, children: [roleSymbol, " "] }), message.role === "user" ? (_jsx(Text, { backgroundColor: "gray", children: trimmedContent })) : (_jsx(Text, { children: trimmedContent }))] })
20
+ ] }));
19
21
  }
@@ -11,4 +11,4 @@ export interface MultiSelectProps {
11
11
  onCancel?: () => void;
12
12
  autoAdvanceOnSelect?: boolean;
13
13
  }
14
- export declare function MultiSelect({ options, selected, onChange, onSubmit, onCancel, autoAdvanceOnSelect, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function MultiSelect({ options, selected, onChange, onSubmit, onCancel, autoAdvanceOnSelect }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from "ink";
3
3
  import { useState } from "react";
4
4
  export function MultiSelect({ options, selected, onChange, onSubmit, onCancel, autoAdvanceOnSelect = true, }) {
@@ -71,6 +71,8 @@ export function MultiSelect({ options, selected, onChange, onSubmit, onCancel, a
71
71
  return (_jsxs(Box, { flexDirection: "column", children: [options.map((option, index) => {
72
72
  const isSelected = selected.includes(option.value);
73
73
  const isFocused = index === focusedIndex;
74
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { inverse: isFocused, children: [isSelected ? "[x]" : "[ ]", " ", option.label] }) }), option.description && (_jsx(Box, { paddingLeft: 4, children: _jsx(Text, { dimColor: true, children: option.description }) }))] }, option.value));
75
- }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { inverse: focusedIndex === options.length, color: "green", bold: true, children: "\u2192 Continue" }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193: Navigate \u2022 Space/Enter: Toggle \u2022 Enter on Continue: Proceed" }) })] }));
74
+ return (_jsxs(Box, { flexDirection: "column", children: [
75
+ _jsx(Box, { children: _jsxs(Text, { inverse: isFocused, children: [isSelected ? "[x]" : "[ ]", " ", option.label] }) }), option.description && (_jsx(Box, { paddingLeft: 4, children: _jsx(Text, { dimColor: true, children: option.description }) }))] }, option.value));
76
+ }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { inverse: focusedIndex === options.length, color: "green", bold: true, children: "\u2192 Continue" }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193: Navigate \u2022 Space/Enter: Toggle \u2022 Enter on Continue: Proceed" }) })
77
+ ] }));
76
78
  }
@@ -6,4 +6,4 @@ export interface ReadlineInputProps {
6
6
  onCtrlT?: () => void;
7
7
  placeholder?: string;
8
8
  }
9
- export declare function ReadlineInput({ value, onChange, onSubmit, onEscape, onCtrlT, placeholder, }: ReadlineInputProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function ReadlineInput({ value, onChange, onSubmit, onEscape, onCtrlT, placeholder }: ReadlineInputProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Text, useInput } from "ink";
3
3
  import React, { useState } from "react";
4
4
  export function ReadlineInput({ value, onChange, onSubmit, onEscape, onCtrlT, placeholder = "", }) {
@@ -237,7 +237,9 @@ export function ReadlineInput({ value, onChange, onSubmit, onEscape, onCtrlT, pl
237
237
  const cursorPos = value.length + cursorOffset;
238
238
  // Show placeholder if empty
239
239
  if (value.length === 0) {
240
- return (_jsxs(_Fragment, { children: [_jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: placeholder })] }));
240
+ return (_jsxs(_Fragment, { children: [
241
+ _jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: placeholder })
242
+ ] }));
241
243
  }
242
244
  // Show value with cursor
243
245
  const before = value.slice(0, cursorPos);
@@ -4,4 +4,4 @@ export interface SimpleTextInputProps {
4
4
  onSubmit: () => void;
5
5
  placeholder?: string;
6
6
  }
7
- export declare function SimpleTextInput({ value, onChange, onSubmit, placeholder, }: SimpleTextInputProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function SimpleTextInput({ value, onChange, onSubmit, placeholder }: SimpleTextInputProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Text, useInput } from "ink";
3
3
  import { useEffect, useState } from "react";
4
4
  export function SimpleTextInput({ value, onChange, onSubmit, placeholder = "", }) {
@@ -159,7 +159,9 @@ export function SimpleTextInput({ value, onChange, onSubmit, placeholder = "", }
159
159
  const cursorPos = value.length + cursorOffset;
160
160
  // Show placeholder if empty
161
161
  if (value.length === 0) {
162
- return (_jsxs(_Fragment, { children: [_jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: placeholder })] }));
162
+ return (_jsxs(_Fragment, { children: [
163
+ _jsx(Text, { inverse: true, children: " " }), _jsx(Text, { dimColor: true, children: placeholder })
164
+ ] }));
163
165
  }
164
166
  // Split by newlines for multi-line rendering
165
167
  const allLines = value.split("\n");
@@ -10,4 +10,4 @@ export interface SingleSelectProps {
10
10
  onSubmit: (selected: string) => void;
11
11
  onCancel?: () => void;
12
12
  }
13
- export declare function SingleSelect({ options, selected: _selected, onChange, onSubmit, onCancel, }: SingleSelectProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function SingleSelect({ options, selected: _selected, onChange, onSubmit, onCancel }: SingleSelectProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Box, Text, useInput } from "ink";
3
3
  import { useState } from "react";
4
4
  export function SingleSelect({ options, selected: _selected, onChange, onSubmit, onCancel, }) {
@@ -41,6 +41,8 @@ export function SingleSelect({ options, selected: _selected, onChange, onSubmit,
41
41
  });
42
42
  return (_jsxs(Box, { flexDirection: "column", children: [options.map((option, index) => {
43
43
  const isFocused = index === focusedIndex;
44
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsxs(Text, { inverse: isFocused, children: [isFocused ? ">" : " ", " ", option.label] }) }), option.description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { dimColor: true, children: option.description }) }))] }, option.value));
45
- }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193: Navigate \u2022 Space/Enter: Select and continue \u2022 Esc: Cancel" }) })] }));
44
+ return (_jsxs(Box, { flexDirection: "column", children: [
45
+ _jsx(Box, { children: _jsxs(Text, { inverse: isFocused, children: [isFocused ? ">" : " ", " ", option.label] }) }), option.description && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { dimColor: true, children: option.description }) }))] }, option.value));
46
+ }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "\u2191/\u2193: Navigate \u2022 Space/Enter: Select and continue \u2022 Esc: Cancel" }) })
47
+ ] }));
46
48
  }
@@ -18,4 +18,4 @@ export interface StatusBarProps {
18
18
  currentModel?: string | null;
19
19
  tokenDisplayMode: "context" | "input" | "output";
20
20
  }
21
- export declare function StatusBar({ connectionStatus, isStreaming, streamingStartTime, hasStreamingContent, totalBilled: _totalBilled, currentContext, currentModel, tokenDisplayMode: _tokenDisplayMode, }: StatusBarProps): import("react/jsx-runtime").JSX.Element;
21
+ export declare function StatusBar({ connectionStatus, isStreaming, streamingStartTime, hasStreamingContent, totalBilled: _totalBilled, currentContext, currentModel, tokenDisplayMode: _tokenDisplayMode }: StatusBarProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +1,4 @@
1
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Text } from "ink";
3
3
  import { useEffect, useState } from "react";
4
4
  import { calculateTokenPercentage, formatTokenPercentage, } from "../../core/utils/model-context.js";
@@ -113,7 +113,12 @@ export function StatusBar({ connectionStatus, isStreaming, streamingStartTime, h
113
113
  const contextPercentage = calculateTokenPercentage(contextTokens, currentModel ?? undefined);
114
114
  const contextPercentageStr = formatTokenPercentage(contextTokens, currentModel ?? undefined);
115
115
  const contextColor = getTokenColor(contextPercentage);
116
- return (_jsxs(_Fragment, { children: [_jsx(Text, { dimColor: true, children: "Ctx: " }), _jsx(Text, { color: contextColor, children: contextPercentageStr }), _jsx(Text, { dimColor: true, children: " | In: " }), _jsx(Text, { children: formatTokenCount(inputTokens) }), _jsx(Text, { dimColor: true, children: " | Out: " }), _jsx(Text, { children: formatTokenCount(outputTokens) })] }));
116
+ return (_jsxs(_Fragment, { children: [
117
+ _jsx(Text, { dimColor: true, children: "Ctx: " }), _jsx(Text, { color: contextColor, children: contextPercentageStr }), _jsx(Text, { dimColor: true, children: " | In: " }), _jsx(Text, { children: formatTokenCount(inputTokens) }), _jsx(Text, { dimColor: true, children: " | Out: " }), _jsx(Text, { children: formatTokenCount(outputTokens) })
118
+ ] }));
117
119
  };
118
- return (_jsxs(_Fragment, { children: [_jsx(Text, { color: statusColor, children: "\u25CF" }), _jsxs(Text, { children: [" ", connectionStatus] }), showWaiting && (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsx(WaitingElapsedTime, { startTime: streamingStartTime })] })), _jsx(Text, { dimColor: true, children: " | " }), renderTokenDisplay()] }));
120
+ return (_jsxs(_Fragment, { children: [
121
+ _jsx(Text, { color: statusColor, children: "\u25CF" }), _jsxs(Text, { children: [" ", connectionStatus] }), showWaiting && (_jsxs(_Fragment, { children: [
122
+ _jsx(Text, { children: " " }), _jsx(WaitingElapsedTime, { startTime: streamingStartTime })
123
+ ] })), _jsx(Text, { dimColor: true, children: " | " }), renderTokenDisplay()] }));
119
124
  }
@@ -37,5 +37,7 @@ export function ToolCall({ toolCall }) {
37
37
  ? ((toolCall.tokenUsage.inputTokens / 1_000_000) * 3 +
38
38
  (toolCall.tokenUsage.outputTokens / 1_000_000) * 15).toFixed(4)
39
39
  : null;
40
- return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", gap: 1, children: [_jsx(Text, { color: statusColors[toolCall.status], children: statusIndicators[toolCall.status] }), _jsx(Text, { color: "cyan", bold: true, children: "[TOOL]" }), _jsx(Text, { children: toolCall.title }), startTime && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", startTime] })), duration && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", duration, "s"] })), cost && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| $", cost] }))] }), toolCall._meta?.truncationWarning && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "yellow", bold: true, children: ["\u26A0\uFE0F ", toolCall._meta.truncationWarning] }) }))] }));
40
+ return (_jsxs(Box, { flexDirection: "column", children: [
41
+ _jsxs(Box, { flexDirection: "row", gap: 1, children: [
42
+ _jsx(Text, { color: statusColors[toolCall.status], children: statusIndicators[toolCall.status] }), _jsx(Text, { color: "cyan", bold: true, children: "[TOOL]" }), _jsx(Text, { children: toolCall.title }), startTime && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", startTime] })), duration && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| ", duration, "s"] })), cost && (_jsxs(Text, { color: "gray", dimColor: true, children: ["| $", cost] }))] }), toolCall._meta?.truncationWarning && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: "yellow", bold: true, children: ["\u26A0\uFE0F ", toolCall._meta.truncationWarning] }) }))] }));
41
43
  }
@@ -13,5 +13,9 @@ export function ToolCallList({ toolCalls }) {
13
13
  const pending = toolCalls.filter((tc) => tc.status === "pending");
14
14
  const completed = toolCalls.filter((tc) => tc.status === "completed");
15
15
  const failed = toolCalls.filter((tc) => tc.status === "failed");
16
- return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [inProgress.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "blue", children: ["\u25B6 In Progress (", inProgress.length, ")"] }), inProgress.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), pending.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "gray", children: ["\u23F8 Pending (", pending.length, ")"] }), pending.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), completed.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "green", children: ["\u2713 Completed (", completed.length, ")"] }), completed.slice(-5).map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id))), completed.length > 5 && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { dimColor: true, children: ["... and ", completed.length - 5, " more"] }) }))] })), failed.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: "red", children: ["\u2717 Failed (", failed.length, ")"] }), failed.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] }))] }));
16
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [inProgress.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
17
+ _jsxs(Text, { bold: true, color: "blue", children: ["\u25B6 In Progress (", inProgress.length, ")"] }), inProgress.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), pending.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
18
+ _jsxs(Text, { bold: true, color: "gray", children: ["\u23F8 Pending (", pending.length, ")"] }), pending.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] })), completed.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
19
+ _jsxs(Text, { bold: true, color: "green", children: ["\u2713 Completed (", completed.length, ")"] }), completed.slice(-5).map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id))), completed.length > 5 && (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { dimColor: true, children: ["... and ", completed.length - 5, " more"] }) }))] })), failed.length > 0 && (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
20
+ _jsxs(Text, { bold: true, color: "red", children: ["\u2717 Failed (", failed.length, ")"] }), failed.map((tc) => (_jsx(ToolCall, { toolCall: tc }, tc.id)))] }))] }));
17
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@townco/ui",
3
- "version": "0.1.79",
3
+ "version": "0.1.82",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -33,10 +33,10 @@
33
33
  "./styles/global.css": "./src/styles/global.css"
34
34
  },
35
35
  "scripts": {
36
- "build": "tsc",
37
- "dev": "tsc --watch",
36
+ "build": "tsgo",
37
+ "dev": "tsgo --watch",
38
38
  "test": "bun test",
39
- "check": "tsc --noEmit",
39
+ "check": "tsgo --noEmit",
40
40
  "prepack": "node scripts/strip-dev-exports.js",
41
41
  "postpack": "node scripts/strip-dev-exports.js restore"
42
42
  },
@@ -49,7 +49,7 @@
49
49
  "@radix-ui/react-slot": "^1.2.4",
50
50
  "@radix-ui/react-tabs": "^1.1.13",
51
51
  "@radix-ui/react-tooltip": "^1.2.8",
52
- "@townco/core": "0.0.57",
52
+ "@townco/core": "0.0.60",
53
53
  "@uiw/react-json-view": "^2.0.0-alpha.39",
54
54
  "class-variance-authority": "^0.7.1",
55
55
  "clsx": "^2.1.1",
@@ -65,13 +65,13 @@
65
65
  "zustand": "^5.0.8"
66
66
  },
67
67
  "devDependencies": {
68
- "@townco/tsconfig": "0.1.76",
68
+ "@townco/tsconfig": "0.1.79",
69
69
  "@types/node": "^24.10.0",
70
70
  "@types/react": "^19.2.2",
71
71
  "ink": "^6.4.0",
72
72
  "react": "19.2.1",
73
73
  "tailwindcss": "^4.1.17",
74
- "typescript": "^5.9.3"
74
+ "@typescript/native-preview": "^7.0.0-dev.20251207.1"
75
75
  },
76
76
  "peerDependencies": {
77
77
  "ink": "^6.4.0",
@@ -1,9 +0,0 @@
1
- import type { ToolCall as ToolCallType } from "../../core/schemas/tool-call.js";
2
- export interface InvokingGroupProps {
3
- toolCalls: ToolCallType[];
4
- }
5
- /**
6
- * InvokingGroup component - displays a group of preliminary (invoking) tool calls
7
- * Shows as "Invoking parallel operation (N)" with a summary of unique tool names
8
- */
9
- export declare function InvokingGroup({ toolCalls }: InvokingGroupProps): import("react/jsx-runtime").JSX.Element;
@@ -1,16 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ListVideo } from "lucide-react";
3
- import React from "react";
4
- /**
5
- * InvokingGroup component - displays a group of preliminary (invoking) tool calls
6
- * Shows as "Invoking parallel operation (N)" with a summary of unique tool names
7
- */
8
- export function InvokingGroup({ toolCalls }) {
9
- // Get unique display names for the summary
10
- const displayNames = toolCalls.map((tc) => tc.prettyName || tc.title);
11
- const uniqueNames = [...new Set(displayNames)];
12
- const summary = uniqueNames.length <= 2
13
- ? uniqueNames.join(", ")
14
- : `${uniqueNames.slice(0, 2).join(", ")} +${uniqueNames.length - 2} more`;
15
- return (_jsxs("div", { className: "flex flex-col my-4", children: [_jsxs("div", { className: "flex items-center gap-1.5 text-paragraph-sm text-muted-foreground/50", children: [_jsx(ListVideo, { className: "h-3 w-3" }), _jsx("span", { children: "Invoking parallel operation" }), _jsx("span", { className: "text-[10px] bg-muted px-1.5 py-0.5 rounded text-muted-foreground/50", children: toolCalls.length })] }), _jsx("span", { className: "text-paragraph-sm text-muted-foreground/50 pl-4.5", children: summary })] }));
16
- }