@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,57 @@
1
+ import type { ToolDefinition } from "../types.js";
2
+ export type SubAgentRole = "explore" | "implement" | "review";
3
+ export declare const SUBAGENT_ROLES: SubAgentRole[];
4
+ export interface RoleDefinition {
5
+ id: SubAgentRole;
6
+ title: string;
7
+ description: string;
8
+ /** 允许的工具名;不含 subtask(禁止嵌套) */
9
+ allowedTools: string[];
10
+ /** 写入类工具是否允许 */
11
+ canWrite: boolean;
12
+ }
13
+ /** 角色工具白名单(与 ALL_TOOLS 对齐的子集) */
14
+ export declare const ROLE_DEFINITIONS: Record<SubAgentRole, RoleDefinition>;
15
+ export declare function normalizeSubAgentRole(raw: unknown): SubAgentRole;
16
+ export declare function isKnownSubAgentRole(raw: unknown): boolean;
17
+ export declare function getRoleDefinition(role: SubAgentRole): RoleDefinition;
18
+ /**
19
+ * 按角色过滤工具;始终剔除 subtask,防止嵌套。
20
+ */
21
+ export declare function filterToolsForRole(tools: ToolDefinition[] | undefined, role: SubAgentRole): ToolDefinition[];
22
+ export interface SubAgentReturnContract {
23
+ role: SubAgentRole;
24
+ success: boolean;
25
+ durationMs: number;
26
+ iterations: number;
27
+ summary: string;
28
+ filesTouched: string[];
29
+ evidence: string[];
30
+ /** 原始模型输出(已截断) */
31
+ rawOutput: string;
32
+ }
33
+ /**
34
+ * 父代理只应消费此契约文本,避免整段子会话上浮。
35
+ */
36
+ export declare function formatSubAgentReturnContract(c: SubAgentReturnContract): string;
37
+ /**
38
+ * 从消息历史提取 write/patch 目标路径。
39
+ */
40
+ export declare function extractFilesTouchedFromMessages(messages: Array<{
41
+ role?: string;
42
+ content?: string;
43
+ tool_calls?: Array<{
44
+ function?: {
45
+ name?: string;
46
+ arguments?: string;
47
+ };
48
+ }>;
49
+ }>): string[];
50
+ /**
51
+ * 从输出中抽简短 evidence 行(失败信息 / 测试命令)。
52
+ */
53
+ export declare function extractEvidenceHints(output: string, max?: number): string[];
54
+ export declare function buildRoleSystemPreamble(role: SubAgentRole): string;
55
+ /** 供 /agents 展示的静态角色说明 */
56
+ export declare function formatRolesHelp(): string;
57
+ //# sourceMappingURL=roles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.d.ts","sourceRoot":"","sources":["../../src/agents/roles.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE9D,eAAO,MAAM,cAAc,EAAE,YAAY,EAAuC,CAAC;AAEjF,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,YAAY,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,gBAAgB;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,iCAAiC;AACjC,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,cAAc,CA0CjE,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAQhE;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAgBzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,CAEpE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,cAAc,EAAE,GAAG,SAAS,EACnC,IAAI,EAAE,YAAY,GACjB,cAAc,EAAE,CAIlB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,sBAAsB,GAAG,MAAM,CA+B9E;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,QAAQ,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAClD,CAAC,CAAC;CACJ,CAAC,GACD,MAAM,EAAE,CAqBV;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAI,GAAG,MAAM,EAAE,CAatE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAsBlE;AAED,0BAA0B;AAC1B,wBAAgB,eAAe,IAAI,MAAM,CAgBxC"}
@@ -0,0 +1,198 @@
1
+ // ============================================================
2
+ // Phase 3.2 — 子代理角色与工具白名单
3
+ // explore / implement / review
4
+ // ============================================================
5
+ export const SUBAGENT_ROLES = ["explore", "implement", "review"];
6
+ /** 角色工具白名单(与 ALL_TOOLS 对齐的子集) */
7
+ export const ROLE_DEFINITIONS = {
8
+ explore: {
9
+ id: "explore",
10
+ title: "探索",
11
+ description: "只读探索代码库:search/read/skill/planner/url_fetch,禁止写与 bash。",
12
+ allowedTools: [
13
+ "read",
14
+ "search",
15
+ "code_symbols",
16
+ "lsp",
17
+ "skill",
18
+ "planner",
19
+ "url_fetch",
20
+ ],
21
+ canWrite: false,
22
+ },
23
+ implement: {
24
+ id: "implement",
25
+ title: "实现",
26
+ description: "实现改动:read/search/write/patch/bash/skill/todo,禁止再 spawn subtask。",
27
+ allowedTools: [
28
+ "read",
29
+ "search",
30
+ "code_symbols",
31
+ "lsp",
32
+ "write",
33
+ "patch",
34
+ "bash",
35
+ "skill",
36
+ "todo",
37
+ "planner",
38
+ "url_fetch",
39
+ ],
40
+ canWrite: true,
41
+ },
42
+ review: {
43
+ id: "review",
44
+ title: "审查",
45
+ description: "只读审查:read/search/skill,产出 CRITICAL/HIGH 清单,禁止写与 bash。",
46
+ allowedTools: ["read", "search", "code_symbols", "lsp", "skill", "planner"],
47
+ canWrite: false,
48
+ },
49
+ };
50
+ export function normalizeSubAgentRole(raw) {
51
+ const s = String(raw ?? "implement").trim().toLowerCase();
52
+ if (s === "explore" || s === "探索" || s === "read" || s === "readonly")
53
+ return "explore";
54
+ if (s === "review" || s === "审查" || s === "audit")
55
+ return "review";
56
+ if (s === "implement" || s === "实现" || s === "build" || s === "code")
57
+ return "implement";
58
+ // 未知角色降级为 implement(可写完整能力),但调用方可校验
59
+ if (SUBAGENT_ROLES.includes(s))
60
+ return s;
61
+ return "implement";
62
+ }
63
+ export function isKnownSubAgentRole(raw) {
64
+ const s = String(raw ?? "").trim().toLowerCase();
65
+ if (!s)
66
+ return true; // 缺省合法
67
+ return (s === "explore" ||
68
+ s === "implement" ||
69
+ s === "review" ||
70
+ s === "探索" ||
71
+ s === "实现" ||
72
+ s === "审查" ||
73
+ s === "read" ||
74
+ s === "readonly" ||
75
+ s === "build" ||
76
+ s === "code" ||
77
+ s === "audit");
78
+ }
79
+ export function getRoleDefinition(role) {
80
+ return ROLE_DEFINITIONS[role];
81
+ }
82
+ /**
83
+ * 按角色过滤工具;始终剔除 subtask,防止嵌套。
84
+ */
85
+ export function filterToolsForRole(tools, role) {
86
+ const def = ROLE_DEFINITIONS[role];
87
+ const allow = new Set(def.allowedTools);
88
+ return (tools ?? []).filter((t) => t.name !== "subtask" && allow.has(t.name));
89
+ }
90
+ const RAW_OUTPUT_MAX = 4000;
91
+ /**
92
+ * 父代理只应消费此契约文本,避免整段子会话上浮。
93
+ */
94
+ export function formatSubAgentReturnContract(c) {
95
+ const files = c.filesTouched.length > 0
96
+ ? c.filesTouched.map((f) => ` - ${f}`).join("\n")
97
+ : " (无)";
98
+ const evidence = c.evidence.length > 0
99
+ ? c.evidence.map((e) => ` - ${e}`).join("\n")
100
+ : " (无)";
101
+ let raw = c.rawOutput.trim();
102
+ if (raw.length > RAW_OUTPUT_MAX) {
103
+ raw =
104
+ raw.slice(0, 2000) +
105
+ `\n…[子代理输出已截断 ${raw.length}→${RAW_OUTPUT_MAX}]…\n` +
106
+ raw.slice(-1200);
107
+ }
108
+ return [
109
+ "【子代理回传契约】",
110
+ `role: ${c.role}`,
111
+ `success: ${c.success}`,
112
+ `duration_ms: ${c.durationMs}`,
113
+ `iterations_budget: ${c.iterations}`,
114
+ `summary: ${c.summary || "(空)"}`,
115
+ "files_touched:",
116
+ files,
117
+ "evidence:",
118
+ evidence,
119
+ "output:",
120
+ raw || "(空)",
121
+ ].join("\n");
122
+ }
123
+ /**
124
+ * 从消息历史提取 write/patch 目标路径。
125
+ */
126
+ export function extractFilesTouchedFromMessages(messages) {
127
+ const files = new Set();
128
+ for (const msg of messages) {
129
+ if (msg.role === "assistant" && msg.tool_calls) {
130
+ for (const tc of msg.tool_calls) {
131
+ const name = tc.function?.name ?? "";
132
+ if (name !== "write" && name !== "patch")
133
+ continue;
134
+ try {
135
+ const args = typeof tc.function?.arguments === "string"
136
+ ? JSON.parse(tc.function.arguments)
137
+ : tc.function?.arguments;
138
+ const p = String(args?.path ?? args?.file ?? "").trim();
139
+ if (p)
140
+ files.add(p);
141
+ }
142
+ catch {
143
+ // ignore
144
+ }
145
+ }
146
+ }
147
+ }
148
+ return Array.from(files).sort();
149
+ }
150
+ /**
151
+ * 从输出中抽简短 evidence 行(失败信息 / 测试命令)。
152
+ */
153
+ export function extractEvidenceHints(output, max = 5) {
154
+ const lines = output.split("\n").map((l) => l.trim()).filter(Boolean);
155
+ const hints = [];
156
+ for (const line of lines) {
157
+ if (/error|fail|拒绝|失败|PASS|FAIL|✓|✗|assert|exception/i.test(line) ||
158
+ /npm |node |pytest |cargo |go test/i.test(line)) {
159
+ hints.push(line.slice(0, 160));
160
+ if (hints.length >= max)
161
+ break;
162
+ }
163
+ }
164
+ return hints;
165
+ }
166
+ export function buildRoleSystemPreamble(role) {
167
+ const def = ROLE_DEFINITIONS[role];
168
+ const tools = def.allowedTools.join(", ");
169
+ if (role === "explore") {
170
+ return (`【子代理角色: explore / 探索】\n` +
171
+ `你只做只读探索与总结。可用工具: ${tools}。\n` +
172
+ `禁止修改文件、禁止 bash。最终回复用中文给出:发现、关键路径、建议下一步。`);
173
+ }
174
+ if (role === "review") {
175
+ return (`【子代理角色: review / 审查】\n` +
176
+ `你只做只读代码审查。可用工具: ${tools}。\n` +
177
+ `禁止修改文件、禁止 bash。最终按 CRITICAL/HIGH/MEDIUM/LOW 列表输出,并引用文件路径。`);
178
+ }
179
+ return (`【子代理角色: implement / 实现】\n` +
180
+ `你负责实现指定子任务。可用工具: ${tools}。\n` +
181
+ `禁止再调用 subtask。完成后用中文总结改动与验证方式。`);
182
+ }
183
+ /** 供 /agents 展示的静态角色说明 */
184
+ export function formatRolesHelp() {
185
+ const lines = ["🎭 【子代理角色】subtask role=…", ""];
186
+ for (const id of SUBAGENT_ROLES) {
187
+ const d = ROLE_DEFINITIONS[id];
188
+ lines.push(`- ${d.id}(${d.title})`);
189
+ lines.push(` ${d.description}`);
190
+ lines.push(` 工具: ${d.allowedTools.join(", ")}`);
191
+ lines.push(` 可写: ${d.canWrite ? "是" : "否"}`);
192
+ }
193
+ lines.push("");
194
+ lines.push("示例: subtask task=\"定位登录 bug\" role=explore");
195
+ lines.push("并行(默认关): QLING_SUBTASK_PARALLEL=1 后 subtask tasks=[\"A\",\"B\"] role=explore");
196
+ lines.push("回传: 父上下文只收【子代理回传契约】,不含完整子会话。");
197
+ return lines.join("\n");
198
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkC1C,eAAO,MAAM,aAAa,EAAE,YAS3B,CAAC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAmC1C,eAAO,MAAM,aAAa,EAAE,YAsB3B,CAAC"}
@@ -2,6 +2,7 @@ import { homedir } from "os";
2
2
  import { readdir, readFile } from "fs/promises";
3
3
  import { join } from "path";
4
4
  import { renderAgentsView } from "../cli/mission-views.js";
5
+ import { formatRolesHelp } from "../agents/roles.js";
5
6
  function resolveStateDir(context) {
6
7
  const loop = context.agentLoop;
7
8
  const runtimeRoot = typeof loop.getRuntimeRootDir === "function" ? loop.getRuntimeRootDir() : undefined;
@@ -35,9 +36,22 @@ async function listLocalMissionsReadOnly(stateDir) {
35
36
  export const agentsCommand = {
36
37
  name: "/agents",
37
38
  aliases: ["/代理"],
38
- description: "查看本地后台 mission 分组视图",
39
- usage: "/agents",
40
- execute: async (_args, context) => {
39
+ description: "查看子代理角色说明与本地后台 mission 分组",
40
+ usage: "/agents [roles|missions]",
41
+ execute: async (args, context) => {
42
+ const sub = String(args ?? "").trim().toLowerCase();
43
+ if (sub === "roles" || sub === "角色" || sub === "role") {
44
+ context.writeLine(formatRolesHelp());
45
+ return;
46
+ }
47
+ if (sub === "missions" || sub === "使命" || sub === "mission") {
48
+ const missions = await listLocalMissionsReadOnly(resolveStateDir(context));
49
+ context.writeLine(renderAgentsView(missions));
50
+ return;
51
+ }
52
+ // 默认:角色 + mission 摘要
53
+ context.writeLine(formatRolesHelp());
54
+ context.writeLine("");
41
55
  const missions = await listLocalMissionsReadOnly(resolveStateDir(context));
42
56
  context.writeLine(renderAgentsView(missions));
43
57
  },
@@ -1 +1 @@
1
- {"version":3,"file":"claude-style.d.ts","sourceRoot":"","sources":["../../src/commands/claude-style.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkD1C,eAAO,MAAM,YAAY,EAAE,YA6B1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAiI1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAuGzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YA0C3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YA2CzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YAkC3B,CAAC;AAwBF,eAAO,MAAM,WAAW,EAAE,YA6BzB,CAAC;AAqBF,eAAO,MAAM,WAAW,EAAE,YA0BzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YA6B3B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,YAAY,EAqBnD,CAAC"}
1
+ {"version":3,"file":"claude-style.d.ts","sourceRoot":"","sources":["../../src/commands/claude-style.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkD1C,eAAO,MAAM,YAAY,EAAE,YAsC1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAiI1B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAuGzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YA0C3B,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YA2CzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YAkC3B,CAAC;AAwBF,eAAO,MAAM,WAAW,EAAE,YA6BzB,CAAC;AAqBF,eAAO,MAAM,WAAW,EAAE,YA0BzB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,YA6B3B,CAAC;AAEF,eAAO,MAAM,yBAAyB,EAAE,YAAY,EAqBnD,CAAC"}
@@ -40,7 +40,7 @@ function createUnavailableCommand(name, description, replacement, aliases = [],
40
40
  export const usageCommand = {
41
41
  name: "/usage",
42
42
  aliases: ["/cost", "/stats"],
43
- description: "查看本地 token 与上下文预算使用情况",
43
+ description: "查看 provider 官方 token usage(无预算)",
44
44
  usage: "/usage",
45
45
  category: "session",
46
46
  availability: "local",
@@ -48,20 +48,29 @@ export const usageCommand = {
48
48
  execute: async (_args, context) => {
49
49
  const stats = typeof context.agentLoop.getSessionStats === "function"
50
50
  ? await context.agentLoop.getSessionStats()
51
- : { sessionId: "unknown", turnCount: 0, tokens: 0, tokenSource: "unknown", compactions: 0 };
52
- const maxTokens = Number(process.env.QLING_MAX_TOKEN_BUDGET ?? process.env.QLING_RUNTIME_MAX_TOKEN_BUDGET ?? "120000");
51
+ : {
52
+ sessionId: "unknown",
53
+ turnCount: 0,
54
+ tokens: 0,
55
+ promptTokens: 0,
56
+ completionTokens: 0,
57
+ tokenSource: "unknown",
58
+ compactions: 0,
59
+ };
53
60
  const tokens = Math.max(0, Number(stats.tokens ?? 0));
54
- const pct = Number.isFinite(maxTokens) && maxTokens > 0 ? Math.round((tokens / maxTokens) * 100) : null;
61
+ const promptTokens = Math.max(0, Number(stats.promptTokens ?? 0));
62
+ const completionTokens = Math.max(0, Number(stats.completionTokens ?? 0));
55
63
  context.writeLine("");
56
- context.writeLine("📈 【本地用量】");
64
+ context.writeLine("📈 【Token 用量 · 官方 usage】");
57
65
  context.writeLine("-----------------------------------------");
58
66
  context.writeLine(`Session : ${stats.sessionId ?? "unknown"}`);
59
67
  context.writeLine(`Turns : ${Number(stats.turnCount ?? 0)}`);
60
- context.writeLine(`Tokens : ${tokens.toLocaleString()}`);
68
+ context.writeLine(`Total : ${tokens.toLocaleString()}`);
69
+ context.writeLine(`Input : ${promptTokens.toLocaleString()}`);
70
+ context.writeLine(`Output : ${completionTokens.toLocaleString()}`);
61
71
  context.writeLine(`Source : ${stats.tokenSource ?? "unknown"}`);
62
- context.writeLine(`Context : ${pct === null ? "unknown" : `${pct}% of ${maxTokens.toLocaleString()}`}`);
63
72
  context.writeLine(`Compacts : ${Number(stats.compactions ?? 0)}`);
64
- context.writeLine("边界 : provider usage 优先;缺失时使用本地估算,不代表最终账单。");
73
+ context.writeLine("边界 : 仅累加模型 API 返回的 usage;无本地字符估算、无 token 预算。");
65
74
  context.writeLine("-----------------------------------------");
66
75
  context.writeLine("");
67
76
  },
@@ -205,7 +214,7 @@ export const planCommand = {
205
214
  context.writeLine("🧭 【Plan Mode】");
206
215
  context.writeLine("-----------------------------------------");
207
216
  context.writeLine(`当前模式 : ${mode}`);
208
- context.writeLine("说明 : plan=只读规划(禁 write/patch/bash/subtask/browser_fetch)");
217
+ context.writeLine("说明 : plan=只读规划(禁 write/patch/bash/subtask/browser_fetch/browser_act)");
209
218
  context.writeLine(" : agent=正常工具权限");
210
219
  context.writeLine("用法 : /plan on | /plan off | /plan status");
211
220
  context.writeLine(" : /plan <任务描述> → 进入 plan 并排队计划 prompt");
@@ -253,7 +262,7 @@ export const planCommand = {
253
262
  }
254
263
  const prompt = [
255
264
  "你正处于轻灵 Plan Mode(只读规划)。",
256
- "约束:不要调用 write/patch/bash/subtask/browser_fetch;只做阅读、搜索与计划输出。",
265
+ "约束:不要调用 write/patch/bash/subtask/browser_fetch/browser_act;只做阅读、搜索与计划输出。",
257
266
  "请先给出分步实施计划,标出风险与验证方式,再等待用户确认。",
258
267
  "用户确认后可用 /plan off 退出 Plan Mode 再实施。",
259
268
  "",
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,eAAO,MAAM,UAAU,UA6DtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAWzB,CAAC"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/commands/help.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1C,eAAO,MAAM,UAAU,UA8DtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,YAWzB,CAAC"}
@@ -7,9 +7,10 @@ export const HELP_LINES = [
7
7
  "/init [--force] - 生成轻灵本地项目指南",
8
8
  "/model [list|use <p>|m] - 查看/列出预设/切换模型或 Provider",
9
9
  "/plan [on|off|status|..] - Plan Mode(只读规划,禁写工具)",
10
+ "/mode [status|cycle] - 循环 Agent、Plan 与 Always Agree(Shift+Tab)",
10
11
  "/expand [on|off|status] - 切换长工具输出展开(同 Ctrl+O)",
11
12
  "/plan [description] - 创建普通会话计划请求",
12
- "/usage, /cost, /stats - 查看本地 token 与上下文用量",
13
+ "/usage, /cost, /stats - 查看 provider 官方 token usage",
13
14
  "/diff - 查看当前 Git 变更摘要",
14
15
  "/copy [N] - 复制最近第 N 条 assistant 回复",
15
16
  "/rewind, /undo - 查看可恢复会话点",
@@ -27,7 +28,7 @@ export const HELP_LINES = [
27
28
  "/loop daemon [interval] [prompt] - 创建 daemon-backed durable loop",
28
29
  "/tasks [cancel <id>|clear] - 查看或取消当前 session 的 loop 任务",
29
30
  "/tasks daemon [cancel <id>|clear] - 查看或取消 daemon runner 的 loop 任务",
30
- "/agents, /代理 - 查看本地后台 mission 分组视图",
31
+ "/agents, /代理 - 子代理角色说明 + 本地 mission 分组(roles|missions)",
31
32
  "/mission, /使命 - 查看或控制本地 mission",
32
33
  "/permissions [status|allow|deny|ask] - 查看或切换工具权限默认策略",
33
34
  "/permissions explain <tool> - 解释指定工具的本地权限决策",
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAoC1C,OAAO,EAAE,mBAAmB,EAAsB,MAAM,cAAc,CAAC;AAqBvE,eAAO,MAAM,QAAQ,EAAE,YAAY,EA8ClC,CAAC;AAMF,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,GAAG,aAAa,CAAC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAyDD,wBAAgB,sBAAsB,IAAI,uBAAuB,EAAE,CAalE;AA4CD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,eAAe,EAAE,CAsBvF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,uBAAuB,EAAE,CAyBxF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE,CAO9E;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,SAAI,EAAE,KAAK,SAAK,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAyB1G;AAoBD,wBAAgB,uBAAuB,CAAC,KAAK,SAAK,GAAG,MAAM,EAAE,CAwC5D;AASD,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuBxE;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5D,OAAO,CAAC,OAAO,CAAC,CAgClB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAuC1C,OAAO,EAAE,mBAAmB,EAAsB,MAAM,cAAc,CAAC;AAqBvE,eAAO,MAAM,QAAQ,EAAE,YAAY,EAiDlC,CAAC;AAMF,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,GAAG,aAAa,CAAC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAyDD,wBAAgB,sBAAsB,IAAI,uBAAuB,EAAE,CAalE;AA4CD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,eAAe,EAAE,CAsBvF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,uBAAuB,EAAE,CAyBxF;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,EAAE,CAO9E;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,SAAI,EAAE,KAAK,SAAK,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAyB1G;AAoBD,wBAAgB,uBAAuB,CAAC,KAAK,SAAK,GAAG,MAAM,EAAE,CAwC5D;AASD,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAuBxE;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC5D,OAAO,CAAC,OAAO,CAAC,CAgClB"}
@@ -13,6 +13,7 @@ import { sessionsCommand } from "./sessions.js";
13
13
  import { resumeCommand } from "./resume.js";
14
14
  import { checkpointCommand } from "./checkpoint.js";
15
15
  import { permissionsCommand } from "./permissions.js";
16
+ import { modeCommand } from "./mode.js";
16
17
  import { statuslineCommand } from "./statusline.js";
17
18
  import { doctorCommand } from "./doctor.js";
18
19
  import { contextCommand } from "./context.js";
@@ -33,6 +34,8 @@ import { hooksCommand } from "./hooks.js";
33
34
  import { agentsCommand } from "./agents.js";
34
35
  import { missionCommand } from "./mission.js";
35
36
  import { verifyCommand } from "./verify.js";
37
+ import { recoverCommand } from "./recover.js";
38
+ import { traceCommand } from "./trace.js";
36
39
  import { withDefaultWriters } from "./runtime.js";
37
40
  import { formatFocusedHelp } from "../help-topics.js";
38
41
  import { formatLocalGuidancePanel } from "../cli/guidance-panel.js";
@@ -54,6 +57,7 @@ export const COMMANDS = [
54
57
  usageCommand,
55
58
  modelCommand,
56
59
  planCommand,
60
+ modeCommand,
57
61
  expandCommand,
58
62
  diffCommand,
59
63
  commitCommand,
@@ -78,6 +82,8 @@ export const COMMANDS = [
78
82
  knowledgeCommand,
79
83
  connectCommand,
80
84
  verifyCommand,
85
+ recoverCommand,
86
+ traceCommand,
81
87
  dreamCommand,
82
88
  distillCommand,
83
89
  storageCommand,
@@ -0,0 +1,16 @@
1
+ import type { SlashCommand } from "./types.js";
2
+ type PermissionMode = "allow" | "deny" | "ask";
3
+ interface ModeAgentLoop {
4
+ isPlanMode?: () => boolean;
5
+ setPlanMode?: (enabled: boolean) => void;
6
+ getPermissionMode?: () => PermissionMode;
7
+ setPermissionMode?: (mode: PermissionMode) => void;
8
+ }
9
+ export interface AgentModeSnapshot {
10
+ sessionMode: "agent" | "plan";
11
+ permissionMode: PermissionMode;
12
+ }
13
+ export declare function cycleAgentMode(loop: ModeAgentLoop): AgentModeSnapshot;
14
+ export declare const modeCommand: SlashCommand;
15
+ export {};
16
+ //# sourceMappingURL=mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode.d.ts","sourceRoot":"","sources":["../../src/commands/mode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,KAAK,cAAc,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAE/C,UAAU,aAAa;IACrB,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,iBAAiB,CAAC,EAAE,MAAM,cAAc,CAAC;IACzC,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B,cAAc,EAAE,cAAc,CAAC;CAChC;AASD,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,iBAAiB,CAkBrE;AAiBD,eAAO,MAAM,WAAW,EAAE,YAyBzB,CAAC"}
@@ -0,0 +1,67 @@
1
+ function readMode(loop) {
2
+ return {
3
+ sessionMode: loop.isPlanMode?.() ? "plan" : "agent",
4
+ permissionMode: loop.getPermissionMode?.() ?? "ask",
5
+ };
6
+ }
7
+ export function cycleAgentMode(loop) {
8
+ const current = readMode(loop);
9
+ let next;
10
+ if (current.sessionMode === "plan") {
11
+ next = { sessionMode: "agent", permissionMode: "allow" };
12
+ }
13
+ else if (current.permissionMode === "allow") {
14
+ next = { sessionMode: "agent", permissionMode: "ask" };
15
+ }
16
+ else {
17
+ next = { sessionMode: "plan", permissionMode: "ask" };
18
+ }
19
+ loop.setPlanMode?.(next.sessionMode === "plan");
20
+ loop.setPermissionMode?.(next.permissionMode);
21
+ process.env.QLING_PLAN_MODE = next.sessionMode === "plan" ? "1" : "0";
22
+ process.env.QLING_GUARD_PERMISSIONS_DEFAULT = next.permissionMode;
23
+ process.env.QLING_PERMISSIONS_MODE = next.permissionMode;
24
+ return next;
25
+ }
26
+ function modeLabel(mode) {
27
+ if (mode.sessionMode === "plan")
28
+ return "Plan / ask(只读规划)";
29
+ if (mode.permissionMode === "allow")
30
+ return "Agent / allow(Always Agree)";
31
+ if (mode.permissionMode === "deny")
32
+ return "Agent / deny(默认拒绝)";
33
+ return "Agent / ask(逐次确认)";
34
+ }
35
+ function writeMode(context, mode) {
36
+ context.writeLine("");
37
+ context.writeLine(`⇧ 模式已切换为: ${modeLabel(mode)}`);
38
+ context.writeLine("循环顺序: Agent/ask → Plan → Agent/allow → Agent/ask");
39
+ context.writeLine("边界: 仅当前进程生效;Plan Mode 始终拒绝写工具。");
40
+ context.writeLine("");
41
+ }
42
+ export const modeCommand = {
43
+ name: "/mode",
44
+ aliases: ["/模式"],
45
+ description: "查看或循环 Agent、Plan 与 Always Agree 模式",
46
+ usage: "/mode [status|cycle]",
47
+ category: "session",
48
+ argumentHint: "[status|cycle]",
49
+ examples: ["/mode", "/mode cycle", "/模式 cycle"],
50
+ execute: async (args, context) => {
51
+ const loop = context.agentLoop;
52
+ const action = (args[0] ?? "status").toLowerCase();
53
+ if (typeof loop.setPlanMode !== "function" || typeof loop.setPermissionMode !== "function") {
54
+ context.writeError("❌ 当前 AgentLoop 不支持模式切换。");
55
+ return;
56
+ }
57
+ if (action === "status" || action === "状态") {
58
+ writeMode(context, readMode(loop));
59
+ return;
60
+ }
61
+ if (action !== "cycle" && action !== "循环" && action !== "next") {
62
+ context.writeError("❌ 用法: /mode [status|cycle]");
63
+ return;
64
+ }
65
+ writeMode(context, cycleAgentMode(loop));
66
+ },
67
+ };
@@ -0,0 +1,3 @@
1
+ import type { SlashCommand } from "./types.js";
2
+ export declare const recoverCommand: SlashCommand;
3
+ //# sourceMappingURL=recover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recover.d.ts","sourceRoot":"","sources":["../../src/commands/recover.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,eAAO,MAAM,cAAc,EAAE,YAwD5B,CAAC"}
@@ -0,0 +1,69 @@
1
+ const ACTIONS = new Set(["retry", "next", "edit", "cancel"]);
2
+ export const recoverCommand = {
3
+ name: "/recover",
4
+ aliases: ["/恢复策略"],
5
+ description: "查看或控制暂停中的任务恢复策略",
6
+ usage: "/recover status | retry | next | edit | cancel",
7
+ category: "session",
8
+ argumentHint: "status | retry | next | edit | cancel",
9
+ examples: ["/recover status", "/recover next", "/recover edit"],
10
+ execute: async (args, context) => {
11
+ const agent = context.agentLoop;
12
+ const action = (args[0] ?? "status").toLowerCase();
13
+ if (typeof agent.getRecoveryState !== "function") {
14
+ context.writeError("恢复控制不可用:当前 AgentLoop 未提供恢复状态。");
15
+ return;
16
+ }
17
+ const state = agent.getRecoveryState();
18
+ if (!state) {
19
+ context.writeLine("当前没有可恢复或暂停的执行任务。");
20
+ return;
21
+ }
22
+ if (action === "status") {
23
+ context.writeLine(formatRecoveryStatus(state));
24
+ return;
25
+ }
26
+ if (!ACTIONS.has(action)) {
27
+ context.writeError("用法: /recover status | retry | next | edit | cancel");
28
+ return;
29
+ }
30
+ if (action !== "cancel" && state.status !== "paused") {
31
+ context.writeError("当前没有暂停中的恢复任务。请先等待任务进入 paused,或使用 /recover status 查看状态。");
32
+ return;
33
+ }
34
+ let result;
35
+ try {
36
+ result = agent.applyRecoveryAction(action);
37
+ }
38
+ catch (error) {
39
+ context.writeError(error instanceof Error ? error.message : String(error));
40
+ return;
41
+ }
42
+ if (action === "edit" && result.prompt)
43
+ context.setInputDraft?.(result.prompt);
44
+ if ((action === "retry" || action === "next") && result.state.originalTask) {
45
+ const strategy = result.state.currentStrategy ?? (action === "next" ? "下一条可用策略" : "当前策略");
46
+ const mode = action === "next" ? "请采用下一条不同的恢复策略" : "请按当前恢复策略";
47
+ context.setImmediatePrompt?.(`${mode}(${strategy})继续原任务;不要重复已失败且没有进展的动作:\n${result.state.originalTask}`);
48
+ }
49
+ context.onRecoveryStateChanged?.(action === "cancel" || action === "edit" ? null : result.state);
50
+ context.writeLine(action === "cancel"
51
+ ? "任务已取消,失败摘要已保留。"
52
+ : action === "edit"
53
+ ? "已恢复原任务草稿,当前执行卡片已结束。"
54
+ : `恢复动作已应用: ${action}(策略: ${result.state.currentStrategy ?? "-"})`);
55
+ },
56
+ };
57
+ function formatRecoveryStatus(state) {
58
+ return [
59
+ "恢复状态",
60
+ `阶段: ${state.status}`,
61
+ `失败类别: ${state.lastFailure?.category ?? "-"}`,
62
+ `失败指纹: ${state.lastFailure?.fingerprint ?? "-"}`,
63
+ `策略尝试: ${state.strategyAttempts}`,
64
+ `剩余预算: ${state.remainingStrategyAttempts}`,
65
+ `当前策略: ${state.currentStrategy ?? "-"}`,
66
+ `已尝试策略: ${(state.attemptedStrategies ?? []).join(", ") || "-"}`,
67
+ "动作: /recover retry | next | edit | cancel",
68
+ ].join("\n");
69
+ }
@@ -50,6 +50,8 @@ export interface SlashCommandContext {
50
50
  toggle: () => boolean;
51
51
  };
52
52
  setImmediatePrompt?: (prompt: string) => void;
53
+ setInputDraft?: (draft: string) => void;
54
+ onRecoveryStateChanged?: (state: unknown | null) => void;
53
55
  onModelChanged?: (model: string) => void | Promise<void>;
54
56
  writeClipboard?: (text: string) => Promise<void>;
55
57
  writeLine: (line?: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/commands/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/commands/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAE3E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,CACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;QAC1B,MAAM,EAAE,QAAQ,CAAC;KAClB,KACE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1B,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5H,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAClE,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7D,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9D,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7E,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnD,cAAc,CAAC,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7D,UAAU,CAAC,EAAE;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,mBAAmB,GAAG;QAClE,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAClC,CAAC,GAAG,IAAI,CAAC,CAAC;IACX,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;QACvC,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;KAChC,CAAC;IACF,0BAA0B;IAC1B,UAAU,CAAC,EAAE;QACX,QAAQ,EAAE,OAAO,CAAC;QAClB,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;QACzC,MAAM,EAAE,MAAM,OAAO,CAAC;KACvB,CAAC;IACF,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;IACzD,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG;IAAE,SAAS,EAAE,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GACrF,mBAAmB,CAqBrB"}
@@ -11,6 +11,8 @@ export function withDefaultWriters(context) {
11
11
  statusLine: context.statusLine,
12
12
  toolOutput: context.toolOutput,
13
13
  setImmediatePrompt: context.setImmediatePrompt,
14
+ setInputDraft: context.setInputDraft,
15
+ onRecoveryStateChanged: context.onRecoveryStateChanged,
14
16
  onModelChanged: context.onModelChanged,
15
17
  writeClipboard: context.writeClipboard,
16
18
  writeLine: context.writeLine ?? ((line = "") => console.log(line)),
@@ -0,0 +1,3 @@
1
+ import type { SlashCommand } from "./types.js";
2
+ export declare const traceCommand: SlashCommand;
3
+ //# sourceMappingURL=trace.d.ts.map