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
@@ -0,0 +1,602 @@
1
+ /**
2
+ * 飞虹 Code Electron 桌面版主进程(简化稳定版)
3
+ * 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
4
+ */
5
+
6
+ const { app, BrowserWindow, shell, Tray, Menu, ipcMain, dialog, clipboard, Notification, session, desktopCapturer, screen, globalShortcut } = require('electron');
7
+ const { spawn } = require('child_process');
8
+ const { existsSync, writeFileSync, readFileSync } = require('fs');
9
+ const { join, resolve } = require('path');
10
+ const http = require('http');
11
+ const os = require('os');
12
+
13
+ // 禁用安全警告
14
+ process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = 'true';
15
+
16
+ // 配置
17
+ const PORT = parseInt(process.env.FH_WEB_PORT || '8081');
18
+ const isDev = !app.isPackaged;
19
+
20
+ // 全局变量
21
+ let mainWindow = null;
22
+ let serverProcess = null;
23
+ let tray = null;
24
+
25
+ // 获取应用根目录
26
+ function getAppPath() {
27
+ if (isDev) return join(__dirname, '..');
28
+ return process.resourcesPath ? join(process.resourcesPath, 'app') : app.getAppPath();
29
+ }
30
+ const APP_PATH = getAppPath();
31
+
32
+ /**
33
+ * 等待服务器就绪
34
+ */
35
+ function waitForServer(port, timeoutMs) {
36
+ return new Promise((resolve, reject) => {
37
+ const startTime = Date.now();
38
+ const check = () => {
39
+ const req = http.get(`http://127.0.0.1:${port}/api/health`, (res) => {
40
+ if (res.statusCode === 200) {
41
+ resolve();
42
+ } else {
43
+ res.resume();
44
+ retry();
45
+ }
46
+ });
47
+ req.on('error', () => retry());
48
+ req.setTimeout(2000, () => { req.destroy(); retry(); });
49
+ };
50
+ const retry = () => {
51
+ if (Date.now() - startTime > timeoutMs) {
52
+ reject(new Error('服务器启动超时'));
53
+ } else {
54
+ setTimeout(check, 500);
55
+ }
56
+ };
57
+ check();
58
+ });
59
+ }
60
+
61
+ /**
62
+ * 启动内置 Web 服务器
63
+ */
64
+ function startServer() {
65
+ return new Promise((resolve, reject) => {
66
+ const serverEntry = join(APP_PATH, 'dist', 'cli', 'index.js');
67
+ if (!existsSync(serverEntry)) {
68
+ reject(new Error('未找到服务器入口文件,请先运行 npm run build'));
69
+ return;
70
+ }
71
+
72
+ console.log('[Electron] 启动服务器,端口: ' + PORT);
73
+
74
+ let serverLog = '';
75
+ let started = false;
76
+
77
+ serverProcess = spawn('node', [serverEntry, 'serve'], {
78
+ cwd: APP_PATH,
79
+ env: { ...process.env, FH_WEB_PORT: String(PORT) },
80
+ stdio: ['ignore', 'pipe', 'pipe']
81
+ });
82
+
83
+ serverProcess.stdout.on('data', (data) => {
84
+ const text = data.toString();
85
+ serverLog += text;
86
+ console.log('[Server] ' + text.trim());
87
+ });
88
+
89
+ serverProcess.stderr.on('data', (data) => {
90
+ const text = data.toString();
91
+ serverLog += text;
92
+ console.error('[Server Error] ' + text.trim());
93
+ });
94
+
95
+ serverProcess.on('error', (err) => {
96
+ if (!started) reject(new Error('启动服务器失败: ' + err.message));
97
+ });
98
+
99
+ serverProcess.on('exit', (code) => {
100
+ console.log('[Electron] 服务器退出,代码: ' + code);
101
+ serverProcess = null;
102
+ if (!started) {
103
+ reject(new Error('服务器启动失败,退出代码: ' + code + '\n\n日志:\n' + serverLog.slice(-2000)));
104
+ }
105
+ });
106
+
107
+ // 等待服务器就绪
108
+ waitForServer(PORT, 60000).then(() => {
109
+ started = true;
110
+ console.log('[Electron] 服务器已就绪');
111
+ resolve();
112
+ }).catch((err) => {
113
+ if (!started) reject(new Error(err.message + '\n\n服务器日志:\n' + serverLog.slice(-2000)));
114
+ });
115
+ });
116
+ }
117
+
118
+ /**
119
+ * 创建主窗口
120
+ */
121
+ function createWindow() {
122
+ mainWindow = new BrowserWindow({
123
+ width: 1400,
124
+ height: 900,
125
+ minWidth: 1024,
126
+ minHeight: 680,
127
+ title: '飞虹 Code',
128
+ webPreferences: {
129
+ preload: join(__dirname, 'preload.js'),
130
+ contextIsolation: true,
131
+ nodeIntegration: false
132
+ },
133
+ show: false,
134
+ backgroundColor: '#1a1a2e'
135
+ });
136
+
137
+ const url = `http://127.0.0.1:${PORT}/`;
138
+ console.log('[Electron] 加载页面: ' + url);
139
+ mainWindow.loadURL(url);
140
+
141
+ mainWindow.once('ready-to-show', () => {
142
+ mainWindow.show();
143
+ });
144
+
145
+ // 外部链接用系统浏览器打开
146
+ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
147
+ shell.openExternal(url);
148
+ return { action: 'deny' };
149
+ });
150
+
151
+ // 关闭时最小化到托盘
152
+ mainWindow.on('close', (e) => {
153
+ if (!app.isQuitting) {
154
+ e.preventDefault();
155
+ mainWindow.hide();
156
+ }
157
+ });
158
+
159
+ mainWindow.on('closed', () => {
160
+ mainWindow = null;
161
+ });
162
+ }
163
+
164
+ /**
165
+ * 创建系统托盘
166
+ */
167
+ function createTray() {
168
+ try {
169
+ const iconPath = join(__dirname, 'icon.png');
170
+ let trayIcon;
171
+ if (existsSync(iconPath)) {
172
+ trayIcon = require('electron').nativeImage.createFromPath(iconPath);
173
+ } else {
174
+ trayIcon = require('electron').nativeImage.createEmpty();
175
+ }
176
+
177
+ tray = new Tray(trayIcon);
178
+ tray.setToolTip('飞虹 Code');
179
+
180
+ const isAutoLaunch = app.getLoginItemSettings().openAtLogin;
181
+
182
+ const contextMenu = Menu.buildFromTemplate([
183
+ { label: '显示主窗口', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); } } },
184
+ { label: '隐藏到托盘', click: () => { if (mainWindow) mainWindow.hide(); } },
185
+ { type: 'separator' },
186
+ { label: '新建任务', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); mainWindow.webContents.send('app:new-task'); } } },
187
+ { label: '快速补全', click: () => { if (mainWindow) { mainWindow.show(); mainWindow.focus(); mainWindow.webContents.send('app:quick-complete'); } } },
188
+ { type: 'separator' },
189
+ {
190
+ label: '开机自启动',
191
+ type: 'checkbox',
192
+ checked: isAutoLaunch,
193
+ click: (menuItem) => {
194
+ app.setLoginItemSettings({ openAtLogin: menuItem.checked });
195
+ console.log('[Electron] 开机自启动设置:', menuItem.checked);
196
+ }
197
+ },
198
+ { label: '检查更新', click: () => { checkForUpdates(); } },
199
+ { type: 'separator' },
200
+ { label: '关于飞虹 Code', click: () => { showAboutDialog(); } },
201
+ { label: '退出', click: () => { app.isQuitting = true; app.quit(); } }
202
+ ]);
203
+ tray.setContextMenu(contextMenu);
204
+
205
+ tray.on('click', () => {
206
+ if (mainWindow) {
207
+ if (mainWindow.isVisible()) mainWindow.hide();
208
+ else { mainWindow.show(); mainWindow.focus(); }
209
+ }
210
+ });
211
+
212
+ // 双击托盘显示主窗口
213
+ tray.on('double-click', () => {
214
+ if (mainWindow) { mainWindow.show(); mainWindow.focus(); }
215
+ });
216
+ } catch (e) {
217
+ console.warn('[Electron] 创建托盘失败: ' + e.message);
218
+ }
219
+ }
220
+
221
+ /**
222
+ * 创建应用菜单(关键:没有菜单会导致复制粘贴等快捷键失效)
223
+ */
224
+ function createMenu() {
225
+ const template = [
226
+ {
227
+ label: '文件',
228
+ submenu: [
229
+ { label: '刷新', role: 'reload' },
230
+ { label: '强制刷新', role: 'forceReload' },
231
+ { type: 'separator' },
232
+ { label: '退出', role: 'quit' }
233
+ ]
234
+ },
235
+ {
236
+ label: '编辑',
237
+ submenu: [
238
+ { label: '撤销', role: 'undo' },
239
+ { label: '重做', role: 'redo' },
240
+ { type: 'separator' },
241
+ { label: '剪切', role: 'cut' },
242
+ { label: '复制', role: 'copy' },
243
+ { label: '粘贴', role: 'paste' },
244
+ { label: '全选', role: 'selectAll' }
245
+ ]
246
+ },
247
+ {
248
+ label: '视图',
249
+ submenu: [
250
+ { label: '放大', role: 'zoomIn' },
251
+ { label: '缩小', role: 'zoomOut' },
252
+ { label: '重置缩放', role: 'resetZoom' },
253
+ { type: 'separator' },
254
+ { label: '全屏', role: 'togglefullscreen' },
255
+ { label: '开发者工具', role: 'toggleDevTools' }
256
+ ]
257
+ },
258
+ {
259
+ label: '窗口',
260
+ submenu: [
261
+ { label: '最小化', role: 'minimize' },
262
+ { label: '关闭', role: 'close' }
263
+ ]
264
+ },
265
+ {
266
+ label: '帮助',
267
+ submenu: [
268
+ { label: '关于飞虹 Code', click: () => {
269
+ dialog.showMessageBox(mainWindow, {
270
+ type: 'info',
271
+ title: '关于飞虹 Code',
272
+ message: '飞虹 Code v0.6.1',
273
+ detail: '终端 AI 编程智能体\n晋江市飞虹智科技企业管理有限公司'
274
+ });
275
+ }}
276
+ ]
277
+ }
278
+ ];
279
+ const menu = Menu.buildFromTemplate(template);
280
+ Menu.setApplicationMenu(menu);
281
+ }
282
+
283
+ /**
284
+ * 设置权限(麦克风、摄像头、屏幕捕获)
285
+ */
286
+ function setupPermissions() {
287
+ // 允许所有权限请求(语音输入、视频通话、截图等)
288
+ session.defaultSession.setPermissionRequestHandler((webContents, permission, callback) => {
289
+ console.log('[Electron] 权限请求: ' + permission);
290
+ // 允许所有权限
291
+ callback(true);
292
+ });
293
+
294
+ // 屏幕捕获:自动选择主屏幕,不需要每次都请求权限
295
+ session.defaultSession.setDisplayMediaRequestHandler((request, callback) => {
296
+ console.log('[Electron] 屏幕捕获请求,自动选择主屏幕');
297
+ desktopCapturer.getSources({ types: ['screen'] }).then(sources => {
298
+ if (sources.length > 0) {
299
+ // 自动选择第一个屏幕(主屏幕)
300
+ callback({ video: sources[0] });
301
+ } else {
302
+ callback({});
303
+ }
304
+ }).catch(err => {
305
+ console.error('[Electron] 获取屏幕源失败:', err.message);
306
+ callback({});
307
+ });
308
+ });
309
+ }
310
+
311
+ /**
312
+ * 设置 IPC
313
+ */
314
+ function setupIpc() {
315
+ ipcMain.on('window:minimize', () => { if (mainWindow) mainWindow.minimize(); });
316
+ ipcMain.on('window:maximize', () => { if (mainWindow) mainWindow.maximize(); });
317
+ ipcMain.on('window:unmaximize', () => { if (mainWindow) mainWindow.unmaximize(); });
318
+ ipcMain.on('window:close', () => { if (mainWindow) mainWindow.close(); });
319
+ ipcMain.handle('window:isMaximized', () => mainWindow ? mainWindow.isMaximized() : false);
320
+
321
+ ipcMain.on('app:quit', () => { app.isQuitting = true; app.quit(); });
322
+ ipcMain.on('app:restart', () => { app.relaunch(); app.exit(0); });
323
+ ipcMain.handle('app:getPath', (_, name) => { try { return app.getPath(name); } catch { return null; } });
324
+
325
+ ipcMain.handle('shell:openExternal', (_, url) => shell.openExternal(url));
326
+ ipcMain.handle('shell:openPath', (_, path) => shell.openPath(path));
327
+
328
+ ipcMain.handle('dialog:showOpen', (_, options) => dialog.showOpenDialog(mainWindow, options));
329
+ ipcMain.handle('dialog:showSave', (_, options) => dialog.showSaveDialog(mainWindow, options));
330
+ ipcMain.handle('dialog:showMessage', (_, options) => dialog.showMessageBox(mainWindow, options));
331
+
332
+ ipcMain.handle('clipboard:writeText', (_, text) => { clipboard.writeText(text); return true; });
333
+ ipcMain.handle('clipboard:readText', () => clipboard.readText());
334
+
335
+ ipcMain.handle('notification:show', (_, { title, body }) => {
336
+ if (Notification.isSupported()) { new Notification({ title, body }).show(); return true; }
337
+ return false;
338
+ });
339
+
340
+ // 截图功能:截取主屏幕,返回 dataURL
341
+ ipcMain.handle('screenshot:capture', async () => {
342
+ try {
343
+ const primaryDisplay = screen.getPrimaryDisplay();
344
+ const { width, height } = primaryDisplay.size;
345
+ const sources = await desktopCapturer.getSources({
346
+ types: ['screen'],
347
+ thumbnailSize: { width, height }
348
+ });
349
+ const primarySource = sources.find(s => s.display_id === String(primaryDisplay.id)) || sources[0];
350
+ if (!primarySource) throw new Error('未找到屏幕源');
351
+ return {
352
+ success: true,
353
+ dataUrl: primarySource.thumbnail.toDataURL(),
354
+ width: width,
355
+ height: height
356
+ };
357
+ } catch (err) {
358
+ return { success: false, error: err.message };
359
+ }
360
+ });
361
+
362
+ // 全局快捷键
363
+ ipcMain.handle('shortcuts:getAll', () => {
364
+ return [
365
+ { accelerator: 'Ctrl+Shift+Space', description: '显示/隐藏主窗口' },
366
+ { accelerator: 'Ctrl+Shift+K', description: '新建任务' },
367
+ { accelerator: 'Ctrl+Shift+L', description: '快速补全' },
368
+ ];
369
+ });
370
+
371
+ // 开机自启
372
+ ipcMain.handle('autolaunch:get', () => {
373
+ return app.getLoginItemSettings().openAtLogin;
374
+ });
375
+ ipcMain.handle('autolaunch:set', (_, enabled) => {
376
+ app.setLoginItemSettings({ openAtLogin: enabled });
377
+ return app.getLoginItemSettings().openAtLogin;
378
+ });
379
+
380
+ // 应用信息
381
+ ipcMain.handle('app:info', () => {
382
+ return {
383
+ version: app.getVersion(),
384
+ name: app.getName(),
385
+ path: app.getAppPath(),
386
+ userData: app.getPath('userData'),
387
+ platform: process.platform,
388
+ arch: process.arch,
389
+ nodeVersion: process.versions.node,
390
+ electronVersion: process.versions.electron,
391
+ chromeVersion: process.versions.chrome,
392
+ };
393
+ });
394
+ }
395
+
396
+ /**
397
+ * 注册全局快捷键
398
+ */
399
+ function registerGlobalShortcuts() {
400
+ try {
401
+ // Ctrl+Shift+Space: 快速唤起飞虹 Code(显示/隐藏主窗口)
402
+ const ret1 = globalShortcut.register('CommandOrControl+Shift+Space', () => {
403
+ if (mainWindow) {
404
+ if (mainWindow.isVisible() && mainWindow.isFocused()) {
405
+ mainWindow.hide();
406
+ } else {
407
+ mainWindow.show();
408
+ mainWindow.focus();
409
+ }
410
+ }
411
+ });
412
+
413
+ // Ctrl+Shift+K: 新建任务
414
+ const ret2 = globalShortcut.register('CommandOrControl+Shift+K', () => {
415
+ if (mainWindow) {
416
+ mainWindow.show();
417
+ mainWindow.focus();
418
+ mainWindow.webContents.send('app:new-task');
419
+ }
420
+ });
421
+
422
+ // Ctrl+Shift+L: 快速补全
423
+ const ret3 = globalShortcut.register('CommandOrControl+Shift+L', () => {
424
+ if (mainWindow) {
425
+ mainWindow.show();
426
+ mainWindow.focus();
427
+ mainWindow.webContents.send('app:quick-complete');
428
+ }
429
+ });
430
+
431
+ if (ret1 && ret2 && ret3) {
432
+ console.log('[Electron] 全局快捷键注册成功');
433
+ } else {
434
+ console.warn('[Electron] 部分全局快捷键注册失败');
435
+ }
436
+ } catch (e) {
437
+ console.warn('[Electron] 全局快捷键注册异常: ' + e.message);
438
+ }
439
+ }
440
+
441
+ /**
442
+ * 检查更新(简化版,实际应使用 electron-updater)
443
+ */
444
+ function checkForUpdates() {
445
+ console.log('[Electron] 检查更新...');
446
+ // 简化版:显示当前版本,实际应使用 electron-updater
447
+ const version = app.getVersion();
448
+ dialog.showMessageBox(mainWindow, {
449
+ type: 'info',
450
+ title: '检查更新',
451
+ message: `当前版本: v${version}`,
452
+ detail: '飞虹 Code 会在有新版本时自动通知您。\n\n您也可以访问官网下载最新版本。',
453
+ buttons: ['确定', '访问官网'],
454
+ defaultId: 0,
455
+ cancelId: 0
456
+ }).then(({ response }) => {
457
+ if (response === 1) {
458
+ shell.openExternal('https://feihong-code.com');
459
+ }
460
+ });
461
+ }
462
+
463
+ /**
464
+ * 显示关于对话框
465
+ */
466
+ function showAboutDialog() {
467
+ const version = app.getVersion();
468
+ dialog.showMessageBox(mainWindow, {
469
+ type: 'info',
470
+ title: '关于飞虹 Code',
471
+ message: `飞虹 Code v${version}`,
472
+ detail: '终端 AI 编程智能体\n晋江市飞虹智科技企业管理有限公司\n飞扬企源研发中心 · 负责人:吴赐虹\n\n技术栈:TypeScript + Electron + Express\n核心能力:多模型路由、企业级 RBAC、全自动 SWE Agent',
473
+ buttons: ['确定', '官方网站', 'GitHub'],
474
+ defaultId: 0,
475
+ cancelId: 0
476
+ }).then(({ response }) => {
477
+ if (response === 1) shell.openExternal('https://feihong-code.com');
478
+ if (response === 2) shell.openExternal('https://github.com/feihong-code');
479
+ });
480
+ }
481
+
482
+ /**
483
+ * 设置深度链接(fhcode:// 协议)
484
+ */
485
+ function setupDeepLink() {
486
+ if (process.defaultApp) {
487
+ if (process.argv.length >= 2) {
488
+ app.setAsDefaultProtocolClient('fhcode', process.execPath, [resolve(process.argv[1])]);
489
+ }
490
+ } else {
491
+ app.setAsDefaultProtocolClient('fhcode');
492
+ }
493
+ console.log('[Electron] 深度链接协议已注册: fhcode://');
494
+ }
495
+
496
+ /**
497
+ * 处理深度链接 URL
498
+ */
499
+ function handleDeepLink(url) {
500
+ console.log('[Electron] 深度链接:', url);
501
+ try {
502
+ const parsed = new URL(url);
503
+ const action = parsed.hostname;
504
+ const params = Object.fromEntries(parsed.searchParams);
505
+
506
+ if (mainWindow) {
507
+ mainWindow.show();
508
+ mainWindow.focus();
509
+ mainWindow.webContents.send('app:deep-link', { action, params });
510
+ }
511
+ } catch (e) {
512
+ console.error('[Electron] 深度链接解析失败:', e.message);
513
+ }
514
+ }
515
+
516
+ // App 就绪
517
+ app.whenReady().then(async () => {
518
+ console.log('[Electron] App 已就绪');
519
+ console.log('[Electron] 应用路径: ' + APP_PATH);
520
+
521
+ try {
522
+ setupIpc();
523
+ setupPermissions();
524
+ setupDeepLink();
525
+ createMenu();
526
+ await startServer();
527
+ createWindow();
528
+ createTray();
529
+ registerGlobalShortcuts();
530
+
531
+ app.on('activate', () => {
532
+ if (BrowserWindow.getAllWindows().length === 0) createWindow();
533
+ });
534
+ } catch (err) {
535
+ console.error('[Electron] 启动失败: ' + err.message);
536
+
537
+ // 显示错误窗口
538
+ const errorWin = new BrowserWindow({
539
+ width: 700,
540
+ height: 500,
541
+ title: '启动失败',
542
+ webPreferences: { nodeIntegration: true, contextIsolation: false }
543
+ });
544
+
545
+ const errorHtml = `
546
+ <html><body style="font-family:Microsoft YaHei,sans-serif;padding:30px;background:#1a1a2e;color:#fff;margin:0;">
547
+ <h2 style="color:#ff6b6b;">飞虹 Code 启动失败</h2>
548
+ <p style="color:#aaa;">错误详情:</p>
549
+ <pre style="background:#0d1117;padding:15px;border-radius:8px;overflow:auto;white-space:pre-wrap;font-size:12px;max-height:300px;">${String(err.message).replace(/</g, '&lt;')}</pre>
550
+ <p style="color:#888;margin-top:20px;">请检查:1) 是否已运行 npm run build 2) 端口 ${PORT} 是否被占用 3) Node.js 版本是否 >= 18</p>
551
+ <p style="color:#666;margin-top:20px;font-size:12px;">关闭此窗口后退出</p>
552
+ </body></html>
553
+ `;
554
+ errorWin.loadURL('data:text/html;charset=utf-8,' + encodeURIComponent(errorHtml));
555
+ errorWin.on('closed', () => app.quit());
556
+ }
557
+ });
558
+
559
+ // 所有窗口关闭时不退出(保持托盘运行)
560
+ app.on('window-all-closed', () => {});
561
+
562
+ // 退出前注销全局快捷键并停止服务器
563
+ app.on('before-quit', () => {
564
+ app.isQuitting = true;
565
+ globalShortcut.unregisterAll();
566
+ if (serverProcess) {
567
+ serverProcess.kill();
568
+ serverProcess = null;
569
+ }
570
+ });
571
+
572
+ // 处理深度链接(Windows/Linux)
573
+ app.on('second-instance', (event, commandLine) => {
574
+ if (mainWindow) {
575
+ if (mainWindow.isMinimized()) mainWindow.restore();
576
+ mainWindow.show();
577
+ mainWindow.focus();
578
+ }
579
+ // 查找深度链接 URL
580
+ const deepLink = commandLine.find(arg => arg.startsWith('fhcode://'));
581
+ if (deepLink) handleDeepLink(deepLink);
582
+ });
583
+
584
+ // 处理深度链接(macOS)
585
+ app.on('open-url', (event, url) => {
586
+ event.preventDefault();
587
+ handleDeepLink(url);
588
+ });
589
+
590
+ // 防止多开
591
+ const gotLock = app.requestSingleInstanceLock();
592
+ if (!gotLock) {
593
+ app.quit();
594
+ } else {
595
+ app.on('second-instance', () => {
596
+ if (mainWindow) {
597
+ if (mainWindow.isMinimized()) mainWindow.restore();
598
+ mainWindow.show();
599
+ mainWindow.focus();
600
+ }
601
+ });
602
+ }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "feihong-code",
3
- "version": "0.6.1",
3
+ "version": "7.2.0",
4
4
  "description": "fhcode(飞虹 Code)— 终端 AI 编程智能体,对标 Muse Code / Cursor CLI:多模型路由(DeepSeek/通义/Ollama/OpenAI)、企业级 RBAC 审计、全自动 SWE Agent、支持离线私有化",
