feihong-code 0.6.1 → 7.2.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 (247) hide show
  1. package/.github/workflows/release.yml +173 -0
  2. package/CHANGELOG.md +83 -454
  3. package/dist/agent/browser-agent.js +354 -0
  4. package/dist/agent/browser-agent.js.map +1 -0
  5. package/dist/agent/change-manager.js +433 -0
  6. package/dist/agent/change-manager.js.map +1 -0
  7. package/dist/agent/code-rag.js +293 -0
  8. package/dist/agent/code-rag.js.map +1 -0
  9. package/dist/agent/code-writer.js +13 -1
  10. package/dist/agent/code-writer.js.map +1 -1
  11. package/dist/agent/completion-engine.js +522 -0
  12. package/dist/agent/completion-engine.js.map +1 -0
  13. package/dist/agent/context-compactor.js +188 -10
  14. package/dist/agent/context-compactor.js.map +1 -1
  15. package/dist/agent/custom-agent.js +368 -0
  16. package/dist/agent/custom-agent.js.map +1 -0
  17. package/dist/agent/design-to-code.js +218 -0
  18. package/dist/agent/design-to-code.js.map +1 -0
  19. package/dist/agent/event-driven-agent.js +359 -0
  20. package/dist/agent/event-driven-agent.js.map +1 -0
  21. package/dist/agent/git-integration.js +324 -0
  22. package/dist/agent/git-integration.js.map +1 -0
  23. package/dist/agent/layered-memory.js +329 -0
  24. package/dist/agent/layered-memory.js.map +1 -0
  25. package/dist/agent/multi-agent.js +359 -0
  26. package/dist/agent/multi-agent.js.map +1 -0
  27. package/dist/agent/orchestrator.js +160 -22
  28. package/dist/agent/orchestrator.js.map +1 -1
  29. package/dist/agent/prompts.js +20 -0
  30. package/dist/agent/prompts.js.map +1 -1
  31. package/dist/agent/quality-gate.js +139 -0
  32. package/dist/agent/quality-gate.js.map +1 -1
  33. package/dist/agent/self-correction.js +274 -0
  34. package/dist/agent/self-correction.js.map +1 -0
  35. package/dist/agent/self-heal.js +42 -12
  36. package/dist/agent/self-heal.js.map +1 -1
  37. package/dist/agent/solo-agent.js +321 -0
  38. package/dist/agent/solo-agent.js.map +1 -0
  39. package/dist/agent/symbol-index.js +258 -28
  40. package/dist/agent/symbol-index.js.map +1 -1
  41. package/dist/agent/team-collaboration.js +252 -0
  42. package/dist/agent/team-collaboration.js.map +1 -0
  43. package/dist/agent/type-checker.js +229 -0
  44. package/dist/agent/type-checker.js.map +1 -0
  45. package/dist/cli/run.js +1 -0
  46. package/dist/cli/run.js.map +1 -1
  47. package/dist/cli/version.js +1 -1
  48. package/dist/integrations/collaboration.js +219 -0
  49. package/dist/integrations/collaboration.js.map +1 -0
  50. package/dist/integrations/figma.js +307 -0
  51. package/dist/integrations/figma.js.map +1 -0
  52. package/dist/integrations/sso.js +327 -0
  53. package/dist/integrations/sso.js.map +1 -0
  54. package/dist/knowledge/library.js +301 -0
  55. package/dist/knowledge/library.js.map +1 -0
  56. package/dist/plugins/manager.js +332 -0
  57. package/dist/plugins/manager.js.map +1 -0
  58. package/dist/runtime/event-log.js.map +1 -1
  59. package/dist/tools/browser/browser.tool.js +217 -0
  60. package/dist/tools/browser/browser.tool.js.map +1 -0
  61. package/dist/tools/index.js +2 -0
  62. package/dist/tools/index.js.map +1 -1
  63. package/dist/tools/shell/exec.js +50 -10
  64. package/dist/tools/shell/exec.js.map +1 -1
  65. package/dist/tools/shell/run-shell.tool.js +8 -2
  66. package/dist/tools/shell/run-shell.tool.js.map +1 -1
  67. package/dist/training/completion-evaluator.js +213 -0
  68. package/dist/training/completion-evaluator.js.map +1 -0
  69. package/dist/training/fim-data.js +248 -0
  70. package/dist/training/fim-data.js.map +1 -0
  71. package/dist/voice/voice-programming.js +223 -0
  72. package/dist/voice/voice-programming.js.map +1 -0
  73. package/dist/web/public/css/style.css +190 -7
  74. package/dist/web/public/index.html +403 -9
  75. package/dist/web/public/js/api.js +191 -4
  76. package/dist/web/public/js/app.js +850 -123
  77. package/dist/web/public/js/mock-api.js +234 -0
  78. package/dist/web/public/js/monaco-editor.js +203 -0
  79. package/dist/web/public/js/ui.js +1271 -54
  80. package/dist/web/public/manifest.json +59 -0
  81. package/dist/web/public/service-worker.js +173 -0
  82. package/dist/web/public/vendor/monaco/vs/abap-D-t0cyap.js +1 -0
  83. package/dist/web/public/vendor/monaco/vs/apex-CcIm7xu6.js +1 -0
  84. package/dist/web/public/vendor/monaco/vs/assets/css.worker-URu8fCFR.js +97 -0
  85. package/dist/web/public/vendor/monaco/vs/assets/editor.worker-lj3bdIIn.js +30 -0
  86. package/dist/web/public/vendor/monaco/vs/assets/editorWebWorkerMain-CA_vMoUU.js +30 -0
  87. package/dist/web/public/vendor/monaco/vs/assets/html.worker-D1SL3iM8.js +474 -0
  88. package/dist/web/public/vendor/monaco/vs/assets/json.worker-CoJx_OPf.js +62 -0
  89. package/dist/web/public/vendor/monaco/vs/assets/ts.worker-BWKtMYOk.js +67722 -0
  90. package/dist/web/public/vendor/monaco/vs/azcli-BA0tQDCg.js +1 -0
  91. package/dist/web/public/vendor/monaco/vs/basic-languages/monaco.contribution.js +1 -0
  92. package/dist/web/public/vendor/monaco/vs/bat-C397hTD6.js +1 -0
  93. package/dist/web/public/vendor/monaco/vs/bicep-DF5aW17k.js +2 -0
  94. package/dist/web/public/vendor/monaco/vs/cameligo-plsz8qhj.js +1 -0
  95. package/dist/web/public/vendor/monaco/vs/clojure-Y2auQMzK.js +1 -0
  96. package/dist/web/public/vendor/monaco/vs/coffee-Bu45yuWE.js +1 -0
  97. package/dist/web/public/vendor/monaco/vs/cpp-CkKPQIni.js +1 -0
  98. package/dist/web/public/vendor/monaco/vs/csharp-CX28MZyh.js +1 -0
  99. package/dist/web/public/vendor/monaco/vs/csp-D8uWnyxW.js +1 -0
  100. package/dist/web/public/vendor/monaco/vs/css-CaeNmE3S.js +3 -0
  101. package/dist/web/public/vendor/monaco/vs/css.worker-CyhWkhHo.js +1 -0
  102. package/dist/web/public/vendor/monaco/vs/cssMode-CV6Ay48H.js +1 -0
  103. package/dist/web/public/vendor/monaco/vs/cypher-DVThT8BS.js +1 -0
  104. package/dist/web/public/vendor/monaco/vs/dart-CmGfCvrO.js +1 -0
  105. package/dist/web/public/vendor/monaco/vs/dockerfile-CZqqYdch.js +1 -0
  106. package/dist/web/public/vendor/monaco/vs/ecl-30fUercY.js +1 -0
  107. package/dist/web/public/vendor/monaco/vs/editor/editor.main.css +1 -0
  108. package/dist/web/public/vendor/monaco/vs/editor/editor.main.js +1 -0
  109. package/dist/web/public/vendor/monaco/vs/editor/editor.worker.js +1 -0
  110. package/dist/web/public/vendor/monaco/vs/editor-KLE6jdfb.js +831 -0
  111. package/dist/web/public/vendor/monaco/vs/editor.js +1 -0
  112. package/dist/web/public/vendor/monaco/vs/editorWorkerHost-fVE1cjcC.js +35 -0
  113. package/dist/web/public/vendor/monaco/vs/elixir-xjPaIfzF.js +1 -0
  114. package/dist/web/public/vendor/monaco/vs/flow9-DqtmStfK.js +1 -0
  115. package/dist/web/public/vendor/monaco/vs/freemarker2-FWreY7v7.js +3 -0
  116. package/dist/web/public/vendor/monaco/vs/fsharp-BOMdg4U1.js +1 -0
  117. package/dist/web/public/vendor/monaco/vs/go-D_hbi-Jt.js +1 -0
  118. package/dist/web/public/vendor/monaco/vs/graphql-CKUU4kLG.js +1 -0
  119. package/dist/web/public/vendor/monaco/vs/handlebars-CZi4pHCH.js +1 -0
  120. package/dist/web/public/vendor/monaco/vs/hcl-DTaboeZW.js +1 -0
  121. package/dist/web/public/vendor/monaco/vs/html-j_7ZTNRU.js +1 -0
  122. package/dist/web/public/vendor/monaco/vs/html.worker-CA3iAimZ.js +1 -0
  123. package/dist/web/public/vendor/monaco/vs/htmlMode-27by_KM4.js +1 -0
  124. package/dist/web/public/vendor/monaco/vs/index-049xrXrp.js +1 -0
  125. package/dist/web/public/vendor/monaco/vs/index-CBVt3dzv.js +5 -0
  126. package/dist/web/public/vendor/monaco/vs/index.js +1 -0
  127. package/dist/web/public/vendor/monaco/vs/ini-CsNwO04R.js +1 -0
  128. package/dist/web/public/vendor/monaco/vs/initialize-DL0l1TGY.js +1 -0
  129. package/dist/web/public/vendor/monaco/vs/java-CI4ZMsH9.js +1 -0
  130. package/dist/web/public/vendor/monaco/vs/javascript-DTJl4Jn1.js +1 -0
  131. package/dist/web/public/vendor/monaco/vs/json.worker-BizpAl9O.js +1 -0
  132. package/dist/web/public/vendor/monaco/vs/jsonMode-DLUiMUrI.js +1 -0
  133. package/dist/web/public/vendor/monaco/vs/julia-BwzEvaQw.js +1 -0
  134. package/dist/web/public/vendor/monaco/vs/kotlin-IUYPiTV8.js +1 -0
  135. package/dist/web/public/vendor/monaco/vs/language/css/css.worker.js +66 -0
  136. package/dist/web/public/vendor/monaco/vs/language/css/monaco.contribution.js +1 -0
  137. package/dist/web/public/vendor/monaco/vs/language/html/html.worker.js +443 -0
  138. package/dist/web/public/vendor/monaco/vs/language/html/monaco.contribution.js +1 -0
  139. package/dist/web/public/vendor/monaco/vs/language/json/json.worker.js +17 -0
  140. package/dist/web/public/vendor/monaco/vs/language/json/monaco.contribution.js +1 -0
  141. package/dist/web/public/vendor/monaco/vs/language/typescript/monaco.contribution.js +1 -0
  142. package/dist/web/public/vendor/monaco/vs/language/typescript/ts.worker.js +67693 -0
  143. package/dist/web/public/vendor/monaco/vs/less-C0eDYdqa.js +2 -0
  144. package/dist/web/public/vendor/monaco/vs/lexon-iON-Kj97.js +1 -0
  145. package/dist/web/public/vendor/monaco/vs/liquid-CLJYelW6.js +1 -0
  146. package/dist/web/public/vendor/monaco/vs/loader.js +1368 -0
  147. package/dist/web/public/vendor/monaco/vs/lspLanguageFeatures-BIkJOWLw.js +2 -0
  148. package/dist/web/public/vendor/monaco/vs/lua-DtygF91M.js +1 -0
  149. package/dist/web/public/vendor/monaco/vs/m3-CsR4AuFi.js +1 -0
  150. package/dist/web/public/vendor/monaco/vs/main-BEx-Fmlo.js +15 -0
  151. package/dist/web/public/vendor/monaco/vs/main-DsK8pnKg.js +3 -0
  152. package/dist/web/public/vendor/monaco/vs/markdown-C_rD0bIw.js +1 -0
  153. package/dist/web/public/vendor/monaco/vs/mdx-CpzZIPHF.js +1 -0
  154. package/dist/web/public/vendor/monaco/vs/mips-CiYP61RB.js +1 -0
  155. package/dist/web/public/vendor/monaco/vs/monaco.contribution-9cKT3C7t.js +1 -0
  156. package/dist/web/public/vendor/monaco/vs/monaco.contribution-BE88ZNGY.js +1 -0
  157. package/dist/web/public/vendor/monaco/vs/monaco.contribution-BPhsneLd.js +1 -0
  158. package/dist/web/public/vendor/monaco/vs/monaco.contribution-BgRy6xDf.js +1 -0
  159. package/dist/web/public/vendor/monaco/vs/msdax-C38-sJlp.js +1 -0
  160. package/dist/web/public/vendor/monaco/vs/mysql-CdtbpvbG.js +1 -0
  161. package/dist/web/public/vendor/monaco/vs/nls/lang/cs.d.ts +1 -0
  162. package/dist/web/public/vendor/monaco/vs/nls/lang/cs.js +9 -0
  163. package/dist/web/public/vendor/monaco/vs/nls/lang/de.d.ts +1 -0
  164. package/dist/web/public/vendor/monaco/vs/nls/lang/de.js +9 -0
  165. package/dist/web/public/vendor/monaco/vs/nls/lang/es.d.ts +1 -0
  166. package/dist/web/public/vendor/monaco/vs/nls/lang/es.js +9 -0
  167. package/dist/web/public/vendor/monaco/vs/nls/lang/fr.d.ts +1 -0
  168. package/dist/web/public/vendor/monaco/vs/nls/lang/fr.js +9 -0
  169. package/dist/web/public/vendor/monaco/vs/nls/lang/it.d.ts +1 -0
  170. package/dist/web/public/vendor/monaco/vs/nls/lang/it.js +9 -0
  171. package/dist/web/public/vendor/monaco/vs/nls/lang/ja.d.ts +1 -0
  172. package/dist/web/public/vendor/monaco/vs/nls/lang/ja.js +9 -0
  173. package/dist/web/public/vendor/monaco/vs/nls/lang/ko.d.ts +1 -0
  174. package/dist/web/public/vendor/monaco/vs/nls/lang/ko.js +9 -0
  175. package/dist/web/public/vendor/monaco/vs/nls/lang/pl.d.ts +1 -0
  176. package/dist/web/public/vendor/monaco/vs/nls/lang/pl.js +9 -0
  177. package/dist/web/public/vendor/monaco/vs/nls/lang/pt-br.d.ts +1 -0
  178. package/dist/web/public/vendor/monaco/vs/nls/lang/pt-br.js +9 -0
  179. package/dist/web/public/vendor/monaco/vs/nls/lang/ru.d.ts +1 -0
  180. package/dist/web/public/vendor/monaco/vs/nls/lang/ru.js +9 -0
  181. package/dist/web/public/vendor/monaco/vs/nls/lang/tr.d.ts +1 -0
  182. package/dist/web/public/vendor/monaco/vs/nls/lang/tr.js +9 -0
  183. package/dist/web/public/vendor/monaco/vs/nls/lang/zh-cn.d.ts +1 -0
  184. package/dist/web/public/vendor/monaco/vs/nls/lang/zh-cn.js +9 -0
  185. package/dist/web/public/vendor/monaco/vs/nls/lang/zh-tw.d.ts +1 -0
  186. package/dist/web/public/vendor/monaco/vs/nls/lang/zh-tw.js +9 -0
  187. package/dist/web/public/vendor/monaco/vs/nls.messages-loader.js +1 -0
  188. package/dist/web/public/vendor/monaco/vs/objective-c-CntZFaHX.js +1 -0
  189. package/dist/web/public/vendor/monaco/vs/pascal-r6kuqfl_.js +1 -0
  190. package/dist/web/public/vendor/monaco/vs/pascaligo-BiXoTmXh.js +1 -0
  191. package/dist/web/public/vendor/monaco/vs/perl-DABw_TcH.js +1 -0
  192. package/dist/web/public/vendor/monaco/vs/pgsql-me_jFXeX.js +1 -0
  193. package/dist/web/public/vendor/monaco/vs/php-D_kh-9LK.js +1 -0
  194. package/dist/web/public/vendor/monaco/vs/pla-VfZjczW0.js +1 -0
  195. package/dist/web/public/vendor/monaco/vs/postiats-BBSzz8Pk.js +1 -0
  196. package/dist/web/public/vendor/monaco/vs/powerquery-Dt-g_2cc.js +1 -0
  197. package/dist/web/public/vendor/monaco/vs/powershell-B-7ap1zc.js +1 -0
  198. package/dist/web/public/vendor/monaco/vs/protobuf-BmtuEB1A.js +2 -0
  199. package/dist/web/public/vendor/monaco/vs/pug-BRpRNeEb.js +1 -0
  200. package/dist/web/public/vendor/monaco/vs/python-CqWUUgfu.js +1 -0
  201. package/dist/web/public/vendor/monaco/vs/qsharp-BzsFaUU9.js +1 -0
  202. package/dist/web/public/vendor/monaco/vs/r-f8dDdrp4.js +1 -0
  203. package/dist/web/public/vendor/monaco/vs/razor-hok5y9Km.js +1 -0
  204. package/dist/web/public/vendor/monaco/vs/redis-fvZQY4PI.js +1 -0
  205. package/dist/web/public/vendor/monaco/vs/redshift-45Et0LQi.js +1 -0
  206. package/dist/web/public/vendor/monaco/vs/restructuredtext-C7UUFKFD.js +1 -0
  207. package/dist/web/public/vendor/monaco/vs/ruby-CZO8zYTz.js +1 -0
  208. package/dist/web/public/vendor/monaco/vs/rust-Bfetafyc.js +1 -0
  209. package/dist/web/public/vendor/monaco/vs/sb-3GYllVck.js +1 -0
  210. package/dist/web/public/vendor/monaco/vs/scala-foMgrKo1.js +1 -0
  211. package/dist/web/public/vendor/monaco/vs/scheme-CHdMtr7p.js +1 -0
  212. package/dist/web/public/vendor/monaco/vs/scss-C1cmLt9V.js +3 -0
  213. package/dist/web/public/vendor/monaco/vs/shell-ClXCKCEW.js +1 -0
  214. package/dist/web/public/vendor/monaco/vs/solidity-MZ6ExpPy.js +1 -0
  215. package/dist/web/public/vendor/monaco/vs/sophia-DWkuSsPQ.js +1 -0
  216. package/dist/web/public/vendor/monaco/vs/sparql-AUGFYSyk.js +1 -0
  217. package/dist/web/public/vendor/monaco/vs/sql-32GpJSV2.js +1 -0
  218. package/dist/web/public/vendor/monaco/vs/st-CuDFIVZ_.js +1 -0
  219. package/dist/web/public/vendor/monaco/vs/swift-t-PfMj7W.js +1 -0
  220. package/dist/web/public/vendor/monaco/vs/systemverilog-Ch4vA8Yt.js +1 -0
  221. package/dist/web/public/vendor/monaco/vs/tcl-D74tq1nH.js +1 -0
  222. package/dist/web/public/vendor/monaco/vs/toggleHighContrast-qGX7E9o7.js +61 -0
  223. package/dist/web/public/vendor/monaco/vs/ts.worker-2QLmBukE.js +1 -0
  224. package/dist/web/public/vendor/monaco/vs/tsMode-B0S_kp2q.js +11 -0
  225. package/dist/web/public/vendor/monaco/vs/twig-C6taOxMV.js +1 -0
  226. package/dist/web/public/vendor/monaco/vs/typescript-_2t_511t.js +1 -0
  227. package/dist/web/public/vendor/monaco/vs/typespec-8OfoLt6R.js +1 -0
  228. package/dist/web/public/vendor/monaco/vs/vb-Dyb2648j.js +1 -0
  229. package/dist/web/public/vendor/monaco/vs/wgsl-BhLXMOR0.js +298 -0
  230. package/dist/web/public/vendor/monaco/vs/workers-BBttULjf.js +1 -0
  231. package/dist/web/public/vendor/monaco/vs/xml-cZjNDqDT.js +1 -0
  232. package/dist/web/public/vendor/monaco/vs/yaml-A1fOIdH6.js +1 -0
  233. package/dist/web/server.js +2073 -210
  234. package/dist/web/server.js.map +1 -1
  235. package/dist/web/task-queue.js +25 -5
  236. package/dist/web/task-queue.js.map +1 -1
  237. package/docs/BENCHMARK_REPORT_en.md +329 -0
  238. package/docs/BENCHMARK_REPORT_zh.md +329 -0
  239. package/docs/DEPLOYMENT.md +382 -0
  240. package/docs/MODEL_FINETUNING.md +405 -0
  241. package/docs/TECHNICAL_SPEC_en.md +292 -0
  242. package/docs/TECHNICAL_SPEC_zh.md +292 -0
  243. package/docs/UPDATE_NOTES_en.md +159 -0
  244. package/docs/UPDATE_NOTES_zh.md +159 -0
  245. package/electron/main.js +602 -0
  246. package/package.json +67 -3
  247. package/tool-schema.json +1 -1
