@dyyz1993/create-agent 2.1.0 → 2.1.2

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 (349) hide show
  1. package/package.json +5 -4
  2. package/src/__tests__/cli.test.ts +2 -0
  3. package/src/__tests__/copy.test.ts +110 -122
  4. package/src/__tests__/create-args.test.ts +113 -0
  5. package/src/__tests__/templates.test.ts +29 -3
  6. package/src/__tests__/update.test.ts +129 -0
  7. package/src/cli.ts +30 -32
  8. package/src/commands/create.ts +83 -24
  9. package/src/commands/update.ts +174 -0
  10. package/src/commands/workspace.ts +26 -6
  11. package/src/lib/copy.ts +233 -93
  12. package/src/lib/templates.ts +12 -0
  13. package/templates/agent/.husky/commit-msg +4 -0
  14. package/templates/agent/.husky/pre-commit +11 -0
  15. package/templates/agent/.husky/pre-push +6 -0
  16. package/templates/agent/.prettierignore +6 -0
  17. package/templates/agent/.prettierrc +9 -0
  18. package/templates/agent/CHANGELOG.md +15 -0
  19. package/templates/agent/commitlint.config.js +8 -0
  20. package/templates/agent/package.json +19 -4
  21. package/templates/agent/src/gateway/__tests__/ws-handler-token.test.ts +53 -39
  22. package/templates/agent/src/mainview/App.tsx +14 -12
  23. package/templates/agent/src/mainview/__tests__/hooks/use-rpc-init.test.ts +194 -190
  24. package/templates/agent/src/mainview/components/bash/BashPanel.tsx +210 -189
  25. package/templates/agent/src/mainview/components/chat/ChatPanel.tsx +45 -20
  26. package/templates/agent/src/mainview/components/common/ThemeToggle.tsx +41 -21
  27. package/templates/agent/src/mainview/components/debug/DebugPanel.tsx +181 -114
  28. package/templates/agent/src/mainview/components/debug/__tests__/DebugPanel.test.tsx +80 -80
  29. package/templates/agent/src/mainview/components/diff/__tests__/DiffViewerPanel.test.tsx +61 -58
  30. package/templates/agent/src/mainview/components/feed/FeedPanel.tsx +43 -41
  31. package/templates/agent/src/mainview/components/file-preview/FilePreviewOverlay.tsx +69 -50
  32. package/templates/agent/src/mainview/components/file-preview/VirtualizedCodeView.tsx +31 -18
  33. package/templates/agent/src/mainview/components/git/GitPanel.tsx +731 -490
  34. package/templates/agent/src/mainview/components/git/__tests__/GitPanel.test.tsx +157 -139
  35. package/templates/agent/src/mainview/components/layout/AppLayout.tsx +210 -161
  36. package/templates/agent/src/mainview/components/layout/__tests__/AppLayout.test.tsx +130 -122
  37. package/templates/agent/src/mainview/components/rules/RulesPanel.tsx +119 -109
  38. package/templates/agent/src/mainview/components/search/SearchPanel.tsx +123 -117
  39. package/templates/agent/src/mainview/components/search/__tests__/SearchPanel.test.tsx +64 -44
  40. package/templates/agent/src/mainview/components/sidebar/__tests__/PinButton.test.tsx +38 -38
  41. package/templates/agent/src/mainview/components/todo/TodoPanel.tsx +40 -38
  42. package/templates/agent/src/mainview/components/todo/__tests__/TodoPanel.test.tsx +72 -72
  43. package/templates/agent/src/mainview/lib/i18n/locales/en.json +175 -155
  44. package/templates/agent/src/mainview/lib/i18n/locales/zh.json +173 -155
  45. package/templates/agent/src/mainview/stores/use-app-store.ts +96 -86
  46. package/templates/agent/src/mainview/stores/use-explorer-store.ts +292 -275
  47. package/templates/agent/src/mainview/types/index.ts +23 -22
  48. package/templates/agent/src/mainview/utils/file-icon.tsx +17 -21
  49. package/templates/agent/src/shared/handlers/chat.ts +53 -53
  50. package/templates/agent/src/shared/handlers/debug.ts +13 -3
  51. package/templates/browser-agent/.env.example +19 -0
  52. package/templates/browser-agent/.husky/commit-msg +4 -0
  53. package/templates/browser-agent/.husky/pre-commit +11 -0
  54. package/templates/browser-agent/.husky/pre-push +6 -0
  55. package/templates/browser-agent/.prettierignore +6 -0
  56. package/templates/browser-agent/.prettierrc +9 -0
  57. package/templates/browser-agent/AGENTS.md +396 -0
  58. package/templates/browser-agent/CHANGELOG.md +15 -0
  59. package/templates/browser-agent/LICENSE +21 -0
  60. package/templates/browser-agent/README.md +103 -0
  61. package/templates/browser-agent/commitlint.config.js +8 -0
  62. package/templates/browser-agent/electrobun.config.ts +27 -0
  63. package/templates/browser-agent/electron/main.js +46 -0
  64. package/templates/browser-agent/electron/preload.js +5 -0
  65. package/templates/browser-agent/electron-builder.json +40 -0
  66. package/templates/browser-agent/eslint.config.mjs +79 -0
  67. package/templates/browser-agent/llms.txt +24 -0
  68. package/templates/browser-agent/package.json +140 -0
  69. package/templates/browser-agent/postcss.config.js +6 -0
  70. package/templates/browser-agent/scripts/dev.ts +138 -0
  71. package/templates/browser-agent/src/__tests__/hybrid-mode.test.ts +126 -0
  72. package/templates/browser-agent/src/__tests__/server-config-security.test.ts +55 -0
  73. package/templates/browser-agent/src/__tests__/server-config.test.ts +59 -0
  74. package/templates/browser-agent/src/bun/index.ts +130 -0
  75. package/templates/browser-agent/src/bun/three.d.ts +1 -0
  76. package/templates/browser-agent/src/gateway/http-routes.ts +1 -0
  77. package/templates/browser-agent/src/gateway/ipc-transport.ts +68 -0
  78. package/templates/browser-agent/src/gateway/sse-transport.ts +221 -0
  79. package/templates/browser-agent/src/mainview/App.tsx +45 -0
  80. package/templates/browser-agent/src/mainview/__tests__/hooks/use-rpc-init.test.ts +202 -0
  81. package/templates/browser-agent/src/mainview/__tests__/hooks/use-sidebar-resize.test.ts +127 -0
  82. package/templates/browser-agent/src/mainview/__tests__/i18n/i18n.test.ts +49 -0
  83. package/templates/browser-agent/src/mainview/__tests__/setup.ts +40 -0
  84. package/templates/browser-agent/src/mainview/__tests__/stores/use-chat-store.test.ts +73 -0
  85. package/templates/browser-agent/src/mainview/__tests__/stores/use-sidebar-store.test.ts +61 -0
  86. package/templates/browser-agent/src/mainview/__tests__/theme-variables.test.ts +36 -0
  87. package/templates/browser-agent/src/mainview/components/assets/AssetsPanel.tsx +139 -0
  88. package/templates/browser-agent/src/mainview/components/chat/ChatPanel.tsx +219 -0
  89. package/templates/browser-agent/src/mainview/components/chat/CommandBar.tsx +184 -0
  90. package/templates/browser-agent/src/mainview/components/chat/MessageBubble.tsx +249 -0
  91. package/templates/browser-agent/src/mainview/components/chat/ToolPicker.tsx +115 -0
  92. package/templates/browser-agent/src/mainview/components/common/ErrorBoundary.tsx +1 -0
  93. package/templates/browser-agent/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
  94. package/templates/browser-agent/src/mainview/components/common/ThemeToggle.tsx +45 -0
  95. package/templates/browser-agent/src/mainview/components/common/__tests__/ErrorBoundary.test.tsx +74 -0
  96. package/templates/browser-agent/src/mainview/components/common/__tests__/LanguageSwitcher.test.tsx +44 -0
  97. package/templates/browser-agent/src/mainview/components/common/__tests__/ThemeToggle.test.tsx +41 -0
  98. package/templates/browser-agent/src/mainview/components/dev/NetworkPanel.tsx +155 -0
  99. package/templates/browser-agent/src/mainview/components/layout/AppLayout.tsx +311 -0
  100. package/templates/browser-agent/src/mainview/components/onboarding/SetupWizard.tsx +310 -0
  101. package/templates/browser-agent/src/mainview/components/process/ProcessPanel.tsx +329 -0
  102. package/templates/browser-agent/src/mainview/components/sidebar/SessionSidebar.tsx +122 -0
  103. package/templates/browser-agent/src/mainview/components/sidebar/SkillSidebar.tsx +115 -0
  104. package/templates/browser-agent/src/mainview/components/topbar/TopBar.tsx +350 -0
  105. package/templates/browser-agent/src/mainview/global.d.ts +13 -0
  106. package/templates/browser-agent/src/mainview/hooks/__tests__/use-breakpoint.test.ts +151 -0
  107. package/templates/browser-agent/src/mainview/hooks/use-agent-chat.ts +157 -0
  108. package/templates/browser-agent/src/mainview/hooks/use-breakpoint.ts +68 -0
  109. package/templates/browser-agent/src/mainview/hooks/use-rpc-init.ts +71 -0
  110. package/templates/browser-agent/src/mainview/hooks/use-sidebar-resize.ts +40 -0
  111. package/templates/browser-agent/src/mainview/index.css +71 -0
  112. package/templates/browser-agent/src/mainview/index.html +12 -0
  113. package/templates/browser-agent/src/mainview/lib/api-client.ts +397 -0
  114. package/templates/browser-agent/src/mainview/lib/i18n/index.ts +30 -0
  115. package/templates/browser-agent/src/mainview/lib/i18n/locales/en.json +130 -0
  116. package/templates/browser-agent/src/mainview/lib/i18n/locales/zh.json +128 -0
  117. package/templates/browser-agent/src/mainview/lib/network-bus.ts +92 -0
  118. package/templates/browser-agent/src/mainview/lib/rpc-cache.ts +94 -0
  119. package/templates/browser-agent/src/mainview/main.tsx +18 -0
  120. package/templates/browser-agent/src/mainview/stores/__tests__/use-connection-store.test.ts +26 -0
  121. package/templates/browser-agent/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  122. package/templates/browser-agent/src/mainview/stores/__tests__/use-log-store.test.ts +28 -0
  123. package/templates/browser-agent/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  124. package/templates/browser-agent/src/mainview/stores/message-batcher.ts +25 -0
  125. package/templates/browser-agent/src/mainview/stores/use-asset-store.ts +65 -0
  126. package/templates/browser-agent/src/mainview/stores/use-chat-store.ts +200 -0
  127. package/templates/browser-agent/src/mainview/stores/use-connection-store.ts +173 -0
  128. package/templates/browser-agent/src/mainview/stores/use-locale-store.ts +27 -0
  129. package/templates/browser-agent/src/mainview/stores/use-log-store.ts +16 -0
  130. package/templates/browser-agent/src/mainview/stores/use-network-panel-store.ts +18 -0
  131. package/templates/browser-agent/src/mainview/stores/use-record-store.ts +147 -0
  132. package/templates/browser-agent/src/mainview/stores/use-session-store.ts +151 -0
  133. package/templates/browser-agent/src/mainview/stores/use-sidebar-store.ts +161 -0
  134. package/templates/browser-agent/src/mainview/stores/use-theme-store.ts +46 -0
  135. package/templates/browser-agent/src/mainview/stores/use-view-store.ts +20 -0
  136. package/templates/browser-agent/src/mainview/types/index.ts +6 -0
  137. package/templates/browser-agent/src/server-config.ts +45 -0
  138. package/templates/browser-agent/src/server.ts +78 -0
  139. package/templates/browser-agent/src/shared/handlers/__tests__/chat-concurrency.test.ts +127 -0
  140. package/templates/browser-agent/src/shared/handlers/__tests__/chat-handler.test.ts +77 -0
  141. package/templates/browser-agent/src/shared/handlers/__tests__/file-handler.test.ts +100 -0
  142. package/templates/browser-agent/src/shared/handlers/__tests__/system-handler.test.ts +55 -0
  143. package/templates/browser-agent/src/shared/handlers/__tests__/timer-handler.test.ts +77 -0
  144. package/templates/browser-agent/src/shared/handlers/browser.ts +596 -0
  145. package/templates/browser-agent/src/shared/handlers/chat.ts +213 -0
  146. package/templates/browser-agent/src/shared/handlers/file.ts +99 -0
  147. package/templates/browser-agent/src/shared/handlers/index.ts +7 -0
  148. package/templates/browser-agent/src/shared/handlers/session.ts +167 -0
  149. package/templates/browser-agent/src/shared/handlers/system.ts +27 -0
  150. package/templates/browser-agent/src/shared/handlers/timer.ts +34 -0
  151. package/templates/browser-agent/src/shared/http-routes.ts +437 -0
  152. package/templates/browser-agent/src/shared/lib/__tests__/logger.test.ts +92 -0
  153. package/templates/browser-agent/src/shared/lib/__tests__/path-security.test.ts +77 -0
  154. package/templates/browser-agent/src/shared/lib/__tests__/web-server.test.ts +203 -0
  155. package/templates/browser-agent/src/shared/lib/agent.ts +384 -0
  156. package/templates/browser-agent/src/shared/lib/cdp.ts +448 -0
  157. package/templates/browser-agent/src/shared/lib/generate.ts +111 -0
  158. package/templates/browser-agent/src/shared/lib/logger.ts +152 -0
  159. package/templates/browser-agent/src/shared/lib/mock-stream.ts +147 -0
  160. package/templates/browser-agent/src/shared/lib/path-security.ts +38 -0
  161. package/templates/browser-agent/src/shared/lib/port-registry.ts +103 -0
  162. package/templates/browser-agent/src/shared/lib/web-server.ts +127 -0
  163. package/templates/browser-agent/src/shared/lib/xhs-extract.ts +71 -0
  164. package/templates/browser-agent/src/shared/modules/browser.ts +86 -0
  165. package/templates/browser-agent/src/shared/modules/chat.ts +20 -0
  166. package/templates/browser-agent/src/shared/modules/file.ts +40 -0
  167. package/templates/browser-agent/src/shared/modules/session.ts +55 -0
  168. package/templates/browser-agent/src/shared/modules/system.ts +8 -0
  169. package/templates/browser-agent/src/shared/modules/timer.ts +11 -0
  170. package/templates/browser-agent/src/shared/register-all-handlers.ts +36 -0
  171. package/templates/browser-agent/src/shared/rpc-schema.ts +34 -0
  172. package/templates/browser-agent/tailwind.config.js +15 -0
  173. package/templates/browser-agent/tsconfig.ipc.json +14 -0
  174. package/templates/browser-agent/tsconfig.json +36 -0
  175. package/templates/browser-agent/vite.config.ts +3 -0
  176. package/templates/browser-agent/vitest.config.ts +3 -0
  177. package/templates/chat/.husky/commit-msg +4 -0
  178. package/templates/chat/.husky/pre-commit +11 -0
  179. package/templates/chat/.husky/pre-push +6 -0
  180. package/templates/chat/CHANGELOG.md +15 -0
  181. package/templates/chat/commitlint.config.js +8 -0
  182. package/templates/chat/package.json +19 -4
  183. package/templates/chat/src/mainview/__tests__/hooks/use-input-history.test.ts +125 -0
  184. package/templates/chat/src/mainview/__tests__/setup.ts +32 -29
  185. package/templates/chat/src/mainview/components/chat/ChatPanel.tsx +80 -55
  186. package/templates/chat/src/mainview/components/common/ThemeToggle.tsx +40 -20
  187. package/templates/chat/src/mainview/lib/i18n/locales/en.json +175 -155
  188. package/templates/chat/src/mainview/lib/i18n/locales/zh.json +173 -155
  189. package/templates/chat/src/shared/handlers/chat.ts +17 -19
  190. package/templates/chat/src/shared/handlers/debug.ts +12 -2
  191. package/templates/cowork/.env.example +8 -0
  192. package/templates/cowork/.prettierignore +6 -0
  193. package/templates/cowork/.prettierrc +9 -0
  194. package/templates/cowork/AGENTS.md +236 -0
  195. package/templates/cowork/CHANGELOG.md +15 -0
  196. package/templates/cowork/LICENSE +21 -0
  197. package/templates/cowork/README.md +103 -0
  198. package/templates/cowork/commitlint.config.js +8 -0
  199. package/templates/cowork/docs/CODE-VIEW-PLAN.md +637 -0
  200. package/templates/cowork/docs/CODE-VIEW-V2.md +196 -0
  201. package/templates/cowork/docs/CODE-VIEW-V4.md +150 -0
  202. package/templates/cowork/electrobun.config.ts +27 -0
  203. package/templates/cowork/eslint.config.mjs +79 -0
  204. package/templates/cowork/llms.txt +24 -0
  205. package/templates/cowork/package.json +87 -0
  206. package/templates/cowork/postcss.config.js +6 -0
  207. package/templates/cowork/scripts/dev.ts +138 -0
  208. package/templates/cowork/src/__tests__/hybrid-mode.test.ts +126 -0
  209. package/templates/cowork/src/__tests__/server-config-security.test.ts +55 -0
  210. package/templates/cowork/src/__tests__/server-config.test.ts +59 -0
  211. package/templates/cowork/src/bun/index.ts +130 -0
  212. package/templates/cowork/src/bun/three.d.ts +1 -0
  213. package/templates/cowork/src/gateway/http-routes.ts +1 -0
  214. package/templates/cowork/src/gateway/ipc-transport.ts +68 -0
  215. package/templates/cowork/src/gateway/sse-transport.ts +231 -0
  216. package/templates/cowork/src/mainview/App.tsx +45 -0
  217. package/templates/cowork/src/mainview/__tests__/hooks/use-rpc-init.test.ts +202 -0
  218. package/templates/cowork/src/mainview/__tests__/hooks/use-sidebar-resize.test.ts +127 -0
  219. package/templates/cowork/src/mainview/__tests__/i18n/i18n.test.ts +49 -0
  220. package/templates/cowork/src/mainview/__tests__/setup.ts +40 -0
  221. package/templates/cowork/src/mainview/__tests__/stores/use-chat-store.test.ts +73 -0
  222. package/templates/cowork/src/mainview/__tests__/stores/use-sidebar-store.test.ts +61 -0
  223. package/templates/cowork/src/mainview/__tests__/theme-variables.test.ts +36 -0
  224. package/templates/cowork/src/mainview/components/chat/TaskChat.tsx +311 -0
  225. package/templates/cowork/src/mainview/components/chat/__tests__/localhost-links.test.ts +76 -0
  226. package/templates/cowork/src/mainview/components/common/ErrorBoundary.tsx +1 -0
  227. package/templates/cowork/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
  228. package/templates/cowork/src/mainview/components/common/ThemeToggle.tsx +45 -0
  229. package/templates/cowork/src/mainview/components/common/__tests__/ErrorBoundary.test.tsx +74 -0
  230. package/templates/cowork/src/mainview/components/common/__tests__/LanguageSwitcher.test.tsx +44 -0
  231. package/templates/cowork/src/mainview/components/common/__tests__/ThemeToggle.test.tsx +41 -0
  232. package/templates/cowork/src/mainview/components/dev/NetworkPanel.tsx +155 -0
  233. package/templates/cowork/src/mainview/components/layout/AppLayout.tsx +216 -0
  234. package/templates/cowork/src/mainview/components/right/ArtifactsPanel.tsx +54 -0
  235. package/templates/cowork/src/mainview/components/right/ContextPanel.tsx +133 -0
  236. package/templates/cowork/src/mainview/components/right/ElementPicker.tsx +206 -0
  237. package/templates/cowork/src/mainview/components/right/PreviewBlock.tsx +155 -0
  238. package/templates/cowork/src/mainview/components/right/ProgressPanel.tsx +85 -0
  239. package/templates/cowork/src/mainview/components/sidebar/TaskSidebar.tsx +211 -0
  240. package/templates/cowork/src/mainview/components/topbar/TopBar.tsx +86 -0
  241. package/templates/cowork/src/mainview/global.d.ts +13 -0
  242. package/templates/cowork/src/mainview/hooks/__tests__/use-breakpoint.test.ts +123 -0
  243. package/templates/cowork/src/mainview/hooks/use-breakpoint.ts +53 -0
  244. package/templates/cowork/src/mainview/hooks/use-rpc-init.ts +26 -0
  245. package/templates/cowork/src/mainview/hooks/use-sidebar-resize.ts +40 -0
  246. package/templates/cowork/src/mainview/index.css +89 -0
  247. package/templates/cowork/src/mainview/index.html +12 -0
  248. package/templates/cowork/src/mainview/lib/api-client.ts +404 -0
  249. package/templates/cowork/src/mainview/lib/i18n/index.ts +30 -0
  250. package/templates/cowork/src/mainview/lib/i18n/locales/en.json +130 -0
  251. package/templates/cowork/src/mainview/lib/i18n/locales/zh.json +128 -0
  252. package/templates/cowork/src/mainview/lib/network-bus.ts +92 -0
  253. package/templates/cowork/src/mainview/lib/rpc-cache.ts +94 -0
  254. package/templates/cowork/src/mainview/main.tsx +18 -0
  255. package/templates/cowork/src/mainview/stores/__tests__/use-connection-store.test.ts +26 -0
  256. package/templates/cowork/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  257. package/templates/cowork/src/mainview/stores/__tests__/use-log-store.test.ts +28 -0
  258. package/templates/cowork/src/mainview/stores/__tests__/use-preview-store.test.ts +193 -0
  259. package/templates/cowork/src/mainview/stores/__tests__/use-sidebar-store.test.ts +81 -0
  260. package/templates/cowork/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  261. package/templates/cowork/src/mainview/stores/message-batcher.ts +25 -0
  262. package/templates/cowork/src/mainview/stores/use-chat-store.ts +198 -0
  263. package/templates/cowork/src/mainview/stores/use-connection-store.ts +168 -0
  264. package/templates/cowork/src/mainview/stores/use-context-store.ts +68 -0
  265. package/templates/cowork/src/mainview/stores/use-locale-store.ts +27 -0
  266. package/templates/cowork/src/mainview/stores/use-log-store.ts +16 -0
  267. package/templates/cowork/src/mainview/stores/use-network-panel-store.ts +18 -0
  268. package/templates/cowork/src/mainview/stores/use-output-store.ts +47 -0
  269. package/templates/cowork/src/mainview/stores/use-preview-store.ts +97 -0
  270. package/templates/cowork/src/mainview/stores/use-sidebar-store.ts +272 -0
  271. package/templates/cowork/src/mainview/stores/use-task-store.ts +86 -0
  272. package/templates/cowork/src/mainview/stores/use-theme-store.ts +46 -0
  273. package/templates/cowork/src/mainview/stores/use-view-store.ts +29 -0
  274. package/templates/cowork/src/mainview/types/index.ts +6 -0
  275. package/templates/cowork/src/server-config.ts +44 -0
  276. package/templates/cowork/src/server.ts +78 -0
  277. package/templates/cowork/src/shared/handlers/__tests__/chat-concurrency.test.ts +127 -0
  278. package/templates/cowork/src/shared/handlers/__tests__/chat-handler.test.ts +77 -0
  279. package/templates/cowork/src/shared/handlers/__tests__/file-handler.test.ts +100 -0
  280. package/templates/cowork/src/shared/handlers/__tests__/preview-handler.test.ts +172 -0
  281. package/templates/cowork/src/shared/handlers/__tests__/system-handler.test.ts +55 -0
  282. package/templates/cowork/src/shared/handlers/__tests__/timer-handler.test.ts +77 -0
  283. package/templates/cowork/src/shared/handlers/chat.ts +213 -0
  284. package/templates/cowork/src/shared/handlers/context.ts +72 -0
  285. package/templates/cowork/src/shared/handlers/file.ts +99 -0
  286. package/templates/cowork/src/shared/handlers/index.ts +9 -0
  287. package/templates/cowork/src/shared/handlers/output.ts +59 -0
  288. package/templates/cowork/src/shared/handlers/preview.ts +81 -0
  289. package/templates/cowork/src/shared/handlers/system.ts +27 -0
  290. package/templates/cowork/src/shared/handlers/task.ts +101 -0
  291. package/templates/cowork/src/shared/handlers/timer.ts +34 -0
  292. package/templates/cowork/src/shared/http-routes.ts +444 -0
  293. package/templates/cowork/src/shared/lib/__tests__/logger.test.ts +92 -0
  294. package/templates/cowork/src/shared/lib/__tests__/path-security.test.ts +77 -0
  295. package/templates/cowork/src/shared/lib/__tests__/web-server.test.ts +203 -0
  296. package/templates/cowork/src/shared/lib/logger.ts +152 -0
  297. package/templates/cowork/src/shared/lib/path-security.ts +38 -0
  298. package/templates/cowork/src/shared/lib/port-registry.ts +103 -0
  299. package/templates/cowork/src/shared/lib/web-server.ts +127 -0
  300. package/templates/cowork/src/shared/modules/chat.ts +20 -0
  301. package/templates/cowork/src/shared/modules/context.ts +32 -0
  302. package/templates/cowork/src/shared/modules/file.ts +40 -0
  303. package/templates/cowork/src/shared/modules/output.ts +20 -0
  304. package/templates/cowork/src/shared/modules/preview.ts +44 -0
  305. package/templates/cowork/src/shared/modules/system.ts +8 -0
  306. package/templates/cowork/src/shared/modules/task.ts +31 -0
  307. package/templates/cowork/src/shared/modules/timer.ts +11 -0
  308. package/templates/cowork/src/shared/register-all-handlers.ts +36 -0
  309. package/templates/cowork/src/shared/rpc-schema.ts +38 -0
  310. package/templates/cowork/tailwind.config.js +15 -0
  311. package/templates/cowork/test-upload.txt +0 -0
  312. package/templates/cowork/tsconfig.ipc.json +14 -0
  313. package/templates/cowork/tsconfig.json +36 -0
  314. package/templates/cowork/vite.config.ts +3 -0
  315. package/templates/cowork/vitest.config.ts +3 -0
  316. package/templates/general/.husky/commit-msg +4 -0
  317. package/templates/general/.husky/pre-commit +11 -0
  318. package/templates/general/.husky/pre-push +6 -0
  319. package/templates/general/CHANGELOG.md +15 -0
  320. package/templates/general/commitlint.config.js +8 -0
  321. package/templates/general/package.json +19 -4
  322. package/templates/general/src/mainview/__tests__/hooks/use-input-history.test.ts +125 -0
  323. package/templates/general/src/mainview/__tests__/setup.ts +32 -29
  324. package/templates/general/src/mainview/components/chat/ChatPanel.tsx +80 -55
  325. package/templates/general/src/mainview/components/common/ThemeToggle.tsx +40 -20
  326. package/templates/general/src/mainview/components/debug/DebugPanel.tsx +170 -156
  327. package/templates/general/src/mainview/components/debug/__tests__/DebugPanel.test.tsx +169 -0
  328. package/templates/general/src/mainview/components/explorer/ConfirmDialog.tsx +42 -42
  329. package/templates/general/src/mainview/components/explorer/ContextMenu.tsx +72 -67
  330. package/templates/general/src/mainview/components/feed/FeedPanel.tsx +7 -5
  331. package/templates/general/src/mainview/components/file-preview/FilePreviewOverlay.tsx +64 -45
  332. package/templates/general/src/mainview/components/file-preview/VirtualizedCodeView.tsx +24 -7
  333. package/templates/general/src/mainview/components/git/GitPanel.tsx +700 -473
  334. package/templates/general/src/mainview/components/layout/AppLayout.tsx +123 -114
  335. package/templates/general/src/mainview/components/search/SearchPanel.tsx +15 -19
  336. package/templates/general/src/mainview/lib/i18n/locales/en.json +175 -155
  337. package/templates/general/src/mainview/lib/i18n/locales/zh.json +173 -155
  338. package/templates/general/src/mainview/stores/__tests__/use-explorer-store.test.ts +259 -0
  339. package/templates/general/src/mainview/stores/__tests__/use-feed-store.test.ts +160 -0
  340. package/templates/general/src/mainview/stores/__tests__/use-git-store.test.ts +313 -0
  341. package/templates/general/src/mainview/stores/__tests__/use-notification-store.test.ts +115 -0
  342. package/templates/general/src/mainview/stores/__tests__/use-sidebar-store.test.ts +120 -0
  343. package/templates/general/src/mainview/stores/use-explorer-store.ts +277 -260
  344. package/templates/general/src/mainview/types/index.ts +21 -20
  345. package/templates/general/src/shared/handlers/chat.ts +1 -1
  346. package/templates/general/src/shared/handlers/debug.ts +12 -2
  347. package/templates/shared/components/ErrorBoundary.tsx +0 -1
  348. package/templates/shared/vite-base.config.ts +8 -7
  349. /package/templates/{shared → browser-agent}/test-upload.txt +0 -0
