feihong-code 7.0.0 → 7.5.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 (149) hide show
  1. package/.github/workflows/ci.yml +180 -140
  2. package/.github/workflows/release.yml +200 -0
  3. package/CHANGELOG.md +94 -65
  4. package/README.md +609 -586
  5. package/dist/agent/browser-agent.js +354 -0
  6. package/dist/agent/browser-agent.js.map +1 -0
  7. package/dist/agent/change-manager.js +433 -0
  8. package/dist/agent/change-manager.js.map +1 -0
  9. package/dist/agent/code-rag.js +293 -0
  10. package/dist/agent/code-rag.js.map +1 -0
  11. package/dist/agent/code-writer.js +13 -1
  12. package/dist/agent/code-writer.js.map +1 -1
  13. package/dist/agent/completion-engine.js +553 -0
  14. package/dist/agent/completion-engine.js.map +1 -0
  15. package/dist/agent/completion-postprocess.js +109 -0
  16. package/dist/agent/completion-postprocess.js.map +1 -0
  17. package/dist/agent/context-budget.js +121 -0
  18. package/dist/agent/context-budget.js.map +1 -0
  19. package/dist/agent/context-compactor.js +235 -10
  20. package/dist/agent/context-compactor.js.map +1 -1
  21. package/dist/agent/custom-agent.js +368 -0
  22. package/dist/agent/custom-agent.js.map +1 -0
  23. package/dist/agent/design-to-code.js +218 -0
  24. package/dist/agent/design-to-code.js.map +1 -0
  25. package/dist/agent/event-driven-agent.js +359 -0
  26. package/dist/agent/event-driven-agent.js.map +1 -0
  27. package/dist/agent/git-integration.js +324 -0
  28. package/dist/agent/git-integration.js.map +1 -0
  29. package/dist/agent/layered-memory.js +329 -0
  30. package/dist/agent/layered-memory.js.map +1 -0
  31. package/dist/agent/lint.js +121 -0
  32. package/dist/agent/lint.js.map +1 -0
  33. package/dist/agent/multi-agent.js +359 -0
  34. package/dist/agent/multi-agent.js.map +1 -0
  35. package/dist/agent/orchestrator.js +136 -25
  36. package/dist/agent/orchestrator.js.map +1 -1
  37. package/dist/agent/prompts.js +54 -54
  38. package/dist/agent/quality-gate.js +139 -0
  39. package/dist/agent/quality-gate.js.map +1 -1
  40. package/dist/agent/self-correction.js +274 -0
  41. package/dist/agent/self-correction.js.map +1 -0
  42. package/dist/agent/self-heal.js +47 -17
  43. package/dist/agent/self-heal.js.map +1 -1
  44. package/dist/agent/solo-agent.js +321 -0
  45. package/dist/agent/solo-agent.js.map +1 -0
  46. package/dist/agent/symbol-index.js +258 -28
  47. package/dist/agent/symbol-index.js.map +1 -1
  48. package/dist/agent/team-collaboration.js +252 -0
  49. package/dist/agent/team-collaboration.js.map +1 -0
  50. package/dist/agent/type-checker.js +229 -0
  51. package/dist/agent/type-checker.js.map +1 -0
  52. package/dist/cli/commands.js +9 -0
  53. package/dist/cli/commands.js.map +1 -1
  54. package/dist/cli/index.js +9 -0
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/multi-pane-tui.js +217 -0
  57. package/dist/cli/multi-pane-tui.js.map +1 -0
  58. package/dist/cli/run.js +130 -40
  59. package/dist/cli/run.js.map +1 -1
  60. package/dist/cli/tui-run.js +79 -0
  61. package/dist/cli/tui-run.js.map +1 -0
  62. package/dist/cli/tui.js.map +1 -1
  63. package/dist/cli/version.js +1 -1
  64. package/dist/integrations/collaboration.js +219 -0
  65. package/dist/integrations/collaboration.js.map +1 -0
  66. package/dist/integrations/figma.js +307 -0
  67. package/dist/integrations/figma.js.map +1 -0
  68. package/dist/integrations/sso.js +327 -0
  69. package/dist/integrations/sso.js.map +1 -0
  70. package/dist/knowledge/library.js +301 -0
  71. package/dist/knowledge/library.js.map +1 -0
  72. package/dist/lsp/lsp-client.js +183 -0
  73. package/dist/lsp/lsp-client.js.map +1 -0
  74. package/dist/lsp/lsp-service.js +159 -0
  75. package/dist/lsp/lsp-service.js.map +1 -0
  76. package/dist/plugins/manager.js +380 -0
  77. package/dist/plugins/manager.js.map +1 -0
  78. package/dist/runtime/event-log.js.map +1 -1
  79. package/dist/shared/i18n.js +108 -100
  80. package/dist/shared/i18n.js.map +1 -1
  81. package/dist/tools/browser/browser.tool.js +217 -0
  82. package/dist/tools/browser/browser.tool.js.map +1 -0
  83. package/dist/tools/generator/code-generator.js +40 -40
  84. package/dist/tools/generator/test-generator.js +9 -9
  85. package/dist/tools/index.js +2 -0
  86. package/dist/tools/index.js.map +1 -1
  87. package/dist/tools/shell/exec.js +73 -11
  88. package/dist/tools/shell/exec.js.map +1 -1
  89. package/dist/tools/shell/run-shell.tool.js +8 -2
  90. package/dist/tools/shell/run-shell.tool.js.map +1 -1
  91. package/dist/training/completion-evaluator.js +213 -0
  92. package/dist/training/completion-evaluator.js.map +1 -0
  93. package/dist/training/fim-data.js +248 -0
  94. package/dist/training/fim-data.js.map +1 -0
  95. package/dist/voice/voice-programming.js +223 -0
  96. package/dist/voice/voice-programming.js.map +1 -0
  97. package/dist/web/extra-apis.js +440 -0
  98. package/dist/web/extra-apis.js.map +1 -0
  99. package/dist/web/public/css/style.css +1729 -1671
  100. package/dist/web/public/index.html +1242 -990
  101. package/dist/web/public/js/api.js +555 -382
  102. package/dist/web/public/js/app.js +2210 -2210
  103. package/dist/web/public/js/mock-api.js +234 -0
  104. package/dist/web/public/js/monaco-editor.js +363 -0
  105. package/dist/web/public/js/ui.js +2251 -1059
  106. package/dist/web/public/js/utils.js +214 -214
  107. package/dist/web/public/manifest.json +59 -0
  108. package/dist/web/public/service-worker.js +173 -0
  109. package/dist/web/server.js +1116 -45
  110. package/dist/web/server.js.map +1 -1
  111. package/dist/web/task-queue.js +22 -2
  112. package/dist/web/task-queue.js.map +1 -1
  113. package/docs/BENCHMARK_REPORT_en.md +386 -329
  114. package/docs/BENCHMARK_REPORT_zh.md +386 -329
  115. package/docs/DPA.md +63 -0
  116. package/docs/DPA/346/225/260/346/215/256/345/244/204/347/220/206/345/215/217/350/256/256/346/250/241/346/235/277_v1.0.md +67 -0
  117. package/docs/SECURITY_WHITEPAPER.md +74 -0
  118. package/docs/SWE_BENCH_REPORT.md +55 -0
  119. package/docs/TECHNICAL_SPEC_en.md +292 -292
  120. package/docs/TECHNICAL_SPEC_zh.md +292 -292
  121. package/docs/UPDATE_NOTES_en.md +159 -159
  122. package/docs/UPDATE_NOTES_zh.md +159 -159
  123. package/docs/UPGRADE_7.2.0.md +309 -0
  124. package/docs/UPGRADE_GUIDE_7_5.md +86 -0
  125. package/docs/geo-feihong-code.html +391 -0
  126. package/docs//345/205/250/351/235/242/345/244/215/347/233/230_50/350/275/256/346/267/261/345/272/246/345/256/241/350/256/241_v7.2.0.md +208 -0
  127. package/docs//345/205/250/351/235/242/345/244/215/347/233/230_6/351/241/271/351/207/215/347/202/271/346/240/270/346/237/245_v7.2.0.md +152 -0
  128. package/docs//345/205/250/351/235/242/345/244/215/347/233/230_/350/277/220/350/241/214/346/227/266/345/256/236/346/265/213/347/211/210_v7.2.0.md +271 -0
  129. package/docs//345/220/210/350/247/204/350/256/244/350/257/201/345/207/206/345/244/207/346/270/205/345/215/225_v7.2.0.md +59 -0
  130. package/docs//345/256/211/345/205/250/347/231/275/347/232/256/344/271/246_v7.2.0.md +82 -0
  131. package/electron/main.js +404 -404
  132. package/package.json +175 -167
  133. package/templates/skills/api-design/SKILL.md +27 -0
  134. package/templates/skills/code-review/SKILL.md +35 -0
  135. package/templates/skills/dependency-upgrade/SKILL.md +29 -0
  136. package/templates/skills/doc-gen/SKILL.md +29 -0
  137. package/templates/skills/git-flow/SKILL.md +26 -0
  138. package/templates/skills/onboarding/SKILL.md +27 -0
  139. package/templates/skills/performance/SKILL.md +29 -0
  140. package/templates/skills/refactor/SKILL.md +28 -0
  141. package/templates/skills/security-audit/SKILL.md +28 -0
  142. package/templates/skills/test-gen/SKILL.md +30 -0
  143. package/tool-schema.json +197 -197
  144. package/dist/hello.js +0 -14
  145. package/dist/hello.js.map +0 -1
  146. package/dist/self-evolve/hook.ts +0 -80
  147. package/dist/self-evolve/manager.d.ts +0 -8
  148. package/dist/web/web-config.js +0 -143
  149. package/dist/web/web-config.js.map +0 -1
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VoiceProgrammingManager = void 0;
4
+ exports.createVoiceProgrammingManager = createVoiceProgrammingManager;
5
+ /**
6
+ * 飞虹 Code - 语音编程 (阶段四-1)
7
+ *
8
+ * 支持语音编程能力:
9
+ * - 语音指令解析:将自然语言语音转换为编程操作
10
+ * - 语音转代码:根据语音描述生成代码
11
+ * - 语音命令:常用操作的语音快捷命令
12
+ * - 语音上下文:维护语音对话上下文
13
+ */
14
+ const logger_1 = require("../shared/logger");
15
+ /** 语音命令映射规则 */
16
+ const COMMAND_RULES = [
17
+ {
18
+ type: 'new_file',
19
+ patterns: [/新建文件|创建文件|新文件|new file/i],
20
+ extractParams: (text) => {
21
+ const match = text.match(/(?:新建|创建|new)\s*(?:文件|file)?\s*(?:叫|名为|named)?\s*([\w.]+)/i);
22
+ return match ? { fileName: match[1] } : {};
23
+ },
24
+ },
25
+ {
26
+ type: 'open_file',
27
+ patterns: [/打开文件|打开|open file|open/i],
28
+ extractParams: (text) => {
29
+ const match = text.match(/(?:打开|open)\s*(?:文件|file)?\s*([\w./]+)/i);
30
+ return match ? { fileName: match[1] } : {};
31
+ },
32
+ },
33
+ { type: 'save_file', patterns: [/保存|存盘|save/i] },
34
+ { type: 'run_code', patterns: [/运行|执行|跑一下|run|execute/i] },
35
+ { type: 'debug_code', patterns: [/调试|debug/i] },
36
+ { type: 'stop_code', patterns: [/停止|终止|stop/i] },
37
+ {
38
+ type: 'search',
39
+ patterns: [/搜索|查找|search|find/i],
40
+ extractParams: (text) => {
41
+ const match = text.match(/(?:搜索|查找|search|find)\s*(?:什么|什么是|for)?\s*(.+)/i);
42
+ return match ? { query: match[1].trim() } : {};
43
+ },
44
+ },
45
+ {
46
+ type: 'goto_line',
47
+ patterns: [/跳到第?\d+行|跳转到|goto line|go to line/i],
48
+ extractParams: (text) => {
49
+ const match = text.match(/(\d+)\s*行/);
50
+ return match ? { line: parseInt(match[1], 10) } : {};
51
+ },
52
+ },
53
+ { type: 'comment', patterns: [/注释|comment/i] },
54
+ { type: 'format', patterns: [/格式化|format|美化代码/i] },
55
+ { type: 'undo', patterns: [/撤销|undo/i] },
56
+ { type: 'redo', patterns: [/重做|恢复|redo/i] },
57
+ { type: 'toggle_terminal', patterns: [/终端|terminal|控制台/i] },
58
+ { type: 'toggle_sidebar', patterns: [/侧边栏|侧栏|sidebar/i] },
59
+ { type: 'toggle_fullscreen', patterns: [/全屏|fullscreen/i] },
60
+ {
61
+ type: 'generate_code',
62
+ patterns: [/生成代码|写代码|帮我写|generate code|write code/i],
63
+ extractParams: (text) => {
64
+ const match = text.match(/(?:生成|写|帮我写|generate|write)\s*(?:代码|code)?\s*(?:实现|做|一个|一个)?\s*(.+)/i);
65
+ return match ? { description: match[1].trim() } : {};
66
+ },
67
+ needConfirm: true,
68
+ },
69
+ { type: 'explain_code', patterns: [/解释代码|解释一下|explain code|explain/i] },
70
+ { type: 'refactor_code', patterns: [/重构|优化代码|refactor/i], needConfirm: true },
71
+ { type: 'review_code', patterns: [/审查代码|代码审查|review code|code review/i] },
72
+ { type: 'zoom_in', patterns: [/放大|zoom in/i] },
73
+ { type: 'zoom_out', patterns: [/缩小|zoom out/i] },
74
+ { type: 'reset_zoom', patterns: [/重置缩放|reset zoom/i] },
75
+ ];
76
+ /**
77
+ * 语音编程管理器
78
+ */
79
+ class VoiceProgrammingManager {
80
+ contexts = new Map();
81
+ constructor() {
82
+ logger_1.logger.info('voice programming manager initialized');
83
+ }
84
+ /**
85
+ * 解析语音指令
86
+ */
87
+ parseCommand(text) {
88
+ const trimmed = text.trim();
89
+ let bestMatch = null;
90
+ for (const rule of COMMAND_RULES) {
91
+ for (const pattern of rule.patterns) {
92
+ if (pattern.test(trimmed)) {
93
+ const match = trimmed.match(pattern);
94
+ const matchLength = match ? match[0].length : 0;
95
+ const confidence = Math.min(1, matchLength / trimmed.length + 0.3);
96
+ const params = rule.extractParams ? rule.extractParams(trimmed) : {};
97
+ if (!bestMatch || confidence > bestMatch.confidence) {
98
+ bestMatch = { type: rule.type, confidence, params, needConfirm: rule.needConfirm || false };
99
+ }
100
+ }
101
+ }
102
+ }
103
+ if (!bestMatch) {
104
+ return { type: 'chat', rawText: trimmed, params: { text: trimmed }, confidence: 0.5, needConfirm: false };
105
+ }
106
+ return {
107
+ type: bestMatch.type,
108
+ rawText: trimmed,
109
+ params: bestMatch.params,
110
+ confidence: bestMatch.confidence,
111
+ needConfirm: bestMatch.needConfirm,
112
+ };
113
+ }
114
+ /**
115
+ * 语音转代码
116
+ */
117
+ async voiceToCode(description, language = 'typescript', _context) {
118
+ logger_1.logger.info('voice to code', { description, language });
119
+ const code = this.generateCodeFromTemplate(description, language);
120
+ return {
121
+ code,
122
+ language,
123
+ explanation: `根据语音描述"${description}"生成的${language}代码`,
124
+ confidence: 0.7,
125
+ };
126
+ }
127
+ /**
128
+ * 基于模板生成代码
129
+ */
130
+ generateCodeFromTemplate(description, language) {
131
+ const desc = description.toLowerCase();
132
+ if (desc.includes('函数') || desc.includes('function')) {
133
+ const nameMatch = description.match(/(?:函数|function)\s*(?:叫|名为)?\s*(\w+)/);
134
+ const name = nameMatch ? nameMatch[1] : 'myFunction';
135
+ if (language === 'typescript' || language === 'javascript') {
136
+ return `function ${name}(params: any): any {\n // TODO: 实现逻辑\n return null;\n}`;
137
+ }
138
+ }
139
+ if (desc.includes('类') || desc.includes('class')) {
140
+ const nameMatch = description.match(/(?:类|class)\s*(?:叫|名为)?\s*(\w+)/);
141
+ const name = nameMatch ? nameMatch[1] : 'MyClass';
142
+ if (language === 'typescript') {
143
+ return `class ${name} {\n constructor() {\n // TODO: 初始化\n }\n\n method(): void {\n // TODO: 实现方法\n }\n}`;
144
+ }
145
+ }
146
+ return `// ${description}\n// TODO: 实现以下功能\n`;
147
+ }
148
+ /**
149
+ * 创建语音会话上下文
150
+ */
151
+ createContext(sessionId) {
152
+ const id = sessionId || `voice-${Date.now()}-${Math.random().toString(36).slice(2)}`;
153
+ const context = {
154
+ sessionId: id,
155
+ history: [],
156
+ createdAt: new Date().toISOString(),
157
+ lastActiveAt: new Date().toISOString(),
158
+ };
159
+ this.contexts.set(id, context);
160
+ return context;
161
+ }
162
+ getContext(sessionId) {
163
+ return this.contexts.get(sessionId);
164
+ }
165
+ addHistory(sessionId, role, text) {
166
+ const context = this.contexts.get(sessionId);
167
+ if (!context)
168
+ return;
169
+ context.history.push({ role, text, timestamp: new Date().toISOString() });
170
+ context.lastActiveAt = new Date().toISOString();
171
+ if (context.history.length > 50)
172
+ context.history = context.history.slice(-50);
173
+ }
174
+ setCurrentFile(sessionId, filePath, language) {
175
+ const context = this.contexts.get(sessionId);
176
+ if (!context)
177
+ return;
178
+ context.currentFile = filePath;
179
+ if (language)
180
+ context.currentLanguage = language;
181
+ context.lastActiveAt = new Date().toISOString();
182
+ }
183
+ cleanupExpiredSessions(maxAgeMs = 30 * 60 * 1000) {
184
+ const now = Date.now();
185
+ let cleaned = 0;
186
+ for (const [id, context] of this.contexts) {
187
+ if (now - new Date(context.lastActiveAt).getTime() > maxAgeMs) {
188
+ this.contexts.delete(id);
189
+ cleaned++;
190
+ }
191
+ }
192
+ if (cleaned > 0)
193
+ logger_1.logger.info('voice sessions cleaned', { cleaned });
194
+ return cleaned;
195
+ }
196
+ getSupportedCommands() {
197
+ return [
198
+ { type: 'new_file', description: '新建文件', examples: ['新建文件', '创建一个叫 utils 的文件'] },
199
+ { type: 'open_file', description: '打开文件', examples: ['打开 index.ts', '打开配置文件'] },
200
+ { type: 'save_file', description: '保存文件', examples: ['保存', '存盘'] },
201
+ { type: 'run_code', description: '运行代码', examples: ['运行', '执行一下', '跑一下'] },
202
+ { type: 'debug_code', description: '调试代码', examples: ['调试', 'debug'] },
203
+ { type: 'search', description: '搜索', examples: ['搜索函数', '查找 TODO'] },
204
+ { type: 'goto_line', description: '跳转到指定行', examples: ['跳到第100行', '跳转到50行'] },
205
+ { type: 'comment', description: '注释代码', examples: ['注释', '注释这行'] },
206
+ { type: 'format', description: '格式化代码', examples: ['格式化', '美化代码'] },
207
+ { type: 'undo', description: '撤销', examples: ['撤销', 'undo'] },
208
+ { type: 'redo', description: '重做', examples: ['重做', '恢复', 'redo'] },
209
+ { type: 'generate_code', description: '生成代码', examples: ['生成一个排序函数', '帮我写一个登录接口'] },
210
+ { type: 'explain_code', description: '解释代码', examples: ['解释这段代码', 'explain'] },
211
+ { type: 'refactor_code', description: '重构代码', examples: ['重构', '优化这段代码'] },
212
+ { type: 'review_code', description: '审查代码', examples: ['审查代码', 'code review'] },
213
+ { type: 'toggle_terminal', description: '切换终端', examples: ['打开终端', '关闭终端'] },
214
+ { type: 'toggle_sidebar', description: '切换侧边栏', examples: ['打开侧边栏', '关闭侧栏'] },
215
+ { type: 'toggle_fullscreen', description: '切换全屏', examples: ['全屏', '退出全屏'] },
216
+ ];
217
+ }
218
+ }
219
+ exports.VoiceProgrammingManager = VoiceProgrammingManager;
220
+ function createVoiceProgrammingManager() {
221
+ return new VoiceProgrammingManager();
222
+ }
223
+ //# sourceMappingURL=voice-programming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice-programming.js","sourceRoot":"","sources":["../../src/voice/voice-programming.ts"],"names":[],"mappings":";;;AAqRA,sEAEC;AAvRD;;;;;;;;GAQG;AACH,6CAA0C;AA6C1C,eAAe;AACf,MAAM,aAAa,GAKd;IACH;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,CAAC,yBAAyB,CAAC;QACrC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,4DAA4D,CAAC,CAAC;YACvF,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,CAAC;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,CAAC,yBAAyB,CAAC;QACrC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;YACpE,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7C,CAAC;KACF;IACD,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;IAChD,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,wBAAwB,CAAC,EAAE;IAC1D,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,WAAW,CAAC,EAAE;IAC/C,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;IAChD;QACE,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,CAAC,oBAAoB,CAAC;QAChC,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;YAC5E,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,CAAC;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,QAAQ,EAAE,CAAC,oCAAoC,CAAC;QAChD,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YACtC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,CAAC;KACF;IACD,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;IAC9C,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,kBAAkB,CAAC,EAAE;IAClD,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACxC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;IAC3C,EAAE,IAAI,EAAE,iBAAiB,EAAE,QAAQ,EAAE,CAAC,kBAAkB,CAAC,EAAE;IAC3D,EAAE,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,CAAC,iBAAiB,CAAC,EAAE;IACzD,EAAE,IAAI,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC,gBAAgB,CAAC,EAAE;IAC3D;QACE,IAAI,EAAE,eAAe;QACrB,QAAQ,EAAE,CAAC,wCAAwC,CAAC;QACpD,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE;YACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;YACjG,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,CAAC;QACD,WAAW,EAAE,IAAI;KAClB;IACD,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,iCAAiC,CAAC,EAAE;IACvE,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC,mBAAmB,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE;IAC7E,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,oCAAoC,CAAC,EAAE;IACzE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,aAAa,CAAC,EAAE;IAC9C,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,cAAc,CAAC,EAAE;IAChD,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,kBAAkB,CAAC,EAAE;CACvD,CAAC;AAEF;;GAEG;AACH,MAAa,uBAAuB;IAC1B,QAAQ,GAA8B,IAAI,GAAG,EAAE,CAAC;IAExD;QACE,eAAM,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,IAAY;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,SAAS,GAA6G,IAAI,CAAC;QAE/H,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACpC,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACrC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;oBAChD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;oBACnE,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAErE,IAAI,CAAC,SAAS,IAAI,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;wBACpD,SAAS,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC;oBAC9F,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QAC5G,CAAC;QAED,OAAO;YACL,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,OAAO,EAAE,OAAO;YAChB,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,WAAW,EAAE,SAAS,CAAC,WAAW;SACnC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,WAAmB,EAAE,WAAmB,YAAY,EAAE,QAAiB;QACvF,eAAM,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAClE,OAAO;YACL,IAAI;YACJ,QAAQ;YACR,WAAW,EAAE,UAAU,WAAW,OAAO,QAAQ,IAAI;YACrD,UAAU,EAAE,GAAG;SAChB,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,WAAmB,EAAE,QAAgB;QACpE,MAAM,IAAI,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;QAEvC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACrD,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YAC3E,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;YACrD,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC3D,OAAO,YAAY,IAAI,0DAA0D,CAAC;YACpF,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACvE,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAClD,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;gBAC9B,OAAO,SAAS,IAAI,+FAA+F,CAAC;YACtH,CAAC;QACH,CAAC;QAED,OAAO,MAAM,WAAW,qBAAqB,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,SAAkB;QAC9B,MAAM,EAAE,GAAG,SAAS,IAAI,SAAS,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACrF,MAAM,OAAO,GAAiB;YAC5B,SAAS,EAAE,EAAE;YACb,OAAO,EAAE,EAAE;YACX,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED,UAAU,CAAC,SAAiB,EAAE,IAA0B,EAAE,IAAY;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAC1E,OAAO,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IAED,cAAc,CAAC,SAAiB,EAAE,QAAgB,EAAE,QAAiB;QACnE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,OAAO,CAAC,WAAW,GAAG,QAAQ,CAAC;QAC/B,IAAI,QAAQ;YAAE,OAAO,CAAC,eAAe,GAAG,QAAQ,CAAC;QACjD,OAAO,CAAC,YAAY,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAClD,CAAC;IAED,sBAAsB,CAAC,WAAmB,EAAE,GAAG,EAAE,GAAG,IAAI;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1C,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC9D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACzB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,IAAI,OAAO,GAAG,CAAC;YAAE,eAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACpE,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,oBAAoB;QAClB,OAAO;YACL,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE;YAChF,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE;YAC/E,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE;YAClE,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;YAC1E,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE;YACtE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;YACpE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE;YAC7E,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;YAClE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE;YACnE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;YAC7D,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;YACnE,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE;YACnF,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE;YAC9E,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE;YAC1E,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE;YAC/E,EAAE,IAAI,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;YAC5E,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE;YAC7E,EAAE,IAAI,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;SAC7E,CAAC;IACJ,CAAC;CACF;AAvJD,0DAuJC;AAED,SAAgB,6BAA6B;IAC3C,OAAO,IAAI,uBAAuB,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,440 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerExtraApis = registerExtraApis;
4
+ const path_1 = require("path");
5
+ const fs_1 = require("fs");
6
+ const voice_programming_1 = require("../voice/voice-programming");
7
+ const library_1 = require("../knowledge/library");
8
+ const figma_1 = require("../integrations/figma");
9
+ const sso_1 = require("../integrations/sso");
10
+ const collaboration_1 = require("../integrations/collaboration");
11
+ const manager_1 = require("../plugins/manager");
12
+ const self_correction_1 = require("../agent/self-correction");
13
+ const lsp_service_1 = require("../lsp/lsp-service");
14
+ const lsp_client_1 = require("../lsp/lsp-client");
15
+ function loadFeishuConfig() {
16
+ const appId = process.env.FH_FEISHU_APP_ID;
17
+ const appSecret = process.env.FH_FEISHU_APP_SECRET;
18
+ if (!appId || !appSecret)
19
+ return undefined;
20
+ return { appId, appSecret, webhookUrl: process.env.FH_FEISHU_WEBHOOK };
21
+ }
22
+ function loadGithubConfig() {
23
+ const token = process.env.FH_GITHUB_TOKEN;
24
+ const owner = process.env.FH_GITHUB_OWNER;
25
+ const repo = process.env.FH_GITHUB_REPO;
26
+ if (!token || !owner || !repo)
27
+ return undefined;
28
+ return { token, owner, repo };
29
+ }
30
+ function bodyOf(req) {
31
+ return (req.body ?? {});
32
+ }
33
+ function registerExtraApis(app, opts) {
34
+ const { dataDir } = opts;
35
+ (0, fs_1.mkdirSync)((0, path_1.join)(dataDir, 'knowledge'), { recursive: true });
36
+ (0, fs_1.mkdirSync)((0, path_1.join)(dataDir, 'plugins'), { recursive: true });
37
+ const voice = (0, voice_programming_1.createVoiceProgrammingManager)();
38
+ const knowledge = (0, library_1.createKnowledgeLibraryManager)((0, path_1.join)(dataDir, 'knowledge'));
39
+ const plugins = (0, manager_1.createPluginManager)((0, path_1.join)(dataDir, 'plugins'));
40
+ const sso = (0, sso_1.createSSOManager)();
41
+ const figma = (0, figma_1.createFigmaIntegration)({ accessToken: process.env.FH_FIGMA_TOKEN ?? '' });
42
+ const collaboration = (0, collaboration_1.createCollaborationManager)({
43
+ feishu: loadFeishuConfig(),
44
+ github: loadGithubConfig(),
45
+ });
46
+ const corrector = (0, self_correction_1.createSelfCorrector)();
47
+ const lsp = (0, lsp_service_1.createLspService)({ enableDiagnostics: true });
48
+ /* ============ 语音编程(原 404) ============ */
49
+ app.get('/api/voice/commands', (_req, res) => {
50
+ res.json({ ok: true, commands: voice.getSupportedCommands() });
51
+ });
52
+ app.post('/api/voice/parse', (req, res) => {
53
+ const body = bodyOf(req);
54
+ const text = String(body.text ?? '');
55
+ if (!text) {
56
+ res.json({ ok: false, error: '缺少 text' });
57
+ return;
58
+ }
59
+ res.json({ ok: true, command: voice.parseCommand(text) });
60
+ });
61
+ app.post('/api/voice/to-code', async (req, res) => {
62
+ const body = bodyOf(req);
63
+ if (!body.description) {
64
+ res.json({ ok: false, error: '缺少 description' });
65
+ return;
66
+ }
67
+ const result = await voice.voiceToCode(String(body.description), String(body.language ?? 'typescript'));
68
+ res.json({ ok: true, result });
69
+ });
70
+ /* ============ AI 资料库(原 404) ============ */
71
+ app.get('/api/knowledge/stats', (_req, res) => {
72
+ res.json({ ok: true, stats: knowledge.getStats() });
73
+ });
74
+ app.get('/api/knowledge/documents', (req, res) => {
75
+ const { category, type, sortBy, order, limit, offset } = req.query;
76
+ res.json({
77
+ ok: true,
78
+ documents: knowledge.listDocuments({
79
+ category: category ? String(category) : undefined,
80
+ type: type ? String(type) : undefined,
81
+ sortBy: sortBy ? String(sortBy) : undefined,
82
+ order: order ? String(order) : undefined,
83
+ limit: limit ? Number(limit) : undefined,
84
+ offset: offset ? Number(offset) : undefined,
85
+ }),
86
+ });
87
+ });
88
+ app.get('/api/knowledge/categories', (_req, res) => {
89
+ res.json({ ok: true, categories: knowledge.getCategories() });
90
+ });
91
+ app.get('/api/knowledge/tags', (_req, res) => {
92
+ res.json({ ok: true, tags: knowledge.getAllTags() });
93
+ });
94
+ app.get('/api/knowledge/document/:id', (req, res) => {
95
+ const doc = knowledge.getDocument(String(req.params.id));
96
+ if (!doc) {
97
+ res.json({ ok: false, error: '文档不存在' });
98
+ return;
99
+ }
100
+ res.json({ ok: true, document: doc });
101
+ });
102
+ app.get('/api/knowledge/document/:id/content', (req, res) => {
103
+ const content = knowledge.getDocumentContent(String(req.params.id));
104
+ if (content === null) {
105
+ res.json({ ok: false, error: '文档不存在' });
106
+ return;
107
+ }
108
+ res.json({ ok: true, content });
109
+ });
110
+ app.post('/api/knowledge/document', (req, res) => {
111
+ const body = bodyOf(req);
112
+ if (!body.title || !body.content) {
113
+ res.json({ ok: false, error: '缺少 title 或 content' });
114
+ return;
115
+ }
116
+ try {
117
+ const doc = knowledge.addDocument({
118
+ title: String(body.title),
119
+ content: String(body.content),
120
+ type: body.type ?? 'text',
121
+ category: body.category ? String(body.category) : undefined,
122
+ tags: Array.isArray(body.tags) ? body.tags.map(String) : undefined,
123
+ });
124
+ res.json({ ok: true, document: doc });
125
+ }
126
+ catch (e) {
127
+ res.json({ ok: false, error: String(e?.message ?? e) });
128
+ }
129
+ });
130
+ app.put('/api/knowledge/document/:id', (req, res) => {
131
+ const doc = knowledge.updateDocument(String(req.params.id), bodyOf(req));
132
+ if (!doc) {
133
+ res.json({ ok: false, error: '文档不存在' });
134
+ return;
135
+ }
136
+ res.json({ ok: true, document: doc });
137
+ });
138
+ app.delete('/api/knowledge/document/:id', (req, res) => {
139
+ const ok = knowledge.deleteDocument(String(req.params.id));
140
+ res.json({ ok, deleted: ok });
141
+ });
142
+ app.post('/api/knowledge/search', (req, res) => {
143
+ const body = bodyOf(req);
144
+ if (!body.query) {
145
+ res.json({ ok: false, error: '缺少 query' });
146
+ return;
147
+ }
148
+ res.json({
149
+ ok: true,
150
+ results: knowledge.search(String(body.query), {
151
+ category: body.category ? String(body.category) : undefined,
152
+ type: body.type ? String(body.type) : undefined,
153
+ tags: Array.isArray(body.tags) ? body.tags.map(String) : undefined,
154
+ limit: body.limit ? Number(body.limit) : undefined,
155
+ }),
156
+ });
157
+ });
158
+ /* ============ SSO 单点登录(原 404) ============ */
159
+ app.get('/api/sso/providers', (_req, res) => {
160
+ res.json({ ok: true, providers: sso.getEnabledProviders() });
161
+ });
162
+ app.post('/api/sso/login-url', (req, res) => {
163
+ const body = bodyOf(req);
164
+ if (!body.providerId) {
165
+ res.json({ ok: false, error: '缺少 providerId' });
166
+ return;
167
+ }
168
+ const url = sso.getLoginUrl(String(body.providerId), body.redirectUri ? String(body.redirectUri) : undefined);
169
+ if (!url) {
170
+ res.json({ ok: false, error: '提供方未配置或不存在' });
171
+ return;
172
+ }
173
+ res.json({ ok: true, url });
174
+ });
175
+ app.post('/api/sso/validate', (req, res) => {
176
+ const body = bodyOf(req);
177
+ if (!body.token) {
178
+ res.json({ ok: false, error: '缺少 token' });
179
+ return;
180
+ }
181
+ const session = sso.validateSession(String(body.token));
182
+ res.json({ ok: !!session, session });
183
+ });
184
+ /* ============ 协作集成(原 404) ============ */
185
+ app.get('/api/collaboration/status', (_req, res) => {
186
+ res.json({
187
+ ok: true,
188
+ feishu: !!collaboration.getFeishu(),
189
+ github: !!collaboration.getGitHub(),
190
+ });
191
+ });
192
+ app.post('/api/collaboration/notify', async (req, res) => {
193
+ const body = bodyOf(req);
194
+ if (!body.message) {
195
+ res.json({ ok: false, error: '缺少 message' });
196
+ return;
197
+ }
198
+ const feishu = collaboration.getFeishu();
199
+ if (!feishu) {
200
+ res.json({ ok: false, error: '飞书未配置(需 FH_FEISHU_APP_ID/SECRET)' });
201
+ return;
202
+ }
203
+ const ok = await feishu.sendMessage(body.message);
204
+ res.json({ ok, sent: ok });
205
+ });
206
+ /* ============ Figma 转代码(原 404) ============ */
207
+ app.get('/api/figma/status', (_req, res) => {
208
+ res.json({ ok: true, configured: !!process.env.FH_FIGMA_TOKEN });
209
+ });
210
+ app.post('/api/figma/convert', async (req, res) => {
211
+ if (!process.env.FH_FIGMA_TOKEN) {
212
+ res.json({ ok: false, error: 'Figma 未配置(需 FH_FIGMA_TOKEN)' });
213
+ return;
214
+ }
215
+ const body = bodyOf(req);
216
+ if (!body.fileKey) {
217
+ res.json({ ok: false, error: '缺少 fileKey' });
218
+ return;
219
+ }
220
+ try {
221
+ const result = await figma.generateCode(String(body.fileKey), body.nodeId ? String(body.nodeId) : undefined, body.framework ?? 'tailwind');
222
+ res.json({ ok: true, result });
223
+ }
224
+ catch (e) {
225
+ res.json({ ok: false, error: String(e?.message ?? e) });
226
+ }
227
+ });
228
+ /* ============ 插件市场(原 404) ============ */
229
+ app.get('/api/plugins', (req, res) => {
230
+ const status = req.query.status ? String(req.query.status) : undefined;
231
+ res.json({ ok: true, plugins: plugins.getInstalledPlugins(status) });
232
+ });
233
+ app.get('/api/plugins/market', (req, res) => {
234
+ const { q, category } = req.query;
235
+ res.json({
236
+ ok: true,
237
+ plugins: plugins.searchMarketPlugins(q ? String(q) : '', category ? String(category) : undefined),
238
+ });
239
+ });
240
+ app.get('/api/plugins/categories', (_req, res) => {
241
+ res.json({ ok: true, categories: plugins.getCategories() });
242
+ });
243
+ app.get('/api/plugins/stats', (_req, res) => {
244
+ res.json({ ok: true, stats: plugins.getStats() });
245
+ });
246
+ app.post('/api/plugins/install', async (req, res) => {
247
+ const body = bodyOf(req);
248
+ if (!body.plugin) {
249
+ res.json({ ok: false, error: '缺少 plugin' });
250
+ return;
251
+ }
252
+ try {
253
+ const installed = await plugins.installPlugin(body.plugin);
254
+ res.json({ ok: true, plugin: installed });
255
+ }
256
+ catch (e) {
257
+ res.json({ ok: false, error: String(e?.message ?? e) });
258
+ }
259
+ });
260
+ app.post('/api/plugins/:id/uninstall', (req, res) => {
261
+ res.json({ ok: plugins.uninstallPlugin(String(req.params.id)) });
262
+ });
263
+ app.post('/api/plugins/:id/enable', (req, res) => {
264
+ res.json({ ok: plugins.enablePlugin(String(req.params.id)) });
265
+ });
266
+ app.post('/api/plugins/:id/disable', (req, res) => {
267
+ res.json({ ok: plugins.disablePlugin(String(req.params.id)) });
268
+ });
269
+ /* ============ 自我修正闭环(原 404) ============ */
270
+ app.post('/api/agent/correct', async (req, res) => {
271
+ const body = bodyOf(req);
272
+ if (!body.filePath) {
273
+ res.json({ ok: false, error: '缺少 filePath' });
274
+ return;
275
+ }
276
+ try {
277
+ const result = await corrector.correctFile(String(body.filePath), async () => {
278
+ throw new Error('需要配置模型修复函数(modelFix)');
279
+ });
280
+ res.json({ ok: true, result });
281
+ }
282
+ catch (e) {
283
+ res.json({ ok: false, error: String(e?.message ?? e) });
284
+ }
285
+ });
286
+ /* ============ LSP 语义服务(P0-2 修复:标准 LSP 风格接口) ============ */
287
+ const lspCwd = (req) => {
288
+ const q = req.query.cwd;
289
+ return q ? String(q) : process.cwd();
290
+ };
291
+ /** P1-1: 编译器级 LSP 客户端单例(按 cwd 缓存) */
292
+ const compilerClients = new Map();
293
+ const getCompilerClient = async (cwd) => {
294
+ let c = compilerClients.get(cwd);
295
+ if (c && c.isRunning)
296
+ return c;
297
+ if (c) {
298
+ c.close();
299
+ compilerClients.delete(cwd);
300
+ }
301
+ c = new lsp_client_1.LspClient();
302
+ const ok = await c.start(cwd, { timeoutMs: 12000 });
303
+ if (!ok) {
304
+ compilerClients.delete(cwd);
305
+ return null;
306
+ }
307
+ compilerClients.set(cwd, c);
308
+ return c;
309
+ };
310
+ const compilerUri = (cwd, file) => 'file:///' + (0, path_1.join)(cwd, file).replace(/\\/g, '/').replace(/^\/+/, '');
311
+ // 编译器级 hover(真实 LSP 服务器;失败回退语义层并标注)
312
+ app.post('/api/lsp/compiler/hover', async (req, res) => {
313
+ const { file, text, line, character } = (req.body ?? {});
314
+ if (!file || typeof text !== 'string' || line === undefined || character === undefined) {
315
+ res.json({ ok: false, error: '缺少 file/text/line/character' });
316
+ return;
317
+ }
318
+ const cwd = lspCwd(req);
319
+ const uri = compilerUri(cwd, file);
320
+ try {
321
+ const client = await getCompilerClient(cwd);
322
+ if (!client) {
323
+ // fallback:自建语义层(编译器不可用时降级)
324
+ const hover = lsp.getHover(cwd, file, Number(line));
325
+ res.json({ ok: true, hover, compiler: false, fallback: '自建语义层(typescript-language-server 不可用)' });
326
+ return;
327
+ }
328
+ client.didOpen(uri, text);
329
+ const hover = await client.hover(uri, Number(line), Number(character));
330
+ res.json({ ok: true, hover, compiler: true });
331
+ }
332
+ catch (e) {
333
+ res.json({ ok: false, error: String(e?.message ?? e), compiler: false });
334
+ }
335
+ });
336
+ // 编译器级 definition(真实 LSP 服务器)
337
+ app.post('/api/lsp/compiler/definition', async (req, res) => {
338
+ const { file, text, line, character } = (req.body ?? {});
339
+ if (!file || typeof text !== 'string' || line === undefined || character === undefined) {
340
+ res.json({ ok: false, error: '缺少 file/text/line/character' });
341
+ return;
342
+ }
343
+ const cwd = lspCwd(req);
344
+ const uri = compilerUri(cwd, file);
345
+ try {
346
+ const client = await getCompilerClient(cwd);
347
+ if (!client) {
348
+ const def = lsp.getDefinition(cwd, file, Number(line));
349
+ res.json({ ok: true, definition: def, compiler: false, fallback: '自建语义层' });
350
+ return;
351
+ }
352
+ client.didOpen(uri, text);
353
+ const definition = await client.definition(uri, Number(line), Number(character));
354
+ res.json({ ok: true, definition, compiler: true });
355
+ }
356
+ catch (e) {
357
+ res.json({ ok: false, error: String(e?.message ?? e), compiler: false });
358
+ }
359
+ });
360
+ app.get('/api/lsp/graph', (req, res) => {
361
+ const cwd = lspCwd(req);
362
+ try {
363
+ res.json({ ok: true, summary: lsp.getGraphSummary(cwd) });
364
+ }
365
+ catch (e) {
366
+ res.json({ ok: false, error: String(e?.message ?? e) });
367
+ }
368
+ });
369
+ app.get('/api/lsp/symbols', (req, res) => {
370
+ const file = req.query.file;
371
+ if (!file) {
372
+ res.json({ ok: false, error: '缺少 file' });
373
+ return;
374
+ }
375
+ try {
376
+ res.json({ ok: true, symbols: lsp.getSymbols(lspCwd(req), String(file)) });
377
+ }
378
+ catch (e) {
379
+ res.json({ ok: false, error: String(e?.message ?? e) });
380
+ }
381
+ });
382
+ app.get('/api/lsp/search', (req, res) => {
383
+ const q = req.query.q;
384
+ if (!q) {
385
+ res.json({ ok: false, error: '缺少 q' });
386
+ return;
387
+ }
388
+ const limit = req.query.limit ? Number(req.query.limit) : 20;
389
+ try {
390
+ res.json({ ok: true, symbols: lsp.search(lspCwd(req), String(q), limit) });
391
+ }
392
+ catch (e) {
393
+ res.json({ ok: false, error: String(e?.message ?? e) });
394
+ }
395
+ });
396
+ app.get('/api/lsp/diagnostics', (req, res) => {
397
+ const file = req.query.file;
398
+ if (!file) {
399
+ res.json({ ok: false, error: '缺少 file' });
400
+ return;
401
+ }
402
+ try {
403
+ res.json({ ok: true, diagnostics: lsp.getDiagnostics(lspCwd(req), String(file)) });
404
+ }
405
+ catch (e) {
406
+ res.json({ ok: false, error: String(e?.message ?? e) });
407
+ }
408
+ });
409
+ app.get('/api/lsp/definition', (req, res) => {
410
+ const file = req.query.file;
411
+ const line = req.query.line ? Number(req.query.line) : NaN;
412
+ if (!file || Number.isNaN(line)) {
413
+ res.json({ ok: false, error: '缺少 file 或 line' });
414
+ return;
415
+ }
416
+ try {
417
+ const def = lsp.getDefinition(lspCwd(req), String(file), line);
418
+ res.json({ ok: true, definition: def });
419
+ }
420
+ catch (e) {
421
+ res.json({ ok: false, error: String(e?.message ?? e) });
422
+ }
423
+ });
424
+ app.get('/api/lsp/hover', (req, res) => {
425
+ const file = req.query.file;
426
+ const line = req.query.line ? Number(req.query.line) : NaN;
427
+ if (!file || Number.isNaN(line)) {
428
+ res.json({ ok: false, error: '缺少 file 或 line' });
429
+ return;
430
+ }
431
+ try {
432
+ const hover = lsp.getHover(lspCwd(req), String(file), line);
433
+ res.json({ ok: true, hover });
434
+ }
435
+ catch (e) {
436
+ res.json({ ok: false, error: String(e?.message ?? e) });
437
+ }
438
+ });
439
+ }
440
+ //# sourceMappingURL=extra-apis.js.map