@@ -5,8 +5,16 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title data-i18n="app.title_login">飞虹 Code 控制台 / fhcode Console</title>
7
7
  <link rel="stylesheet" href="css/style.css">
8
+ <!-- Monaco Editor AMD Loader(代码编辑器内核,VSCode 同款) -->
9
+ <script src="vendor/monaco/vs/loader.js"></script>
8
10
  </head>
9
11
  <body>
12
+ <!-- 后端服务断连提示横幅 -->
13
+ <div class="backend-offline-banner" id="backendOfflineBanner" style="display:none;">
14
+ <span class="bob-icon">⚠️</span>
15
+ <span class="bob-text" id="backendOfflineText">后端服务已断开,正在自动重连…</span>
16
+ <button class="bob-reconnect" id="backendReconnectBtn">立即重连</button>
17
+ </div>
10
18
  <div id="loginOverlay">
11
19
  <div class="login-card">
12
20
  <h2 data-i18n="app.title_login">飞虹 Code 控制台</h2>
@@ -72,6 +80,10 @@
72
80
  <span class="icon">📎</span>
73
81
  <span class="label" data-i18n="sidebar.office">办公助理</span>
74
82
  </div>
83
+ <div class="sidebar-icon" data-nav="nodes" title="节点管理" data-i18n="sidebar.nodes">
84
+ <span class="icon">🔗</span>
85
+ <span class="label" data-i18n="sidebar.nodes">节点管理</span>
86
+ </div>
75
87
  <div class="sidebar-icon" data-nav="memory" title="记忆系统" data-i18n="sidebar.memory">
