@townco/ui 0.1.3 → 0.1.7

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 (250) hide show
  1. package/README.md +11 -11
  2. package/dist/core/hooks/use-chat-input.d.ts +17 -17
  3. package/dist/core/hooks/use-chat-input.js +55 -64
  4. package/dist/core/hooks/use-chat-messages.d.ts +11 -11
  5. package/dist/core/hooks/use-chat-messages.js +114 -121
  6. package/dist/core/hooks/use-chat-session.d.ts +5 -5
  7. package/dist/core/hooks/use-chat-session.js +80 -78
  8. package/dist/core/index.d.ts +1 -1
  9. package/dist/core/index.js +1 -1
  10. package/dist/core/schemas/chat.d.ts +56 -83
  11. package/dist/core/schemas/chat.js +25 -27
  12. package/dist/core/store/chat-store.d.ts +22 -28
  13. package/dist/core/store/chat-store.js +50 -59
  14. package/dist/gui/components/Button.d.ts +7 -23
  15. package/dist/gui/components/Button.js +27 -40
  16. package/dist/gui/components/Card.d.ts +7 -26
  17. package/dist/gui/components/Card.js +8 -54
  18. package/dist/gui/components/ChatInput.d.ts +36 -58
  19. package/dist/gui/components/ChatInput.js +121 -191
  20. package/dist/gui/components/ChatSecondaryPanel.d.ts +11 -14
  21. package/dist/gui/components/ChatSecondaryPanel.js +38 -115
  22. package/dist/gui/components/ChatStatus.d.ts +2 -4
  23. package/dist/gui/components/ChatStatus.js +34 -45
  24. package/dist/gui/components/Conversation.d.ts +14 -17
  25. package/dist/gui/components/Conversation.js +83 -143
  26. package/dist/gui/components/Dialog.d.ts +11 -57
  27. package/dist/gui/components/Dialog.js +8 -84
  28. package/dist/gui/components/HeightTransition.d.ts +7 -12
  29. package/dist/gui/components/HeightTransition.js +77 -88
  30. package/dist/gui/components/Input.d.ts +6 -13
  31. package/dist/gui/components/Input.js +16 -27
  32. package/dist/gui/components/Label.d.ts +1 -7
  33. package/dist/gui/components/Label.js +2 -12
  34. package/dist/gui/components/MarkdownRenderer.d.ts +4 -6
  35. package/dist/gui/components/MarkdownRenderer.js +81 -178
  36. package/dist/gui/components/Message.d.ts +18 -25
  37. package/dist/gui/components/Message.js +23 -44
  38. package/dist/gui/components/MessageContent.d.ts +22 -29
  39. package/dist/gui/components/MessageContent.js +85 -157
  40. package/dist/gui/components/Reasoning.d.ts +24 -30
  41. package/dist/gui/components/Reasoning.js +60 -187
  42. package/dist/gui/components/Response.d.ts +9 -11
  43. package/dist/gui/components/Response.js +90 -229
  44. package/dist/gui/components/Select.d.ts +10 -69
  45. package/dist/gui/components/Select.js +12 -118
  46. package/dist/gui/components/Tabs.d.ts +4 -24
  47. package/dist/gui/components/Tabs.js +4 -32
  48. package/dist/gui/components/Task.d.ts +24 -28
  49. package/dist/gui/components/Task.js +31 -164
  50. package/dist/gui/components/Textarea.d.ts +7 -15
  51. package/dist/gui/components/Textarea.js +46 -63
  52. package/dist/gui/components/ThinkingBlock.d.ts +10 -20
  53. package/dist/gui/components/ThinkingBlock.js +35 -134
  54. package/dist/gui/components/TodoList.d.ts +10 -12
  55. package/dist/gui/components/TodoList.js +7 -22
  56. package/dist/gui/components/TodoListItem.d.ts +6 -9
  57. package/dist/gui/components/TodoListItem.js +4 -18
  58. package/dist/gui/components/index.d.ts +8 -59
  59. package/dist/gui/components/index.js +8 -42
  60. package/dist/gui/lib/utils.js +1 -1
  61. package/dist/index.d.ts +1 -1
  62. package/dist/index.js +1 -1
  63. package/dist/index.test.js +1 -0
  64. package/dist/sdk/client/acp-client.d.ts +76 -88
  65. package/dist/sdk/client/acp-client.js +217 -215
  66. package/dist/sdk/index.d.ts +1 -1
  67. package/dist/sdk/index.js +1 -1
  68. package/dist/sdk/schemas/agent.d.ts +64 -111
  69. package/dist/sdk/schemas/agent.js +24 -24
  70. package/dist/sdk/schemas/message.d.ts +147 -245
  71. package/dist/sdk/schemas/message.js +40 -40
  72. package/dist/sdk/schemas/session.d.ts +135 -219
  73. package/dist/sdk/schemas/session.js +27 -27
  74. package/dist/sdk/transports/http.d.ts +55 -55
  75. package/dist/sdk/transports/http.js +469 -472
  76. package/dist/sdk/transports/stdio.d.ts +20 -20
  77. package/dist/sdk/transports/stdio.js +286 -289
  78. package/dist/sdk/transports/types.d.ts +42 -42
  79. package/dist/sdk/transports/websocket.d.ts +12 -12
  80. package/dist/sdk/transports/websocket.js +46 -52
  81. package/dist/tui/components/ChatView.d.ts +2 -4
  82. package/dist/tui/components/ChatView.js +18 -51
  83. package/dist/tui/components/GameOfLife.js +35 -64
  84. package/dist/tui/components/InputBox.d.ts +11 -18
  85. package/dist/tui/components/InputBox.js +10 -70
  86. package/dist/tui/components/MessageList.d.ts +2 -4
  87. package/dist/tui/components/MessageList.js +10 -37
  88. package/dist/tui/components/MultiSelect.d.ts +10 -15
  89. package/dist/tui/components/MultiSelect.js +73 -116
  90. package/dist/tui/components/ReadlineInput.d.ts +6 -12
  91. package/dist/tui/components/ReadlineInput.js +237 -252
  92. package/dist/tui/components/SingleSelect.d.ts +9 -15
  93. package/dist/tui/components/SingleSelect.js +43 -84
  94. package/dist/tui/components/StatusBar.d.ts +6 -11
  95. package/dist/tui/components/StatusBar.js +67 -102
  96. package/dist/tui/index.d.ts +1 -1
  97. package/dist/tui/index.js +1 -1
  98. package/package.json +2 -2
  99. package/dist/core/hooks/index.d.ts.map +0 -1
  100. package/dist/core/hooks/index.js.map +0 -1
  101. package/dist/core/hooks/use-chat-input.d.ts.map +0 -1
  102. package/dist/core/hooks/use-chat-input.js.map +0 -1
  103. package/dist/core/hooks/use-chat-messages.d.ts.map +0 -1
  104. package/dist/core/hooks/use-chat-messages.js.map +0 -1
  105. package/dist/core/hooks/use-chat-session.d.ts.map +0 -1
  106. package/dist/core/hooks/use-chat-session.js.map +0 -1
  107. package/dist/core/hooks/use-media-query.d.ts +0 -39
  108. package/dist/core/hooks/use-media-query.js +0 -80
  109. package/dist/core/index.d.ts.map +0 -1
  110. package/dist/core/index.js.map +0 -1
  111. package/dist/core/schemas/chat.d.ts.map +0 -1
  112. package/dist/core/schemas/chat.js.map +0 -1
  113. package/dist/core/schemas/index.d.ts.map +0 -1
  114. package/dist/core/schemas/index.js.map +0 -1
  115. package/dist/core/store/chat-store.d.ts.map +0 -1
  116. package/dist/core/store/chat-store.js.map +0 -1
  117. package/dist/gui/components/Button.d.ts.map +0 -1
  118. package/dist/gui/components/Button.js.map +0 -1
  119. package/dist/gui/components/Card.d.ts.map +0 -1
  120. package/dist/gui/components/Card.js.map +0 -1
  121. package/dist/gui/components/ChatHeader.d.ts +0 -65
  122. package/dist/gui/components/ChatHeader.js +0 -189
  123. package/dist/gui/components/ChatInput.d.ts.map +0 -1
  124. package/dist/gui/components/ChatInput.js.map +0 -1
  125. package/dist/gui/components/ChatInterface.d.ts +0 -12
  126. package/dist/gui/components/ChatInterface.d.ts.map +0 -1
  127. package/dist/gui/components/ChatInterface.js +0 -204
  128. package/dist/gui/components/ChatInterface.js.map +0 -1
  129. package/dist/gui/components/ChatLayout.d.ts +0 -82
  130. package/dist/gui/components/ChatLayout.js +0 -232
  131. package/dist/gui/components/ChatPanelTabContent.d.ts +0 -27
  132. package/dist/gui/components/ChatPanelTabContent.js +0 -93
  133. package/dist/gui/components/ChatPreview.d.ts +0 -12
  134. package/dist/gui/components/ChatPreview.d.ts.map +0 -1
  135. package/dist/gui/components/ChatPreview.js +0 -214
  136. package/dist/gui/components/ChatPreview.js.map +0 -1
  137. package/dist/gui/components/ChatSecondaryPanel.d.ts.map +0 -1
  138. package/dist/gui/components/ChatSecondaryPanel.js.map +0 -1
  139. package/dist/gui/components/ChatSidebar.d.ts +0 -27
  140. package/dist/gui/components/ChatSidebar.js +0 -57
  141. package/dist/gui/components/ChatStatus.d.ts.map +0 -1
  142. package/dist/gui/components/ChatStatus.js.map +0 -1
  143. package/dist/gui/components/ChatView.d.ts +0 -8
  144. package/dist/gui/components/ChatView.d.ts.map +0 -1
  145. package/dist/gui/components/ChatView.js +0 -42
  146. package/dist/gui/components/ChatView.js.map +0 -1
  147. package/dist/gui/components/ConfigPanel.d.ts +0 -20
  148. package/dist/gui/components/ConfigPanel.d.ts.map +0 -1
  149. package/dist/gui/components/ConfigPanel.js +0 -225
  150. package/dist/gui/components/ConfigPanel.js.map +0 -1
  151. package/dist/gui/components/Conversation.d.ts.map +0 -1
  152. package/dist/gui/components/Conversation.js.map +0 -1
  153. package/dist/gui/components/Dialog.d.ts.map +0 -1
  154. package/dist/gui/components/Dialog.js.map +0 -1
  155. package/dist/gui/components/DropdownMenu.d.ts +0 -108
  156. package/dist/gui/components/DropdownMenu.js +0 -215
  157. package/dist/gui/components/HeightTransition.d.ts.map +0 -1
  158. package/dist/gui/components/HeightTransition.js.map +0 -1
  159. package/dist/gui/components/Input.d.ts.map +0 -1
  160. package/dist/gui/components/Input.js.map +0 -1
  161. package/dist/gui/components/InputBox.d.ts +0 -21
  162. package/dist/gui/components/InputBox.d.ts.map +0 -1
  163. package/dist/gui/components/InputBox.js +0 -90
  164. package/dist/gui/components/InputBox.js.map +0 -1
  165. package/dist/gui/components/Label.d.ts.map +0 -1
  166. package/dist/gui/components/Label.js.map +0 -1
  167. package/dist/gui/components/MarkdownRenderer.d.ts.map +0 -1
  168. package/dist/gui/components/MarkdownRenderer.js.map +0 -1
  169. package/dist/gui/components/Message.d.ts.map +0 -1
  170. package/dist/gui/components/Message.js.map +0 -1
  171. package/dist/gui/components/MessageContent.d.ts.map +0 -1
  172. package/dist/gui/components/MessageContent.js.map +0 -1
  173. package/dist/gui/components/MessageList.d.ts.map +0 -1
  174. package/dist/gui/components/MessageList.js.map +0 -1
  175. package/dist/gui/components/PlaygroundLayout.d.ts +0 -14
  176. package/dist/gui/components/PlaygroundLayout.d.ts.map +0 -1
  177. package/dist/gui/components/PlaygroundLayout.js +0 -49
  178. package/dist/gui/components/PlaygroundLayout.js.map +0 -1
  179. package/dist/gui/components/Reasoning.d.ts.map +0 -1
  180. package/dist/gui/components/Reasoning.js.map +0 -1
  181. package/dist/gui/components/Response.d.ts.map +0 -1
  182. package/dist/gui/components/Response.js.map +0 -1
  183. package/dist/gui/components/Select.d.ts.map +0 -1
  184. package/dist/gui/components/Select.js.map +0 -1
  185. package/dist/gui/components/Sonner.d.ts +0 -7
  186. package/dist/gui/components/Sonner.js +0 -34
  187. package/dist/gui/components/StatusBar.d.ts +0 -12
  188. package/dist/gui/components/StatusBar.d.ts.map +0 -1
  189. package/dist/gui/components/StatusBar.js +0 -58
  190. package/dist/gui/components/StatusBar.js.map +0 -1
  191. package/dist/gui/components/Tabs.d.ts.map +0 -1
  192. package/dist/gui/components/Tabs.js.map +0 -1
  193. package/dist/gui/components/Task.d.ts.map +0 -1
  194. package/dist/gui/components/Task.js.map +0 -1
  195. package/dist/gui/components/Textarea.d.ts.map +0 -1
  196. package/dist/gui/components/Textarea.js.map +0 -1
  197. package/dist/gui/components/ThinkingBlock.d.ts.map +0 -1
  198. package/dist/gui/components/ThinkingBlock.js.map +0 -1
  199. package/dist/gui/components/TodoList.d.ts.map +0 -1
  200. package/dist/gui/components/TodoList.js.map +0 -1
  201. package/dist/gui/components/TodoListItem.d.ts.map +0 -1
  202. package/dist/gui/components/TodoListItem.js.map +0 -1
  203. package/dist/gui/components/index.d.ts.map +0 -1
  204. package/dist/gui/components/index.js.map +0 -1
  205. package/dist/gui/index.d.ts.map +0 -1
  206. package/dist/gui/index.js.map +0 -1
  207. package/dist/gui/lib/utils.d.ts.map +0 -1
  208. package/dist/gui/lib/utils.js.map +0 -1
  209. package/dist/index.d.ts.map +0 -1
  210. package/dist/index.js.map +0 -1
  211. package/dist/sdk/client/acp-client.d.ts.map +0 -1
  212. package/dist/sdk/client/acp-client.js.map +0 -1
  213. package/dist/sdk/client/index.d.ts.map +0 -1
  214. package/dist/sdk/client/index.js.map +0 -1
  215. package/dist/sdk/index.d.ts.map +0 -1
  216. package/dist/sdk/index.js.map +0 -1
  217. package/dist/sdk/schemas/agent.d.ts.map +0 -1
  218. package/dist/sdk/schemas/agent.js.map +0 -1
  219. package/dist/sdk/schemas/index.d.ts.map +0 -1
  220. package/dist/sdk/schemas/index.js.map +0 -1
  221. package/dist/sdk/schemas/message.d.ts.map +0 -1
  222. package/dist/sdk/schemas/message.js.map +0 -1
  223. package/dist/sdk/schemas/session.d.ts.map +0 -1
  224. package/dist/sdk/schemas/session.js.map +0 -1
  225. package/dist/sdk/transports/http.d.ts.map +0 -1
  226. package/dist/sdk/transports/http.js.map +0 -1
  227. package/dist/sdk/transports/index.d.ts.map +0 -1
  228. package/dist/sdk/transports/index.js.map +0 -1
  229. package/dist/sdk/transports/stdio.d.ts.map +0 -1
  230. package/dist/sdk/transports/stdio.js.map +0 -1
  231. package/dist/sdk/transports/types.d.ts.map +0 -1
  232. package/dist/sdk/transports/types.js.map +0 -1
  233. package/dist/sdk/transports/websocket.d.ts.map +0 -1
  234. package/dist/sdk/transports/websocket.js.map +0 -1
  235. package/dist/tui/components/ChatView.d.ts.map +0 -1
  236. package/dist/tui/components/ChatView.js.map +0 -1
  237. package/dist/tui/components/GameOfLife.d.ts.map +0 -1
  238. package/dist/tui/components/GameOfLife.js.map +0 -1
  239. package/dist/tui/components/InputBox.d.ts.map +0 -1
  240. package/dist/tui/components/InputBox.js.map +0 -1
  241. package/dist/tui/components/MessageList.d.ts.map +0 -1
  242. package/dist/tui/components/MessageList.js.map +0 -1
  243. package/dist/tui/components/ReadlineInput.d.ts.map +0 -1
  244. package/dist/tui/components/ReadlineInput.js.map +0 -1
  245. package/dist/tui/components/StatusBar.d.ts.map +0 -1
  246. package/dist/tui/components/StatusBar.js.map +0 -1
  247. package/dist/tui/components/index.d.ts.map +0 -1
  248. package/dist/tui/components/index.js.map +0 -1
  249. package/dist/tui/index.d.ts.map +0 -1
  250. package/dist/tui/index.js.map +0 -1
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @town/ui
1
+ # @townco/ui
2
2
 
