thincoder 0.12.62 → 0.12.64

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 (231) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +46 -49
  3. package/bin/thincoder.mjs +68 -34
  4. package/package.json +7 -6
  5. package/src/acp/bridge.mjs +35 -15
  6. package/src/acp/client-caps.mjs +86 -0
  7. package/src/acp/ext.mjs +86 -0
  8. package/src/acp/handlers-session.mjs +257 -0
  9. package/src/acp/handlers-slots.mjs +196 -0
  10. package/src/acp/login.mjs +48 -0
  11. package/src/acp/session.mjs +6 -4
  12. package/src/acp.mjs +67 -379
  13. package/src/cli/distill-command.mjs +3 -3
  14. package/src/cli/make-agent.mjs +60 -17
  15. package/src/cli/memory-command.mjs +3 -3
  16. package/src/cli/permission.mjs +4 -48
  17. package/src/cli/setup-wizard.mjs +1 -1
  18. package/src/completions.mjs +3 -1
  19. package/src/crash-reports.mjs +1 -1
  20. package/src/distill.mjs +4 -4
  21. package/src/heap-watch.mjs +1 -1
  22. package/src/prompt-injections.mjs +20 -0
  23. package/src/tui/agent-turn.mjs +40 -9
  24. package/src/tui/cmd-advisor.mjs +5 -5
  25. package/src/tui/cmd-config.mjs +8 -8
  26. package/src/tui/cmd-eng.mjs +35 -9
  27. package/src/tui/cmd-mcp.mjs +9 -8
  28. package/src/tui/cmd-model.mjs +1 -1
  29. package/src/tui/cmd-new.mjs +6 -5
  30. package/src/tui/cmd-plan.mjs +9 -0
  31. package/src/tui/cmd-reindex.mjs +1 -1
  32. package/src/tui/cmd-restore.mjs +2 -2
  33. package/src/tui/cmd-session.mjs +24 -1
  34. package/src/tui/cmd-skills.mjs +1 -1
  35. package/src/tui/cmd-think.mjs +22 -9
  36. package/src/tui/config-helpers.mjs +1 -1
  37. package/src/tui/display-budget.mjs +33 -11
  38. package/src/tui/index.mjs +18 -10
  39. package/src/tui/interaction.mjs +16 -7
  40. package/src/tui/key-modes.mjs +9 -4
  41. package/src/tui/ledger-surface.mjs +22 -59
  42. package/src/tui/model-catalog.mjs +4 -4
  43. package/src/tui/model-picker.mjs +8 -7
  44. package/src/tui/mouse.mjs +11 -6
  45. package/src/tui/pickers.mjs +15 -2
  46. package/src/tui/render-conversation.mjs +1 -1
  47. package/src/tui/render-frame.mjs +15 -6
  48. package/src/tui/render-loop.mjs +1 -1
  49. package/src/tui/render-segments.mjs +3 -1
  50. package/src/tui/slash-commands.mjs +1 -1
  51. package/src/tui/startup.mjs +14 -14
  52. package/src/tui/subagent-blocks.mjs +20 -3
  53. package/src/tui/subagent-freeze.mjs +73 -2
  54. package/src/tui/suspension-drive.mjs +57 -23
  55. package/src/tui/tool-events.mjs +11 -8
  56. package/src/tui/tui-lifecycle.mjs +9 -0
  57. package/src/tui/wizard.mjs +3 -3
  58. package/src/tui/wrapped-spawn.mjs +6 -2
  59. package/src/abort-provenance.mjs +0 -116
  60. package/src/advisor/citations.mjs +0 -139
  61. package/src/advisor/compaction.mjs +0 -174
  62. package/src/advisor/convergence.mjs +0 -80
  63. package/src/advisor/history.mjs +0 -77
  64. package/src/advisor/loop.mjs +0 -293
  65. package/src/advisor/messages.mjs +0 -299
  66. package/src/advisor/project-context.mjs +0 -194
  67. package/src/advisor/repos.mjs +0 -150
  68. package/src/advisor/run.mjs +0 -293
  69. package/src/advisor/truncate.mjs +0 -57
  70. package/src/advisor.mjs +0 -290
  71. package/src/agent/completion.mjs +0 -146
  72. package/src/agent/dispatch.mjs +0 -489
  73. package/src/agent/helpers.mjs +0 -384
  74. package/src/agent/post-turn.mjs +0 -70
  75. package/src/agent/record-results.mjs +0 -174
  76. package/src/agent/relay-prefix.mjs +0 -39
  77. package/src/agent/run-stages.mjs +0 -244
  78. package/src/agent/setup-reminders.mjs +0 -69
  79. package/src/agent/setup.mjs +0 -354
  80. package/src/agent/spawn-child.mjs +0 -243
  81. package/src/agent-tools/advisor-async.mjs +0 -346
  82. package/src/agent-tools/advisor-settle.mjs +0 -231
  83. package/src/agent-tools/advisor.mjs +0 -260
  84. package/src/agent-tools/async-settle.mjs +0 -204
  85. package/src/agent-tools/batch-segment.mjs +0 -195
  86. package/src/agent-tools/consult.mjs +0 -473
  87. package/src/agent-tools/design-token.mjs +0 -117
  88. package/src/agent-tools/digest-budget.mjs +0 -76
  89. package/src/agent-tools/eng.mjs +0 -67
  90. package/src/agent-tools/escalate-async.mjs +0 -295
  91. package/src/agent-tools/goal.mjs +0 -119
  92. package/src/agent-tools/plan.mjs +0 -81
  93. package/src/agent-tools/read-history.mjs +0 -309
  94. package/src/agent-tools/recent-changes.mjs +0 -24
  95. package/src/agent-tools/review-streak.mjs +0 -93
  96. package/src/agent-tools/settings.mjs +0 -265
  97. package/src/agent-tools/skill.mjs +0 -47
  98. package/src/agent-tools/subagent-actions.mjs +0 -482
  99. package/src/agent-tools/subagent-async.mjs +0 -434
  100. package/src/agent-tools/subagent-panel.mjs +0 -160
  101. package/src/agent-tools/subagent-run.mjs +0 -205
  102. package/src/agent-tools/subagent-scheduler.mjs +0 -392
  103. package/src/agent-tools/subagent-spawn.mjs +0 -459
  104. package/src/agent-tools/subagent.mjs +0 -404
  105. package/src/agent-tools/task.mjs +0 -87
  106. package/src/agent-tools/timer.mjs +0 -46
  107. package/src/agent-tools/verify.mjs +0 -271
  108. package/src/agent-tools.mjs +0 -17
  109. package/src/agent.mjs +0 -417
  110. package/src/auto-think.mjs +0 -115
  111. package/src/config-migrate.mjs +0 -70
  112. package/src/config.mjs +0 -496
  113. package/src/context.mjs +0 -392
  114. package/src/conventions.mjs +0 -223
  115. package/src/embedding.mjs +0 -120
  116. package/src/escape.mjs +0 -152
  117. package/src/expand-home.mjs +0 -16
  118. package/src/explore-distill.mjs +0 -155
  119. package/src/generate-title.mjs +0 -88
  120. package/src/git/checkpoint.mjs +0 -448
  121. package/src/git/gitmem.mjs +0 -100
  122. package/src/hooks.mjs +0 -97
  123. package/src/ledger.mjs +0 -227
  124. package/src/log.mjs +0 -195
  125. package/src/markdown.mjs +0 -106
  126. package/src/mcp/helpers.mjs +0 -51
  127. package/src/mcp/transport-http.mjs +0 -248
  128. package/src/mcp/transport-stdio.mjs +0 -140
  129. package/src/mcp/transport-ws.mjs +0 -122
  130. package/src/mcp.mjs +0 -295
  131. package/src/memory/code-index.mjs +0 -219
  132. package/src/memory/code-sync.mjs +0 -415
  133. package/src/memory/core.mjs +0 -299
  134. package/src/memory/delete.mjs +0 -236
  135. package/src/memory/docs.mjs +0 -419
  136. package/src/memory/file-walk.mjs +0 -109
  137. package/src/memory/scan.mjs +0 -95
  138. package/src/memory/schema.mjs +0 -452
  139. package/src/memory.mjs +0 -21
  140. package/src/model-ref.mjs +0 -66
  141. package/src/model-specs.mjs +0 -179
  142. package/src/peer-domains.mjs +0 -265
  143. package/src/peer-instances.mjs +0 -231
  144. package/src/prompt-overlays.mjs +0 -82
  145. package/src/prompts/advisor-design.md +0 -41
  146. package/src/prompts/advisor-round1.md +0 -41
  147. package/src/prompts/advisor-round2.md +0 -46
  148. package/src/prompts/advisor-round3.md +0 -42
  149. package/src/prompts/common.md +0 -115
  150. package/src/prompts/consult-base.md +0 -19
  151. package/src/prompts/discipline-engineering.md +0 -258
  152. package/src/prompts/discipline-normal.md +0 -185
  153. package/src/prompts/persona-coder.md +0 -21
  154. package/src/prompts/persona-eng-coder.md +0 -37
  155. package/src/prompts/persona-eng-designer.md +0 -60
  156. package/src/prompts/persona-engineering.md +0 -55
  157. package/src/prompts/persona-explore.md +0 -15
  158. package/src/prompts/persona-normal.md +0 -27
  159. package/src/prompts/persona-plan.md +0 -26
  160. package/src/provider/anthropic.mjs +0 -225
  161. package/src/provider/core.mjs +0 -476
  162. package/src/provider/errors.mjs +0 -101
  163. package/src/provider/google.mjs +0 -257
  164. package/src/provider/index.mjs +0 -7
  165. package/src/provider/list-models.mjs +0 -93
  166. package/src/provider/normalize.mjs +0 -81
  167. package/src/provider/rate.mjs +0 -108
  168. package/src/provider/responses.mjs +0 -495
  169. package/src/provider/retry.mjs +0 -88
  170. package/src/provider/sse.mjs +0 -264
  171. package/src/proxy.mjs +0 -261
  172. package/src/rules.mjs +0 -53
  173. package/src/session-gc.mjs +0 -221
  174. package/src/session-guard.mjs +0 -59
  175. package/src/session-migrate.mjs +0 -48
  176. package/src/session-rename.mjs +0 -38
  177. package/src/session-segments.mjs +0 -100
  178. package/src/session-slots.mjs +0 -492
  179. package/src/session-store.mjs +0 -441
  180. package/src/session.mjs +0 -492
  181. package/src/skills.mjs +0 -153
  182. package/src/text-budget.mjs +0 -46
  183. package/src/token-ttl.mjs +0 -274
  184. package/src/tools/apply_patch.md +0 -15
  185. package/src/tools/bash.md +0 -37
  186. package/src/tools/bash.mjs +0 -268
  187. package/src/tools/checklist-sync.mjs +0 -181
  188. package/src/tools/checklist.md +0 -13
  189. package/src/tools/checklist.mjs +0 -299
  190. package/src/tools/delete.md +0 -13
  191. package/src/tools/edit-batch.mjs +0 -191
  192. package/src/tools/edit-diff.mjs +0 -348
  193. package/src/tools/edit.md +0 -30
  194. package/src/tools/execute.md +0 -21
  195. package/src/tools/execute.mjs +0 -228
  196. package/src/tools/fetch.md +0 -12
  197. package/src/tools/file.mjs +0 -469
  198. package/src/tools/file_ops.md +0 -17
  199. package/src/tools/get_current_time.md +0 -8
  200. package/src/tools/git-checkpoint.mjs +0 -143
  201. package/src/tools/git-ext.mjs +0 -173
  202. package/src/tools/git.md +0 -54
  203. package/src/tools/git.mjs +0 -356
  204. package/src/tools/glob-dialect.mjs +0 -130
  205. package/src/tools/glob.md +0 -11
  206. package/src/tools/grep.md +0 -19
  207. package/src/tools/hashline_edit.md +0 -14
  208. package/src/tools/index.mjs +0 -36
  209. package/src/tools/insert_after.md +0 -15
  210. package/src/tools/lint.md +0 -10
  211. package/src/tools/linter.mjs +0 -128
  212. package/src/tools/ls.md +0 -12
  213. package/src/tools/lsp.md +0 -10
  214. package/src/tools/lsp.mjs +0 -316
  215. package/src/tools/ops.mjs +0 -299
  216. package/src/tools/patch.mjs +0 -282
  217. package/src/tools/process.md +0 -10
  218. package/src/tools/question.md +0 -16
  219. package/src/tools/question.mjs +0 -26
  220. package/src/tools/read.md +0 -20
  221. package/src/tools/read_image.md +0 -8
  222. package/src/tools/repomap.mjs +0 -314
  223. package/src/tools/search.mjs +0 -236
  224. package/src/tools/shared.mjs +0 -446
  225. package/src/tools/tree.md +0 -14
  226. package/src/tools/tree.mjs +0 -66
  227. package/src/tools/wait_for.md +0 -22
  228. package/src/tools/web.mjs +0 -224
  229. package/src/tools/websearch.md +0 -16
  230. package/src/tools/write.md +0 -11
  231. package/src/traces/trace-store.mjs +0 -355