76
88
  <span class="icon">🧠</span>
77
89
  <span class="label" data-i18n="sidebar.memory">记忆系统</span>
@@ -142,15 +154,16 @@
142
154
  <div class="dropdown-item" data-action="screenshot" data-i18n="chat.screenshot">📷 截图</div>
143
155
  <div class="dropdown-item" data-action="upload-file" data-i18n="chat.upload_file">📄 上传文件</div>
144
156
  <div class="dropdown-item" data-action="upload-image" data-i18n="chat.upload_image">🖼 上传图片</div>
145
- <div class="dropdown-item" data-action="direct-mode" data-i18n="chat.direct_mode">🖥 直接操作电脑</div>
157
+ <div class="dropdown-item" data-action="direct-mode" data-i18n="chat.direct_mode">🖥 电脑操作</div>
146
158
  <div class="dropdown-item" data-action="voice" data-i18n="chat.voice">🎤 语音输入</div>
147
159
  <div class="dropdown-divider"></div>
148
160
  <div class="dropdown-item" data-action="agent-type" data-i18n="chat.agent_type">🤖 选择智能体类型</div>
149
161
  </div>
150
162
  </div>
151
163
  <button class="pill" id="screenshotBtn" title="截图(框选屏幕区域发给 AI)" data-i18n="chat.screenshot">📷 截图</button>
