@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.
Files changed (254) hide show
  1. package/CHANGELOG.md +154 -0
  2. package/README.en.md +82 -17
  3. package/README.md +15 -7
  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 +29 -8
  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 +51 -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,33 @@
1
+ export type VerificationStageName = "syntax_type" | "affected_tests" | "configured" | "full_gate";
2
+ export interface VerificationStage {
3
+ name: VerificationStageName;
4
+ command: string;
5
+ }
6
+ export interface VerificationResult {
7
+ ok: boolean;
8
+ stages: Array<{
9
+ name: VerificationStageName;
10
+ command: string;
11
+ code: number;
12
+ durationMs: number;
13
+ }>;
14
+ failedStage?: VerificationStageName;
15
+ failingTests: string[];
16
+ stdout: string;
17
+ stderr: string;
18
+ }
19
+ export declare class StagedVerifier {
20
+ private readonly execute;
21
+ private readonly now;
22
+ constructor(options: {
23
+ execute: (command: string) => Promise<{
24
+ code: number;
25
+ stdout: string;
26
+ stderr: string;
27
+ }>;
28
+ now?: () => number;
29
+ });
30
+ run(stages: VerificationStage[]): Promise<VerificationResult>;
31
+ }
32
+ export declare function extractFailingTests(output: string): string[];
33
+ //# sourceMappingURL=staged-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"staged-verifier.d.ts","sourceRoot":"","sources":["../../src/execution/staged-verifier.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,gBAAgB,GAAG,YAAY,GAAG,WAAW,CAAC;AAElG,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,qBAAqB,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiF;IACzG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,EAAE;QACnB,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACxF,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;KACpB;IAKK,GAAG,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAmBpE;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAS5D"}
@@ -0,0 +1,39 @@
1
+ export class StagedVerifier {
2
+ execute;
3
+ now;
4
+ constructor(options) {
5
+ this.execute = options.execute;
6
+ this.now = options.now ?? (() => Date.now());
7
+ }
8
+ async run(stages) {
9
+ const completed = [];
10
+ for (const stage of stages) {
11
+ const startedAt = this.now();
12
+ const result = await this.execute(stage.command);
13
+ completed.push({ name: stage.name, command: stage.command, code: result.code, durationMs: this.now() - startedAt });
14
+ if (result.code !== 0) {
15
+ return {
16
+ ok: false,
17
+ stages: completed,
18
+ failedStage: stage.name,
19
+ failingTests: extractFailingTests(`${result.stdout}\n${result.stderr}`),
20
+ stdout: result.stdout,
21
+ stderr: result.stderr,
22
+ };
23
+ }
24
+ }
25
+ return { ok: true, stages: completed, failingTests: [], stdout: "", stderr: "" };
26
+ }
27
+ }
28
+ export function extractFailingTests(output) {
29
+ const names = new Set();
30
+ for (const line of output.split(/\r?\n/)) {
31
+ const fail = line.match(/^\s*FAIL\s+(.+?)\s*$/i);
32
+ if (fail)
33
+ names.add(fail[1].trim());
34
+ const nodeTest = line.match(/^\s*not ok\s+\d+\s+-\s+(.+?)\s*$/i);
35
+ if (nodeTest)
36
+ names.add(nodeTest[1].trim());
37
+ }
38
+ return [...names].sort();
39
+ }
@@ -0,0 +1,58 @@
1
+ export type ExecutionRunStatus = "queued" | "running" | "awaiting_approval" | "recovering" | "paused" | "succeeded" | "failed" | "canceled";
2
+ export type FailureCategory = "provider_transient" | "provider_terminal" | "invalid_tool_arguments" | "permission_required" | "permission_denied" | "sandbox_denied" | "tool_not_found" | "tool_execution" | "verification_failed" | "context_exhausted" | "repeated_action" | "no_progress" | "user_canceled";
3
+ export interface ProgressSnapshot {
4
+ diffHash?: string;
5
+ failingTests?: string[];
6
+ completedTodos?: number;
7
+ changed?: boolean;
8
+ /** Basename-only list of modified paths (no full workspace leak). */
9
+ changedFiles?: string[];
10
+ /** Recovery strategies already attempted when this snapshot was recorded. */
11
+ attemptedStrategies?: string[];
12
+ currentStrategy?: string;
13
+ }
14
+ export interface FailureClassification {
15
+ category: FailureCategory;
16
+ message: string;
17
+ tool?: string;
18
+ targetPath?: string;
19
+ verificationCommand?: string;
20
+ fingerprint?: string;
21
+ }
22
+ export interface ExecutionEvent {
23
+ eventId: string;
24
+ runId: string;
25
+ sessionId?: string;
26
+ attemptId?: string;
27
+ toolCallId?: string;
28
+ type: string;
29
+ timestamp: number;
30
+ stage?: string;
31
+ status?: ExecutionRunStatus;
32
+ tool?: string;
33
+ category?: FailureCategory;
34
+ fingerprint?: string;
35
+ durationMs?: number;
36
+ progress?: ProgressSnapshot;
37
+ recoveryAction?: string;
38
+ }
39
+ export interface RecoveryDecision {
40
+ action: "recover" | "pause" | "fail";
41
+ category?: FailureCategory;
42
+ reason: string;
43
+ remainingStrategyAttempts: number;
44
+ recommendedStrategy?: string;
45
+ }
46
+ export interface RecoveryState {
47
+ runId: string;
48
+ sessionId: string;
49
+ originalTask: string;
50
+ status: "running" | "recovering" | "paused" | "failed" | "canceled";
51
+ strategyAttempts: number;
52
+ remainingStrategyAttempts: number;
53
+ currentStrategy?: string;
54
+ attemptedStrategies: string[];
55
+ lastFailure?: FailureClassification;
56
+ lastProgress?: ProgressSnapshot;
57
+ }
58
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/execution/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,SAAS,GACT,mBAAmB,GACnB,YAAY,GACZ,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,MAAM,eAAe,GACvB,oBAAoB,GACpB,mBAAmB,GACnB,wBAAwB,GACxB,qBAAqB,GACrB,mBAAmB,GACnB,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,qBAAqB,GACrB,mBAAmB,GACnB,iBAAiB,GACjB,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB,EAAE,MAAM,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB,EAAE,MAAM,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,YAAY,CAAC,EAAE,gBAAgB,CAAC;CACjC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import type { Message } from "../types.js";
2
+ import type { VerificationAgent } from "../pipeline/verification.js";
3
+ import type { RecoveryController } from "./recovery-controller.js";
4
+ import type { ExecutionEventBus } from "./event-bus.js";
5
+ import type { ProgressSnapshot, RecoveryState } from "./types.js";
6
+ import type { PreparedToolCall } from "../agent/tool-orchestrator.js";
7
+ export type ShellResult = {
8
+ code: number;
9
+ stdout: string;
10
+ stderr: string;
11
+ };
12
+ export declare function runShellCommand(cmd: string, cwd: string): Promise<ShellResult>;
13
+ export declare function getWorkspaceDiffHash(runCommand: (cmd: string) => Promise<ShellResult>): Promise<string>;
14
+ export declare function getWorkspaceChangedFiles(runCommand: (cmd: string) => Promise<ShellResult>): Promise<string[]>;
15
+ export declare function buildVerificationProgress(failingTests: string[], runCommand: (cmd: string) => Promise<ShellResult>): Promise<ProgressSnapshot>;
16
+ export declare function persistVerificationCommand(workspaceDir: string, verificationCommand: string | null): Promise<void>;
17
+ export declare function loadVerificationCommand(workspaceDir: string): Promise<string | null>;
18
+ export declare function runAdvisoryVerification(options: {
19
+ messages: Message[];
20
+ verifier: VerificationAgent;
21
+ emit: (event: string, ...args: unknown[]) => void;
22
+ }): Promise<void>;
23
+ export type WriteVerificationOutcome = {
24
+ kind: "noop";
25
+ } | {
26
+ kind: "pass";
27
+ summary: string;
28
+ } | {
29
+ kind: "advisory";
30
+ } | {
31
+ kind: "recover";
32
+ userMessage: string;
33
+ strategy: string;
34
+ strategyAttempts: number;
35
+ failureMessage: string;
36
+ } | {
37
+ kind: "pause";
38
+ text: string;
39
+ };
40
+ export interface WriteVerificationDeps {
41
+ verificationCommand: string | null;
42
+ runCommand: (cmd: string) => Promise<ShellResult>;
43
+ recoveryController: RecoveryController;
44
+ executionEventBus: ExecutionEventBus;
45
+ emit: (event: string, ...args: unknown[]) => void;
46
+ getRecoveryState: () => RecoveryState | null;
47
+ verifier: VerificationAgent;
48
+ messages: Message[];
49
+ runId: string;
50
+ }
51
+ /**
52
+ * After write/patch/bash tools: staged verification or advisory.
53
+ * Mutates nothing except via recovery controller / event bus / emit callbacks.
54
+ * Caller applies recover/pause side effects on messages and attempt status.
55
+ */
56
+ export declare function runWriteToolVerification(preparedCalls: PreparedToolCall[], deps: WriteVerificationDeps): Promise<WriteVerificationOutcome>;
57
+ export declare function stagesSummary(verificationCommand: string | null): string;
58
+ //# sourceMappingURL=verification-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-loop.d.ts","sourceRoot":"","sources":["../../src/execution/verification-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,195 @@
1
+ // ============================================================
2
+ // 写操作验证闭环(从 AgentLoop 抽出)
3
+ // StagedVerifier 驱动恢复;无 stage 时仅 advisory
4
+ // ============================================================
5
+ import { createHash } from "node:crypto";
6
+ import { exec } from "node:child_process";
7
+ import { existsSync } from "node:fs";
8
+ import * as fs from "node:fs/promises";
9
+ import * as path from "node:path";
10
+ import { StagedVerifier } from "./staged-verifier.js";
11
+ import { formatVerificationStagesSummary, resolveVerificationStages, } from "./verification-stages.js";
12
+ import { classifyFailure } from "./failure-classifier.js";
13
+ import { buildVerificationFailureUserMessage, formatRecoveryInstruction, formatRecoveryPause, } from "./recovery-messages.js";
14
+ export function runShellCommand(cmd, cwd) {
15
+ return new Promise((resolve) => {
16
+ exec(cmd, { cwd }, (error, stdout, stderr) => {
17
+ const code = error ? (error.code ?? 1) : 0;
18
+ resolve({ code, stdout, stderr });
19
+ });
20
+ });
21
+ }
22
+ export async function getWorkspaceDiffHash(runCommand) {
23
+ const result = await runCommand("git diff --no-ext-diff --binary");
24
+ const content = result.code === 0 ? result.stdout : "git-unavailable";
25
+ return createHash("sha256").update(content).digest("hex").slice(0, 20);
26
+ }
27
+ export async function getWorkspaceChangedFiles(runCommand) {
28
+ const result = await runCommand("git status --porcelain");
29
+ if (result.code !== 0 || !result.stdout.trim())
30
+ return [];
31
+ const names = new Set();
32
+ for (const line of result.stdout.split(/\r?\n/)) {
33
+ const trimmed = line.trim();
34
+ if (!trimmed)
35
+ continue;
36
+ const body = trimmed.slice(2).trim();
37
+ const pathPart = body.includes(" -> ") ? body.split(" -> ").pop() : body;
38
+ const base = path.basename(pathPart.replace(/^"+|"+$/g, ""));
39
+ if (base)
40
+ names.add(base);
41
+ if (names.size >= 20)
42
+ break;
43
+ }
44
+ return [...names].sort();
45
+ }
46
+ export async function buildVerificationProgress(failingTests, runCommand) {
47
+ const [diffHash, changedFiles] = await Promise.all([
48
+ getWorkspaceDiffHash(runCommand),
49
+ getWorkspaceChangedFiles(runCommand),
50
+ ]);
51
+ return {
52
+ diffHash,
53
+ failingTests: [...failingTests],
54
+ changedFiles,
55
+ changed: changedFiles.length > 0,
56
+ };
57
+ }
58
+ export async function persistVerificationCommand(workspaceDir, verificationCommand) {
59
+ const filePath = path.join(workspaceDir, ".qling-verify.json");
60
+ try {
61
+ if (verificationCommand) {
62
+ await fs.writeFile(filePath, JSON.stringify({ verificationCommand }, null, 2), "utf-8");
63
+ }
64
+ else if (existsSync(filePath)) {
65
+ await fs.unlink(filePath);
66
+ }
67
+ }
68
+ catch (err) {
69
+ console.error("[verification] Failed to persist verification command: " + err.message);
70
+ }
71
+ }
72
+ export async function loadVerificationCommand(workspaceDir) {
73
+ const filePath = path.join(workspaceDir, ".qling-verify.json");
74
+ if (!existsSync(filePath))
75
+ return null;
76
+ try {
77
+ const content = await fs.readFile(filePath, "utf-8");
78
+ const data = JSON.parse(content);
79
+ return data.verificationCommand ?? null;
80
+ }
81
+ catch (err) {
82
+ console.error("[verification] Failed to load verification command: " + err.message);
83
+ return null;
84
+ }
85
+ }
86
+ export async function runAdvisoryVerification(options) {
87
+ const toolMsgs = options.messages.filter((m) => m.role === "tool");
88
+ if (toolMsgs.length === 0)
89
+ return;
90
+ try {
91
+ const lastResult = JSON.parse(toolMsgs[toolMsgs.length - 1].content);
92
+ const vr = await options.verifier.verify("文件操作/Bash执行", "操作成功完成", lastResult.output);
93
+ const icon = vr.verdict === "PASS" ? "✅" : vr.verdict === "FAIL" ? "❌" : "⚠️";
94
+ console.error(icon + " 旁路验证(非恢复驱动): " + vr.verdict);
95
+ if (vr.verdict !== "PASS") {
96
+ console.error(" 详情: " + vr.details);
97
+ console.error(" 提示: 设置 /verify set 或 QLING_VERIFY_* 以启用命令级恢复验证");
98
+ }
99
+ options.emit("verification", vr.verdict, vr.details ?? vr.verdict);
100
+ }
101
+ catch {
102
+ // ignore advisory failures
103
+ }
104
+ }
105
+ /**
106
+ * After write/patch/bash tools: staged verification or advisory.
107
+ * Mutates nothing except via recovery controller / event bus / emit callbacks.
108
+ * Caller applies recover/pause side effects on messages and attempt status.
109
+ */
110
+ export async function runWriteToolVerification(preparedCalls, deps) {
111
+ const hasWrites = preparedCalls.some((t) => t.call.name === "write" || t.call.name === "patch" || t.call.name === "bash");
112
+ if (!hasWrites)
113
+ return { kind: "noop" };
114
+ const stages = resolveVerificationStages({
115
+ configuredCommand: deps.verificationCommand,
116
+ });
117
+ if (stages.length === 0) {
118
+ await runAdvisoryVerification({
119
+ messages: deps.messages,
120
+ verifier: deps.verifier,
121
+ emit: deps.emit,
122
+ });
123
+ return { kind: "advisory" };
124
+ }
125
+ const stagedVerifier = new StagedVerifier({ execute: (command) => deps.runCommand(command) });
126
+ const verification = await stagedVerifier.run(stages);
127
+ if (verification.ok) {
128
+ const summary = formatVerificationStagesSummary(stages);
129
+ deps.emit("verification", "PASS", `验证通过: ${summary}`);
130
+ return { kind: "pass", summary };
131
+ }
132
+ const failedCommand = stages.find((stage) => stage.name === verification.failedStage)?.command ??
133
+ stages.map((stage) => stage.command).join(" && ");
134
+ const failure = classifyFailure(new Error(`verification command failed: ${failedCommand}`), {
135
+ tool: "verify",
136
+ verificationCommand: failedCommand,
137
+ });
138
+ const progress = await buildVerificationProgress(verification.failingTests, deps.runCommand);
139
+ const decision = deps.recoveryController.recordFailure(failure, progress);
140
+ const state = deps.recoveryController.getRecoveryState();
141
+ const progressWithStrategy = {
142
+ ...progress,
143
+ attemptedStrategies: state.attemptedStrategies,
144
+ currentStrategy: state.currentStrategy,
145
+ };
146
+ deps.executionEventBus.emit({
147
+ runId: state.runId,
148
+ sessionId: state.sessionId,
149
+ type: "verification_failed",
150
+ status: decision.action === "pause" ? "paused" : "recovering",
151
+ stage: verification.failedStage,
152
+ tool: "verify",
153
+ category: decision.category,
154
+ fingerprint: failure.fingerprint,
155
+ progress: progressWithStrategy,
156
+ recoveryAction: decision.recommendedStrategy ?? decision.action,
157
+ });
158
+ if (decision.action === "pause") {
159
+ deps.executionEventBus.completeAttempt(deps.runId, "failed");
160
+ deps.emit("recovery_paused", state, decision);
161
+ return {
162
+ kind: "pause",
163
+ text: formatRecoveryPause({
164
+ reason: verification.stderr || verification.stdout,
165
+ next: decision.reason,
166
+ state,
167
+ verificationStagesSummary: formatVerificationStagesSummary(stages),
168
+ }),
169
+ };
170
+ }
171
+ const strategy = decision.recommendedStrategy ?? "targeted_verification_repair";
172
+ const instruction = formatRecoveryInstruction(failure, strategy);
173
+ const userMessage = buildVerificationFailureUserMessage({
174
+ failedStage: verification.failedStage,
175
+ failedCommand,
176
+ failingTests: verification.failingTests,
177
+ changedFiles: progress.changedFiles ?? [],
178
+ fingerprint: failure.fingerprint,
179
+ attemptedStrategies: state.attemptedStrategies,
180
+ strategy,
181
+ stdout: verification.stdout.slice(-2_000),
182
+ stderr: verification.stderr.slice(-2_000),
183
+ instructionBody: instruction.split("\n").slice(1).join("\n"),
184
+ });
185
+ return {
186
+ kind: "recover",
187
+ userMessage,
188
+ strategy,
189
+ strategyAttempts: state.strategyAttempts,
190
+ failureMessage: failure.message,
191
+ };
192
+ }
193
+ export function stagesSummary(verificationCommand) {
194
+ return formatVerificationStagesSummary(resolveVerificationStages({ configuredCommand: verificationCommand }));
195
+ }
@@ -0,0 +1,17 @@
1
+ import type { VerificationStage } from "./staged-verifier.js";
2
+ /**
3
+ * Resolve ordered verification stages for write recovery.
4
+ *
5
+ * Sources (later stages append; configured command always last when set):
6
+ * 1. `QLING_VERIFY_STAGES` — JSON array of `{name,command}` or `name=command;name=command`
7
+ * 2. Convenience env: `QLING_VERIFY_TYPECHECK_CMD`, `QLING_VERIFY_TEST_CMD`, `QLING_VERIFY_FULL_CMD`
8
+ * 3. Session/workspace `configuredCommand` from `/verify set` or `.qling-verify.json`
9
+ */
10
+ export declare function resolveVerificationStages(options: {
11
+ configuredCommand?: string | null;
12
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
13
+ }): VerificationStage[];
14
+ export declare function parseVerifyStagesEnv(raw: string): VerificationStage[];
15
+ /** Summarize stages for doctor / status output. */
16
+ export declare function formatVerificationStagesSummary(stages: VerificationStage[]): string;
17
+ //# sourceMappingURL=verification-stages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification-stages.d.ts","sourceRoot":"","sources":["../../src/execution/verification-stages.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAyB,MAAM,sBAAsB,CAAC;AASrF;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC9D,GAAG,iBAAiB,EAAE,CA2BtB;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAsCrE;AAYD,mDAAmD;AACnD,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAGnF"}
@@ -0,0 +1,102 @@
1
+ // ============================================================
2
+ // 统一验证阶段解析:写操作恢复闭环只走 StagedVerifier
3
+ // ============================================================
4
+ const KNOWN_STAGE_NAMES = new Set([
5
+ "syntax_type",
6
+ "affected_tests",
7
+ "configured",
8
+ "full_gate",
9
+ ]);
10
+ /**
11
+ * Resolve ordered verification stages for write recovery.
12
+ *
13
+ * Sources (later stages append; configured command always last when set):
14
+ * 1. `QLING_VERIFY_STAGES` — JSON array of `{name,command}` or `name=command;name=command`
15
+ * 2. Convenience env: `QLING_VERIFY_TYPECHECK_CMD`, `QLING_VERIFY_TEST_CMD`, `QLING_VERIFY_FULL_CMD`
16
+ * 3. Session/workspace `configuredCommand` from `/verify set` or `.qling-verify.json`
17
+ */
18
+ export function resolveVerificationStages(options) {
19
+ const env = options.env ?? process.env;
20
+ const stages = [];
21
+ const seen = new Set();
22
+ const push = (name, command) => {
23
+ const cmd = String(command ?? "").trim();
24
+ if (!cmd)
25
+ return;
26
+ const key = `${name}::${cmd}`;
27
+ if (seen.has(key))
28
+ return;
29
+ seen.add(key);
30
+ stages.push({ name, command: cmd });
31
+ };
32
+ const rawStages = String(env.QLING_VERIFY_STAGES ?? "").trim();
33
+ if (rawStages) {
34
+ for (const stage of parseVerifyStagesEnv(rawStages)) {
35
+ push(stage.name, stage.command);
36
+ }
37
+ }
38
+ push("syntax_type", env.QLING_VERIFY_TYPECHECK_CMD);
39
+ push("affected_tests", env.QLING_VERIFY_TEST_CMD);
40
+ push("full_gate", env.QLING_VERIFY_FULL_CMD);
41
+ push("configured", options.configuredCommand ?? undefined);
42
+ return stages;
43
+ }
44
+ export function parseVerifyStagesEnv(raw) {
45
+ const trimmed = raw.trim();
46
+ if (!trimmed)
47
+ return [];
48
+ if (trimmed.startsWith("[")) {
49
+ try {
50
+ const parsed = JSON.parse(trimmed);
51
+ if (!Array.isArray(parsed))
52
+ return [];
53
+ return parsed
54
+ .map((item) => normalizeStage(item?.name, item?.command))
55
+ .filter((item) => item !== null);
56
+ }
57
+ catch {
58
+ return [];
59
+ }
60
+ }
61
+ // name=command;name=command or name:command|name:command
62
+ const parts = trimmed.split(/[;|]/).map((part) => part.trim()).filter(Boolean);
63
+ const stages = [];
64
+ for (const part of parts) {
65
+ const eq = part.indexOf("=");
66
+ const colon = part.indexOf(":");
67
+ let name = "";
68
+ let command = "";
69
+ if (eq > 0) {
70
+ name = part.slice(0, eq).trim();
71
+ command = part.slice(eq + 1).trim();
72
+ }
73
+ else if (colon > 0) {
74
+ name = part.slice(0, colon).trim();
75
+ command = part.slice(colon + 1).trim();
76
+ }
77
+ else {
78
+ command = part;
79
+ name = "configured";
80
+ }
81
+ const stage = normalizeStage(name, command);
82
+ if (stage)
83
+ stages.push(stage);
84
+ }
85
+ return stages;
86
+ }
87
+ function normalizeStage(nameRaw, commandRaw) {
88
+ const command = String(commandRaw ?? "").trim();
89
+ if (!command)
90
+ return null;
91
+ const name = String(nameRaw ?? "configured").trim().toLowerCase().replace(/-/g, "_");
92
+ const mapped = KNOWN_STAGE_NAMES.has(name)
93
+ ? name
94
+ : "configured";
95
+ return { name: mapped, command };
96
+ }
97
+ /** Summarize stages for doctor / status output. */
98
+ export function formatVerificationStagesSummary(stages) {
99
+ if (stages.length === 0)
100
+ return "none(写操作后无命令验证;仅 advisory 规则提示)";
101
+ return stages.map((stage) => `${stage.name}=${stage.command}`).join(" → ");
102
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"help-topics.d.ts","sourceRoot":"","sources":["../src/help-topics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkVD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAI5E;AAiCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,EAAE,CAoD1G"}
1
+ {"version":3,"file":"help-topics.d.ts","sourceRoot":"","sources":["../src/help-topics.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA6VD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CAI5E;AAiCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,EAAE,CAoD1G"}
@@ -32,6 +32,17 @@ const TOPICS = [
32
32
  cliExamples: [],
33
33
  boundary: "Plan Mode 仅当前进程生效;写工具由权限层拒绝;/plan off 恢复 agent 模式。",
34
34
  },
35
+ {
36
+ id: "mode",
37
+ title: "Agent 执行模式",
38
+ summary: "查看或循环 Agent/ask、Plan 与 Agent/allow(Always Agree)。",
39
+ aliases: ["mode", "/mode", "模式", "/模式"],
40
+ slashUsage: "/mode [status|cycle]",
41
+ cliUsage: "仅 TUI:Shift+Tab 或 slash 命令",
42
+ slashExamples: ["/mode", "/mode cycle", "/模式 cycle"],
43
+ cliExamples: [],
44
+ boundary: "只影响当前进程;Plan Mode 优先于 allow,仍会拒绝写工具;不写默认配置。",
45
+ },
35
46
  {
36
47
  id: "diff",
37
48
  title: "Git 变更摘要",
package/dist/index.js CHANGED
@@ -581,7 +581,6 @@ async function main() {
581
581
  workspaceDir: loaded.config.runtime.workspace_dir ?? process.cwd(),
582
582
  stateDir: loaded.config.runtime.file_state_dir,
583
583
  cacheDir: loaded.config.runtime.file_cache_dir,
584
- maxTokens: loaded.config.runtime.max_token_budget,
585
584
  });
586
585
  console.log(formatContextReport(report).join("\n"));
587
586
  return;
@@ -655,7 +654,6 @@ async function main() {
655
654
  workspaceDir: loaded.config.runtime.workspace_dir,
656
655
  model: loaded.config.llm.model,
657
656
  permissionMode: loaded.config.guard.permissions.default,
658
- maxTokens: loaded.config.runtime.max_token_budget,
659
657
  costPer1kTokens: parseStatusLineCostPer1k(process.env.QLING_STATUSLINE_COST_PER_1K_TOKENS),
660
658
  });
661
659
  console.log("");
@@ -910,18 +908,12 @@ async function main() {
910
908
  model: loaded.config.llm.model,
911
909
  maxIterations: loaded.config.runtime.max_steps,
912
910
  tools,
913
- tokenBudget: {
914
- maxTokens: loaded.config.runtime.max_token_budget,
915
- totalBudget: loaded.config.runtime.max_token_budget,
916
- nudgeThreshold: 0.2,
917
- },
918
911
  runtime: {
919
912
  workspaceDir: loaded.config.runtime.workspace_dir,
920
913
  fileCacheDir: loaded.config.runtime.file_cache_dir,
921
914
  fileStateDir: loaded.config.runtime.file_state_dir,
922
915
  maxSteps: loaded.config.runtime.max_steps,
923
916
  parseRetries: loaded.config.runtime.parse_retries,
924
- maxTokenBudget: loaded.config.runtime.max_token_budget,
925
917
  toolRepeatLimit: loaded.config.runtime.tool_repeat_limit,
926
918
  timeoutMs: loaded.config.runtime.timeout_ms,
927
919
  },
@@ -0,0 +1,36 @@
1
+ export type TsModule = typeof import("typescript");
2
+ export interface LspLocation {
3
+ file: string;
4
+ line: number;
5
+ character: number;
6
+ preview?: string;
7
+ }
8
+ export interface LspHoverResult {
9
+ display: string;
10
+ documentation: string;
11
+ }
12
+ export interface LspSymbolItem {
13
+ name: string;
14
+ kind: string;
15
+ line: number;
16
+ character: number;
17
+ }
18
+ export declare function isLspEnabled(env?: NodeJS.ProcessEnv | Record<string, string | undefined>): boolean;
19
+ export declare function loadTypeScript(): Promise<TsModule | null>;
20
+ interface ServiceBundle {
21
+ ts: TsModule;
22
+ service: import("typescript").LanguageService;
23
+ workspaceDir: string;
24
+ dispose: () => void;
25
+ }
26
+ export declare function getTsService(ts: TsModule, workspaceDir: string): ServiceBundle;
27
+ export declare function resetTsServiceCache(): void;
28
+ export declare function lspDefinition(bundle: ServiceBundle, absFile: string, line: number, character: number): LspLocation[];
29
+ export declare function lspHover(bundle: ServiceBundle, absFile: string, line: number, character: number): LspHoverResult | null;
30
+ export declare function lspReferences(bundle: ServiceBundle, absFile: string, line: number, character: number, limit?: number): LspLocation[];
31
+ export declare function lspDocumentSymbols(bundle: ServiceBundle, absFile: string, limit?: number): LspSymbolItem[];
32
+ /** 无 tsconfig 时:为单文件创建临时 service */
33
+ export declare function getOrCreateServiceForFile(ts: TsModule, workspaceDir: string, absFile: string): ServiceBundle;
34
+ export declare function resolveAbsFile(workspaceDir: string, filePath: string): string;
35
+ export {};
36
+ //# sourceMappingURL=ts-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-service.d.ts","sourceRoot":"","sources":["../../src/lsp/ts-service.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,QAAQ,GAAG,cAAc,YAAY,CAAC,CAAC;AAEnD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAC1B,GAAG,GAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACxE,OAAO,CAGT;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAO/D;AA4BD,UAAU,aAAa;IACrB,EAAE,EAAE,QAAQ,CAAC;IACb,OAAO,EAAE,OAAO,YAAY,EAAE,eAAe,CAAC;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAqFD,wBAAgB,YAAY,CAC1B,EAAE,EAAE,QAAQ,EACZ,YAAY,EAAE,MAAM,GACnB,aAAa,CAQf;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAS1C;AAOD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,WAAW,EAAE,CAqBf;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,cAAc,GAAG,IAAI,CAUvB;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,KAAK,SAAK,GACT,WAAW,EAAE,CAkBf;AAED,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,SAAK,GACT,aAAa,EAAE,CAyBjB;AAED,oCAAoC;AACpC,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,QAAQ,EACZ,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GACd,aAAa,CAgEf;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM7E"}