@deepwhale/coding-agent 1.0.12 → 1.0.13

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 (162) hide show
  1. package/dist/agent/agent-compaction.d.ts +74 -0
  2. package/dist/agent/agent-compaction.d.ts.map +1 -0
  3. package/dist/agent/agent-compaction.js +145 -0
  4. package/dist/agent/agent-compaction.js.map +1 -0
  5. package/dist/agent/index.d.ts +16 -0
  6. package/dist/agent/index.d.ts.map +1 -0
  7. package/dist/agent/index.js +17 -0
  8. package/dist/agent/index.js.map +1 -0
  9. package/dist/agent/session-adapter.d.ts +177 -0
  10. package/dist/agent/session-adapter.d.ts.map +1 -0
  11. package/dist/agent/session-adapter.js +365 -0
  12. package/dist/agent/session-adapter.js.map +1 -0
  13. package/dist/agent/tool-loop.d.ts +123 -0
  14. package/dist/agent/tool-loop.d.ts.map +1 -0
  15. package/dist/agent/tool-loop.js +436 -0
  16. package/dist/agent/tool-loop.js.map +1 -0
  17. package/dist/env/load-project-env.d.ts +40 -0
  18. package/dist/env/load-project-env.d.ts.map +1 -0
  19. package/dist/env/load-project-env.js +80 -0
  20. package/dist/env/load-project-env.js.map +1 -0
  21. package/dist/index.d.ts +31 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +30 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/llm-factory.d.ts +50 -0
  26. package/dist/llm-factory.d.ts.map +1 -0
  27. package/dist/llm-factory.js +110 -0
  28. package/dist/llm-factory.js.map +1 -0
  29. package/dist/modes/index.d.ts +14 -0
  30. package/dist/modes/index.d.ts.map +1 -0
  31. package/dist/modes/index.js +14 -0
  32. package/dist/modes/index.js.map +1 -0
  33. package/dist/modes/print.d.ts +50 -0
  34. package/dist/modes/print.d.ts.map +1 -0
  35. package/dist/modes/print.js +236 -0
  36. package/dist/modes/print.js.map +1 -0
  37. package/dist/modes/rpc.d.ts +52 -0
  38. package/dist/modes/rpc.d.ts.map +1 -0
  39. package/dist/modes/rpc.js +316 -0
  40. package/dist/modes/rpc.js.map +1 -0
  41. package/dist/modes/tui.d.ts +107 -0
  42. package/dist/modes/tui.d.ts.map +1 -0
  43. package/dist/modes/tui.js +680 -0
  44. package/dist/modes/tui.js.map +1 -0
  45. package/dist/policy/args-digest.d.ts +13 -0
  46. package/dist/policy/args-digest.d.ts.map +1 -0
  47. package/dist/policy/args-digest.js +29 -0
  48. package/dist/policy/args-digest.js.map +1 -0
  49. package/dist/policy/chain.d.ts +19 -0
  50. package/dist/policy/chain.d.ts.map +1 -0
  51. package/dist/policy/chain.js +24 -0
  52. package/dist/policy/chain.js.map +1 -0
  53. package/dist/policy/index.d.ts +17 -0
  54. package/dist/policy/index.d.ts.map +1 -0
  55. package/dist/policy/index.js +16 -0
  56. package/dist/policy/index.js.map +1 -0
  57. package/dist/policy/sanitize-reason.d.ts +11 -0
  58. package/dist/policy/sanitize-reason.d.ts.map +1 -0
  59. package/dist/policy/sanitize-reason.js +24 -0
  60. package/dist/policy/sanitize-reason.js.map +1 -0
  61. package/dist/policy/static-rules.d.ts +32 -0
  62. package/dist/policy/static-rules.d.ts.map +1 -0
  63. package/dist/policy/static-rules.js +106 -0
  64. package/dist/policy/static-rules.js.map +1 -0
  65. package/dist/policy/types.d.ts +56 -0
  66. package/dist/policy/types.d.ts.map +1 -0
  67. package/dist/policy/types.js +13 -0
  68. package/dist/policy/types.js.map +1 -0
  69. package/dist/repl/repl-command-router.d.ts +78 -0
  70. package/dist/repl/repl-command-router.d.ts.map +1 -0
  71. package/dist/repl/repl-command-router.js +112 -0
  72. package/dist/repl/repl-command-router.js.map +1 -0
  73. package/dist/repl/repl-confirm.d.ts +49 -0
  74. package/dist/repl/repl-confirm.d.ts.map +1 -0
  75. package/dist/repl/repl-confirm.js +88 -0
  76. package/dist/repl/repl-confirm.js.map +1 -0
  77. package/dist/repl/repl-session.d.ts +79 -0
  78. package/dist/repl/repl-session.d.ts.map +1 -0
  79. package/dist/repl/repl-session.js +129 -0
  80. package/dist/repl/repl-session.js.map +1 -0
  81. package/dist/repl/repl-signal-coordinator.d.ts +74 -0
  82. package/dist/repl/repl-signal-coordinator.d.ts.map +1 -0
  83. package/dist/repl/repl-signal-coordinator.js +73 -0
  84. package/dist/repl/repl-signal-coordinator.js.map +1 -0
  85. package/dist/repl.d.ts +117 -0
  86. package/dist/repl.d.ts.map +1 -0
  87. package/dist/repl.js +626 -0
  88. package/dist/repl.js.map +1 -0
  89. package/dist/sandbox/docker-runner.d.ts +147 -0
  90. package/dist/sandbox/docker-runner.d.ts.map +1 -0
  91. package/dist/sandbox/docker-runner.js +426 -0
  92. package/dist/sandbox/docker-runner.js.map +1 -0
  93. package/dist/sandbox/env-gate.d.ts +28 -0
  94. package/dist/sandbox/env-gate.d.ts.map +1 -0
  95. package/dist/sandbox/env-gate.js +65 -0
  96. package/dist/sandbox/env-gate.js.map +1 -0
  97. package/dist/sandbox/local-runner.d.ts +29 -0
  98. package/dist/sandbox/local-runner.d.ts.map +1 -0
  99. package/dist/sandbox/local-runner.js +79 -0
  100. package/dist/sandbox/local-runner.js.map +1 -0
  101. package/dist/sandbox/types.d.ts +80 -0
  102. package/dist/sandbox/types.d.ts.map +1 -0
  103. package/dist/sandbox/types.js +25 -0
  104. package/dist/sandbox/types.js.map +1 -0
  105. package/dist/tools/bash.d.ts +35 -0
  106. package/dist/tools/bash.d.ts.map +1 -0
  107. package/dist/tools/bash.js +233 -0
  108. package/dist/tools/bash.js.map +1 -0
  109. package/dist/tools/edit-file.d.ts +22 -0
  110. package/dist/tools/edit-file.d.ts.map +1 -0
  111. package/dist/tools/edit-file.js +79 -0
  112. package/dist/tools/edit-file.js.map +1 -0
  113. package/dist/tools/find.d.ts +21 -0
  114. package/dist/tools/find.d.ts.map +1 -0
  115. package/dist/tools/find.js +168 -0
  116. package/dist/tools/find.js.map +1 -0
  117. package/dist/tools/grep.d.ts +19 -0
  118. package/dist/tools/grep.d.ts.map +1 -0
  119. package/dist/tools/grep.js +170 -0
  120. package/dist/tools/grep.js.map +1 -0
  121. package/dist/tools/index.d.ts +10 -0
  122. package/dist/tools/index.d.ts.map +1 -0
  123. package/dist/tools/index.js +10 -0
  124. package/dist/tools/index.js.map +1 -0
  125. package/dist/tools/read-file.d.ts +18 -0
  126. package/dist/tools/read-file.d.ts.map +1 -0
  127. package/dist/tools/read-file.js +52 -0
  128. package/dist/tools/read-file.js.map +1 -0
  129. package/dist/tools/registry.d.ts +39 -0
  130. package/dist/tools/registry.d.ts.map +1 -0
  131. package/dist/tools/registry.js +67 -0
  132. package/dist/tools/registry.js.map +1 -0
  133. package/dist/tools/write-file.d.ts +18 -0
  134. package/dist/tools/write-file.d.ts.map +1 -0
  135. package/dist/tools/write-file.js +47 -0
  136. package/dist/tools/write-file.js.map +1 -0
  137. package/dist/tui-ink-bundle.js +38587 -0
  138. package/dist/types.d.ts +89 -0
  139. package/dist/types.d.ts.map +1 -0
  140. package/dist/types.js +5 -0
  141. package/dist/types.js.map +1 -0
  142. package/dist/util/index.d.ts +16 -0
  143. package/dist/util/index.d.ts.map +1 -0
  144. package/dist/util/index.js +16 -0
  145. package/dist/util/index.js.map +1 -0
  146. package/dist/util/tui-history.d.ts +37 -0
  147. package/dist/util/tui-history.d.ts.map +1 -0
  148. package/dist/util/tui-history.js +93 -0
  149. package/dist/util/tui-history.js.map +1 -0
  150. package/dist/verify/format-report.d.ts +57 -0
  151. package/dist/verify/format-report.d.ts.map +1 -0
  152. package/dist/verify/format-report.js +128 -0
  153. package/dist/verify/format-report.js.map +1 -0
  154. package/dist/verify/index.d.ts +8 -0
  155. package/dist/verify/index.d.ts.map +1 -0
  156. package/dist/verify/index.js +8 -0
  157. package/dist/verify/index.js.map +1 -0
  158. package/dist/verify/verify-runner.d.ts +186 -0
  159. package/dist/verify/verify-runner.d.ts.map +1 -0
  160. package/dist/verify/verify-runner.js +707 -0
  161. package/dist/verify/verify-runner.js.map +1 -0
  162. package/package.json +1 -1
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @deepwhale/coding-agent — LLM provider factory
3
+ *
4
+ * Sprint 1b.5 Step 2 (2.5 拍板, C3 拍板 2026-06-03):
5
+ * REPL 启动时 provider 怎么选, 拍板为 "env 推断 + flag 显式覆盖":
6
+ * 1. options.provider 显式给 → 优先用显式值 (REPL --provider flag)
7
+ * 2. options.provider 未给 → 看 env:
8
+ * - DEEPWHALE_PROVIDER=deepseek|anthropic 显式设 → 用该值 (D-21.1 拍板,
9
+ * 让 shell user 一行 set 决断, 不必 unset 另一个 key)
10
+ * - ANTHROPIC_AUTH_TOKEN 设了 + DEEPSEEK_API_KEY 没设 → anthropic (走 DeepSeek shim)
11
+ * - DEEPSEEK_API_KEY 设了 + ANTHROPIC_AUTH_TOKEN 没设 → deepseek
12
+ * - 两个都设了 → 报错 (静默走错 provider 误用 API key 是 P0 风险)
13
+ * - 两个都没设 → 报错 (让 user 知道必须设 key)
14
+ *
15
+ * 设计原则 (Hermes 1a follow-up #2 lesson):
16
+ * - 不**静默** default 到某个 provider, 必报清晰错
17
+ * - DEEPWHALE_PROVIDER 是 "user 决断" 显式语义, 优先级高于 env 推断
18
+ * - 不**做**汇率换算 / 跨 provider 兼容 (DeepSeek shim 走同一 endpoint, 接口层隔离)
19
+ * - 注入点已存在 (ReplOptions.client), factory 只在 startRepl 入口用
20
+ */
21
+ import { AnthropicClient, DeepSeekClient, type LLMClient } from '@deepwhale/llm';
22
+ export type Provider = 'deepseek' | 'anthropic';
23
+ export interface CreateClientOptions {
24
+ /** 显式 provider. 跟 env 推断冲突时, 优先用显式值 + warn. */
25
+ provider?: Provider;
26
+ /** 显式 model ID. 不传则用 provider 默认 (deepseek → deepseek-v4-flash, anthropic → claude-sonnet-4-5). */
27
+ model?: string;
28
+ }
29
+ /**
30
+ * C3 拍板: env 推断 + flag 显式覆盖.
31
+ * - provider 显式给 → 走 provider (不再读 env, 显式胜出)
32
+ * - provider 未给 → 看 env (ANTHROPIC_AUTH_TOKEN vs DEEPSEEK_API_KEY)
33
+ * - provider 显式 + env 也设了不一致 → 显式胜出, 不报错 (user 知道自己传了啥)
34
+ * - 都没设 → 报错 (跟 1b 时代 APIKeyMissingError 行为一致, 引导 user 设 env)
35
+ */
36
+ export declare function createDefaultClient(options?: CreateClientOptions): LLMClient;
37
+ /**
38
+ * 公开 env key 解析, 给 mode 层 (repl/print/rpc) 显式判断 provider 用.
39
+ * 跟 AnthropicClient.resolveApiKey 内部逻辑**保持一致**: ANTHROPIC_AUTH_TOKEN 优先,
40
+ * DEEPSEEK_API_KEY 退路. 不抛 (返 undefined 让 caller 决定).
41
+ */
42
+ export declare function resolveAnthropicApiKey(): string | undefined;
43
+ /**
44
+ * 重新导出 Re-export 给 cli.ts 入口, 让 cli.ts 不必直接 import from @deepwhale/llm
45
+ * (单测 mock LLMClient 时, 走 @deepwhale/coding-agent/llm-factory 一处 import 即可).
46
+ *
47
+ * Provider + CreateClientOptions type 已在上面 line 22-25 export, 这里只 re-export class.
48
+ */
49
+ export { AnthropicClient, DeepSeekClient };
50
+ //# sourceMappingURL=llm-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-factory.d.ts","sourceRoot":"","sources":["../src/llm-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,KAAK,SAAS,EAAsB,MAAM,gBAAgB,CAAC;AAErG,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC;AAEhD,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,mGAAmG;IACnG,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,mBAAwB,GAAG,SAAS,CAchF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAM3D;AAiDD;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * @deepwhale/coding-agent — LLM provider factory
3
+ *
4
+ * Sprint 1b.5 Step 2 (2.5 拍板, C3 拍板 2026-06-03):
5
+ * REPL 启动时 provider 怎么选, 拍板为 "env 推断 + flag 显式覆盖":
6
+ * 1. options.provider 显式给 → 优先用显式值 (REPL --provider flag)
7
+ * 2. options.provider 未给 → 看 env:
8
+ * - DEEPWHALE_PROVIDER=deepseek|anthropic 显式设 → 用该值 (D-21.1 拍板,
9
+ * 让 shell user 一行 set 决断, 不必 unset 另一个 key)
10
+ * - ANTHROPIC_AUTH_TOKEN 设了 + DEEPSEEK_API_KEY 没设 → anthropic (走 DeepSeek shim)
11
+ * - DEEPSEEK_API_KEY 设了 + ANTHROPIC_AUTH_TOKEN 没设 → deepseek
12
+ * - 两个都设了 → 报错 (静默走错 provider 误用 API key 是 P0 风险)
13
+ * - 两个都没设 → 报错 (让 user 知道必须设 key)
14
+ *
15
+ * 设计原则 (Hermes 1a follow-up #2 lesson):
16
+ * - 不**静默** default 到某个 provider, 必报清晰错
17
+ * - DEEPWHALE_PROVIDER 是 "user 决断" 显式语义, 优先级高于 env 推断
18
+ * - 不**做**汇率换算 / 跨 provider 兼容 (DeepSeek shim 走同一 endpoint, 接口层隔离)
19
+ * - 注入点已存在 (ReplOptions.client), factory 只在 startRepl 入口用
20
+ */
21
+ import { AnthropicClient, DeepSeekClient, APIKeyMissingError } from '@deepwhale/llm';
22
+ /**
23
+ * C3 拍板: env 推断 + flag 显式覆盖.
24
+ * - provider 显式给 → 走 provider (不再读 env, 显式胜出)
25
+ * - provider 未给 → 看 env (ANTHROPIC_AUTH_TOKEN vs DEEPSEEK_API_KEY)
26
+ * - provider 显式 + env 也设了不一致 → 显式胜出, 不报错 (user 知道自己传了啥)
27
+ * - 都没设 → 报错 (跟 1b 时代 APIKeyMissingError 行为一致, 引导 user 设 env)
28
+ */
29
+ export function createDefaultClient(options = {}) {
30
+ const resolved = resolveProvider(options.provider);
31
+ switch (resolved) {
32
+ case 'deepseek':
33
+ return new DeepSeekClient({ ...(options.model !== undefined ? { model: options.model } : {}) });
34
+ case 'anthropic':
35
+ // Sprint 1b.5 Step 2.5 (F1 拍板, review 2026-06-03): 不**传** apiKey, 让 AnthropicClient
36
+ // 内部 resolveApiKey() 读 env. 之前传 'placeholder' 是测试 mock 路径留下的 bug, 会**盖**
37
+ // 真实 env ANTHROPIC_AUTH_TOKEN / DEEPSEEK_API_KEY, Step 3 真接会 401.
38
+ //
39
+ // X3 拍板: 测试场景单测 mock fetch, 不**走**真 HTTP, apiKey 走 env 也无所谓.
40
+ // 真要测试"不传 apiKey 时 constructor 抛" 的路径, 显式 inject options.apiKey.
41
+ return new AnthropicClient({ ...(options.model !== undefined ? { model: options.model } : {}) });
42
+ }
43
+ }
44
+ /**
45
+ * 公开 env key 解析, 给 mode 层 (repl/print/rpc) 显式判断 provider 用.
46
+ * 跟 AnthropicClient.resolveApiKey 内部逻辑**保持一致**: ANTHROPIC_AUTH_TOKEN 优先,
47
+ * DEEPSEEK_API_KEY 退路. 不抛 (返 undefined 让 caller 决定).
48
+ */
49
+ export function resolveAnthropicApiKey() {
50
+ const anthropic = process.env['ANTHROPIC_AUTH_TOKEN'];
51
+ if (anthropic !== undefined && anthropic !== '')
52
+ return anthropic;
53
+ const deepseek = process.env['DEEPSEEK_API_KEY'];
54
+ if (deepseek !== undefined && deepseek !== '')
55
+ return deepseek;
56
+ return undefined;
57
+ }
58
+ /**
59
+ * 解析 provider (env 推断 + flag 显式).
60
+ * 显式给 → 直接返, 跳过 env 推断.
61
+ * 显式未给 → 看 env:
62
+ * - 都没设 → 抛 APIKeyMissingError (跟 1b 时代一致, 引导 user)
63
+ * - 都设了 → 抛 'both-set' 错误 (P0 风险, 强制 user 决断)
64
+ * - 只设一个 → 返那个
65
+ *
66
+ * Sprint 1c-revive-2-D-21.1 (2026-06-06, 修 Anthropic wins tiebreak bug):
67
+ * 之前 if-else 顺序是 "hasAnthropic 排第一", 跟产品 "DeepSeek-first" 品牌
68
+ * (README:18 / package.json:6 / DeepSeekClient 默认 model=deepseek-v4-flash)
69
+ * 矛盾. 两个都设的实情被 tryCreateClient catch 静默 + tryCreateClient
70
+ * 自身的 fallback 让用户误以为"在走 anthropic". 拍板: 跟品牌一致,
71
+ * hasDeepseek 排第一; 都设的 error 信息明示用户可以传 --provider 决断.
72
+ * 行为兼容: 单 key 路径 (只设 Anthropic 或只设 DeepSeek) 完全不变.
73
+ */
74
+ function resolveProvider(explicit) {
75
+ // 优先级: 显式 options.provider > DEEPWHALE_PROVIDER env > 单 key 推断.
76
+ if (explicit !== undefined)
77
+ return explicit;
78
+ // Sprint 1c-revive-2-D-21.1 (2026-06-06): DEEPWHALE_PROVIDER 让 user shell 一行
79
+ // 决断 (e.g. `DEEPWHALE_PROVIDER=deepseek deepwhale` 即使两个 key 都设了也走 deepseek).
80
+ const providerEnv = process.env['DEEPWHALE_PROVIDER'];
81
+ if (providerEnv === 'deepseek' || providerEnv === 'anthropic') {
82
+ return providerEnv;
83
+ }
84
+ // DEEPWHALE_PROVIDER 设了非法值: 静默 fall through 到 env 推断, 不让 typo
85
+ // (e.g. `DEEPWHALE_PROVIDER=depseek`) 整个 CLI 崩. 拍板: 静默忽略, 因为
86
+ // "拼错" 不该是 fatal, user 该看到下面的 "Both set" 错才知道哪里设错了.
87
+ const hasAnthropic = (process.env['ANTHROPIC_AUTH_TOKEN'] ?? '') !== '';
88
+ const hasDeepseek = (process.env['DEEPSEEK_API_KEY'] ?? '') !== '';
89
+ if (hasAnthropic && hasDeepseek) {
90
+ throw new APIKeyMissingError('Both ANTHROPIC_AUTH_TOKEN and DEEPSEEK_API_KEY are set. ' +
91
+ 'Unset one, or set DEEPWHALE_PROVIDER=<deepseek|anthropic>, or pass --provider <name>. ' +
92
+ 'This is a safety check to prevent silently using the wrong provider with the wrong API key. ' +
93
+ 'Note: DeepWhale is DeepSeek-first (default model: deepseek-v4-flash).');
94
+ }
95
+ if (hasDeepseek)
96
+ return 'deepseek';
97
+ if (hasAnthropic)
98
+ return 'anthropic';
99
+ throw new APIKeyMissingError('No LLM API key set. Set DEEPSEEK_API_KEY (DeepSeek) or ' +
100
+ 'ANTHROPIC_AUTH_TOKEN (Anthropic, via DeepSeek shim /anthropic endpoint) ' +
101
+ 'environment variable, or pass --provider explicitly.');
102
+ }
103
+ /**
104
+ * 重新导出 Re-export 给 cli.ts 入口, 让 cli.ts 不必直接 import from @deepwhale/llm
105
+ * (单测 mock LLMClient 时, 走 @deepwhale/coding-agent/llm-factory 一处 import 即可).
106
+ *
107
+ * Provider + CreateClientOptions type 已在上面 line 22-25 export, 这里只 re-export class.
108
+ */
109
+ export { AnthropicClient, DeepSeekClient };
110
+ //# sourceMappingURL=llm-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-factory.js","sourceRoot":"","sources":["../src/llm-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAkB,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAWrG;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA+B,EAAE;IACnE,MAAM,QAAQ,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,UAAU;YACb,OAAO,IAAI,cAAc,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAClG,KAAK,WAAW;YACd,oFAAoF;YACpF,yEAAyE;YACzE,kEAAkE;YAClE,EAAE;YACF,6DAA6D;YAC7D,iEAAiE;YACjE,OAAO,IAAI,eAAe,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACrG,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAClE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACjD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC/D,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,eAAe,CAAC,QAA8B;IACrD,gEAAgE;IAChE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IAC5C,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtD,IAAI,WAAW,KAAK,UAAU,IAAI,WAAW,KAAK,WAAW,EAAE,CAAC;QAC9D,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,8DAA8D;IAC9D,6DAA6D;IAC7D,oDAAoD;IACpD,MAAM,YAAY,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;IACxE,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;IACnE,IAAI,YAAY,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,kBAAkB,CAC1B,0DAA0D;YACxD,wFAAwF;YACxF,8FAA8F;YAC9F,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,WAAW;QAAE,OAAO,UAAU,CAAC;IACnC,IAAI,YAAY;QAAE,OAAO,WAAW,CAAC;IACrC,MAAM,IAAI,kBAAkB,CAC1B,yDAAyD;QACvD,0EAA0E;QAC1E,sDAAsD,CACzD,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @deepwhale/coding-agent/modes — CLI 运行模式
3
+ *
4
+ * Sprint 1a 落地:
5
+ * - interactive: REPL(repl.ts 已有,bin 直接复用 startRepl)
6
+ * - print: 一次性 chat + tool loop(脚本/CI 友好)
7
+ * - rpc: NDJSON over stdio(编辑器/LSP 集成用)
8
+ *
9
+ * Sprint 1b 再加:rpc method 注册表(initialize / chat / cancel / shutdown)。
10
+ */
11
+ export { runPrintMode } from './print.js';
12
+ export { runRpcMode } from './rpc.js';
13
+ export { runTuiMode } from './tui.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @deepwhale/coding-agent/modes — CLI 运行模式
3
+ *
4
+ * Sprint 1a 落地:
5
+ * - interactive: REPL(repl.ts 已有,bin 直接复用 startRepl)
6
+ * - print: 一次性 chat + tool loop(脚本/CI 友好)
7
+ * - rpc: NDJSON over stdio(编辑器/LSP 集成用)
8
+ *
9
+ * Sprint 1b 再加:rpc method 注册表(initialize / chat / cancel / shutdown)。
10
+ */
11
+ export { runPrintMode } from './print.js';
12
+ export { runRpcMode } from './rpc.js';
13
+ export { runTuiMode } from './tui.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Print 模式 — Sprint 1a
3
+ *
4
+ * 一次性 chat(默认)+ tool loop:接 -p prompt,跑完退出。
5
+ *
6
+ * 用法:
7
+ * deepwhale -p "列出当前目录"
8
+ *
9
+ * 行为契约:
10
+ * - enableToolLoop=true(默认):接 tool loop(runToolLoop + createDefaultRegistry)
11
+ * - enableToolLoop=false(--no-tool-loop):纯 chat,**完全不暴露 tools schema 给 LLM**,
12
+ * 不调任何工具。即使 LLM 想调 tool_calls,client 端 tools=undefined,
13
+ * LLM 服务端收到请求 schema 不含 tools,会回纯文本 content。
14
+ * - 流式输出到 stdout(不缓冲)
15
+ * - 退出码:0 正常 / 1 错误 / 2 用法错
16
+ *
17
+ * Sprint 1a 简化:不读 stdin,只读 -p 参数。
18
+ */
19
+ import { type LLMClient } from '@deepwhale/llm';
20
+ import { type AgentCompactionConfig } from '../agent/index.js';
21
+ import { type Provider } from '../llm-factory.js';
22
+ export interface PrintModeOptions {
23
+ prompt: string;
24
+ sessionPath?: string;
25
+ enableToolLoop?: boolean;
26
+ maxSteps?: number;
27
+ /**
28
+ * 注入 LLM 客户端(默认 createDefaultClient env 推断, Sprint 1b.5 Step 2.5 C3 拍板)。
29
+ * Sprint 1a follow-up: 单测用。
30
+ */
31
+ client?: LLMClient;
32
+ /** Sprint 1b.5 Step 2.5: 显式 provider, 跟 env 推断冲突时优先. */
33
+ provider?: Provider;
34
+ /** Sprint 1b.5 Step 2.5: 显式 model. 不传则用 provider 默认. */
35
+ model?: string;
36
+ /**
37
+ * Session compaction 集成 (Sprint 1c-revive-2-D-6, review P1 修复 2026-06-04).
38
+ * 不传 = baseline (走 runToolLoop). 传 = 走 runToolLoopWithCompaction.
39
+ * 拍板: writer 字段 print mode 内部构造 (跟 sessionPath 同 instance).
40
+ */
41
+ compactionConfig?: Omit<AgentCompactionConfig, 'writer' | 'state'> | null;
42
+ /**
43
+ * Sprint 1c-revive-3-D-13 (2026-06-05): --yes 标志.
44
+ * yes=true bypass require_confirmation (write_file / edit_file / 危险 bash).
45
+ * 不 bypass deny. 拍板: print mode 默认 isInteractive=false + policy=staticToolPolicy.
46
+ */
47
+ yes?: boolean;
48
+ }
49
+ export declare function runPrintMode(options: PrintModeOptions): Promise<number>;
50
+ //# sourceMappingURL=print.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.d.ts","sourceRoot":"","sources":["../../src/modes/print.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAoB,KAAK,SAAS,EAAsB,MAAM,gBAAgB,CAAC;AAEtF,OAAO,EAML,KAAK,qBAAqB,EAG3B,MAAM,mBAAmB,CAAC;AAI3B,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIvE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1E;;;;OAIG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmL7E"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Print 模式 — Sprint 1a
3
+ *
4
+ * 一次性 chat(默认)+ tool loop:接 -p prompt,跑完退出。
5
+ *
6
+ * 用法:
7
+ * deepwhale -p "列出当前目录"
8
+ *
9
+ * 行为契约:
10
+ * - enableToolLoop=true(默认):接 tool loop(runToolLoop + createDefaultRegistry)
11
+ * - enableToolLoop=false(--no-tool-loop):纯 chat,**完全不暴露 tools schema 给 LLM**,
12
+ * 不调任何工具。即使 LLM 想调 tool_calls,client 端 tools=undefined,
13
+ * LLM 服务端收到请求 schema 不含 tools,会回纯文本 content。
14
+ * - 流式输出到 stdout(不缓冲)
15
+ * - 退出码:0 正常 / 1 错误 / 2 用法错
16
+ *
17
+ * Sprint 1a 简化:不读 stdin,只读 -p 参数。
18
+ */
19
+ import process from 'node:process';
20
+ import { APIKeyMissingError } from '@deepwhale/llm';
21
+ import { SessionReader, SessionWriter } from '@deepwhale/core';
22
+ import { isToolLoopError, loadSession, persistToolLoopSteps, runToolLoop, runToolLoopWithCompaction, } from '../agent/index.js';
23
+ import { CompactionState } from '@deepwhale/core';
24
+ import { createDefaultRegistry } from '../tools/registry.js';
25
+ import { formatUsageStatus } from '../repl.js';
26
+ import { createDefaultClient } from '../llm-factory.js';
27
+ import { resolveSandboxRunnerFromEnv } from '../sandbox/env-gate.js';
28
+ import { staticToolPolicy } from '../policy/static-rules.js';
29
+ export async function runPrintMode(options) {
30
+ // Sprint 1b.5 Step 2.5: print mode 跟 startRepl 一样, 用 createDefaultClient 让 provider
31
+ // 走 env 推断 + 显式 provider 优先 (C3 拍板). 不再写死 DeepSeekClient.
32
+ const client = options.client ??
33
+ createDefaultClient({
34
+ ...(options.provider !== undefined ? { provider: options.provider } : {}),
35
+ ...(options.model !== undefined ? { model: options.model } : {}),
36
+ });
37
+ // Sprint 1c-revive-2-D-6 (review P2 修复, 2026-06-04): 拿掉 anthropic × tool loop
38
+ // 温柔降级 (跟 startRepl 同拍板, 见 repl.ts). D-4 已实装 AnthropicClient tool
39
+ // schema 转换, --provider anthropic 选了就该跑 tool loop.
40
+ const enableToolLoop = options.enableToolLoop ?? true;
41
+ const sessionPath = options.sessionPath;
42
+ // Sprint 1c-revive-3-D-12 review P1 修复 (2026-06-05): 入口解析 sandbox env.
43
+ // 未知值 throw (fail-closed), 由 CLI `main().catch` 写到 stderr + exit 1.
44
+ // 解析成功则把 runner 显式注入 registry, 跟 BashTool 对齐.
45
+ const sandboxRunner = resolveSandboxRunnerFromEnv({ sandboxRoot: process.cwd() });
46
+ // Sprint 1c-revive-3-D-13 (2026-06-05): print mode 拍板 isInteractive=false
47
+ // (非交互, 无用户确认). default policy = staticToolPolicy. --yes 透传 bypass
48
+ // require_confirmation, 不 bypass deny.
49
+ const policyYes = options.yes ?? false;
50
+ // session 加载
51
+ let workingMessages = [];
52
+ const writer = sessionPath ? new SessionWriter(sessionPath) : null;
53
+ const reader = sessionPath ? new SessionReader(sessionPath) : null;
54
+ if (writer && reader) {
55
+ try {
56
+ await writer.open();
57
+ const loaded = await loadSession(reader);
58
+ workingMessages = [...loaded.messages];
59
+ }
60
+ catch (e) {
61
+ process.stderr.write(`warning: could not load session: ${String(e)}\n`);
62
+ }
63
+ }
64
+ // Sprint 1c-revive-2-D-6 (review P1 修复, 2026-06-04): compaction 集成.
65
+ // 传 options.compactionConfig + writer 存在 → 注入完整 AgentCompactionConfig.
66
+ let compactionConfig = null;
67
+ if (options.compactionConfig && writer) {
68
+ compactionConfig = {
69
+ ...options.compactionConfig,
70
+ writer,
71
+ state: new CompactionState(options.compactionConfig.pauseAfterFailures ?? 2),
72
+ };
73
+ }
74
+ else if (options.compactionConfig && !writer) {
75
+ process.stderr.write('warning: compactionConfig requires sessionPath; falling back to baseline (no compaction).\n');
76
+ }
77
+ try {
78
+ // 持久化 user 输入
79
+ if (writer) {
80
+ const userEvent = { kind: 'user', ts: Date.now(), content: options.prompt };
81
+ await writer.append(userEvent);
82
+ }
83
+ // 构造 turn 消息:历史 + 本轮 user。Sprint 1a 修 P1 — user 必须进 LLM。
84
+ const turnMessages = [
85
+ ...workingMessages,
86
+ { role: 'user', content: options.prompt },
87
+ ];
88
+ // 调 LLM。两种模式分支:
89
+ // - enableToolLoop=true (默认): 走 runToolLoop (有 compactionConfig 时走
90
+ // runToolLoopWithCompaction, Sprint 1c-revive-2-D-6 拍板), 创 registry
91
+ // - enableToolLoop=false (--no-tool-loop): 走 client.stream 直发,
92
+ // tools 字段不传, 强制 LLM 服务端 schema 里不出现 tool, 不会产生 tool_calls
93
+ const summaryFn = compactionConfig
94
+ ? makeLlmSummarizeFn(client, compactionConfig.protocol)
95
+ : null;
96
+ let result;
97
+ try {
98
+ if (enableToolLoop) {
99
+ if (compactionConfig !== null && summaryFn !== null) {
100
+ result = await runToolLoopWithCompaction(client, turnMessages, {
101
+ registry: createDefaultRegistry({ sandboxRunner }),
102
+ onChunk: (chunk) => {
103
+ if (chunk.content)
104
+ process.stdout.write(chunk.content);
105
+ },
106
+ ...(options.maxSteps !== undefined ? { maxSteps: options.maxSteps } : {}),
107
+ policy: staticToolPolicy,
108
+ isInteractive: false, // print mode = 非交互 (D-13 拍板)
109
+ yes: policyYes,
110
+ ...(writer ? { writer } : {}),
111
+ }, compactionConfig, summaryFn);
112
+ }
113
+ else {
114
+ result = await runToolLoop(client, turnMessages, {
115
+ registry: createDefaultRegistry({ sandboxRunner }),
116
+ onChunk: (chunk) => {
117
+ if (chunk.content)
118
+ process.stdout.write(chunk.content);
119
+ },
120
+ ...(options.maxSteps !== undefined ? { maxSteps: options.maxSteps } : {}),
121
+ policy: staticToolPolicy,
122
+ isInteractive: false, // print mode = 非交互 (D-13 拍板)
123
+ yes: policyYes,
124
+ ...(writer ? { writer } : {}),
125
+ });
126
+ }
127
+ printStepSummary(result.steps);
128
+ }
129
+ else {
130
+ // --no-tool-loop: 真关闭 tool calling。流式 + tools=undefined,
131
+ // 让 LLM 服务端只回 content, 不返回 tool_calls 字段。
132
+ // stream() 内部已累加好 final.content, 这里只负责把增量实写到 stdout。
133
+ // 注意: client.stream 的 onChunk 接 ChatChunk, content 在 delta.content 上
134
+ // (与 runToolLoop 的 onChunk 签名不同, 后者直接 .content)。
135
+ const streamResult = await client.stream(turnMessages, {
136
+ onChunk: (chunk) => {
137
+ if (chunk.delta.content)
138
+ process.stdout.write(chunk.delta.content);
139
+ },
140
+ });
141
+ // 包装成 ToolLoopResult 形态,让 caller 持久化逻辑无感
142
+ result = {
143
+ messages: [...turnMessages, { role: 'assistant', content: streamResult.content }],
144
+ final: streamResult,
145
+ steps: [
146
+ {
147
+ kind: 'assistant',
148
+ ts: Date.now(),
149
+ message: { role: 'assistant', content: streamResult.content },
150
+ result: streamResult,
151
+ },
152
+ ],
153
+ };
154
+ }
155
+ }
156
+ catch (e) {
157
+ if (isToolLoopError(e)) {
158
+ process.stderr.write(`\nerror: tool loop hit max steps (${e.steps})\n`);
159
+ }
160
+ else if (e instanceof APIKeyMissingError) {
161
+ // Sprint 1c-revive-4-D-20.1 (2026-06-05) review-fix: print mode 缺 key
162
+ // 给 setup hint + 退出码 2 (跟参数错一致), 跟 CLI main().catch 拍板一致.
163
+ process.stderr.write('Error: API key not set. deepwhale needs DEEPSEEK_API_KEY (or ANTHROPIC_AUTH_TOKEN),\n' +
164
+ ' or pass --provider. See --help for full setup.\n' +
165
+ ' Hint: --verify runs build/lint/typecheck/test and does NOT need a key.\n' +
166
+ ` Underlying: ${e.message}\n`);
167
+ return 2;
168
+ }
169
+ else {
170
+ process.stderr.write(`\nerror: ${e instanceof Error ? e.message : String(e)}\n`);
171
+ }
172
+ return 1;
173
+ }
174
+ // 持久化 steps
175
+ if (writer) {
176
+ try {
177
+ await persistToolLoopSteps(writer, result.steps);
178
+ }
179
+ catch {
180
+ /* best-effort */
181
+ }
182
+ }
183
+ // Sprint 1b: 退出后打一行 cache / cost summary 到 stderr (不污染 stdout)
184
+ // 跟 REPL 状态栏用同一个 formatUsageStatus, 风格统一
185
+ const usageLine = formatUsageStatus(result.final.usage);
186
+ if (usageLine !== null) {
187
+ process.stderr.write(` ${usageLine}\n`);
188
+ }
189
+ return 0;
190
+ }
191
+ finally {
192
+ if (writer) {
193
+ try {
194
+ await writer.close();
195
+ }
196
+ catch {
197
+ /* best-effort */
198
+ }
199
+ }
200
+ }
201
+ }
202
+ function printStepSummary(steps) {
203
+ for (const step of steps) {
204
+ if (step.kind === 'tool') {
205
+ const status = step.result.success ? '✓' : '✗';
206
+ process.stdout.write(` ${status} ${step.tool_call.name} (${step.duration_ms}ms)\n`);
207
+ }
208
+ }
209
+ }
210
+ /**
211
+ * 生成 LLM summary callback (Sprint 1c-revive-2-D-6).
212
+ *
213
+ * 跟 1c-revive-2-D-5 cluster test (compaction-cross-protocol-2d5.test.ts:231)
214
+ * + startRepl 同形态 helper 拍板一致. 跨 openai/anthropic 同形态 (走
215
+ * LLMClient 统一契约).
216
+ */
217
+ function makeLlmSummarizeFn(client, _protocol) {
218
+ return async (toSummarize) => {
219
+ const summaryMessages = [
220
+ {
221
+ role: 'system',
222
+ content: 'You are a concise summarizer. Compress the following conversation into 1 short paragraph ' +
223
+ '(max 200 words). Preserve key arithmetic results, tool calls, and final answers.',
224
+ },
225
+ {
226
+ role: 'user',
227
+ content: toSummarize
228
+ .map((m, i) => `[${i}] ${m.role}: ${m.content ?? '(empty)'}`)
229
+ .join('\n'),
230
+ },
231
+ ];
232
+ const r = await client.chat(summaryMessages, {});
233
+ return r.content;
234
+ };
235
+ }
236
+ //# sourceMappingURL=print.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.js","sourceRoot":"","sources":["../../src/modes/print.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * RPC 模式 — Sprint 1a stub
3
+ *
4
+ * NDJSON over stdio(Codex / oh-my-pi 借鉴):每行 = 1 个 JSON object。
5
+ * - request: { id, method, params }
6
+ * - response: { id, result | error }
7
+ * - notification: { method, params } // server push,无 id
8
+ *
9
+ * Sprint 1a stub 范围:
10
+ * - 实现 NDJSON line parser + writer
11
+ * - 实现 1 个 method: 'chat'(复用 runPrintMode 逻辑)
12
+ * - 拒绝其他 method 返回 "method not found"
13
+ * - Ctrl-C 优雅退出
14
+ *
15
+ * Sprint 1b 扩展:
16
+ * - initialize / cancel / shutdown
17
+ * - session 加载/恢复/分支
18
+ * - streaming 增量推送(sse-like notifications)
19
+ */
20
+ import { type LLMClient } from '@deepwhale/llm';
21
+ import { type AgentCompactionConfig } from '../agent/index.js';
22
+ import { type Provider } from '../llm-factory.js';
23
+ export interface RpcModeOptions {
24
+ sessionPath?: string;
25
+ maxSteps?: number;
26
+ /** 注入 LLM 客户端(默认 createDefaultClient env 推断, Sprint 1c-revive-2-D-5+ P2)。 */
27
+ client?: LLMClient;
28
+ /** Sprint 1c-revive-2-D-5+ P2: 显式 provider, 跟 env 推断冲突时优先. */
29
+ provider?: Provider;
30
+ /** Sprint 1c-revive-2-D-5+ P2: 显式 model. */
31
+ model?: string;
32
+ /** 注入输入流(默认 process.stdin)。Sprint 1a follow-up:单测用。 */
33
+ input?: NodeJS.ReadableStream;
34
+ /**
35
+ * 注入 signal handler 监听哪个信号(默认监听 SIGINT + SIGTERM)。
36
+ * Sprint 1a follow-up #3: 单测用 — 避免重复监听真实 OS signal 污染 vitest 全局。
37
+ * 设成 `[]` 跳过 signal handler 注册, 仅靠 stdin close 退出。
38
+ */
39
+ watchSignals?: ReadonlyArray<NodeJS.Signals>;
40
+ /**
41
+ * Session compaction 集成 (Sprint 1c-revive-2-D-6, review P1 修复 2026-06-04).
42
+ * 不传 = baseline. 传 = runToolLoopWithCompaction 跨 chat request 持久化
43
+ * (CompactionState 闭包持有, writer 复用 sessionPath writer).
44
+ */
45
+ compactionConfig?: Omit<AgentCompactionConfig, 'writer' | 'state'> | null;
46
+ /**
47
+ * Sprint 1c-revive-3-D-13 (2026-06-05): --yes 标志. rpc 拍板 isInteractive=false.
48
+ */
49
+ yes?: boolean;
50
+ }
51
+ export declare function runRpcMode(options: RpcModeOptions): Promise<number>;
52
+ //# sourceMappingURL=rpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/modes/rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAML,KAAK,qBAAqB,EAE3B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAuB,KAAK,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAKvE,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B;;;;OAIG;IACH,YAAY,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7C;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1E;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAuBD,wBAAsB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAyKzE"}