@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,436 @@
1
+ /**
2
+ * Tool Loop — minimal agent loop (Sprint 1a)
3
+ *
4
+ * 协议(Codex/oh-my-pi 借鉴):
5
+ * 1. 把 system + history 喂给 LLM
6
+ * 2. 如果 LLM 返回 tool_calls:
7
+ * - 用 ToolRegistry 调工具(schema 校验 Sprint 1b 加)
8
+ * - 把结果作为 tool 消息 push 回 messages
9
+ * - 回到 (1)
10
+ * 3. 如果 LLM 返回 content(finish_reason='stop')→ 终结
11
+ * 4. 如果 max_steps 触顶 → 抛 ToolLoopLimitError
12
+ *
13
+ * Sprint 1a 范围(极简):
14
+ * - 同步(不并发 tool_calls;DeepSeek V4 Flash 一次只调 1 个常见)
15
+ * - 不做 budget cap(v2.0)
16
+ * - 不做 schema 校验(trust LLM 输出,argparse 失败时 tool 返回 error 即可)
17
+ * - 不做 plan mode(v2.5)
18
+ * - 不做 cost accounting(1b 加)
19
+ * - 流式:可选 onChunk 回调(REPL 用)
20
+ *
21
+ * 错误处理:
22
+ * - tool 自身失败 → tool 消息 content 是 error,loop 继续
23
+ * - LLM 失败 → 抛 LLMError(caller 决定是否 retry/终止)
24
+ * - max_steps 触顶 → 抛 ToolLoopLimitError(caller 决定是否放弃)
25
+ *
26
+ * @module @deepwhale/coding-agent/agent
27
+ */
28
+ import { canonicalizeSchema, LLMStreamError, LLMUnknownError } from '@deepwhale/llm';
29
+ import { evaluatePolicy } from '../policy/chain.js';
30
+ import { staticToolPolicy, evaluateBashCommand } from '../policy/static-rules.js';
31
+ import { computeArgsDigest } from '../policy/args-digest.js';
32
+ import { sanitizeReason } from '../policy/sanitize-reason.js';
33
+ import { appendPolicyDecisionEvent } from './session-adapter.js';
34
+ /** Sprint 1a 默认:跟 LLM 来回 5 轮(够用 coding agent 短任务,长任务 caller 调高)。 */
35
+ export const TOOL_LOOP_DEFAULT_MAX_STEPS = 5;
36
+ /**
37
+ * 错误:maxSteps 触顶、LLM 一直在调工具不收敛。
38
+ * caller 通常应当:缩短 prompt / 拆任务 / 主动放弃。
39
+ */
40
+ export class ToolLoopLimitError extends Error {
41
+ steps;
42
+ lastResult;
43
+ name = 'ToolLoopLimitError';
44
+ isToolLoopError = true;
45
+ constructor(steps, lastResult) {
46
+ super(`Tool loop exceeded max steps (${steps}); LLM kept calling tools without stopping`);
47
+ this.steps = steps;
48
+ this.lastResult = lastResult;
49
+ }
50
+ }
51
+ /** 类型守卫。 */
52
+ export function isToolLoopError(err) {
53
+ return err instanceof Error && err.isToolLoopError === true;
54
+ }
55
+ /**
56
+ * 执行一轮 tool loop。
57
+ *
58
+ * 行为契约:
59
+ * - 不修改输入 messages(immutable),返回**新**数组(带 tool 步骤)
60
+ * - 任何 LLM 调用失败 → 抛 LLMError(ToolLoopStep.error 事件也写入 steps)
61
+ * - tool 自身失败 → 不抛,包成 tool 消息的 error content 继续
62
+ * - maxSteps 触顶 → 抛 ToolLoopLimitError(steps 同时写入)
63
+ * - 外部 abort → 抛带 cause 的 LLMUnknownError(包装 AbortError)
64
+ *
65
+ * Sprint 1a 限制:
66
+ * - 只支持非流式调用时 onChunk=null;有 onChunk 时走 stream()。
67
+ * - onChunk 触发的内容**也**写入最终 final.content(assembled)
68
+ */
69
+ export async function runToolLoop(client, messages, options = {}) {
70
+ const maxSteps = options.maxSteps ?? TOOL_LOOP_DEFAULT_MAX_STEPS;
71
+ const registry = options.registry;
72
+ const onChunk = options.onChunk;
73
+ const toolTimeoutMs = options.toolTimeoutMs;
74
+ if (registry === undefined) {
75
+ throw new LLMUnknownError('ToolLoop: registry is required (no default in Sprint 1a)');
76
+ }
77
+ // 复制 messages 到可变数组(Sprint 1a 保持 caller 引用不变)
78
+ const working = [...messages];
79
+ const steps = [];
80
+ let lastResult;
81
+ for (let stepIdx = 0; stepIdx < maxSteps; stepIdx += 1) {
82
+ if (options.signal?.aborted) {
83
+ throw new LLMUnknownError('Tool loop aborted by caller', { cause: options.signal.reason });
84
+ }
85
+ // 1) 调 LLM
86
+ const tools = buildLlmTools(registry.list());
87
+ try {
88
+ lastResult = onChunk
89
+ ? await runStreamStep(client, working, tools, onChunk, options.signal)
90
+ : await client.chat(working, {
91
+ tools,
92
+ tool_choice: 'auto',
93
+ ...(options.signal !== undefined ? { signal: options.signal } : {}),
94
+ });
95
+ }
96
+ catch (err) {
97
+ steps.push({ kind: 'error', ts: Date.now(), error: err });
98
+ throw err;
99
+ }
100
+ // 2) 把 assistant 消息写进 working(tool_calls 必带;content 可能空)
101
+ // Sprint 1c-revive-2-D-21.1 (2026-06-06, 修 DeepSeek V4 thinking 400 bug):
102
+ // reasoning_content 也写进 working, 让下轮 LLM call 时 toWireMessage 透传.
103
+ // DeepSeek V4 默认开 thinking, 多轮必须回传上轮 reasoning, 否则 400.
104
+ // 不开 thinking 时 (V3 旧 alias / thinking 关) lastResult.reasoning_content
105
+ // 是 undefined, 字段 absent, 行为不变.
106
+ const assistantMsg = {
107
+ role: 'assistant',
108
+ content: lastResult.content,
109
+ ...(lastResult.reasoning_content !== undefined
110
+ ? { reasoning_content: lastResult.reasoning_content }
111
+ : {}),
112
+ };
113
+ if (lastResult.tool_calls && lastResult.tool_calls.length > 0) {
114
+ assistantMsg.tool_calls = lastResult.tool_calls;
115
+ }
116
+ working.push(assistantMsg);
117
+ steps.push({
118
+ kind: 'assistant',
119
+ ts: Date.now(),
120
+ message: assistantMsg,
121
+ result: lastResult,
122
+ });
123
+ // 3) 如果没 tool_calls → 收敛,return
124
+ const tcs = lastResult.tool_calls;
125
+ if (!tcs || tcs.length === 0) {
126
+ return { messages: working, final: lastResult, steps };
127
+ }
128
+ // 4) 执行 tool_calls(同步串行)
129
+ for (const tc of tcs) {
130
+ if (options.signal?.aborted) {
131
+ throw new LLMUnknownError('Tool loop aborted by caller', { cause: options.signal.reason });
132
+ }
133
+ const toolResult = await executeToolCall(registry, tc, toolTimeoutMs, options.signal, {
134
+ ...(options.policy !== undefined ? { policy: options.policy } : {}),
135
+ ...(options.isInteractive !== undefined ? { isInteractive: options.isInteractive } : {}),
136
+ ...(options.yes !== undefined ? { yes: options.yes } : {}),
137
+ ...(options.writer !== undefined ? { writer: options.writer } : {}),
138
+ });
139
+ const toolMsg = {
140
+ role: 'tool',
141
+ content: formatToolResult(toolResult),
142
+ tool_call_id: tc.id,
143
+ name: tc.name,
144
+ };
145
+ working.push(toolMsg);
146
+ steps.push({
147
+ kind: 'tool',
148
+ ts: Date.now(),
149
+ tool_call: tc,
150
+ result: toolResult,
151
+ duration_ms: toolResult.meta?.['duration_ms'] ?? 0,
152
+ });
153
+ }
154
+ }
155
+ // 5) 触顶
156
+ steps.push({ kind: 'limit', ts: Date.now(), steps: maxSteps, lastResult });
157
+ throw new ToolLoopLimitError(maxSteps, lastResult);
158
+ }
159
+ // ============================================================================
160
+ // 内部 helper
161
+ // ============================================================================
162
+ /**
163
+ * 把 ToolRegistry 里的工具转成 LLM 看得懂的 wire schema。
164
+ * Sprint 1b (Prefix-cache 机制 4): canonicalizeSchema 让 key 顺序稳定,
165
+ * LLM 端 hash 稳定 → prefix-cache 命中率不再因 property 顺序抖动归零。
166
+ * (对齐 Reasonix schema_canonicalize.go:10-67)
167
+ */
168
+ function buildLlmTools(tools) {
169
+ return tools.map((t) => canonicalizeSchema({
170
+ name: t.name,
171
+ description: t.description,
172
+ parameters: t.schema,
173
+ }));
174
+ }
175
+ /**
176
+ * 调单个 tool。
177
+ * Sprint 1a:直接 execute(),不做 schema 校验(LLM 错了包成 tool 错误继续)。
178
+ * Sprint 1a 超时策略:toolTimeoutMs 由外层 setTimeout + AbortController 统一包。
179
+ * Sprint 1c-revive-3-D-13 (2026-06-05): policy gate 在 execute 之前.
180
+ * 拍板: deny / require_confirmation 都返 success=false, LLM 续聊看到 tool 错误.
181
+ * bash 工具自身用 evaluateBashCommand 拍 cmd 危险模式, 双重防线 (tool-loop 一层 + bash 工具一层).
182
+ */
183
+ async function executeToolCall(registry, tc, toolTimeoutMs, externalSignal, options = {}) {
184
+ const tool = registry.get(tc.name);
185
+ if (!tool) {
186
+ return {
187
+ success: false,
188
+ content: '',
189
+ error: `tool-not-found: '${tc.name}' is not registered. Available: ${registry
190
+ .list()
191
+ .map((t) => t.name)
192
+ .join(', ')}`,
193
+ };
194
+ }
195
+ // Sprint 1c-revive-3-D-13: policy check (在 execute 之前, 拍板红线 deny 默认走 fail-closed)
196
+ // 拍板 (用户 2026-06-05):
197
+ // - 'allow' 不写 session, 也不在 tool result 里加 meta (除 yes bypass 走 user_approved 拍板)
198
+ // - 'deny' / 'require_confirmation' 走 fail-closed: tool 不执行, 返 success=false
199
+ // - 非交互模式 + require_confirmation → policy_blocked (no interactive confirmation)
200
+ // - session 写 fail → 抛 (audit 红线, 写不进就拒绝继续)
201
+ //
202
+ // Sprint 1c-revive-3-D-13 review P1(b) 修复 (2026-06-05): --yes bypass 落 user_approved 审计
203
+ // 拍板 (用户 2026-06-05): "保持 PolicyDecision 简洁, 在 tool-loop.ts 里保留 raw decision".
204
+ // 实现: 在 require_confirmation 分支里, 如果 ctx.yes=true, 落 user_approved 事件再
205
+ // 继续执行 (绕过交互确认), tool result 仍返 success (不返 policy_blocked).
206
+ if (options.policy !== null) {
207
+ const policy = options.policy ?? staticToolPolicy;
208
+ const argsDigest = computeArgsDigest(tc.args);
209
+ const ctx = {
210
+ isInteractive: options.isInteractive ?? false,
211
+ yes: options.yes ?? false,
212
+ argsDigest,
213
+ };
214
+ let decision = evaluatePolicy({ name: tc.name, argsDigest }, ctx, policy);
215
+ // bash 工具自身层用 evaluateBashCommand 拍 cmd 危险模式 (双重防线).
216
+ // tool-loop 这层 staticToolPolicy 走 allow, 不会 deny; 改走 bash 自身层.
217
+ if (tc.name === 'bash' && decision.decision !== 'deny' && decision.decision === 'allow') {
218
+ const cmd = tc.args['command'] ?? '';
219
+ const args = tc.args['args'] ?? [];
220
+ const bashDecision = evaluateBashCommand(cmd, args);
221
+ if (bashDecision.decision === 'require_confirmation') {
222
+ decision = evaluatePolicy({ name: tc.name, argsDigest }, ctx, {
223
+ evaluate: () => bashDecision,
224
+ });
225
+ }
226
+ }
227
+ if (decision.decision === 'deny') {
228
+ const reason = sanitizeReason(decision.reason);
229
+ // 落 session (拍板: 'deny' 写 policy_decision)
230
+ if (options.writer) {
231
+ await appendPolicyDecisionEvent(options.writer, {
232
+ tool_call_id: tc.id,
233
+ name: tc.name,
234
+ decision: 'deny',
235
+ argsDigest,
236
+ reason,
237
+ });
238
+ }
239
+ return {
240
+ success: false,
241
+ content: '',
242
+ error: `policy_blocked: ${reason}`,
243
+ meta: { argsDigest, policy: 'deny' },
244
+ };
245
+ }
246
+ if (decision.decision === 'require_confirmation') {
247
+ // === Sprint 1c-revive-3-D-13.5 review P1 重排 (2026-06-05) ===
248
+ // 顺序拍板 (用户 2026-06-05): ctx.yes first → !isInteractive → policy.confirm.
249
+ // 理由: --yes 是显式用户拍板, 必须最先处理 (audit 红线不丢);
250
+ // 非交互模式是机器模式 (print/rpc), 没用户就 deny (fail-closed);
251
+ // 最后才走 policy.confirm (REPL D-15 才会注入, D-13 MVP 落 no-confirm-impl deny).
252
+ // 不要最小插入留阅读陷阱: 整段重排成下面 4 个分支, 一段一段看完就懂优先级.
253
+ // 1) ctx.yes first: --yes 显式拍板, 落 user_approved 后放行 (audit 红线).
254
+ if (ctx.yes) {
255
+ if (options.writer) {
256
+ await appendPolicyDecisionEvent(options.writer, {
257
+ tool_call_id: tc.id,
258
+ name: tc.name,
259
+ decision: 'user_approved',
260
+ argsDigest,
261
+ reason: sanitizeReason(`--yes bypass: ${decision.reason}`),
262
+ meta: { bypassedByYes: true, isInteractive: ctx.isInteractive },
263
+ });
264
+ }
265
+ // 不返, 继续往下走 (执行工具)
266
+ }
267
+ else if (!ctx.isInteractive) {
268
+ // 2) 非交互模式: print/rpc 没有用户, 默认 deny (R-3 拍板: fail-closed).
269
+ const reason = sanitizeReason(`non-interactive mode: ${decision.reason}`);
270
+ if (options.writer) {
271
+ await appendPolicyDecisionEvent(options.writer, {
272
+ tool_call_id: tc.id,
273
+ name: tc.name,
274
+ decision: 'deny',
275
+ argsDigest,
276
+ reason,
277
+ meta: { isInteractive: false },
278
+ });
279
+ }
280
+ return {
281
+ success: false,
282
+ content: '',
283
+ error: `policy_blocked: ${reason}`,
284
+ meta: { argsDigest, policy: 'require_confirmation', isInteractive: false },
285
+ };
286
+ }
287
+ else if (typeof policy.confirm === 'function') {
288
+ // 3) 交互模式 + 注入 confirm: 走 y/N (D-15 注入 readline; D-13 MVP 没人调这条).
289
+ // Sprint 1c-revive-3-D-19 (2026-06-05): 透传 externalSignal 给 confirm (Ctrl+C / turn 取消).
290
+ // 拍板 (D-19): repl-confirm.ts 拿到 signal 后, abort 时立即 resolve null (dismissed).
291
+ // 老 confirm() 实现 (单参 prompt) 继续合法 (opts 默认 undefined).
292
+ const ok = await policy.confirm(`Allow ${tc.name}? (${sanitizeReason(decision.reason)})`, {
293
+ ...(externalSignal !== undefined ? { signal: externalSignal } : {}),
294
+ });
295
+ const userDecision = ok === true ? 'user_approved' : 'user_denied';
296
+ if (options.writer) {
297
+ await appendPolicyDecisionEvent(options.writer, {
298
+ tool_call_id: tc.id,
299
+ name: tc.name,
300
+ decision: userDecision,
301
+ argsDigest,
302
+ reason: ok === true ? 'user approved' : `user ${ok === false ? 'denied' : 'dismissed'}`,
303
+ });
304
+ }
305
+ if (ok !== true) {
306
+ return {
307
+ success: false,
308
+ content: '',
309
+ error: `policy_blocked: user ${ok === false ? 'denied' : 'dismissed'} confirmation`,
310
+ meta: { argsDigest, policy: 'require_confirmation', userDecision: ok },
311
+ };
312
+ }
313
+ }
314
+ else {
315
+ // 4) 交互模式 + 没 confirm 实现: 兜底 deny (fail-closed, D-13 MVP 现状).
316
+ const reason = sanitizeReason(`no confirm impl: ${decision.reason}`);
317
+ if (options.writer) {
318
+ await appendPolicyDecisionEvent(options.writer, {
319
+ tool_call_id: tc.id,
320
+ name: tc.name,
321
+ decision: 'deny',
322
+ argsDigest,
323
+ reason,
324
+ meta: { reason: 'no-confirm-impl' },
325
+ });
326
+ }
327
+ return {
328
+ success: false,
329
+ content: '',
330
+ error: `policy_blocked: ${reason}`,
331
+ meta: { argsDigest, policy: 'require_confirmation', reason: 'no-confirm-impl' },
332
+ };
333
+ }
334
+ }
335
+ // 'allow' 走默认, 不落 session, 不返特殊 meta
336
+ }
337
+ // Sprint 1a 修 P2-B:tool 自带 timeout 不支持,通过外层 setTimeout + Promise.race 包一层强制中断。
338
+ // 不动 Tool.execute() 签名(Sprint 1a 简化),而是 race 出 timeout 时 reject 让上层 catch 包成 tool 错误。
339
+ // 同步清掉 timer 避免进程 hang。
340
+ let timer;
341
+ let timeoutReason;
342
+ const executePromise = Promise.resolve().then(() => tool.execute(tc.args));
343
+ let timeoutPromise;
344
+ if (toolTimeoutMs !== undefined) {
345
+ timeoutPromise = new Promise((_resolve, reject) => {
346
+ timer = setTimeout(() => {
347
+ timeoutReason = new Error(`tool-timeout: '${tc.name}' exceeded ${toolTimeoutMs}ms`);
348
+ reject(timeoutReason);
349
+ }, toolTimeoutMs);
350
+ });
351
+ }
352
+ // externalSignal 一旦 abort,立即 reject 以让 race 收敛
353
+ const externalAbortPromise = externalSignal
354
+ ? new Promise((_resolve, reject) => {
355
+ if (externalSignal.aborted) {
356
+ reject(new Error('aborted: external signal already triggered'));
357
+ return;
358
+ }
359
+ externalSignal.addEventListener('abort', () => reject(new Error('aborted: external signal triggered')), { once: true });
360
+ })
361
+ : undefined;
362
+ const start = Date.now();
363
+ try {
364
+ const raceCandidates = [executePromise];
365
+ if (timeoutPromise)
366
+ raceCandidates.push(timeoutPromise);
367
+ if (externalAbortPromise)
368
+ raceCandidates.push(externalAbortPromise);
369
+ const result = (await Promise.race(raceCandidates));
370
+ return {
371
+ ...result,
372
+ meta: { ...(result.meta ?? {}), duration_ms: Date.now() - start },
373
+ };
374
+ }
375
+ catch (err) {
376
+ // 区分是 tool 自身抛错,还是 timeout/abort 包出来的错
377
+ const isSynthetic = err === timeoutReason || (err instanceof Error && /^(aborted:)/.test(err.message));
378
+ return {
379
+ success: false,
380
+ content: '',
381
+ error: isSynthetic
382
+ ? err instanceof Error
383
+ ? err.message
384
+ : String(err)
385
+ : `tool-threw: ${err instanceof Error ? err.message : String(err)}`,
386
+ meta: { duration_ms: Date.now() - start },
387
+ };
388
+ }
389
+ finally {
390
+ if (timer)
391
+ clearTimeout(timer);
392
+ if (externalSignal && externalAbortPromise) {
393
+ externalSignal.removeEventListener('abort', () => { });
394
+ }
395
+ }
396
+ }
397
+ /**
398
+ * 把 ToolResult 序列化成 tool 消息的 content。
399
+ *
400
+ * Sprint 1a 简化:success 时返回 content;失败时返回 [error] xxx。
401
+ * Sprint 1b 会改成 Observation 4 字段 + Recovery 3 字段 schema 统一形态。
402
+ */
403
+ function formatToolResult(r) {
404
+ if (r.success)
405
+ return r.content;
406
+ return `[error] ${r.error ?? 'unknown tool error'}`;
407
+ }
408
+ /**
409
+ * 走 stream API 的一步:assemble chunks 到 final result,复用 chat() 的同等逻辑。
410
+ *
411
+ * Sprint 1a 简化:stream 模式下,tool_calls 一次性在最后 chunk 出现(DeepSeek V4 当前实现)。
412
+ * 如果未来 OAI 协议增量给 tool_calls(index 字段递增),sprint 1b 再加增量合并。
413
+ */
414
+ async function runStreamStep(client, messages, tools, onChunk, signal) {
415
+ try {
416
+ const result = await client.stream([...messages], {
417
+ tools,
418
+ tool_choice: 'auto',
419
+ ...(signal !== undefined ? { signal } : {}),
420
+ onChunk: (c) => {
421
+ if (c.delta.content)
422
+ onChunk({ content: c.delta.content });
423
+ if (c.delta.tool_calls)
424
+ onChunk({ tool_calls: c.delta.tool_calls });
425
+ },
426
+ });
427
+ return result;
428
+ }
429
+ catch (err) {
430
+ if (err instanceof LLMStreamError) {
431
+ throw new LLMUnknownError(`Stream step failed: ${err.message}`, { cause: err });
432
+ }
433
+ throw err;
434
+ }
435
+ }
436
+ //# sourceMappingURL=tool-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-loop.js","sourceRoot":"","sources":["../../src/agent/tool-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @deepwhale/coding-agent — 轻量 `.env` loader (项目根目录)
3
+ *
4
+ * 拍板 (Sprint 1c-revive-2-D-7 review, 2026-06-04):
5
+ * - 读项目根的 `.env` (用户**自己**负责放, 跟 .gitignore 一致不入仓)
6
+ * - 只补缺, 不覆盖 (`process.env[key] ??= value`)
7
+ * → CI / PowerShell `$env:VAR=...` / shell `export VAR=...` 优先级永远最高
8
+ * → 安全: 不会因为 .env 里的旧值误覆盖生产/CI 显式设的 key
9
+ * - 解析规则 (跟 dotenv 简化版一致, 不引 dep):
10
+ * - 空行 / `#` 注释跳过
11
+ * - `KEY=VALUE` 形式, `=` 第一次出现分界
12
+ * - VALUE 头尾成对 `"..."` 或 `'...'` → 去引号
13
+ * - `export KEY=...` 前缀 → 忽略前缀 (dotenv 兼容)
14
+ * - `KEY=` 后无值 → 设为空字符串 (但仍占位置, 不再被覆盖)
15
+ * - 文件不存在 / 读失败 → silent return (不抛, 不污染启动)
16
+ * - **不**读 user-managed secret store (`~/.deepwhale/` 是 product 设计; loadProjectEnv 走项目根 .env, 见 .env.example),
17
+ * 跟 .env loader 职责分离 — 跟 llm/test 红线 1 一致: test 代码不直接读 secret 文件)
18
+ *
19
+ * 用法:
20
+ * - CLI 入口: `bin/deepwhale.js` 在 import dist 之前调一次
21
+ * - vitest setupFile: 跨包测试也用
22
+ * - 不用动 callers — 一行 import + 一行调用
23
+ *
24
+ * 不变量:
25
+ * - 不会 throw (加载失败当 .env 不存在处理)
26
+ * - 不会 log 任何 key 值 (跟 .env loader 红线一致: 永不 echo 凭据)
27
+ * - 同步实现, 不阻塞 — .env 一般 < 10 行, sync readFileSync 完全够
28
+ *
29
+ * @module @deepwhale/coding-agent/load-project-env
30
+ */
31
+ /**
32
+ * 从项目根目录加载 `.env`, 补缺到 `process.env`.
33
+ *
34
+ * 拍板: 缺文件的 .env 不会报错 — silent skip, 跟生产/CI 行为保持一致.
35
+ * 重复调用安全 — 第二次调时所有 key 都已存在 (`??=` 不会改), 实际是 no-op.
36
+ *
37
+ * @param cwd 解析 `.env` 路径的基准. 默认 `process.cwd()`. 显式传为了单测.
38
+ */
39
+ export declare function loadProjectEnv(cwd?: string): void;
40
+ //# sourceMappingURL=load-project-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-project-env.d.ts","sourceRoot":"","sources":["../../src/env/load-project-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,IAAI,CAsChE"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @deepwhale/coding-agent — 轻量 `.env` loader (项目根目录)
3
+ *
4
+ * 拍板 (Sprint 1c-revive-2-D-7 review, 2026-06-04):
5
+ * - 读项目根的 `.env` (用户**自己**负责放, 跟 .gitignore 一致不入仓)
6
+ * - 只补缺, 不覆盖 (`process.env[key] ??= value`)
7
+ * → CI / PowerShell `$env:VAR=...` / shell `export VAR=...` 优先级永远最高
8
+ * → 安全: 不会因为 .env 里的旧值误覆盖生产/CI 显式设的 key
9
+ * - 解析规则 (跟 dotenv 简化版一致, 不引 dep):
10
+ * - 空行 / `#` 注释跳过
11
+ * - `KEY=VALUE` 形式, `=` 第一次出现分界
12
+ * - VALUE 头尾成对 `"..."` 或 `'...'` → 去引号
13
+ * - `export KEY=...` 前缀 → 忽略前缀 (dotenv 兼容)
14
+ * - `KEY=` 后无值 → 设为空字符串 (但仍占位置, 不再被覆盖)
15
+ * - 文件不存在 / 读失败 → silent return (不抛, 不污染启动)
16
+ * - **不**读 user-managed secret store (`~/.deepwhale/` 是 product 设计; loadProjectEnv 走项目根 .env, 见 .env.example),
17
+ * 跟 .env loader 职责分离 — 跟 llm/test 红线 1 一致: test 代码不直接读 secret 文件)
18
+ *
19
+ * 用法:
20
+ * - CLI 入口: `bin/deepwhale.js` 在 import dist 之前调一次
21
+ * - vitest setupFile: 跨包测试也用
22
+ * - 不用动 callers — 一行 import + 一行调用
23
+ *
24
+ * 不变量:
25
+ * - 不会 throw (加载失败当 .env 不存在处理)
26
+ * - 不会 log 任何 key 值 (跟 .env loader 红线一致: 永不 echo 凭据)
27
+ * - 同步实现, 不阻塞 — .env 一般 < 10 行, sync readFileSync 完全够
28
+ *
29
+ * @module @deepwhale/coding-agent/load-project-env
30
+ */
31
+ import { existsSync, readFileSync } from 'node:fs';
32
+ import { resolve } from 'node:path';
33
+ /**
34
+ * 从项目根目录加载 `.env`, 补缺到 `process.env`.
35
+ *
36
+ * 拍板: 缺文件的 .env 不会报错 — silent skip, 跟生产/CI 行为保持一致.
37
+ * 重复调用安全 — 第二次调时所有 key 都已存在 (`??=` 不会改), 实际是 no-op.
38
+ *
39
+ * @param cwd 解析 `.env` 路径的基准. 默认 `process.cwd()`. 显式传为了单测.
40
+ */
41
+ export function loadProjectEnv(cwd = process.cwd()) {
42
+ const envPath = resolve(cwd, '.env');
43
+ if (!existsSync(envPath))
44
+ return;
45
+ let text;
46
+ try {
47
+ text = readFileSync(envPath, 'utf8');
48
+ }
49
+ catch {
50
+ // 权限 / IO 失败 → 静默 (跟 dotenv 缺文件同语义, 不污染启动)
51
+ return;
52
+ }
53
+ for (const raw of text.split(/\r?\n/)) {
54
+ const line = raw.trim();
55
+ if (!line)
56
+ continue;
57
+ if (line.startsWith('#'))
58
+ continue;
59
+ // 兼容 dotenv 的 `export KEY=...` 前缀 (PowerShell 不会写这个, 但 shell 可能)
60
+ const stripped = line.startsWith('export ') ? line.slice('export '.length).trim() : line;
61
+ const eq = stripped.indexOf('=');
62
+ if (eq <= 0)
63
+ continue; // 没 `=` / `=` 在最前 (无 key) → 跳过
64
+ const key = stripped.slice(0, eq).trim();
65
+ if (!key)
66
+ continue;
67
+ let value = stripped.slice(eq + 1).trim();
68
+ // 头尾成对引号 → 去引号
69
+ if (value.length >= 2) {
70
+ const first = value[0];
71
+ const last = value[value.length - 1];
72
+ if ((first === '"' && last === '"') || (first === "'" && last === "'")) {
73
+ value = value.slice(1, -1);
74
+ }
75
+ }
76
+ // 拍板红线: 只补缺, 不覆盖. CI / shell `export` 永远优先.
77
+ process.env[key] ??= value;
78
+ }
79
+ }
80
+ //# sourceMappingURL=load-project-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-project-env.js","sourceRoot":"","sources":["../../src/env/load-project-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO;IAEjC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,2CAA2C;QAC3C,OAAO;IACT,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAEnC,iEAAiE;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAEzF,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,EAAE,IAAI,CAAC;YAAE,SAAS,CAAC,+BAA+B;QACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1C,eAAe;QACf,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;YACtC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACvE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;IAC7B,CAAC;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @deepwhale/coding-agent — Coding Agent CLI + 工具运行时
3
+ *
4
+ * Sprint 0.2 落地:
5
+ * - 6 工具骨架:bash / read_file / write_file / edit_file / find / grep
6
+ * - Tool Registry 抽象
7
+ * - Tool ↔ EditEngine 桥接(edit_file 走 EditEngine 接口,不直接 import hashline)
8
+ *
9
+ * Sprint 0.3 落地:CLI 入口 + REPL + LLM 客户端
10
+ * - runOneTurn: 单轮 chat 单元(无 readline 依赖,单测 100% 覆盖)
11
+ * - startRepl: readline 循环 + 内建命令 + 错误友好提示
12
+ *
13
+ * Sprint 1a 落地:最小 Agent Loop
14
+ * - runToolLoop: LLM ↔ tool_calls ↔ LLM 闭环
15
+ * - ToolLoopLimitError: maxSteps 触顶时抛
16
+ */
17
+ export * from './tools/index.js';
18
+ export * from './tools/registry.js';
19
+ export * from './types.js';
20
+ export * from './agent/index.js';
21
+ export * from './modes/index.js';
22
+ export * from './verify/index.js';
23
+ export * from './policy/index.js';
24
+ export * from './util/index.js';
25
+ export type { ChatMessage, LLMClient } from '@deepwhale/llm';
26
+ export { SessionReader, SessionWriter } from '@deepwhale/core';
27
+ export { startRepl, runOneTurn, formatUsageStatus, createReplConfirm } from './repl.js';
28
+ export type { ReplConfirmController, ReplConfirmOptions, ReplConfirm } from './repl/repl-confirm.js';
29
+ export type { ReplOptions } from './repl.js';
30
+ export { createDefaultClient, type CreateClientOptions, type Provider } from './llm-factory.js';
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAEhC,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACxF,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrG,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG7C,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @deepwhale/coding-agent — Coding Agent CLI + 工具运行时
3
+ *
4
+ * Sprint 0.2 落地:
5
+ * - 6 工具骨架:bash / read_file / write_file / edit_file / find / grep
6
+ * - Tool Registry 抽象
7
+ * - Tool ↔ EditEngine 桥接(edit_file 走 EditEngine 接口,不直接 import hashline)
8
+ *
9
+ * Sprint 0.3 落地:CLI 入口 + REPL + LLM 客户端
10
+ * - runOneTurn: 单轮 chat 单元(无 readline 依赖,单测 100% 覆盖)
11
+ * - startRepl: readline 循环 + 内建命令 + 错误友好提示
12
+ *
13
+ * Sprint 1a 落地:最小 Agent Loop
14
+ * - runToolLoop: LLM ↔ tool_calls ↔ LLM 闭环
15
+ * - ToolLoopLimitError: maxSteps 触顶时抛
16
+ */
17
+ export * from './tools/index.js';
18
+ export * from './tools/registry.js';
19
+ export * from './types.js';
20
+ export * from './agent/index.js';
21
+ export * from './modes/index.js';
22
+ export * from './verify/index.js'; // Sprint 1c-revive-2-D-11-4 (2026-06-04): verify module
23
+ export * from './policy/index.js'; // Sprint 1c-revive-2-D-24.2 (2026-06-06): tui-ink needs ToolPolicy/staticToolPolicy
24
+ export * from './util/index.js'; // Sprint 1c-revive-2-D-25 B4 (2026-06-06): tui-ink + tui.ts 共享 util (tui-history)
25
+ export { SessionReader, SessionWriter } from '@deepwhale/core';
26
+ export { startRepl, runOneTurn, formatUsageStatus, createReplConfirm } from './repl.js';
27
+ // Sprint 1c-revive-2-D-25 B2 (2026-06-06): tui-ink App needs LLMClient factory + ToolRegistry
28
+ // (useRunToolLoop 修 3 参签名, 业务 1:1 跟 modes/tui.ts L482 + L770 同形态)
29
+ export { createDefaultClient } from './llm-factory.js';
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC,CAAC,wDAAwD;AAC3F,cAAc,mBAAmB,CAAC,CAAC,oFAAoF;AACvH,cAAc,iBAAiB,CAAC,CAAC,kFAAkF;AAGnH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAGxF,8FAA8F;AAC9F,kEAAkE;AAClE,OAAO,EAAE,mBAAmB,EAA2C,MAAM,kBAAkB,CAAC"}