@dyyz1993/create-agent 2.1.1 → 2.1.3

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 (348) 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 +127 -91
  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/package.json +3 -2
  17. package/templates/agent/src/gateway/__tests__/ws-handler-token.test.ts +53 -39
  18. package/templates/agent/src/mainview/App.tsx +14 -12
  19. package/templates/agent/src/mainview/__tests__/hooks/use-rpc-init.test.ts +194 -190
  20. package/templates/agent/src/mainview/components/bash/BashPanel.tsx +210 -189
  21. package/templates/agent/src/mainview/components/chat/ChatPanel.tsx +45 -20
  22. package/templates/agent/src/mainview/components/common/ThemeToggle.tsx +41 -21
  23. package/templates/agent/src/mainview/components/debug/DebugPanel.tsx +181 -114
  24. package/templates/agent/src/mainview/components/debug/__tests__/DebugPanel.test.tsx +80 -80
  25. package/templates/agent/src/mainview/components/diff/__tests__/DiffViewerPanel.test.tsx +61 -58
  26. package/templates/agent/src/mainview/components/feed/FeedPanel.tsx +43 -41
  27. package/templates/agent/src/mainview/components/file-preview/FilePreviewOverlay.tsx +69 -50
  28. package/templates/agent/src/mainview/components/file-preview/VirtualizedCodeView.tsx +31 -18
  29. package/templates/agent/src/mainview/components/git/GitPanel.tsx +731 -490
  30. package/templates/agent/src/mainview/components/git/__tests__/GitPanel.test.tsx +157 -139
  31. package/templates/agent/src/mainview/components/layout/AppLayout.tsx +210 -161
  32. package/templates/agent/src/mainview/components/layout/__tests__/AppLayout.test.tsx +130 -122
  33. package/templates/agent/src/mainview/components/rules/RulesPanel.tsx +119 -109
  34. package/templates/agent/src/mainview/components/search/SearchPanel.tsx +123 -117
  35. package/templates/agent/src/mainview/components/search/__tests__/SearchPanel.test.tsx +64 -44
  36. package/templates/agent/src/mainview/components/sidebar/__tests__/PinButton.test.tsx +38 -38
  37. package/templates/agent/src/mainview/components/todo/TodoPanel.tsx +40 -38
  38. package/templates/agent/src/mainview/components/todo/__tests__/TodoPanel.test.tsx +72 -72
  39. package/templates/agent/src/mainview/lib/api-client.ts +36 -27
  40. package/templates/agent/src/mainview/lib/i18n/locales/en.json +175 -155
  41. package/templates/agent/src/mainview/lib/i18n/locales/zh.json +173 -155
  42. package/templates/agent/src/mainview/stores/use-app-store.ts +96 -86
  43. package/templates/agent/src/mainview/stores/use-explorer-store.ts +292 -275
  44. package/templates/agent/src/mainview/types/index.ts +23 -22
  45. package/templates/agent/src/mainview/utils/file-icon.tsx +17 -21
  46. package/templates/agent/src/shared/handlers/chat.ts +53 -53
  47. package/templates/agent/src/shared/handlers/debug.ts +14 -6
  48. package/templates/agent/tsconfig.ipc.json +1 -1
  49. package/templates/agent/tsconfig.json +4 -1
  50. package/templates/browser-agent/.env.example +19 -0
  51. package/templates/browser-agent/.husky/commit-msg +4 -0
  52. package/templates/browser-agent/.husky/pre-commit +11 -0
  53. package/templates/browser-agent/.husky/pre-push +6 -0
  54. package/templates/browser-agent/.prettierignore +6 -0
  55. package/templates/browser-agent/.prettierrc +9 -0
  56. package/templates/browser-agent/AGENTS.md +396 -0
  57. package/templates/browser-agent/LICENSE +21 -0
  58. package/templates/browser-agent/README.md +103 -0
  59. package/templates/browser-agent/commitlint.config.js +8 -0
  60. package/templates/browser-agent/electrobun.config.ts +27 -0
  61. package/templates/browser-agent/electron/main.js +46 -0
  62. package/templates/browser-agent/electron/preload.js +5 -0
  63. package/templates/browser-agent/electron-builder.json +40 -0
  64. package/templates/browser-agent/eslint.config.mjs +79 -0
  65. package/templates/browser-agent/llms.txt +24 -0
  66. package/templates/browser-agent/package.json +141 -0
  67. package/templates/browser-agent/postcss.config.js +6 -0
  68. package/templates/browser-agent/scripts/dev.ts +138 -0
  69. package/templates/browser-agent/src/__tests__/hybrid-mode.test.ts +126 -0
  70. package/templates/browser-agent/src/__tests__/server-config-security.test.ts +55 -0
  71. package/templates/browser-agent/src/__tests__/server-config.test.ts +59 -0
  72. package/templates/browser-agent/src/bun/index.ts +130 -0
  73. package/templates/browser-agent/src/bun/three.d.ts +1 -0
  74. package/templates/browser-agent/src/gateway/http-routes.ts +1 -0
  75. package/templates/browser-agent/src/gateway/ipc-transport.ts +68 -0
  76. package/templates/browser-agent/src/gateway/sse-transport.ts +221 -0
  77. package/templates/browser-agent/src/mainview/App.tsx +45 -0
  78. package/templates/browser-agent/src/mainview/__tests__/hooks/use-rpc-init.test.ts +202 -0
  79. package/templates/browser-agent/src/mainview/__tests__/hooks/use-sidebar-resize.test.ts +127 -0
  80. package/templates/browser-agent/src/mainview/__tests__/i18n/i18n.test.ts +49 -0
  81. package/templates/browser-agent/src/mainview/__tests__/setup.ts +40 -0
  82. package/templates/browser-agent/src/mainview/__tests__/stores/use-chat-store.test.ts +73 -0
  83. package/templates/browser-agent/src/mainview/__tests__/stores/use-sidebar-store.test.ts +61 -0
  84. package/templates/browser-agent/src/mainview/__tests__/theme-variables.test.ts +36 -0
  85. package/templates/browser-agent/src/mainview/components/assets/AssetsPanel.tsx +139 -0
  86. package/templates/browser-agent/src/mainview/components/chat/ChatPanel.tsx +219 -0
  87. package/templates/browser-agent/src/mainview/components/chat/CommandBar.tsx +184 -0
  88. package/templates/browser-agent/src/mainview/components/chat/MessageBubble.tsx +249 -0
  89. package/templates/browser-agent/src/mainview/components/chat/ToolPicker.tsx +115 -0
  90. package/templates/browser-agent/src/mainview/components/common/ErrorBoundary.tsx +1 -0
  91. package/templates/browser-agent/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
  92. package/templates/browser-agent/src/mainview/components/common/ThemeToggle.tsx +45 -0
  93. package/templates/browser-agent/src/mainview/components/common/__tests__/ErrorBoundary.test.tsx +74 -0
  94. package/templates/browser-agent/src/mainview/components/common/__tests__/LanguageSwitcher.test.tsx +44 -0
  95. package/templates/browser-agent/src/mainview/components/common/__tests__/ThemeToggle.test.tsx +41 -0
  96. package/templates/browser-agent/src/mainview/components/dev/NetworkPanel.tsx +155 -0
  97. package/templates/browser-agent/src/mainview/components/layout/AppLayout.tsx +311 -0
  98. package/templates/browser-agent/src/mainview/components/onboarding/SetupWizard.tsx +310 -0
  99. package/templates/browser-agent/src/mainview/components/process/ProcessPanel.tsx +329 -0
  100. package/templates/browser-agent/src/mainview/components/sidebar/SessionSidebar.tsx +122 -0
  101. package/templates/browser-agent/src/mainview/components/sidebar/SkillSidebar.tsx +115 -0
  102. package/templates/browser-agent/src/mainview/components/topbar/TopBar.tsx +350 -0
  103. package/templates/browser-agent/src/mainview/global.d.ts +13 -0
  104. package/templates/browser-agent/src/mainview/hooks/__tests__/use-breakpoint.test.ts +151 -0
  105. package/templates/browser-agent/src/mainview/hooks/use-agent-chat.ts +157 -0
  106. package/templates/browser-agent/src/mainview/hooks/use-breakpoint.ts +68 -0
  107. package/templates/browser-agent/src/mainview/hooks/use-rpc-init.ts +71 -0
  108. package/templates/browser-agent/src/mainview/hooks/use-sidebar-resize.ts +40 -0
  109. package/templates/browser-agent/src/mainview/index.css +71 -0
  110. package/templates/browser-agent/src/mainview/index.html +12 -0
  111. package/templates/browser-agent/src/mainview/lib/api-client.ts +397 -0
  112. package/templates/browser-agent/src/mainview/lib/i18n/index.ts +30 -0
  113. package/templates/browser-agent/src/mainview/lib/i18n/locales/en.json +130 -0
  114. package/templates/browser-agent/src/mainview/lib/i18n/locales/zh.json +128 -0
  115. package/templates/browser-agent/src/mainview/lib/network-bus.ts +92 -0
  116. package/templates/browser-agent/src/mainview/lib/rpc-cache.ts +94 -0
  117. package/templates/browser-agent/src/mainview/main.tsx +18 -0
  118. package/templates/browser-agent/src/mainview/stores/__tests__/use-connection-store.test.ts +26 -0
  119. package/templates/browser-agent/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  120. package/templates/browser-agent/src/mainview/stores/__tests__/use-log-store.test.ts +28 -0
  121. package/templates/browser-agent/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  122. package/templates/browser-agent/src/mainview/stores/message-batcher.ts +25 -0
  123. package/templates/browser-agent/src/mainview/stores/use-asset-store.ts +65 -0
  124. package/templates/browser-agent/src/mainview/stores/use-chat-store.ts +200 -0
  125. package/templates/browser-agent/src/mainview/stores/use-connection-store.ts +173 -0
  126. package/templates/browser-agent/src/mainview/stores/use-locale-store.ts +27 -0
  127. package/templates/browser-agent/src/mainview/stores/use-log-store.ts +16 -0
  128. package/templates/browser-agent/src/mainview/stores/use-network-panel-store.ts +18 -0
  129. package/templates/browser-agent/src/mainview/stores/use-record-store.ts +147 -0
  130. package/templates/browser-agent/src/mainview/stores/use-session-store.ts +151 -0
  131. package/templates/browser-agent/src/mainview/stores/use-sidebar-store.ts +161 -0
  132. package/templates/browser-agent/src/mainview/stores/use-theme-store.ts +46 -0
  133. package/templates/browser-agent/src/mainview/stores/use-view-store.ts +20 -0
  134. package/templates/browser-agent/src/mainview/types/index.ts +6 -0
  135. package/templates/browser-agent/src/server-config.ts +45 -0
  136. package/templates/browser-agent/src/server.ts +78 -0
  137. package/templates/browser-agent/src/shared/handlers/__tests__/chat-concurrency.test.ts +127 -0
  138. package/templates/browser-agent/src/shared/handlers/__tests__/chat-handler.test.ts +77 -0
  139. package/templates/browser-agent/src/shared/handlers/__tests__/file-handler.test.ts +100 -0
  140. package/templates/browser-agent/src/shared/handlers/__tests__/system-handler.test.ts +55 -0
  141. package/templates/browser-agent/src/shared/handlers/__tests__/timer-handler.test.ts +77 -0
  142. package/templates/browser-agent/src/shared/handlers/browser.ts +596 -0
  143. package/templates/browser-agent/src/shared/handlers/chat.ts +213 -0
  144. package/templates/browser-agent/src/shared/handlers/file.ts +99 -0
  145. package/templates/browser-agent/src/shared/handlers/index.ts +7 -0
  146. package/templates/browser-agent/src/shared/handlers/session.ts +167 -0
  147. package/templates/browser-agent/src/shared/handlers/system.ts +27 -0
  148. package/templates/browser-agent/src/shared/handlers/timer.ts +34 -0
  149. package/templates/browser-agent/src/shared/http-routes.ts +437 -0
  150. package/templates/browser-agent/src/shared/lib/__tests__/logger.test.ts +92 -0
  151. package/templates/browser-agent/src/shared/lib/__tests__/path-security.test.ts +77 -0
  152. package/templates/browser-agent/src/shared/lib/__tests__/web-server.test.ts +203 -0
  153. package/templates/browser-agent/src/shared/lib/agent.ts +384 -0
  154. package/templates/browser-agent/src/shared/lib/cdp.ts +448 -0
  155. package/templates/browser-agent/src/shared/lib/generate.ts +111 -0
  156. package/templates/browser-agent/src/shared/lib/logger.ts +152 -0
  157. package/templates/browser-agent/src/shared/lib/mock-stream.ts +147 -0
  158. package/templates/browser-agent/src/shared/lib/path-security.ts +38 -0
  159. package/templates/browser-agent/src/shared/lib/port-registry.ts +103 -0
  160. package/templates/browser-agent/src/shared/lib/web-server.ts +127 -0
  161. package/templates/browser-agent/src/shared/lib/xhs-extract.ts +71 -0
  162. package/templates/browser-agent/src/shared/modules/browser.ts +86 -0
  163. package/templates/browser-agent/src/shared/modules/chat.ts +20 -0
  164. package/templates/browser-agent/src/shared/modules/file.ts +40 -0
  165. package/templates/browser-agent/src/shared/modules/session.ts +55 -0
  166. package/templates/browser-agent/src/shared/modules/system.ts +8 -0
  167. package/templates/browser-agent/src/shared/modules/timer.ts +11 -0
  168. package/templates/browser-agent/src/shared/register-all-handlers.ts +36 -0
  169. package/templates/browser-agent/src/shared/rpc-schema.ts +34 -0
  170. package/templates/browser-agent/tailwind.config.js +15 -0
  171. package/templates/browser-agent/tsconfig.ipc.json +14 -0
  172. package/templates/browser-agent/tsconfig.json +36 -0
  173. package/templates/browser-agent/vite.config.ts +3 -0
  174. package/templates/browser-agent/vitest.config.ts +3 -0
  175. package/templates/chat/.husky/commit-msg +4 -0
  176. package/templates/chat/.husky/pre-commit +11 -0
  177. package/templates/chat/.husky/pre-push +6 -0
  178. package/templates/chat/commitlint.config.js +8 -0
  179. package/templates/chat/package.json +19 -3
  180. package/templates/chat/src/mainview/__tests__/hooks/use-input-history.test.ts +125 -0
  181. package/templates/chat/src/mainview/__tests__/setup.ts +32 -29
  182. package/templates/chat/src/mainview/components/chat/ChatPanel.tsx +80 -55
  183. package/templates/chat/src/mainview/components/common/ThemeToggle.tsx +40 -20
  184. package/templates/chat/src/mainview/lib/api-client.ts +10 -1
  185. package/templates/chat/src/mainview/lib/i18n/locales/en.json +175 -155
  186. package/templates/chat/src/mainview/lib/i18n/locales/zh.json +173 -155
  187. package/templates/chat/src/shared/handlers/chat.ts +17 -19
  188. package/templates/chat/src/shared/handlers/debug.ts +13 -5
  189. package/templates/chat/tsconfig.json +5 -2
  190. package/templates/cowork/.env.example +8 -0
  191. package/templates/cowork/.prettierignore +6 -0
  192. package/templates/cowork/.prettierrc +9 -0
  193. package/templates/cowork/AGENTS.md +236 -0
  194. package/templates/cowork/LICENSE +21 -0
  195. package/templates/cowork/README.md +103 -0
  196. package/templates/cowork/commitlint.config.js +8 -0
  197. package/templates/cowork/docs/CODE-VIEW-PLAN.md +637 -0
  198. package/templates/cowork/docs/CODE-VIEW-V2.md +196 -0
  199. package/templates/cowork/docs/CODE-VIEW-V4.md +150 -0
  200. package/templates/cowork/electrobun.config.ts +27 -0
  201. package/templates/cowork/eslint.config.mjs +79 -0
  202. package/templates/cowork/llms.txt +24 -0
  203. package/templates/cowork/package.json +88 -0
  204. package/templates/cowork/postcss.config.js +6 -0
  205. package/templates/cowork/scripts/dev.ts +138 -0
  206. package/templates/cowork/src/__tests__/hybrid-mode.test.ts +126 -0
  207. package/templates/cowork/src/__tests__/server-config-security.test.ts +55 -0
  208. package/templates/cowork/src/__tests__/server-config.test.ts +59 -0
  209. package/templates/cowork/src/bun/index.ts +130 -0
  210. package/templates/cowork/src/bun/three.d.ts +1 -0
  211. package/templates/cowork/src/gateway/http-routes.ts +1 -0
  212. package/templates/cowork/src/gateway/ipc-transport.ts +68 -0
  213. package/templates/cowork/src/gateway/sse-transport.ts +231 -0
  214. package/templates/cowork/src/mainview/App.tsx +45 -0
  215. package/templates/cowork/src/mainview/__tests__/hooks/use-rpc-init.test.ts +202 -0
  216. package/templates/cowork/src/mainview/__tests__/hooks/use-sidebar-resize.test.ts +127 -0
  217. package/templates/cowork/src/mainview/__tests__/i18n/i18n.test.ts +49 -0
  218. package/templates/cowork/src/mainview/__tests__/setup.ts +40 -0
  219. package/templates/cowork/src/mainview/__tests__/stores/use-chat-store.test.ts +73 -0
  220. package/templates/cowork/src/mainview/__tests__/stores/use-sidebar-store.test.ts +61 -0
  221. package/templates/cowork/src/mainview/__tests__/theme-variables.test.ts +36 -0
  222. package/templates/cowork/src/mainview/components/chat/TaskChat.tsx +311 -0
  223. package/templates/cowork/src/mainview/components/chat/__tests__/localhost-links.test.ts +76 -0
  224. package/templates/cowork/src/mainview/components/common/ErrorBoundary.tsx +1 -0
  225. package/templates/cowork/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
  226. package/templates/cowork/src/mainview/components/common/ThemeToggle.tsx +45 -0
  227. package/templates/cowork/src/mainview/components/common/__tests__/ErrorBoundary.test.tsx +74 -0
  228. package/templates/cowork/src/mainview/components/common/__tests__/LanguageSwitcher.test.tsx +44 -0
  229. package/templates/cowork/src/mainview/components/common/__tests__/ThemeToggle.test.tsx +41 -0
  230. package/templates/cowork/src/mainview/components/dev/NetworkPanel.tsx +155 -0
  231. package/templates/cowork/src/mainview/components/layout/AppLayout.tsx +216 -0
  232. package/templates/cowork/src/mainview/components/right/ArtifactsPanel.tsx +54 -0
  233. package/templates/cowork/src/mainview/components/right/ContextPanel.tsx +133 -0
  234. package/templates/cowork/src/mainview/components/right/ElementPicker.tsx +206 -0
  235. package/templates/cowork/src/mainview/components/right/PreviewBlock.tsx +155 -0
  236. package/templates/cowork/src/mainview/components/right/ProgressPanel.tsx +85 -0
  237. package/templates/cowork/src/mainview/components/sidebar/TaskSidebar.tsx +211 -0
  238. package/templates/cowork/src/mainview/components/topbar/TopBar.tsx +86 -0
  239. package/templates/cowork/src/mainview/global.d.ts +13 -0
  240. package/templates/cowork/src/mainview/hooks/__tests__/use-breakpoint.test.ts +123 -0
  241. package/templates/cowork/src/mainview/hooks/use-breakpoint.ts +53 -0
  242. package/templates/cowork/src/mainview/hooks/use-rpc-init.ts +26 -0
  243. package/templates/cowork/src/mainview/hooks/use-sidebar-resize.ts +40 -0
  244. package/templates/cowork/src/mainview/index.css +89 -0
  245. package/templates/cowork/src/mainview/index.html +12 -0
  246. package/templates/cowork/src/mainview/lib/api-client.ts +404 -0
  247. package/templates/cowork/src/mainview/lib/i18n/index.ts +30 -0
  248. package/templates/cowork/src/mainview/lib/i18n/locales/en.json +130 -0
  249. package/templates/cowork/src/mainview/lib/i18n/locales/zh.json +128 -0
  250. package/templates/cowork/src/mainview/lib/network-bus.ts +92 -0
  251. package/templates/cowork/src/mainview/lib/rpc-cache.ts +94 -0
  252. package/templates/cowork/src/mainview/main.tsx +18 -0
  253. package/templates/cowork/src/mainview/stores/__tests__/use-connection-store.test.ts +26 -0
  254. package/templates/cowork/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  255. package/templates/cowork/src/mainview/stores/__tests__/use-log-store.test.ts +28 -0
  256. package/templates/cowork/src/mainview/stores/__tests__/use-preview-store.test.ts +193 -0
  257. package/templates/cowork/src/mainview/stores/__tests__/use-sidebar-store.test.ts +81 -0
  258. package/templates/cowork/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  259. package/templates/cowork/src/mainview/stores/message-batcher.ts +25 -0
  260. package/templates/cowork/src/mainview/stores/use-chat-store.ts +198 -0
  261. package/templates/cowork/src/mainview/stores/use-connection-store.ts +168 -0
  262. package/templates/cowork/src/mainview/stores/use-context-store.ts +68 -0
  263. package/templates/cowork/src/mainview/stores/use-locale-store.ts +27 -0
  264. package/templates/cowork/src/mainview/stores/use-log-store.ts +16 -0
  265. package/templates/cowork/src/mainview/stores/use-network-panel-store.ts +18 -0
  266. package/templates/cowork/src/mainview/stores/use-output-store.ts +47 -0
  267. package/templates/cowork/src/mainview/stores/use-preview-store.ts +97 -0
  268. package/templates/cowork/src/mainview/stores/use-sidebar-store.ts +272 -0
  269. package/templates/cowork/src/mainview/stores/use-task-store.ts +86 -0
  270. package/templates/cowork/src/mainview/stores/use-theme-store.ts +46 -0
  271. package/templates/cowork/src/mainview/stores/use-view-store.ts +29 -0
  272. package/templates/cowork/src/mainview/types/index.ts +6 -0
  273. package/templates/cowork/src/server-config.ts +44 -0
  274. package/templates/cowork/src/server.ts +78 -0
  275. package/templates/cowork/src/shared/handlers/__tests__/chat-concurrency.test.ts +127 -0
  276. package/templates/cowork/src/shared/handlers/__tests__/chat-handler.test.ts +77 -0
  277. package/templates/cowork/src/shared/handlers/__tests__/file-handler.test.ts +100 -0
  278. package/templates/cowork/src/shared/handlers/__tests__/preview-handler.test.ts +172 -0
  279. package/templates/cowork/src/shared/handlers/__tests__/system-handler.test.ts +55 -0
  280. package/templates/cowork/src/shared/handlers/__tests__/timer-handler.test.ts +77 -0
  281. package/templates/cowork/src/shared/handlers/chat.ts +213 -0
  282. package/templates/cowork/src/shared/handlers/context.ts +72 -0
  283. package/templates/cowork/src/shared/handlers/file.ts +99 -0
  284. package/templates/cowork/src/shared/handlers/index.ts +9 -0
  285. package/templates/cowork/src/shared/handlers/output.ts +59 -0
  286. package/templates/cowork/src/shared/handlers/preview.ts +81 -0
  287. package/templates/cowork/src/shared/handlers/system.ts +27 -0
  288. package/templates/cowork/src/shared/handlers/task.ts +101 -0
  289. package/templates/cowork/src/shared/handlers/timer.ts +34 -0
  290. package/templates/cowork/src/shared/http-routes.ts +444 -0
  291. package/templates/cowork/src/shared/lib/__tests__/logger.test.ts +92 -0
  292. package/templates/cowork/src/shared/lib/__tests__/path-security.test.ts +77 -0
  293. package/templates/cowork/src/shared/lib/__tests__/web-server.test.ts +203 -0
  294. package/templates/cowork/src/shared/lib/logger.ts +152 -0
  295. package/templates/cowork/src/shared/lib/path-security.ts +38 -0
  296. package/templates/cowork/src/shared/lib/port-registry.ts +103 -0
  297. package/templates/cowork/src/shared/lib/web-server.ts +127 -0
  298. package/templates/cowork/src/shared/modules/chat.ts +20 -0
  299. package/templates/cowork/src/shared/modules/context.ts +32 -0
  300. package/templates/cowork/src/shared/modules/file.ts +40 -0
  301. package/templates/cowork/src/shared/modules/output.ts +20 -0
  302. package/templates/cowork/src/shared/modules/preview.ts +44 -0
  303. package/templates/cowork/src/shared/modules/system.ts +8 -0
  304. package/templates/cowork/src/shared/modules/task.ts +31 -0
  305. package/templates/cowork/src/shared/modules/timer.ts +11 -0
  306. package/templates/cowork/src/shared/register-all-handlers.ts +36 -0
  307. package/templates/cowork/src/shared/rpc-schema.ts +38 -0
  308. package/templates/cowork/tailwind.config.js +15 -0
  309. package/templates/cowork/test-upload.txt +0 -0
  310. package/templates/cowork/tsconfig.ipc.json +14 -0
  311. package/templates/cowork/tsconfig.json +36 -0
  312. package/templates/cowork/vite.config.ts +3 -0
  313. package/templates/cowork/vitest.config.ts +3 -0
  314. package/templates/general/.husky/commit-msg +4 -0
  315. package/templates/general/.husky/pre-commit +11 -0
  316. package/templates/general/.husky/pre-push +6 -0
  317. package/templates/general/commitlint.config.js +8 -0
  318. package/templates/general/package.json +19 -3
  319. package/templates/general/src/mainview/__tests__/hooks/use-input-history.test.ts +125 -0
  320. package/templates/general/src/mainview/__tests__/setup.ts +32 -29
  321. package/templates/general/src/mainview/components/chat/ChatPanel.tsx +80 -55
  322. package/templates/general/src/mainview/components/common/ThemeToggle.tsx +40 -20
  323. package/templates/general/src/mainview/components/debug/DebugPanel.tsx +170 -156
  324. package/templates/general/src/mainview/components/debug/__tests__/DebugPanel.test.tsx +169 -0
  325. package/templates/general/src/mainview/components/explorer/ConfirmDialog.tsx +42 -42
  326. package/templates/general/src/mainview/components/explorer/ContextMenu.tsx +72 -67
  327. package/templates/general/src/mainview/components/feed/FeedPanel.tsx +7 -5
  328. package/templates/general/src/mainview/components/file-preview/FilePreviewOverlay.tsx +64 -45
  329. package/templates/general/src/mainview/components/file-preview/VirtualizedCodeView.tsx +24 -7
  330. package/templates/general/src/mainview/components/git/GitPanel.tsx +700 -473
  331. package/templates/general/src/mainview/components/layout/AppLayout.tsx +123 -114
  332. package/templates/general/src/mainview/components/search/SearchPanel.tsx +15 -19
  333. package/templates/general/src/mainview/lib/api-client.ts +10 -1
  334. package/templates/general/src/mainview/lib/i18n/locales/en.json +175 -155
  335. package/templates/general/src/mainview/lib/i18n/locales/zh.json +173 -155
  336. package/templates/general/src/mainview/stores/__tests__/use-explorer-store.test.ts +259 -0
  337. package/templates/general/src/mainview/stores/__tests__/use-feed-store.test.ts +160 -0
  338. package/templates/general/src/mainview/stores/__tests__/use-git-store.test.ts +313 -0
  339. package/templates/general/src/mainview/stores/__tests__/use-notification-store.test.ts +115 -0
  340. package/templates/general/src/mainview/stores/__tests__/use-sidebar-store.test.ts +120 -0
  341. package/templates/general/src/mainview/stores/use-explorer-store.ts +277 -260
  342. package/templates/general/src/mainview/types/index.ts +21 -20
  343. package/templates/general/src/shared/handlers/chat.ts +1 -1
  344. package/templates/general/src/shared/handlers/debug.ts +13 -5
  345. package/templates/general/tsconfig.json +5 -2
  346. package/templates/shared/components/ErrorBoundary.tsx +0 -1
  347. package/templates/shared/vite-base.config.ts +8 -7
  348. /package/templates/{shared → browser-agent}/test-upload.txt +0 -0
