@dyyz1993/create-agent 1.9.0

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 (358) hide show
  1. package/package.json +25 -0
  2. package/src/__tests__/cli.test.ts +85 -0
  3. package/src/__tests__/copy.test.ts +168 -0
  4. package/src/__tests__/templates.test.ts +87 -0
  5. package/src/cli.ts +65 -0
  6. package/src/commands/create.ts +49 -0
  7. package/src/commands/list.ts +12 -0
  8. package/src/commands/status.ts +85 -0
  9. package/src/commands/workspace.ts +129 -0
  10. package/src/lib/copy.ts +285 -0
  11. package/src/lib/templates.ts +57 -0
  12. package/src/lib/types.ts +6 -0
  13. package/templates/agent/.env.example +7 -0
  14. package/templates/agent/LICENSE +21 -0
  15. package/templates/agent/README.md +87 -0
  16. package/templates/agent/bun.lock +1279 -0
  17. package/templates/agent/electrobun.config.ts +27 -0
  18. package/templates/agent/eslint.config.mjs +63 -0
  19. package/templates/agent/llms.txt +24 -0
  20. package/templates/agent/package-lock.json +3670 -0
  21. package/templates/agent/package.json +59 -0
  22. package/templates/agent/postcss.config.js +6 -0
  23. package/templates/agent/scripts/dev.ts +138 -0
  24. package/templates/agent/src/__tests__/server-config.test.ts +59 -0
  25. package/templates/agent/src/bun/index.ts +73 -0
  26. package/templates/agent/src/gateway/__tests__/ws-handler.test.ts +48 -0
  27. package/templates/agent/src/gateway/http-routes.ts +1 -0
  28. package/templates/agent/src/gateway/ipc-transport.ts +68 -0
  29. package/templates/agent/src/gateway/ws-handler.ts +86 -0
  30. package/templates/agent/src/mainview/App.tsx +41 -0
  31. package/templates/agent/src/mainview/__tests__/components/ChatPanel.test.tsx +114 -0
  32. package/templates/agent/src/mainview/__tests__/components/ExplorerSidebar.test.tsx +141 -0
  33. package/templates/agent/src/mainview/__tests__/components/MessageBubble.test.tsx +72 -0
  34. package/templates/agent/src/mainview/__tests__/hooks/use-input-history.test.ts +125 -0
  35. package/templates/agent/src/mainview/__tests__/hooks/use-rpc-init.test.ts +217 -0
  36. package/templates/agent/src/mainview/__tests__/hooks/use-sidebar-resize.test.ts +127 -0
  37. package/templates/agent/src/mainview/__tests__/i18n/i18n.test.ts +48 -0
  38. package/templates/agent/src/mainview/__tests__/setup.ts +37 -0
  39. package/templates/agent/src/mainview/__tests__/stores/use-chat-store.test.ts +83 -0
  40. package/templates/agent/src/mainview/__tests__/stores/use-sidebar-store.test.ts +85 -0
  41. package/templates/agent/src/mainview/components/activity-bar/ActivityBar.tsx +36 -0
  42. package/templates/agent/src/mainview/components/activity-bar/MobileTabBar.tsx +36 -0
  43. package/templates/agent/src/mainview/components/activity-bar/__tests__/ActivityBar.test.tsx +44 -0
  44. package/templates/agent/src/mainview/components/activity-bar/__tests__/MobileTabBar.test.tsx +44 -0
  45. package/templates/agent/src/mainview/components/bash/BashPanel.tsx +206 -0
  46. package/templates/agent/src/mainview/components/bash/__tests__/BashPanel.test.tsx +103 -0
  47. package/templates/agent/src/mainview/components/chat/ChatPanel.tsx +102 -0
  48. package/templates/agent/src/mainview/components/chat/MessageBubble.tsx +86 -0
  49. package/templates/agent/src/mainview/components/common/ErrorBoundary.tsx +58 -0
  50. package/templates/agent/src/mainview/components/common/LanguageSwitcher.tsx +14 -0
  51. package/templates/agent/src/mainview/components/common/ThemeToggle.tsx +24 -0
  52. package/templates/agent/src/mainview/components/common/__tests__/ErrorBoundary.test.tsx +74 -0
  53. package/templates/agent/src/mainview/components/common/__tests__/LanguageSwitcher.test.tsx +44 -0
  54. package/templates/agent/src/mainview/components/common/__tests__/ThemeToggle.test.tsx +41 -0
  55. package/templates/agent/src/mainview/components/debug/DebugPanel.tsx +120 -0
  56. package/templates/agent/src/mainview/components/debug/__tests__/DebugPanel.test.tsx +102 -0
  57. package/templates/agent/src/mainview/components/diff/DiffViewerPanel.tsx +106 -0
  58. package/templates/agent/src/mainview/components/diff/__tests__/DiffViewerPanel.test.tsx +73 -0
  59. package/templates/agent/src/mainview/components/explorer/ConfirmDialog.tsx +53 -0
  60. package/templates/agent/src/mainview/components/explorer/ContextMenu.tsx +82 -0
  61. package/templates/agent/src/mainview/components/explorer/ExplorerSidebar.tsx +221 -0
  62. package/templates/agent/src/mainview/components/explorer/InlineInput.tsx +55 -0
  63. package/templates/agent/src/mainview/components/explorer/TreeNodeItem.tsx +121 -0
  64. package/templates/agent/src/mainview/components/explorer/__tests__/ConfirmDialog.test.tsx +37 -0
  65. package/templates/agent/src/mainview/components/explorer/__tests__/ContextMenu.test.tsx +49 -0
  66. package/templates/agent/src/mainview/components/explorer/__tests__/InlineInput.test.tsx +48 -0
  67. package/templates/agent/src/mainview/components/explorer/__tests__/TreeNodeItem.test.tsx +146 -0
  68. package/templates/agent/src/mainview/components/feed/FeedPanel.tsx +239 -0
  69. package/templates/agent/src/mainview/components/feed/__tests__/FeedPanel.test.tsx +108 -0
  70. package/templates/agent/src/mainview/components/file-preview/FilePreviewOverlay.tsx +56 -0
  71. package/templates/agent/src/mainview/components/file-preview/VirtualizedCodeView.tsx +99 -0
  72. package/templates/agent/src/mainview/components/file-preview/__tests__/FilePreviewOverlay.test.tsx +96 -0
  73. package/templates/agent/src/mainview/components/file-preview/__tests__/VirtualizedCodeView.test.tsx +58 -0
  74. package/templates/agent/src/mainview/components/git/GitBranchSelector.tsx +98 -0
  75. package/templates/agent/src/mainview/components/git/GitCommitInput.tsx +60 -0
  76. package/templates/agent/src/mainview/components/git/GitPanel.tsx +528 -0
  77. package/templates/agent/src/mainview/components/git/__tests__/GitBranchSelector.test.tsx +76 -0
  78. package/templates/agent/src/mainview/components/git/__tests__/GitCommitInput.test.tsx +91 -0
  79. package/templates/agent/src/mainview/components/git/__tests__/GitPanel.test.tsx +174 -0
  80. package/templates/agent/src/mainview/components/layout/AppLayout.tsx +170 -0
  81. package/templates/agent/src/mainview/components/layout/__tests__/AppLayout.test.tsx +163 -0
  82. package/templates/agent/src/mainview/components/rules/RulesPanel.tsx +117 -0
  83. package/templates/agent/src/mainview/components/rules/__tests__/RulesPanel.test.tsx +91 -0
  84. package/templates/agent/src/mainview/components/search/SearchPanel.tsx +404 -0
  85. package/templates/agent/src/mainview/components/search/__tests__/SearchPanel.test.tsx +50 -0
  86. package/templates/agent/src/mainview/components/sidebar/PinButton.tsx +20 -0
  87. package/templates/agent/src/mainview/components/sidebar/__tests__/PinButton.test.tsx +48 -0
  88. package/templates/agent/src/mainview/components/todo/TodoPanel.tsx +141 -0
  89. package/templates/agent/src/mainview/components/todo/__tests__/TodoPanel.test.tsx +91 -0
  90. package/templates/agent/src/mainview/global.d.ts +13 -0
  91. package/templates/agent/src/mainview/hooks/__tests__/use-breakpoint.test.ts +147 -0
  92. package/templates/agent/src/mainview/hooks/use-breakpoint.ts +34 -0
  93. package/templates/agent/src/mainview/hooks/use-input-history.ts +84 -0
  94. package/templates/agent/src/mainview/hooks/use-rpc-init.ts +61 -0
  95. package/templates/agent/src/mainview/hooks/use-sidebar-resize.ts +40 -0
  96. package/templates/agent/src/mainview/index.css +61 -0
  97. package/templates/agent/src/mainview/index.html +12 -0
  98. package/templates/agent/src/mainview/lib/api-client.ts +192 -0
  99. package/templates/agent/src/mainview/lib/i18n/index.ts +30 -0
  100. package/templates/agent/src/mainview/lib/i18n/locales/en.json +157 -0
  101. package/templates/agent/src/mainview/lib/i18n/locales/zh.json +157 -0
  102. package/templates/agent/src/mainview/lib/rpc-cache.ts +94 -0
  103. package/templates/agent/src/mainview/main.tsx +24 -0
  104. package/templates/agent/src/mainview/stores/__tests__/use-app-store.test.ts +86 -0
  105. package/templates/agent/src/mainview/stores/__tests__/use-bash-store.test.ts +99 -0
  106. package/templates/agent/src/mainview/stores/__tests__/use-connection-store.test.ts +26 -0
  107. package/templates/agent/src/mainview/stores/__tests__/use-explorer-store.test.ts +130 -0
  108. package/templates/agent/src/mainview/stores/__tests__/use-feed-store.test.ts +132 -0
  109. package/templates/agent/src/mainview/stores/__tests__/use-git-store.test.ts +161 -0
  110. package/templates/agent/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  111. package/templates/agent/src/mainview/stores/__tests__/use-log-store.test.ts +28 -0
  112. package/templates/agent/src/mainview/stores/__tests__/use-notification-store.test.ts +102 -0
  113. package/templates/agent/src/mainview/stores/__tests__/use-rules-store.test.ts +75 -0
  114. package/templates/agent/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  115. package/templates/agent/src/mainview/stores/__tests__/use-todo-store.test.ts +75 -0
  116. package/templates/agent/src/mainview/stores/message-batcher.ts +25 -0
  117. package/templates/agent/src/mainview/stores/use-app-store.ts +99 -0
  118. package/templates/agent/src/mainview/stores/use-bash-store.ts +93 -0
  119. package/templates/agent/src/mainview/stores/use-chat-store.ts +37 -0
  120. package/templates/agent/src/mainview/stores/use-connection-store.ts +42 -0
  121. package/templates/agent/src/mainview/stores/use-explorer-store.ts +320 -0
  122. package/templates/agent/src/mainview/stores/use-feed-store.ts +129 -0
  123. package/templates/agent/src/mainview/stores/use-git-store.ts +291 -0
  124. package/templates/agent/src/mainview/stores/use-locale-store.ts +27 -0
  125. package/templates/agent/src/mainview/stores/use-log-store.ts +16 -0
  126. package/templates/agent/src/mainview/stores/use-notification-store.ts +82 -0
  127. package/templates/agent/src/mainview/stores/use-rules-store.ts +54 -0
  128. package/templates/agent/src/mainview/stores/use-sidebar-store.ts +99 -0
  129. package/templates/agent/src/mainview/stores/use-theme-store.ts +46 -0
  130. package/templates/agent/src/mainview/stores/use-todo-store.ts +54 -0
  131. package/templates/agent/src/mainview/types/index.ts +33 -0
  132. package/templates/agent/src/mainview/utils/constants.ts +1 -0
  133. package/templates/agent/src/mainview/utils/drop-handler.ts +150 -0
  134. package/templates/agent/src/mainview/utils/file-icon.tsx +24 -0
  135. package/templates/agent/src/mainview/utils/file-utils.ts +35 -0
  136. package/templates/agent/src/server-config.ts +43 -0
  137. package/templates/agent/src/server.ts +89 -0
  138. package/templates/agent/src/shared/handlers/__tests__/bash-handler.test.ts +135 -0
  139. package/templates/agent/src/shared/handlers/__tests__/chat-handler.test.ts +77 -0
  140. package/templates/agent/src/shared/handlers/__tests__/feed-handler.test.ts +108 -0
  141. package/templates/agent/src/shared/handlers/__tests__/file-handler.test.ts +100 -0
  142. package/templates/agent/src/shared/handlers/__tests__/system-handler.test.ts +55 -0
  143. package/templates/agent/src/shared/handlers/__tests__/timer-handler.test.ts +77 -0
  144. package/templates/agent/src/shared/handlers/bash.ts +89 -0
  145. package/templates/agent/src/shared/handlers/chat.ts +179 -0
  146. package/templates/agent/src/shared/handlers/feed.ts +53 -0
  147. package/templates/agent/src/shared/handlers/file.ts +99 -0
  148. package/templates/agent/src/shared/handlers/git.ts +263 -0
  149. package/templates/agent/src/shared/handlers/index.ts +10 -0
  150. package/templates/agent/src/shared/handlers/rules.ts +45 -0
  151. package/templates/agent/src/shared/handlers/system.ts +27 -0
  152. package/templates/agent/src/shared/handlers/timer.ts +34 -0
  153. package/templates/agent/src/shared/handlers/todo.ts +45 -0
  154. package/templates/agent/src/shared/lib/__tests__/bash-security.test.ts +125 -0
  155. package/templates/agent/src/shared/lib/__tests__/logger.test.ts +92 -0
  156. package/templates/agent/src/shared/lib/__tests__/path-security.test.ts +77 -0
  157. package/templates/agent/src/shared/lib/bash-security.ts +64 -0
  158. package/templates/agent/src/shared/lib/logger.ts +130 -0
  159. package/templates/agent/src/shared/lib/path-security.ts +38 -0
  160. package/templates/agent/src/shared/lib/port-registry.ts +103 -0
  161. package/templates/agent/src/shared/modules/bash.ts +19 -0
  162. package/templates/agent/src/shared/modules/chat.ts +20 -0
  163. package/templates/agent/src/shared/modules/feed.ts +30 -0
  164. package/templates/agent/src/shared/modules/file.ts +40 -0
  165. package/templates/agent/src/shared/modules/git.ts +81 -0
  166. package/templates/agent/src/shared/modules/rules.ts +25 -0
  167. package/templates/agent/src/shared/modules/system.ts +8 -0
  168. package/templates/agent/src/shared/modules/timer.ts +11 -0
  169. package/templates/agent/src/shared/modules/todo.ts +27 -0
  170. package/templates/agent/src/shared/register-all-handlers.ts +36 -0
  171. package/templates/agent/src/shared/rpc-schema.ts +35 -0
  172. package/templates/agent/tailwind.config.js +15 -0
  173. package/templates/agent/tsconfig.json +26 -0
  174. package/templates/agent/vite.config.ts +3 -0
  175. package/templates/agent/vitest.config.ts +3 -0
  176. package/templates/chat/.env.example +6 -0
  177. package/templates/chat/LICENSE +21 -0
  178. package/templates/chat/README.md +56 -0
  179. package/templates/chat/bun.lock +1203 -0
  180. package/templates/chat/electrobun.config.ts +27 -0
  181. package/templates/chat/eslint.config.mjs +56 -0
  182. package/templates/chat/llms.txt +24 -0
  183. package/templates/chat/package-lock.json +3670 -0
  184. package/templates/chat/package.json +58 -0
  185. package/templates/chat/postcss.config.js +6 -0
  186. package/templates/chat/scripts/dev.ts +138 -0
  187. package/templates/chat/src/__tests__/server-config.test.ts +59 -0
  188. package/templates/chat/src/bun/index.ts +72 -0
  189. package/templates/chat/src/gateway/__tests__/ws-handler.test.ts +48 -0
  190. package/templates/chat/src/gateway/http-routes.ts +1 -0
  191. package/templates/chat/src/gateway/ipc-transport.ts +68 -0
  192. package/templates/chat/src/gateway/ws-handler.ts +86 -0
  193. package/templates/chat/src/mainview/App.tsx +108 -0
  194. package/templates/chat/src/mainview/__tests__/components/ChatPanel.test.tsx +76 -0
  195. package/templates/chat/src/mainview/__tests__/components/MessageBubble.test.tsx +48 -0
  196. package/templates/chat/src/mainview/__tests__/i18n/i18n.test.ts +48 -0
  197. package/templates/chat/src/mainview/__tests__/setup-verify.test.ts +8 -0
  198. package/templates/chat/src/mainview/__tests__/setup.ts +37 -0
  199. package/templates/chat/src/mainview/__tests__/stores/use-app-store.test.ts +46 -0
  200. package/templates/chat/src/mainview/__tests__/stores/use-chat-store.test.ts +104 -0
  201. package/templates/chat/src/mainview/__tests__/stores/use-connection-store.test.ts +35 -0
  202. package/templates/chat/src/mainview/__tests__/stores/use-log-store.test.ts +45 -0
  203. package/templates/chat/src/mainview/__tests__/stores/use-notification-store.test.ts +102 -0
  204. package/templates/chat/src/mainview/__tests__/stores/use-sidebar-store.test.ts +89 -0
  205. package/templates/chat/src/mainview/components/activity-bar/ActivityBar.tsx +26 -0
  206. package/templates/chat/src/mainview/components/activity-bar/MobileTabBar.tsx +20 -0
  207. package/templates/chat/src/mainview/components/chat/ChatPanel.tsx +66 -0
  208. package/templates/chat/src/mainview/components/chat/MessageBubble.tsx +85 -0
  209. package/templates/chat/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
  210. package/templates/chat/src/mainview/components/common/ThemeToggle.tsx +24 -0
  211. package/templates/chat/src/mainview/components/sidebar/PinButton.tsx +20 -0
  212. package/templates/chat/src/mainview/global.d.ts +13 -0
  213. package/templates/chat/src/mainview/hooks/use-breakpoint.ts +34 -0
  214. package/templates/chat/src/mainview/hooks/use-input-history.ts +84 -0
  215. package/templates/chat/src/mainview/index.css +61 -0
  216. package/templates/chat/src/mainview/index.html +12 -0
  217. package/templates/chat/src/mainview/lib/api-client.ts +175 -0
  218. package/templates/chat/src/mainview/lib/i18n/index.ts +30 -0
  219. package/templates/chat/src/mainview/lib/i18n/locales/en.json +157 -0
  220. package/templates/chat/src/mainview/lib/i18n/locales/zh.json +157 -0
  221. package/templates/chat/src/mainview/main.tsx +20 -0
  222. package/templates/chat/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  223. package/templates/chat/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  224. package/templates/chat/src/mainview/stores/message-batcher.ts +25 -0
  225. package/templates/chat/src/mainview/stores/use-app-store.ts +50 -0
  226. package/templates/chat/src/mainview/stores/use-chat-store.ts +37 -0
  227. package/templates/chat/src/mainview/stores/use-connection-store.ts +42 -0
  228. package/templates/chat/src/mainview/stores/use-locale-store.ts +27 -0
  229. package/templates/chat/src/mainview/stores/use-log-store.ts +16 -0
  230. package/templates/chat/src/mainview/stores/use-notification-store.ts +82 -0
  231. package/templates/chat/src/mainview/stores/use-sidebar-store.ts +98 -0
  232. package/templates/chat/src/mainview/stores/use-theme-store.ts +46 -0
  233. package/templates/chat/src/mainview/types/index.ts +8 -0
  234. package/templates/chat/src/mainview/utils/constants.ts +1 -0
  235. package/templates/chat/src/server-config.ts +42 -0
  236. package/templates/chat/src/server.ts +89 -0
  237. package/templates/chat/src/shared/__tests__/chat-handler.test.ts +71 -0
  238. package/templates/chat/src/shared/__tests__/system-handler.test.ts +70 -0
  239. package/templates/chat/src/shared/handlers/chat.ts +186 -0
  240. package/templates/chat/src/shared/handlers/index.ts +2 -0
  241. package/templates/chat/src/shared/handlers/system.ts +27 -0
  242. package/templates/chat/src/shared/lib/logger.ts +130 -0
  243. package/templates/chat/src/shared/lib/path-security.ts +38 -0
  244. package/templates/chat/src/shared/lib/port-registry.ts +103 -0
  245. package/templates/chat/src/shared/modules/chat.ts +20 -0
  246. package/templates/chat/src/shared/modules/system.ts +8 -0
  247. package/templates/chat/src/shared/register-all-handlers.ts +36 -0
  248. package/templates/chat/src/shared/rpc-schema.ts +11 -0
  249. package/templates/chat/tailwind.config.js +15 -0
  250. package/templates/chat/tsconfig.json +26 -0
  251. package/templates/chat/vite.config.ts +3 -0
  252. package/templates/chat/vitest.config.ts +3 -0
  253. package/templates/general/.env.example +7 -0
  254. package/templates/general/LICENSE +21 -0
  255. package/templates/general/README.md +113 -0
  256. package/templates/general/bun.lock +1266 -0
  257. package/templates/general/electrobun.config.ts +27 -0
  258. package/templates/general/eslint.config.mjs +56 -0
  259. package/templates/general/llms.txt +24 -0
  260. package/templates/general/package-lock.json +3670 -0
  261. package/templates/general/package.json +59 -0
  262. package/templates/general/postcss.config.js +6 -0
  263. package/templates/general/scripts/dev.ts +138 -0
  264. package/templates/general/src/__tests__/server-config.test.ts +59 -0
  265. package/templates/general/src/bun/index.ts +72 -0
  266. package/templates/general/src/gateway/http-routes.ts +1 -0
  267. package/templates/general/src/gateway/ipc-transport.ts +68 -0
  268. package/templates/general/src/gateway/ws-handler.ts +86 -0
  269. package/templates/general/src/mainview/App.tsx +40 -0
  270. package/templates/general/src/mainview/__tests__/components/ChatPanel.test.tsx +82 -0
  271. package/templates/general/src/mainview/__tests__/components/FeedPanel.test.tsx +109 -0
  272. package/templates/general/src/mainview/__tests__/components/GitPanel.test.tsx +151 -0
  273. package/templates/general/src/mainview/__tests__/i18n/i18n.test.ts +48 -0
  274. package/templates/general/src/mainview/__tests__/setup-verify.test.ts +8 -0
  275. package/templates/general/src/mainview/__tests__/setup.ts +37 -0
  276. package/templates/general/src/mainview/components/activity-bar/ActivityBar.tsx +40 -0
  277. package/templates/general/src/mainview/components/activity-bar/MobileTabBar.tsx +29 -0
  278. package/templates/general/src/mainview/components/chat/ChatPanel.tsx +66 -0
  279. package/templates/general/src/mainview/components/chat/MessageBubble.tsx +85 -0
  280. package/templates/general/src/mainview/components/common/LanguageSwitcher.tsx +15 -0
  281. package/templates/general/src/mainview/components/common/ThemeToggle.tsx +24 -0
  282. package/templates/general/src/mainview/components/debug/DebugPanel.tsx +176 -0
  283. package/templates/general/src/mainview/components/diff/DiffViewerPanel.tsx +108 -0
  284. package/templates/general/src/mainview/components/explorer/ConfirmDialog.tsx +52 -0
  285. package/templates/general/src/mainview/components/explorer/ContextMenu.tsx +82 -0
  286. package/templates/general/src/mainview/components/explorer/ExplorerSidebar.tsx +225 -0
  287. package/templates/general/src/mainview/components/explorer/InlineInput.tsx +55 -0
  288. package/templates/general/src/mainview/components/explorer/TreeNodeItem.tsx +121 -0
  289. package/templates/general/src/mainview/components/feed/FeedPanel.tsx +248 -0
  290. package/templates/general/src/mainview/components/file-preview/FilePreviewOverlay.tsx +55 -0
  291. package/templates/general/src/mainview/components/file-preview/VirtualizedCodeView.tsx +99 -0
  292. package/templates/general/src/mainview/components/git/GitBranchSelector.tsx +93 -0
  293. package/templates/general/src/mainview/components/git/GitCommitInput.tsx +60 -0
  294. package/templates/general/src/mainview/components/git/GitPanel.tsx +533 -0
  295. package/templates/general/src/mainview/components/layout/AppLayout.tsx +146 -0
  296. package/templates/general/src/mainview/components/search/SearchPanel.tsx +405 -0
  297. package/templates/general/src/mainview/components/sidebar/PinButton.tsx +20 -0
  298. package/templates/general/src/mainview/global.d.ts +13 -0
  299. package/templates/general/src/mainview/hooks/use-breakpoint.ts +34 -0
  300. package/templates/general/src/mainview/hooks/use-input-history.ts +84 -0
  301. package/templates/general/src/mainview/hooks/use-rpc-init.ts +61 -0
  302. package/templates/general/src/mainview/hooks/use-sidebar-resize.ts +40 -0
  303. package/templates/general/src/mainview/index.css +61 -0
  304. package/templates/general/src/mainview/index.html +12 -0
  305. package/templates/general/src/mainview/lib/api-client.ts +175 -0
  306. package/templates/general/src/mainview/lib/i18n/index.ts +30 -0
  307. package/templates/general/src/mainview/lib/i18n/locales/en.json +157 -0
  308. package/templates/general/src/mainview/lib/i18n/locales/zh.json +157 -0
  309. package/templates/general/src/mainview/main.tsx +20 -0
  310. package/templates/general/src/mainview/stores/__tests__/use-chat-store.test.ts +104 -0
  311. package/templates/general/src/mainview/stores/__tests__/use-connection-store.test.ts +35 -0
  312. package/templates/general/src/mainview/stores/__tests__/use-locale-store.test.ts +32 -0
  313. package/templates/general/src/mainview/stores/__tests__/use-log-store.test.ts +45 -0
  314. package/templates/general/src/mainview/stores/__tests__/use-theme-store.test.ts +59 -0
  315. package/templates/general/src/mainview/stores/message-batcher.ts +25 -0
  316. package/templates/general/src/mainview/stores/use-app-store.ts +104 -0
  317. package/templates/general/src/mainview/stores/use-chat-store.ts +37 -0
  318. package/templates/general/src/mainview/stores/use-connection-store.ts +42 -0
  319. package/templates/general/src/mainview/stores/use-explorer-store.ts +315 -0
  320. package/templates/general/src/mainview/stores/use-feed-store.ts +129 -0
  321. package/templates/general/src/mainview/stores/use-git-store.ts +284 -0
  322. package/templates/general/src/mainview/stores/use-locale-store.ts +27 -0
  323. package/templates/general/src/mainview/stores/use-log-store.ts +16 -0
  324. package/templates/general/src/mainview/stores/use-notification-store.ts +82 -0
  325. package/templates/general/src/mainview/stores/use-sidebar-store.ts +99 -0
  326. package/templates/general/src/mainview/stores/use-theme-store.ts +46 -0
  327. package/templates/general/src/mainview/types/index.ts +33 -0
  328. package/templates/general/src/mainview/utils/constants.ts +1 -0
  329. package/templates/general/src/mainview/utils/drop-handler.ts +150 -0
  330. package/templates/general/src/mainview/utils/file-icon.tsx +24 -0
  331. package/templates/general/src/mainview/utils/file-utils.ts +35 -0
  332. package/templates/general/src/server-config.ts +42 -0
  333. package/templates/general/src/server.ts +89 -0
  334. package/templates/general/src/shared/handlers/__tests__/chat.test.ts +183 -0
  335. package/templates/general/src/shared/handlers/__tests__/system.test.ts +94 -0
  336. package/templates/general/src/shared/handlers/__tests__/timer.test.ts +113 -0
  337. package/templates/general/src/shared/handlers/chat.ts +179 -0
  338. package/templates/general/src/shared/handlers/feed.ts +53 -0
  339. package/templates/general/src/shared/handlers/file.ts +99 -0
  340. package/templates/general/src/shared/handlers/git.ts +263 -0
  341. package/templates/general/src/shared/handlers/index.ts +7 -0
  342. package/templates/general/src/shared/handlers/system.ts +27 -0
  343. package/templates/general/src/shared/handlers/timer.ts +34 -0
  344. package/templates/general/src/shared/lib/logger.ts +130 -0
  345. package/templates/general/src/shared/lib/path-security.ts +38 -0
  346. package/templates/general/src/shared/lib/port-registry.ts +103 -0
  347. package/templates/general/src/shared/modules/chat.ts +20 -0
  348. package/templates/general/src/shared/modules/feed.ts +30 -0
  349. package/templates/general/src/shared/modules/file.ts +40 -0
  350. package/templates/general/src/shared/modules/git.ts +81 -0
  351. package/templates/general/src/shared/modules/system.ts +8 -0
  352. package/templates/general/src/shared/modules/timer.ts +11 -0
  353. package/templates/general/src/shared/register-all-handlers.ts +36 -0
  354. package/templates/general/src/shared/rpc-schema.ts +31 -0
  355. package/templates/general/tailwind.config.js +15 -0
  356. package/templates/general/tsconfig.json +26 -0
  357. package/templates/general/vite.config.ts +3 -0
  358. package/templates/general/vitest.config.ts +3 -0