@@ -1,66 +1,91 @@
1
- import { useEffect, useRef } from "react";
1
+ import { useCallback, useEffect, useRef } from "react";
2
2
  import { MessageSquare, Send } from "lucide-react";
3
3
  import { useTranslation } from "react-i18next";
4
4
  import { useChatStore } from "../../stores/use-chat-store";
5
+ import { useInputHistory } from "../../hooks/use-input-history";
5
6
  import { MessageBubble } from "./MessageBubble";
6
7
 
7
8
  export function ChatPanel() {
8
- const { t } = useTranslation();
9
- const messages = useChatStore((s) => s.messages);
10
- const inputText = useChatStore((s) => s.inputText);
11
- const setInputText = useChatStore((s) => s.setInputText);
12
- const sendMessage = useChatStore((s) => s.sendMessage);
13
- const messagesEndRef = useRef<HTMLDivElement>(null);
9
+ const { t } = useTranslation();
10
+ const messages = useChatStore((s) => s.messages);
11
+ const inputText = useChatStore((s) => s.inputText);
12
+ const setInputText = useChatStore((s) => s.setInputText);
13
+ const sendMessage = useChatStore((s) => s.sendMessage);
14
+ const messagesEndRef = useRef<HTMLDivElement>(null);
15
+ const { saveToHistory, navigatePrev, navigateNext } = useInputHistory("default");
14
16
 
15
- useEffect(() => {
16
- messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
17
- }, [messages]);
17
+ const handleSend = useCallback(() => {
18
+ const text = inputText.trim();
19
+ if (!text) return;
20
+ saveToHistory(text);
21
+ sendMessage();
22
+ }, [inputText, saveToHistory, sendMessage]);
18
23
 
19
- return (
20
- <div className="flex-1 flex flex-col overflow-hidden relative">
21
- {/* Chat header */}
22
- <div className="px-4 py-2 bg-[var(--color-bg-secondary)] border-b border-[var(--color-border-primary)] flex items-center justify-between flex-shrink-0">
23
- <h2 className="text-sm font-semibold flex items-center gap-1.5">
24
- <MessageSquare className="w-4 h-4 text-[var(--color-text-accent)]" />
25
- {t("chat.title")}
26
- {messages.length > 0 && (
27
- <span className="ml-1 px-2 py-0.5 bg-[var(--color-accent)]/30 text-[var(--color-text-accent)] rounded text-[10px]">
28
- {messages.length}
29
- </span>
30
- )}
31
- </h2>
32
- </div>
24
+ useEffect(() => {
25
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
26
+ }, [messages]);
33
27
 
34
- {/* Messages list */}
35
- <div className="flex-1 overflow-y-auto p-4 space-y-3">
36
- {messages.length === 0 ? (
37
- <div className="flex items-center justify-center h-full text-[var(--color-text-placeholder)] text-sm">
38
- {t("chat.empty")}
39
- </div>
40
- ) : (
41
- messages.map((msg) => <MessageBubble key={msg.id} message={msg} />)
42
- )}
43
- <div ref={messagesEndRef} />
44
- </div>
28
+ return (
29
+ <div className="flex-1 flex flex-col overflow-hidden relative">
30
+ {/* Chat header */}
31
+ <div className="px-4 py-2 bg-[var(--color-bg-secondary)] border-b border-[var(--color-border-primary)] flex items-center justify-between flex-shrink-0">
32
+ <h2 className="text-sm font-semibold flex items-center gap-1.5">
33
+ <MessageSquare className="w-4 h-4 text-[var(--color-text-accent)]" />
34
+ {t("chat.title")}
35
+ {messages.length > 0 && (
36
+ <span className="ml-1 px-2 py-0.5 bg-[var(--color-accent)]/30 text-[var(--color-text-accent)] rounded text-[10px]">
37
+ {messages.length}
38
+ </span>
39
+ )}
40
+ </h2>
41
+ </div>
45
42
 
46
- {/* Input bar */}
47
- <div className="px-4 py-3 bg-[var(--color-bg-secondary)] border-t border-[var(--color-border-primary)] flex gap-2 flex-shrink-0">
48
- <input
49
- type="text"
50
- value={inputText}
51
- onChange={(e) => setInputText(e.target.value)}
52
- onKeyDown={(e) => e.key === "Enter" && !e.shiftKey && sendMessage()}
53
- placeholder={t("chat.placeholder")}
54
- className="flex-1 px-3 py-2 text-sm bg-[var(--color-bg-tertiary)] rounded-lg text-[var(--color-text-primary)] border border-[var(--color-border-secondary)] focus:border-[var(--color-accent)] focus:outline-none"
55
- />
56
- <button
57
- onClick={sendMessage}
58
- className="px-4 py-2 text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] rounded-lg transition-colors flex items-center gap-1.5"
59
- >
60
- <Send className="w-4 h-4" />
61
- {t("chat.send")}
62
- </button>
63
- </div>
64
- </div>
65
- );
43
+ {/* Messages list */}
44
+ <div className="flex-1 overflow-y-auto p-4 space-y-3">
45
+ {messages.length === 0 ? (
46
+ <div className="flex items-center justify-center h-full text-[var(--color-text-placeholder)] text-sm">
47
+ {t("chat.empty")}
48
+ </div>
49
+ ) : (
50
+ messages.map((msg) => <MessageBubble key={msg.id} message={msg} />)
51
+ )}
52
+ <div ref={messagesEndRef} />
53
+ </div>
54
+
55
+ {/* Input bar */}
56
+ <form
57
+ onSubmit={(e) => e.preventDefault()}
58
+ className="px-4 py-3 bg-[var(--color-bg-secondary)] border-t border-[var(--color-border-primary)] flex gap-2 flex-shrink-0"
59
+ >
60
+ <input
61
+ type="text"
62
+ value={inputText}
63
+ onChange={(e) => setInputText(e.target.value)}
64
+ onKeyDown={(e) => {
65
+ if (e.key === "Enter" && !e.shiftKey) {
66
+ e.preventDefault();
67
+ handleSend();
68
+ } else if (e.key === "ArrowUp" && !inputText) {
69
+ e.preventDefault();
70
+ const prev = navigatePrev();
71
+ if (prev !== null) setInputText(prev);
72
+ } else if (e.key === "ArrowDown") {
73
+ e.preventDefault();
74
+ const next = navigateNext();
75
+ if (next !== null) setInputText(next);
76
+ }
77
+ }}
78
+ placeholder={t("chat.placeholder")}
79
+ className="flex-1 px-3 py-2 text-sm bg-[var(--color-bg-tertiary)] rounded-lg text-[var(--color-text-primary)] border border-[var(--color-border-secondary)] focus:border-[var(--color-accent)] focus:outline-none"
80
+ />
81
+ <button
82
+ onClick={handleSend}
83
+ className="px-4 py-2 text-sm bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] rounded-lg transition-colors flex items-center gap-1.5"
84
+ >
85
+ <Send className="w-4 h-4" />
86
+ {t("chat.send")}
87
+ </button>
88
+ </form>
89
+ </div>
90
+ );
66
91
  }