@@ -1,21 +1,21 @@
1
- import { useState, useEffect } from "react";
2
- import { useTranslation } from "react-i18next";
3
- import { Plus, Trash2, Circle, Clock, CheckCircle2, ListTodo } from "lucide-react";
4
- import { useTodoStore } from "../../stores/use-todo-store";
5
- import type { TodoStatus } from "@shared/modules/todo";
1
+ import { useState, useEffect } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Plus, Trash2, Circle, Clock, CheckCircle2, ListTodo } from 'lucide-react';
4
+ import { useTodoStore } from '../../stores/use-todo-store';
5
+ import type { TodoStatus } from '@shared/modules/todo';
6
6
 
7
7
  const nextStatus: Record<TodoStatus, TodoStatus> = {
8
- pending: "in_progress",
9
- in_progress: "completed",
10
- completed: "pending",
8
+ pending: 'in_progress',
9
+ in_progress: 'completed',
10
+ completed: 'pending',
11
11
  };
12
12
 
13
- const statusFlow = ["pending", "in_progress", "completed"] as const;
13
+ const statusFlow = ['pending', 'in_progress', 'completed'] as const;
14
14
 
15
15
  export function TodoPanel() {
16
16
  const { t } = useTranslation();
17
17
  const [showInput, setShowInput] = useState(false);
18
- const [input, setInput] = useState("");
18
+ const [input, setInput] = useState('');
19
19
  const items = useTodoStore((s) => s.items);
20
20
  const fetchItems = useTodoStore((s) => s.fetchItems);
21
21
  const addItem = useTodoStore((s) => s.addItem);
@@ -29,13 +29,13 @@ export function TodoPanel() {
29
29
  const handleAdd = () => {
30
30
  if (!input.trim()) return;
31
31
  addItem(input.trim());
32
- setInput("");
32
+ setInput('');
33
33
  setShowInput(false);
34
34
  };
35
35
 
36
36
  const handleKeyDown = (e: React.KeyboardEvent) => {
37
- if (e.key === "Enter") handleAdd();
38
- if (e.key === "Escape") setShowInput(false);
37
+ if (e.key === 'Enter') handleAdd();
38
+ if (e.key === 'Escape') setShowInput(false);
39
39
  };
40
40
 
41
41
  const statusConfig: Record<
@@ -44,34 +44,34 @@ export function TodoPanel() {
44
44
  > = {
45
45
  pending: {
46
46
  icon: Circle,
47
- color: "text-gray-400",
48
- label: t("todo.statusPending"),
49
- circleColor: "border-gray-500",
47
+ color: 'text-[var(--color-text-tertiary)]',
48
+ label: t('todo.statusPending'),
49
+ circleColor: 'border-[var(--color-border-primary)]',
50
50
  },
51
51
  in_progress: {
52
52
  icon: Clock,
53
- color: "text-yellow-400",
54
- label: t("todo.statusInProgress"),
55
- circleColor: "border-yellow-400 bg-yellow-400/20",
53
+ color: 'text-yellow-400',
54
+ label: t('todo.statusInProgress'),
55
+ circleColor: 'border-yellow-400 bg-yellow-400/20',
56
56
  },
57
57
  completed: {
58
58
  icon: CheckCircle2,
59
- color: "text-green-400",
60
- label: t("todo.statusCompleted"),
61
- circleColor: "border-green-400 bg-green-400/20",
59
+ color: 'text-[var(--color-text-success)]',
60
+ label: t('todo.statusCompleted'),
61
+ circleColor: 'border-[var(--color-text-success)] bg-[var(--color-text-success)]/20',
62
62
  },
63
63
  };
64
64
 
65
65
  return (
66
66
  <div className="flex flex-col h-full">
67
67
  <div className="p-3 border-b border-[var(--color-border-primary)] flex items-center justify-between">
68
- <span className="text-sm text-[var(--color-text-secondary)]">{t("todo.title")}</span>
68
+ <span className="text-sm text-[var(--color-text-secondary)]">{t('todo.title')}</span>
69
69
  <button
70
70
  onClick={() => setShowInput(!showInput)}
71
71
  className="flex items-center gap-1 px-2 py-1 text-xs bg-[var(--color-accent)] hover:bg-[var(--color-accent-hover)] rounded text-[var(--color-text-primary)]"
72
72
  >
73
73
  <Plus className="w-3 h-3" />
74
- {t("todo.add")}
74
+ {t('todo.add')}
75
75
  </button>
76
76
  </div>
77
77
 
@@ -82,26 +82,26 @@ export function TodoPanel() {
82
82
  value={input}
83
83
  onChange={(e) => setInput(e.target.value)}
84
84
  onKeyDown={handleKeyDown}
85
- placeholder={t("todo.placeholder")}
85
+ placeholder={t('todo.placeholder')}
86
86
  autoFocus
87
87
  className="flex-1 bg-[var(--color-bg-primary)] text-[var(--color-text-secondary)] px-3 py-1.5 rounded text-sm border border-[var(--color-border-secondary)] focus:border-[var(--color-accent)] focus:outline-none"
88
88
  />
89
89
  <button
90
90
  onClick={handleAdd}
91
91
  disabled={!input.trim()}
92
- className="px-3 py-1 text-xs bg-green-600 hover:bg-green-500 disabled:opacity-40 rounded text-white"
92
+ className="px-3 py-1 text-xs bg-[var(--color-text-success)] hover:opacity-80 disabled:opacity-40 rounded text-white"
93
93
  >
94
- {t("todo.save")}
94
+ {t('todo.save')}
95
95
  </button>
96
96
  </div>
97
97
  )}
98
98
 
99
99
  <div className="flex-1 overflow-auto p-3">
100
100
  {items.length === 0 ? (
101
- <div className="flex flex-col items-center justify-center h-full text-gray-600">
101
+ <div className="flex flex-col items-center justify-center h-full text-[var(--color-text-tertiary)]">
102
102
  <ListTodo className="w-12 h-12 mb-3 opacity-30" />
103
- <span className="text-sm">{t("todo.empty")}</span>
104
- <span className="text-xs mt-1">{t("todo.emptyHint")}</span>
103
+ <span className="text-sm">{t('todo.empty')}</span>
104
+ <span className="text-xs mt-1">{t('todo.emptyHint')}</span>
105
105
  </div>
106
106
  ) : (
107
107
  <div className="space-y-2.5">
@@ -123,27 +123,29 @@ export function TodoPanel() {
123
123
  <div className="flex-1 min-w-0">
124
124
  <p
125
125
  className={`text-sm leading-relaxed ${
126
- item.status === "completed"
127
- ? "text-[var(--color-text-placeholder)] line-through"
128
- : "text-[var(--color-text-secondary)]"
126
+ item.status === 'completed'
127
+ ? 'text-[var(--color-text-placeholder)] line-through'
128
+ : 'text-[var(--color-text-secondary)]'
129
129
  }`}
130
130
  >
131
131
  {item.content}
132
132
  </p>
133
133
  <div className="flex items-center gap-1.5 mt-2 text-[11px] text-[var(--color-text-placeholder)]">
134
- <span>{t("todo.status")}</span>
134
+ <span>{t('todo.status')}</span>
135
135
  {statusFlow.map((s) => {
136
136
  const sc = statusConfig[s]!;
137
137
  const isActive = s === item.status;
138
138
  return (
139
139
  <span
140
140
  key={s}
141
- className={`inline-flex items-center gap-0.5 ${isActive ? sc.color + " font-medium" : ""}`}
141
+ className={`inline-flex items-center gap-0.5 ${isActive ? sc.color + ' font-medium' : ''}`}
142
142
  >
143
143
  {isActive && <sc.icon className="w-2.5 h-2.5" />}
144
144
  {sc.label}
145
- {s !== "completed" && (
146
- <span className="text-gray-700 mx-0.5">&rarr;</span>
145
+ {s !== 'completed' && (
146
+ <span className="text-[var(--color-text-placeholder)] mx-0.5">
147
+ &rarr;
148
+ </span>
147
149
  )}
148
150
  </span>
149
151
  );
@@ -152,7 +154,7 @@ export function TodoPanel() {
152
154
  </div>
153
155
  <button
154
156
  onClick={() => removeItem(item.id)}
155
- className="text-gray-600 hover:text-[var(--color-text-error)] opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0 self-start mt-0.5"
157
+ className="text-[var(--color-text-tertiary)] hover:text-[var(--color-text-error)] opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0 self-start mt-0.5"
156
158
  >
157
159
  <Trash2 className="w-3.5 h-3.5" />
158
160
  </button>
@@ -1,91 +1,91 @@
1
- import { describe, it, expect, vi, afterEach } from "vitest";
2
- import { render, screen, cleanup, fireEvent } from "@testing-library/react";
3
- import React from "react";
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import { render, screen, cleanup, fireEvent } from '@testing-library/react';
3
+ import React from 'react';
4
4
 
5
5
  const mockAddItem = vi.fn();
6
6
  const mockUpdateItem = vi.fn();
7
7
  const mockRemoveItem = vi.fn();
8
8
  const mockFetchItems = vi.fn();
9
9
 
10
- vi.mock("../../../stores/use-todo-store", () => ({
11
- useTodoStore: (selector: any) =>
12
- selector({
13
- items: [
14
- { id: "1", content: "Buy milk", status: "pending" },
15
- { id: "2", content: "Write code", status: "completed" },
16
- ],
17
- fetchItems: mockFetchItems,
18
- addItem: mockAddItem,
19
- updateItem: mockUpdateItem,
20
- removeItem: mockRemoveItem,
21
- }),
10
+ vi.mock('../../../stores/use-todo-store', () => ({
11
+ useTodoStore: <T,>(selector: (s: Record<string, unknown>) => T) =>
12
+ selector({
13
+ items: [
14
+ { id: '1', content: 'Buy milk', status: 'pending' },
15
+ { id: '2', content: 'Write code', status: 'completed' },
16
+ ],
17
+ fetchItems: mockFetchItems,
18
+ addItem: mockAddItem,
19
+ updateItem: mockUpdateItem,
20
+ removeItem: mockRemoveItem,
21
+ }),
22
22
  }));
23
23
 
24
- vi.mock("react-i18next", () => ({
25
- useTranslation: () => ({ t: (k: string) => k }),
24
+ vi.mock('react-i18next', () => ({
25
+ useTranslation: () => ({ t: (k: string) => k }),
26
26
  }));
27
27
 
28
- describe("TodoPanel", () => {
29
- afterEach(() => {
30
- cleanup();
31
- vi.clearAllMocks();
32
- });
28
+ describe('TodoPanel', () => {
29
+ afterEach(() => {
30
+ cleanup();
31
+ vi.clearAllMocks();
32
+ });
33
33
 
34
- it("should render todo title", async () => {
35
- const { TodoPanel } = await import("../TodoPanel");
36
- render(<TodoPanel />);
37
- expect(screen.getByText("todo.title")).toBeDefined();
38
- });
34
+ it('should render todo title', async () => {
35
+ const { TodoPanel } = await import('../TodoPanel');
36
+ render(<TodoPanel />);
37
+ expect(screen.getByText('todo.title')).toBeDefined();
38
+ });
39
39
 
40
- it("should render add button", async () => {
41
- const { TodoPanel } = await import("../TodoPanel");
42
- render(<TodoPanel />);
43
- expect(screen.getByText("todo.add")).toBeDefined();
44
- });
40
+ it('should render add button', async () => {
41
+ const { TodoPanel } = await import('../TodoPanel');
42
+ render(<TodoPanel />);
43
+ expect(screen.getByText('todo.add')).toBeDefined();
44
+ });
45
45
 
46
- it("should display todo items", async () => {
47
- const { TodoPanel } = await import("../TodoPanel");
48
- render(<TodoPanel />);
49
- expect(screen.getByText("Buy milk")).toBeDefined();
50
- expect(screen.getByText("Write code")).toBeDefined();
51
- });
46
+ it('should display todo items', async () => {
47
+ const { TodoPanel } = await import('../TodoPanel');
48
+ render(<TodoPanel />);
49
+ expect(screen.getByText('Buy milk')).toBeDefined();
50
+ expect(screen.getByText('Write code')).toBeDefined();
51
+ });
52
52
 
53
- it("should call fetchItems on mount", async () => {
54
- const { TodoPanel } = await import("../TodoPanel");
55
- render(<TodoPanel />);
56
- expect(mockFetchItems).toHaveBeenCalled();
57
- });
53
+ it('should call fetchItems on mount', async () => {
54
+ const { TodoPanel } = await import('../TodoPanel');
55
+ render(<TodoPanel />);
56
+ expect(mockFetchItems).toHaveBeenCalled();
57
+ });
58
58
 
59
- it("should show input when add button is clicked", async () => {
60
- const { TodoPanel } = await import("../TodoPanel");
61
- render(<TodoPanel />);
62
- fireEvent.click(screen.getByText("todo.add"));
63
- expect(screen.getByPlaceholderText("todo.placeholder")).toBeDefined();
64
- });
59
+ it('should show input when add button is clicked', async () => {
60
+ const { TodoPanel } = await import('../TodoPanel');
61
+ render(<TodoPanel />);
62
+ fireEvent.click(screen.getByText('todo.add'));
63
+ expect(screen.getByPlaceholderText('todo.placeholder')).toBeDefined();
64
+ });
65
65
 
66
- it("should call addItem on input submit", async () => {
67
- const { TodoPanel } = await import("../TodoPanel");
68
- render(<TodoPanel />);
69
- fireEvent.click(screen.getByText("todo.add"));
70
- const input = screen.getByPlaceholderText("todo.placeholder");
71
- fireEvent.change(input, { target: { value: "New task" } });
72
- fireEvent.click(screen.getByText("todo.save"));
73
- expect(mockAddItem).toHaveBeenCalledWith("New task");
74
- });
66
+ it('should call addItem on input submit', async () => {
67
+ const { TodoPanel } = await import('../TodoPanel');
68
+ render(<TodoPanel />);
69
+ fireEvent.click(screen.getByText('todo.add'));
70
+ const input = screen.getByPlaceholderText('todo.placeholder');
71
+ fireEvent.change(input, { target: { value: 'New task' } });
72
+ fireEvent.click(screen.getByText('todo.save'));
73
+ expect(mockAddItem).toHaveBeenCalledWith('New task');
74
+ });
75
75
 
76
- it("should hide input on Escape", async () => {
77
- const { TodoPanel } = await import("../TodoPanel");
78
- render(<TodoPanel />);
79
- fireEvent.click(screen.getByText("todo.add"));
80
- const input = screen.getByPlaceholderText("todo.placeholder");
81
- fireEvent.keyDown(input, { key: "Escape" });
82
- expect(screen.queryByPlaceholderText("todo.placeholder")).toBeNull();
83
- });
76
+ it('should hide input on Escape', async () => {
77
+ const { TodoPanel } = await import('../TodoPanel');
78
+ render(<TodoPanel />);
79
+ fireEvent.click(screen.getByText('todo.add'));
80
+ const input = screen.getByPlaceholderText('todo.placeholder');
81
+ fireEvent.keyDown(input, { key: 'Escape' });
82
+ expect(screen.queryByPlaceholderText('todo.placeholder')).toBeNull();
83
+ });
84
84
 
85
- it("should render status indicators for each item", async () => {
86
- const { TodoPanel } = await import("../TodoPanel");
87
- const _container = render(<TodoPanel />);
88
- const statusTexts = screen.getAllByText("todo.status");
89
- expect(statusTexts.length).toBeGreaterThan(0);
90
- });
85
+ it('should render status indicators for each item', async () => {
86
+ const { TodoPanel } = await import('../TodoPanel');
87
+ const _container = render(<TodoPanel />);
88
+ const statusTexts = screen.getAllByText('todo.status');
89
+ expect(statusTexts.length).toBeGreaterThan(0);
90
+ });
91
91
  });
@@ -1,13 +1,22 @@
1
- import { createTypedClient, WebSocketTransport, IPCTransport } from "@dyyz1993/rpc-core";
1
+ import { createTypedClient, WebSocketTransport, IPCTransport } from '@dyyz1993/rpc-core';
2
2
  import type {
3
3
  TypedClient,
4
4
  MethodParams,
5
5
  MethodResult,
6
6
  EventPayload,
7
7
  EventMetadata,
8
- } from "@dyyz1993/rpc-core";
9
- import type { RPCMethods, RPCEvents } from "../../shared/rpc-schema";
10
- import { rpcCache, CACHEABLE_METHODS } from "./rpc-cache";
8
+ } from '@dyyz1993/rpc-core';
9
+ import type { RPCMethods, RPCEvents } from '../../shared/rpc-schema';
10
+
11
+ /** Keep the subscribe filter as strict as the typed client's (metadata keys). */
12
+ type SubscribeFilter<K extends keyof RPCEvents = keyof RPCEvents> = RPCEvents[K] extends {
13
+ metadata: infer M;
14
+ }
15
+ ? Partial<M>
16
+ : RPCEvents[K] extends { metadata?: infer M }
17
+ ? Partial<NonNullable<M>>
18
+ : Record<string, unknown>;
19
+ import { rpcCache, CACHEABLE_METHODS } from './rpc-cache';
11
20
 
12
21
  /**
13
22
  * Token 来源优先级:
@@ -16,13 +25,13 @@ import { rpcCache, CACHEABLE_METHODS } from "./rpc-cache";
16
25
  * 3. 默认值(开发用)
17
26
  */
18
27
  function resolveAuthToken(): string {
19
- if (typeof window !== "undefined") {
20
- const fromQuery = new URLSearchParams(window.location.search).get("token");
28
+ if (typeof window !== 'undefined') {
29
+ const fromQuery = new URLSearchParams(window.location.search).get('token');
21
30
  if (fromQuery) return fromQuery;
22
- const fromStorage = localStorage.getItem("rpc-auth-token");
31
+ const fromStorage = localStorage.getItem('rpc-auth-token');
23
32
  if (fromStorage) return fromStorage;
24
33
  }
25
- return "pi-agent-template-token";
34
+ return 'pi-agent-template-token';
26
35
  }
27
36
 
28
37
  const AUTH_TOKEN = resolveAuthToken();
@@ -30,7 +39,7 @@ const AUTH_TOKEN = resolveAuthToken();
30
39
  class APIClientImpl {
31
40
  private client: TypedClient<RPCMethods, RPCEvents> | null = null;
32
41
  private initPromise: Promise<void> | null = null;
33
- private _transport: "ipc" | "websocket" = "websocket";
42
+ private _transport: 'ipc' | 'websocket' = 'websocket';
34
43
  private _baseUrl: string | null = null;
35
44
  private wsTransport: WebSocketTransport | null = null;
36
45
 
@@ -41,7 +50,7 @@ class APIClientImpl {
41
50
  if (this.client) return;
42
51
 
43
52
  const ipcTransport = new IPCTransport();
44
- this._transport = "ipc";
53
+ this._transport = 'ipc';
45
54
  this._baseUrl = null;
46
55
  this.client = createTypedClient<RPCMethods, RPCEvents>(ipcTransport);
47
56
  this.setupElectrobunBridge(ipcTransport);
@@ -52,7 +61,7 @@ class APIClientImpl {
52
61
  */
53
62
  async initialize(): Promise<void> {
54
63
  // 已连接且 transport 正常 → 直接返回
55
- if (this.client && (this._transport === "ipc" || this.wsTransport?.isConnected())) {
64
+ if (this.client && (this._transport === 'ipc' || this.wsTransport?.isConnected())) {
56
65
  return;
57
66
  }
58
67
 
@@ -69,11 +78,11 @@ class APIClientImpl {
69
78
  this.initPromise = (async () => {
70
79
  const env = this.detectEnvironment();
71
80
 
72
- if (env === "electrobun") {
81
+ if (env === 'electrobun') {
73
82
  // 不应走到这里,桌面端应通过 initSyncForDesktop() 初始化
74
83
  this.initSyncForDesktop();
75
84
  } else {
76
- this._transport = "websocket";
85
+ this._transport = 'websocket';
77
86
  const wsUrl = this.getWebSocketUrl();
78
87
  this.wsTransport = new WebSocketTransport({
79
88
  url: wsUrl,
@@ -91,19 +100,19 @@ class APIClientImpl {
91
100
  return this.initPromise;
92
101
  }
93
102
 
94
- private detectEnvironment(): "electrobun" | "browser" {
95
- if (typeof window === "undefined") return "browser";
96
- if (window.__electrobunBunBridge) return "electrobun";
97
- return "browser";
103
+ private detectEnvironment(): 'electrobun' | 'browser' {
104
+ if (typeof window === 'undefined') return 'browser';
105
+ if (window.__electrobunBunBridge) return 'electrobun';
106
+ return 'browser';
98
107
  }
99
108
 
100
109
  private getWebSocketUrl(): string {
101
- if (typeof window === "undefined") return `ws://localhost:3100?token=${AUTH_TOKEN}`;
110
+ if (typeof window === 'undefined') return `ws://localhost:3100?token=${AUTH_TOKEN}`;
102
111
  const customUrl =
103
- new URLSearchParams(window.location.search).get("ws") ||
104
- localStorage.getItem("rpc-websocket-url");
112
+ new URLSearchParams(window.location.search).get('ws') ||
113
+ localStorage.getItem('rpc-websocket-url');
105
114
  if (customUrl)
106
- return customUrl.includes("token=") ? customUrl : `${customUrl}?token=${AUTH_TOKEN}`;
115
+ return customUrl.includes('token=') ? customUrl : `${customUrl}?token=${AUTH_TOKEN}`;
107
116
  return `ws://${window.location.host}/ws?token=${AUTH_TOKEN}`;
108
117
  }
109
118
 
@@ -113,7 +122,7 @@ class APIClientImpl {
113
122
  * - Browser → Bun: 通过 __electrobunBunBridge.postMessage 发送 Electrobun 消息格式
114
123
  */
115
124
  private setupElectrobunBridge(ipcTransport: IPCTransport): void {
116
- if (typeof window === "undefined") return;
125
+ if (typeof window === 'undefined') return;
117
126
 
118
127
  const win = window;
119
128
 
@@ -129,8 +138,8 @@ class APIClientImpl {
129
138
  ipcTransport.send = async (message: unknown) => {
130
139
  // 包装成 Electrobun message packet,bun 端 defineRPC 注册了 "rpc-message" handler
131
140
  const electrobunPacket = {
132
- type: "message",
133
- id: "rpc-message",
141
+ type: 'message',
142
+ id: 'rpc-message',
134
143
  payload: JSON.stringify(message),
135
144
  };
136
145
  bridge.postMessage(JSON.stringify(electrobunPacket));
@@ -138,7 +147,7 @@ class APIClientImpl {
138
147
  }
139
148
  }
140
149
 
141
- getTransport(): "ipc" | "websocket" {
150
+ getTransport(): 'ipc' | 'websocket' {
142
151
  return this._transport;
143
152
  }
144
153
 
@@ -154,7 +163,7 @@ class APIClientImpl {
154
163
 
155
164
  async call<K extends keyof RPCMethods>(
156
165
  method: K,
157
- params: MethodParams<RPCMethods, K>
166
+ params: MethodParams<RPCMethods, K>,
158
167
  ): Promise<MethodResult<RPCMethods, K>> {
159
168
  const methodStr = method as string;
160
169
  const ttl = CACHEABLE_METHODS[methodStr];
@@ -176,7 +185,7 @@ class APIClientImpl {
176
185
  async subscribe<K extends keyof RPCEvents>(
177
186
  eventType: K,
178
187
  handler: (payload: EventPayload<RPCEvents[K]>, metadata: EventMetadata<RPCEvents[K]>) => void,
179
- filter?: Record<string, unknown>
188
+ filter?: SubscribeFilter<K>,
180
189
  ): Promise<string> {
181
190
  await this.initialize();
182
191
  return this.client!.subscribe(eventType, handler, filter);