@qlingzzy/qling 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/CHANGELOG.md +158 -0
  2. package/README.en.md +83 -18
  3. package/README.md +19 -9
  4. package/dist/agent/main-loop.d.ts +120 -0
  5. package/dist/agent/main-loop.d.ts.map +1 -0
  6. package/dist/agent/main-loop.js +279 -0
  7. package/dist/agent/subtask-parallel.d.ts +29 -0
  8. package/dist/agent/subtask-parallel.d.ts.map +1 -0
  9. package/dist/agent/subtask-parallel.js +107 -0
  10. package/dist/agent/subtask.d.ts +13 -0
  11. package/dist/agent/subtask.d.ts.map +1 -1
  12. package/dist/agent/subtask.js +79 -24
  13. package/dist/agent/system-prompt.d.ts +39 -0
  14. package/dist/agent/system-prompt.d.ts.map +1 -0
  15. package/dist/agent/system-prompt.js +89 -0
  16. package/dist/agent/tool-orchestrator.d.ts +66 -0
  17. package/dist/agent/tool-orchestrator.d.ts.map +1 -0
  18. package/dist/agent/tool-orchestrator.js +355 -0
  19. package/dist/agent-loop.d.ts +29 -16
  20. package/dist/agent-loop.d.ts.map +1 -1
  21. package/dist/agent-loop.js +262 -807
  22. package/dist/agents/roles.d.ts +57 -0
  23. package/dist/agents/roles.d.ts.map +1 -0
  24. package/dist/agents/roles.js +198 -0
  25. package/dist/commands/agents.d.ts.map +1 -1
  26. package/dist/commands/agents.js +17 -3
  27. package/dist/commands/claude-style.d.ts.map +1 -1
  28. package/dist/commands/claude-style.js +19 -10
  29. package/dist/commands/help.d.ts.map +1 -1
  30. package/dist/commands/help.js +3 -2
  31. package/dist/commands/index.d.ts.map +1 -1
  32. package/dist/commands/index.js +6 -0
  33. package/dist/commands/mode.d.ts +16 -0
  34. package/dist/commands/mode.d.ts.map +1 -0
  35. package/dist/commands/mode.js +67 -0
  36. package/dist/commands/recover.d.ts +3 -0
  37. package/dist/commands/recover.d.ts.map +1 -0
  38. package/dist/commands/recover.js +69 -0
  39. package/dist/commands/runtime.d.ts +2 -0
  40. package/dist/commands/runtime.d.ts.map +1 -1
  41. package/dist/commands/runtime.js +2 -0
  42. package/dist/commands/trace.d.ts +3 -0
  43. package/dist/commands/trace.d.ts.map +1 -0
  44. package/dist/commands/trace.js +45 -0
  45. package/dist/commands/verify.js +2 -2
  46. package/dist/config-report.d.ts +0 -1
  47. package/dist/config-report.d.ts.map +1 -1
  48. package/dist/config-report.js +1 -2
  49. package/dist/config.d.ts +0 -1
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +0 -1
  52. package/dist/context-report.d.ts +13 -7
  53. package/dist/context-report.d.ts.map +1 -1
  54. package/dist/context-report.js +64 -61
  55. package/dist/context-tool-hygiene.d.ts +36 -0
  56. package/dist/context-tool-hygiene.d.ts.map +1 -0
  57. package/dist/context-tool-hygiene.js +125 -0
  58. package/dist/dashboard/client.d.ts +2 -0
  59. package/dist/dashboard/client.d.ts.map +1 -0
  60. package/dist/dashboard/client.js +305 -0
  61. package/dist/dashboard/model.d.ts +13 -0
  62. package/dist/dashboard/model.d.ts.map +1 -0
  63. package/dist/dashboard/model.js +112 -0
  64. package/dist/dashboard/page.d.ts +3 -0
  65. package/dist/dashboard/page.d.ts.map +1 -0
  66. package/dist/dashboard/page.js +204 -0
  67. package/dist/dashboard/types.d.ts +63 -0
  68. package/dist/dashboard/types.d.ts.map +1 -0
  69. package/dist/dashboard/types.js +1 -0
  70. package/dist/dashboard-server.d.ts +24 -4
  71. package/dist/dashboard-server.d.ts.map +1 -1
  72. package/dist/dashboard-server.js +397 -302
  73. package/dist/discovery-registry.d.ts +17 -3
  74. package/dist/discovery-registry.d.ts.map +1 -1
  75. package/dist/discovery-registry.js +78 -3
  76. package/dist/doctor.d.ts +8 -0
  77. package/dist/doctor.d.ts.map +1 -1
  78. package/dist/doctor.js +116 -0
  79. package/dist/eval/llm-tasks.d.ts +5 -0
  80. package/dist/eval/llm-tasks.d.ts.map +1 -0
  81. package/dist/eval/llm-tasks.js +125 -0
  82. package/dist/eval/repo-tasks.d.ts +12 -0
  83. package/dist/eval/repo-tasks.d.ts.map +1 -0
  84. package/dist/eval/repo-tasks.js +220 -0
  85. package/dist/eval/runner.d.ts +3 -1
  86. package/dist/eval/runner.d.ts.map +1 -1
  87. package/dist/eval/runner.js +23 -4
  88. package/dist/eval/tasks.d.ts.map +1 -1
  89. package/dist/eval/tasks.js +186 -0
  90. package/dist/eval/types.d.ts +8 -5
  91. package/dist/eval/types.d.ts.map +1 -1
  92. package/dist/execution/event-bus.d.ts +44 -0
  93. package/dist/execution/event-bus.d.ts.map +1 -0
  94. package/dist/execution/event-bus.js +76 -0
  95. package/dist/execution/failure-classifier.d.ts +11 -0
  96. package/dist/execution/failure-classifier.d.ts.map +1 -0
  97. package/dist/execution/failure-classifier.js +66 -0
  98. package/dist/execution/progress-detector.d.ts +3 -0
  99. package/dist/execution/progress-detector.d.ts.map +1 -0
  100. package/dist/execution/progress-detector.js +23 -0
  101. package/dist/execution/recovery-controller.d.ts +24 -0
  102. package/dist/execution/recovery-controller.d.ts.map +1 -0
  103. package/dist/execution/recovery-controller.js +114 -0
  104. package/dist/execution/recovery-messages.d.ts +24 -0
  105. package/dist/execution/recovery-messages.d.ts.map +1 -0
  106. package/dist/execution/recovery-messages.js +48 -0
  107. package/dist/execution/recovery-metrics.d.ts +16 -0
  108. package/dist/execution/recovery-metrics.d.ts.map +1 -0
  109. package/dist/execution/recovery-metrics.js +73 -0
  110. package/dist/execution/recovery-strategy-planner.d.ts +6 -0
  111. package/dist/execution/recovery-strategy-planner.d.ts.map +1 -0
  112. package/dist/execution/recovery-strategy-planner.js +24 -0
  113. package/dist/execution/run-trace-store.d.ts +29 -0
  114. package/dist/execution/run-trace-store.d.ts.map +1 -0
  115. package/dist/execution/run-trace-store.js +140 -0
  116. package/dist/execution/staged-verifier.d.ts +33 -0
  117. package/dist/execution/staged-verifier.d.ts.map +1 -0
  118. package/dist/execution/staged-verifier.js +39 -0
  119. package/dist/execution/types.d.ts +58 -0
  120. package/dist/execution/types.d.ts.map +1 -0
  121. package/dist/execution/types.js +1 -0
  122. package/dist/execution/verification-loop.d.ts +58 -0
  123. package/dist/execution/verification-loop.d.ts.map +1 -0
  124. package/dist/execution/verification-loop.js +195 -0
  125. package/dist/execution/verification-stages.d.ts +17 -0
  126. package/dist/execution/verification-stages.d.ts.map +1 -0
  127. package/dist/execution/verification-stages.js +102 -0
  128. package/dist/help-topics.d.ts.map +1 -1
  129. package/dist/help-topics.js +11 -0
  130. package/dist/index.js +0 -8
  131. package/dist/lsp/ts-service.d.ts +36 -0
  132. package/dist/lsp/ts-service.d.ts.map +1 -0
  133. package/dist/lsp/ts-service.js +291 -0
  134. package/dist/memory/lifecycle.d.ts +19 -0
  135. package/dist/memory/lifecycle.d.ts.map +1 -0
  136. package/dist/memory/lifecycle.js +53 -0
  137. package/dist/memory.d.ts +0 -16
  138. package/dist/memory.d.ts.map +1 -1
  139. package/dist/memory.js +0 -36
  140. package/dist/metrics/collector.d.ts +7 -0
  141. package/dist/metrics/collector.d.ts.map +1 -1
  142. package/dist/metrics/collector.js +60 -0
  143. package/dist/mission/manager.d.ts +1 -0
  144. package/dist/mission/manager.d.ts.map +1 -1
  145. package/dist/mission/manager.js +9 -0
  146. package/dist/mission/progress-notify.d.ts +39 -0
  147. package/dist/mission/progress-notify.d.ts.map +1 -0
  148. package/dist/mission/progress-notify.js +386 -0
  149. package/dist/pipeline/hooks.d.ts +1 -1
  150. package/dist/pipeline/hooks.d.ts.map +1 -1
  151. package/dist/pipeline/hooks.js +1 -0
  152. package/dist/pipeline/sections.d.ts +8 -4
  153. package/dist/pipeline/sections.d.ts.map +1 -1
  154. package/dist/pipeline/sections.js +70 -27
  155. package/dist/pipeline/verification.d.ts +1 -0
  156. package/dist/pipeline/verification.d.ts.map +1 -1
  157. package/dist/pipeline/verification.js +10 -7
  158. package/dist/providers/llm-client.d.ts +38 -0
  159. package/dist/providers/llm-client.d.ts.map +1 -0
  160. package/dist/providers/llm-client.js +105 -0
  161. package/dist/sdk.d.ts +1 -0
  162. package/dist/sdk.d.ts.map +1 -1
  163. package/dist/sdk.js +1 -0
  164. package/dist/session/durable-session-supervisor.d.ts.map +1 -1
  165. package/dist/session/durable-session-supervisor.js +13 -6
  166. package/dist/session/session-persistence.d.ts +29 -0
  167. package/dist/session/session-persistence.d.ts.map +1 -0
  168. package/dist/session/session-persistence.js +45 -0
  169. package/dist/session/session-scheduler.d.ts +8 -1
  170. package/dist/session/session-scheduler.d.ts.map +1 -1
  171. package/dist/session/session-scheduler.js +33 -4
  172. package/dist/session-task-report.d.ts +1 -0
  173. package/dist/session-task-report.d.ts.map +1 -1
  174. package/dist/session-task-report.js +2 -1
  175. package/dist/shortcuts.d.ts.map +1 -1
  176. package/dist/shortcuts.js +1 -0
  177. package/dist/skills/registry.d.ts.map +1 -1
  178. package/dist/skills/registry.js +10 -0
  179. package/dist/skills/security-scan.d.ts +15 -0
  180. package/dist/skills/security-scan.d.ts.map +1 -0
  181. package/dist/skills/security-scan.js +95 -0
  182. package/dist/skills/types.d.ts +2 -0
  183. package/dist/skills/types.d.ts.map +1 -1
  184. package/dist/statusline.d.ts +3 -3
  185. package/dist/statusline.d.ts.map +1 -1
  186. package/dist/statusline.js +9 -17
  187. package/dist/token-usage.d.ts +27 -0
  188. package/dist/token-usage.d.ts.map +1 -0
  189. package/dist/token-usage.js +107 -0
  190. package/dist/tools/bash.d.ts.map +1 -1
  191. package/dist/tools/bash.js +5 -3
  192. package/dist/tools/browser-act-session.d.ts +48 -0
  193. package/dist/tools/browser-act-session.d.ts.map +1 -0
  194. package/dist/tools/browser-act-session.js +168 -0
  195. package/dist/tools/browser-act.d.ts +14 -0
  196. package/dist/tools/browser-act.d.ts.map +1 -0
  197. package/dist/tools/browser-act.js +297 -0
  198. package/dist/tools/code-symbols.d.ts +35 -0
  199. package/dist/tools/code-symbols.d.ts.map +1 -0
  200. package/dist/tools/code-symbols.js +257 -0
  201. package/dist/tools/index.d.ts +4 -1
  202. package/dist/tools/index.d.ts.map +1 -1
  203. package/dist/tools/index.js +22 -2
  204. package/dist/tools/lsp.d.ts +13 -0
  205. package/dist/tools/lsp.d.ts.map +1 -0
  206. package/dist/tools/lsp.js +136 -0
  207. package/dist/tools/patch.d.ts +5 -0
  208. package/dist/tools/patch.d.ts.map +1 -1
  209. package/dist/tools/patch.js +25 -4
  210. package/dist/tools/search.d.ts +7 -0
  211. package/dist/tools/search.d.ts.map +1 -1
  212. package/dist/tools/search.js +20 -3
  213. package/dist/tools/skill.d.ts +2 -0
  214. package/dist/tools/skill.d.ts.map +1 -1
  215. package/dist/tools/skill.js +47 -14
  216. package/dist/tools/subtask.d.ts +3 -1
  217. package/dist/tools/subtask.d.ts.map +1 -1
  218. package/dist/tools/subtask.js +151 -56
  219. package/dist/tui/shell.d.ts +12 -0
  220. package/dist/tui/shell.d.ts.map +1 -1
  221. package/dist/tui/shell.js +36 -3
  222. package/dist/tui/streaming-repl.d.ts +1 -0
  223. package/dist/tui/streaming-repl.d.ts.map +1 -1
  224. package/dist/tui/streaming-repl.js +27 -4
  225. package/dist/tui/streaming-tui.d.ts +10 -0
  226. package/dist/tui/streaming-tui.d.ts.map +1 -1
  227. package/dist/tui/streaming-tui.js +70 -12
  228. package/dist/types.d.ts +0 -8
  229. package/dist/types.d.ts.map +1 -1
  230. package/dist/workflow-runtime.d.ts.map +1 -1
  231. package/dist/workflow-runtime.js +10 -2
  232. package/dist/workflow-types.d.ts +2 -0
  233. package/dist/workflow-types.d.ts.map +1 -1
  234. package/docs/install.md +46 -12
  235. package/docs/skills.md +56 -7
  236. package/docs/web-routing.md +83 -0
  237. package/package.json +18 -4
  238. package/scripts/dep-layers.mjs +275 -0
  239. package/scripts/eval-llm.mjs +27 -0
  240. package/scripts/eval-recovery.mjs +101 -0
  241. package/scripts/eval-tasks.mjs +20 -0
  242. package/scripts/validate-packaging.mjs +57 -0
  243. package/skills/examples/README.md +23 -0
  244. package/skills/examples/add-function/SKILL.md +31 -0
  245. package/skills/examples/fix-failing-test/SKILL.md +32 -0
  246. package/skills/examples/pr-summary/SKILL.md +34 -0
  247. package/skills/lifecycle-build/SKILL.md +22 -0
  248. package/skills/lifecycle-plan/SKILL.md +32 -0
  249. package/skills/lifecycle-review/SKILL.md +25 -0
  250. package/skills/lifecycle-ship/SKILL.md +22 -0
  251. package/skills/lifecycle-spec/SKILL.md +24 -0
  252. package/skills/lifecycle-test/SKILL.md +21 -0
  253. package/skills/opencli/SKILL.md +222 -0
  254. 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
@@ -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;IA6BxD,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"}
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;AAKlE,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;IA2BnB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI3C,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQtC,YAAY,IAAI,OAAO,EAAE;IAKnB,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;IAezF,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"}
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"}
@@ -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"}