164
+ <button class="pill" id="voiceBtn" title="语音输入(点击开始/停止)" data-i18n="chat.voice">🎤 语音</button>
152
165
  <span class="pill" id="skillPill" title="当前智能体" data-i18n="chat.agent_default">🤖 通用助手</span>
153
- <span class="pill" id="directModePill" style="display:none;" title="直接操作电脑模式已开启" data-i18n="chat.direct_mode">🖥 直接操作电脑</span>
166
+ <span class="pill" id="directModePill" style="display:none;" title="电脑操作模式已开启" data-i18n="chat.direct_mode">🖥 电脑操作</span>
154
167
  <span id="voiceBadge" class="voice-badge" style="display:none;" data-i18n="chat.listening">● 正在听…</span>
155
168
  <span class="spacer"></span>
156
169
  <button id="sendBtn" data-i18n="chat.send">▶ 发送</button>
@@ -183,7 +196,10 @@
183
196
  <div data-i18n="nav.automations"><h2>⚡ 自动化</h2><div class="sub">把常用目标存成指令,一键发起任务</div></div>
184
197
  <button id="newAutoBtn" data-i18n="btn.new_automation">+ 新建指令</button>
185
198
  </div>
186
- <div class="grid" id="autoGrid" data-i18n="empty.no_automations"><div class="empty">还没有快捷指令</div></div>
199
+ <div class="section-title">常用快捷指令</div>
200
+ <div class="grid" id="builtinAutoGrid"></div>
201
+ <div class="section-title" style="margin-top:20px;">我的指令</div>
202
+ <div class="grid" id="autoGrid" data-i18n="empty.no_automations"><div class="empty">还没有自定义指令,点击上方「新建指令」或从常用指令保存</div></div>
187
203
  </div>
188
204
 
189
205
  <!-- 模板库页面 -->
@@ -194,6 +210,10 @@
194
210
  </div>
195
211
  <div class="section-title" data-i18n="tpl.builtin">内置模板</div>
196
212
  <div class="grid" id="builtinGrid"></div>
213
+ <div class="section-title" style="margin-top:20px;" id="nodeTplTitle" data-i18n="tpl.node">来自节点</div>
214
+ <div class="grid" id="nodeTplGrid"><div class="empty">暂无节点模板,去「节点管理」添加节点</div></div>
215
+ <div class="section-title" style="margin-top:20px;" id="customTplTitle" data-i18n="tpl.custom">自定义来源</div>
216
+ <div class="grid" id="customTplGrid"><div class="empty">暂无自定义来源模板</div></div>
197
217
  <div class="section-title" style="margin-top:20px;" data-i18n="tpl.my">我的模板</div>
198
218
  <div class="grid" id="userTplGrid" data-i18n="empty.no_templates"><div class="empty">暂无自定义模板</div></div>
199
219
  </div>
@@ -208,6 +228,8 @@
208
228
  <option value="all" data-i18n="market.source_all">全部来源</option>
209
229
  <option value="clawhub">ClawHub</option>
210
230
  <option value="agent-foundry">Agent-Foundry</option>
231
+ <option value="node">节点</option>
232
+ <option value="custom">自定义来源</option>
211
233
  </select>
212
234
  <button id="marketRefresh" data-i18n="btn.refresh">刷新</button>
213
235
  </div>
@@ -225,6 +247,21 @@
225
247
  <div class="grid" id="officeGrid" data-i18n="common.loading"><div class="empty">加载中…</div></div>
226
248
  </div>
227
249
 
250
+ <!-- 节点管理页面 -->
251
+ <div class="page-view" data-view="nodes">
252
+ <div class="page-head">
253
+ <div><h2>🔗 节点管理</h2><div class="sub">连接外部节点,扩展模板/插件/办公能力来源</div></div>
254
+ <div class="row" style="flex:0 0 auto; gap:8px;">
255
+ <button id="addNodeBtn">+ 添加节点</button>
256
+ <button id="addSourceBtn" class="ghost">+ 自定义来源</button>
257
+ </div>
258
+ </div>
259
+ <div class="section-title">已连接节点</div>
260
+ <div class="grid" id="nodesGrid"><div class="empty">还没有添加节点,点击上方「添加节点」连接外部服务</div></div>
261
+ <div class="section-title" style="margin-top:20px;">自定义来源</div>
262
+ <div class="grid" id="sourcesGrid"><div class="empty">还没有自定义来源,点击上方「自定义来源」添加远程数据源</div></div>
263
+ </div>
264
+
228
265
  <!-- 记忆系统页面 -->
229
266
  <div class="page-view" data-view="memory">
230
267
  <div class="page-head">
@@ -267,8 +304,17 @@
267
304
  <div class="row" style="margin-bottom:16px;align-items:center;">
268
305
  <input type="date" id="memDateInput" style="margin:0;width:160px;" />
269
306
  <button id="memLoadDay" style="margin:0;" data-i18n="btn.view">查看</button>
307
+ <button id="memAddShort" style="margin:0;" class="ghost">+ 添加记录</button>
270
308
  <span class="muted" id="memDateLabel" style="margin-left:8px;"></span>
271
309
  </div>