@@ -1,25 +1,45 @@
1
1
  import { useThemeStore } from "../../stores/use-theme-store";
2
2
 
3
3
  export function ThemeToggle() {
4
- const theme = useThemeStore((s) => s.theme);
5
- const toggleTheme = useThemeStore((s) => s.toggleTheme);
4
+ const theme = useThemeStore((s) => s.theme);
5
+ const toggleTheme = useThemeStore((s) => s.toggleTheme);
6
6
 
7
- return (
8
- <button
9
- data-testid="theme-toggle"
10
- onClick={toggleTheme}
11
- className="p-1.5 rounded-md hover:bg-[var(--color-bg-hover)] transition-colors"
12
- title={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
13
- >
14
- {theme === "dark" ? (
15
- <svg className="w-4 h-4 text-yellow-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
16
- <path strokeLinecap="round" strokeLinejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
17
- </svg>
18
- ) : (
19
- <svg className="w-4 h-4 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
20
- <path strokeLinecap="round" strokeLinejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
21
- </svg>
22
- )}
23
- </button>
24
- );
7
+ return (
8
+ <button
9
+ data-testid="theme-toggle"
10
+ onClick={toggleTheme}
11
+ className="p-1.5 rounded-md hover:bg-[var(--color-bg-hover)] transition-colors"
12
+ title={theme === "dark" ? "Switch to light mode" : "Switch to dark mode"}
13
+ >
14
+ {theme === "dark" ? (
15
+ <svg
16
+ className="w-4 h-4 text-yellow-400"
17
+ fill="none"
18
+ viewBox="0 0 24 24"
19
+ stroke="currentColor"
20
+ strokeWidth={2}
21
+ >
22
+ <path
23
+ strokeLinecap="round"
24
+ strokeLinejoin="round"
25
+ d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
26
+ />
27
+ </svg>
28
+ ) : (
29
+ <svg
30
+ className="w-4 h-4 text-[var(--color-text-tertiary)]"
31
+ fill="none"
32
+ viewBox="0 0 24 24"
33
+ stroke="currentColor"
34
+ strokeWidth={2}
35
+ >
36
+ <path
37
+ strokeLinecap="round"
38
+ strokeLinejoin="round"
39
+ d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
40
+ />
41
+ </svg>
42
+ )}
43
+ </button>
44
+ );
25
45
  }
@@ -8,169 +8,183 @@ import type { DemoMethod } from "../../types";
8
8
  const COLLAPSED_KEY = "debug-panel-collapsed";
9
9
 
10
10
  function readCollapsed(): boolean {
11
- try {
12
- return localStorage.getItem(COLLAPSED_KEY) === "true";
13
- } catch {
14
- return false;
15
- }
11
+ try {
12
+ return localStorage.getItem(COLLAPSED_KEY) === "true";
13
+ } catch {
14
+ return false;
15
+ }
16
16
  }
17
17
 
18
18
  export function DebugPanel() {
19
- const { t } = useTranslation();
20
- const [collapsed, setCollapsed] = useState(readCollapsed);
19
+ const { t } = useTranslation();
20
+ const [collapsed, setCollapsed] = useState(readCollapsed);
21
21
 
22
- useEffect(() => {
23
- try {
24
- localStorage.setItem(COLLAPSED_KEY, String(collapsed));
25
- } catch { /* ignore */ }
26
- }, [collapsed]);
22
+ useEffect(() => {
23
+ try {
24
+ localStorage.setItem(COLLAPSED_KEY, String(collapsed));
25
+ } catch {
26
+ /* ignore */
27
+ }
28
+ }, [collapsed]);
27
29
 
28
- const method = useAppStore((s) => s.method);
29
- const result = useAppStore((s) => s.result);
30
- const logs = useLogStore((s) => s.logs);
31
- const tickEvents = useAppStore((s) => s.tickEvents);
32
- const tickCount = useAppStore((s) => s.tickCount);
33
- const subscriptionId = useAppStore((s) => s.subscriptionId);
34
- const timerRunning = useAppStore((s) => s.timerRunning);
35
- const setMethod = useAppStore((s) => s.setMethod);
36
- const callRPC = useAppStore((s) => s.callRPC);
37
- const handleSubscribe = useAppStore((s) => s.handleSubscribe);
38
- const handleUnsubscribe = useAppStore((s) => s.handleUnsubscribe);
39
- const clearDebug = useAppStore((s) => s.clearDebug);
30
+ const method = useAppStore((s) => s.method);
31
+ const result = useAppStore((s) => s.result);
32
+ const logs = useLogStore((s) => s.logs);
33
+ const tickEvents = useAppStore((s) => s.tickEvents);
34
+ const tickCount = useAppStore((s) => s.tickCount);
35
+ const subscriptionId = useAppStore((s) => s.subscriptionId);
36
+ const timerRunning = useAppStore((s) => s.timerRunning);
37
+ const setMethod = useAppStore((s) => s.setMethod);
38
+ const callRPC = useAppStore((s) => s.callRPC);
39
+ const handleSubscribe = useAppStore((s) => s.handleSubscribe);
40
+ const handleUnsubscribe = useAppStore((s) => s.handleUnsubscribe);
41
+ const clearDebug = useAppStore((s) => s.clearDebug);
40
42
 
41
- if (collapsed) {
42
- return (
43
- <div className="w-12 bg-[var(--color-bg-primary)] border-l border-[var(--color-border-primary)] flex flex-col items-center justify-start pt-2 flex-shrink-0">
44
- <button
45
- onClick={() => setCollapsed(false)}
46
- title="Expand Debug Panel"
47
- className="w-10 h-6 flex items-center gap-1 text-xs text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] transition-colors"
48
- >
49
- <ChevronRight className="w-3 h-3" />
50
- {t("tabs.debug")}
51
- </button>
52
- </div>
53
- );
54
- }
43
+ if (collapsed) {
44
+ return (
45
+ <div className="w-12 bg-[var(--color-bg-primary)] border-l border-[var(--color-border-primary)] flex flex-col items-center justify-start pt-2 flex-shrink-0">
46
+ <button
47
+ onClick={() => setCollapsed(false)}
48
+ title={t("debug.expandPanel")}
49
+ className="w-10 h-6 flex items-center gap-1 text-xs text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] transition-colors"
50
+ >
51
+ <ChevronRight className="w-3 h-3" />
52
+ {t("tabs.debug")}
53
+ </button>
54
+ </div>
55
+ );
56
+ }
55
57
 
56
- return (
57
- <div className="w-72 bg-[var(--color-bg-primary)] border-l border-[var(--color-border-primary)] flex flex-col flex-shrink-0 overflow-y-auto">
58
- <div className="flex items-center justify-between px-2 py-1.5 border-b border-[var(--color-border-primary)]">
59
- <button
60
- onClick={() => setCollapsed(true)}
61
- title="Collapse Debug Panel"
62
- className="flex items-center gap-1 text-[11px] text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] transition-colors"
63
- >
64
- <ChevronDown className="w-3 h-3" />
65
- {t("tabs.debug")}
66
- </button>
67
- <button
68
- onClick={clearDebug}
69
- title="Clear all debug data"
70
- className="flex items-center gap-1 text-[11px] text-[var(--color-text-placeholder)] hover:text-red-400 transition-colors"
71
- >
72
- <Trash2 className="w-3 h-3" />
73
- Clear
74
- </button>
75
- </div>
76
- {/* RPC Calls */}
77
- <div className="p-3 border-b border-[var(--color-border-primary)]">
78
- <div className="flex items-center justify-between mb-2">
79
- <h2 className="text-xs font-semibold flex items-center gap-1.5">
80
- <Send className="w-3.5 h-3.5 text-[var(--color-text-accent)]" />
81
- {t("debug.rpcCalls")}
82
- </h2>
83
- </div>
84
- <div className="flex gap-2 mb-2">
85
- <select
86
- value={method}
87
- onChange={(e) => setMethod(e.target.value as DemoMethod)}
88
- className="flex-1 px-2 py-1 text-xs bg-[var(--color-bg-tertiary)] rounded text-[var(--color-text-primary)] border border-[var(--color-border-secondary)]"
89
- >
90
- <option value="system.ping">system.ping</option>
91
- <option value="system.hello">system.hello</option>
92
- <option value="system.echo">system.echo</option>
93
- <option value="chat.send">chat.send</option>
94
- </select>
95
- <button
96
- onClick={() => callRPC("")}
97
- className="px-3 py-1 text-xs bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] rounded transition-colors flex items-center gap-1"
98
- >
99
- <Play className="w-3 h-3" />
100
- {t("debug.call")}
101
- </button>
102
- </div>
103
- {!!result && (
104
- <div className="bg-[var(--color-bg-tertiary)] rounded p-2">
105
- <pre className="text-[var(--color-text-success)] text-[11px] overflow-x-auto whitespace-pre-wrap">
106
- {JSON.stringify(result, null, 2)}
107
- </pre>
108
- </div>
109
- )}
110
- </div>
58
+ return (
59
+ <div className="w-72 bg-[var(--color-bg-primary)] border-l border-[var(--color-border-primary)] flex flex-col flex-shrink-0 overflow-y-auto">
60
+ <div className="flex items-center justify-between px-2 py-1.5 border-b border-[var(--color-border-primary)]">
61
+ <button
62
+ onClick={() => setCollapsed(true)}
63
+ title={t("debug.collapsePanel")}
64
+ className="flex items-center gap-1 text-[11px] text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] transition-colors"
65
+ >
66
+ <ChevronDown className="w-3 h-3" />
67
+ {t("tabs.debug")}
68
+ </button>
69
+ <button
70
+ onClick={clearDebug}
71
+ title={t("debug.clearAll")}
72
+ className="flex items-center gap-1 text-[11px] text-[var(--color-text-placeholder)] hover:text-[var(--color-text-error)] transition-colors"
73
+ >
74
+ <Trash2 className="w-3 h-3" />
75
+ {t("debug.clear")}
76
+ </button>
77
+ </div>
78
+ {/* RPC Calls */}
79
+ <div className="p-3 border-b border-[var(--color-border-primary)]">
80
+ <div className="flex items-center justify-between mb-2">
81
+ <h2 className="text-xs font-semibold flex items-center gap-1.5">
82
+ <Send className="w-3.5 h-3.5 text-[var(--color-text-accent)]" />
83
+ {t("debug.rpcCalls")}
84
+ </h2>
85
+ </div>
86
+ <div className="flex gap-2 mb-2">
87
+ <select
88
+ aria-label={t("debug.rpcCalls")}
89
+ value={method}
90
+ onChange={(e) => setMethod(e.target.value as DemoMethod)}
91
+ className="flex-1 px-2 py-1 text-xs bg-[var(--color-bg-tertiary)] rounded text-[var(--color-text-primary)] border border-[var(--color-border-secondary)]"
92
+ >
93
+ <option value="system.ping">system.ping</option>
94
+ <option value="system.hello">system.hello</option>
95
+ <option value="system.echo">system.echo</option>
96
+ <option value="chat.send">chat.send</option>
97
+ </select>
98
+ <button
99
+ onClick={() => callRPC("")}
100
+ className="px-3 py-1 text-xs bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] rounded transition-colors flex items-center gap-1"
101
+ >
102
+ <Play className="w-3 h-3" />
103
+ {t("debug.call")}
104
+ </button>
105
+ </div>
106
+ {!!result && (
107
+ <div className="bg-[var(--color-bg-tertiary)] rounded p-2">
108
+ <pre className="text-[var(--color-text-success)] text-[11px] overflow-x-auto whitespace-pre-wrap">
109
+ {JSON.stringify(result, null, 2)}
110
+ </pre>
111
+ </div>
112
+ )}
113
+ </div>
111
114
 
112
- {/* Subscriptions */}
113
- <div className="p-3 border-b border-[var(--color-border-primary)]">
114
- <div className="flex items-center justify-between mb-2">
115
- <h2 className="text-xs font-semibold flex items-center gap-1.5">
116
- {timerRunning ? (
117
- <Square className="w-3.5 h-3.5 text-green-400 fill-green-400" />
118
- ) : (
119
- <Play className="w-3.5 h-3.5 text-[var(--color-text-tertiary)]" />
120
- )}
121
- {t("debug.subscriptions")}
122
- {timerRunning && (
123
- <span className="ml-1 px-1.5 py-0.5 bg-green-600/30 text-green-400 rounded text-[10px]">
124
- {t("feed.live")}
125
- </span>
126
- )}
127
- </h2>
128
- <div className="flex gap-2 items-center">
129
- <span className="text-[11px] text-[var(--color-text-tertiary)]">
130
- {t("debug.events", { count: tickCount })}
131
- </span>
132
- {!subscriptionId ? (
133
- <button
134
- onClick={handleSubscribe}
135
- className="px-2 py-0.5 text-xs bg-green-600 hover:bg-green-700 rounded transition-colors"
136
- >
137
- {t("debug.subscribe")}
138
- </button>
139
- ) : (
140
- <button
141
- onClick={handleUnsubscribe}
142
- className="px-2 py-0.5 text-xs bg-red-600 hover:bg-red-700 rounded transition-colors"
143
- >
144
- {t("debug.unsubscribe")}
145
- </button>
146
- )}
147
- </div>
148
- </div>
149
- <div className="bg-[var(--color-bg-tertiary)] rounded p-2 max-h-32 overflow-y-auto font-mono text-[11px]">
150
- {tickEvents.length === 0 ? (
151
- <div className="text-[var(--color-text-placeholder)] text-center py-1">{t("debug.noEvents")}</div>
152
- ) : (
153
- tickEvents.map((ev, i) => (
154
- <div key={i} className="text-cyan-400">{ev}</div>
155
- ))
156
- )}
157
- </div>
158
- </div>
115
+ {/* Subscriptions */}
116
+ <div className="p-3 border-b border-[var(--color-border-primary)]">
117
+ <div className="flex items-center justify-between mb-2">
118
+ <h2 className="text-xs font-semibold flex items-center gap-1.5">
119
+ {timerRunning ? (
120
+ <Square className="w-3.5 h-3.5 text-[var(--color-text-success)] fill-[var(--color-text-success)]" />
121
+ ) : (
122
+ <Play className="w-3.5 h-3.5 text-[var(--color-text-tertiary)]" />
123
+ )}
124
+ {t("debug.subscriptions")}
125
+ {timerRunning && (
126
+ <span className="ml-1 px-1.5 py-0.5 bg-[var(--color-text-success)]/30 text-[var(--color-text-success)] rounded text-[10px]">
127
+ {t("feed.live")}
128
+ </span>
129
+ )}
130
+ </h2>
131
+ <div className="flex gap-2 items-center">
132
+ <span className="text-[11px] text-[var(--color-text-tertiary)]">
133
+ {t("debug.events", { count: tickCount })}
134
+ </span>
135
+ {!subscriptionId ? (
136
+ <button
137
+ onClick={handleSubscribe}
138
+ className="px-2 py-0.5 text-xs bg-[var(--color-text-success)] hover:opacity-80 rounded transition-colors"
139
+ >
140
+ {t("debug.subscribe")}
141
+ </button>
142
+ ) : (
143
+ <button
144
+ onClick={handleUnsubscribe}
145
+ className="px-2 py-0.5 text-xs bg-[var(--color-text-error)] hover:opacity-80 rounded transition-colors"
146
+ >
147
+ {t("debug.unsubscribe")}
148
+ </button>
149
+ )}
150
+ </div>
151
+ </div>
152
+ <div className="bg-[var(--color-bg-tertiary)] rounded p-2 max-h-32 overflow-y-auto font-mono text-[11px]">
153
+ {tickEvents.length === 0 ? (
154
+ <div className="text-[var(--color-text-placeholder)] text-center py-1">
155
+ {t("debug.noEvents")}
156
+ </div>
157
+ ) : (
158
+ tickEvents.map((ev, i) => (
159
+ <div key={i} className="text-[var(--color-text-info)]">
160
+ {ev}
161
+ </div>
162
+ ))
163
+ )}
164
+ </div>
165
+ </div>
159
166
 
160
- {/* Logs */}
161
- <div className="p-3 flex flex-col flex-1 min-h-0">
162
- <h2 className="text-xs font-semibold mb-2 flex-shrink-0 flex items-center gap-1.5">
163
- <File className="w-3.5 h-3.5 text-[var(--color-text-tertiary)]" />
164
- {t("debug.logs")}
165
- </h2>
166
- <div className="flex-1 bg-black rounded p-2 overflow-y-auto font-mono text-[11px]">
167
- {logs.map((log, i) => (
168
- <div key={i} className={log.includes("Error") ? "text-red-400" : "text-green-400"}>
169
- {log}
170
- </div>
171
- ))}
172
- </div>
173
- </div>
174
- </div>
175
- );
167
+ {/* Logs */}
168
+ <div className="p-3 flex flex-col flex-1 min-h-0">
169
+ <h2 className="text-xs font-semibold mb-2 flex-shrink-0 flex items-center gap-1.5">
170
+ <File className="w-3.5 h-3.5 text-[var(--color-text-tertiary)]" />
171
+ {t("debug.logs")}
172
+ </h2>
173
+ <div className="flex-1 bg-black rounded p-2 overflow-y-auto font-mono text-[11px]">
174
+ {logs.map((log, i) => (
175
+ <div
176
+ key={i}
177
+ className={
178
+ log.includes("Error")
179
+ ? "text-[var(--color-text-error)]"
180
+ : "text-[var(--color-text-success)]"
181
+ }
182
+ >
183
+ {log}
184
+ </div>
185
+ ))}
186
+ </div>
187
+ </div>
188
+ </div>
189
+ );
176
190
  }