@townco/ui 0.1.7 → 0.1.9

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 (243) hide show
  1. package/dist/core/hooks/index.d.ts +1 -0
  2. package/dist/core/hooks/index.d.ts.map +1 -0
  3. package/dist/core/hooks/index.js +1 -0
  4. package/dist/core/hooks/index.js.map +1 -0
  5. package/dist/core/hooks/use-chat-input.d.ts +17 -17
  6. package/dist/core/hooks/use-chat-input.d.ts.map +1 -0
  7. package/dist/core/hooks/use-chat-input.js +64 -55
  8. package/dist/core/hooks/use-chat-input.js.map +1 -0
  9. package/dist/core/hooks/use-chat-messages.d.ts +11 -11
  10. package/dist/core/hooks/use-chat-messages.d.ts.map +1 -0
  11. package/dist/core/hooks/use-chat-messages.js +121 -114
  12. package/dist/core/hooks/use-chat-messages.js.map +1 -0
  13. package/dist/core/hooks/use-chat-session.d.ts +5 -5
  14. package/dist/core/hooks/use-chat-session.d.ts.map +1 -0
  15. package/dist/core/hooks/use-chat-session.js +78 -80
  16. package/dist/core/hooks/use-chat-session.js.map +1 -0
  17. package/dist/core/hooks/use-media-query.d.ts +39 -0
  18. package/dist/core/hooks/use-media-query.js +84 -0
  19. package/dist/core/index.d.ts.map +1 -0
  20. package/dist/core/index.js.map +1 -0
  21. package/dist/core/schemas/chat.d.ts +83 -56
  22. package/dist/core/schemas/chat.d.ts.map +1 -0
  23. package/dist/core/schemas/chat.js +27 -25
  24. package/dist/core/schemas/chat.js.map +1 -0
  25. package/dist/core/schemas/index.d.ts.map +1 -0
  26. package/dist/core/schemas/index.js.map +1 -0
  27. package/dist/core/store/chat-store.d.ts +28 -22
  28. package/dist/core/store/chat-store.d.ts.map +1 -0
  29. package/dist/core/store/chat-store.js +59 -50
  30. package/dist/core/store/chat-store.js.map +1 -0
  31. package/dist/gui/components/Button.d.ts +23 -7
  32. package/dist/gui/components/Button.d.ts.map +1 -0
  33. package/dist/gui/components/Button.js +40 -27
  34. package/dist/gui/components/Button.js.map +1 -0
  35. package/dist/gui/components/Card.d.ts +26 -7
  36. package/dist/gui/components/Card.d.ts.map +1 -0
  37. package/dist/gui/components/Card.js +54 -8
  38. package/dist/gui/components/Card.js.map +1 -0
  39. package/dist/gui/components/ChatHeader.d.ts +38 -0
  40. package/dist/gui/components/ChatHeader.js +86 -0
  41. package/dist/gui/components/ChatInput.d.ts +19 -1
  42. package/dist/gui/components/ChatInput.d.ts.map +1 -0
  43. package/dist/gui/components/ChatInput.js +94 -11
  44. package/dist/gui/components/ChatInput.js.map +1 -0
  45. package/dist/gui/components/ChatInputCommandMenu.d.ts +20 -0
  46. package/dist/gui/components/ChatInputCommandMenu.js +62 -0
  47. package/dist/gui/components/ChatInterface.d.ts +12 -0
  48. package/dist/gui/components/ChatInterface.d.ts.map +1 -0
  49. package/dist/gui/components/ChatInterface.js +204 -0
  50. package/dist/gui/components/ChatInterface.js.map +1 -0
  51. package/dist/gui/components/ChatLayout.d.ts +52 -0
  52. package/dist/gui/components/ChatLayout.js +105 -0
  53. package/dist/gui/components/ChatPanelTabContent.d.ts +18 -0
  54. package/dist/gui/components/ChatPanelTabContent.js +15 -0
  55. package/dist/gui/components/ChatPreview.d.ts +12 -0
  56. package/dist/gui/components/ChatPreview.d.ts.map +1 -0
  57. package/dist/gui/components/ChatPreview.js +214 -0
  58. package/dist/gui/components/ChatPreview.js.map +1 -0
  59. package/dist/gui/components/ChatSecondaryPanel.d.ts +14 -11
  60. package/dist/gui/components/ChatSecondaryPanel.d.ts.map +1 -0
  61. package/dist/gui/components/ChatSecondaryPanel.js +115 -38
  62. package/dist/gui/components/ChatSecondaryPanel.js.map +1 -0
  63. package/dist/gui/components/ChatSidebar.d.ts +14 -0
  64. package/dist/gui/components/ChatSidebar.js +23 -0
  65. package/dist/gui/components/ChatStatus.d.ts +4 -2
  66. package/dist/gui/components/ChatStatus.d.ts.map +1 -0
  67. package/dist/gui/components/ChatStatus.js +45 -34
  68. package/dist/gui/components/ChatStatus.js.map +1 -0
  69. package/dist/gui/components/ChatView.d.ts +8 -0
  70. package/dist/gui/components/ChatView.d.ts.map +1 -0
  71. package/dist/gui/components/ChatView.js +42 -0
  72. package/dist/gui/components/ChatView.js.map +1 -0
  73. package/dist/gui/components/ConfigPanel.d.ts +20 -0
  74. package/dist/gui/components/ConfigPanel.d.ts.map +1 -0
  75. package/dist/gui/components/ConfigPanel.js +225 -0
  76. package/dist/gui/components/ConfigPanel.js.map +1 -0
  77. package/dist/gui/components/Conversation.d.ts +17 -14
  78. package/dist/gui/components/Conversation.d.ts.map +1 -0
  79. package/dist/gui/components/Conversation.js +143 -83
  80. package/dist/gui/components/Conversation.js.map +1 -0
  81. package/dist/gui/components/Dialog.d.ts +57 -11
  82. package/dist/gui/components/Dialog.d.ts.map +1 -0
  83. package/dist/gui/components/Dialog.js +84 -8
  84. package/dist/gui/components/Dialog.js.map +1 -0
  85. package/dist/gui/components/DropdownMenu.d.ts +27 -0
  86. package/dist/gui/components/DropdownMenu.js +68 -0
  87. package/dist/gui/components/HeightTransition.d.ts +12 -7
  88. package/dist/gui/components/HeightTransition.d.ts.map +1 -0
  89. package/dist/gui/components/HeightTransition.js +88 -77
  90. package/dist/gui/components/HeightTransition.js.map +1 -0
  91. package/dist/gui/components/Input.d.ts +13 -6
  92. package/dist/gui/components/Input.d.ts.map +1 -0
  93. package/dist/gui/components/Input.js +27 -16
  94. package/dist/gui/components/Input.js.map +1 -0
  95. package/dist/gui/components/InputBox.d.ts +21 -0
  96. package/dist/gui/components/InputBox.d.ts.map +1 -0
  97. package/dist/gui/components/InputBox.js +90 -0
  98. package/dist/gui/components/InputBox.js.map +1 -0
  99. package/dist/gui/components/Label.d.ts +7 -1
  100. package/dist/gui/components/Label.d.ts.map +1 -0
  101. package/dist/gui/components/Label.js +12 -2
  102. package/dist/gui/components/Label.js.map +1 -0
  103. package/dist/gui/components/MarkdownRenderer.d.ts +6 -4
  104. package/dist/gui/components/MarkdownRenderer.d.ts.map +1 -0
  105. package/dist/gui/components/MarkdownRenderer.js +178 -81
  106. package/dist/gui/components/MarkdownRenderer.js.map +1 -0
  107. package/dist/gui/components/Message.d.ts +4 -0
  108. package/dist/gui/components/Message.d.ts.map +1 -0
  109. package/dist/gui/components/Message.js +77 -3
  110. package/dist/gui/components/Message.js.map +1 -0
  111. package/dist/gui/components/MessageContent.d.ts +29 -22
  112. package/dist/gui/components/MessageContent.d.ts.map +1 -0
  113. package/dist/gui/components/MessageContent.js +1 -1
  114. package/dist/gui/components/MessageContent.js.map +1 -0
  115. package/dist/gui/components/MessageList.d.ts.map +1 -0
  116. package/dist/gui/components/MessageList.js.map +1 -0
  117. package/dist/gui/components/PlaygroundLayout.d.ts +14 -0
  118. package/dist/gui/components/PlaygroundLayout.d.ts.map +1 -0
  119. package/dist/gui/components/PlaygroundLayout.js +49 -0
  120. package/dist/gui/components/PlaygroundLayout.js.map +1 -0
  121. package/dist/gui/components/Reasoning.d.ts +30 -24
  122. package/dist/gui/components/Reasoning.d.ts.map +1 -0
  123. package/dist/gui/components/Reasoning.js +187 -60
  124. package/dist/gui/components/Reasoning.js.map +1 -0
  125. package/dist/gui/components/Response.d.ts +11 -9
  126. package/dist/gui/components/Response.d.ts.map +1 -0
  127. package/dist/gui/components/Response.js +229 -90
  128. package/dist/gui/components/Response.js.map +1 -0
  129. package/dist/gui/components/Select.d.ts +69 -10
  130. package/dist/gui/components/Select.d.ts.map +1 -0
  131. package/dist/gui/components/Select.js +118 -12
  132. package/dist/gui/components/Select.js.map +1 -0
  133. package/dist/gui/components/Sonner.d.ts +5 -0
  134. package/dist/gui/components/Sonner.js +23 -0
  135. package/dist/gui/components/StatusBar.d.ts +12 -0
  136. package/dist/gui/components/StatusBar.d.ts.map +1 -0
  137. package/dist/gui/components/StatusBar.js +58 -0
  138. package/dist/gui/components/StatusBar.js.map +1 -0
  139. package/dist/gui/components/Tabs.d.ts +24 -4
  140. package/dist/gui/components/Tabs.d.ts.map +1 -0
  141. package/dist/gui/components/Tabs.js +32 -4
  142. package/dist/gui/components/Tabs.js.map +1 -0
  143. package/dist/gui/components/Task.d.ts +28 -24
  144. package/dist/gui/components/Task.d.ts.map +1 -0
  145. package/dist/gui/components/Task.js +164 -31
  146. package/dist/gui/components/Task.js.map +1 -0
  147. package/dist/gui/components/Textarea.d.ts +15 -7
  148. package/dist/gui/components/Textarea.d.ts.map +1 -0
  149. package/dist/gui/components/Textarea.js +63 -46
  150. package/dist/gui/components/Textarea.js.map +1 -0
  151. package/dist/gui/components/ThinkingBlock.d.ts +20 -10
  152. package/dist/gui/components/ThinkingBlock.d.ts.map +1 -0
  153. package/dist/gui/components/ThinkingBlock.js +134 -35
  154. package/dist/gui/components/ThinkingBlock.js.map +1 -0
  155. package/dist/gui/components/TodoList.d.ts +12 -10
  156. package/dist/gui/components/TodoList.d.ts.map +1 -0
  157. package/dist/gui/components/TodoList.js +22 -7
  158. package/dist/gui/components/TodoList.js.map +1 -0
  159. package/dist/gui/components/TodoListItem.d.ts +9 -6
  160. package/dist/gui/components/TodoListItem.d.ts.map +1 -0
  161. package/dist/gui/components/TodoListItem.js +18 -4
  162. package/dist/gui/components/TodoListItem.js.map +1 -0
  163. package/dist/gui/components/index.d.ts +9 -1
  164. package/dist/gui/components/index.d.ts.map +1 -0
  165. package/dist/gui/components/index.js +11 -1
  166. package/dist/gui/components/index.js.map +1 -0
  167. package/dist/gui/index.d.ts.map +1 -0
  168. package/dist/gui/index.js.map +1 -0
  169. package/dist/gui/lib/utils.d.ts.map +1 -0
  170. package/dist/gui/lib/utils.js +1 -1
  171. package/dist/gui/lib/utils.js.map +1 -0
  172. package/dist/index.d.ts.map +1 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/index.test.js +0 -1
  175. package/dist/sdk/client/acp-client.d.ts +88 -76
  176. package/dist/sdk/client/acp-client.d.ts.map +1 -0
  177. package/dist/sdk/client/acp-client.js +215 -217
  178. package/dist/sdk/client/acp-client.js.map +1 -0
  179. package/dist/sdk/client/index.d.ts.map +1 -0
  180. package/dist/sdk/client/index.js.map +1 -0
  181. package/dist/sdk/index.d.ts.map +1 -0
  182. package/dist/sdk/index.js.map +1 -0
  183. package/dist/sdk/schemas/agent.d.ts +111 -64
  184. package/dist/sdk/schemas/agent.d.ts.map +1 -0
  185. package/dist/sdk/schemas/agent.js +24 -24
  186. package/dist/sdk/schemas/agent.js.map +1 -0
  187. package/dist/sdk/schemas/index.d.ts.map +1 -0
  188. package/dist/sdk/schemas/index.js.map +1 -0
  189. package/dist/sdk/schemas/message.d.ts +245 -147
  190. package/dist/sdk/schemas/message.d.ts.map +1 -0
  191. package/dist/sdk/schemas/message.js +40 -40
  192. package/dist/sdk/schemas/message.js.map +1 -0
  193. package/dist/sdk/schemas/session.d.ts +219 -135
  194. package/dist/sdk/schemas/session.d.ts.map +1 -0
  195. package/dist/sdk/schemas/session.js +27 -27
  196. package/dist/sdk/schemas/session.js.map +1 -0
  197. package/dist/sdk/transports/http.d.ts +55 -55
  198. package/dist/sdk/transports/http.d.ts.map +1 -0
  199. package/dist/sdk/transports/http.js +472 -469
  200. package/dist/sdk/transports/http.js.map +1 -0
  201. package/dist/sdk/transports/index.d.ts.map +1 -0
  202. package/dist/sdk/transports/index.js.map +1 -0
  203. package/dist/sdk/transports/stdio.d.ts +20 -20
  204. package/dist/sdk/transports/stdio.d.ts.map +1 -0
  205. package/dist/sdk/transports/stdio.js.map +1 -0
  206. package/dist/sdk/transports/types.d.ts +42 -42
  207. package/dist/sdk/transports/types.d.ts.map +1 -0
  208. package/dist/sdk/transports/types.js.map +1 -0
  209. package/dist/sdk/transports/websocket.d.ts +12 -12
  210. package/dist/sdk/transports/websocket.d.ts.map +1 -0
  211. package/dist/sdk/transports/websocket.js +52 -46
  212. package/dist/sdk/transports/websocket.js.map +1 -0
  213. package/dist/tui/components/ChatView.d.ts +4 -2
  214. package/dist/tui/components/ChatView.d.ts.map +1 -0
  215. package/dist/tui/components/ChatView.js +51 -18
  216. package/dist/tui/components/ChatView.js.map +1 -0
  217. package/dist/tui/components/GameOfLife.d.ts.map +1 -0
  218. package/dist/tui/components/GameOfLife.js +64 -35
  219. package/dist/tui/components/GameOfLife.js.map +1 -0
  220. package/dist/tui/components/InputBox.d.ts +18 -11
  221. package/dist/tui/components/InputBox.d.ts.map +1 -0
  222. package/dist/tui/components/InputBox.js +70 -10
  223. package/dist/tui/components/InputBox.js.map +1 -0
  224. package/dist/tui/components/MessageList.d.ts +4 -2
  225. package/dist/tui/components/MessageList.d.ts.map +1 -0
  226. package/dist/tui/components/MessageList.js +37 -10
  227. package/dist/tui/components/MessageList.js.map +1 -0
  228. package/dist/tui/components/ReadlineInput.d.ts +12 -6
  229. package/dist/tui/components/ReadlineInput.d.ts.map +1 -0
  230. package/dist/tui/components/ReadlineInput.js +252 -237
  231. package/dist/tui/components/ReadlineInput.js.map +1 -0
  232. package/dist/tui/components/SingleSelect.d.ts +15 -9
  233. package/dist/tui/components/SingleSelect.js +84 -43
  234. package/dist/tui/components/StatusBar.d.ts +11 -6
  235. package/dist/tui/components/StatusBar.d.ts.map +1 -0
  236. package/dist/tui/components/StatusBar.js +102 -67
  237. package/dist/tui/components/StatusBar.js.map +1 -0
  238. package/dist/tui/components/index.d.ts.map +1 -0
  239. package/dist/tui/components/index.js.map +1 -0
  240. package/dist/tui/index.d.ts.map +1 -0
  241. package/dist/tui/index.js.map +1 -0
  242. package/package.json +6 -4
  243. package/src/styles/global.css +2 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatView.d.ts","sourceRoot":"","sources":["../../../src/gui/components/ChatView.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,EAAE,aAAa,2CAoCjD"}
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import {
3
+ useChatInput,
4
+ useChatMessages,
5
+ useChatSession,
6
+ } from "../../core/index.js";
7
+ import { InputBox } from "./InputBox.js";
8
+ import { MessageList } from "./MessageList.js";
9
+ import { StatusBar } from "./StatusBar.js";
10
+ export function ChatView({ client }) {
11
+ // Use headless hooks for business logic (same as TUI!)
12
+ const { connectionStatus, sessionId } = useChatSession(client);
13
+ const { messages, isStreaming } = useChatMessages(client);
14
+ const {
15
+ value,
16
+ isSubmitting,
17
+ attachedFiles,
18
+ onChange,
19
+ onSubmit,
20
+ onRemoveFile,
21
+ } = useChatInput(client);
22
+ return _jsxs("div", {
23
+ className: "flex flex-col h-screen bg-gray-50",
24
+ children: [
25
+ _jsx(StatusBar, {
26
+ connectionStatus: connectionStatus,
27
+ sessionId: sessionId,
28
+ isStreaming: isStreaming,
29
+ }),
30
+ _jsx(MessageList, { messages: messages }),
31
+ _jsx(InputBox, {
32
+ value: value,
33
+ isSubmitting: isSubmitting,
34
+ attachedFiles: attachedFiles,
35
+ onChange: onChange,
36
+ onSubmit: onSubmit,
37
+ onRemoveFile: onRemoveFile,
38
+ }),
39
+ ],
40
+ });
41
+ }
42
+ //# sourceMappingURL=ChatView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatView.js","sourceRoot":"","sources":["../../../src/gui/components/ChatView.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,GACb,MAAM,qBAAqB,CAAC;AAO7B,MAAM,UAAU,QAAQ,CAAC,EAAE,MAAM,EAAiB;IAChD,uDAAuD;IACvD,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC1D,MAAM,EACJ,KAAK,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,YAAY,GACb,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEzB,OAAO,CACL,eAAK,SAAS,EAAC,mCAAmC,aAEhD,KAAC,SAAS,IACR,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,GACxB,EAGF,KAAC,WAAW,IAAC,QAAQ,EAAE,QAAQ,GAAI,EAGnC,KAAC,QAAQ,IACP,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,GAC1B,IACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface ThemeConfig {
2
+ colorScheme: "light" | "dark";
3
+ accentColor: string;
4
+ typography: string;
5
+ fontSize: number;
6
+ thinkingDisplayStyle: "collapsible" | "inline";
7
+ }
8
+ interface ConfigPanelProps {
9
+ config: ThemeConfig;
10
+ status: string;
11
+ onConfigChange: (config: ThemeConfig) => void;
12
+ onStatusChange: (status: string) => void;
13
+ }
14
+ export declare function ConfigPanel({
15
+ config,
16
+ status,
17
+ onConfigChange,
18
+ onStatusChange,
19
+ }: ConfigPanelProps): import("react/jsx-runtime").JSX.Element;
20
+ //# sourceMappingURL=ConfigPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigPanel.d.ts","sourceRoot":"","sources":["../../../src/gui/components/ConfigPanel.tsx"],"names":[],"mappings":"AA4BA,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,aAAa,GAAG,QAAQ,CAAC;CAChD;AAED,UAAU,gBAAgB;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC9C,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1C;AAED,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,MAAM,EACN,cAAc,EACd,cAAc,GACf,EAAE,gBAAgB,2CA6JlB"}
@@ -0,0 +1,225 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Input } from "./Input.js";
3
+ import { Label } from "./Label.js";
4
+ import {
5
+ Select,
6
+ SelectContent,
7
+ SelectItem,
8
+ SelectTrigger,
9
+ SelectValue,
10
+ } from "./Select.js";
11
+
12
+ const fontOptions = [
13
+ "Inter",
14
+ "Arial",
15
+ "Georgia",
16
+ "Courier New",
17
+ "Times New Roman",
18
+ "Verdana",
19
+ ];
20
+ const statusOptions = [
21
+ "v0.1.0",
22
+ "Connected",
23
+ "Syncing...",
24
+ "Ready",
25
+ "Processing",
26
+ "Online",
27
+ ];
28
+ export function ConfigPanel({
29
+ config,
30
+ status,
31
+ onConfigChange,
32
+ onStatusChange,
33
+ }) {
34
+ const handleColorSchemeChange = (newScheme) => {
35
+ onConfigChange({ ...config, colorScheme: newScheme });
36
+ };
37
+ const handleAccentColorChange = (e) => {
38
+ const newColor = e.target.value;
39
+ onConfigChange({ ...config, accentColor: newColor });
40
+ };
41
+ const handleTypographyChange = (newTypography) => {
42
+ onConfigChange({ ...config, typography: newTypography });
43
+ };
44
+ const handleFontSizeChange = (e) => {
45
+ const newSize = parseInt(e.target.value, 10);
46
+ if (!isNaN(newSize) && newSize > 0) {
47
+ onConfigChange({ ...config, fontSize: newSize });
48
+ }
49
+ };
50
+ const handleThinkingDisplayStyleChange = (newStyle) => {
51
+ onConfigChange({ ...config, thinkingDisplayStyle: newStyle });
52
+ };
53
+ const handleStatusChange = () => {
54
+ const currentIndex = statusOptions.indexOf(status);
55
+ const nextIndex = (currentIndex + 1) % statusOptions.length;
56
+ onStatusChange(statusOptions[nextIndex]);
57
+ };
58
+ return _jsxs("div", {
59
+ className:
60
+ "h-full p-6 bg-[var(--color-surface)] border-r border-[var(--color-border)] overflow-y-auto",
61
+ children: [
62
+ _jsx("h2", {
63
+ className: "text-2xl font-semibold mb-8 m-0 text-[var(--color-text)]",
64
+ children: "Design Configuration",
65
+ }),
66
+ _jsxs("div", {
67
+ className: "mb-6",
68
+ children: [
69
+ _jsx(Label, {
70
+ htmlFor: "color-scheme",
71
+ className: "mb-2 text-[var(--color-text)]",
72
+ children: "Color Scheme",
73
+ }),
74
+ _jsxs(Select, {
75
+ value: config.colorScheme,
76
+ onValueChange: handleColorSchemeChange,
77
+ children: [
78
+ _jsx(SelectTrigger, {
79
+ id: "color-scheme",
80
+ className:
81
+ "w-full bg-[var(--color-bg)] text-[var(--color-text)] border-[var(--color-border)] focus:border-[var(--color-accent)]",
82
+ children: _jsx(SelectValue, {}),
83
+ }),
84
+ _jsxs(SelectContent, {
85
+ className: "bg-[var(--color-bg)] border-[var(--color-border)]",
86
+ children: [
87
+ _jsx(SelectItem, { value: "light", children: "Light" }),
88
+ _jsx(SelectItem, { value: "dark", children: "Dark" }),
89
+ ],
90
+ }),
91
+ ],
92
+ }),
93
+ ],
94
+ }),
95
+ _jsxs("div", {
96
+ className: "mb-6",
97
+ children: [
98
+ _jsx(Label, {
99
+ htmlFor: "accent-color",
100
+ className: "mb-2 text-[var(--color-text)]",
101
+ children: "Accent Color",
102
+ }),
103
+ _jsxs("div", {
104
+ className: "flex gap-2 items-center",
105
+ children: [
106
+ _jsx("input", {
107
+ type: "color",
108
+ id: "accent-color",
109
+ value: config.accentColor,
110
+ onChange: handleAccentColorChange,
111
+ className:
112
+ "w-[60px] h-10 border border-[var(--color-border)] rounded-md cursor-pointer bg-transparent",
113
+ }),
114
+ _jsx(Input, {
115
+ type: "text",
116
+ value: config.accentColor,
117
+ onChange: handleAccentColorChange,
118
+ pattern: "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",
119
+ className:
120
+ "flex-1 bg-[var(--color-bg)] text-[var(--color-text)] border-[var(--color-border)] focus:border-[var(--color-accent)]",
121
+ }),
122
+ ],
123
+ }),
124
+ ],
125
+ }),
126
+ _jsxs("div", {
127
+ className: "mb-6",
128
+ children: [
129
+ _jsx(Label, {
130
+ htmlFor: "typography",
131
+ className: "mb-2 text-[var(--color-text)]",
132
+ children: "Typography",
133
+ }),
134
+ _jsxs(Select, {
135
+ value: config.typography,
136
+ onValueChange: handleTypographyChange,
137
+ children: [
138
+ _jsx(SelectTrigger, {
139
+ id: "typography",
140
+ className:
141
+ "w-full bg-[var(--color-bg)] text-[var(--color-text)] border-[var(--color-border)] focus:border-[var(--color-accent)]",
142
+ children: _jsx(SelectValue, {}),
143
+ }),
144
+ _jsx(SelectContent, {
145
+ className: "bg-[var(--color-bg)] border-[var(--color-border)]",
146
+ children: fontOptions.map((font) =>
147
+ _jsx(SelectItem, { value: font, children: font }, font),
148
+ ),
149
+ }),
150
+ ],
151
+ }),
152
+ ],
153
+ }),
154
+ _jsxs("div", {
155
+ className: "mb-6",
156
+ children: [
157
+ _jsx(Label, {
158
+ htmlFor: "font-size",
159
+ className: "mb-2 text-[var(--color-text)]",
160
+ children: "Font Size (px)",
161
+ }),
162
+ _jsx(Input, {
163
+ type: "number",
164
+ id: "font-size",
165
+ value: config.fontSize,
166
+ onChange: handleFontSizeChange,
167
+ min: "8",
168
+ max: "32",
169
+ className:
170
+ "w-full bg-[var(--color-bg)] text-[var(--color-text)] border-[var(--color-border)] focus:border-[var(--color-accent)]",
171
+ }),
172
+ ],
173
+ }),
174
+ _jsxs("div", {
175
+ className: "mb-6",
176
+ children: [
177
+ _jsx(Label, {
178
+ htmlFor: "thinking-display-style",
179
+ className: "mb-2 text-[var(--color-text)]",
180
+ children: "Thinking Display Style",
181
+ }),
182
+ _jsxs(Select, {
183
+ value: config.thinkingDisplayStyle || "collapsible",
184
+ onValueChange: handleThinkingDisplayStyleChange,
185
+ children: [
186
+ _jsx(SelectTrigger, {
187
+ id: "thinking-display-style",
188
+ className:
189
+ "w-full bg-[var(--color-bg)] text-[var(--color-text)] border-[var(--color-border)] focus:border-[var(--color-accent)]",
190
+ children: _jsx(SelectValue, {}),
191
+ }),
192
+ _jsxs(SelectContent, {
193
+ className: "bg-[var(--color-bg)] border-[var(--color-border)]",
194
+ children: [
195
+ _jsx(SelectItem, {
196
+ value: "collapsible",
197
+ children: "Collapsible Section",
198
+ }),
199
+ _jsx(SelectItem, { value: "inline", children: "Inline" }),
200
+ ],
201
+ }),
202
+ ],
203
+ }),
204
+ ],
205
+ }),
206
+ _jsxs("div", {
207
+ className: "mb-6",
208
+ children: [
209
+ _jsx(Label, {
210
+ htmlFor: "status-test",
211
+ className: "mb-2 text-[var(--color-text)]",
212
+ children: "Chat Status",
213
+ }),
214
+ _jsxs("button", {
215
+ onClick: handleStatusChange,
216
+ className:
217
+ "w-full px-4 py-2 rounded-lg bg-[var(--color-accent)] text-white font-medium hover:opacity-90 transition-opacity text-[var(--font-size)] font-[var(--font-family)]",
218
+ children: ["Change Status: ", status],
219
+ }),
220
+ ],
221
+ }),
222
+ ],
223
+ });
224
+ }
225
+ //# sourceMappingURL=ConfigPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigPanel.js","sourceRoot":"","sources":["../../../src/gui/components/ConfigPanel.tsx"],"names":[],"mappings":"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"}
@@ -3,18 +3,21 @@ import * as React from "react";
3
3
  * Conversation component inspired by shadcn.io/ai