310
+ <!-- 添加记录文本框(默认隐藏,点击添加记录后展开) -->
311
+ <div id="memShortEditor" style="display:none;margin-bottom:16px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);">
312
+ <textarea id="memShortInput" rows="4" placeholder="直接输入你想记录的内容,点击保存即可添加到今天的短期记忆..." style="width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
313
+ <div style="margin-top:8px;display:flex;gap:8px;justify-content:flex-end;">
314
+ <button id="memShortCancel" class="ghost">取消</button>
315
+ <button id="memShortSave" class="primary">保存</button>
316
+ </div>
317
+ </div>
272
318
  <div class="card memory-content" id="memShortContent">
273
319
  <div class="empty" data-i18n="btn.view">选择日期查看短期记忆</div>
274
320
  </div>
@@ -276,9 +322,26 @@
276
322
 
277
323
  <!-- 长期记忆面板 -->
278
324
  <div class="mem-panel" id="memLongPanel" style="display:none;">
325
+ <div class="row" style="margin-bottom:16px;align-items:center;">
326
+ <button id="memEditLong" style="margin:0;">✎ 编辑</button>
327
+ <button id="memSaveLong" style="margin:0;display:none;" class="primary">💾 保存</button>
328
+ <button id="memCancelLong" style="margin:0;display:none;" class="ghost">取消</button>
329
+ <button id="memAppendLong" style="margin:0;" class="ghost">+ 追加</button>
330
+ <span class="muted" style="margin-left:8px;">长期记忆会在对话中被 AI 参考</span>
331
+ </div>
332
+ <!-- 追加条目文本框(默认隐藏) -->
333
+ <div id="memLongAppendEditor" style="display:none;margin-bottom:16px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);">
334
+ <input type="text" id="memAppendTitle" placeholder="条目标题(如:项目知识/用户偏好)" style="width:100%;padding:8px 10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;margin-bottom:8px;box-sizing:border-box;" />
335
+ <textarea id="memAppendContent" rows="3" placeholder="输入你想追加的记忆内容..." style="width:100%;padding:10px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
336
+ <div style="margin-top:8px;display:flex;gap:8px;justify-content:flex-end;">
337
+ <button id="memAppendCancel" class="ghost">取消</button>
338
+ <button id="memAppendSave" class="primary">追加</button>
339
+ </div>
340
+ </div>
279
341
  <div class="card memory-content" id="memLongContent">
280
342
  <div class="empty" data-i18n="common.loading">加载中…</div>
281
343
  </div>
344
+ <textarea id="memLongEditor" style="display:none;width:100%;min-height:400px;padding:12px;border:1px solid var(--border);border-radius:8px;background:var(--bg);color:var(--ink);font-family:monospace;font-size:13px;resize:vertical;box-sizing:border-box;"></textarea>
282
345
  </div>
283
346
 
284
347
  <!-- 总结历史面板 -->
@@ -475,6 +538,17 @@
475
538
  <button id="modelSettingsShortcut" class="ghost-btn" title="大模型设置" data-i18n="sidebar.settings">🧠</button>
476
539
  </div>
477
540
  </div>
541
+ <!-- 视频通话窗口 -->
542
+ <div class="video-call-window" id="videoCallWindow" style="display:none;">
543
+ <div class="video-call-header">
544
+ <span>📹 视频通话中</span>
545
+ <div style="display:flex;gap:8px;align-items:center;">
546
+ <button class="video-call-snapshot" id="videoSnapshotBtn" title="截取当前画面发送">📸</button>
547
+ <button class="video-call-close" id="videoCallClose">✕</button>
548
+ </div>
549
+ </div>
550
+ <video id="localVideo" autoplay muted playsinline></video>
551
+ </div>
478
552
  </main>
479
553
 
480
554
  <!-- 右侧面板 -->
@@ -482,6 +556,11 @@
482
556
  <div class="right-tabs">
483
557
  <div class="right-tab active" data-tab="detail" data-i18n="right.detail">📦 任务详情</div>
484
558
  <div class="right-tab" data-tab="preview" data-i18n="right.preview">👁 产物预览</div>
559
+ <div class="right-tab" data-tab="changes" id="changesTab">📝 变更</div>
560
+ <div class="right-tab" data-tab="design" id="designTab">🎨 设计稿</div>
561
+ <div class="right-tab" data-tab="git" id="gitTab">🔀 Git</div>
562
+ <div class="right-tab" data-tab="team" id="teamTab">👥 团队</div>
563
+ <div class="right-tab" data-tab="computer" id="computerTab" style="display:none;">🖥 电脑操作</div>
485
564
  </div>
486
565
  <div class="right-body">
487
566
  <div class="preview-panel active" id="detailPanel">
@@ -491,6 +570,230 @@
491
570
  <div class="preview-title" id="previewTitle" data-i18n="right.preview_title">预览</div>
492
571
  <div class="preview-content" id="previewContent" data-i18n="right.preview_title"><div class="muted">点击任务或对话中的文件/代码进行预览。</div></div>
493
572
  </div>