5
5
  "bin": {
6
6
  "fhcode": "dist/cli/index.js"
7
7
  },
8
- "main": "dist/cli/index.js",
8
+ "main": "electron/main.js",
9
9
  "files": [
10
10
  "dist",
11
11
  "README.md",
@@ -31,7 +31,12 @@
31
31
  "eval": "node scripts/eval.mjs",
32
32
  "test": "tsx --test tests/unit/*.test.ts",
33
33
  "verify": "npm run typecheck && npm run build && npm run verify:m4 && npm run verify:m6 && npm run verify:m7 && npm run verify:m8 && npm run verify:m9",
34
- "prepublishOnly": "npm run build"
34
+ "prepublishOnly": "npm run build",
35
+ "electron": "electron .",
36
+ "electron:dev": "electron .",
37
+ "electron:build": "npm run build && electron-builder --win --x64",
38
+ "electron:dist": "npm run build && electron-builder --win --x64 --publish never",
39
+ "electron:pack": "npm run build && electron-builder --dir"
35
40
  },
36
41
  "keywords": [
37
42
  "ai",
@@ -93,16 +98,75 @@
93
98
  "url": "https://www.klai.top"
94
99
  },
95
100
  "devDependencies": {
101
+ "@capacitor/android": "^8.5.0",
102
+ "@capacitor/cli": "^7.6.8",
96
103
  "@types/express": "^5.0.6",
97
104
  "@types/node": "^26.2.0",
105
+ "electron": "^41.7.1",
106
+ "electron-builder": "^26.15.3",
98
107
  "tsx": "^4.19.2",
99
108
  "typescript": "^5.6.3"
100
109
  },