3
3
  Unified UI package with composable components for chat interfaces.
4
4
 
@@ -6,14 +6,14 @@ Unified UI package with composable components for chat interfaces.
6
6
 
7
7
  Three layers:
8
8
 
9
- 1. **Core** (`@town/ui/core`) - Headless business logic
10
- 1. **TUI** (`@town/ui/tui`) - Terminal renderers (Ink)
11
- 1. **GUI** (`@town/ui/gui`) - Web renderers (React + Tailwind)
9
+ 1. **Core** (`@townco/ui/core`) - Headless business logic
10
+ 1. **TUI** (`@townco/ui/tui`) - Terminal renderers (Ink)
11
+ 1. **GUI** (`@townco/ui/gui`) - Web renderers (React + Tailwind)
12
12
 
13
13
  ## Installation
14
14
 
15
15
  ```bash
16
- bun add @town/ui @town/ui
16
+ bun add @townco/ui @townco/ui
17
17
 
18
18
  # For TUI
19
19
  bun add ink react
@@ -27,7 +27,7 @@ bun add react react-dom
27
27
  ### Core (Headless Hooks)
28
28
 
29
29
  ```typescript
30
- import { useChatSession, useChatMessages, useChatInput } from "@town/ui/core";
30
+ import { useChatSession, useChatMessages, useChatInput } from "@townco/ui/core";
31
31
 
