@qlingzzy/qling 1.0.0 → 1.1.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/CHANGELOG.md +154 -0
- package/README.en.md +82 -17
- package/README.md +15 -7
- package/dist/agent/main-loop.d.ts +120 -0
- package/dist/agent/main-loop.d.ts.map +1 -0
- package/dist/agent/main-loop.js +279 -0
- package/dist/agent/subtask-parallel.d.ts +29 -0
- package/dist/agent/subtask-parallel.d.ts.map +1 -0
- package/dist/agent/subtask-parallel.js +107 -0
- package/dist/agent/subtask.d.ts +13 -0
- package/dist/agent/subtask.d.ts.map +1 -1
- package/dist/agent/subtask.js +79 -24
- package/dist/agent/system-prompt.d.ts +39 -0
- package/dist/agent/system-prompt.d.ts.map +1 -0
- package/dist/agent/system-prompt.js +89 -0
- package/dist/agent/tool-orchestrator.d.ts +66 -0
- package/dist/agent/tool-orchestrator.d.ts.map +1 -0
- package/dist/agent/tool-orchestrator.js +355 -0
- package/dist/agent-loop.d.ts +29 -16
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +262 -807
- package/dist/agents/roles.d.ts +57 -0
- package/dist/agents/roles.d.ts.map +1 -0
- package/dist/agents/roles.js +198 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +17 -3
- package/dist/commands/claude-style.d.ts.map +1 -1
- package/dist/commands/claude-style.js +19 -10
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +3 -2
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +6 -0
- package/dist/commands/mode.d.ts +16 -0
- package/dist/commands/mode.d.ts.map +1 -0
- package/dist/commands/mode.js +67 -0
- package/dist/commands/recover.d.ts +3 -0
- package/dist/commands/recover.d.ts.map +1 -0
- package/dist/commands/recover.js +69 -0
- package/dist/commands/runtime.d.ts +2 -0
- package/dist/commands/runtime.d.ts.map +1 -1
- package/dist/commands/runtime.js +2 -0
- package/dist/commands/trace.d.ts +3 -0
- package/dist/commands/trace.d.ts.map +1 -0
- package/dist/commands/trace.js +45 -0
- package/dist/commands/verify.js +2 -2
- package/dist/config-report.d.ts +0 -1
- package/dist/config-report.d.ts.map +1 -1
- package/dist/config-report.js +1 -2
- package/dist/config.d.ts +0 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -1
- package/dist/context-report.d.ts +13 -7
- package/dist/context-report.d.ts.map +1 -1
- package/dist/context-report.js +64 -61
- package/dist/context-tool-hygiene.d.ts +36 -0
- package/dist/context-tool-hygiene.d.ts.map +1 -0
- package/dist/context-tool-hygiene.js +125 -0
- package/dist/dashboard/client.d.ts +2 -0
- package/dist/dashboard/client.d.ts.map +1 -0
- package/dist/dashboard/client.js +305 -0
- package/dist/dashboard/model.d.ts +13 -0
- package/dist/dashboard/model.d.ts.map +1 -0
- package/dist/dashboard/model.js +112 -0
- package/dist/dashboard/page.d.ts +3 -0
- package/dist/dashboard/page.d.ts.map +1 -0
- package/dist/dashboard/page.js +204 -0
- package/dist/dashboard/types.d.ts +63 -0
- package/dist/dashboard/types.d.ts.map +1 -0
- package/dist/dashboard/types.js +1 -0
- package/dist/dashboard-server.d.ts +24 -4
- package/dist/dashboard-server.d.ts.map +1 -1
- package/dist/dashboard-server.js +397 -302
- package/dist/discovery-registry.d.ts +17 -3
- package/dist/discovery-registry.d.ts.map +1 -1
- package/dist/discovery-registry.js +78 -3
- package/dist/doctor.d.ts +8 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +116 -0
- package/dist/eval/llm-tasks.d.ts +5 -0
- package/dist/eval/llm-tasks.d.ts.map +1 -0
- package/dist/eval/llm-tasks.js +125 -0
- package/dist/eval/repo-tasks.d.ts +12 -0
- package/dist/eval/repo-tasks.d.ts.map +1 -0
- package/dist/eval/repo-tasks.js +220 -0
- package/dist/eval/runner.d.ts +3 -1
- package/dist/eval/runner.d.ts.map +1 -1
- package/dist/eval/runner.js +23 -4
- package/dist/eval/tasks.d.ts.map +1 -1
- package/dist/eval/tasks.js +186 -0
- package/dist/eval/types.d.ts +8 -5
- package/dist/eval/types.d.ts.map +1 -1
- package/dist/execution/event-bus.d.ts +44 -0
- package/dist/execution/event-bus.d.ts.map +1 -0
- package/dist/execution/event-bus.js +76 -0
- package/dist/execution/failure-classifier.d.ts +11 -0
- package/dist/execution/failure-classifier.d.ts.map +1 -0
- package/dist/execution/failure-classifier.js +66 -0
- package/dist/execution/progress-detector.d.ts +3 -0
- package/dist/execution/progress-detector.d.ts.map +1 -0
- package/dist/execution/progress-detector.js +23 -0
- package/dist/execution/recovery-controller.d.ts +24 -0
- package/dist/execution/recovery-controller.d.ts.map +1 -0
- package/dist/execution/recovery-controller.js +114 -0
- package/dist/execution/recovery-messages.d.ts +24 -0
- package/dist/execution/recovery-messages.d.ts.map +1 -0
- package/dist/execution/recovery-messages.js +48 -0
- package/dist/execution/recovery-metrics.d.ts +16 -0
- package/dist/execution/recovery-metrics.d.ts.map +1 -0
- package/dist/execution/recovery-metrics.js +73 -0
- package/dist/execution/recovery-strategy-planner.d.ts +6 -0
- package/dist/execution/recovery-strategy-planner.d.ts.map +1 -0
- package/dist/execution/recovery-strategy-planner.js +24 -0
- package/dist/execution/run-trace-store.d.ts +29 -0
- package/dist/execution/run-trace-store.d.ts.map +1 -0
- package/dist/execution/run-trace-store.js +140 -0
- package/dist/execution/staged-verifier.d.ts +33 -0
- package/dist/execution/staged-verifier.d.ts.map +1 -0
- package/dist/execution/staged-verifier.js +39 -0
- package/dist/execution/types.d.ts +58 -0
- package/dist/execution/types.d.ts.map +1 -0
- package/dist/execution/types.js +1 -0
- package/dist/execution/verification-loop.d.ts +58 -0
- package/dist/execution/verification-loop.d.ts.map +1 -0
- package/dist/execution/verification-loop.js +195 -0
- package/dist/execution/verification-stages.d.ts +17 -0
- package/dist/execution/verification-stages.d.ts.map +1 -0
- package/dist/execution/verification-stages.js +102 -0
- package/dist/help-topics.d.ts.map +1 -1
- package/dist/help-topics.js +11 -0
- package/dist/index.js +0 -8
- package/dist/lsp/ts-service.d.ts +36 -0
- package/dist/lsp/ts-service.d.ts.map +1 -0
- package/dist/lsp/ts-service.js +291 -0
- package/dist/memory/lifecycle.d.ts +19 -0
- package/dist/memory/lifecycle.d.ts.map +1 -0
- package/dist/memory/lifecycle.js +53 -0
- package/dist/memory.d.ts +0 -16
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +0 -36
- package/dist/metrics/collector.d.ts +7 -0
- package/dist/metrics/collector.d.ts.map +1 -1
- package/dist/metrics/collector.js +60 -0
- package/dist/mission/manager.d.ts +1 -0
- package/dist/mission/manager.d.ts.map +1 -1
- package/dist/mission/manager.js +9 -0
- package/dist/mission/progress-notify.d.ts +39 -0
- package/dist/mission/progress-notify.d.ts.map +1 -0
- package/dist/mission/progress-notify.js +386 -0
- package/dist/pipeline/hooks.d.ts +1 -1
- package/dist/pipeline/hooks.d.ts.map +1 -1
- package/dist/pipeline/hooks.js +1 -0
- package/dist/pipeline/sections.d.ts +8 -4
- package/dist/pipeline/sections.d.ts.map +1 -1
- package/dist/pipeline/sections.js +70 -27
- package/dist/pipeline/verification.d.ts +1 -0
- package/dist/pipeline/verification.d.ts.map +1 -1
- package/dist/pipeline/verification.js +10 -7
- package/dist/providers/llm-client.d.ts +38 -0
- package/dist/providers/llm-client.d.ts.map +1 -0
- package/dist/providers/llm-client.js +105 -0
- package/dist/sdk.d.ts +1 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +1 -0
- package/dist/session/durable-session-supervisor.d.ts.map +1 -1
- package/dist/session/durable-session-supervisor.js +13 -6
- package/dist/session/session-persistence.d.ts +29 -0
- package/dist/session/session-persistence.d.ts.map +1 -0
- package/dist/session/session-persistence.js +45 -0
- package/dist/session/session-scheduler.d.ts +8 -1
- package/dist/session/session-scheduler.d.ts.map +1 -1
- package/dist/session/session-scheduler.js +33 -4
- package/dist/session-task-report.d.ts +1 -0
- package/dist/session-task-report.d.ts.map +1 -1
- package/dist/session-task-report.js +2 -1
- package/dist/shortcuts.d.ts.map +1 -1
- package/dist/shortcuts.js +1 -0
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +10 -0
- package/dist/skills/security-scan.d.ts +15 -0
- package/dist/skills/security-scan.d.ts.map +1 -0
- package/dist/skills/security-scan.js +95 -0
- package/dist/skills/types.d.ts +2 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/statusline.d.ts +3 -3
- package/dist/statusline.d.ts.map +1 -1
- package/dist/statusline.js +9 -17
- package/dist/token-usage.d.ts +27 -0
- package/dist/token-usage.d.ts.map +1 -0
- package/dist/token-usage.js +107 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +5 -3
- package/dist/tools/browser-act-session.d.ts +48 -0
- package/dist/tools/browser-act-session.d.ts.map +1 -0
- package/dist/tools/browser-act-session.js +168 -0
- package/dist/tools/browser-act.d.ts +14 -0
- package/dist/tools/browser-act.d.ts.map +1 -0
- package/dist/tools/browser-act.js +297 -0
- package/dist/tools/code-symbols.d.ts +35 -0
- package/dist/tools/code-symbols.d.ts.map +1 -0
- package/dist/tools/code-symbols.js +257 -0
- package/dist/tools/index.d.ts +4 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +22 -2
- package/dist/tools/lsp.d.ts +13 -0
- package/dist/tools/lsp.d.ts.map +1 -0
- package/dist/tools/lsp.js +136 -0
- package/dist/tools/patch.d.ts +5 -0
- package/dist/tools/patch.d.ts.map +1 -1
- package/dist/tools/patch.js +25 -4
- package/dist/tools/search.d.ts +7 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +20 -3
- package/dist/tools/skill.d.ts +2 -0
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +47 -14
- package/dist/tools/subtask.d.ts +3 -1
- package/dist/tools/subtask.d.ts.map +1 -1
- package/dist/tools/subtask.js +151 -56
- package/dist/tui/shell.d.ts +12 -0
- package/dist/tui/shell.d.ts.map +1 -1
- package/dist/tui/shell.js +36 -3
- package/dist/tui/streaming-repl.d.ts +1 -0
- package/dist/tui/streaming-repl.d.ts.map +1 -1
- package/dist/tui/streaming-repl.js +27 -4
- package/dist/tui/streaming-tui.d.ts +10 -0
- package/dist/tui/streaming-tui.d.ts.map +1 -1
- package/dist/tui/streaming-tui.js +70 -12
- package/dist/types.d.ts +0 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/workflow-runtime.d.ts.map +1 -1
- package/dist/workflow-runtime.js +10 -2
- package/dist/workflow-types.d.ts +2 -0
- package/dist/workflow-types.d.ts.map +1 -1
- package/docs/install.md +29 -8
- package/docs/skills.md +56 -7
- package/docs/web-routing.md +83 -0
- package/package.json +18 -4
- package/scripts/dep-layers.mjs +275 -0
- package/scripts/eval-llm.mjs +27 -0
- package/scripts/eval-recovery.mjs +101 -0
- package/scripts/eval-tasks.mjs +20 -0
- package/scripts/validate-packaging.mjs +51 -0
- package/skills/examples/README.md +23 -0
- package/skills/examples/add-function/SKILL.md +31 -0
- package/skills/examples/fix-failing-test/SKILL.md +32 -0
- package/skills/examples/pr-summary/SKILL.md +34 -0
- package/skills/lifecycle-build/SKILL.md +22 -0
- package/skills/lifecycle-plan/SKILL.md +32 -0
- package/skills/lifecycle-review/SKILL.md +25 -0
- package/skills/lifecycle-ship/SKILL.md +22 -0
- package/skills/lifecycle-spec/SKILL.md +24 -0
- package/skills/lifecycle-test/SKILL.md +21 -0
- package/skills/opencli/SKILL.md +222 -0
- package/skills/qling.md +14 -3
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// Phase 4.3 — 可选 TypeScript LanguageService(进程内,非 stdio LSP)
|
|
3
|
+
// 启用:QLING_LSP=1;依赖可选 peer/dev 的 typescript 包
|
|
4
|
+
// ============================================================
|
|
5
|
+
import { readFileSync, existsSync, statSync } from "fs";
|
|
6
|
+
import { relative, resolve, extname } from "path";
|
|
7
|
+
export function isLspEnabled(env = process.env) {
|
|
8
|
+
const raw = String(env.QLING_LSP ?? "").trim().toLowerCase();
|
|
9
|
+
return raw === "1" || raw === "true" || raw === "on" || raw === "yes";
|
|
10
|
+
}
|
|
11
|
+
export async function loadTypeScript() {
|
|
12
|
+
try {
|
|
13
|
+
const mod = await import("typescript");
|
|
14
|
+
return mod.default ?? mod;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function isTsLike(file) {
|
|
21
|
+
const ext = extname(file).toLowerCase();
|
|
22
|
+
return [".ts", ".tsx", ".js", ".jsx", ".mts", ".cts", ".mjs", ".cjs"].includes(ext);
|
|
23
|
+
}
|
|
24
|
+
function lineCharToPos(ts, content, line, character) {
|
|
25
|
+
// line/character 1-based for agent UX
|
|
26
|
+
const l = Math.max(1, line) - 1;
|
|
27
|
+
const c = Math.max(1, character) - 1;
|
|
28
|
+
return ts.getPositionOfLineAndCharacter(ts.createSourceFile("tmp.ts", content, ts.ScriptTarget.Latest, true), l, c);
|
|
29
|
+
}
|
|
30
|
+
function posToLineChar(ts, content, pos) {
|
|
31
|
+
const sf = ts.createSourceFile("tmp.ts", content, ts.ScriptTarget.Latest, true);
|
|
32
|
+
const lc = ts.getLineAndCharacterOfPosition(sf, pos);
|
|
33
|
+
return { line: lc.line + 1, character: lc.character + 1 };
|
|
34
|
+
}
|
|
35
|
+
const cache = new Map();
|
|
36
|
+
function createLanguageService(ts, workspaceDir) {
|
|
37
|
+
const root = resolve(workspaceDir);
|
|
38
|
+
const configPath = ts.findConfigFile(root, ts.sys.fileExists.bind(ts.sys), "tsconfig.json");
|
|
39
|
+
let options = {
|
|
40
|
+
allowJs: true,
|
|
41
|
+
checkJs: false,
|
|
42
|
+
target: ts.ScriptTarget.ES2022,
|
|
43
|
+
module: ts.ModuleKind.ESNext,
|
|
44
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
45
|
+
jsx: ts.JsxEmit.ReactJSX,
|
|
46
|
+
skipLibCheck: true,
|
|
47
|
+
esModuleInterop: true,
|
|
48
|
+
};
|
|
49
|
+
let rootFileNames = [];
|
|
50
|
+
if (configPath) {
|
|
51
|
+
const read = ts.readConfigFile(configPath, ts.sys.readFile.bind(ts.sys));
|
|
52
|
+
const parsed = ts.parseJsonConfigFileContent(read.config, ts.sys, resolve(configPath, ".."));
|
|
53
|
+
options = parsed.options;
|
|
54
|
+
rootFileNames = parsed.fileNames;
|
|
55
|
+
}
|
|
56
|
+
const fileExists = (f) => existsSync(f);
|
|
57
|
+
const readFile = (f) => {
|
|
58
|
+
try {
|
|
59
|
+
return readFileSync(f, "utf8");
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
// 确保打开的文件在 project 中
|
|
66
|
+
const extraFiles = new Set();
|
|
67
|
+
const host = {
|
|
68
|
+
getCompilationSettings: () => options,
|
|
69
|
+
getScriptFileNames: () => {
|
|
70
|
+
const set = new Set(rootFileNames);
|
|
71
|
+
for (const f of extraFiles)
|
|
72
|
+
set.add(f);
|
|
73
|
+
return Array.from(set);
|
|
74
|
+
},
|
|
75
|
+
getScriptVersion: (fileName) => {
|
|
76
|
+
try {
|
|
77
|
+
const stat = statSync(fileName);
|
|
78
|
+
return `${stat.mtimeMs}:${stat.size}`;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return "0";
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
getScriptSnapshot: (fileName) => {
|
|
85
|
+
const text = readFile(fileName);
|
|
86
|
+
if (text === undefined)
|
|
87
|
+
return undefined;
|
|
88
|
+
return ts.ScriptSnapshot.fromString(text);
|
|
89
|
+
},
|
|
90
|
+
getCurrentDirectory: () => root,
|
|
91
|
+
getDefaultLibFileName: (opts) => ts.getDefaultLibFilePath(opts),
|
|
92
|
+
fileExists,
|
|
93
|
+
readFile,
|
|
94
|
+
readDirectory: ts.sys.readDirectory,
|
|
95
|
+
directoryExists: ts.sys.directoryExists,
|
|
96
|
+
getDirectories: ts.sys.getDirectories,
|
|
97
|
+
};
|
|
98
|
+
const service = ts.createLanguageService(host, ts.createDocumentRegistry());
|
|
99
|
+
return {
|
|
100
|
+
ts,
|
|
101
|
+
service,
|
|
102
|
+
workspaceDir: root,
|
|
103
|
+
dispose: () => {
|
|
104
|
+
service.dispose();
|
|
105
|
+
cache.delete(root);
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export function getTsService(ts, workspaceDir) {
|
|
110
|
+
const root = resolve(workspaceDir);
|
|
111
|
+
let bundle = cache.get(root);
|
|
112
|
+
if (!bundle) {
|
|
113
|
+
bundle = createLanguageService(ts, root);
|
|
114
|
+
cache.set(root, bundle);
|
|
115
|
+
}
|
|
116
|
+
return bundle;
|
|
117
|
+
}
|
|
118
|
+
export function resetTsServiceCache() {
|
|
119
|
+
for (const b of cache.values()) {
|
|
120
|
+
try {
|
|
121
|
+
b.service.dispose();
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// ignore
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
cache.clear();
|
|
128
|
+
}
|
|
129
|
+
function rel(workspaceDir, abs) {
|
|
130
|
+
const r = relative(workspaceDir, abs).replace(/\\/g, "/");
|
|
131
|
+
return r || abs;
|
|
132
|
+
}
|
|
133
|
+
export function lspDefinition(bundle, absFile, line, character) {
|
|
134
|
+
const { ts, service, workspaceDir } = bundle;
|
|
135
|
+
if (!isTsLike(absFile) || !existsSync(absFile))
|
|
136
|
+
return [];
|
|
137
|
+
const content = readFileSync(absFile, "utf8");
|
|
138
|
+
const pos = lineCharToPos(ts, content, line, character);
|
|
139
|
+
const defs = service.getDefinitionAtPosition(absFile, pos) ?? [];
|
|
140
|
+
return defs.map((d) => {
|
|
141
|
+
const fileText = existsSync(d.fileName) ? readFileSync(d.fileName, "utf8") : "";
|
|
142
|
+
const lc = fileText
|
|
143
|
+
? posToLineChar(ts, fileText, d.textSpan.start)
|
|
144
|
+
: { line: 1, character: 1 };
|
|
145
|
+
const preview = fileText
|
|
146
|
+
? fileText.slice(d.textSpan.start, d.textSpan.start + Math.min(d.textSpan.length, 120))
|
|
147
|
+
: undefined;
|
|
148
|
+
return {
|
|
149
|
+
file: rel(workspaceDir, d.fileName),
|
|
150
|
+
line: lc.line,
|
|
151
|
+
character: lc.character,
|
|
152
|
+
preview: preview?.replace(/\s+/g, " ").trim(),
|
|
153
|
+
};
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
export function lspHover(bundle, absFile, line, character) {
|
|
157
|
+
const { ts, service } = bundle;
|
|
158
|
+
if (!isTsLike(absFile) || !existsSync(absFile))
|
|
159
|
+
return null;
|
|
160
|
+
const content = readFileSync(absFile, "utf8");
|
|
161
|
+
const pos = lineCharToPos(ts, content, line, character);
|
|
162
|
+
const info = service.getQuickInfoAtPosition(absFile, pos);
|
|
163
|
+
if (!info)
|
|
164
|
+
return null;
|
|
165
|
+
const display = ts.displayPartsToString(info.displayParts ?? []);
|
|
166
|
+
const documentation = ts.displayPartsToString(info.documentation ?? []);
|
|
167
|
+
return { display, documentation };
|
|
168
|
+
}
|
|
169
|
+
export function lspReferences(bundle, absFile, line, character, limit = 30) {
|
|
170
|
+
const { ts, service, workspaceDir } = bundle;
|
|
171
|
+
if (!isTsLike(absFile) || !existsSync(absFile))
|
|
172
|
+
return [];
|
|
173
|
+
const content = readFileSync(absFile, "utf8");
|
|
174
|
+
const pos = lineCharToPos(ts, content, line, character);
|
|
175
|
+
const refs = service.findReferences(absFile, pos)?.flatMap((r) => r.references) ?? [];
|
|
176
|
+
return refs.slice(0, limit).map((ref) => {
|
|
177
|
+
const fileText = existsSync(ref.fileName) ? readFileSync(ref.fileName, "utf8") : "";
|
|
178
|
+
const lc = fileText
|
|
179
|
+
? posToLineChar(ts, fileText, ref.textSpan.start)
|
|
180
|
+
: { line: 1, character: 1 };
|
|
181
|
+
return {
|
|
182
|
+
file: rel(workspaceDir, ref.fileName),
|
|
183
|
+
line: lc.line,
|
|
184
|
+
character: lc.character,
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export function lspDocumentSymbols(bundle, absFile, limit = 80) {
|
|
189
|
+
const { ts, service } = bundle;
|
|
190
|
+
if (!isTsLike(absFile) || !existsSync(absFile))
|
|
191
|
+
return [];
|
|
192
|
+
const nav = service.getNavigationBarItems(absFile);
|
|
193
|
+
const out = [];
|
|
194
|
+
const walk = (items, depth = 0) => {
|
|
195
|
+
for (const item of items) {
|
|
196
|
+
if (out.length >= limit)
|
|
197
|
+
return;
|
|
198
|
+
const span = item.spans[0];
|
|
199
|
+
if (span) {
|
|
200
|
+
const content = readFileSync(absFile, "utf8");
|
|
201
|
+
const lc = posToLineChar(ts, content, span.start);
|
|
202
|
+
out.push({
|
|
203
|
+
name: item.text,
|
|
204
|
+
kind: String(item.kind),
|
|
205
|
+
line: lc.line,
|
|
206
|
+
character: lc.character,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (item.childItems?.length)
|
|
210
|
+
walk(item.childItems, depth + 1);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
walk(nav);
|
|
214
|
+
return out;
|
|
215
|
+
}
|
|
216
|
+
/** 无 tsconfig 时:为单文件创建临时 service */
|
|
217
|
+
export function getOrCreateServiceForFile(ts, workspaceDir, absFile) {
|
|
218
|
+
const root = resolve(workspaceDir);
|
|
219
|
+
const existing = cache.get(root);
|
|
220
|
+
if (existing)
|
|
221
|
+
return existing;
|
|
222
|
+
// 若有 tsconfig,正常创建
|
|
223
|
+
const configPath = ts.findConfigFile(root, ts.sys.fileExists.bind(ts.sys), "tsconfig.json");
|
|
224
|
+
if (configPath) {
|
|
225
|
+
return getTsService(ts, root);
|
|
226
|
+
}
|
|
227
|
+
// 单文件项目
|
|
228
|
+
const file = resolve(absFile);
|
|
229
|
+
const options = {
|
|
230
|
+
allowJs: true,
|
|
231
|
+
target: ts.ScriptTarget.ES2022,
|
|
232
|
+
module: ts.ModuleKind.ESNext,
|
|
233
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
234
|
+
skipLibCheck: true,
|
|
235
|
+
};
|
|
236
|
+
const host = {
|
|
237
|
+
getCompilationSettings: () => options,
|
|
238
|
+
getScriptFileNames: () => [file],
|
|
239
|
+
getScriptVersion: () => {
|
|
240
|
+
try {
|
|
241
|
+
return String(statSync(file).mtimeMs);
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return "0";
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
getScriptSnapshot: (fileName) => {
|
|
248
|
+
try {
|
|
249
|
+
return ts.ScriptSnapshot.fromString(readFileSync(fileName, "utf8"));
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return undefined;
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
getCurrentDirectory: () => root,
|
|
256
|
+
getDefaultLibFileName: (opts) => ts.getDefaultLibFilePath(opts),
|
|
257
|
+
fileExists: (f) => existsSync(f),
|
|
258
|
+
readFile: (f) => {
|
|
259
|
+
try {
|
|
260
|
+
return readFileSync(f, "utf8");
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
readDirectory: ts.sys.readDirectory,
|
|
267
|
+
directoryExists: ts.sys.directoryExists,
|
|
268
|
+
getDirectories: ts.sys.getDirectories,
|
|
269
|
+
};
|
|
270
|
+
const service = ts.createLanguageService(host, ts.createDocumentRegistry());
|
|
271
|
+
const bundle = {
|
|
272
|
+
ts,
|
|
273
|
+
service,
|
|
274
|
+
workspaceDir: root,
|
|
275
|
+
dispose: () => {
|
|
276
|
+
service.dispose();
|
|
277
|
+
cache.delete(root + "::" + file);
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
// 使用 workspace key 仍可能冲突;用 root 即可覆盖无 tsconfig 场景
|
|
281
|
+
cache.set(root, bundle);
|
|
282
|
+
return bundle;
|
|
283
|
+
}
|
|
284
|
+
export function resolveAbsFile(workspaceDir, filePath) {
|
|
285
|
+
if (!filePath)
|
|
286
|
+
return "";
|
|
287
|
+
if (existsSync(filePath) && (filePath.includes("/") || filePath.includes("\\") || /^[A-Za-z]:/.test(filePath))) {
|
|
288
|
+
return resolve(filePath);
|
|
289
|
+
}
|
|
290
|
+
return resolve(workspaceDir, filePath);
|
|
291
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Message } from "../types.js";
|
|
2
|
+
import { MemoryStore } from "../memory.js";
|
|
3
|
+
export interface AutoDreamOptions {
|
|
4
|
+
messages: Message[];
|
|
5
|
+
turnCount: number;
|
|
6
|
+
memoryStore: MemoryStore;
|
|
7
|
+
memoryDreamLLMEnabled: boolean;
|
|
8
|
+
memoryDreamTurnThreshold: number;
|
|
9
|
+
memoryMaxEntries: number;
|
|
10
|
+
model: string;
|
|
11
|
+
apiKey: string;
|
|
12
|
+
endpoint: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Run one auto-dream pass. Returns number of changed memory entries.
|
|
16
|
+
* Failures are swallowed by the caller if desired; this function rethrows only unexpected errors.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runAutoDream(options: AutoDreamOptions): Promise<number>;
|
|
19
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/memory/lifecycle.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAwB,MAAM,cAAc,CAAC;AAGjE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,MAAM,CAAC;IACjC,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkD7E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// 记忆生命周期(从 AgentLoop 抽出):auto-dream 整理
|
|
3
|
+
// domain 层 — 不依赖 agent-loop / TUI / CLI
|
|
4
|
+
// ============================================================
|
|
5
|
+
import { extractDreamMemories } from "../memory.js";
|
|
6
|
+
import { extractDreamMemoriesLLM } from "./memory-llm-dream.js";
|
|
7
|
+
/**
|
|
8
|
+
* Run one auto-dream pass. Returns number of changed memory entries.
|
|
9
|
+
* Failures are swallowed by the caller if desired; this function rethrows only unexpected errors.
|
|
10
|
+
*/
|
|
11
|
+
export async function runAutoDream(options) {
|
|
12
|
+
const transcript = options.messages
|
|
13
|
+
.filter((m) => m.role === "user" || m.role === "assistant")
|
|
14
|
+
.map((m) => m.content);
|
|
15
|
+
let memories;
|
|
16
|
+
let changedCount = 0;
|
|
17
|
+
if (options.memoryDreamLLMEnabled) {
|
|
18
|
+
memories = await extractDreamMemoriesLLM(transcript, options.turnCount, {
|
|
19
|
+
enabled: true,
|
|
20
|
+
model: options.model,
|
|
21
|
+
maxTokens: 300,
|
|
22
|
+
apiKey: options.apiKey,
|
|
23
|
+
endpoint: options.endpoint || "https://api.deepseek.com",
|
|
24
|
+
});
|
|
25
|
+
const { consolidateMemoriesLLM } = await import("./consolidation.js");
|
|
26
|
+
const existing = options.memoryStore.exportPersisted();
|
|
27
|
+
const ops = await consolidateMemoriesLLM(memories, existing, {
|
|
28
|
+
apiKey: options.apiKey,
|
|
29
|
+
endpoint: options.endpoint || "https://api.deepseek.com",
|
|
30
|
+
model: options.model,
|
|
31
|
+
});
|
|
32
|
+
options.memoryStore.applyOperations(ops, "workspace");
|
|
33
|
+
changedCount = ops.filter((op) => op.action !== "NOOP").length;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
memories = await extractDreamMemories({ turnCount: options.turnCount, transcript }, {
|
|
37
|
+
enabled: true,
|
|
38
|
+
turnThreshold: options.memoryDreamTurnThreshold,
|
|
39
|
+
transcriptWindow: 4,
|
|
40
|
+
});
|
|
41
|
+
const existingContents = new Set(options.memoryStore.exportPersisted().map((e) => e.content));
|
|
42
|
+
const newMems = memories.filter((m) => !existingContents.has(m));
|
|
43
|
+
for (const mem of newMems) {
|
|
44
|
+
options.memoryStore.add(mem, "auto-dream", 0.6);
|
|
45
|
+
}
|
|
46
|
+
changedCount = newMems.length;
|
|
47
|
+
}
|
|
48
|
+
if (changedCount > 0) {
|
|
49
|
+
options.memoryStore.compactPersisted(options.memoryMaxEntries);
|
|
50
|
+
await options.memoryStore.saveToDisk();
|
|
51
|
+
}
|
|
52
|
+
return changedCount;
|
|
53
|
+
}
|
package/dist/memory.d.ts
CHANGED
|
@@ -129,21 +129,5 @@ interface DreamConfig {
|
|
|
129
129
|
transcriptWindow?: number;
|
|
130
130
|
}
|
|
131
131
|
export declare function extractDreamMemories(ctx: DreamContext, config: DreamConfig): Promise<string[]>;
|
|
132
|
-
export declare class TokenBudgetManager {
|
|
133
|
-
maxTokens: number;
|
|
134
|
-
nudgeThreshold: number;
|
|
135
|
-
usedTokens: number;
|
|
136
|
-
constructor(maxTokens: number, nudgeThreshold?: number, usedTokens?: number);
|
|
137
|
-
addUsage(tokens: number): void;
|
|
138
|
-
syncUsage(actualTokens: number): void;
|
|
139
|
-
reset(): void;
|
|
140
|
-
getRemaining(): number;
|
|
141
|
-
getRemainingPct(): number;
|
|
142
|
-
shouldNudge(): boolean;
|
|
143
|
-
buildNudgeMessage(): string;
|
|
144
|
-
estimateMessagesCost(messages: {
|
|
145
|
-
content: string;
|
|
146
|
-
}[]): number;
|
|
147
|
-
}
|
|
148
132
|
export {};
|
|
149
133
|
//# sourceMappingURL=memory.d.ts.map
|
package/dist/memory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/memory.js
CHANGED
|
@@ -594,39 +594,3 @@ export async function extractDreamMemories(ctx, config) {
|
|
|
594
594
|
}
|
|
595
595
|
return Array.from(new Set(memories));
|
|
596
596
|
}
|
|
597
|
-
// --- Token Budget Manager ---
|
|
598
|
-
export class TokenBudgetManager {
|
|
599
|
-
maxTokens;
|
|
600
|
-
nudgeThreshold;
|
|
601
|
-
usedTokens;
|
|
602
|
-
constructor(maxTokens, nudgeThreshold = 0.2, usedTokens = 0) {
|
|
603
|
-
this.maxTokens = maxTokens;
|
|
604
|
-
this.nudgeThreshold = nudgeThreshold;
|
|
605
|
-
this.usedTokens = usedTokens;
|
|
606
|
-
}
|
|
607
|
-
addUsage(tokens) {
|
|
608
|
-
this.usedTokens += tokens;
|
|
609
|
-
}
|
|
610
|
-
syncUsage(actualTokens) {
|
|
611
|
-
this.usedTokens = actualTokens;
|
|
612
|
-
}
|
|
613
|
-
reset() {
|
|
614
|
-
this.usedTokens = 0;
|
|
615
|
-
}
|
|
616
|
-
getRemaining() {
|
|
617
|
-
return this.maxTokens - this.usedTokens;
|
|
618
|
-
}
|
|
619
|
-
getRemainingPct() {
|
|
620
|
-
return this.getRemaining() / this.maxTokens;
|
|
621
|
-
}
|
|
622
|
-
shouldNudge() {
|
|
623
|
-
return this.getRemainingPct() < this.nudgeThreshold;
|
|
624
|
-
}
|
|
625
|
-
buildNudgeMessage() {
|
|
626
|
-
const pct = Math.round(this.getRemainingPct() * 100);
|
|
627
|
-
return "Token 预算即将耗尽(剩余 " + pct + "%),请精简回复,减少工具调用频率。";
|
|
628
|
-
}
|
|
629
|
-
estimateMessagesCost(messages) {
|
|
630
|
-
return messages.reduce((sum, m) => sum + m.content.length * 4, 0);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
@@ -9,6 +9,13 @@ export declare class MetricsCollector {
|
|
|
9
9
|
record(event: Omit<MetricEvent, "ts" | "session_id">): void;
|
|
10
10
|
flush(): Promise<void>;
|
|
11
11
|
query(query: MetricsQuery): Promise<MetricEvent[]>;
|
|
12
|
+
queryRecent(options: MetricsQuery & {
|
|
13
|
+
maxScanBytes?: number;
|
|
14
|
+
}): Promise<{
|
|
15
|
+
events: MetricEvent[];
|
|
16
|
+
scannedBytes: number;
|
|
17
|
+
truncated: boolean;
|
|
18
|
+
}>;
|
|
12
19
|
startAutoFlush(): ReturnType<typeof setInterval>;
|
|
13
20
|
stopAutoFlush(timer: ReturnType<typeof setInterval>): void;
|
|
14
21
|
purgeOldEntries(retentionDays: number): Promise<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/metrics/collector.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAS;gBAEpB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAE,MAAe;IAM7E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,IAAI;IAYrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/metrics/collector.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAS;gBAEpB,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAE,MAAe;IAM7E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,IAAI;IAYrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBtB,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA6BlD,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG;QACxC,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IA6DhF,cAAc,IAAI,UAAU,CAAC,OAAO,WAAW,CAAC;IAMhD,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,GAAG,IAAI;IAIpD,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuC7D,OAAO,CAAC,YAAY;CAOrB"}
|
|
@@ -75,6 +75,66 @@ export class MetricsCollector {
|
|
|
75
75
|
return results.slice(0, query.limit);
|
|
76
76
|
return results;
|
|
77
77
|
}
|
|
78
|
+
async queryRecent(options) {
|
|
79
|
+
const limit = Math.min(100, Math.max(1, Math.floor(options.limit ?? 20)));
|
|
80
|
+
const maxScanBytes = Math.min(8 * 1024 * 1024, Math.max(1024, Math.floor(options.maxScanBytes ?? 1024 * 1024)));
|
|
81
|
+
const events = this.buffer
|
|
82
|
+
.filter((event) => this.matchesQuery(event, options))
|
|
83
|
+
.sort((a, b) => b.ts - a.ts);
|
|
84
|
+
let scannedBytes = 0;
|
|
85
|
+
let truncated = false;
|
|
86
|
+
if (events.length < limit && fsSync.existsSync(this.metricsDir)) {
|
|
87
|
+
const files = (await fs.readdir(this.metricsDir))
|
|
88
|
+
.filter((file) => file.startsWith("metrics-") && file.endsWith(".jsonl"))
|
|
89
|
+
.sort()
|
|
90
|
+
.reverse();
|
|
91
|
+
for (const file of files) {
|
|
92
|
+
if (events.length >= limit || scannedBytes >= maxScanBytes)
|
|
93
|
+
break;
|
|
94
|
+
const filePath = path.join(this.metricsDir, file);
|
|
95
|
+
const stat = await fs.stat(filePath);
|
|
96
|
+
const bytesToRead = Math.min(stat.size, maxScanBytes - scannedBytes);
|
|
97
|
+
if (bytesToRead <= 0)
|
|
98
|
+
break;
|
|
99
|
+
const start = Math.max(0, stat.size - bytesToRead);
|
|
100
|
+
const handle = await fs.open(filePath, "r");
|
|
101
|
+
try {
|
|
102
|
+
const buffer = Buffer.alloc(bytesToRead);
|
|
103
|
+
const { bytesRead } = await handle.read(buffer, 0, bytesToRead, start);
|
|
104
|
+
scannedBytes += bytesRead;
|
|
105
|
+
let text = buffer.subarray(0, bytesRead).toString("utf-8");
|
|
106
|
+
if (start > 0) {
|
|
107
|
+
const firstBreak = text.indexOf("\n");
|
|
108
|
+
text = firstBreak >= 0 ? text.slice(firstBreak + 1) : "";
|
|
109
|
+
truncated = true;
|
|
110
|
+
}
|
|
111
|
+
const lines = text.split(/\r?\n/).filter(Boolean).reverse();
|
|
112
|
+
for (const line of lines) {
|
|
113
|
+
if (events.length >= limit)
|
|
114
|
+
break;
|
|
115
|
+
try {
|
|
116
|
+
const event = JSON.parse(line);
|
|
117
|
+
if (this.matchesQuery(event, options))
|
|
118
|
+
events.push(event);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Ignore incomplete or invalid JSONL records.
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
await handle.close();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (scannedBytes >= maxScanBytes)
|
|
130
|
+
truncated = true;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
events: events.sort((a, b) => b.ts - a.ts).slice(0, limit),
|
|
134
|
+
scannedBytes,
|
|
135
|
+
truncated,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
78
138
|
startAutoFlush() {
|
|
79
139
|
return setInterval(() => {
|
|
80
140
|
this.flush().catch(() => { });
|
|
@@ -11,6 +11,7 @@ export declare class MissionManager {
|
|
|
11
11
|
getMission(id: string): Mission | undefined;
|
|
12
12
|
getMissionOrThrow(id: string): Mission;
|
|
13
13
|
listMissions(): Mission[];
|
|
14
|
+
refresh(): Promise<void>;
|
|
14
15
|
getMissionLogs(id: string): Promise<MissionEvent[]>;
|
|
15
16
|
appendLog(id: string, message: string, meta?: Record<string, unknown>): Promise<void>;
|
|
16
17
|
pauseMission(id: string, reason?: string): Promise<Mission>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/mission/manager.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/mission/manager.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAMlE,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAmC;gBAEvC,QAAQ,EAAE,MAAM;IAItB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAO,GACzC,OAAO,CAAC,OAAO,CAAC;IAmCb,YAAY,CAChB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,aAAa,EACrB,KAAK,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EACxB,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,OAAO,CAAC;IA6BnB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI3C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQtC,YAAY,IAAI,OAAO,EAAE;IAKnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAanD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBzF,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3D,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5D,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkB5D,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAyBlC,WAAW;YAKX,YAAY;IAe1B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,YAAY;YAIN,WAAW;YAKX,sBAAsB;IAiCpC,OAAO,CAAC,kBAAkB;CAM3B"}
|
package/dist/mission/manager.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import * as fs from "fs/promises";
|
|
6
6
|
import * as path from "path";
|
|
7
7
|
import { existsSync } from "fs";
|
|
8
|
+
import { notifyMissionLog, notifyMissionProgress } from "./progress-notify.js";
|
|
8
9
|
const TERMINAL_STATUSES = new Set(["succeeded", "failed", "canceled"]);
|
|
9
10
|
const PAUSABLE_STATUSES = new Set(["queued", "running", "blocked"]);
|
|
10
11
|
export class MissionManager {
|
|
@@ -77,6 +78,8 @@ export class MissionManager {
|
|
|
77
78
|
...meta,
|
|
78
79
|
},
|
|
79
80
|
});
|
|
81
|
+
// Phase 3.5: 可选 Telegram/Slack 进度推送(失败不阻断使命)
|
|
82
|
+
void notifyMissionProgress(mission, previousStatus, status).catch(() => undefined);
|
|
80
83
|
return mission;
|
|
81
84
|
}
|
|
82
85
|
getMission(id) {
|
|
@@ -93,6 +96,10 @@ export class MissionManager {
|
|
|
93
96
|
return Array.from(this.missions.values())
|
|
94
97
|
.sort((a, b) => b.createdAt - a.createdAt);
|
|
95
98
|
}
|
|
99
|
+
async refresh() {
|
|
100
|
+
this.missions.clear();
|
|
101
|
+
await this.loadMissions();
|
|
102
|
+
}
|
|
96
103
|
async getMissionLogs(id) {
|
|
97
104
|
this.getMissionOrThrow(id);
|
|
98
105
|
const filePath = this.getEventPath(id);
|
|
@@ -118,6 +125,8 @@ export class MissionManager {
|
|
|
118
125
|
...meta,
|
|
119
126
|
},
|
|
120
127
|
});
|
|
128
|
+
// 里程碑日志可选推送(QLING_MISSION_NOTIFY_LOGS,默认 milestone)
|
|
129
|
+
void notifyMissionLog(mission, message).catch(() => undefined);
|
|
121
130
|
}
|
|
122
131
|
async pauseMission(id, reason) {
|
|
123
132
|
return this.applyControlTransition(id, "pause", "paused", PAUSABLE_STATUSES, reason);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Mission, MissionStatus } from "./types.js";
|
|
2
|
+
export type MissionNotifyEnv = NodeJS.ProcessEnv | Record<string, string | undefined>;
|
|
3
|
+
export declare function isMissionNotifyEnabled(env?: MissionNotifyEnv): boolean;
|
|
4
|
+
export declare function resolveNotifyStyle(env?: MissionNotifyEnv): "plain" | "rich";
|
|
5
|
+
/** 使命日志推送策略:off | milestone(默认)| all */
|
|
6
|
+
export type MissionLogNotifyMode = "off" | "milestone" | "all";
|
|
7
|
+
export declare function resolveMissionLogNotifyMode(env?: MissionNotifyEnv): MissionLogNotifyMode;
|
|
8
|
+
/**
|
|
9
|
+
* 是否应对本条使命日志发通道通知。
|
|
10
|
+
*/
|
|
11
|
+
export declare function shouldNotifyMissionLog(message: string, env?: MissionNotifyEnv): boolean;
|
|
12
|
+
export declare function formatMissionLogMessage(mission: Pick<Mission, "id" | "name" | "status">, message: string): string;
|
|
13
|
+
export declare function statusEmoji(status: MissionStatus): string;
|
|
14
|
+
export declare function formatMissionProgressMessage(mission: Pick<Mission, "id" | "name" | "description" | "status" | "error">, from: MissionStatus | null, to: MissionStatus): string;
|
|
15
|
+
/** Telegram HTML(需 escape) */
|
|
16
|
+
export declare function formatMissionProgressTelegramHtml(mission: Pick<Mission, "id" | "name" | "description" | "status" | "error">, from: MissionStatus | null, to: MissionStatus): string;
|
|
17
|
+
/** Slack Block Kit 最小卡片 */
|
|
18
|
+
export declare function formatMissionProgressSlackBlocks(mission: Pick<Mission, "id" | "name" | "description" | "status" | "error">, from: MissionStatus | null, to: MissionStatus): {
|
|
19
|
+
text: string;
|
|
20
|
+
blocks: unknown[];
|
|
21
|
+
};
|
|
22
|
+
export interface NotifyDispatchResult {
|
|
23
|
+
attempted: boolean;
|
|
24
|
+
telegram: "sent" | "skipped" | "error";
|
|
25
|
+
slack: "sent" | "skipped" | "error";
|
|
26
|
+
detail: string;
|
|
27
|
+
style: "plain" | "rich";
|
|
28
|
+
}
|
|
29
|
+
export declare function assertSlackResponseOk(data: unknown): void;
|
|
30
|
+
/**
|
|
31
|
+
* 向已配置的 Telegram / Slack 发送使命进度(失败不抛出)。
|
|
32
|
+
*/
|
|
33
|
+
export declare function notifyMissionProgress(mission: Mission, from: MissionStatus | null, to: MissionStatus, env?: MissionNotifyEnv): Promise<NotifyDispatchResult>;
|
|
34
|
+
/**
|
|
35
|
+
* 使命日志推送(默认仅里程碑;失败不抛出)。
|
|
36
|
+
* QLING_MISSION_NOTIFY_LOGS=off|milestone|all
|
|
37
|
+
*/
|
|
38
|
+
export declare function notifyMissionLog(mission: Mission, message: string, env?: MissionNotifyEnv): Promise<NotifyDispatchResult>;
|
|
39
|
+
//# sourceMappingURL=progress-notify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-notify.d.ts","sourceRoot":"","sources":["../../src/mission/progress-notify.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEtF,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,gBAA8B,GAAG,OAAO,CAInF;AAED,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,gBAA8B,GAClC,OAAO,GAAG,MAAM,CAGlB;AAED,wCAAwC;AACxC,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,WAAW,GAAG,KAAK,CAAC;AAE/D,wBAAgB,2BAA2B,CACzC,GAAG,GAAE,gBAA8B,GAClC,oBAAoB,CAKtB;AAKD;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,gBAA8B,GAClC,OAAO,CAMT;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC,EAChD,OAAO,EAAE,MAAM,GACd,MAAM,CASR;AAYD,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEzD;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC,EAC1E,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,EAAE,EAAE,aAAa,GAChB,MAAM,CAiBR;AAED,8BAA8B;AAC9B,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC,EAC1E,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,EAAE,EAAE,aAAa,GAChB,MAAM,CAmBR;AAED,2BAA2B;AAC3B,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,GAAG,aAAa,GAAG,QAAQ,GAAG,OAAO,CAAC,EAC1E,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,EAAE,EAAE,aAAa,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAqCrC;AAaD,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC;CACzB;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CASzD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,EAAE,EAAE,aAAa,EACjB,GAAG,GAAE,gBAA8B,GAClC,OAAO,CAAC,oBAAoB,CAAC,CA0H/B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,gBAA8B,GAClC,OAAO,CAAC,oBAAoB,CAAC,CA8H/B"}
|