573
+ <div class="preview-panel" id="computerPanel">
574
+ <div class="computer-controls">
575
+ <button id="screenCaptureBtn" class="pill">📷 截取屏幕</button>
576
+ <span id="mousePos" class="muted" style="font-size:12px;">坐标: -</span>
577
+ </div>
578
+ <div class="screen-preview" id="screenPreview">
579
+ <div class="muted" style="text-align:center;padding:40px;">点击「截取屏幕」查看当前屏幕</div>
580
+ </div>
581
+ <div class="computer-actions">
582
+ <div style="margin-bottom:8px;font-size:13px;font-weight:600;">快捷操作</div>
583
+ <div style="display:flex;gap:6px;flex-wrap:wrap;margin-bottom:10px;">
584
+ <button class="pill" id="clickLeftBtn">左键点击</button>
585
+ <button class="pill" id="clickRightBtn">右键点击</button>
586
+ <button class="pill" id="doubleClickBtn">双击</button>
587
+ </div>
588
+ <div style="margin-bottom:8px;">
589
+ <input type="text" id="typeTextInput" placeholder="输入文字后回车发送" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;" />
590
+ </div>
591
+ <div style="display:flex;gap:6px;flex-wrap:wrap;">
592
+ <button class="pill" data-key="{ENTER}">回车</button>
593
+ <button class="pill" data-key="{TAB}">Tab</button>
594
+ <button class="pill" data-key="{ESC}">Esc</button>
595
+ <button class="pill" data-key="^c">复制</button>
596
+ <button class="pill" data-key="^v">粘贴</button>
597
+ <button class="pill" data-key="^a">全选</button>
598
+ </div>
599
+ </div>
600
+ </div>
601
+ <!-- P3: 多文件变更面板 -->
602
+ <div class="preview-panel" id="changesPanel">
603
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;">
604
+ <div style="font-size:13px;font-weight:600;">📝 待审批变更 <span id="changesCount" class="badge" style="margin-left:4px;">0</span></div>
605
+ <div style="display:flex;gap:6px;">
606
+ <button id="changesDetectBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="检测文件冲突">⚠️ 检测冲突</button>
607
+ <button id="changesRefreshBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;">🔄</button>
608
+ <button id="changesCommitBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;background:#2d5a3d;color:#fff;">✓ 全部提交</button>
609
+ <button id="changesDiscardBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;">🗑 丢弃</button>
610
+ </div>
611
+ </div>
612
+ <div id="changesList" style="overflow-y:auto;max-height:calc(100vh - 280px);">
613
+ <div class="muted" style="text-align:center;padding:30px;font-size:12px;">暂无暂存变更<br/><span style="font-size:11px;">AI 生成的文件修改会先暂存在这里,审批后才写入磁盘</span></div>
614
+ </div>
615
+ </div>
616
+ <!-- P2-1: 设计稿转代码面板 -->
617
+ <div class="preview-panel" id="designPanel">
618
+ <div style="margin-bottom:10px;font-size:13px;font-weight:600;">🎨 设计稿转代码</div>
619
+ <!-- 图片上传区域 -->
620
+ <div id="designDropZone" style="border:2px dashed var(--border);border-radius:8px;padding:20px;text-align:center;cursor:pointer;margin-bottom:10px;transition:border-color 0.2s;">
621
+ <div style="font-size:24px;margin-bottom:6px;">📷</div>
622
+ <div style="font-size:12px;color:var(--muted);">点击或拖拽上传设计稿图片</div>
623
+ <div style="font-size:10px;color:var(--muted);margin-top:4px;">支持 PNG/JPG/WebP,最大 8MB</div>
624
+ <input type="file" id="designFileInput" accept="image/*" style="display:none;" />
625
+ </div>
626
+ <!-- 图片预览 -->
627
+ <div id="designImagePreview" style="display:none;margin-bottom:10px;">
628
+ <img id="designPreviewImg" style="width:100%;max-height:200px;object-fit:contain;border-radius:6px;border:1px solid var(--border);" />
629
+ <button id="designRemoveImgBtn" style="margin-top:6px;font-size:11px;padding:2px 8px;background:none;border:1px solid var(--border);border-radius:4px;cursor:pointer;color:var(--ink);">🗑 移除图片</button>
630
+ </div>
631
+ <!-- 框架选择 -->
632
+ <div style="margin-bottom:8px;">
633
+ <label style="font-size:12px;font-weight:600;display:block;margin-bottom:4px;">目标框架</label>
634
+ <select id="designFramework" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;background:var(--card);color:var(--ink);">
635
+ <option value="html">HTML + 内联 CSS</option>
636
+ <option value="tailwind">HTML + Tailwind CSS</option>
637
+ <option value="html-css">HTML + CSS(分离)</option>
638
+ <option value="react">React 组件(JSX)</option>
639
+ <option value="vue">Vue 3 单文件组件</option>
640
+ </select>
641
+ </div>
642
+ <!-- 附加说明 -->
643
+ <div style="margin-bottom:8px;">
644
+ <label style="font-size:12px;font-weight:600;display:block;margin-bottom:4px;">附加说明(可选)</label>
645
+ <textarea id="designInstructions" placeholder="如:使用深色主题、响应式设计、圆角按钮..." style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;resize:vertical;min-height:50px;background:var(--card);color:var(--ink);"></textarea>
646
+ </div>
647
+ <!-- 生成按钮 -->
648
+ <button id="designGenerateBtn" style="width:100%;padding:8px;font-size:13px;font-weight:600;background:#2d5a3d;color:#fff;border:none;border-radius:6px;cursor:pointer;margin-bottom:10px;">✨ 生成代码</button>
649
+ <!-- 生成状态 -->
650
+ <div id="designStatus" style="display:none;font-size:12px;color:var(--muted);text-align:center;margin-bottom:10px;">
651
+ <span style="display:inline-block;width:12px;height:12px;border:2px solid var(--muted);border-top-color:transparent;border-radius:50%;animation:spin 0.8s linear infinite;vertical-align:middle;margin-right:6px;"></span>
652
+ <span id="designStatusText">正在分析设计稿...</span>
653
+ </div>
654
+ <!-- 结果区域:代码 + 预览切换 -->
655
+ <div id="designResult" style="display:none;">
656
+ <div style="display:flex;gap:4px;margin-bottom:8px;">
657
+ <button class="design-result-tab active" data-tab="code" style="flex:1;padding:5px;font-size:11px;border:1px solid var(--border);border-radius:4px;cursor:pointer;background:var(--card);color:var(--ink);">📄 代码</button>
658
+ <button class="design-result-tab" data-tab="preview" style="flex:1;padding:5px;font-size:11px;border:1px solid var(--border);border-radius:4px;cursor:pointer;background:var(--card);color:var(--ink);">👁 预览</button>
659
+ </div>
660
+ <!-- 代码视图 -->
661
+ <div id="designCodeView" style="margin-bottom:10px;">
662
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:4px;">
663
+ <span style="font-size:11px;color:var(--muted);" id="designCodeLang">HTML</span>
664
+ <button id="designCopyBtn" style="font-size:10px;padding:2px 6px;background:none;border:1px solid var(--border);border-radius:3px;cursor:pointer;color:var(--ink);">📋 复制</button>
665
+ </div>
666
+ <pre id="designCode" style="margin:0;max-height:300px;overflow:auto;padding:10px;background:var(--card);border:1px solid var(--border);border-radius:6px;font-size:11px;line-height:1.5;white-space:pre-wrap;word-break:break-all;"></pre>
667
+ </div>
668
+ <!-- 预览视图 -->
669
+ <div id="designPreviewView" style="display:none;margin-bottom:10px;">
670
+ <iframe id="designPreviewFrame" style="width:100%;height:300px;border:1px solid var(--border);border-radius:6px;background:#fff;"></iframe>
671
+ </div>
672
+ <!-- 迭代修正 -->
673
+ <div style="border-top:1px solid var(--border);padding-top:8px;">
674
+ <div style="font-size:12px;font-weight:600;margin-bottom:4px;">🔧 迭代修正</div>
675
+ <textarea id="designFeedback" placeholder="描述需要修改的地方,如:按钮颜色改为蓝色、标题字号增大..." style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;resize:vertical;min-height:40px;margin-bottom:6px;background:var(--card);color:var(--ink);"></textarea>
676
+ <button id="designRefineBtn" style="width:100%;padding:6px;font-size:12px;background:var(--card);color:var(--ink);border:1px solid var(--border);border-radius:6px;cursor:pointer;">🔄 修正代码</button>
677
+ </div>
678
+ </div>
679
+ </div>
680
+ <!-- P2-2: Git 集成面板 -->
681
+ <div class="preview-panel" id="gitPanel">
682
+ <!-- 分支信息和操作 -->
683
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px;">
684
+ <div style="font-size:13px;font-weight:600;">🔀 Git <span id="gitBranchName" class="muted" style="font-size:11px;font-weight:normal;"></span></div>
685
+ <div style="display:flex;gap:4px;">
686
+ <button id="gitRefreshBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="刷新">🔄</button>
687
+ <button id="gitPullBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="拉取">⬇ 拉取</button>
688
+ <button id="gitPushBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;" title="推送">⬆ 推送</button>
689
+ </div>
690
+ </div>
691
+ <!-- 非仓库提示 -->
692
+ <div id="gitNoRepo" style="display:none;text-align:center;padding:30px;">
693
+ <div style="font-size:24px;margin-bottom:8px;">📦</div>
694
+ <div class="muted" style="font-size:12px;margin-bottom:10px;">当前目录不是 Git 仓库</div>
695
+ <button id="gitInitBtn" class="ghost-btn" style="font-size:11px;padding:4px 12px;">初始化 Git 仓库</button>
696
+ </div>
697
+ <!-- Git 内容区 -->
698
+ <div id="gitContent" style="display:none;">
699
+ <!-- 分支切换 -->
700
+ <div style="margin-bottom:8px;">
701
+ <select id="gitBranchSelect" style="width:100%;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);"></select>
702
+ </div>
703
+ <!-- 暂存区 -->
704
+ <div style="margin-bottom:10px;">
705
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;">
706
+ <span style="font-size:11px;font-weight:600;color:#2d8a4e;">📥 暂存区 <span id="gitStagedCount" class="muted">0</span></span>
707
+ <button id="gitResetAllBtn" class="ghost-btn" style="font-size:10px;padding:2px 6px;display:none;">全部取消</button>
708
+ </div>
709
+ <div id="gitStagedList" style="max-height:120px;overflow-y:auto;"></div>
710
+ </div>
711
+ <!-- 工作区修改 -->
712
+ <div style="margin-bottom:10px;">
713
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;">
714
+ <span style="font-size:11px;font-weight:600;color:#c0392b;">📝 修改 <span id="gitModifiedCount" class="muted">0</span></span>
715
+ <button id="gitAddAllBtn" class="ghost-btn" style="font-size:10px;padding:2px 6px;display:none;">全部暂存</button>
716
+ </div>
717
+ <div id="gitModifiedList" style="max-height:120px;overflow-y:auto;"></div>
718
+ </div>
719
+ <!-- 未跟踪文件 -->
720
+ <div style="margin-bottom:10px;">
721
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px;">
722
+ <span style="font-size:11px;font-weight:600;color:#888;">❓ 未跟踪 <span id="gitUntrackedCount" class="muted">0</span></span>
723
+ </div>
724
+ <div id="gitUntrackedList" style="max-height:80px;overflow-y:auto;"></div>
725
+ </div>
726
+ <!-- 提交 -->
727
+ <div style="border-top:1px solid var(--border);padding-top:8px;">
728
+ <textarea id="gitCommitMessage" placeholder="提交信息(Ctrl+Enter 提交)" style="width:100%;padding:6px 8px;font-size:12px;border:1px solid var(--border);border-radius:6px;resize:vertical;min-height:50px;margin-bottom:6px;background:var(--card);color:var(--ink);"></textarea>
729
+ <button id="gitCommitBtn" style="width:100%;padding:6px;font-size:12px;font-weight:600;background:#2d5a3d;color:#fff;border:none;border-radius:6px;cursor:pointer;">✓ 提交</button>
730
+ </div>
731
+ <!-- 提交历史 -->
732
+ <div style="margin-top:10px;border-top:1px solid var(--border);padding-top:8px;">
733
+ <div style="font-size:11px;font-weight:600;margin-bottom:4px;cursor:pointer;" id="gitLogToggle">📜 提交历史 ▼</div>
734
+ <div id="gitLogList" style="display:none;max-height:150px;overflow-y:auto;font-size:11px;"></div>
735
+ </div>
736
+ </div>
737
+ <!-- Diff 查看模态 -->
738
+ <div id="gitDiffModal" style="display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.5);z-index:1000;display:none;align-items:center;justify-content:center;">
739
+ <div style="background:var(--card);border-radius:8px;padding:16px;max-width:90%;max-height:80%;width:700px;overflow:hidden;display:flex;flex-direction:column;">
740
+ <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
741
+ <span id="gitDiffTitle" style="font-size:13px;font-weight:600;">Diff</span>
742
+ <button id="gitDiffCloseBtn" style="background:none;border:none;font-size:18px;cursor:pointer;color:var(--ink);">✕</button>
743
+ </div>
744
+ <pre id="gitDiffContent" style="margin:0;overflow:auto;flex:1;font-size:11px;line-height:1.5;white-space:pre-wrap;word-break:break-all;"></pre>
745
+ </div>
746
+ </div>
747
+ </div>
748
+ <!-- P2-3: 团队协作面板 -->
749
+ <div class="preview-panel" id="teamPanel">
750
+ <!-- 团队信息和统计 -->
751
+ <div style="margin-bottom:10px;">
752
+ <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;">
753
+ <span style="font-size:13px;font-weight:600;">👥 <span id="teamName">团队</span></span>
754
+ <button id="teamRefreshBtn" class="ghost-btn" style="font-size:11px;padding:3px 8px;">🔄</button>
755
+ </div>
756
+ <div style="display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:10px;">
757
+ <div style="background:var(--card);padding:8px;border-radius:6px;text-align:center;">
758
+ <div style="font-size:16px;font-weight:600;color:#2d5a3d;" id="teamMemberCount">0</div>
759
+ <div style="font-size:10px;color:var(--muted);">成员</div>
760
+ </div>
761
+ <div style="background:var(--card);padding:8px;border-radius:6px;text-align:center;">
762
+ <div style="font-size:16px;font-weight:600;color:#2d5a3d;" id="teamTaskCount">0</div>
763
+ <div style="font-size:10px;color:var(--muted);">任务</div>
764
+ </div>
765
+ </div>
766
+ </div>
767
+ <!-- Tab 切换 -->
768
+ <div style="display:flex;gap:4px;margin-bottom:8px;border-bottom:1px solid var(--border);padding-bottom:6px;">
769
+ <button class="team-tab active" data-tab="members" style="flex:1;padding:5px;font-size:11px;border:none;background:none;cursor:pointer;color:var(--ink);border-bottom:2px solid #2d5a3d;font-weight:600;">👤 成员</button>
770
+ <button class="team-tab" data-tab="tasks" style="flex:1;padding:5px;font-size:11px;border:none;background:none;cursor:pointer;color:var(--muted);border-bottom:2px solid transparent;">📋 任务</button>
771
+ </div>
772
+ <!-- 成员管理 -->
773
+ <div id="teamMembersTab">
774
+ <div style="display:flex;gap:4px;margin-bottom:8px;">
775
+ <input type="text" id="teamInviteName" placeholder="姓名" style="flex:1;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);" />
776
+ <input type="email" id="teamInviteEmail" placeholder="邮箱" style="flex:1;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);" />
777
+ <button id="teamInviteBtn" style="padding:5px 10px;font-size:11px;background:#2d5a3d;color:#fff;border:none;border-radius:4px;cursor:pointer;">邀请</button>
778
+ </div>
779
+ <div id="teamMembersList" style="max-height:300px;overflow-y:auto;"></div>
780
+ </div>
781
+ <!-- 任务管理 -->
782
+ <div id="teamTasksTab" style="display:none;">
783
+ <div style="display:flex;gap:4px;margin-bottom:8px;">
784
+ <input type="text" id="teamTaskTitle" placeholder="任务标题" style="flex:1;padding:5px 8px;font-size:11px;border:1px solid var(--border);border-radius:4px;background:var(--card);color:var(--ink);" />
785
+ <button id="teamCreateTaskBtn" style="padding:5px 10px;font-size:11px;background:#2d5a3d;color:#fff;border:none;border-radius:4px;cursor:pointer;">创建</button>
786
+ </div>
787
+ <div style="display:flex;gap:4px;margin-bottom:8px;flex-wrap:wrap;">
788
+ <button class="team-task-filter active" data-status="" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">全部</button>
789
+ <button class="team-task-filter" data-status="todo" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">待办</button>
790
+ <button class="team-task-filter" data-status="in-progress" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">进行中</button>
791
+ <button class="team-task-filter" data-status="review" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">评审</button>
792
+ <button class="team-task-filter" data-status="done" style="padding:3px 8px;font-size:10px;border:1px solid var(--border);border-radius:3px;cursor:pointer;background:var(--card);color:var(--ink);">完成</button>
793
+ </div>
794
+ <div id="teamTasksList" style="max-height:300px;overflow-y:auto;"></div>
795
+ </div>
796
+ </div>
494
797
  </div>