@@ -1,225 +0,0 @@
1
- /**
2
- * provider/anthropic.mjs — Anthropic Messages API (Claude)
3
- * Endpoint: POST https://api.anthropic.com/v1/messages
4
- * Docs: https://docs.anthropic.com/en/api/messages
5
- */
6
-
7
- import { specForModel } from "../config.mjs"
8
- import { proxyFetch } from "../proxy.mjs"
9
- import { requestWithRetry } from "./retry.mjs"
10
- import { effectiveFetchTimeoutMs } from "./core.mjs"
11
- import { abortError } from "../abort-provenance.mjs"
12
-
13
- const ANTHROPIC_VERSION = "2023-06-01"
14
-
15
- /** OpenAI 语义 tool_choice → Anthropic tool_choice(2026-08-31 能力层)。
16
- * 传入值形态:undefined | "auto" | "required" | "none" | {type:"function",function:{name}} */
17
- function mapToolChoice(choice) {
18
- if (choice === "auto") return { type: "auto" }
19
- if (choice === "required") return { type: "any" }
20
- if (choice === "none") return { type: "none" }
21
- if (choice && typeof choice === "object" && choice.function?.name) return { type: "tool", name: choice.function.name }
22
- throw new Error(`Invalid tool_choice for Anthropic format: ${JSON.stringify(choice).slice(0, 120)}`)
23
- }
24
-
25
-
26
- /** Convert OpenAI-format tools to Anthropic format */
27
- export function normalizeTools(tools) {
28
- return (tools || []).map((t) => ({
29
- name: t.function.name,
30
- description: t.function.description || "",
31
- input_schema: t.function.parameters || { type: "object", properties: {} },
32
- }))
33
- }
34
-
35
- /** Build and send an Anthropic chat request. Returns the same shape as core.mjs chat.
36
- * 2026-08-31 会诊 #6:接入 rateGate/recordRate + 429 Retry-After 单次重试
37
- * (原实现完全绕过 TPM/RPM 闸门与记账——用户配了 tpm 以为受控实际不受控)。
38
- * 注:5xx/网络退避重试未与 OpenAI 格式对齐(三 transport 共用那步工作量大,见报告)。 */
39
- export async function chat(provider, { messages, tools, onToken, onReasoning, onWait, signal, toolChoice, parallelToolCalls }) {
40
- // Extract system message(s) — Anthropic uses top-level `system` field
41
- const systemMessages = []
42
- const chatMessages = []
43
- for (const m of messages) {
44
- if (m.role === "system") {
45
- systemMessages.push(typeof m.content === "string" ? m.content : JSON.stringify(m.content))
46
- } else {
47
- chatMessages.push(m)
48
- }
49
- }
50
-
51
- const spec = specForModel(provider.model)
52
- const body = {
53
- model: provider.model,
54
- messages: chatMessages,
55
- stream: true,
56
- max_tokens: provider.maxTokens || (spec.maxOutput || 8192),
57
- }
58
- if (systemMessages.length > 0) body.system = systemMessages.join("\n\n")
59
- if (tools?.length) body.tools = tools
60
- // 2026-08-31:tool_choice 能力层——OpenAI 语义映射到 Anthropic tool_choice
61
- // (auto→{type:"auto"} / required→{type:"any"} / none→{type:"none"} / 具体函数→{type:"tool",name})
62
- if (toolChoice !== undefined) body.tool_choice = mapToolChoice(toolChoice)
63
- if (provider.temperature != null) {
64
- let t = provider.temperature
65
- // Anthropic API hard limit is 0-1; models without a declared tempRange still get clamped
66
- const [tMin, tMax] = spec.tempRange ?? [0, 1]
67
- t = Math.min(tMax, Math.max(tMin, t))
68
- t = Math.round(t * 100) / 100
69
- body.temperature = t
70
- }
71
-
72
- // 2026-09-01:FETCH_TIMEOUT_MS 常量退役(绝对墙钟废除)——anthropic/responses 经 core.mjs 的
73
- // effectiveFetchTimeoutMs 共用;响应头阶段 600s 默认,body 阶段 idle 超时。
74
- const headers = {
75
- ...(provider.headers ?? {}), // 定制头展开(PROVIDER.md §21):定制头在前、内置头在后——同名内置头胜出
76
- "Content-Type": "application/json",
77
- "x-api-key": provider.apiKey,
78
- "anthropic-version": ANTHROPIC_VERSION,
79
- }
80
-
81
- // Active signal check
82
- if (signal?.aborted) throw abortError(signal, "provider", "transport-anthropic")
83
-
84
- // 会诊 #6:TPM/RPM 闸门 + 记账(rate.mjs 与 OpenAI 格式共用同一窗口)
85
- const { rateGate, recordRate } = await import("./rate.mjs")
86
- const estimated = await (async () => {
87
- const { estimateRequestTokens } = await import("./rate.mjs")
88
- return estimateRequestTokens(body)
89
- })()
90
- await rateGate(provider, estimated, onWait, signal)
91
-
92
- // 2026-08-31:4xx/5xx/网络与 OpenAI 格式统一退避重试链(原仅 429 Retry-After 单次重试,
93
- // 5xx 直接抛——DeepSeek/Claude 排队 503 时其他格式可自动恢复,这里语义割裂)
94
- const response = await requestWithRetry(
95
- () => proxyFetch(`${provider.baseURL}/messages`, {
96
- method: "POST",
97
- headers,
98
- body: JSON.stringify(body),
99
- // 2026-09-01:同 core.mjs——绝对墙钟废除(长生成被 10min 腰斩),signal 只保留用户取消链;
100
- // 响应头阶段仍用 fetchTimeoutMs(600s 默认),body 阶段由 parseAnthropicStream 读侧 idle 管
101
- signal,
102
- _headerTimeoutMs: effectiveFetchTimeoutMs(provider),
103
- _bodyIdleMs: 120_000,
104
- }, provider.proxyUri),
105
- { signal, onWait, buildMessage: (status, text) => `Anthropic API error ${status}: ${text}` },
106
- )
107
-
108
- const result = await parseAnthropicStream(response, { onToken, onReasoning, signal })
109
- recordRate(provider, estimated, result.usage)
110
- return finishAnthropic(result)
111
- }
112
-
113
- /** Convert the parsed stream to the core.mjs result shape (usage → OpenAI-compatible). */
114
- function finishAnthropic(result) {
115
- const usage = result.usage
116
- if (usage) {
117
- return {
118
- content: result.content,
119
- reasoning: result.reasoning,
120
- usage: {
121
- prompt_tokens: usage.input_tokens ?? 0,
122
- completion_tokens: usage.output_tokens ?? 0,
123
- total_tokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),
124
- prompt_cache_hit_tokens: usage.cache_read_input_tokens ?? 0,
125
- prompt_cache_miss_tokens: usage.cache_creation_input_tokens ?? 0,
126
- },
127
- toolCalls: result.toolCalls,
128
- }
129
- }
130
- return { content: result.content, reasoning: result.reasoning, toolCalls: result.toolCalls }
131
- }
132
-
133
- /**
134
- * Parse Anthropic SSE stream.
135
- * Events: message_start, content_block_start, content_block_delta, content_block_stop, message_delta, message_stop
136
- */
137
- async function parseAnthropicStream(response, { onToken, onReasoning, signal }) {
138
- const result = { content: "", reasoning: "", toolCalls: [], usage: null }
139
- const decoder = new TextDecoder()
140
- let buffer = ""
141
- const toolBlocks = new Map()
142
-
143
- const processEvent = (eventType, data) => {
144
- if (!data) return
145
- let json
146
- try { json = JSON.parse(data) } catch { return }
147
-
148
- switch (eventType) {
149
- case "message_start":
150
- if (json.message?.usage) result.usage = json.message.usage
151
- break
152
- case "content_block_start": {
153
- const block = json.content_block
154
- if (block?.type === "tool_use") {
155
- toolBlocks.set(json.index, { id: block.id, name: block.name, arguments: "" })
156
- }
157
- break
158
- }
159
- case "content_block_delta": {
160
- const delta = json.delta
161
- if (delta?.type === "text_delta" && delta.text) {
162
- result.content += delta.text
163
- onToken?.(delta.text)
164
- } else if (delta?.type === "thinking_delta" && delta.thinking) {
165
- result.reasoning += delta.thinking
166
- onReasoning?.(delta.thinking)
167
- } else if (delta?.type === "input_json_delta" && delta.partial_json) {
168
- const block = toolBlocks.get(json.index)
169
- if (block) block.arguments += delta.partial_json
170
- }
171
- break
172
- }
173
- case "message_delta":
174
- if (json.usage) result.usage = json.usage
175
- break
176
- case "message_stop":
177
- for (const [, block] of toolBlocks) {
178
- result.toolCalls.push({ id: block.id, name: block.name, arguments: block.arguments })
179
- }
180
- break
181
- }
182
- }
183
-
184
- if (!response.body) throw new Error("No stream response body")
185
- let currentEvent = ""
186
- let currentData = ""
187
-
188
- for await (const chunk of response.body) {
189
- if (signal?.aborted) {
190
- throw abortError(signal, "provider", "transport-anthropic")
191
- }
192
- buffer += decoder.decode(chunk, { stream: true })
193
- // BOM 剥除(会诊 #12):首个 chunk 可能带 \uFEFF,否则 message_start 事件被静默丢失(含 usage)
194
- if (buffer.charCodeAt(0) === 0xfeff) buffer = buffer.slice(1)
195
- const lines = buffer.split("\n")
196
- buffer = lines.pop()
197
-
198
- for (const line of lines) {
199
- if (line.startsWith("event: ")) {
200
- if (currentEvent) processEvent(currentEvent, currentData)
201
- currentEvent = line.slice(7).trim()
202
- currentData = ""
203
- } else if (line.startsWith("data: ")) {
204
- currentData = line.slice(6).trim()
205
- } else if (line === "" || line === "\r") { // CRLF 空行是 "\r"(会诊 #13)
206
- if (currentEvent) processEvent(currentEvent, currentData)
207
- currentEvent = ""
208
- currentData = ""
209
- }
210
- }
211
- }
212
- // Flush remaining
213
- buffer += decoder.decode()
214
- for (const line of buffer.split("\n")) {
215
- if (line.startsWith("event: ")) {
216
- if (currentEvent) processEvent(currentEvent, currentData)
217
- currentEvent = line.slice(7)
218
- } else if (line.startsWith("data: ")) {
219
- currentData = line.slice(6)
220
- }
221
- }
222
- if (currentEvent) processEvent(currentEvent, currentData)
223
-
224
- return result
225
- }