feihong-code 7.0.0 → 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 +50 -0
- 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 +127 -16
- package/dist/agent/orchestrator.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 +40 -10
- 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/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 +58 -0
- package/dist/web/public/index.html +210 -0
- package/dist/web/public/js/api.js +115 -1
- 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 +926 -4
- 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 +1019 -0
- package/dist/web/server.js.map +1 -1
- package/dist/web/task-queue.js +22 -2
- package/dist/web/task-queue.js.map +1 -1
- package/docs/DEPLOYMENT.md +382 -0
- package/docs/MODEL_FINETUNING.md +405 -0
- package/electron/main.js +202 -4
- package/package.json +6 -1
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GitIntegration = void 0;
|
|
4
|
+
exports.createGitIntegration = createGitIntegration;
|
|
5
|
+
/**
|
|
6
|
+
* 飞虹 Code - Git 集成模块 (P2-2)
|
|
7
|
+
* 完整的 Git 操作封装:状态、diff、暂存、提交、分支、历史、推送/拉取
|
|
8
|
+
*
|
|
9
|
+
* 设计原则:
|
|
10
|
+
* - 所有操作通过 child_process 调用 git 命令
|
|
11
|
+
* - 非 git 仓库时安全退出
|
|
12
|
+
* - 破坏性操作(push/reset/force)需要显式确认
|
|
13
|
+
* - 输出结构化,便于前端展示
|
|
14
|
+
*/
|
|
15
|
+
const child_process_1 = require("child_process");
|
|
16
|
+
const fs_1 = require("fs");
|
|
17
|
+
const path_1 = require("path");
|
|
18
|
+
const logger_1 = require("../shared/logger");
|
|
19
|
+
/** 执行 git 命令 */
|
|
20
|
+
function git(args, cwd, timeoutMs = 30000) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
(0, child_process_1.execFile)('git', args, { cwd, timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
|
|
23
|
+
resolve({
|
|
24
|
+
code: error ? error.code ?? 1 : 0,
|
|
25
|
+
stdout: stdout || '',
|
|
26
|
+
stderr: stderr || '',
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Git 集成管理器
|
|
33
|
+
*/
|
|
34
|
+
class GitIntegration {
|
|
35
|
+
cwd;
|
|
36
|
+
constructor(cwd) {
|
|
37
|
+
this.cwd = cwd;
|
|
38
|
+
}
|
|
39
|
+
/** 是否为 git 仓库 */
|
|
40
|
+
isRepo() {
|
|
41
|
+
return (0, fs_1.existsSync)((0, path_1.join)(this.cwd, '.git'));
|
|
42
|
+
}
|
|
43
|
+
/** 获取 Git 状态 */
|
|
44
|
+
async status() {
|
|
45
|
+
if (!this.isRepo()) {
|
|
46
|
+
return {
|
|
47
|
+
isRepo: false, branch: '', upstream: null, ahead: 0, behind: 0,
|
|
48
|
+
files: [], stagedCount: 0, modifiedCount: 0, untrackedCount: 0,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// 获取状态(porcelain 格式 + 分支信息)
|
|
52
|
+
const statusResult = await git(['status', '--porcelain=v2', '--branch'], this.cwd);
|
|
53
|
+
const files = [];
|
|
54
|
+
let branch = '';
|
|
55
|
+
let upstream = null;
|
|
56
|
+
let ahead = 0;
|
|
57
|
+
let behind = 0;
|
|
58
|
+
for (const line of statusResult.stdout.split('\n')) {
|
|
59
|
+
if (!line)
|
|
60
|
+
continue;
|
|
61
|
+
if (line.startsWith('# ')) {
|
|
62
|
+
// 分支信息
|
|
63
|
+
const parts = line.slice(2).split(' ');
|
|
64
|
+
if (parts[0] === 'branch.head')
|
|
65
|
+
branch = parts[1] || '';
|
|
66
|
+
if (parts[0] === 'branch.upstream')
|
|
67
|
+
upstream = parts[1] || null;
|
|
68
|
+
if (parts[0] === 'branch.ab') {
|
|
69
|
+
const ab = parts[1] || '';
|
|
70
|
+
const aMatch = ab.match(/\+(\d+)/);
|
|
71
|
+
const bMatch = ab.match(/-(\d+)/);
|
|
72
|
+
ahead = aMatch ? parseInt(aMatch[1]) : 0;
|
|
73
|
+
behind = bMatch ? parseInt(bMatch[1]) : 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else if (line.startsWith('1 ') || line.startsWith('2 ')) {
|
|
77
|
+
// 已跟踪文件变更
|
|
78
|
+
const parts = line.split(' ');
|
|
79
|
+
const xy = parts[1] || '';
|
|
80
|
+
const indexStatus = xy[0] || '.';
|
|
81
|
+
const workTreeStatus = xy[1] || '.';
|
|
82
|
+
const path = parts.slice(parts.length - 1)[0] || '';
|
|
83
|
+
files.push({
|
|
84
|
+
path,
|
|
85
|
+
indexStatus,
|
|
86
|
+
workTreeStatus,
|
|
87
|
+
conflict: indexStatus === 'U' || workTreeStatus === 'U' || xy === 'AA' || xy === 'DD',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else if (line.startsWith('? ')) {
|
|
91
|
+
// 未跟踪文件
|
|
92
|
+
const path = line.slice(2);
|
|
93
|
+
files.push({ path, indexStatus: '?', workTreeStatus: '?', conflict: false });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const stagedCount = files.filter((f) => f.indexStatus !== '.' && f.indexStatus !== '?').length;
|
|
97
|
+
const modifiedCount = files.filter((f) => f.workTreeStatus !== '.' && f.workTreeStatus !== '?').length;
|
|
98
|
+
const untrackedCount = files.filter((f) => f.indexStatus === '?').length;
|
|
99
|
+
return { isRepo: true, branch, upstream, ahead, behind, files, stagedCount, modifiedCount, untrackedCount };
|
|
100
|
+
}
|
|
101
|
+
/** 获取文件 diff */
|
|
102
|
+
async diff(path, staged = false) {
|
|
103
|
+
if (!this.isRepo())
|
|
104
|
+
return [];
|
|
105
|
+
const args = ['diff', '--color=never', '--unified=3'];
|
|
106
|
+
if (staged)
|
|
107
|
+
args.push('--cached');
|
|
108
|
+
if (path)
|
|
109
|
+
args.push('--', path);
|
|
110
|
+
const result = await git(args, this.cwd);
|
|
111
|
+
return this.parseDiff(result.stdout);
|
|
112
|
+
}
|
|
113
|
+
/** 解析 diff 输出 */
|
|
114
|
+
parseDiff(diffText) {
|
|
115
|
+
const files = [];
|
|
116
|
+
if (!diffText.trim())
|
|
117
|
+
return files;
|
|
118
|
+
const fileBlocks = diffText.split(/^diff --git /m).slice(1);
|
|
119
|
+
for (const block of fileBlocks) {
|
|
120
|
+
const lines = block.split('\n');
|
|
121
|
+
const headerLine = lines[0] || '';
|
|
122
|
+
const oldPathMatch = headerLine.match(/a\/(.+) b\//);
|
|
123
|
+
const newPathMatch = headerLine.match(/ b\/(.+)/);
|
|
124
|
+
const oldPath = oldPathMatch ? oldPathMatch[1] : null;
|
|
125
|
+
const newPath = newPathMatch ? newPathMatch[1] : null;
|
|
126
|
+
const path = newPath || oldPath || '';
|
|
127
|
+
const isNew = lines.some((l) => l.startsWith('new file mode'));
|
|
128
|
+
const isDeleted = lines.some((l) => l.startsWith('deleted file mode'));
|
|
129
|
+
const isBinary = lines.some((l) => l.includes('Binary files'));
|
|
130
|
+
const hunks = [];
|
|
131
|
+
let currentHunk = null;
|
|
132
|
+
let additions = 0;
|
|
133
|
+
let deletions = 0;
|
|
134
|
+
for (const line of lines) {
|
|
135
|
+
if (line.startsWith('@@')) {
|
|
136
|
+
if (currentHunk)
|
|
137
|
+
hunks.push(currentHunk);
|
|
138
|
+
const match = line.match(/@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/);
|
|
139
|
+
currentHunk = {
|
|
140
|
+
header: line,
|
|
141
|
+
oldStart: match ? parseInt(match[1]) : 0,
|
|
142
|
+
oldLines: match ? (match[2] ? parseInt(match[2]) : 1) : 0,
|
|
143
|
+
newStart: match ? parseInt(match[3]) : 0,
|
|
144
|
+
newLines: match ? (match[4] ? parseInt(match[4]) : 1) : 0,
|
|
145
|
+
lines: [],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
else if (currentHunk) {
|
|
149
|
+
if (line.startsWith('+')) {
|
|
150
|
+
currentHunk.lines.push({ type: 'add', content: line.slice(1) });
|
|
151
|
+
additions++;
|
|
152
|
+
}
|
|
153
|
+
else if (line.startsWith('-')) {
|
|
154
|
+
currentHunk.lines.push({ type: 'remove', content: line.slice(1) });
|
|
155
|
+
deletions++;
|
|
156
|
+
}
|
|
157
|
+
else if (line.startsWith(' ')) {
|
|
158
|
+
currentHunk.lines.push({ type: 'context', content: line.slice(1) });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (currentHunk)
|
|
163
|
+
hunks.push(currentHunk);
|
|
164
|
+
files.push({ path, oldPath, newPath, isNew, isDeleted, isBinary, hunks, additions, deletions });
|
|
165
|
+
}
|
|
166
|
+
return files;
|
|
167
|
+
}
|
|
168
|
+
/** 暂存文件(git add) */
|
|
169
|
+
async add(paths) {
|
|
170
|
+
if (!this.isRepo())
|
|
171
|
+
return { success: false, message: '不是 git 仓库' };
|
|
172
|
+
const result = await git(['add', '--', ...paths], this.cwd);
|
|
173
|
+
if (result.code === 0) {
|
|
174
|
+
logger_1.logger.info('git add', { paths });
|
|
175
|
+
return { success: true, message: `已暂存 ${paths.length} 个文件` };
|
|
176
|
+
}
|
|
177
|
+
return { success: false, message: result.stderr.trim() || 'git add 失败' };
|
|
178
|
+
}
|
|
179
|
+
/** 取消暂存(git reset HEAD) */
|
|
180
|
+
async reset(paths) {
|
|
181
|
+
if (!this.isRepo())
|
|
182
|
+
return { success: false, message: '不是 git 仓库' };
|
|
183
|
+
const result = await git(['reset', 'HEAD', '--', ...paths], this.cwd);
|
|
184
|
+
if (result.code === 0) {
|
|
185
|
+
return { success: true, message: `已取消暂存 ${paths.length} 个文件` };
|
|
186
|
+
}
|
|
187
|
+
return { success: false, message: result.stderr.trim() || 'git reset 失败' };
|
|
188
|
+
}
|
|
189
|
+
/** 提交(git commit) */
|
|
190
|
+
async commit(message, paths) {
|
|
191
|
+
if (!this.isRepo())
|
|
192
|
+
return { success: false, message: '不是 git 仓库' };
|
|
193
|
+
if (!message.trim())
|
|
194
|
+
return { success: false, message: '提交信息不能为空' };
|
|
195
|
+
const args = ['commit', '-m', message];
|
|
196
|
+
if (paths && paths.length)
|
|
197
|
+
args.push('--', ...paths);
|
|
198
|
+
const result = await git(args, this.cwd);
|
|
199
|
+
if (result.code === 0) {
|
|
200
|
+
// 获取提交 hash
|
|
201
|
+
const hashResult = await git(['rev-parse', 'HEAD'], this.cwd);
|
|
202
|
+
const hash = hashResult.stdout.trim();
|
|
203
|
+
logger_1.logger.info('git commit', { hash, message });
|
|
204
|
+
return { success: true, hash, message: '提交成功' };
|
|
205
|
+
}
|
|
206
|
+
return { success: false, message: result.stderr.trim() || 'git commit 失败' };
|
|
207
|
+
}
|
|
208
|
+
/** 获取分支列表 */
|
|
209
|
+
async branches() {
|
|
210
|
+
if (!this.isRepo())
|
|
211
|
+
return [];
|
|
212
|
+
const result = await git(['branch', '-vv', '--no-abbrev'], this.cwd);
|
|
213
|
+
const branches = [];
|
|
214
|
+
for (const line of result.stdout.split('\n')) {
|
|
215
|
+
if (!line.trim())
|
|
216
|
+
continue;
|
|
217
|
+
const isCurrent = line.startsWith('*');
|
|
218
|
+
const isRemote = line.trim().startsWith('remotes/');
|
|
219
|
+
const name = isRemote
|
|
220
|
+
? line.trim().replace(/^remotes\//, '')
|
|
221
|
+
: line.trim().replace(/^[\* ]\s*/, '').split(/\s+/)[0] || '';
|
|
222
|
+
// 解析 upstream 和 ahead/behind
|
|
223
|
+
let upstream = null;
|
|
224
|
+
let ahead = 0;
|
|
225
|
+
let behind = 0;
|
|
226
|
+
const upstreamMatch = line.match(/\[([^\]]+)\]/);
|
|
227
|
+
if (upstreamMatch) {
|
|
228
|
+
const info = upstreamMatch[1];
|
|
229
|
+
upstream = info.split(':')[0];
|
|
230
|
+
const aMatch = info.match(/ahead (\d+)/);
|
|
231
|
+
const bMatch = info.match(/behind (\d+)/);
|
|
232
|
+
ahead = aMatch ? parseInt(aMatch[1]) : 0;
|
|
233
|
+
behind = bMatch ? parseInt(bMatch[1]) : 0;
|
|
234
|
+
}
|
|
235
|
+
// 获取最后提交 hash
|
|
236
|
+
const hashMatch = line.match(/([0-9a-f]{7,40})/);
|
|
237
|
+
const lastCommit = hashMatch ? hashMatch[1] : '';
|
|
238
|
+
branches.push({ name, current: isCurrent, remote: isRemote, upstream, ahead, behind, lastCommit });
|
|
239
|
+
}
|
|
240
|
+
return branches;
|
|
241
|
+
}
|
|
242
|
+
/** 切换分支 */
|
|
243
|
+
async checkout(branch, createNew = false) {
|
|
244
|
+
if (!this.isRepo())
|
|
245
|
+
return { success: false, message: '不是 git 仓库' };
|
|
246
|
+
const args = createNew ? ['checkout', '-b', branch] : ['checkout', branch];
|
|
247
|
+
const result = await git(args, this.cwd);
|
|
248
|
+
if (result.code === 0) {
|
|
249
|
+
return { success: true, message: `已切换到分支 ${branch}` };
|
|
250
|
+
}
|
|
251
|
+
return { success: false, message: result.stderr.trim() || 'git checkout 失败' };
|
|
252
|
+
}
|
|
253
|
+
/** 获取提交历史 */
|
|
254
|
+
async log(count = 20) {
|
|
255
|
+
if (!this.isRepo())
|
|
256
|
+
return [];
|
|
257
|
+
const format = '%H%n%h%n%an%n%ae%n%aI%n%s%n%b%n---END---';
|
|
258
|
+
const result = await git(['log', `--pretty=format:${format}`, `-${count}`], this.cwd);
|
|
259
|
+
const commits = [];
|
|
260
|
+
const blocks = result.stdout.split('---END---').filter((b) => b.trim());
|
|
261
|
+
for (const block of blocks) {
|
|
262
|
+
const lines = block.trim().split('\n');
|
|
263
|
+
if (lines.length < 6)
|
|
264
|
+
continue;
|
|
265
|
+
const [hash, shortHash, author, email, date, subject, ...bodyLines] = lines;
|
|
266
|
+
commits.push({
|
|
267
|
+
hash,
|
|
268
|
+
shortHash,
|
|
269
|
+
author,
|
|
270
|
+
email,
|
|
271
|
+
date,
|
|
272
|
+
subject,
|
|
273
|
+
message: bodyLines.join('\n').trim() || subject,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
return commits;
|
|
277
|
+
}
|
|
278
|
+
/** 推送 */
|
|
279
|
+
async push(remote = 'origin', branch, force = false) {
|
|
280
|
+
if (!this.isRepo())
|
|
281
|
+
return { success: false, message: '不是 git 仓库' };
|
|
282
|
+
const args = ['push'];
|
|
283
|
+
if (force)
|
|
284
|
+
args.push('--force-with-lease');
|
|
285
|
+
args.push(remote);
|
|
286
|
+
if (branch)
|
|
287
|
+
args.push(branch);
|
|
288
|
+
const result = await git(args, this.cwd, 60000);
|
|
289
|
+
if (result.code === 0) {
|
|
290
|
+
return { success: true, message: '推送成功' };
|
|
291
|
+
}
|
|
292
|
+
return { success: false, message: result.stderr.trim() || 'git push 失败' };
|
|
293
|
+
}
|
|
294
|
+
/** 拉取 */
|
|
295
|
+
async pull(remote = 'origin', branch) {
|
|
296
|
+
if (!this.isRepo())
|
|
297
|
+
return { success: false, message: '不是 git 仓库' };
|
|
298
|
+
const args = ['pull'];
|
|
299
|
+
args.push(remote);
|
|
300
|
+
if (branch)
|
|
301
|
+
args.push(branch);
|
|
302
|
+
const result = await git(args, this.cwd, 60000);
|
|
303
|
+
if (result.code === 0) {
|
|
304
|
+
return { success: true, message: '拉取成功' };
|
|
305
|
+
}
|
|
306
|
+
return { success: false, message: result.stderr.trim() || 'git pull 失败' };
|
|
307
|
+
}
|
|
308
|
+
/** 初始化仓库 */
|
|
309
|
+
async init() {
|
|
310
|
+
if (this.isRepo())
|
|
311
|
+
return { success: false, message: '已经是 git 仓库' };
|
|
312
|
+
const result = await git(['init'], this.cwd);
|
|
313
|
+
if (result.code === 0) {
|
|
314
|
+
return { success: true, message: 'Git 仓库初始化成功' };
|
|
315
|
+
}
|
|
316
|
+
return { success: false, message: result.stderr.trim() || 'git init 失败' };
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
exports.GitIntegration = GitIntegration;
|
|
320
|
+
/** 便捷函数:创建 Git 集成管理器 */
|
|
321
|
+
function createGitIntegration(cwd) {
|
|
322
|
+
return new GitIntegration(cwd);
|
|
323
|
+
}
|
|
324
|
+
//# sourceMappingURL=git-integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-integration.js","sourceRoot":"","sources":["../../src/agent/git-integration.ts"],"names":[],"mappings":";;;AAwZA,oDAEC;AA1ZD;;;;;;;;;GASG;AACH,iDAAyC;AACzC,2BAAgC;AAChC,+BAA4B;AAC5B,6CAA0C;AAS1C,gBAAgB;AAChB,SAAS,GAAG,CAAC,IAAc,EAAE,GAAW,EAAE,SAAS,GAAG,KAAK;IACzD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAA,wBAAQ,EAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAC5E,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,OAAO,CAAC;gBACN,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,KAAa,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC1C,MAAM,EAAE,MAAM,IAAI,EAAE;gBACpB,MAAM,EAAE,MAAM,IAAI,EAAE;aACrB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACL,CAAC;AA0ED;;GAEG;AACH,MAAa,cAAc;IACjB,GAAG,CAAS;IAEpB,YAAY,GAAW;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,iBAAiB;IACjB,MAAM;QACJ,OAAO,IAAA,eAAU,EAAC,IAAA,WAAI,EAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACnB,OAAO;gBACL,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;gBAC9D,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,cAAc,EAAE,CAAC;aAC/D,CAAC;QACJ,CAAC;QAED,4BAA4B;QAC5B,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACnF,MAAM,KAAK,GAAoB,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,QAAQ,GAAkB,IAAI,CAAC;QACnC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,OAAO;gBACP,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,aAAa;oBAAE,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACxD,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,iBAAiB;oBAAE,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;gBAChE,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;oBAC7B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;oBACnC,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBAClC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACzC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,UAAU;gBACV,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC1B,MAAM,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;gBACjC,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;gBACpC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpD,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI;oBACJ,WAAW;oBACX,cAAc;oBACd,QAAQ,EAAE,WAAW,KAAK,GAAG,IAAI,cAAc,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,IAAI;iBACtF,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,QAAQ;gBACR,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,IAAI,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QAC/F,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,GAAG,IAAI,CAAC,CAAC,cAAc,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QACvG,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;QAEzE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;IAC9G,CAAC;IAED,gBAAgB;IAChB,KAAK,CAAC,IAAI,CAAC,IAAa,EAAE,MAAM,GAAG,KAAK;QACtC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,CAAC;QAE9B,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,iBAAiB;IACT,SAAS,CAAC,QAAgB;QAChC,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;YAAE,OAAO,KAAK,CAAC;QAEnC,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5D,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YACrD,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtD,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtD,MAAM,IAAI,GAAG,OAAO,IAAI,OAAO,IAAI,EAAE,CAAC;YAEtC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACvE,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;YAE/D,MAAM,KAAK,GAAe,EAAE,CAAC;YAC7B,IAAI,WAAW,GAAoB,IAAI,CAAC;YACxC,IAAI,SAAS,GAAG,CAAC,CAAC;YAClB,IAAI,SAAS,GAAG,CAAC,CAAC;YAElB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,IAAI,WAAW;wBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;oBACvE,WAAW,GAAG;wBACZ,MAAM,EAAE,IAAI;wBACZ,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACxC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACzD,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACxC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACzD,KAAK,EAAE,EAAE;qBACV,CAAC;gBACJ,CAAC;qBAAM,IAAI,WAAW,EAAE,CAAC;oBACvB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACzB,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBAChE,SAAS,EAAE,CAAC;oBACd,CAAC;yBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBACnE,SAAS,EAAE,CAAC;oBACd,CAAC;yBAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBAChC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBACtE,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,WAAW;gBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAEzC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED,oBAAoB;IACpB,KAAK,CAAC,GAAG,CAAC,KAAe;QACvB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC5D,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,eAAM,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,KAAK,CAAC,MAAM,MAAM,EAAE,CAAC;QAC/D,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,YAAY,EAAE,CAAC;IAC3E,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,KAAK,CAAC,KAAe;QACzB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACtE,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,KAAK,CAAC,MAAM,MAAM,EAAE,CAAC;QACjE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,cAAc,EAAE,CAAC;IAC7E,CAAC;IAED,qBAAqB;IACrB,KAAK,CAAC,MAAM,CAAC,OAAe,EAAE,KAAgB;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACpE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QAEpE,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,YAAY;YACZ,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9D,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACtC,eAAM,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAClD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,eAAe,EAAE,CAAC;IAC9E,CAAC;IAED,aAAa;IACb,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,CAAC;QAE9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAgB,EAAE,CAAC;QAEjC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,QAAQ;gBACnB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAE/D,6BAA6B;YAC7B,IAAI,QAAQ,GAAkB,IAAI,CAAC;YACnC,IAAI,KAAK,GAAG,CAAC,CAAC;YACd,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACjD,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,IAAI,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;gBAC9B,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;gBACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;gBAC1C,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC;YAED,cAAc;YACd,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACjD,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAEjD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QACrG,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,WAAW;IACX,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,SAAS,GAAG,KAAK;QAC9C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACpE,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC;QACxD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,iBAAiB,EAAE,CAAC;IAChF,CAAC;IAED,aAAa;IACb,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,CAAC;QAE9B,MAAM,MAAM,GAAG,0CAA0C,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,mBAAmB,MAAM,EAAE,EAAE,IAAI,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAEtF,MAAM,OAAO,GAAgB,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAExE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,SAAS;YAC/B,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC;YAC5E,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI;gBACJ,SAAS;gBACT,MAAM;gBACN,KAAK;gBACL,IAAI;gBACJ,OAAO;gBACP,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,OAAO;aAChD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,MAAe,EAAE,KAAK,GAAG,KAAK;QAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACpE,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC5C,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;IAC5E,CAAC;IAED,SAAS;IACT,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,EAAE,MAAe;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;QACpE,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAClB,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE9B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC5C,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;IAC5E,CAAC;IAED,YAAY;IACZ,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM,EAAE;YAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QACnD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,aAAa,EAAE,CAAC;IAC5E,CAAC;CACF;AAtSD,wCAsSC;AAED,wBAAwB;AACxB,SAAgB,oBAAoB,CAAC,GAAW;IAC9C,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LayeredMemory = void 0;
|
|
4
|
+
exports.createLayeredMemory = createLayeredMemory;
|
|
5
|
+
/**
|
|
6
|
+
* 飞虹 Code (Muse Code 参照复刻)
|
|
7
|
+
* 晋江市飞虹智科技企业管理有限公司 · 飞扬企源研发中心 · 负责人:吴赐虹
|
|
8
|
+
*
|
|
9
|
+
* P1-2 分层记忆架构(Layered Memory Architecture):
|
|
10
|
+
* - 工作记忆(Working Memory):当前对话窗口,完整消息列表
|
|
11
|
+
* - 任务记忆(Task Memory):子任务完成后的结构化 Checkpoint 列表
|
|
12
|
+
* - 项目记忆(Project Memory):跨会话持久化记忆(技术决策、用户偏好、历史任务)
|
|
13
|
+
*
|
|
14
|
+
* 核心能力:
|
|
15
|
+
* - 自动压缩:工作记忆超阈值时,将早期内容压缩为任务记忆 Checkpoint
|
|
16
|
+
* - 上下文召回:新任务启动时,从项目记忆中召回相关历史任务摘要
|
|
17
|
+
* - 分层注入:构建上下文时,项目记忆摘要 + 任务记忆 Checkpoint + 工作记忆完整消息
|
|
18
|
+
* - 持久化:任务记忆可落盘,支持跨会话恢复
|
|
19
|
+
*
|
|
20
|
+
* 设计原则:
|
|
21
|
+
* - 不丢失关键决策:压缩时保留决策点、产物路径、遗留问题,丢弃过程性对话
|
|
22
|
+
* - 可观测:每层记忆的大小、压缩次数、召回结果都有统计
|
|
23
|
+
* - 可配置:压缩阈值、保留轮数、记忆目录均可配置
|
|
24
|
+
*/
|
|
25
|
+
const fs_1 = require("fs");
|
|
26
|
+
const path_1 = require("path");
|
|
27
|
+
const os_1 = require("os");
|
|
28
|
+
const context_compactor_1 = require("./context-compactor");
|
|
29
|
+
const logger_1 = require("../shared/logger");
|
|
30
|
+
const DEFAULT_CONFIG = {
|
|
31
|
+
workingMemoryThreshold: 30,
|
|
32
|
+
preservedRounds: 10,
|
|
33
|
+
maxTaskCheckpoints: 20,
|
|
34
|
+
memoryDir: (0, path_1.join)(process.env.FH_HOME?.trim() || (0, path_1.join)((0, os_1.homedir)(), '.feihong-code'), 'layered-memory'),
|
|
35
|
+
useSmartCompaction: true,
|
|
36
|
+
maxRecalledItems: 5,
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* 分层记忆管理器
|
|
40
|
+
*/
|
|
41
|
+
class LayeredMemory {
|
|
42
|
+
config;
|
|
43
|
+
/** 工作记忆:当前对话窗口的完整消息 */
|
|
44
|
+
workingMemory = [];
|
|
45
|
+
/** 任务记忆:子任务完成后的结构化 Checkpoint */
|
|
46
|
+
taskMemory = [];
|
|
47
|
+
/** 项目记忆:跨会话持久化的历史任务摘要 */
|
|
48
|
+
projectMemory = [];
|
|
49
|
+
/** 统计 */
|
|
50
|
+
stats = {
|
|
51
|
+
workingMemoryCount: 0,
|
|
52
|
+
taskMemoryCount: 0,
|
|
53
|
+
projectMemoryCount: 0,
|
|
54
|
+
totalCompressions: 0,
|
|
55
|
+
totalCheckpoints: 0,
|
|
56
|
+
lastCompactionAt: null,
|
|
57
|
+
};
|
|
58
|
+
/** 当前任务的起始消息索引(用于创建 checkpoint 时确定范围) */
|
|
59
|
+
currentTaskStartIdx = 0;
|
|
60
|
+
constructor(config = {}) {
|
|
61
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
62
|
+
this.ensureDirs();
|
|
63
|
+
this.loadProjectMemory();
|
|
64
|
+
}
|
|
65
|
+
/** 添加消息到工作记忆 */
|
|
66
|
+
append(message) {
|
|
67
|
+
this.workingMemory.push(message);
|
|
68
|
+
this.stats.workingMemoryCount = this.workingMemory.length;
|
|
69
|
+
}
|
|
70
|
+
/** 批量添加消息 */
|
|
71
|
+
appendAll(messages) {
|
|
72
|
+
for (const m of messages)
|
|
73
|
+
this.workingMemory.push(m);
|
|
74
|
+
this.stats.workingMemoryCount = this.workingMemory.length;
|
|
75
|
+
}
|
|
76
|
+
/** 获取当前工作记忆 */
|
|
77
|
+
getWorkingMemory() {
|
|
78
|
+
return [...this.workingMemory];
|
|
79
|
+
}
|
|
80
|
+
/** 获取任务记忆 */
|
|
81
|
+
getTaskMemory() {
|
|
82
|
+
return [...this.taskMemory];
|
|
83
|
+
}
|
|
84
|
+
/** 获取项目记忆 */
|
|
85
|
+
getProjectMemory() {
|
|
86
|
+
return [...this.projectMemory];
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 检查并执行压缩(如果工作记忆超阈值)
|
|
90
|
+
* 返回是否执行了压缩
|
|
91
|
+
*/
|
|
92
|
+
compressIfNeeded() {
|
|
93
|
+
if (!(0, context_compactor_1.shouldCompact)(this.workingMemory, this.config.workingMemoryThreshold)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
const before = this.workingMemory.length;
|
|
97
|
+
if (this.config.useSmartCompaction) {
|
|
98
|
+
// 智能压缩:基于内容重要性选择性保留
|
|
99
|
+
const { messages: compacted, stats } = (0, context_compactor_1.smartCompact)(this.workingMemory, this.config.preservedRounds * 2);
|
|
100
|
+
this.workingMemory = compacted;
|
|
101
|
+
logger_1.logger.info('layered-memory: smart compaction', { before, after: compacted.length, preserved: stats.preservedMessages });
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// 普通压缩:保留最近 N 轮,压缩早期
|
|
105
|
+
const { messages: compacted } = (0, context_compactor_1.compactContext)(this.workingMemory, this.config.preservedRounds);
|
|
106
|
+
this.workingMemory = compacted;
|
|
107
|
+
logger_1.logger.info('layered-memory: regular compaction', { before, after: compacted.length });
|
|
108
|
+
}
|
|
109
|
+
this.stats.totalCompressions++;
|
|
110
|
+
this.stats.lastCompactionAt = new Date().toISOString();
|
|
111
|
+
this.stats.workingMemoryCount = this.workingMemory.length;
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 创建任务级 Checkpoint(子任务完成时调用)
|
|
116
|
+
* 将当前任务从起始位置到现在的消息压缩为结构化摘要
|
|
117
|
+
*/
|
|
118
|
+
createTaskCheckpoint(goal) {
|
|
119
|
+
const endIdx = this.workingMemory.length;
|
|
120
|
+
const checkpoint = (0, context_compactor_1.createCheckpoint)(this.workingMemory, {
|
|
121
|
+
start: this.currentTaskStartIdx,
|
|
122
|
+
end: endIdx,
|
|
123
|
+
}, goal);
|
|
124
|
+
this.taskMemory.push(checkpoint);
|
|
125
|
+
this.stats.totalCheckpoints++;
|
|
126
|
+
this.stats.taskMemoryCount = this.taskMemory.length;
|
|
127
|
+
// 如果任务记忆超阈值,合并最早的 Checkpoint
|
|
128
|
+
if (this.taskMemory.length > this.config.maxTaskCheckpoints) {
|
|
129
|
+
this.mergeOldestCheckpoints();
|
|
130
|
+
}
|
|
131
|
+
// 更新当前任务起始位置
|
|
132
|
+
this.currentTaskStartIdx = endIdx;
|
|
133
|
+
logger_1.logger.info('layered-memory: checkpoint created', {
|
|
134
|
+
goal,
|
|
135
|
+
result: checkpoint.result,
|
|
136
|
+
artifacts: checkpoint.artifacts.length,
|
|
137
|
+
totalCheckpoints: this.taskMemory.length,
|
|
138
|
+
});
|
|
139
|
+
return checkpoint;
|
|
140
|
+
}
|
|
141
|
+
/** 合并最早的两个 Checkpoint 为一个(保留关键信息) */
|
|
142
|
+
mergeOldestCheckpoints() {
|
|
143
|
+
if (this.taskMemory.length < 2)
|
|
144
|
+
return;
|
|
145
|
+
const [first, second, ...rest] = this.taskMemory;
|
|
146
|
+
const merged = {
|
|
147
|
+
goal: `${first.goal} + ${second.goal}`,
|
|
148
|
+
approach: [...first.approach, ...second.approach].slice(0, 8),
|
|
149
|
+
result: second.result === 'success' && first.result === 'success' ? 'success' : 'partial',
|
|
150
|
+
artifacts: [...new Set([...first.artifacts, ...second.artifacts])].slice(0, 15),
|
|
151
|
+
decisions: [...first.decisions, ...second.decisions].slice(0, 5),
|
|
152
|
+
pendingIssues: [...first.pendingIssues, ...second.pendingIssues].slice(0, 5),
|
|
153
|
+
keyParams: { ...first.keyParams, ...second.keyParams },
|
|
154
|
+
createdAt: second.createdAt,
|
|
155
|
+
messageRange: { start: first.messageRange.start, end: second.messageRange.end },
|
|
156
|
+
};
|
|
157
|
+
this.taskMemory = [merged, ...rest];
|
|
158
|
+
this.stats.taskMemoryCount = this.taskMemory.length;
|
|
159
|
+
logger_1.logger.info('layered-memory: oldest checkpoints merged', { total: this.taskMemory.length });
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* 从项目记忆中召回与当前目标相关的历史条目
|
|
163
|
+
* 基于标签和关键词匹配
|
|
164
|
+
*/
|
|
165
|
+
recall(goal) {
|
|
166
|
+
if (this.projectMemory.length === 0)
|
|
167
|
+
return [];
|
|
168
|
+
const keywords = this.extractKeywords(goal);
|
|
169
|
+
const scored = this.projectMemory.map((entry) => {
|
|
170
|
+
let score = 0;
|
|
171
|
+
// 标签匹配
|
|
172
|
+
for (const tag of entry.tags) {
|
|
173
|
+
if (keywords.some((kw) => tag.toLowerCase().includes(kw.toLowerCase()))) {
|
|
174
|
+
score += 2;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
// 目标文本匹配
|
|
178
|
+
for (const kw of keywords) {
|
|
179
|
+
if (entry.goal.toLowerCase().includes(kw.toLowerCase()))
|
|
180
|
+
score += 1;
|
|
181
|
+
if (entry.decisions.some((d) => d.toLowerCase().includes(kw.toLowerCase())))
|
|
182
|
+
score += 0.5;
|
|
183
|
+
}
|
|
184
|
+
// 时间衰减:越近的权重越高
|
|
185
|
+
const ageDays = (Date.now() - new Date(entry.timestamp).getTime()) / (1000 * 60 * 60 * 24);
|
|
186
|
+
score *= Math.max(0.3, 1 - ageDays / 30); // 30 天以上衰减到 0.3
|
|
187
|
+
return { entry, score };
|
|
188
|
+
});
|
|
189
|
+
scored.sort((a, b) => b.score - a.score);
|
|
190
|
+
const recalled = scored.filter((x) => x.score > 0).slice(0, this.config.maxRecalledItems).map((x) => x.entry);
|
|
191
|
+
logger_1.logger.info('layered-memory: recalled project memory', {
|
|
192
|
+
goal: goal.slice(0, 50),
|
|
193
|
+
recalled: recalled.length,
|
|
194
|
+
total: this.projectMemory.length,
|
|
195
|
+
});
|
|
196
|
+
return recalled;
|
|
197
|
+
}
|
|
198
|
+
/** 提取关键词(中英文混合) */
|
|
199
|
+
extractKeywords(text) {
|
|
200
|
+
const words = [];
|
|
201
|
+
const english = text.match(/[A-Za-z_$][A-Za-z0-9_$]*/g) || [];
|
|
202
|
+
for (const w of english) {
|
|
203
|
+
if (w.length >= 3)
|
|
204
|
+
words.push(w.toLowerCase());
|
|
205
|
+
}
|
|
206
|
+
const chinese = text.match(/[\u4e00-\u9fa5]{2,4}/g) || [];
|
|
207
|
+
words.push(...chinese);
|
|
208
|
+
return [...new Set(words)].slice(0, 15);
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 构建完整上下文(用于注入 system prompt)
|
|
212
|
+
* 包含:项目记忆召回摘要 + 任务记忆 Checkpoint 合并 + 工作记忆完整消息
|
|
213
|
+
*/
|
|
214
|
+
buildContext(goal) {
|
|
215
|
+
const parts = [];
|
|
216
|
+
// 1. 项目记忆召回(如果有目标)
|
|
217
|
+
if (goal) {
|
|
218
|
+
const recalled = this.recall(goal);
|
|
219
|
+
if (recalled.length > 0) {
|
|
220
|
+
parts.push('=== 项目记忆(相关历史任务召回)===');
|
|
221
|
+
for (const entry of recalled) {
|
|
222
|
+
parts.push(`\n📌 ${entry.goal}`);
|
|
223
|
+
if (entry.decisions.length > 0) {
|
|
224
|
+
parts.push(` 决策: ${entry.decisions.slice(0, 3).join('; ')}`);
|
|
225
|
+
}
|
|
226
|
+
if (entry.artifacts.length > 0) {
|
|
227
|
+
parts.push(` 产物: ${entry.artifacts.slice(0, 5).join(', ')}`);
|
|
228
|
+
}
|
|
229
|
+
if (entry.pendingIssues.length > 0) {
|
|
230
|
+
parts.push(` 遗留: ${entry.pendingIssues.join('; ')}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
parts.push('=== 项目记忆结束 ===\n');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
// 2. 任务记忆 Checkpoint 合并
|
|
237
|
+
if (this.taskMemory.length > 0) {
|
|
238
|
+
parts.push((0, context_compactor_1.mergeCheckpoints)(this.taskMemory));
|
|
239
|
+
parts.push('');
|
|
240
|
+
}
|
|
241
|
+
const systemPrompt = parts.join('\n');
|
|
242
|
+
return { systemPrompt, messages: this.workingMemory };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* 将当前任务记忆持久化为项目记忆条目(任务完成时调用)
|
|
246
|
+
*/
|
|
247
|
+
persistToProjectMemory(goal, tags = []) {
|
|
248
|
+
const entry = {
|
|
249
|
+
id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
250
|
+
goal,
|
|
251
|
+
decisions: this.taskMemory.flatMap((cp) => cp.decisions).slice(0, 10),
|
|
252
|
+
artifacts: [...new Set(this.taskMemory.flatMap((cp) => cp.artifacts))].slice(0, 20),
|
|
253
|
+
pendingIssues: this.taskMemory.flatMap((cp) => cp.pendingIssues).slice(0, 5),
|
|
254
|
+
userPreferences: [],
|
|
255
|
+
timestamp: new Date().toISOString(),
|
|
256
|
+
tags: tags.length > 0 ? tags : this.extractKeywords(goal),
|
|
257
|
+
};
|
|
258
|
+
this.projectMemory.push(entry);
|
|
259
|
+
this.saveProjectMemory();
|
|
260
|
+
this.stats.projectMemoryCount = this.projectMemory.length;
|
|
261
|
+
logger_1.logger.info('layered-memory: persisted to project memory', {
|
|
262
|
+
goal,
|
|
263
|
+
tags: entry.tags,
|
|
264
|
+
total: this.projectMemory.length,
|
|
265
|
+
});
|
|
266
|
+
return entry;
|
|
267
|
+
}
|
|
268
|
+
/** 清空当前会话的工作记忆和任务记忆(项目记忆保留) */
|
|
269
|
+
resetSession() {
|
|
270
|
+
this.workingMemory = [];
|
|
271
|
+
this.taskMemory = [];
|
|
272
|
+
this.currentTaskStartIdx = 0;
|
|
273
|
+
this.stats.workingMemoryCount = 0;
|
|
274
|
+
this.stats.taskMemoryCount = 0;
|
|
275
|
+
logger_1.logger.info('layered-memory: session reset');
|
|
276
|
+
}
|
|
277
|
+
/** 获取记忆统计 */
|
|
278
|
+
getStats() {
|
|
279
|
+
return { ...this.stats };
|
|
280
|
+
}
|
|
281
|
+
/** 确保目录存在 */
|
|
282
|
+
ensureDirs() {
|
|
283
|
+
try {
|
|
284
|
+
(0, fs_1.mkdirSync)(this.config.memoryDir, { recursive: true });
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
/* 目录创建失败忽略 */
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** 项目记忆文件路径 */
|
|
291
|
+
projectMemoryFile() {
|
|
292
|
+
return (0, path_1.join)(this.config.memoryDir, 'project-memory.json');
|
|
293
|
+
}
|
|
294
|
+
/** 加载项目记忆 */
|
|
295
|
+
loadProjectMemory() {
|
|
296
|
+
try {
|
|
297
|
+
const file = this.projectMemoryFile();
|
|
298
|
+
if (!(0, fs_1.existsSync)(file))
|
|
299
|
+
return;
|
|
300
|
+
const parsed = JSON.parse((0, fs_1.readFileSync)(file, 'utf8'));
|
|
301
|
+
if (Array.isArray(parsed)) {
|
|
302
|
+
this.projectMemory = parsed;
|
|
303
|
+
this.stats.projectMemoryCount = parsed.length;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch (e) {
|
|
307
|
+
logger_1.logger.warn('layered-memory: failed to load project memory', { error: e instanceof Error ? e.message : String(e) });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** 保存项目记忆 */
|
|
311
|
+
saveProjectMemory() {
|
|
312
|
+
try {
|
|
313
|
+
const file = this.projectMemoryFile();
|
|
314
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(file), { recursive: true });
|
|
315
|
+
// 只保留最近 100 条,防止文件过大
|
|
316
|
+
const toSave = this.projectMemory.slice(-100);
|
|
317
|
+
(0, fs_1.writeFileSync)(file, JSON.stringify(toSave, null, 2), 'utf8');
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
logger_1.logger.warn('layered-memory: failed to save project memory', { error: e instanceof Error ? e.message : String(e) });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
exports.LayeredMemory = LayeredMemory;
|
|
325
|
+
/** 便捷函数:创建分层记忆管理器 */
|
|
326
|
+
function createLayeredMemory(config) {
|
|
327
|
+
return new LayeredMemory(config);
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=layered-memory.js.map
|