thincoder 0.12.62 → 0.12.63

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 (228) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +13 -12
  3. package/bin/thincoder.mjs +53 -27
  4. package/package.json +6 -5
  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 +240 -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 +59 -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 +25 -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-reindex.mjs +1 -1
  31. package/src/tui/cmd-restore.mjs +2 -2
  32. package/src/tui/cmd-session.mjs +24 -1
  33. package/src/tui/cmd-skills.mjs +1 -1
  34. package/src/tui/cmd-think.mjs +22 -9
  35. package/src/tui/config-helpers.mjs +1 -1
  36. package/src/tui/display-budget.mjs +33 -11
  37. package/src/tui/index.mjs +9 -9
  38. package/src/tui/interaction.mjs +16 -7
  39. package/src/tui/key-modes.mjs +9 -4
  40. package/src/tui/ledger-surface.mjs +26 -10
  41. package/src/tui/model-catalog.mjs +4 -4
  42. package/src/tui/model-picker.mjs +8 -7
  43. package/src/tui/mouse.mjs +11 -6
  44. package/src/tui/pickers.mjs +15 -2
  45. package/src/tui/render-conversation.mjs +1 -1
  46. package/src/tui/render-frame.mjs +10 -5
  47. package/src/tui/render-loop.mjs +1 -1
  48. package/src/tui/render-segments.mjs +3 -1
  49. package/src/tui/slash-commands.mjs +1 -1
  50. package/src/tui/startup.mjs +14 -14
  51. package/src/tui/subagent-blocks.mjs +20 -3
  52. package/src/tui/subagent-freeze.mjs +73 -2
  53. package/src/tui/suspension-drive.mjs +46 -22
  54. package/src/tui/tool-events.mjs +11 -8
  55. package/src/tui/wizard.mjs +3 -3
  56. package/src/abort-provenance.mjs +0 -116
  57. package/src/advisor/citations.mjs +0 -139
  58. package/src/advisor/compaction.mjs +0 -174
  59. package/src/advisor/convergence.mjs +0 -80
  60. package/src/advisor/history.mjs +0 -77
  61. package/src/advisor/loop.mjs +0 -293
  62. package/src/advisor/messages.mjs +0 -299
  63. package/src/advisor/project-context.mjs +0 -194
  64. package/src/advisor/repos.mjs +0 -150
  65. package/src/advisor/run.mjs +0 -293
  66. package/src/advisor/truncate.mjs +0 -57
  67. package/src/advisor.mjs +0 -290
  68. package/src/agent/completion.mjs +0 -146
  69. package/src/agent/dispatch.mjs +0 -489
  70. package/src/agent/helpers.mjs +0 -384
  71. package/src/agent/post-turn.mjs +0 -70
  72. package/src/agent/record-results.mjs +0 -174
  73. package/src/agent/relay-prefix.mjs +0 -39
  74. package/src/agent/run-stages.mjs +0 -244
  75. package/src/agent/setup-reminders.mjs +0 -69
  76. package/src/agent/setup.mjs +0 -354
  77. package/src/agent/spawn-child.mjs +0 -243
  78. package/src/agent-tools/advisor-async.mjs +0 -346
  79. package/src/agent-tools/advisor-settle.mjs +0 -231
  80. package/src/agent-tools/advisor.mjs +0 -260
  81. package/src/agent-tools/async-settle.mjs +0 -204
  82. package/src/agent-tools/batch-segment.mjs +0 -195
  83. package/src/agent-tools/consult.mjs +0 -473
  84. package/src/agent-tools/design-token.mjs +0 -117
  85. package/src/agent-tools/digest-budget.mjs +0 -76
  86. package/src/agent-tools/eng.mjs +0 -67
  87. package/src/agent-tools/escalate-async.mjs +0 -295
  88. package/src/agent-tools/goal.mjs +0 -119
  89. package/src/agent-tools/plan.mjs +0 -81
  90. package/src/agent-tools/read-history.mjs +0 -309
  91. package/src/agent-tools/recent-changes.mjs +0 -24
  92. package/src/agent-tools/review-streak.mjs +0 -93
  93. package/src/agent-tools/settings.mjs +0 -265
  94. package/src/agent-tools/skill.mjs +0 -47
  95. package/src/agent-tools/subagent-actions.mjs +0 -482
  96. package/src/agent-tools/subagent-async.mjs +0 -434
  97. package/src/agent-tools/subagent-panel.mjs +0 -160
  98. package/src/agent-tools/subagent-run.mjs +0 -205
  99. package/src/agent-tools/subagent-scheduler.mjs +0 -392
  100. package/src/agent-tools/subagent-spawn.mjs +0 -459
  101. package/src/agent-tools/subagent.mjs +0 -404
  102. package/src/agent-tools/task.mjs +0 -87
  103. package/src/agent-tools/timer.mjs +0 -46
  104. package/src/agent-tools/verify.mjs +0 -271
  105. package/src/agent-tools.mjs +0 -17
  106. package/src/agent.mjs +0 -417
  107. package/src/auto-think.mjs +0 -115
  108. package/src/config-migrate.mjs +0 -70
  109. package/src/config.mjs +0 -496
  110. package/src/context.mjs +0 -392
  111. package/src/conventions.mjs +0 -223
  112. package/src/embedding.mjs +0 -120
  113. package/src/escape.mjs +0 -152
  114. package/src/expand-home.mjs +0 -16
  115. package/src/explore-distill.mjs +0 -155
  116. package/src/generate-title.mjs +0 -88
  117. package/src/git/checkpoint.mjs +0 -448
  118. package/src/git/gitmem.mjs +0 -100
  119. package/src/hooks.mjs +0 -97
  120. package/src/ledger.mjs +0 -227
  121. package/src/log.mjs +0 -195
  122. package/src/markdown.mjs +0 -106
  123. package/src/mcp/helpers.mjs +0 -51
  124. package/src/mcp/transport-http.mjs +0 -248
  125. package/src/mcp/transport-stdio.mjs +0 -140
  126. package/src/mcp/transport-ws.mjs +0 -122
  127. package/src/mcp.mjs +0 -295
  128. package/src/memory/code-index.mjs +0 -219
  129. package/src/memory/code-sync.mjs +0 -415
  130. package/src/memory/core.mjs +0 -299
  131. package/src/memory/delete.mjs +0 -236
  132. package/src/memory/docs.mjs +0 -419
  133. package/src/memory/file-walk.mjs +0 -109
  134. package/src/memory/scan.mjs +0 -95
  135. package/src/memory/schema.mjs +0 -452
  136. package/src/memory.mjs +0 -21
  137. package/src/model-ref.mjs +0 -66
  138. package/src/model-specs.mjs +0 -179
  139. package/src/peer-domains.mjs +0 -265
  140. package/src/peer-instances.mjs +0 -231
  141. package/src/prompt-overlays.mjs +0 -82
  142. package/src/prompts/advisor-design.md +0 -41
  143. package/src/prompts/advisor-round1.md +0 -41
  144. package/src/prompts/advisor-round2.md +0 -46
  145. package/src/prompts/advisor-round3.md +0 -42
  146. package/src/prompts/common.md +0 -115
  147. package/src/prompts/consult-base.md +0 -19
  148. package/src/prompts/discipline-engineering.md +0 -258
  149. package/src/prompts/discipline-normal.md +0 -185
  150. package/src/prompts/persona-coder.md +0 -21
  151. package/src/prompts/persona-eng-coder.md +0 -37
  152. package/src/prompts/persona-eng-designer.md +0 -60
  153. package/src/prompts/persona-engineering.md +0 -55
  154. package/src/prompts/persona-explore.md +0 -15
  155. package/src/prompts/persona-normal.md +0 -27
  156. package/src/prompts/persona-plan.md +0 -26
  157. package/src/provider/anthropic.mjs +0 -225
  158. package/src/provider/core.mjs +0 -476
  159. package/src/provider/errors.mjs +0 -101
  160. package/src/provider/google.mjs +0 -257
  161. package/src/provider/index.mjs +0 -7
  162. package/src/provider/list-models.mjs +0 -93
  163. package/src/provider/normalize.mjs +0 -81
  164. package/src/provider/rate.mjs +0 -108
  165. package/src/provider/responses.mjs +0 -495
  166. package/src/provider/retry.mjs +0 -88
  167. package/src/provider/sse.mjs +0 -264
  168. package/src/proxy.mjs +0 -261
  169. package/src/rules.mjs +0 -53
  170. package/src/session-gc.mjs +0 -221
  171. package/src/session-guard.mjs +0 -59
  172. package/src/session-migrate.mjs +0 -48
  173. package/src/session-rename.mjs +0 -38
  174. package/src/session-segments.mjs +0 -100
  175. package/src/session-slots.mjs +0 -492
  176. package/src/session-store.mjs +0 -441
  177. package/src/session.mjs +0 -492
  178. package/src/skills.mjs +0 -153
  179. package/src/text-budget.mjs +0 -46
  180. package/src/token-ttl.mjs +0 -274
  181. package/src/tools/apply_patch.md +0 -15
  182. package/src/tools/bash.md +0 -37
  183. package/src/tools/bash.mjs +0 -268
  184. package/src/tools/checklist-sync.mjs +0 -181
  185. package/src/tools/checklist.md +0 -13
  186. package/src/tools/checklist.mjs +0 -299
  187. package/src/tools/delete.md +0 -13
  188. package/src/tools/edit-batch.mjs +0 -191
  189. package/src/tools/edit-diff.mjs +0 -348
  190. package/src/tools/edit.md +0 -30
  191. package/src/tools/execute.md +0 -21
  192. package/src/tools/execute.mjs +0 -228
  193. package/src/tools/fetch.md +0 -12
  194. package/src/tools/file.mjs +0 -469
  195. package/src/tools/file_ops.md +0 -17
  196. package/src/tools/get_current_time.md +0 -8
  197. package/src/tools/git-checkpoint.mjs +0 -143
  198. package/src/tools/git-ext.mjs +0 -173
  199. package/src/tools/git.md +0 -54
  200. package/src/tools/git.mjs +0 -356
  201. package/src/tools/glob-dialect.mjs +0 -130
  202. package/src/tools/glob.md +0 -11
  203. package/src/tools/grep.md +0 -19
  204. package/src/tools/hashline_edit.md +0 -14
  205. package/src/tools/index.mjs +0 -36
  206. package/src/tools/insert_after.md +0 -15
  207. package/src/tools/lint.md +0 -10
  208. package/src/tools/linter.mjs +0 -128
  209. package/src/tools/ls.md +0 -12
  210. package/src/tools/lsp.md +0 -10
  211. package/src/tools/lsp.mjs +0 -316
  212. package/src/tools/ops.mjs +0 -299
  213. package/src/tools/patch.mjs +0 -282
  214. package/src/tools/process.md +0 -10
  215. package/src/tools/question.md +0 -16
  216. package/src/tools/question.mjs +0 -26
  217. package/src/tools/read.md +0 -20
  218. package/src/tools/read_image.md +0 -8
  219. package/src/tools/repomap.mjs +0 -314
  220. package/src/tools/search.mjs +0 -236
  221. package/src/tools/shared.mjs +0 -446
  222. package/src/tools/tree.md +0 -14
  223. package/src/tools/tree.mjs +0 -66
  224. package/src/tools/wait_for.md +0 -22
  225. package/src/tools/web.mjs +0 -224
  226. package/src/tools/websearch.md +0 -16
  227. package/src/tools/write.md +0 -11
  228. 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
- }