@@ -0,0 +1,2 @@
1
+ export { register as system } from "./system";
2
+ export { register as chat } from "./chat";
@@ -0,0 +1,27 @@
1
+ import type { RPCServer } from "@dyyz1993/rpc-core";
2
+ import type { MethodParams, MethodResult } from "@dyyz1993/rpc-core";
3
+ import type { RPCMethods, HandlerOptions } from "../rpc-schema";
4
+
5
+ type RegisterFn = <K extends keyof RPCMethods & string>(
6
+ method: K,
7
+ handler: (params: MethodParams<RPCMethods, K>) => Promise<MethodResult<RPCMethods, K>>,
8
+ ) => void;
9
+
10
+ export function register(server: RPCServer, options: HandlerOptions): void {
11
+ const r: RegisterFn = (method, handler) => {
12
+ server.register(method, handler as (params: unknown) => Promise<unknown>);
13
+ };
14
+
15
+ r("system.ping", async () => ({
16
+ pong: true,
17
+ timestamp: Date.now(),
18
+ platform: options.platform,
19
+ }));
20
+
21
+ r("system.hello", async (params) => ({
22
+ message: `Hello ${params.name || "World"}!`,
23
+ timestamp: Date.now(),
24
+ }));
25
+
26
+ r("system.echo", async (params) => params);
27
+ }
@@ -0,0 +1,130 @@
1
+ import { appendFile, mkdir as mkdirAsync, readdir as readdirAsync, unlink as unlinkAsync, stat as statAsync } from "fs/promises";
2
+ import { mkdirSync, existsSync } from "fs";
3
+ import { join } from "path";
4
+
5
+ export type LogModule = "server" | "gateway" | "system" | "chat";
6
+ type LogLevel = "debug" | "info" | "warn" | "error";
7
+
8
+ interface LogEntry {
9
+ timestamp: string;
10
+ level: LogLevel;
11
+ module: LogModule;
12
+ message: string;
13
+ data?: Record<string, unknown>;
14
+ }
15
+
16
+ let _logDir: string | null = null;
17
+ let _maxAgeDays = 30;
18
+
19
+ export async function configureLogDir(dir: string, options?: { maxAgeDays?: number }): Promise<void> {
20
+ _logDir = dir;
21
+ if (options?.maxAgeDays !== undefined) {
22
+ _maxAgeDays = options.maxAgeDays;
23
+ }
24
+ if (!existsSync(dir)) {
25
+ mkdirSync(dir, { recursive: true });
26
+ }
27
+ await cleanOldLogs(dir, _maxAgeDays);
28
+ }
29
+
30
+ function getLogDir(): string {
31
+ if (!_logDir) {
32
+ _logDir = "logs";
33
+ if (!existsSync(_logDir)) {
34
+ mkdirSync(_logDir, { recursive: true });
35
+ }
36
+ }
37
+ return _logDir;
38
+ }
39
+
40
+ async function cleanOldLogs(dir: string, maxAgeDays: number): Promise<void> {
41
+ try {
42
+ if (!existsSync(dir)) return;
43
+ const files = await readdirAsync(dir);
44
+ const cutoff = Date.now() - maxAgeDays * 86400000;
45
+ for (const f of files) {
46
+ if (!f.endsWith(".log")) continue;
47
+ const filePath = join(dir, f);
48
+ const s = await statAsync(filePath);
49
+ if (s.mtimeMs < cutoff) {
50
+ await unlinkAsync(filePath);
51
+ }
52
+ }
53
+ } catch { /* ignore */ }
54
+ }
55
+
56
+ function formatLine(entry: LogEntry): string {
57
+ const base = `[${entry.timestamp}] [${entry.level.toUpperCase()}] [${entry.module}] ${entry.message}`;
58
+ return entry.data ? `${base} ${JSON.stringify(entry.data)}` : base;
59
+ }
60
+
61
+ let writeQueue: Promise<void> = Promise.resolve();
62
+
63
+ function writeToFile(line: string): void {
64
+ writeQueue = writeQueue.then(async () => {
65
+ try {
66
+ const date = new Date().toISOString().slice(0, 10);
67
+ const dir = getLogDir();
68
+ if (!existsSync(dir)) {
69
+ await mkdirAsync(dir, { recursive: true });
70
+ }
71
+ await appendFile(join(dir, `${date}.log`), `${line}\n`);
72
+ } catch { /* ignore */ }
73
+ });
74
+ }
75
+
76
+ export function flushLogs(): Promise<void> {
77
+ return writeQueue;
78
+ }
79
+
80
+ export class Logger {
81
+ private readonly module: LogModule;
82
+
83
+ constructor(module: LogModule) {
84
+ this.module = module;
85
+ }
86
+
87
+ debug(message: string, data?: Record<string, unknown>): void {
88
+ this.write("debug", message, data);
89
+ }
90
+
91
+ info(message: string, data?: Record<string, unknown>): void {
92
+ this.write("info", message, data);
93
+ }
94
+
95
+ warn(message: string, data?: Record<string, unknown>): void {
96
+ this.write("warn", message, data);
97
+ }
98
+
99
+ error(message: string, data?: Record<string, unknown>): void {
100
+ this.write("error", message, data);
101
+ }
102
+
103
+ private write(level: LogLevel, message: string, data?: Record<string, unknown>): void {
104
+ const entry: LogEntry = {
105
+ timestamp: new Date().toISOString(),
106
+ level,
107
+ module: this.module,
108
+ message,
109
+ ...(data ? { data } : {}),
110
+ };
111
+
112
+ const line = formatLine(entry);
113
+
114
+ if (level === "error") {
115
+ console.error(line);
116
+ } else if (level === "warn") {
117
+ console.warn(line);
118
+ } else {
119
+ console.log(line);
120
+ }
121
+
122
+ if (process.env.NODE_ENV !== "production" || level !== "debug") {
123
+ writeToFile(line);
124
+ }
125
+ }
126
+ }
127
+
128
+ export function createLogger(module: LogModule): Logger {
129
+ return new Logger(module);
130
+ }
@@ -0,0 +1,38 @@
1
+ import { resolve } from "path";
2
+
3
+ let allowedRoots: string[] = [process.cwd()];
4
+
5
+ export function setAllowedRoots(roots: string[]): void {
6
+ allowedRoots = roots.map((r) => resolve(r));
7
+ }
8
+
9
+ export function isRpcPathAllowed(requestedPath: string): boolean {
10
+ try {
11
+ if (requestedPath.includes("\0")) return false;
12
+
13
+ const decoded = decodeURIComponent(requestedPath);
14
+ const resolved = resolve(decoded);
15
+ return allowedRoots.some(
16
+ (root) => resolved === root || resolved.startsWith(root + "/")
17
+ );
18
+ } catch {
19
+ return false;
20
+ }
21
+ }
22
+
23
+ export function validatePath(requestedPath: string): string {
24
+ if (requestedPath.includes("\0")) {
25
+ throw new Error(`Access denied: path contains null bytes`);
26
+ }
27
+
28
+ const decoded = decodeURIComponent(requestedPath);
29
+ const resolved = resolve(decoded);
30
+
31
+ if (!isRpcPathAllowed(resolved)) {
32
+ throw new Error(
33
+ `Access denied: path "${requestedPath}" is outside allowed roots`
34
+ );
35
+ }
36
+
37
+ return resolved;
38
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Global port registry — tracks all running pi-agent instances.
3
+ *
4
+ * File: ~/.pi-agent/ports.json
5
+ *
6
+ * Format:
7
+ * {
8
+ * "/absolute/project/path": {
9
+ * "port": 3101,
10
+ * "pid": 12345,
11
+ * "startedAt": "2026-04-29T08:00:00.000Z",
12
+ * "name": "my-project"
13
+ * }
14
+ * }
15
+ */
16
+
17
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
18
+ import { join, basename } from "path";
19
+ import { homedir } from "os";
20
+
21
+ const REGISTRY_DIR = join(homedir(), ".pi-agent");
22
+ const REGISTRY_FILE = join(REGISTRY_DIR, "ports.json");
23
+
24
+ export interface PortEntry {
25
+ port: number;
26
+ pid: number;
27
+ startedAt: string;
28
+ name: string;
29
+ }
30
+
31
+ export type PortRegistry = Record<string, PortEntry>;
32
+
33
+ function ensureDir() {
34
+ if (!existsSync(REGISTRY_DIR)) {
35
+ mkdirSync(REGISTRY_DIR, { recursive: true });
36
+ }
37
+ }
38
+
39
+ export function readRegistry(): PortRegistry {
40
+ try {
41
+ if (!existsSync(REGISTRY_FILE)) return {};
42
+ return JSON.parse(readFileSync(REGISTRY_FILE, "utf-8"));
43
+ } catch {
44
+ return {};
45
+ }
46
+ }
47
+
48
+ function writeRegistry(registry: PortRegistry): void {
49
+ ensureDir();
50
+ writeFileSync(REGISTRY_FILE, JSON.stringify(registry, null, 2), "utf-8");
51
+ }
52
+
53
+ export function registerPort(projectPath: string, port: number, name: string): void {
54
+ const registry = readRegistry();
55
+ registry[projectPath] = {
56
+ port,
57
+ pid: process.pid,
58
+ startedAt: new Date().toISOString(),
59
+ name: name || basename(projectPath),
60
+ };
61
+ writeRegistry(registry);
62
+ }
63
+
64
+ export function unregisterPort(projectPath: string): void {
65
+ const registry = readRegistry();
66
+ delete registry[projectPath];
67
+ if (Object.keys(registry).length === 0) {
68
+ writeRegistry(registry);
69
+ } else {
70
+ writeRegistry(registry);
71
+ }
72
+ }
73
+
74
+ export function cleanupStaleEntries(): void {
75
+ const registry = readRegistry();
76
+ let changed = false;
77
+ for (const [path, entry] of Object.entries(registry)) {
78
+ try {
79
+ process.kill(entry.pid, 0);
80
+ } catch {
81
+ delete registry[path];
82
+ changed = true;
83
+ }
84
+ }
85
+ if (changed) writeRegistry(registry);
86
+ }
87
+
88
+ export function formatRegistryForOutput(): string {
89
+ cleanupStaleEntries();
90
+ const registry = readRegistry();
91
+ const entries = Object.entries(registry);
92
+ if (entries.length === 0) return "No active instances.";
93
+
94
+ const lines = entries.map(([path, entry]) => {
95
+ const uptime = Math.round((Date.now() - new Date(entry.startedAt).getTime()) / 1000);
96
+ const uptimeStr = uptime < 60 ? `${uptime}s` : uptime < 3600 ? `${Math.floor(uptime / 60)}m ${uptime % 60}s` : `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`;
97
+ return ` ${entry.name} → http://localhost:${entry.port} (PID ${entry.pid}, up ${uptimeStr})\n ${path}`;
98
+ });
99
+
100
+ return `Active pi-agent instances (${entries.length}):\n${lines.join("\n\n")}\n\nRegistry: ${REGISTRY_FILE}`;
101
+ }
102
+
103
+ export { REGISTRY_FILE };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Chat 模块 — 聊天消息
3
+ */
4
+ export interface ChatMethods {
5
+ "chat.list": {
6
+ params: { limit?: number; cursor?: string };
7
+ result: {
8
+ messages: { id: string; role: "user" | "assistant"; content: string; timestamp: number }[];
9
+ hasMore: boolean;
10
+ };
11
+ };
12
+ "chat.send": {
13
+ params: { content: string };
14
+ result: { ok: boolean };
15
+ };
16
+ }
17
+
18
+ export interface ChatEvents {
19
+ "chat.message": { id: string; role: "user" | "assistant"; content: string; timestamp: number };
20
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * System 模块 — 基础连通性 & 调试
3
+ */
4
+ export interface SystemMethods {
5
+ "system.ping": { params: {}; result: { pong: boolean; timestamp: number; platform: string } };
6
+ "system.hello": { params: { name?: string }; result: { message: string; timestamp: number } };
7
+ "system.echo": { params: unknown; result: unknown };
8
+ }
@@ -0,0 +1,36 @@
1
+ import { RPCServer, type Transport } from "@dyyz1993/rpc-core";
2
+ import type { HandlerOptions } from "./rpc-schema";
3
+ import * as handlers from "./handlers/index";
4
+
5
+ type RegisterFn = (server: RPCServer, options: HandlerOptions) => void;
6
+
7
+ /**
8
+ * 自动注册所有 handlers — 从 handlers/index.ts barrel 导入
9
+ *
10
+ * 新增模块:在 handlers/ 创建文件,并在 handlers/index.ts 加一行 export
11
+ */
12
+ export function registerAllHandlers(server: RPCServer, options: HandlerOptions): void {
13
+ for (const mod of Object.values(handlers) as RegisterFn[]) {
14
+ mod(server, options);
15
+ }
16
+ }
17
+
18
+ const noopTransport: Transport = {
19
+ send: async () => {},
20
+ onMessage: () => () => {},
21
+ onError: () => () => {},
22
+ onDisconnect: () => () => {},
23
+ isConnected: () => false,
24
+ close: () => {},
25
+ };
26
+
27
+ let _cachedMethods: string[] | null = null;
28
+
29
+ export function discoverMethodNames(): string[] {
30
+ if (_cachedMethods) return _cachedMethods;
31
+ const server = new RPCServer(noopTransport);
32
+ registerAllHandlers(server, { platform: "web" });
33
+ _cachedMethods = server.getRegisteredMethods();
34
+ server.close();
35
+ return _cachedMethods;
36
+ }
@@ -0,0 +1,11 @@
1
+ import type { AnyMethods } from "@dyyz1993/rpc-core";
2
+ import type { SystemMethods } from "./modules/system";
3
+ import type { ChatMethods, ChatEvents } from "./modules/chat";
4
+
5
+ export interface RPCMethods extends AnyMethods, SystemMethods, ChatMethods {}
6
+
7
+ export interface RPCEvents extends ChatEvents {}
8
+
9
+ export interface HandlerOptions {
10
+ platform: "desktop" | "web";
11
+ }
@@ -0,0 +1,15 @@
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ darkMode: "class",
4
+ content: ["./src/mainview/**/*.{html,js,ts,jsx,tsx}"],
5
+ theme: {
6
+ extend: {
7
+ colors: {
8
+ gray: {
9
+ 850: "#1f2937",
10
+ },
11
+ },
12
+ },
13
+ },
14
+ plugins: [],
15
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+ "moduleResolution": "bundler",
9
+ "allowImportingTsExtensions": true,
10
+ "isolatedModules": true,
11
+ "moduleDetection": "force",
12
+ "noEmit": true,
13
+ "jsx": "react-jsx",
14
+ "strict": true,
15
+ "noUnusedLocals": true,
16
+ "noUnusedParameters": true,
17
+ "noFallthroughCasesInSwitch": true,
18
+ "baseUrl": ".",
19
+ "paths": {
20
+ "@dyyz1993/rpc-core": ["../packages/rpc-core/src/index.ts"],
21
+ "@shared/*": ["../shared/*"]
22
+ }
23
+ },
24
+ "include": ["src", "../shared"],
25
+ "exclude": ["node_modules", "dist", "build", "../../package/dist", "**/__tests__/**", "**/*.test.ts", "**/*.test.tsx"]
26
+ }
@@ -0,0 +1,3 @@
1
+ import { createViteConfig } from "../shared/vite-base.config";
2
+
3
+ export default createViteConfig(__dirname);
@@ -0,0 +1,3 @@
1
+ import { createVitestConfig } from "../shared/vitest-base.config";
2
+
3
+ export default createVitestConfig(__dirname);
@@ -0,0 +1,7 @@
1
+ # Web server configuration
2
+ PORT=3100
3
+ AUTH_TOKEN=your-secret-token-here
4
+ MAX_UPLOAD_SIZE=5242880
5
+ LOG_DIR=logs
6
+ ENABLE_BASH=true
7
+ CORS_ORIGIN=http://localhost:5173
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 [username]
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,113 @@
1
+ # Pi Agent App
2
+
3
+ Desktop + Web application template built with Electrobun, React, Tailwind CSS, and RPC architecture.
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ bun install
9
+
10
+ # Development with HMR (recommended)
11
+ bun run dev:hmr
12
+
13
+ # Development without HMR
14
+ bun run dev
15
+
16
+ # Build
17
+ bun run build
18
+ ```
19
+
20
+ ## Transport 选型
21
+
22
+ 本项目基于 `@dyyz1993/rpc-core`,提供 4 种 Transport 适配不同场景:
23
+
24
+ | Transport | 场景 | 通信方式 |
25
+ |---|---|---|
26
+ | `WebSocketTransport` | Web 端 | TCP → WebSocket 长连接 |
27
+ | `IPCTransport` | Electrobun 桌面端 | macOS Mach Port 原生桥接 |
28
+ | `InMemoryTransport` | 同进程(TUI / 测试) | 进程内函数直接调用 |
29
+ | `StdioTransport` | 父子进程(CLI / TUI) | NDJSON over stdin/stdout |
30
+
31
+ ### 使用示例
32
+
33
+ ```typescript
34
+ // Web 端
35
+ import { WebSocketTransport } from "@dyyz1993/rpc-core";
36
+ const transport = new WebSocketTransport("ws://localhost:3100/ws?token=xxx");
37
+ await transport.connect();
38
+
39
+ // 桌面端 (Electrobun)
40
+ import { IPCTransport } from "@dyyz1993/rpc-core";
41
+ const transport = new IPCTransport();
42
+
43
+ // 同进程 TUI / 测试
44
+ import { InMemoryTransport } from "@dyyz1993/rpc-core";
45
+ const { client, server } = InMemoryTransport.createPair();
46
+
47
+ // 父子进程 CLI
48
+ import { StdioTransport } from "@dyyz1993/rpc-core";
49
+ const transport = new StdioTransport(); // 默认 process.stdin / process.stdout
50
+ await transport.connect();
51
+ ```
52
+
53
+ ### 父子进程 STDIO 对接
54
+
55
+ ```typescript
56
+ // 父进程:启动 TUI 子进程
57
+ import { spawn } from "child_process";
58
+ import { StdioTransport } from "@dyyz1993/rpc-core";
59
+
60
+ const child = spawn("bun", ["tui.ts"], { stdio: ["pipe", "pipe", "inherit"] });
61
+ const transport = new StdioTransport({
62
+ stdin: child.stdout,
63
+ stdout: child.stdin,
64
+ });
65
+ await transport.connect();
66
+ ```
67
+
68
+ ## Project Structure
69
+
70
+ ```
71
+ ├── src/
72
+ │ ├── bun/
73
+ │ │ └── index.ts # Desktop entry (Electrobun main process)
74
+ │ ├── server.ts # Web entry (HTTP + WebSocket server)
75
+ │ ├── gateway/
76
+ │ │ ├── http-routes.ts # HTTP endpoints
77
+ │ │ ├── ws-handler.ts # WebSocket RPC server
78
+ │ │ └── ipc-transport.ts # Electrobun IPC bridge
79
+ │ ├── shared/
80
+ │ │ ├── rpc-schema.ts # Unified RPC type definitions
81
+ │ │ ├── register-all-handlers.ts
82
+ │ │ ├── modules/ # RPC method type definitions
83
+ │ │ └── handlers/ # RPC handler implementations
84
+ │ └── mainview/ # React frontend
85
+ │ ├── App.tsx
86
+ │ ├── components/
87
+ │ │ ├── activity-bar/
88
+ │ │ ├── chat/
89
+ │ │ ├── explorer/
90
+ │ │ ├── feed/
91
+ │ │ ├── file-preview/
92
+ │ │ ├── git/
93
+ │ │ ├── search/ # File search across project
94
+ │ │ └── debug/
95
+ │ ├── stores/ # Zustand state management
96
+ │ └── lib/
97
+ │ └── api-client.ts # Typed RPC client (auto-detects transport)
98
+ ├── eslint-plugin-rpc/ # Custom ESLint rules for RPC conventions
99
+ ├── electrobun.config.ts
100
+ ├── vite.config.ts
101
+ └── tailwind.config.js
102
+ ```
103
+
104
+ ## RPC 模块列表
105
+
106
+ | 模块 | 方法 | 事件 | 说明 |
107
+ |---|---|---|---|
108
+ | `system` | ping, hello, echo | - | 连通性测试 |
109
+ | `file` | listDir, readFile, createFile, createDir, rename, delete, copy, findProjectRoot | - | 文件系统操作 |
110
+ | `timer` | start, stop | timer.tick | 定时器 + 实时推送 |
111
+ | `chat` | list, send | chat.message | 聊天(支持按 role 过滤) |
112
+ | `git` | status, diff, log, branches, checkout, add, reset, commit, push, pull | - | Git 版本控制 |
113
+ | `feed` | post, list | feed.update | Feed 流(支持 category 过滤) |