4
4
  * Auto-scrolling chat container that maintains scroll position during streaming
5
5
  */
6
- export interface ConversationProps extends React.HTMLAttributes<HTMLDivElement> {
7
- /** Whether to auto-scroll to bottom on new messages */
8
- autoScroll?: boolean;
9
- /** Whether content is currently streaming */
10
- isStreaming?: boolean;
11
- /** Scroll behavior type */
12
- scrollBehavior?: ScrollBehavior;
13
- /** Threshold for considering user at bottom (px from bottom) */
14
- scrollThreshold?: number;
15
- /** Show scroll-to-bottom button when not at bottom */
16
- showScrollButton?: boolean;
17
- /** Custom scroll button */
18
- scrollButton?: React.ReactNode;
6
+ export interface ConversationProps
7
+ extends React.HTMLAttributes<HTMLDivElement> {
8
+ /** Whether to auto-scroll to bottom on new messages */
9
+ autoScroll?: boolean;
10
+ /** Whether content is currently streaming */
11
+ isStreaming?: boolean;
12
+ /** Scroll behavior type */
13
+ scrollBehavior?: ScrollBehavior;
14
+ /** Threshold for considering user at bottom (px from bottom) */
15
+ scrollThreshold?: number;
16
+ /** Show scroll-to-bottom button when not at bottom */
17
+ showScrollButton?: boolean;
18
+ /** Custom scroll button */
19
+ scrollButton?: React.ReactNode;
19
20
  }
20
- export declare const Conversation: React.ForwardRefExoticComponent<ConversationProps & React.RefAttributes<HTMLDivElement>>;
21
+ export declare const Conversation: React.ForwardRefExoticComponent<
22
+ ConversationProps & React.RefAttributes<HTMLDivElement>
23
+ >;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conversation.d.ts","sourceRoot":"","sources":["../../../src/gui/components/Conversation.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;GAGG;AAEH,MAAM,WAAW,iBACf,SAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;IAC5C,uDAAuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,2BAA2B;IAC3B,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAChC;AAED,eAAO,MAAM,YAAY,0FAsJxB,CAAC"}
@@ -1,87 +1,147 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
1
  import * as React from "react";
3
2
  import { useCallback, useEffect, useRef, useState } from "react";
3
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
4
  import { cn } from "../lib/utils.js";
5
- export const Conversation = React.forwardRef(({ autoScroll = true, isStreaming = false, scrollBehavior = "smooth", scrollThreshold = 100, showScrollButton = true, scrollButton, className, children, ...props }, ref) => {
6
- const containerRef = useRef(null);
7
- const [isNearBottom, setIsNearBottom] = useState(true);
8
- const [showButton, setShowButton] = useState(false);
9
- const lastScrollTopRef = useRef(0);
10
- // Combine refs
11
- React.useImperativeHandle(ref, () => {
12
- if (!containerRef.current) {
13
- throw new Error("Container ref not initialized");
14
- }
15
- return containerRef.current;
16
- });
17
- // Check if user is near bottom of scroll area
18
- const checkScrollPosition = useCallback(() => {
19
- const container = containerRef.current;
20
- if (!container)
21
- return;
22
- const { scrollTop, scrollHeight, clientHeight } = container;
23
- const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
24
- const nearBottom = distanceFromBottom < scrollThreshold;
25
- setIsNearBottom(nearBottom);
26
- setShowButton(!nearBottom && showScrollButton);
27
- lastScrollTopRef.current = scrollTop;
28
- }, [scrollThreshold, showScrollButton]);
29
- // Scroll to bottom
30
- const scrollToBottom = useCallback((behavior = scrollBehavior) => {
31
- const container = containerRef.current;
32
- if (!container)
33
- return;
34
- container.scrollTo({
35
- top: container.scrollHeight,
36
- behavior,
37
- });
38
- }, [scrollBehavior]);
39
- // Auto-scroll when new content appears and user is near bottom
40
- useEffect(() => {
41
- if (!autoScroll)
42
- return;
43
- const container = containerRef.current;
44
- if (!container)
45
- return;
46
- // Always scroll during streaming if user is near bottom
47
- if (isStreaming && isNearBottom) {
48
- scrollToBottom("auto");
49
- }
50
- // Scroll on new messages if near bottom
51
- else if (!isStreaming && isNearBottom) {
52
- scrollToBottom();
53
- }
54
- }, [autoScroll, isStreaming, isNearBottom, scrollToBottom]);
55
- // Set up scroll listener
56
- useEffect(() => {
57
- const container = containerRef.current;
58
- if (!container)
59
- return;
60
- const handleScroll = () => {
61
- checkScrollPosition();
62
- };
63
- container.addEventListener("scroll", handleScroll, { passive: true });
64
- // Check initial position
65
- checkScrollPosition();
66
- return () => {
67
- container.removeEventListener("scroll", handleScroll);
68
- };
69
- }, [checkScrollPosition]);
70
- // Watch for resize events
71
- useEffect(() => {
72
- const container = containerRef.current;
73
- if (!container)
74
- return;
75
- const resizeObserver = new ResizeObserver(() => {
76
- if (isNearBottom && autoScroll) {
77
- scrollToBottom("auto");
78
- }
79
- });
80
- resizeObserver.observe(container);
81
- return () => {
82
- resizeObserver.disconnect();
83
- };
84
- }, [isNearBottom, autoScroll, scrollToBottom]);
85
- return (_jsxs("div", { className: "relative flex-1", children: [_jsx("div", { ref: containerRef, className: cn("h-full overflow-y-auto overflow-x-hidden", "scrollbar-thin scrollbar-thumb-[border] scrollbar-track-transparent", className), ...props, children: _jsx("div", { className: "flex flex-col gap-4 px-4 py-4", children: children }) }), showButton && (_jsx("div", { className: "absolute bottom-4 left-1/2 -translate-x-1/2 z-10", children: scrollButton || (_jsxs("button", { type: "button", onClick: () => scrollToBottom(), className: "px-4 py-2 rounded-full bg-card border border-border shadow-lg hover:shadow-xl hover:bg-card/90 transition-all text-sm font-medium text-foreground flex items-center gap-2", "aria-label": "Scroll to bottom", children: [_jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", role: "img", "aria-label": "Down arrow", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 14l-7 7m0 0l-7-7m7 7V3" }) }), "Scroll to bottom"] })) }))] }));
86
- });
5
+ export const Conversation = React.forwardRef(
6
+ (
7
+ {
8
+ autoScroll = true,
9
+ isStreaming = false,
10
+ scrollBehavior = "smooth",
11
+ scrollThreshold = 100,
12
+ showScrollButton = true,
13
+ scrollButton,
14
+ className,
15
+ children,
16
+ ...props
17
+ },
18
+ ref,
19
+ ) => {
20
+ const containerRef = useRef(null);
21
+ const [isNearBottom, setIsNearBottom] = useState(true);
22
+ const [showButton, setShowButton] = useState(false);
23
+ const lastScrollTopRef = useRef(0);
24
+ // Combine refs
25
+ React.useImperativeHandle(ref, () => {
26
+ if (!containerRef.current) {
27
+ throw new Error("Container ref not initialized");
28
+ }
29
+ return containerRef.current;
30
+ });
31
+ // Check if user is near bottom of scroll area
32
+ const checkScrollPosition = useCallback(() => {
33
+ const container = containerRef.current;
34
+ if (!container) return;
35
+ const { scrollTop, scrollHeight, clientHeight } = container;
36
+ const distanceFromBottom = scrollHeight - scrollTop - clientHeight;
37
+ const nearBottom = distanceFromBottom < scrollThreshold;
38
+ setIsNearBottom(nearBottom);
39
+ setShowButton(!nearBottom && showScrollButton);
40
+ lastScrollTopRef.current = scrollTop;
41
+ }, [scrollThreshold, showScrollButton]);
42
+ // Scroll to bottom
43
+ const scrollToBottom = useCallback(
44
+ (behavior = scrollBehavior) => {
45
+ const container = containerRef.current;
46
+ if (!container) return;
47
+ container.scrollTo({
48
+ top: container.scrollHeight,
49
+ behavior,
50
+ });
51
+ },
52
+ [scrollBehavior],
53
+ );
54
+ // Auto-scroll when new content appears and user is near bottom
55
+ useEffect(() => {
56
+ if (!autoScroll) return;
57
+ const container = containerRef.current;
58
+ if (!container) return;
59
+ // Always scroll during streaming if user is near bottom
60
+ if (isStreaming && isNearBottom) {
61
+ scrollToBottom("auto");
62
+ }
63
+ // Scroll on new messages if near bottom
64
+ else if (!isStreaming && isNearBottom) {
65
+ scrollToBottom();
66
+ }
67
+ }, [autoScroll, isStreaming, isNearBottom, scrollToBottom]);
68
+ // Set up scroll listener
69
+ useEffect(() => {
70
+ const container = containerRef.current;
71
+ if (!container) return;
72
+ const handleScroll = () => {
73
+ checkScrollPosition();
74
+ };
75
+ container.addEventListener("scroll", handleScroll, { passive: true });
76
+ // Check initial position
77
+ checkScrollPosition();
78
+ return () => {
79
+ container.removeEventListener("scroll", handleScroll);
80
+ };
81
+ }, [checkScrollPosition]);
82
+ // Watch for resize events
83
+ useEffect(() => {
84
+ const container = containerRef.current;
85
+ if (!container) return;
86
+ const resizeObserver = new ResizeObserver(() => {
87
+ if (isNearBottom && autoScroll) {
88
+ scrollToBottom("auto");
89
+ }
90
+ });
91
+ resizeObserver.observe(container);
92
+ return () => {
93
+ resizeObserver.disconnect();
94
+ };
95
+ }, [isNearBottom, autoScroll, scrollToBottom]);
96
+ return _jsxs("div", {
97
+ className: "relative flex-1",
98
+ children: [
99
+ _jsx("div", {
100
+ ref: containerRef,
101
+ className: cn(
102
+ "h-full overflow-y-auto overflow-x-hidden",
103
+ "scrollbar-thin scrollbar-thumb-[border] scrollbar-track-transparent",
104
+ className,
105
+ ),
106
+ ...props,
107
+ children: _jsx("div", {
108
+ className: "flex flex-col gap-4 px-4 py-4",
109
+ children: children,
110
+ }),
111
+ }),
112
+ showButton &&
113
+ _jsx("div", {
114
+ className: "absolute bottom-4 left-1/2 -translate-x-1/2 z-10",
115
+ children:
116
+ scrollButton ||
117
+ _jsxs("button", {
118
+ type: "button",
119
+ onClick: () => scrollToBottom(),
120
+ className:
121
+ "px-4 py-2 rounded-full bg-card border border-border shadow-lg hover:shadow-xl hover:bg-card/90 transition-all text-sm font-medium text-foreground flex items-center gap-2",
122
+ "aria-label": "Scroll to bottom",
123
+ children: [
124
+ _jsx("svg", {
125
+ className: "w-4 h-4",
126
+ fill: "none",
127
+ stroke: "currentColor",
128
+ viewBox: "0 0 24 24",
129
+ xmlns: "http://www.w3.org/2000/svg",
130
+ role: "img",
131
+ "aria-label": "Down arrow",
132
+ children: _jsx("path", {
133
+ strokeLinecap: "round",
134
+ strokeLinejoin: "round",
135
+ strokeWidth: 2,
136
+ d: "M19 14l-7 7m0 0l-7-7m7 7V3",
137
+ }),
138
+ }),
139
+ "Scroll to bottom",
140
+ ],
141
+ }),
142
+ }),
143
+ ],
144
+ });
145
+ },
146
+ );
87
147
  Conversation.displayName = "Conversation";
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conversation.js","sourceRoot":"","sources":["../../../src/gui/components/Conversation.tsx"],"names":[],"mappings":"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"}