495
798
  </aside>
496
799
  </div>
@@ -513,6 +816,62 @@
513
816
  </div>
514
817
  </div>
515
818
 
819
+ <!-- 添加节点模态框 -->
820
+ <div class="mask" id="nodeModal">
821
+ <div class="modal">
822
+ <span class="close-x" data-close="nodeModal">✕</span>
823
+ <h3 id="nodeModalTitle">添加节点</h3>
824
+ <p class="hint">连接外部节点,扩展模板/插件/办公能力来源。节点需提供标准 API 或本地 JSON 文件。</p>
825
+ <input type="hidden" id="nodeEditId" />
826
+ <label for="nodeName">节点名称</label>
827
+ <input type="text" id="nodeName" placeholder="如:公司内部技能库" />
828
+ <label for="nodeType">节点类型</label>
829
+ <select id="nodeType">
830
+ <option value="http">HTTP API 节点</option>
831
+ <option value="local">本地目录节点</option>
832
+ <option value="git">Git 仓库节点</option>
833
+ </select>
834
+ <label for="nodeUrl">地址(URL 或本地路径)</label>
835
+ <input type="text" id="nodeUrl" placeholder="如:https://api.example.com 或 D:\nodes\my-node" />
836
+ <label for="nodeApiKey">API Key(可选)</label>
837
+ <input type="password" id="nodeApiKey" placeholder="留空表示不需要认证" autocomplete="off" />
838
+ <label>提供的能力</label>
839
+ <div style="display:flex;gap:16px;margin-bottom:12px;">
840
+ <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapTemplates" checked /> 模板</label>
841
+ <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapSkills" checked /> 插件</label>
842
+ <label style="display:flex;align-items:center;gap:6px;cursor:pointer;"><input type="checkbox" id="nodeCapOffice" checked /> 办公</label>
843
+ </div>
844
+ <div class="footer">
845
+ <button class="ghost" data-close="nodeModal">取消</button>
846
+ <button id="nodeSaveBtn" class="primary">保存并测试连接</button>
847
+ </div>
848
+ </div>
849
+ </div>
850
+
851
+ <!-- 添加自定义来源模态框 -->
852
+ <div class="mask" id="sourceModal">
853
+ <div class="modal">
854
+ <span class="close-x" data-close="sourceModal">✕</span>
855
+ <h3 id="sourceModalTitle">添加自定义来源</h3>
856
+ <p class="hint">添加远程 JSON 数据源,自动拉取模板/插件/办公能力。</p>
857
+ <input type="hidden" id="sourceEditId" />
858
+ <label for="sourceName">来源名称</label>
859
+ <input type="text" id="sourceName" placeholder="如:团队共享模板" />
860
+ <label for="sourceType">来源类型</label>
861
+ <select id="sourceType">
862
+ <option value="templates">模板</option>
863
+ <option value="skills">插件</option>
864
+ <option value="office">办公能力</option>
865
+ </select>
866
+ <label for="sourceUrl">JSON 数据地址</label>
867
+ <input type="text" id="sourceUrl" placeholder="https://example.com/templates.json" />
868
+ <div class="footer">
869
+ <button class="ghost" data-close="sourceModal">取消</button>
870
+ <button id="sourceSaveBtn" class="primary">保存</button>
871
+ </div>
872
+ </div>
873
+ </div>
874
+
516
875
  <div class="mask" id="tplModal">