32
32
  function MyComponent({ client }) {
33
33
  const { connectionStatus, sessionId } = useChatSession(client);
@@ -42,8 +42,8 @@ function MyComponent({ client }) {
42
42
 
43
43
  ```typescript
44
44
  import { render } from "ink";
45
- import { ChatView } from "@town/ui/tui";
46
- import { AcpClient } from "@town/ui";
45
+ import { ChatView } from "@townco/ui/tui";
46
+ import { AcpClient } from "@townco/ui";
47
47
 
48
48
  const client = new AcpClient({ stdio: { agentPath: "./agent" } });
49
49
  render(<ChatView client={client} />);
@@ -53,8 +53,8 @@ render(<ChatView client={client} />);
53
53
 
54
54
  ```typescript
55
55
  import ReactDOM from "react-dom/client";
56
- import { ChatView } from "@town/ui/gui";
57
- import { AcpClient } from "@town/ui";
56
+ import { ChatView } from "@townco/ui/gui";
57
+ import { AcpClient } from "@townco/ui";
58
58
 
59
59
  const client = new AcpClient({ http: { baseUrl: "http://localhost:8080" } });
60
60
  ReactDOM.createRoot(root).render(<ChatView client={client} />);
@@ -152,7 +152,7 @@ bun test
152
152
  ## Example: Custom Component
153
153
 
154
154
  ```typescript
155
- import { useChatMessages, useChatInput } from "@town/ui/core";
155
+ import { useChatMessages, useChatInput } from "@townco/ui/core";
156
156
 
157
157
  function CustomChat({ client }) {
158
158
  const { messages, sendMessage } = useChatMessages(client);
@@ -3,21 +3,21 @@ import type { AcpClient } from "../../sdk/client/index.js";
3
3
  * Hook for managing chat input
4
4
  */
5
5
  export declare function useChatInput(client: AcpClient | null): {
6
- value: string;
7
- isSubmitting: boolean;
8
- attachedFiles: {
9
- name: string;
10
- path: string;
11
- size: number;
12
- mimeType: string;
13
- }[];
14
- onChange: (value: string) => void;
15
- onSubmit: () => Promise<void>;
16
- onAttachFile: (file: {
17
- name: string;
18
- path: string;
19
- size: number;
20
- mimeType: string;
21
- }) => void;
22
- onRemoveFile: (index: number) => void;
6
+ value: string;
7
+ isSubmitting: boolean;
8
+ attachedFiles: {
9
+ name: string;
10
+ path: string;
11
+ size: number;
12
+ mimeType: string;
13
+ }[];
14
+ onChange: (value: string) => void;
15
+ onSubmit: () => Promise<void>;
16
+ onAttachFile: (file: {
17
+ name: string;
18
+ path: string;
19
+ size: number;
20
+ mimeType: string;
21
+ }) => void;
22
+ onRemoveFile: (index: number) => void;
23
23
  };
@@ -5,68 +5,59 @@ import { useChatMessages } from "./use-chat-messages.js";
5
5
  * Hook for managing chat input
6
6
  */
7
7
  export function useChatInput(client) {
8
- const input = useChatStore((state) => state.input);
9
- const setInputValue = useChatStore((state) => state.setInputValue);
10
- const setInputSubmitting = useChatStore((state) => state.setInputSubmitting);
11
- const addFileAttachment = useChatStore((state) => state.addFileAttachment);
12
- const removeFileAttachment = useChatStore(
13
- (state) => state.removeFileAttachment,
14
- );
15
- const { sendMessage } = useChatMessages(client);
16
- /**
17
- * Handle input value change
18
- */
19
- const handleInputChange = useCallback(
20
- (value) => {
21
- setInputValue(value);
22
- },
23
- [setInputValue],
24
- );
25
- /**
26
- * Handle input submission
27
- */
28
- const handleSubmit = useCallback(async () => {
29
- if (!input.value.trim() || input.isSubmitting) {
30
- return;
31
- }
32
- const message = input.value;
33
- // Clear input immediately for better UX
34
- setInputValue("");
35
- setInputSubmitting(true);
36
- try {
37
- await sendMessage(message);
38
- } catch (error) {
39
- // Error is handled in useChatMessages
40
- console.error("Failed to send message:", error);
41
- } finally {
42
- setInputSubmitting(false);
43
- }
44
- }, [input, setInputValue, setInputSubmitting, sendMessage]);
45
- /**
46
- * Handle file attachment
47
- */
48
- const handleAttachFile = useCallback(
49
- (file) => {
50
- addFileAttachment(file);
51
- },
52
- [addFileAttachment],
53
- );
54
- /**
55
- * Handle file removal
56
- */
57
- const handleRemoveFile = useCallback(
58
- (index) => {
59
- removeFileAttachment(index);
60
- },
61
- [removeFileAttachment],
62
- );
63
- return {
64
- value: input.value,
65
- isSubmitting: input.isSubmitting,
66
- attachedFiles: input.attachedFiles,
67
- onChange: handleInputChange,
68
- onSubmit: handleSubmit,
69
- onAttachFile: handleAttachFile,
70
- onRemoveFile: handleRemoveFile,
71
- };
8
+ const input = useChatStore((state) => state.input);
9
+ const setInputValue = useChatStore((state) => state.setInputValue);
10
+ const setInputSubmitting = useChatStore((state) => state.setInputSubmitting);
11
+ const addFileAttachment = useChatStore((state) => state.addFileAttachment);
12
+ const removeFileAttachment = useChatStore((state) => state.removeFileAttachment);
13
+ const { sendMessage } = useChatMessages(client);
14
+ /**
15
+ * Handle input value change
16
+ */
17
+ const handleInputChange = useCallback((value) => {
18
+ setInputValue(value);
19
+ }, [setInputValue]);
20
+ /**
21
+ * Handle input submission
22
+ */
23
+ const handleSubmit = useCallback(async () => {
24
+ if (!input.value.trim() || input.isSubmitting) {
25
+ return;
26
+ }
27
+ const message = input.value;
28
+ // Clear input immediately for better UX
29
+ setInputValue("");
30
+ setInputSubmitting(true);
31
+ try {
32
+ await sendMessage(message);
33
+ }
34
+ catch (error) {
35
+ // Error is handled in useChatMessages
36
+ console.error("Failed to send message:", error);
37
+ }
38
+ finally {
39
+ setInputSubmitting(false);
40
+ }
41
+ }, [input, setInputValue, setInputSubmitting, sendMessage]);
42
+ /**
43
+ * Handle file attachment
44
+ */
45
+ const handleAttachFile = useCallback((file) => {
46
+ addFileAttachment(file);
47
+ }, [addFileAttachment]);
48
+ /**
49
+ * Handle file removal
50
+ */
51
+ const handleRemoveFile = useCallback((index) => {
52
+ removeFileAttachment(index);
53
+ }, [removeFileAttachment]);
54
+ return {
55
+ value: input.value,
56
+ isSubmitting: input.isSubmitting,
57
+ attachedFiles: input.attachedFiles,
58
+ onChange: handleInputChange,
59
+ onSubmit: handleSubmit,
60
+ onAttachFile: handleAttachFile,
61
+ onRemoveFile: handleRemoveFile,
62
+ };
72
63
  }
@@ -3,15 +3,15 @@ import type { AcpClient } from "../../sdk/client/index.js";
3
3
  * Hook for managing chat messages
4
4
  */
5
5
  export declare function useChatMessages(client: AcpClient | null): {
6
- messages: {
7
- id: string;
8
- role: "user" | "assistant" | "system";
9
- content: string;
10
- timestamp: string;
11
- isStreaming: boolean;
12
- streamingStartTime?: number | undefined;
13
- metadata?: Record<string, unknown> | undefined;
14
- }[];
15
- isStreaming: boolean;
16
- sendMessage: (content: string) => Promise<void>;
6
+ messages: {
7
+ id: string;
8
+ role: "user" | "assistant" | "system";
9
+ content: string;
10
+ timestamp: string;
11
+ isStreaming: boolean;
12
+ streamingStartTime?: number | undefined;
13
+ metadata?: Record<string, unknown> | undefined;
14
+ }[];
15
+ isStreaming: boolean;
16
+ sendMessage: (content: string) => Promise<void>;
17
17
  };
@@ -4,125 +4,118 @@ import { useChatStore } from "../store/chat-store.js";
4
4
  * Hook for managing chat messages
5
5
  */
6
6
  export function useChatMessages(client) {
7
- const messages = useChatStore((state) => state.messages);
8
- const isStreaming = useChatStore((state) => state.isStreaming);
9
- const sessionId = useChatStore((state) => state.sessionId);
10
- const setIsStreaming = useChatStore((state) => state.setIsStreaming);
11
- const setStreamingStartTime = useChatStore(
12
- (state) => state.setStreamingStartTime,
13
- );
14
- const addMessage = useChatStore((state) => state.addMessage);
15
- const updateMessage = useChatStore((state) => state.updateMessage);
16
- const setError = useChatStore((state) => state.setError);
17
- /**
18
- * Send a message to the agent
19
- */
20
- const sendMessage = useCallback(
21
- async (content) => {
22
- if (!client) {
23
- console.error("❌ No client available");
24
- setError("No client available");
25
- return;
26
- }
27
- if (!sessionId) {
28
- console.error("❌ No active session");
29
- setError("No active session");
30
- return;
31
- }
32
- try {
33
- // Start streaming and track time immediately
34
- const startTime = Date.now();
35
- setIsStreaming(true);
36
- setStreamingStartTime(startTime);
37
- // Add user message to UI
38
- const userMessage = {
39
- id: `msg_${Date.now()}_user`,
40
- role: "user",
41
- content,
42
- timestamp: new Date().toISOString(),
43
- isStreaming: false,
44
- };
45
- addMessage(userMessage);
46
- // Create placeholder for assistant message BEFORE sending
47
- const assistantMessageId = `msg_${Date.now()}_assistant`;
48
- const assistantMessage = {
49
- id: assistantMessageId,
50
- role: "assistant",
51
- content: "",
52
- timestamp: new Date().toISOString(),
53
- isStreaming: true,
54
- streamingStartTime: startTime, // Use the same start time from when user sent message
55
- };
56
- addMessage(assistantMessage);
57
- // Build full conversation history (excluding system messages)
58
- const conversationHistory = messages
59
- .filter((msg) => msg.role !== "system")
60
- .map(
61
- (msg) =>
62
- `${msg.role === "user" ? "Human" : "Assistant"}: ${msg.content}`,
63
- )
64
- .join("\n\n");
65
- // Combine history with new message
66
- const fullPrompt = conversationHistory
67
- ? `${conversationHistory}\n\nHuman: ${content}`
68
- : content;
69
- // Start receiving chunks (async iterator)
70
- const messageStream = client.receiveMessages();
71
- // Send full conversation without awaiting (fire and forget)
72
- // This allows chunks to start arriving while we're listening
73
- client.sendMessage(fullPrompt, sessionId).catch((error) => {
74
- const message =
75
- error instanceof Error ? error.message : String(error);
76
- setError(message);
77
- setIsStreaming(false);
78
- setStreamingStartTime(null);
79
- });
80
- // Listen for streaming chunks
81
- let accumulatedContent = "";
82
- for await (const chunk of messageStream) {
83
- if (chunk.isComplete) {
84
- // Update final message
85
- updateMessage(assistantMessageId, {
86
- content: accumulatedContent,
87
- isStreaming: false,
88
- streamingStartTime: undefined, // Clear streaming start time
89
- });
90
- setIsStreaming(false);
91
- setStreamingStartTime(null); // Clear global streaming start time
92
- break;
93
- } else {
94
- // Update streaming content
95
- if (chunk.contentDelta.type === "text") {
96
- accumulatedContent += chunk.contentDelta.text;
97
- updateMessage(assistantMessageId, {
98
- content: accumulatedContent,
99
- });
100
- // Small delay to allow Ink to render between chunks (~60fps)
101
- await new Promise((resolve) => setTimeout(resolve, 16));
102
- }
103
- }
104
- }
105
- } catch (error) {
106
- const message = error instanceof Error ? error.message : String(error);
107
- setError(message);
108
- setIsStreaming(false);
109
- setStreamingStartTime(null); // Clear streaming start time on error
110
- }
111
- },
112
- [
113
- client,
114
- sessionId,
115
- messages,
116
- addMessage,
117
- updateMessage,
118
- setIsStreaming,
119
- setStreamingStartTime,
120
- setError,
121
- ],
122
- );
123
- return {
124
- messages,
125
- isStreaming,
126
- sendMessage,
127
- };
7
+ const messages = useChatStore((state) => state.messages);
8
+ const isStreaming = useChatStore((state) => state.isStreaming);
9
+ const sessionId = useChatStore((state) => state.sessionId);
10
+ const setIsStreaming = useChatStore((state) => state.setIsStreaming);
11
+ const setStreamingStartTime = useChatStore((state) => state.setStreamingStartTime);
12
+ const addMessage = useChatStore((state) => state.addMessage);
13
+ const updateMessage = useChatStore((state) => state.updateMessage);
14
+ const setError = useChatStore((state) => state.setError);
15
+ /**
16
+ * Send a message to the agent
17
+ */
18
+ const sendMessage = useCallback(async (content) => {
19
+ if (!client) {
20
+ console.error("❌ No client available");
21
+ setError("No client available");
22
+ return;
23
+ }
24
+ if (!sessionId) {
25
+ console.error("❌ No active session");
26
+ setError("No active session");
27
+ return;
28
+ }
29
+ try {
30
+ // Start streaming and track time immediately
31
+ const startTime = Date.now();
32
+ setIsStreaming(true);
33
+ setStreamingStartTime(startTime);
34
+ // Add user message to UI
35
+ const userMessage = {
36
+ id: `msg_${Date.now()}_user`,
37
+ role: "user",
38
+ content,
39
+ timestamp: new Date().toISOString(),
40
+ isStreaming: false,
41
+ };
42
+ addMessage(userMessage);
43
+ // Create placeholder for assistant message BEFORE sending
44
+ const assistantMessageId = `msg_${Date.now()}_assistant`;
45
+ const assistantMessage = {
46
+ id: assistantMessageId,
47
+ role: "assistant",
48
+ content: "",
49
+ timestamp: new Date().toISOString(),
50
+ isStreaming: true,
51
+ streamingStartTime: startTime, // Use the same start time from when user sent message
52
+ };
53
+ addMessage(assistantMessage);
54
+ // Build full conversation history (excluding system messages)
55
+ const conversationHistory = messages
56
+ .filter((msg) => msg.role !== "system")
57
+ .map((msg) => `${msg.role === "user" ? "Human" : "Assistant"}: ${msg.content}`)
58
+ .join("\n\n");
59
+ // Combine history with new message
60
+ const fullPrompt = conversationHistory
61
+ ? `${conversationHistory}\n\nHuman: ${content}`
62
+ : content;
63
+ // Start receiving chunks (async iterator)
64
+ const messageStream = client.receiveMessages();
65
+ // Send full conversation without awaiting (fire and forget)
66
+ // This allows chunks to start arriving while we're listening
67
+ client.sendMessage(fullPrompt, sessionId).catch((error) => {
68
+ const message = error instanceof Error ? error.message : String(error);
69
+ setError(message);
70
+ setIsStreaming(false);
71
+ setStreamingStartTime(null);
72
+ });
73
+ // Listen for streaming chunks
74
+ let accumulatedContent = "";
75
+ for await (const chunk of messageStream) {
76
+ if (chunk.isComplete) {
77
+ // Update final message
78
+ updateMessage(assistantMessageId, {
79
+ content: accumulatedContent,
80
+ isStreaming: false,
81
+ streamingStartTime: undefined, // Clear streaming start time
82
+ });
83
+ setIsStreaming(false);
84
+ setStreamingStartTime(null); // Clear global streaming start time
85
+ break;
86
+ }
87
+ else {
88
+ // Update streaming content
89
+ if (chunk.contentDelta.type === "text") {
90
+ accumulatedContent += chunk.contentDelta.text;
91
+ updateMessage(assistantMessageId, {
92
+ content: accumulatedContent,
93
+ });
94
+ // Small delay to allow Ink to render between chunks (~60fps)
95
+ await new Promise((resolve) => setTimeout(resolve, 16));
96
+ }
97
+ }
98
+ }
99
+ }
100
+ catch (error) {
101
+ const message = error instanceof Error ? error.message : String(error);
102
+ setError(message);
103
+ setIsStreaming(false);
104
+ setStreamingStartTime(null); // Clear streaming start time on error
105
+ }
106
+ }, [
107
+ client,
108
+ sessionId,
109
+ messages,
110
+ addMessage,
111
+ updateMessage,
112
+ setIsStreaming,
113
+ setStreamingStartTime,
114
+ setError,
115
+ ]);
116
+ return {
117
+ messages,
118
+ isStreaming,
119
+ sendMessage,
120
+ };
128
121
  }
@@ -3,9 +3,9 @@ import type { AcpClient } from "../../sdk/client/index.js";
3
3
  * Hook for managing chat session lifecycle
4
4
  */
5
5
  export declare function useChatSession(client: AcpClient | null): {
6
- connectionStatus: "error" | "connecting" | "connected" | "disconnected";
7
- sessionId: string | null;
8
- connect: () => Promise<void>;
9
- startSession: () => Promise<void>;
10
- disconnect: () => Promise<void>;
6
+ connectionStatus: "error" | "connecting" | "connected" | "disconnected";
7
+ sessionId: string | null;
8
+ connect: () => Promise<void>;
9
+ startSession: () => Promise<void>;
10
+ disconnect: () => Promise<void>;
11
11
  };