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.
- package/.github/workflows/release.yml +173 -0
- package/CHANGELOG.md +83 -454
- package/dist/agent/browser-agent.js +354 -0
- package/dist/agent/browser-agent.js.map +1 -0
- package/dist/agent/change-manager.js +433 -0
- package/dist/agent/change-manager.js.map +1 -0
- package/dist/agent/code-rag.js +293 -0
- package/dist/agent/code-rag.js.map +1 -0
- package/dist/agent/code-writer.js +13 -1
- package/dist/agent/code-writer.js.map +1 -1
- package/dist/agent/completion-engine.js +522 -0
- package/dist/agent/completion-engine.js.map +1 -0
- package/dist/agent/context-compactor.js +188 -10
- package/dist/agent/context-compactor.js.map +1 -1
- package/dist/agent/custom-agent.js +368 -0
- package/dist/agent/custom-agent.js.map +1 -0
- package/dist/agent/design-to-code.js +218 -0
- package/dist/agent/design-to-code.js.map +1 -0
- package/dist/agent/event-driven-agent.js +359 -0
- package/dist/agent/event-driven-agent.js.map +1 -0
- package/dist/agent/git-integration.js +324 -0
- package/dist/agent/git-integration.js.map +1 -0
- package/dist/agent/layered-memory.js +329 -0
- package/dist/agent/layered-memory.js.map +1 -0
- package/dist/agent/multi-agent.js +359 -0
- package/dist/agent/multi-agent.js.map +1 -0
- package/dist/agent/orchestrator.js +160 -22
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts.js +20 -0
- package/dist/agent/prompts.js.map +1 -1
- package/dist/agent/quality-gate.js +139 -0
- package/dist/agent/quality-gate.js.map +1 -1
- package/dist/agent/self-correction.js +274 -0
- package/dist/agent/self-correction.js.map +1 -0
- package/dist/agent/self-heal.js +42 -12
- package/dist/agent/self-heal.js.map +1 -1
- package/dist/agent/solo-agent.js +321 -0
- package/dist/agent/solo-agent.js.map +1 -0
- package/dist/agent/symbol-index.js +258 -28
- package/dist/agent/symbol-index.js.map +1 -1
- package/dist/agent/team-collaboration.js +252 -0
- package/dist/agent/team-collaboration.js.map +1 -0
- package/dist/agent/type-checker.js +229 -0
- package/dist/agent/type-checker.js.map +1 -0
- package/dist/cli/run.js +1 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/integrations/collaboration.js +219 -0
- package/dist/integrations/collaboration.js.map +1 -0
- package/dist/integrations/figma.js +307 -0
- package/dist/integrations/figma.js.map +1 -0
- package/dist/integrations/sso.js +327 -0
- package/dist/integrations/sso.js.map +1 -0
- package/dist/knowledge/library.js +301 -0
- package/dist/knowledge/library.js.map +1 -0
- package/dist/plugins/manager.js +332 -0
- package/dist/plugins/manager.js.map +1 -0
- package/dist/runtime/event-log.js.map +1 -1
- package/dist/tools/browser/browser.tool.js +217 -0
- package/dist/tools/browser/browser.tool.js.map +1 -0
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/shell/exec.js +50 -10
- package/dist/tools/shell/exec.js.map +1 -1
- package/dist/tools/shell/run-shell.tool.js +8 -2
- package/dist/tools/shell/run-shell.tool.js.map +1 -1
- package/dist/training/completion-evaluator.js +213 -0
- package/dist/training/completion-evaluator.js.map +1 -0
- package/dist/training/fim-data.js +248 -0
- package/dist/training/fim-data.js.map +1 -0
- package/dist/voice/voice-programming.js +223 -0
- package/dist/voice/voice-programming.js.map +1 -0
- package/dist/web/public/css/style.css +190 -7
- package/dist/web/public/index.html +403 -9
- package/dist/web/public/js/api.js +191 -4
- package/dist/web/public/js/app.js +850 -123
- package/dist/web/public/js/mock-api.js +234 -0
- package/dist/web/public/js/monaco-editor.js +203 -0
- package/dist/web/public/js/ui.js +1271 -54
- package/dist/web/public/manifest.json +59 -0
- package/dist/web/public/service-worker.js +173 -0
- package/dist/web/public/vendor/monaco/vs/abap-D-t0cyap.js +1 -0
- package/dist/web/public/vendor/monaco/vs/apex-CcIm7xu6.js +1 -0
- package/dist/web/public/vendor/monaco/vs/assets/css.worker-URu8fCFR.js +97 -0
- package/dist/web/public/vendor/monaco/vs/assets/editor.worker-lj3bdIIn.js +30 -0
- package/dist/web/public/vendor/monaco/vs/assets/editorWebWorkerMain-CA_vMoUU.js +30 -0
- package/dist/web/public/vendor/monaco/vs/assets/html.worker-D1SL3iM8.js +474 -0
- package/dist/web/public/vendor/monaco/vs/assets/json.worker-CoJx_OPf.js +62 -0
- package/dist/web/public/vendor/monaco/vs/assets/ts.worker-BWKtMYOk.js +67722 -0
- package/dist/web/public/vendor/monaco/vs/azcli-BA0tQDCg.js +1 -0
- package/dist/web/public/vendor/monaco/vs/basic-languages/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/bat-C397hTD6.js +1 -0
- package/dist/web/public/vendor/monaco/vs/bicep-DF5aW17k.js +2 -0
- package/dist/web/public/vendor/monaco/vs/cameligo-plsz8qhj.js +1 -0
- package/dist/web/public/vendor/monaco/vs/clojure-Y2auQMzK.js +1 -0
- package/dist/web/public/vendor/monaco/vs/coffee-Bu45yuWE.js +1 -0
- package/dist/web/public/vendor/monaco/vs/cpp-CkKPQIni.js +1 -0
- package/dist/web/public/vendor/monaco/vs/csharp-CX28MZyh.js +1 -0
- package/dist/web/public/vendor/monaco/vs/csp-D8uWnyxW.js +1 -0
- package/dist/web/public/vendor/monaco/vs/css-CaeNmE3S.js +3 -0
- package/dist/web/public/vendor/monaco/vs/css.worker-CyhWkhHo.js +1 -0
- package/dist/web/public/vendor/monaco/vs/cssMode-CV6Ay48H.js +1 -0
- package/dist/web/public/vendor/monaco/vs/cypher-DVThT8BS.js +1 -0
- package/dist/web/public/vendor/monaco/vs/dart-CmGfCvrO.js +1 -0
- package/dist/web/public/vendor/monaco/vs/dockerfile-CZqqYdch.js +1 -0
- package/dist/web/public/vendor/monaco/vs/ecl-30fUercY.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editor/editor.main.css +1 -0
- package/dist/web/public/vendor/monaco/vs/editor/editor.main.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editor/editor.worker.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editor-KLE6jdfb.js +831 -0
- package/dist/web/public/vendor/monaco/vs/editor.js +1 -0
- package/dist/web/public/vendor/monaco/vs/editorWorkerHost-fVE1cjcC.js +35 -0
- package/dist/web/public/vendor/monaco/vs/elixir-xjPaIfzF.js +1 -0
- package/dist/web/public/vendor/monaco/vs/flow9-DqtmStfK.js +1 -0
- package/dist/web/public/vendor/monaco/vs/freemarker2-FWreY7v7.js +3 -0
- package/dist/web/public/vendor/monaco/vs/fsharp-BOMdg4U1.js +1 -0
- package/dist/web/public/vendor/monaco/vs/go-D_hbi-Jt.js +1 -0
- package/dist/web/public/vendor/monaco/vs/graphql-CKUU4kLG.js +1 -0
- package/dist/web/public/vendor/monaco/vs/handlebars-CZi4pHCH.js +1 -0
- package/dist/web/public/vendor/monaco/vs/hcl-DTaboeZW.js +1 -0
- package/dist/web/public/vendor/monaco/vs/html-j_7ZTNRU.js +1 -0
- package/dist/web/public/vendor/monaco/vs/html.worker-CA3iAimZ.js +1 -0
- package/dist/web/public/vendor/monaco/vs/htmlMode-27by_KM4.js +1 -0
- package/dist/web/public/vendor/monaco/vs/index-049xrXrp.js +1 -0
- package/dist/web/public/vendor/monaco/vs/index-CBVt3dzv.js +5 -0
- package/dist/web/public/vendor/monaco/vs/index.js +1 -0
- package/dist/web/public/vendor/monaco/vs/ini-CsNwO04R.js +1 -0
- package/dist/web/public/vendor/monaco/vs/initialize-DL0l1TGY.js +1 -0
- package/dist/web/public/vendor/monaco/vs/java-CI4ZMsH9.js +1 -0
- package/dist/web/public/vendor/monaco/vs/javascript-DTJl4Jn1.js +1 -0
- package/dist/web/public/vendor/monaco/vs/json.worker-BizpAl9O.js +1 -0
- package/dist/web/public/vendor/monaco/vs/jsonMode-DLUiMUrI.js +1 -0
- package/dist/web/public/vendor/monaco/vs/julia-BwzEvaQw.js +1 -0
- package/dist/web/public/vendor/monaco/vs/kotlin-IUYPiTV8.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/css/css.worker.js +66 -0
- package/dist/web/public/vendor/monaco/vs/language/css/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/html/html.worker.js +443 -0
- package/dist/web/public/vendor/monaco/vs/language/html/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/json/json.worker.js +17 -0
- package/dist/web/public/vendor/monaco/vs/language/json/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/typescript/monaco.contribution.js +1 -0
- package/dist/web/public/vendor/monaco/vs/language/typescript/ts.worker.js +67693 -0
- package/dist/web/public/vendor/monaco/vs/less-C0eDYdqa.js +2 -0
- package/dist/web/public/vendor/monaco/vs/lexon-iON-Kj97.js +1 -0
- package/dist/web/public/vendor/monaco/vs/liquid-CLJYelW6.js +1 -0
- package/dist/web/public/vendor/monaco/vs/loader.js +1368 -0
- package/dist/web/public/vendor/monaco/vs/lspLanguageFeatures-BIkJOWLw.js +2 -0
- package/dist/web/public/vendor/monaco/vs/lua-DtygF91M.js +1 -0
- package/dist/web/public/vendor/monaco/vs/m3-CsR4AuFi.js +1 -0
- package/dist/web/public/vendor/monaco/vs/main-BEx-Fmlo.js +15 -0
- package/dist/web/public/vendor/monaco/vs/main-DsK8pnKg.js +3 -0
- package/dist/web/public/vendor/monaco/vs/markdown-C_rD0bIw.js +1 -0
- package/dist/web/public/vendor/monaco/vs/mdx-CpzZIPHF.js +1 -0
- package/dist/web/public/vendor/monaco/vs/mips-CiYP61RB.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-9cKT3C7t.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-BE88ZNGY.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-BPhsneLd.js +1 -0
- package/dist/web/public/vendor/monaco/vs/monaco.contribution-BgRy6xDf.js +1 -0
- package/dist/web/public/vendor/monaco/vs/msdax-C38-sJlp.js +1 -0
- package/dist/web/public/vendor/monaco/vs/mysql-CdtbpvbG.js +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/cs.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/cs.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/de.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/de.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/es.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/es.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/fr.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/fr.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/it.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/it.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ja.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ja.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ko.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ko.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pl.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pl.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pt-br.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/pt-br.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ru.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/ru.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/tr.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/tr.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-cn.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-cn.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-tw.d.ts +1 -0
- package/dist/web/public/vendor/monaco/vs/nls/lang/zh-tw.js +9 -0
- package/dist/web/public/vendor/monaco/vs/nls.messages-loader.js +1 -0
- package/dist/web/public/vendor/monaco/vs/objective-c-CntZFaHX.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pascal-r6kuqfl_.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pascaligo-BiXoTmXh.js +1 -0
- package/dist/web/public/vendor/monaco/vs/perl-DABw_TcH.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pgsql-me_jFXeX.js +1 -0
- package/dist/web/public/vendor/monaco/vs/php-D_kh-9LK.js +1 -0
- package/dist/web/public/vendor/monaco/vs/pla-VfZjczW0.js +1 -0
- package/dist/web/public/vendor/monaco/vs/postiats-BBSzz8Pk.js +1 -0
- package/dist/web/public/vendor/monaco/vs/powerquery-Dt-g_2cc.js +1 -0
- package/dist/web/public/vendor/monaco/vs/powershell-B-7ap1zc.js +1 -0
- package/dist/web/public/vendor/monaco/vs/protobuf-BmtuEB1A.js +2 -0
- package/dist/web/public/vendor/monaco/vs/pug-BRpRNeEb.js +1 -0
- package/dist/web/public/vendor/monaco/vs/python-CqWUUgfu.js +1 -0
- package/dist/web/public/vendor/monaco/vs/qsharp-BzsFaUU9.js +1 -0
- package/dist/web/public/vendor/monaco/vs/r-f8dDdrp4.js +1 -0
- package/dist/web/public/vendor/monaco/vs/razor-hok5y9Km.js +1 -0
- package/dist/web/public/vendor/monaco/vs/redis-fvZQY4PI.js +1 -0
- package/dist/web/public/vendor/monaco/vs/redshift-45Et0LQi.js +1 -0
- package/dist/web/public/vendor/monaco/vs/restructuredtext-C7UUFKFD.js +1 -0
- package/dist/web/public/vendor/monaco/vs/ruby-CZO8zYTz.js +1 -0
- package/dist/web/public/vendor/monaco/vs/rust-Bfetafyc.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sb-3GYllVck.js +1 -0
- package/dist/web/public/vendor/monaco/vs/scala-foMgrKo1.js +1 -0
- package/dist/web/public/vendor/monaco/vs/scheme-CHdMtr7p.js +1 -0
- package/dist/web/public/vendor/monaco/vs/scss-C1cmLt9V.js +3 -0
- package/dist/web/public/vendor/monaco/vs/shell-ClXCKCEW.js +1 -0
- package/dist/web/public/vendor/monaco/vs/solidity-MZ6ExpPy.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sophia-DWkuSsPQ.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sparql-AUGFYSyk.js +1 -0
- package/dist/web/public/vendor/monaco/vs/sql-32GpJSV2.js +1 -0
- package/dist/web/public/vendor/monaco/vs/st-CuDFIVZ_.js +1 -0
- package/dist/web/public/vendor/monaco/vs/swift-t-PfMj7W.js +1 -0
- package/dist/web/public/vendor/monaco/vs/systemverilog-Ch4vA8Yt.js +1 -0
- package/dist/web/public/vendor/monaco/vs/tcl-D74tq1nH.js +1 -0
- package/dist/web/public/vendor/monaco/vs/toggleHighContrast-qGX7E9o7.js +61 -0
- package/dist/web/public/vendor/monaco/vs/ts.worker-2QLmBukE.js +1 -0
- package/dist/web/public/vendor/monaco/vs/tsMode-B0S_kp2q.js +11 -0
- package/dist/web/public/vendor/monaco/vs/twig-C6taOxMV.js +1 -0
- package/dist/web/public/vendor/monaco/vs/typescript-_2t_511t.js +1 -0
- package/dist/web/public/vendor/monaco/vs/typespec-8OfoLt6R.js +1 -0
- package/dist/web/public/vendor/monaco/vs/vb-Dyb2648j.js +1 -0
- package/dist/web/public/vendor/monaco/vs/wgsl-BhLXMOR0.js +298 -0
- package/dist/web/public/vendor/monaco/vs/workers-BBttULjf.js +1 -0
- package/dist/web/public/vendor/monaco/vs/xml-cZjNDqDT.js +1 -0
- package/dist/web/public/vendor/monaco/vs/yaml-A1fOIdH6.js +1 -0
- package/dist/web/server.js +2073 -210
- package/dist/web/server.js.map +1 -1
- package/dist/web/task-queue.js +25 -5
- package/dist/web/task-queue.js.map +1 -1
- package/docs/BENCHMARK_REPORT_en.md +329 -0
- package/docs/BENCHMARK_REPORT_zh.md +329 -0
- package/docs/DEPLOYMENT.md +382 -0
- package/docs/MODEL_FINETUNING.md +405 -0
- package/docs/TECHNICAL_SPEC_en.md +292 -0
- package/docs/TECHNICAL_SPEC_zh.md +292 -0
- package/docs/UPDATE_NOTES_en.md +159 -0
- package/docs/UPDATE_NOTES_zh.md +159 -0
- package/electron/main.js +602 -0
- package/package.json +67 -3
- package/tool-schema.json +1 -1
|
@@ -107,8 +107,80 @@
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
async function loadTemplates() {
|
|
110
|
-
try {
|
|
111
|
-
|
|
110
|
+
try {
|
|
111
|
+
const d = await api('/api/templates');
|
|
112
|
+
renderBuiltin(d.builtin || []);
|
|
113
|
+
renderNodeTpl(d.node || []);
|
|
114
|
+
renderCustomTpl(d.custom || []);
|
|
115
|
+
renderUserTpl(d.user || []);
|
|
116
|
+
} catch (e) { console.warn('加载模板失败', e); }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* ========== 节点管理 ========== */
|
|
120
|
+
async function loadNodes() {
|
|
121
|
+
try {
|
|
122
|
+
const d = await api('/api/nodes');
|
|
123
|
+
renderNodesGrid(d.nodes || []);
|
|
124
|
+
} catch (e) { console.warn('加载节点失败', e); }
|
|
125
|
+
}
|
|
126
|
+
async function saveNode(data) {
|
|
127
|
+
try {
|
|
128
|
+
const d = data.id
|
|
129
|
+
? await api('/api/nodes/' + data.id, 'PUT', data)
|
|
130
|
+
: await api('/api/nodes', 'POST', data);
|
|
131
|
+
await loadNodes();
|
|
132
|
+
toast(data.id ? '节点已更新' : '节点已添加,连接状态:' + (d.connection?.ok ? '成功' : '失败'));
|
|
133
|
+
return d;
|
|
134
|
+
} catch (e) { toast('保存失败:' + e.message); }
|
|
135
|
+
}
|
|
136
|
+
async function deleteNode(id) {
|
|
137
|
+
try { await api('/api/nodes/' + id, 'DELETE'); await loadNodes(); toast('已删除节点'); }
|
|
138
|
+
catch (e) { toast('删除失败:' + e.message); }
|
|
139
|
+
}
|
|
140
|
+
async function testNode(id) {
|
|
141
|
+
try {
|
|
142
|
+
const d = await api('/api/nodes/' + id + '/test', 'POST');
|
|
143
|
+
toast(d.ok ? '连接成功' : '连接失败:' + (d.error || ''));
|
|
144
|
+
await loadNodes();
|
|
145
|
+
return d;
|
|
146
|
+
} catch (e) { toast('测试失败:' + e.message); }
|
|
147
|
+
}
|
|
148
|
+
async function syncNode(id) {
|
|
149
|
+
try {
|
|
150
|
+
const d = await api('/api/nodes/' + id + '/sync', 'POST');
|
|
151
|
+
toast(d.ok ? '同步完成:' + (d.synced || []).join('、') : '同步失败:' + (d.error || ''));
|
|
152
|
+
await loadNodes();
|
|
153
|
+
await loadTemplates();
|
|
154
|
+
await loadMarket();
|
|
155
|
+
await loadOffice();
|
|
156
|
+
return d;
|
|
157
|
+
} catch (e) { toast('同步失败:' + e.message); }
|
|
158
|
+
}
|
|
159
|
+
async function toggleNode(id, enabled) {
|
|
160
|
+
try { await api('/api/nodes/' + id, 'PUT', { enabled }); await loadNodes(); }
|
|
161
|
+
catch (e) { toast('操作失败:' + e.message); }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* ========== 自定义来源 ========== */
|
|
165
|
+
async function loadSources() {
|
|
166
|
+
try {
|
|
167
|
+
const d = await api('/api/sources');
|
|
168
|
+
renderSourcesGrid(d.sources || []);
|
|
169
|
+
} catch (e) { console.warn('加载来源失败', e); }
|
|
170
|
+
}
|
|
171
|
+
async function saveSource(data) {
|
|
172
|
+
try {
|
|
173
|
+
const d = data.id
|
|
174
|
+
? await api('/api/sources/' + data.id, 'PUT', data)
|
|
175
|
+
: await api('/api/sources', 'POST', data);
|
|
176
|
+
await loadSources();
|
|
177
|
+
toast(data.id ? '来源已更新' : '来源已添加');
|
|
178
|
+
return d;
|
|
179
|
+
} catch (e) { toast('保存失败:' + e.message); }
|
|
180
|
+
}
|
|
181
|
+
async function deleteSource(id) {
|
|
182
|
+
try { await api('/api/sources/' + id, 'DELETE'); await loadSources(); toast('已删除来源'); }
|
|
183
|
+
catch (e) { toast('删除失败:' + e.message); }
|
|
112
184
|
}
|
|
113
185
|
|
|
114
186
|
async function delAuto(id) {
|
|
@@ -122,7 +194,7 @@
|
|
|
122
194
|
}
|
|
123
195
|
|
|
124
196
|
async function loadAutomations() {
|
|
125
|
-
try { const d = await api('/api/automations'); renderAutoGrid(d.automations || []); }
|
|
197
|
+
try { const d = await api('/api/automations'); renderBuiltinAutomations(d.builtin || []); renderAutoGrid(d.automations || []); }
|
|
126
198
|
catch (e) { console.warn('加载自动化失败', e); }
|
|
127
199
|
}
|
|
128
200
|
|
|
@@ -272,6 +344,7 @@
|
|
|
272
344
|
status.classList.remove('err');
|
|
273
345
|
document.getElementById('loginOverlay').style.display = 'none';
|
|
274
346
|
document.getElementById('appLayout').classList.add('show');
|
|
347
|
+
document.documentElement.classList.add('logged-in');
|
|
275
348
|
await afterLogin();
|
|
276
349
|
} catch (e) {
|
|
277
350
|
status.textContent = '登录失败:' + e.message;
|
|
@@ -282,7 +355,16 @@
|
|
|
282
355
|
}
|
|
283
356
|
|
|
284
357
|
async function api(path, method = 'GET', body) {
|
|
285
|
-
|
|
358
|
+
let res;
|
|
359
|
+
try {
|
|
360
|
+
res = await fetch(path, { method, headers: authHeaders(), body: body ? JSON.stringify(body) : undefined });
|
|
361
|
+
} catch (e) {
|
|
362
|
+
// 网络层失败(Failed to fetch / 连接拒绝 / 超时中断):标记后端可能已断开
|
|
363
|
+
if (typeof BackendConn !== 'undefined') BackendConn.markFailure();
|
|
364
|
+
throw e;
|
|
365
|
+
}
|
|
366
|
+
// 请求到达后端并返回响应:若之前处于断连状态,立即恢复
|
|
367
|
+
if (typeof BackendConn !== 'undefined' && !BackendConn.online) BackendConn.setOnline(true);
|
|
286
368
|
if (!res.ok) {
|
|
287
369
|
const d = await res.json().catch(() => ({}));
|
|
288
370
|
// 401:令牌确实被服务端拒绝,清除并回到登录页。
|
|
@@ -307,3 +389,108 @@
|
|
|
307
389
|
function authHeaders() {
|
|
308
390
|
return state.token ? { 'Authorization': 'Bearer ' + state.token, 'Content-Type': 'application/json' } : { 'Content-Type': 'application/json' };
|
|
309
391
|
}
|
|
392
|
+
|
|
393
|
+
/* ========== 后端连接状态监测(心跳 + 断连横幅 + 自动重连) ==========
|
|
394
|
+
* 解决问题:后端进程崩溃后,前端无感知,用户操作均报 "Failed to fetch" 且不知原因。
|
|
395
|
+
* 机制:
|
|
396
|
+
* 1. 每 5s 轮询 /api/health,连续失败 2 次判定后端断开,顶部显示红色横幅。
|
|
397
|
+
* 2. 断连后自动加快到每 2s 重试,恢复后自动切回 5s 并 toast 提示。
|
|
398
|
+
* 3. 任意 api() 调用网络失败也会累计失败计数(双保险,不必等下一轮心跳)。
|
|
399
|
+
* 4. 页面从后台切回 / 网络恢复事件时立即检测一次。
|
|
400
|
+
*/
|
|
401
|
+
const BackendConn = {
|
|
402
|
+
online: true,
|
|
403
|
+
heartbeatTimer: null,
|
|
404
|
+
reconnectTimer: null,
|
|
405
|
+
intervalMs: 5000, // 正常心跳间隔
|
|
406
|
+
reconnectMs: 2000, // 断连后重连检测间隔
|
|
407
|
+
consecutiveFailures: 0,
|
|
408
|
+
threshold: 2, // 连续失败 N 次才判定断开(避免瞬时抖动误报)
|
|
409
|
+
healthTimeoutMs: 3000, // 单次健康检查超时
|
|
410
|
+
|
|
411
|
+
init() {
|
|
412
|
+
this.startHeartbeat();
|
|
413
|
+
// 重连按钮
|
|
414
|
+
const btn = document.getElementById('backendReconnectBtn');
|
|
415
|
+
if (btn) btn.addEventListener('click', () => this.reconnect());
|
|
416
|
+
// 页面从后台切回前台时立即检测
|
|
417
|
+
document.addEventListener('visibilitychange', () => {
|
|
418
|
+
if (!document.hidden) this.check();
|
|
419
|
+
});
|
|
420
|
+
// 浏览器网络恢复事件
|
|
421
|
+
window.addEventListener('online', () => this.check());
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
startHeartbeat() {
|
|
425
|
+
if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
|
|
426
|
+
this.heartbeatTimer = setInterval(() => this.check(), this.intervalMs);
|
|
427
|
+
},
|
|
428
|
+
|
|
429
|
+
async check() {
|
|
430
|
+
try {
|
|
431
|
+
const ctrl = new AbortController();
|
|
432
|
+
const timeout = setTimeout(() => ctrl.abort(), this.healthTimeoutMs);
|
|
433
|
+
const res = await fetch('/api/health', {
|
|
434
|
+
method: 'GET',
|
|
435
|
+
signal: ctrl.signal,
|
|
436
|
+
cache: 'no-store',
|
|
437
|
+
headers: { 'Cache-Control': 'no-cache' },
|
|
438
|
+
});
|
|
439
|
+
clearTimeout(timeout);
|
|
440
|
+
if (res.ok) {
|
|
441
|
+
this.consecutiveFailures = 0;
|
|
442
|
+
this.setOnline(true);
|
|
443
|
+
} else {
|
|
444
|
+
this.markFailure();
|
|
445
|
+
}
|
|
446
|
+
} catch (e) {
|
|
447
|
+
this.markFailure();
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
|
|
451
|
+
/** 累计失败次数,达到阈值则判定断开 */
|
|
452
|
+
markFailure() {
|
|
453
|
+
this.consecutiveFailures++;
|
|
454
|
+
if (this.consecutiveFailures >= this.threshold) {
|
|
455
|
+
this.setOnline(false);
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
setOnline(online) {
|
|
460
|
+
if (this.online === online) return;
|
|
461
|
+
this.online = online;
|
|
462
|
+
const banner = document.getElementById('backendOfflineBanner');
|
|
463
|
+
const text = document.getElementById('backendOfflineText');
|
|
464
|
+
if (banner) {
|
|
465
|
+
banner.style.display = online ? 'none' : 'flex';
|
|
466
|
+
}
|
|
467
|
+
if (online) {
|
|
468
|
+
// 恢复:切回正常心跳间隔
|
|
469
|
+
if (this.reconnectTimer) { clearInterval(this.reconnectTimer); this.reconnectTimer = null; }
|
|
470
|
+
this.startHeartbeat();
|
|
471
|
+
try { toast('后端服务已恢复连接'); } catch (e) {}
|
|
472
|
+
} else {
|
|
473
|
+
// 断开:停止正常心跳,加快重连检测
|
|
474
|
+
if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; }
|
|
475
|
+
if (!this.reconnectTimer) {
|
|
476
|
+
this.reconnectTimer = setInterval(() => this.check(), this.reconnectMs);
|
|
477
|
+
}
|
|
478
|
+
if (text) text.textContent = '后端服务已断开,正在自动重连…';
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
/** 手动触发重连:重置失败计数并立即检测 */
|
|
483
|
+
reconnect() {
|
|
484
|
+
const text = document.getElementById('backendOfflineText');
|
|
485
|
+
if (text) text.textContent = '正在重连后端服务…';
|
|
486
|
+
this.consecutiveFailures = 0;
|
|
487
|
+
this.check();
|
|
488
|
+
},
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// 页面加载完成后启动心跳监测
|
|
492
|
+
if (document.readyState === 'loading') {
|
|
493
|
+
document.addEventListener('DOMContentLoaded', () => BackendConn.init());
|
|
494
|
+
} else {
|
|
495
|
+
BackendConn.init();
|
|
496
|
+
}
|