101
110
  "dependencies": {
111
+ "@capacitor/core": "^8.5.0",
102
112
  "express": "^4.21.2",
113
+ "monaco-editor": "^0.56.0",
114
+ "playwright-core": "^1.62.1",
103
115
  "zod": "^4.4.3"
104
116
  },
105
117
  "publishConfig": {
106
118
  "registry": "https://registry.npmjs.org/"
119
+ },
120
+ "build": {
121
+ "appId": "com.feihong.code",
122
+ "productName": "飞虹 Code",
123
+ "copyright": "Copyright © 2026 晋江市飞虹智科技企业管理有限公司",
124
+ "directories": {
125
+ "output": "release"
126
+ },
127
+ "files": [
128
+ "electron/**/*",
129
+ "dist/**/*",
130
+ "package.json",
131
+ "!**/*.ts",
132
+ "!**/*.map",
133
+ "!tests/**",
134
+ "!docs/**",
135
+ "!scripts/**",
136
+ "!src/**"
137
+ ],
138
+ "extraResources": [
139
+ {
140
+ "from": "dist",
141
+ "to": "app/dist"
142
+ }
143
+ ],
144
+ "win": {
145
+ "target": [
146
+ {
147
+ "target": "nsis",
148
+ "arch": [
149
+ "x64"
150
+ ]
151
+ },
152
+ {
153
+ "target": "portable",
154
+ "arch": [
155
+ "x64"
156
+ ]
157
+ }
158
+ ],
159
+ "icon": "electron/icon.png"
160
+ },
161
+ "nsis": {
162
+ "oneClick": false,
163
+ "allowToChangeInstallationDirectory": true,
164
+ "createDesktopShortcut": true,
165
+ "createStartMenuShortcut": true,
166
+ "shortcutName": "飞虹 Code"
167
+ },
168
+ "portable": {
169
+ "artifactName": "飞虹Code-Portable-${version}.exe"
170
+ }
107
171
  }
108
172
  }