517
876
  <div class="modal">
518
877
  <span class="close-x" data-close="tplModal">✕</span>
@@ -602,14 +961,47 @@
602
961
  </div>
603
962
 
604
963
  <div class="mask" id="folderPickerModal">
605
- <div class="modal" style="width:520px;">
964
+ <div class="modal" style="width:560px;">
606
965
  <span class="close-x" data-close="folderPickerModal">✕</span>
607
- <h3 data-i18n="modal.folder_title">📂 选择工作区文件夹</h3>
608
- <div class="fp-path" id="fpPath" style="font-size:12px;color:var(--ink-2);word-break:break-all;padding:8px;background:var(--bg);border-radius:8px;">—</div>
609
- <div class="file-tree" id="fpTree" style="max-height:280px;overflow:auto;margin:10px 0;"></div>
966
+ <h3 id="fpTitle">📂 选择工作区文件夹</h3>
967
+
968
+ <!-- 驱动器选择视图 -->
969
+ <div id="fpDrivesView">
970
+ <p class="hint" style="margin:8px 0;">请选择一个驱动器,然后在其中选择或新建文件夹作为工作区。</p>
971
+ <div class="fp-drives-grid" id="fpDrivesGrid" style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:10px 0;max-height:320px;overflow:auto;"></div>
972
+ </div>
973
+
974
+ <!-- 文件夹选择视图 -->
975
+ <div id="fpFoldersView" style="display:none;">
976
+ <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
977
+ <button class="ghost sm" id="fpBackToDrives" style="flex-shrink:0;">← 驱动器</button>
978
+ <button class="ghost sm" id="fpUpDir" style="flex-shrink:0;">↑ 上级</button>
979
+ <div class="fp-path" id="fpPath" style="flex:1;font-size:12px;color:var(--ink-2);word-break:break-all;padding:6px 8px;background:var(--bg);border-radius:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">—</div>
980
+ </div>
981
+ <div style="display:flex;gap:8px;margin-bottom:8px;">
982
+ <button class="ghost sm" id="fpNewFolder">+ 新建文件夹</button>
983
+ <button class="ghost sm" id="fpRenameFolder" disabled>✎ 重命名</button>
984
+ </div>
985
+ <div class="file-tree" id="fpTree" style="max-height:260px;overflow:auto;margin:10px 0;"></div>
986
+ </div>
987
+
988
+ <!-- 新建文件夹输入框 -->
989
+ <div id="fpMkdirBar" style="display:none;gap:8px;margin-bottom:8px;">
990
+ <input type="text" id="fpMkdirName" placeholder="输入新文件夹名称" style="flex:1;padding:6px 10px;border:1px solid var(--line);border-radius:6px;font-size:13px;" />
991
+ <button class="primary sm" id="fpMkdirConfirm">确定</button>
992
+ <button class="ghost sm" id="fpMkdirCancel">取消</button>
993
+ </div>
994
+
995
+ <!-- 重命名输入框 -->
996
+ <div id="fpRenameBar" style="display:none;gap:8px;margin-bottom:8px;">
997
+ <input type="text" id="fpRenameName" placeholder="输入新名称" style="flex:1;padding:6px 10px;border:1px solid var(--line);border-radius:6px;font-size:13px;" />
998
+ <button class="primary sm" id="fpRenameConfirm">确定</button>
999
+ <button class="ghost sm" id="fpRenameCancel">取消</button>
1000
+ </div>
1001
+
610
1002
  <div class="footer">
611
- <button class="ghost" id="fpCancel" data-close="folderPickerModal" data-i18n="btn.cancel">取消</button>
612
- <button class="primary" id="fpConfirm" data-i18n="btn.select_folder">选择此文件夹</button>
1003
+ <button class="ghost" id="fpCancel" data-close="folderPickerModal">取消</button>
1004
+ <button class="primary" id="fpConfirm" disabled>选择此文件夹</button>
613
1005
  </div>
614
1006
  </div>
615
1007
  </div>
@@ -798,7 +1190,9 @@
798
1190
  <input type="file" id="imageInput" accept="image/*" />
799
1191
  <div class="toast" id="toast"></div>
800
1192
 
1193
+ <script src="js/mock-api.js"></script>
801
1194
  <script src="js/utils.js"></script>
1195
+ <script src="js/monaco-editor.js"></script>
802
1196
  <script src="js/api.js"></script>
803
1197
  <script src="js/ui.js"></script>
804
1198
  <script src="js/app.js"></script>