thincoder 0.12.64 → 0.12.65
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.
- package/CHANGELOG.md +24 -0
- package/README.md +99 -42
- package/bin/thincoder.mjs +18 -0
- package/package.json +2 -2
- package/src/acp/handlers-session.mjs +25 -1
- package/src/acp/handlers-slots.mjs +1 -1
- package/src/tui/agent-turn.mjs +5 -2
- package/src/tui/cmd-advisor.mjs +1 -1
- package/src/tui/cmd-eng.mjs +2 -1
- package/src/tui/cmd-mcp-form.mjs +11 -5
- package/src/tui/conversation-writer.mjs +62 -0
- package/src/tui/index.mjs +43 -305
- package/src/tui/input-face.mjs +187 -0
- package/src/tui/key-handler-busy.mjs +42 -0
- package/src/tui/key-handler-ctrlc.mjs +118 -0
- package/src/tui/key-handler-edit.mjs +115 -0
- package/src/tui/key-handler-modals.mjs +87 -0
- package/src/tui/key-handler-scroll.mjs +110 -0
- package/src/tui/key-handler.mjs +32 -382
- package/src/tui/render-frame.mjs +8 -3
- package/src/tui/subagent-freeze.mjs +3 -3
- package/src/tui/suspension-drive.mjs +10 -9
- package/src/tui/tui-state.mjs +65 -0
- package/src/tui/turn-face.mjs +64 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## [0.12.65] — 2026-09-22
|
|
2
|
+
|
|
3
|
+
> 0.12.64 → 0.12.65(连续号——发布时定号)
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`session index` 命令**(`--status` 读数 / `--rebuild` 全量重扫)+ 启动后懒建索引;`read_history` 走索引——超大会话可答 + `path:"all"` 跨会话检索。
|
|
8
|
+
- **忙时排队提交**:主会话忙时 Enter 不再被吞——入单槽 + `[sending queued message]` 回执 + 回合边界送达;**挂起会话内**同样受理;Ctrl+I 保持打断式通道。
|
|
9
|
+
- **退出即释放会话认领**:Ctrl+C / 正常退出释放本进程认领——重启恢复直达原槽。
|
|
10
|
+
- **`session gc` 进度 / 预估行**(显式面长跑可见)。
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **MCP 表单脱敏**:headers/env 值位改 `••••(masked)`(键名保留)——与设置工具同谓词单源。
|
|
15
|
+
- **槽绑定优先写**:`/eng` · `/advisor` 写面改 `agent._slot ?? activeSlot(cwd)`(不写他槽)。
|
|
16
|
+
- **i18n 单源**:auto-turn 上限行改读核键(`digest.capAuto` / `digest.capStop`)。
|
|
17
|
+
- **`git diff` / `log` 传 path 未命中 ⇒ 加注**(不再显示成假洁净)。
|
|
18
|
+
- **结构收正(内部)**:`key-handler` 拆五族档(498 → 124 + 5 档)· `index.mjs` 拆四新档(`startTUI` 417 → 149)· README 折行。
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- **TUI 退出钩子 TypeError**(`ledgerSurface.dispose` 打在 Promise 上)——每次退出抛错,已修(`node test-startup.mjs` 转绿)。
|
|
23
|
+
- 表单 `[object Object]` 渲染瑕疙 · plan 未知 action 报错串断言补全 · 压缩第三去向用例补全。
|
|
24
|
+
|
|
1
25
|
## [0.12.64] — 2026-09-21
|
|
2
26
|
|
|
3
27
|
> 0.12.63 → 0.12.64(连续号——发布时定号)
|
package/README.md
CHANGED
|
@@ -8,25 +8,33 @@ The "Thin" in ThinCoder doesn't mean "feature-poor" — it means **sharp thinkin
|
|
|
8
8
|
While every AI agent races to be "all-powerful", ThinCoder plays the opposite card: **restraint, precision, no filler**.
|
|
9
9
|
Its persona is a geek engineer of few words who cuts to the bone: give it a complex requirement, get back a clean implementation.
|
|
10
10
|
|
|
11
|
-
Design philosophy (the entire meaning of the name): if the Node standard library can do it, no third-party dependency is allowed. The project's `node_modules` contains no third-party packages — only the first-party `@thincoder/core` shared core (a local link in development,
|
|
11
|
+
Design philosophy (the entire meaning of the name): if the Node standard library can do it, no third-party dependency is allowed. The project's `node_modules` contains no third-party packages — only the first-party `@thincoder/core` shared core (a local link in development,
|
|
12
|
+
resolved from the npm registry for releases).
|
|
12
13
|
|
|
13
14
|
## Features
|
|
14
15
|
|
|
15
16
|
- **Fix-verify loop**: file changes without `verify` get pushed back — syntax check + tests must pass before the agent can claim completion (auto-repair up to 3 rounds)
|
|
16
17
|
- **Checkpoint system**: auto-snapshot before every user task, `list`/`create`/`rewind` tools for the model, single-file restore — rewinding itself is reversible (pre-rewind state auto-saved)
|
|
17
|
-
- **Codebase understanding** ⭐0.5.0: `repo_outline` (dependency outline, auto-injected at startup), `code_search` (source FTS5 + vectors + JSDoc extraction), `doc_search` (docs chunked by ## headings) — background indexing, auto-incremental updates on file writes, three tools
|
|
18
|
-
|
|
18
|
+
- **Codebase understanding** ⭐0.5.0: `repo_outline` (dependency outline, auto-injected at startup), `code_search` (source FTS5 + vectors + JSDoc extraction), `doc_search` (docs chunked by ## headings) — background indexing, auto-incremental updates on file writes, three tools
|
|
19
|
+
guided by "structure → intent → details"
|
|
20
|
+
- **Model adaptation** ⭐: top-tier only, latest only. Built-in flagship models from twenty-one providers — DeepSeek / Kimi / Kimi For Coding / GLM / GLM Coding Plan (智谱 Coding) / Qwen / Qwen Token Plan / MiMo (小米) / MiMo Token Plan (小米套餐) / MiniMax / OpenAI / Claude / Gemini /
|
|
21
|
+
Grok / Mistral / Volcengine Ark (豆包) / Hunyuan (腾讯混元) / Tencent TokenHub (腾讯混元网关) / SiliconFlow (硅基流动) / OpenRouter / Groq. No legacy model compatibility. Auto-matched context windows, truncation-resume protocols (prefix/partial), thinking-mode APIs (thinking.type /
|
|
22
|
+
reasoning_effort), reasoning_content echo strategies (reasoningEcho), output limits, temperature range clamping — all deeply adapted.
|
|
19
23
|
- **Toolset**: `read` / `write` / `edit` / `bash` / `glob` (supports `**`) / `grep` / `websearch` / `ls` / `fetch` + `read_image` (image/video paste) + three retrieval tools + MCP — all zero-dependency, file tools confined to the working directory
|
|
20
24
|
- **Memory system**: three layers (personal/project/team), FTS5 + vector RRF hybrid retrieval, git-friendly markdown format
|
|
21
25
|
- **Two-phase tool scheduling**: permission prompts serialized, read-only tools parallelized, side-effect tools serialized
|
|
22
26
|
- **Session persistence** ⭐0.5.0: unlimited archive slots, `/session` to switch anytime, tool results visible after restore. Process-level isolation — multiple instances in the same directory each get their own session slot
|
|
23
|
-
- **Concurrent subagents**: five roles — `explore`/`plan`/`coder`/`eng-coder`/`eng-designer` — dispatched in parallel, streaming output visible, reports land in the conversation; per-subagent model override (`subagent` tool `model` arg or `agent.subagentModel` config — e.g.
|
|
24
|
-
|
|
27
|
+
- **Concurrent subagents**: five roles — `explore`/`plan`/`coder`/`eng-coder`/`eng-designer` — dispatched in parallel, streaming output visible, reports land in the conversation; per-subagent model override (`subagent` tool `model` arg or `agent.subagentModel` config — e.g.
|
|
28
|
+
discuss with `glm-5.2`, let `deepseek-v4-flash` implement)
|
|
29
|
+
- **Multi-model consultation 会诊 + 飞刀 (escalate)** ⭐0.12.30: `consult_start`/`consult_stop` run several configured models in parallel as independent read-only consultants (each with its own TUI activity card, `main_history` access to the failure trail); when every model settles,
|
|
30
|
+
the full verdict digest is delivered automatically (R17 — consult_check retired). `escalate` flies in a stronger model for a single expert implementation run with full write access (default-async since R17 — the post-op report arrives automatically with its mutations merged).
|
|
31
|
+
Candidate pool = `agent.consultModels` ([{ provider, model, effort? }], up to 5); budgets via `agent.consultTurns` / `agent.consultTimeoutMs`
|
|
25
32
|
- **Plan Mode**: read-only exploration + design, implement after user approval
|
|
26
33
|
- **AUTO mode**: `/auto` full authorization, no confirmations on long tasks
|
|
27
34
|
- **Task tracking**: `task` tool breaks down multi-step work, status bar ✓n/m live progress, auto-filters completed items
|
|
28
35
|
- **Goal/Verify/Skills**: long-goal tracking, completion verification, reusable skills
|
|
29
|
-
- **Streaming TUI**: bare ANSI, permission preview right above the input box, write/edit auto-shows diffs, paste shortcut hint in the input box corner for multimodal models (Win: Alt+V / Mac/Linux: Ctrl+V). Two-level model picker (providers → models), search/filter support,
|
|
36
|
+
- **Streaming TUI**: bare ANSI, permission preview right above the input box, write/edit auto-shows diffs, paste shortcut hint in the input box corner for multimodal models (Win: Alt+V / Mac/Linux: Ctrl+V). Two-level model picker (providers → models), search/filter support,
|
|
37
|
+
Shift+Enter for multiline input
|
|
30
38
|
|
|
31
39
|
## Memory: What One Learns, the Whole Team Knows
|
|
32
40
|
|
|
@@ -69,7 +77,8 @@ npm install -g thincoder
|
|
|
69
77
|
thincoder
|
|
70
78
|
```
|
|
71
79
|
|
|
72
|
-
First launch walks you through a setup wizard: arrow keys to pick a provider (built-in presets or a custom endpoint) → enter API key → optionally enter an embedding key (SiliconFlow, enables vector memory search, skippable) → arrow keys to pick a model — no hand-editing config
|
|
80
|
+
First launch walks you through a setup wizard: arrow keys to pick a provider (built-in presets or a custom endpoint) → enter API key → optionally enter an embedding key (SiliconFlow, enables vector memory search, skippable) → arrow keys to pick a model — no hand-editing config
|
|
81
|
+
files. Adjust anytime with `/model` (add/remove providers, set keys, custom endpoints) or `/config embedkey`. `chat`/`distill` also offer in-place interactive setup when no key is configured in a terminal (in pipes/CI they exit with an error and instructions).
|
|
73
82
|
|
|
74
83
|
You can also hand-write `~/.thincoder/config.json` (see "Configuration" below), then:
|
|
75
84
|
|
|
@@ -95,11 +104,16 @@ thincoder upgrade
|
|
|
95
104
|
|
|
96
105
|
Running from source: replace `thincoder` above with `node bin/thincoder.mjs`.
|
|
97
106
|
|
|
98
|
-
Slash commands in the TUI: `/help`, `/model` (two-level picker: first select provider, then model; also add/remove providers, set keys, custom endpoints; `/model <provider>:<name>` switches directly), `/submodel` (subagent models per type — picker over global +
|
|
107
|
+
Slash commands in the TUI: `/help`, `/model` (two-level picker: first select provider, then model; also add/remove providers, set keys, custom endpoints; `/model <provider>:<name>` switches directly), `/submodel` (subagent models per type — picker over global +
|
|
108
|
+
explore/plan/coder/eng-coder/eng-designer slots, or `/submodel <type> <provider:model>` directly), `/shell` (platform-aware picker of available shells — e.g. `/shell` → pick Git Bash/pwsh, or `/shell "C:\Program Files\Git\bin\bash.exe"`, `/shell reset`; fixes win11 cmd
|
|
109
|
+
encoding/command issues), `/think` (thinking mode toggle and reasoning effort), `/config` (view config; no-argument form opens the interactive menu — e.g. default model, embedding key, proxy; `/config embedkey` sets the embedding key directly), `/session` (list/switch archived
|
|
110
|
+
sessions), `/reindex` (rebuild the index), `/extract` (extract knowledge from the current session), `/restore` (restore checkpoint), `/clear`, `/exit`. High-frequency commands support abbreviations: `/h` `/x` `/m` `/p` `/t` `/c` `/n`. Typing `/` shows live matching hints in the
|
|
111
|
+
status bar. Model picker supports search/filter — type to narrow down results.
|
|
99
112
|
|
|
100
113
|
Configuration comes exclusively from `~/.thincoder/config.json` — no environment-variable configuration is supported.
|
|
101
114
|
|
|
102
|
-
> **Kimi note**: Kimi has **two separate platforms with non-interchangeable API keys** — Moonshot (`https://api.moonshot.cn/v1`, keys `sk-...`, platform.moonshot.cn) and **Kimi For Coding** (`https://api.kimi.com/coding/v1`, keys `sk-kimi-...`, platform.kimi.com, model ID `k3`).
|
|
115
|
+
> **Kimi note**: Kimi has **two separate platforms with non-interchangeable API keys** — Moonshot (`https://api.moonshot.cn/v1`, keys `sk-...`, platform.moonshot.cn) and **Kimi For Coding** (`https://api.kimi.com/coding/v1`, keys `sk-kimi-...`, platform.kimi.com, model ID `k3`).
|
|
116
|
+
> Use the `kimi` preset for Moonshot and `kimi-code` for Kimi For Coding — putting one platform's key on the other's endpoint fails with 401 (a hint is appended when the key/baseURL look mismatched).
|
|
103
117
|
|
|
104
118
|
## Configuration
|
|
105
119
|
|
|
@@ -212,6 +226,13 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
212
226
|
|
|
213
227
|
## Changelog
|
|
214
228
|
|
|
229
|
+
### 0.12.65 (2026-09)
|
|
230
|
+
- **Session index** — `thincoder session index [--status|--rebuild]`. `read_history` now answers over-limit sessions and searches across sessions (`path:"all"`), backed by a derived, rebuildable `node:sqlite` index; the session files remain the only source of truth.
|
|
231
|
+
- **Queue submissions while busy** — Enter during a running turn is no longer swallowed: it lands in a single slot with a visible `[sending queued message]` receipt and runs at the turn boundary. The same now applies inside suspended sessions. Ctrl+I stays the interrupt-style channel.
|
|
232
|
+
- **Release claims on exit** — a clean exit frees this process's session claims, so restarts resume directly instead of relying on process probing.
|
|
233
|
+
- **Safer, clearer surfaces** — MCP form headers/env values are masked; `/eng` and `/advisor` write to the bound slot; `git diff`/`log` note an unmatched pathspec instead of looking clean; `session gc` prints progress and estimates.
|
|
234
|
+
- **Fixes** — the TUI exit no longer throws (`ledgerSurface.dispose`); oversized modules split (`key-handler` 498→124 + 5 family modules; `index.mjs` 499→228, `startTUI` 417→149).
|
|
235
|
+
|
|
215
236
|
### 0.12.64 (2026-09)
|
|
216
237
|
- **PROJECT-MANIFEST model** — per-use project resolution (owning-ancestor discovery + a five-step ladder); a missing manifest is no longer fatal (degrade at startup + a clear prompt to build one).
|
|
217
238
|
- **Batch record lifecycle tool** (`batch`: create / append / status / close), **ledger executor column**, **two-tier signal lines** (digest/ask) with the start line, and **session claim release** (rejections write nothing).
|
|
@@ -227,8 +248,10 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
227
248
|
- Last release in the pre-core shape (self-contained copies); 0.12.63 onward resolves the core from `@thincoder/core`.
|
|
228
249
|
|
|
229
250
|
### 0.12.11 (2026-08)
|
|
230
|
-
- **Subagent model per type** — `subagent` tool `model` arg, `config.agent.subagentModels` (per explore/plan/coder/eng-coder) and `config.agent.subagentModel` (global fallback); priority: tool arg > type > global > parent provider. `/submodel` TUI command: picker over 5 slots
|
|
231
|
-
|
|
251
|
+
- **Subagent model per type** — `subagent` tool `model` arg, `config.agent.subagentModels` (per explore/plan/coder/eng-coder) and `config.agent.subagentModel` (global fallback); priority: tool arg > type > global > parent provider. `/submodel` TUI command: picker over 5 slots
|
|
252
|
+
(global + 4 roles) with provider→model selection, or direct args (`/submodel coder deepseek:deepseek-v4-flash`).
|
|
253
|
+
- **Configurable bash shell** — `config.shell` or `/shell` TUI command: platform-aware picker (Windows: pwsh/Git Bash/WSL bash; POSIX: bash/zsh/fish — availability-detected, custom path supported). Windows default cmd now forces UTF-8 per command (`chcp 65001`) — fixes garbled
|
|
254
|
+
Chinese output on win11.
|
|
232
255
|
- **Markdown table alignment fix** — `stringWidth` strips ANSI (zero display width) and rendered table rows are padded back to the computed width; inline markers (`` `code` ``, `**bold**`) no longer shift the borders.
|
|
233
256
|
- **sliceByWidth keeps ANSI sequences whole** — never slices mid-escape-sequence.
|
|
234
257
|
|
|
@@ -236,44 +259,57 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
236
259
|
- **Code-quality pass (advisor subsystem):**
|
|
237
260
|
- **Drop 11 unused exports** — internal-use symbols no longer leak through the module API (advisor table headers/constants, plan reminders, token-UUID helper, shrinkOversized).
|
|
238
261
|
- **Advisor tool-timeout timer is now cleared** when the tool wins the race (no dangling timers); static import replaces a dynamic import on the hot path.
|
|
239
|
-
- **Advisor re-review no longer trusts git output** — the follow-up path previously injected a `git diff HEAD` snapshot: once fixes were committed the diff was empty and the model read "no changes" as "no fixes", misreporting fixed items as unfixed. The follow-up now injects
|
|
262
|
+
- **Advisor re-review no longer trusts git output** — the follow-up path previously injected a `git diff HEAD` snapshot: once fixes were committed the diff was empty and the model read "no changes" as "no fixes", misreporting fixed items as unfixed. The follow-up now injects
|
|
263
|
+
**no git information at all** — verification is `read`-only, evidence must quote this round's read output (line numbers from the stale prior table are not evidence), and dead snapshot-dedup fields were removed.
|
|
240
264
|
|
|
241
265
|
### 0.12.9 (2026-08)
|
|
242
266
|
- **Prompt-system quality pass (both CLI and VS Code extension, byte-identical sync):**
|
|
243
267
|
- **Advisor-after-code rule moved from system.md to discipline.md** — engineering mode no longer receives the conflicting "call advisor after changing code" instruction (its review-timing rules say do not call unprompted). Standard mode behavior unchanged.
|
|
244
|
-
- **engineering.md delivery-review semantics unified** — the mandatory-flow step and the state table now both say: eng-coder self-reviews inside the subagent; the architect verifies against acceptance criteria and re-reviews only when asked or when the delivery looks wrong.
|
|
268
|
+
- **engineering.md delivery-review semantics unified** — the mandatory-flow step and the state table now both say: eng-coder self-reviews inside the subagent; the architect verifies against acceptance criteria and re-reviews only when asked or when the delivery looks wrong.
|
|
269
|
+
(Previously the step forced a parent-side advisor code review that the hard rules contradicted.)
|
|
245
270
|
- **checkpoint description aligned with actual auto-snapshot triggers** (task-list deletion + context compaction; manual checkpoint for the rest).
|
|
246
271
|
- **advisor round budget wording fixed** — prompts advertise a 30-round budget; the mechanical hard cap is 100 rounds (loop guard). Both layers are now named explicitly.
|
|
247
272
|
|
|
248
273
|
### 0.12.8 (2026-08)
|
|
249
|
-
- **Fix: pending-task pushback fires at most once** — the completion guard that reminds the model to update pending tasks before finishing could loop forever when a pending item could not be resolved. Now each task-list state earns exactly one reminder; if the model insists on
|
|
274
|
+
- **Fix: pending-task pushback fires at most once** — the completion guard that reminds the model to update pending tasks before finishing could loop forever when a pending item could not be resolved. Now each task-list state earns exactly one reminder; if the model insists on
|
|
275
|
+
finishing anyway, it is allowed to (updating the list via the task tool resets the budget). VS Code extension synced.
|
|
250
276
|
|
|
251
277
|
### 0.12.7 (2026-08)
|
|
252
|
-
- **Fix: long replies and thinking are never folded** — the long-message folding feature (0.12.6) collapsed main output and reasoning behind a click when they exceeded 12 lines, hurting readability. Folding now applies to secondary dim-colored content (tool summaries/status)
|
|
278
|
+
- **Fix: long replies and thinking are never folded** — the long-message folding feature (0.12.6) collapsed main output and reasoning behind a click when they exceeded 12 lines, hurting readability. Folding now applies to secondary dim-colored content (tool summaries/status)
|
|
279
|
+
only; expanded blocks are exempt from the consecutive-dim folding so nothing folds twice.
|
|
253
280
|
- **Fix: wide tables misaligned in narrow terminals** — a many-column table that still exceeded the terminal width after column shrinking (e.g. 8 columns at 40 cols) wrapped at the terminal and misaligned. Table rows are now clipped with an ellipsis instead of ever exceeding the width.
|
|
254
281
|
|
|
255
282
|
### 0.12.6 (2026-08)
|
|
256
|
-
- **Checkpoint v2 — full-file-copy snapshots** — snapshots now store complete copies of changed files (tracked + untracked) instead of a git diff patch: rollback works even after commits happened post-snapshot. New `versions` checkpoint action lists a file's historical copies
|
|
257
|
-
|
|
283
|
+
- **Checkpoint v2 — full-file-copy snapshots** — snapshots now store complete copies of changed files (tracked + untracked) instead of a git diff patch: rollback works even after commits happened post-snapshot. New `versions` checkpoint action lists a file's historical copies
|
|
284
|
+
across snapshots (time / size / content hash) and restores a specific version. **Full rollback is disabled** (as dangerous as a working-tree reset — silently discards post-snapshot work); oversized files (>5MB) are skipped with an explicit notice; files created after a snapshot
|
|
285
|
+
are never deleted by a restore.
|
|
286
|
+
- **Git destructive-command protection** — `checkout --` / `restore` / `reset --hard` / `clean -f` (including bypass variants like `checkout HEAD -- .`) auto-snapshot every uncommitted file **before** running, then execute without blocking — a model rollback can no longer destroy
|
|
287
|
+
uncommitted work. Snapshot triggers slimmed to: destructive-git guard, pre-restore, manual.
|
|
258
288
|
- **Fix: bash no longer hangs on background processes** — `start /b`, `&`, `nohup` children that hold the output pipe no longer stall the tool until timeout (resolves after a short grace with a notice).
|
|
259
|
-
- **Mouse support** (SGR-protocol terminals) — click a picker option to select it, click a folded-block hint to expand it, click a message line for an action menu (copy to clipboard / load into the input box). **Long messages (>12 wrapped lines) auto-fold** to first/hint/last
|
|
289
|
+
- **Mouse support** (SGR-protocol terminals) — click a picker option to select it, click a folded-block hint to expand it, click a message line for an action menu (copy to clipboard / load into the input box). **Long messages (>12 wrapped lines) auto-fold** to first/hint/last
|
|
290
|
+
with click-to-expand — folding now has real objects in everyday sessions.
|
|
260
291
|
- **Fix: legacy session hash migration** — the 12→40 char hash migration now tries every historical algorithm (CLI 12-char, VS Code 16-char, both drive-letter cases): Windows sessions from older versions are found and migrated on next startup instead of being stranded.
|
|
261
292
|
|
|
262
293
|
### 0.12.5 (2026-08)
|
|
263
294
|
- **Fix: inline code styling** — markdown code spans now render with underline instead of reverse video (less harsh on the eyes)
|
|
264
295
|
|
|
265
296
|
### 0.12.4 (2026-08)
|
|
266
|
-
- **Context compaction unified spec** — CLI/VS Code now share one compaction semantics (`docs/design/CONTEXT-COMPACTION.md`): window-adaptive tail size (`max(10, ctx/100K×30)`, ≤40% of history), measured prompt-token baseline preferred, pure-estimation path includes system+tools
|
|
267
|
-
-
|
|
297
|
+
- **Context compaction unified spec** — CLI/VS Code now share one compaction semantics (`docs/design/CONTEXT-COMPACTION.md`): window-adaptive tail size (`max(10, ctx/100K×30)`, ≤40% of history), measured prompt-token baseline preferred, pure-estimation path includes system+tools
|
|
298
|
+
overhead, head/tail tool-call pairing protection on both sides, 3-tier fallback (LLM summary → deterministic truncation after 3 failures → per-message shrink), compaction summaries are silent to the frontend (no streaming into the conversation), task re-injection deduplicated.
|
|
299
|
+
Unknown model names now warn once instead of silently degrading to the 128K default
|
|
300
|
+
- **Kimi For Coding support** — new `kimi-code` preset (`api.kimi.com/coding/v1`, model `k3`, platform.kimi.com, `sk-kimi-` keys — NOT interchangeable with Moonshot); `MODEL_SPECS` gains the `k3` alias (1M context / multimodal / partialMode / reasoningEcho); 401 errors hint at
|
|
301
|
+
the two-platform key mismatch; README documents the split
|
|
268
302
|
- **Ctrl+C double-confirm** — idle-state first Ctrl+C only warns (3s window), second press exits; picker-cancel and in-flight abort semantics unchanged
|
|
269
303
|
- **Empty-response auto-retry** — a transient empty LLM response (reasoning exhausted / truncated output) injects a retry reminder instead of aborting the whole turn; after 2 consecutive empties the original error surfaces (with the `/think` lowering hint)
|
|
270
|
-
- **Lightweight inline markdown display** — model replies render `**bold**`, `` `code` `` (reverse video), `~~strike~~`, and `# headings` (marker-stripped + bold) via ANSI instead of showing literal markers; code spans are not re-interpreted; streaming-safe on unclosed markers;
|
|
304
|
+
- **Lightweight inline markdown display** — model replies render `**bold**`, `` `code` `` (reverse video), `~~strike~~`, and `# headings` (marker-stripped + bold) via ANSI instead of showing literal markers; code spans are not re-interpreted; streaming-safe on unclosed markers;
|
|
305
|
+
copied text comes out clean
|
|
271
306
|
|
|
272
307
|
### 0.12.3 (2026-08)
|
|
273
308
|
- **Fix: user-level skills loading** — skills in `~/.thincoder/skills/` are now properly discovered and loaded alongside project-level skills. Project-level skills with the same name take priority. Both `skill list` and `skill load` support both directories.
|
|
274
309
|
|
|
275
310
|
### 0.12.2 (2026-08)
|
|
276
|
-
- **Session isolation for multiple processes** — each process gets a unique session ID (`pid-timestamp-random`), manifest tracks slot ownership via `slotSessions` mapping. Concurrent sessions in the same directory automatically get separate slots. Dead process slots are
|
|
311
|
+
- **Session isolation for multiple processes** — each process gets a unique session ID (`pid-timestamp-random`), manifest tracks slot ownership via `slotSessions` mapping. Concurrent sessions in the same directory automatically get separate slots. Dead process slots are
|
|
312
|
+
intelligently reclaimed via `isProcessAlive()` check
|
|
277
313
|
- **Two-level model picker** — `/model` now shows providers first, then models for selected provider. Reduces visual clutter when many providers are configured. Direct switching still works: `/model qwen:qwen-max`
|
|
278
314
|
- **Picker improvements** — auto-scroll keeps selected item visible, "type to filter" hint shown, search/filter support added
|
|
279
315
|
- **Shift+Enter multiline input** — TUI now supports Shift+Enter for multiline input (regular Enter still submits)
|
|
@@ -286,7 +322,8 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
286
322
|
- **Fix: `/exit` screen artifacts** — `/exit` now uses synchronous `process.exit(0)` instead of the deferred cleanup callback, preventing the post-handler `render()` from redrawing the TUI over the cleaned terminal. Ctrl+C and `/exit` now produce identical clean exits.
|
|
287
323
|
|
|
288
324
|
### 0.12.0 (2026-07)
|
|
289
|
-
- **Interactive slash command UX** — `/advisor`, `/think`, `/config`, `/mcp` now use persistent menu loops with live state feedback. Toggle, change settings, and see results without re-entering the command. Cursor position is remembered across menu cycles. `/plan` and `/auto` now
|
|
325
|
+
- **Interactive slash command UX** — `/advisor`, `/think`, `/config`, `/mcp` now use persistent menu loops with live state feedback. Toggle, change settings, and see results without re-entering the command. Cursor position is remembered across menu cycles. `/plan` and `/auto` now
|
|
326
|
+
show immediate local feedback (`❯ Plan: ON/OFF`).
|
|
290
327
|
- **User-level AGENTS.md** — `~/.thincoder/AGENTS.md` is now loaded alongside the project-level `AGENTS.md`. User-level preferences (language, style, format) apply across all projects; project-level rules take priority.
|
|
291
328
|
- **Skill subdirectory format** — `.thincoder/skills/` now supports the standard `skill-name/SKILL.md` subdirectory convention (Claude Code / Cursor compatible). Flat `.md` files remain fully backward-compatible. Subdirectories take priority when both formats exist with the same name.
|
|
292
329
|
- **MCP stdio `env` field** — `env` key in MCP stdio server config is now merged into the child process environment. Enables MCP servers requiring custom environment variables (e.g. `deveco-mcp`).
|
|
@@ -294,9 +331,12 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
294
331
|
- **Cleaner conversations** — Removed redundant `[System reminder: ...]` injections from `/advisor`, `/plan`, `/auto`, and `/think` toggles. All feedback is now local TUI output, not conversation noise.
|
|
295
332
|
|
|
296
333
|
### 0.10.0 (2026-07)
|
|
297
|
-
- **LSP tool** — `lsp` tool provides code intelligence via Language Server Protocol: go-to-definition, find-references, hover info, document symbols, diagnostics. Zero-dependency JSON-RPC 2.0 over stdio client. Lazy-starts language servers on first call. Configurable via
|
|
298
|
-
|
|
299
|
-
- **
|
|
334
|
+
- **LSP tool** — `lsp` tool provides code intelligence via Language Server Protocol: go-to-definition, find-references, hover info, document symbols, diagnostics. Zero-dependency JSON-RPC 2.0 over stdio client. Lazy-starts language servers on first call. Configurable via
|
|
335
|
+
`lsp.servers` in config.json (defaults: `typescript-language-server` for JS/TS, `pyright-langserver` for Python).
|
|
336
|
+
- **Smart context: compaction checkpoint** — `compressIfNeeded` now auto-creates a git checkpoint before compaction. A checkpoint reference is injected after compaction so the model can reconstruct context from git diff + recent messages + task progress. Prevents information loss
|
|
337
|
+
during long sessions.
|
|
338
|
+
- **CodeMode: sandboxed JS execution** — `execute` tool backed by `vm.Script.runInNewContext`. Compose multiple file operations (read/write/glob/grep/log) into a single script, reducing API round-trips and keeping intermediate results out of context. Sandbox strips all Node APIs,
|
|
339
|
+
limits output to 50KB, enforces 30s timeout, and blocks private IPs in fetch. Script size capped at 50KB.
|
|
300
340
|
|
|
301
341
|
### 0.9.0 (2026-07)
|
|
302
342
|
- **Checkpoint v2** — snapshot-before-destructive with full workspace copies, per-file restore (`cat` preview), auto-recover on failed apply, and escape-hatch hints when git checks fail
|
|
@@ -310,7 +350,8 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
310
350
|
- **Roadmap**: LSP tool, intelligent context management (checkpoint-based reconstruction), and CodeMode sandboxed JS are planned for 0.10.0.
|
|
311
351
|
|
|
312
352
|
### 0.8.13 (2026-07)
|
|
313
|
-
- **TUI: incremental rendering** — panel-level cache (`panelCache`) with sync-update bracketing (`DECSET 2026`). Only redraws changed panels, eliminating flicker. `saveCursor`/`restoreCursor` for efficient cursor positioning. Panel order reorganized:
|
|
353
|
+
- **TUI: incremental rendering** — panel-level cache (`panelCache`) with sync-update bracketing (`DECSET 2026`). Only redraws changed panels, eliminating flicker. `saveCursor`/`restoreCursor` for efficient cursor positioning. Panel order reorganized:
|
|
354
|
+
`header → conversation → subagent → output → todo → picker → permission → queue → input → status`.
|
|
314
355
|
- **Ctrl+I inject resume** — Ctrl+I (or Tab during processing) now properly interrupts, injects the message, and *resumes* the agent loop. Controller is recreated after abort. Added active signal check in SSE read loop for faster abort on Windows.
|
|
315
356
|
- **Processing hints** — Input box shows "Ctrl+U clear" hint during processing. Tab during processing treated as Ctrl+I. Slash commands re-render the frame.
|
|
316
357
|
- **Compression visibility** — `compressIfNeeded` now forwards `onToken`/`onReasoning` callbacks, making compression activity visible in the TUI.
|
|
@@ -326,7 +367,8 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
326
367
|
- **ClearScreen on exit** — terminal restored with `clearScreen` ANSI on TUI cleanup.
|
|
327
368
|
|
|
328
369
|
### 0.8.12 (2026-07)
|
|
329
|
-
- **Indexing: git-repo-only** — `codeSync` and `docSync` now only index inside git worktrees (via `git ls-files`), respecting `.gitignore`. Non-git directories get empty indexes. Prevents 2.9GB memory.db from accidentally indexing entire user profiles (AppData, browser
|
|
370
|
+
- **Indexing: git-repo-only** — `codeSync` and `docSync` now only index inside git worktrees (via `git ls-files`), respecting `.gitignore`. Non-git directories get empty indexes. Prevents 2.9GB memory.db from accidentally indexing entire user profiles (AppData, browser
|
|
371
|
+
extensions, Office add-ins, Program Files)
|
|
330
372
|
- **Indexing: file-size caps** — code files >1MB and doc files >512KB are skipped during bulk indexing (minified bundles, test fixtures, generated code)
|
|
331
373
|
- **Compaction: earlier trigger** — `COMPACT_RATIO` lowered from 0.8 to 0.6 (with 40K floor), so injected context (directory tree, git context, outline, memory/doc search results) doesn't starve the model for headroom before compaction fires
|
|
332
374
|
- **Bugfix: event-loop blocking** — `buildOutline`/`buildSummary` in `repomap.mjs` now awaited (was sync calling async), `setup.mjs` outline injection fixed, `codeSync` walk uses `readFile` instead of `readFileSync`
|
|
@@ -338,11 +380,14 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
338
380
|
- **Feat**: `checklist` tool — persistent project task tracking in `.thincoder/checklist.md`. Add/mark/list items, auto-archive done items to `checklist-done.md`. Injected at session start (pending + in_progress only)
|
|
339
381
|
- **Feat**: updated prompts — four-step workflow (requirements→design→development→testing), three-step debugging strategy (logs→docs→binary search), working checklist discipline
|
|
340
382
|
- **Feat**: methodology docs — `docs/design/METHODOLOGY.md` rebuilt, `PHILOSOPHY.md` expanded with worldview #6 (official docs over guessing)
|
|
341
|
-
- **Bugfix**: vision guard — `read_image` now refuses non-vision models before reading the file, the agent loop injects a system reminder instead of image parts for text-only models, and `stripImagesForTextModel` sanitizes image parts at send time (history untouched, restored
|
|
383
|
+
- **Bugfix**: vision guard — `read_image` now refuses non-vision models before reading the file, the agent loop injects a system reminder instead of image parts for text-only models, and `stripImagesForTextModel` sanitizes image parts at send time (history untouched, restored
|
|
384
|
+
when switching back to a vision model). Previously a single image in history made text-only APIs (e.g. DeepSeek) reject EVERY subsequent request with 400, bricking the conversation
|
|
342
385
|
- **Improvement**: silent `catch {}` blocks now log to stderr (checkpoint file copies, MCP notify/close, session incremental save, clipboard paste, provider picker, team-memory rebase abort, tool dispatch) — failures are visible for debugging instead of disappearing
|
|
343
386
|
|
|
344
387
|
### 0.8.10 (2026-07)
|
|
345
|
-
- **Bugfix**: pasted text now lands in the active TUI text target — the API key prompt when adding a provider via `/model` (and any free-text `askQuestion`) now accepts paste correctly. Previously, bracketed-paste injection in the terminal was always written to the main input
|
|
388
|
+
- **Bugfix**: pasted text now lands in the active TUI text target — the API key prompt when adding a provider via `/model` (and any free-text `askQuestion`) now accepts paste correctly. Previously, bracketed-paste injection in the terminal was always written to the main input
|
|
389
|
+
box, so pasting into a question prompt appeared as "nothing happened" and orphaned the text into the input box after the question closed. Both bracketed-paste (Windows Terminal / most modern terminals) and Ctrl+V-as-key-event (legacy conhost) now route through a single
|
|
390
|
+
`insertPastedText` helper that targets the question answer, options-list (ignored), or main input box as appropriate
|
|
346
391
|
|
|
347
392
|
### 0.8.9 (2026-07)
|
|
348
393
|
- **Bugfix**: `wizardProviderItems` was defined inside `createWizard()` but not included in the return statement, causing key-handler to crash with `TypeError` during provider selection on first launch (/ new config)
|
|
@@ -359,16 +404,20 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
359
404
|
- **Code review fixes**: output friendliness, readability, English-only strings, TUI polish
|
|
360
405
|
|
|
361
406
|
### 0.8.0 (2026-07)
|
|
362
|
-
- **TUI rendering overhaul**: layout engine (`layout.mjs`) — panels are positioned declaratively by priority instead of hand-pinned arithmetic; `renderFrame` is now a pure function (no state mutation); cursor position derived from layout coordinates. Status bar slash-command
|
|
363
|
-
|
|
407
|
+
- **TUI rendering overhaul**: layout engine (`layout.mjs`) — panels are positioned declaratively by priority instead of hand-pinned arithmetic; `renderFrame` is now a pure function (no state mutation); cursor position derived from layout coordinates. Status bar slash-command
|
|
408
|
+
hints moved from if-else chain to lookup table. Three Chinese UI strings fixed to English
|
|
409
|
+
- **Subagent panel redesigned**: per-instance tracking (`role#id/` prefix) — parallel subagents of the same role no longer overwrite each other. Shows current tool name + args, or streaming text last line (what it's writing right now), instead of truncated 200-char token
|
|
410
|
+
fragments. `onToolCall` relayed from subagent to parent TUI. Only the earliest running subagent is marked done on completion (not all)
|
|
364
411
|
- **Tool file split**: `system.mjs` (337 lines) split into `bash.mjs` / `glob.mjs` / `grep.mjs` / `ls.mjs`; `repomap.mjs` (306 lines) split into `repomap.mjs` (public API) + `repomap-parse.mjs` (dependency graph parsing)
|
|
365
412
|
- **Export position normalization**: 8 files rearranged — exports at top, implementation helpers below, for top-down readability
|
|
366
|
-
- **Provider management UX**: Add Provider excludes already-added presets from the list; Esc in sub-pickers (Add/Remove/Key) returns to model picker instead of exiting; config operations no longer leave traces in the conversation flow (picker refresh is the feedback); `❯ You:`
|
|
413
|
+
- **Provider management UX**: Add Provider excludes already-added presets from the list; Esc in sub-pickers (Add/Remove/Key) returns to model picker instead of exiting; config operations no longer leave traces in the conversation flow (picker refresh is the feedback); `❯ You:`
|
|
414
|
+
label restored for user messages
|
|
367
415
|
- **distill-cmd import fix**: resolved export name mismatch that crashed TUI startup
|
|
368
416
|
|
|
369
417
|
### 0.7.8 (2026-07)
|
|
370
418
|
- **Provider config flow streamlined**: adding a provider now immediately prompts for API key (no more "go back to /provider → Set Key"). Switching to a keyless provider via `/model` also prompts for key inline. Empty input gives clear "skipped" feedback
|
|
371
|
-
- **bash tool: file writing forbidden**: models must use write/edit/insert_after/apply_patch instead of `echo`/`sed`/`printf > file`. Fixes GBK encoding corruption on Chinese Windows (cmd.exe writes redirected files in ANSI code page, not UTF-8). `PYTHONIOENCODING=utf-8` set for
|
|
419
|
+
- **bash tool: file writing forbidden**: models must use write/edit/insert_after/apply_patch instead of `echo`/`sed`/`printf > file`. Fixes GBK encoding corruption on Chinese Windows (cmd.exe writes redirected files in ANSI code page, not UTF-8). `PYTHONIOENCODING=utf-8` set for
|
|
420
|
+
Python subprocesses on Windows
|
|
372
421
|
|
|
373
422
|
### 0.7.7 (2026-07)
|
|
374
423
|
- **Code review fixes (4 critical bugs)**:
|
|
@@ -376,7 +425,8 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
376
425
|
- `gitSync` skipped deleted files → stale chunks remained in index forever; `--diff-filter` now includes `D`, and `ENOENT` is distinguished from other errors (failed files don't advance the anchor)
|
|
377
426
|
- Completion guard was a one-shot latch → after firing once, further mutations could finish unverified; now re-armed with a pushback counter (max 2 pushes, 3rd passes through)
|
|
378
427
|
- Verify-failure exhaustion returned raw model text without honesty framing → now injects a system reminder forcing the model to state what's still failing, what was tried, and that the work is unfinished
|
|
379
|
-
- **Input queue during processing**: messages typed while the agent is processing are queued and auto-executed when processing ends. Queue preview shown as a single line above the input box (no collision with subagent panel). `Ctrl+D` deletes the last queued item. `/cancel` and
|
|
428
|
+
- **Input queue during processing**: messages typed while the agent is processing are queued and auto-executed when processing ends. Queue preview shown as a single line above the input box (no collision with subagent panel). `Ctrl+D` deletes the last queued item. `/cancel` and
|
|
429
|
+
`/exit` bypass the queue
|
|
380
430
|
|
|
381
431
|
### 0.7.6 (2026-07)
|
|
382
432
|
- **SYSTEM_PROMPT split into core + discipline**: core rules (shared by all agents) separated from coding/testing/debugging discipline (main agent + coder), so explore/plan subagents no longer burn attention on irrelevant coding clauses — single source of truth, one rule changed in one file
|
|
@@ -389,13 +439,16 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
389
439
|
- **Testing discipline refined**: full-test trigger changed from "touched core infrastructure files" to "changed core infrastructure behavior" — adding a helper to memory.mjs no longer triggers the full suite
|
|
390
440
|
|
|
391
441
|
### 0.7.5 (2026-07)
|
|
392
|
-
- **Compound prompt instructions split**: 8 compound sentences across SYSTEM_PROMPT / main-overlay / coder-overlay split into independent bullets (one attention node per instruction), improving instruction-following on DeepSeek/GLM/Qwen — fallback clauses like "add tests after
|
|
442
|
+
- **Compound prompt instructions split**: 8 compound sentences across SYSTEM_PROMPT / main-overlay / coder-overlay split into independent bullets (one attention node per instruction), improving instruction-following on DeepSeek/GLM/Qwen — fallback clauses like "add tests after
|
|
443
|
+
changing code" no longer get skipped
|
|
393
444
|
- **Testing discipline strengthened**: SYSTEM_PROMPT Testing discipline gained an independent hard rule (changing behavior/adding code requires tests); main-overlay self-review checklist gained "do existing tests cover the change"; coder-overlay final checklist gained a test item
|
|
394
445
|
- **Plan mode workflow**: main-overlay's plan mode instruction split from one compound sentence into a 3-step numbered flow
|
|
395
446
|
|
|
396
447
|
### 0.7.4 (2026-07)
|
|
397
|
-
- **verify tiered self-check**: default quick mode (syntax-check changed files + git diff + self-review checklist, milliseconds); `full=true` also runs the full npm test suite — no more waiting ten-plus seconds per line changed; quick satisfies the completion guard, use full when
|
|
398
|
-
|
|
448
|
+
- **verify tiered self-check**: default quick mode (syntax-check changed files + git diff + self-review checklist, milliseconds); `full=true` also runs the full npm test suite — no more waiting ten-plus seconds per line changed; quick satisfies the completion guard, use full when
|
|
449
|
+
wrapping up or touching core infrastructure
|
|
450
|
+
- **Prompt discipline strengthened**: SYSTEM_PROMPT gained Testing discipline (when to run which tier) and Debugging strategy (diagnose before treating, one change at a time); coder/plan/main overlays gained self-review checklists (simplest solution, match project patterns, don't
|
|
451
|
+
touch unrelated files)
|
|
399
452
|
- **Fix**: quick mode marked verification passed even when syntax checks failed, gutting the completion guard
|
|
400
453
|
|
|
401
454
|
### 0.7.3 (2026-07)
|
|
@@ -403,18 +456,22 @@ Code conventions: pure `.mjs`, no semicolons, no third-party npm dependencies al
|
|
|
403
456
|
- **TUI paste hint**: with a multimodal model, the input box corner shows the OS-appropriate paste shortcut; hidden for text-only models
|
|
404
457
|
|
|
405
458
|
### 0.7.2 (2026-07)
|
|
406
|
-
- **TPM/RPM proactive rate gate**: with `tpm`/`rpm` budgets configured on a provider, requests are booked against a local sliding window (60s, input+output) before sending — over budget means sleeping until the window frees up instead of gambling on 429s; covers the main loop /
|
|
459
|
+
- **TPM/RPM proactive rate gate**: with `tpm`/`rpm` budgets configured on a provider, requests are booked against a local sliding window (60s, input+output) before sending — over budget means sleeping until the window frees up instead of gambling on 429s; covers the main loop /
|
|
460
|
+
compaction summaries / subagents / truncation resume. Status bar shows `TPM throttle wait ~Ns`; the gate is off for unconfigured providers
|
|
407
461
|
- **429-specific backoff**: respects the `Retry-After` header, otherwise backs off 15s/30s/60s (60s window — sub-second backoff is pointless); quota/balance errors (`exceeded_current_quota_error`) are distinguished from rate limits and no longer retried uselessly
|
|
408
462
|
- **Dependency injection as compact summary**: `buildSummary` (directory-level dependencies + hub files + entry points, naturally ~1-2k chars) replaces the full-outline injection; detailed import/export available on demand via `repo_outline`
|
|
409
463
|
- **TUI menus**: `/model` `/config` `/provider` `/think` `/mcp` `/goal` `/session` `/restore` unified into picker menus
|
|
410
464
|
- **Session robustness**: corrupted files or disk errors during archive/switch no longer crash — silently abandoned
|
|
411
465
|
|
|
412
466
|
### 0.7.1 (2026-07)
|
|
413
|
-
- **Context explosion fix (urgent)**: the startup dependency-outline injection is no longer unbounded — a multi-repo parent directory (thousands of indexed files) produced a 1.4M-char ≈ 350K-token outline, re-injected every turn, blowing up context within a few turns and tripping
|
|
414
|
-
|
|
467
|
+
- **Context explosion fix (urgent)**: the startup dependency-outline injection is no longer unbounded — a multi-repo parent directory (thousands of indexed files) produced a 1.4M-char ≈ 350K-token outline, re-injected every turn, blowing up context within a few turns and tripping
|
|
468
|
+
TPM limits. Now truncated to 6000 chars (with a pointer to `repo_outline` for focused queries) and injected only once per session
|
|
469
|
+
- **Compaction escape hatch**: when history was too short (≤13 messages) to slice a middle section, compaction never happened — one giant message (huge paste/oversized injection) could deadlock. Now a deterministic slimming path: oversized user/tool bodies are truncated to stubs,
|
|
470
|
+
reasoning_content and tool_calls pairing untouched
|
|
415
471
|
- **docSync ReferenceError fix**: undeclared `failed`/`errors` made every doc index sync throw (two tests red)
|
|
416
472
|
- **apply_patch tool**: unified-diff multi-file atomic patching (any failed hunk → nothing written), permission preview shows the diff directly
|
|
417
|
-
- **checkpoint tool**: `list`/`create`/`rewind` snapshot abilities exposed to the model (previously only wired to TUI auto-snapshots + /rewind, so the model couldn't save itself); the bash destructive-git guard upgraded to per-segment detection (chained forms like
|
|
473
|
+
- **checkpoint tool**: `list`/`create`/`rewind` snapshot abilities exposed to the model (previously only wired to TUI auto-snapshots + /rewind, so the model couldn't save itself); the bash destructive-git guard upgraded to per-segment detection (chained forms like
|
|
474
|
+
`&&`/`;`/`|`/command substitution no longer slip through)
|
|
418
475
|
- **bash process-tree kill**: timeout/interrupt kills the whole tree (POSIX process groups / Windows taskkill /T) — no orphaned grandchildren
|
|
419
476
|
- **Subagent display contract**: only content/thinking tokens relay to the TUI scrolling area; internal tool calls no longer flood the screen
|
|
420
477
|
- **Path safety**: `resolveInCwd` prevents symlink escapes (realpath double-check); edit rejects empty old_string; single-file incremental indexing skips hidden directories and node_modules
|
package/bin/thincoder.mjs
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* thincoder upgrade Update to the latest version from npm
|
|
9
9
|
* thincoder completion <sh> Shell completion: bash / zsh / fish
|
|
10
10
|
* thincoder session gc Session dir GC: --dry-run report / --confirm delete cold projects (SESSION.md §6.12)
|
|
11
|
+
* thincoder session index Derived session index: --status report / --rebuild (SESSION.md §6.19)
|
|
11
12
|
* thincoder acp Agent Client Protocol server (stdio, for Zed/JetBrains/Paseo)
|
|
12
13
|
* thincoder -v Print version
|
|
13
14
|
* thincoder --help Print help
|
|
@@ -118,6 +119,9 @@ Usage:
|
|
|
118
119
|
thincoder session gc --dry-run | --confirm <hash|--all>
|
|
119
120
|
Session dir GC: report/recycle cold & stale project data into a 7-day recycle bin
|
|
120
121
|
(cold = manifest idle >90d; stale = no live owner + unreachable/empty cwd + 7-day window)
|
|
122
|
+
thincoder session index [--status | --rebuild]
|
|
123
|
+
Derived session index (disposable, rebuilt on demand): --status reports sessions /
|
|
124
|
+
messages / tool calls + coverage + size; --rebuild reindexes every session file
|
|
121
125
|
thincoder upgrade Update to the latest version from npm
|
|
122
126
|
thincoder completion <sh> Generate shell completion script (bash / zsh / fish)
|
|
123
127
|
thincoder -v, --version Print version
|
|
@@ -146,6 +150,13 @@ if (command === undefined || command === "tui" || command === "chat" || command
|
|
|
146
150
|
const startupCfg = loadConfig()
|
|
147
151
|
scheduleTraceCleanup({ dir: tracesRoot(), retentionHours: startupCfg.traces?.retentionHours ?? 24 })
|
|
148
152
|
} catch { /* 配置缺失/损坏 → 跳过清理(零风险) */ }
|
|
153
|
+
// SESSION.md §6.19 D-SE45 触发点②(2026-09-22 会话索引批):派生索引启动窗外延迟拍
|
|
154
|
+
// (核侧 `scheduleSessionIndexPass`——3s 起 / 单趟 ≤2s 且 ≤40 会话 / 每进程一次;与轨迹清理
|
|
155
|
+
// 同址簇、同纪律:失败静默、不 unref)。索引 = 派生品(零权威)——主存零险。
|
|
156
|
+
try {
|
|
157
|
+
const { scheduleSessionIndexPass } = await import("@thincoder/core/session-index-pass.mjs")
|
|
158
|
+
scheduleSessionIndexPass()
|
|
159
|
+
} catch { /* 拍挂点失败静默——不阻断启动 */ }
|
|
149
160
|
}
|
|
150
161
|
|
|
151
162
|
switch (command) {
|
|
@@ -423,6 +434,13 @@ switch (command) {
|
|
|
423
434
|
case "session": {
|
|
424
435
|
// SESSION.md §6.12 / §6.17:会话目录 GC 显式面(冷 cwd 90 天面 + 三合取存量组全量面)——
|
|
425
436
|
// 双端同面(2026-09-21 端差注销:VS Code 端命令 `thincoder.sessionGc` 走同一核数据面)。
|
|
437
|
+
// SESSION.md §6.19 D-SE46(2026-09-22 会话索引批):`session index` = 派生索引库显式面
|
|
438
|
+
// (--status 读数 / --rebuild 全量重扫)——同一 `session` 分发族(壳侧分发,实现在核)。
|
|
439
|
+
if (args[0] === "index") {
|
|
440
|
+
const { runSessionIndex } = await import("@thincoder/core/session-index-cmd.mjs")
|
|
441
|
+
process.exitCode = await runSessionIndex(args)
|
|
442
|
+
break
|
|
443
|
+
}
|
|
426
444
|
const { runSessionGc } = await import("@thincoder/core/session-gc.mjs")
|
|
427
445
|
process.exitCode = await runSessionGc(args)
|
|
428
446
|
break
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thincoder",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.65",
|
|
4
4
|
"description": "Thin coding agent - zero third-party dependencies, no build step, Node.js native. Sharp code, zero bloat.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">=24"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@thincoder/core": "^0.9.
|
|
23
|
+
"@thincoder/core": "^0.9.3"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"bin/",
|
|
@@ -8,9 +8,15 @@
|
|
|
8
8
|
* 受门 handler 首行求值,真 ⇒ 放行、假 ⇒ `-32000`。客户端可以不调 `authenticate`
|
|
9
9
|
* (契约逐字「**May** return an `auth_required` error … **if** the agent requires
|
|
10
10
|
* authentication」)。
|
|
11
|
+
*
|
|
12
|
+
* #168①(2026-09-22 · SESSION.md §6.15 / §6.16):`session/close` 入释放面——关闭会话 ⇒
|
|
13
|
+
* 释放该会话认领(保留集 = 本进程其余在存会话的活绑定槽,同 cwd;落盘判据三条沿用)。
|
|
11
14
|
*/
|
|
12
15
|
import { resolve } from "node:path"
|
|
13
|
-
import { normalizeCwd, bindRecordStore, newSession, slotPath } from "@thincoder/core/session.mjs"
|
|
16
|
+
import { loadManifest, normalizeCwd, bindRecordStore, newSession, saveManifest, slotPath } from "@thincoder/core/session.mjs"
|
|
17
|
+
// 认领释放谓词单源(SESSION.md §6.2 / §6.16——与 VSC 端壳 `releaseClaimsAll` 同源档;
|
|
18
|
+
// core `session.mjs` 未 re-export 该名——直引 manifest 档,先例 = `thincoder-vscode/src/extension/session-io.mjs`)。
|
|
19
|
+
import { staleClaims } from "@thincoder/core/session-slots-manifest.mjs"
|
|
14
20
|
import { PLAN_ENGINEERING_REFUSED } from "@thincoder/core/agent-tools/plan.mjs"
|
|
15
21
|
import { ACP_ERRORS } from "./transport.mjs"
|
|
16
22
|
|
|
@@ -107,6 +113,22 @@ export function createSessionHandlers(ctx) {
|
|
|
107
113
|
return { session: s }
|
|
108
114
|
}
|
|
109
115
|
|
|
116
|
+
/** #168①(SESSION.md §6.15 / §6.16——2026-09-22 定裁 · 台账 #168①):`session/close` ⇒
|
|
117
|
+
* 释放被关闭会话的槽认领。公式代入:释放 A ⟺ `slotSessions[A]` 为本进程 ∧ `A ∉ 保留集`;
|
|
118
|
+
* **保留集 = 本进程其余在存会话的活绑定槽**(同 cwd——ACP 单 cwd 模型)。取值点(实施轮定位报告):
|
|
119
|
+
* 会话记录容器 = `ctx.sessions`(`Map<id, session>`——`thincoder-cli/src/acp.mjs:98` 单容器);
|
|
120
|
+
* 槽值 = `session.agent._slot`(认领写入同源 = `handlers-slots.mjs:96-100` / `:151-155` /
|
|
121
|
+
* `handlers-session.mjs` 的 newSession 认领点)。落盘判据三条由核 `saveManifest` `opts.release`
|
|
122
|
+
* 自动继承(fresh 同次快照 / 值条件删除 / 内存认领表移除)——**零新增写盘路径**;本进程无残留认领
|
|
123
|
+
* ⇒ 零写早退(判据单源 `staleClaims`——同核 `releaseClaimsAll` 早退形)。 */
|
|
124
|
+
const releaseClosedSessionSlot = () => {
|
|
125
|
+
const cwd = getCwd()
|
|
126
|
+
const m = loadManifest(cwd)
|
|
127
|
+
const keep = [...sessions.values()].map((s) => s.agent?._slot).filter((slot) => slot != null)
|
|
128
|
+
if (staleClaims(m, keep).length === 0) return
|
|
129
|
+
saveManifest(cwd, m, null, { release: keep })
|
|
130
|
+
}
|
|
131
|
+
|
|
110
132
|
return {
|
|
111
133
|
"session/new": async (params) => {
|
|
112
134
|
const gate = requireConfigured()
|
|
@@ -199,7 +221,9 @@ export function createSessionHandlers(ctx) {
|
|
|
199
221
|
// Abort any in-flight turn first — the client is gone, the agent must
|
|
200
222
|
// stop consuming LLM tokens and emitting notifications.
|
|
201
223
|
found.session.cancel()
|
|
224
|
+
// 先出容器再释放(保留集 = 其余在存会话——被关闭者不留在保留集内)。
|
|
202
225
|
sessions.delete(String(params.sessionId))
|
|
226
|
+
releaseClosedSessionSlot() // #168①:释放该会话认领(保留集 = 同 cwd 其余在存会话槽)
|
|
203
227
|
log(`session ${params.sessionId} closed by client`)
|
|
204
228
|
}
|
|
205
229
|
return {}
|
|
@@ -29,7 +29,7 @@ export function createSlotsHandlers(ctx) {
|
|
|
29
29
|
|
|
30
30
|
/** #41 装载后一行重估(F3 准翻列 / F4):`applySession` 已按槽订正 config ⇒ 工程模式会话
|
|
31
31
|
* 就地判据(单源)+ 附着——缺档格 `writer:'main'` 建档;非工程模式零动作(零 manifest I/O)。
|
|
32
|
-
* 判据不通过 ⇒
|
|
32
|
+
* 判据不通过 ⇒ 保持不附着(装载已发生——本行是「装载后订正」位;启动侧恒不拒,拒面 = 「翻转可否进」)+ 留痕。 */
|
|
33
33
|
const reattach = (ag) => {
|
|
34
34
|
if (ag?.config?.agent?.engineering !== true) return
|
|
35
35
|
const r = resolveEngineeringManifest(getCwd(), { writer: "main" })
|
package/src/tui/agent-turn.mjs
CHANGED
|
@@ -21,6 +21,7 @@ import { buildToolCallbacks, sweepToolBlocks } from "./tool-events.mjs"
|
|
|
21
21
|
import { freezeAllSubTasks } from "./subagent-blocks.mjs" // freezeReclaimDigestedBlocks 随 §17 段迁 suspension-drive.mjs
|
|
22
22
|
import { ensureSessionTitle } from "@thincoder/core/generate-title.mjs"
|
|
23
23
|
import { logEvent, errText } from "@thincoder/core/log.mjs"
|
|
24
|
+
import { t } from "@thincoder/core/i18n.mjs"
|
|
24
25
|
import { suspensionSession, poolLive } from "./suspension-drive.mjs"
|
|
25
26
|
|
|
26
27
|
/** Exit-flush bound for the async end-of-run distillation (SEND-STALL-DISTILL §2.5):
|
|
@@ -191,11 +192,11 @@ async function runAgentTurnInner(ctx, text, opts) {
|
|
|
191
192
|
// §2 统一规则自动 resume(无人值守授权);手动档静默拒绝(部分消化留在
|
|
192
193
|
// 历史,会话回挂起——结果不丢,只是不再烧轮次)。
|
|
193
194
|
if (agent.autoApprove) {
|
|
194
|
-
pushLine("
|
|
195
|
+
pushLine(t("digest.capAuto"), C.dim)
|
|
195
196
|
state.controller = makeController()
|
|
196
197
|
continue
|
|
197
198
|
}
|
|
198
|
-
pushLine(
|
|
199
|
+
pushLine(t("digest.capStop", { turns: error.turn }), C.warn)
|
|
199
200
|
if (opts?._logOutcome) opts._logOutcome.result = "stopped"
|
|
200
201
|
break
|
|
201
202
|
}
|
|
@@ -339,6 +340,8 @@ async function runAgentTurnInner(ctx, text, opts) {
|
|
|
339
340
|
// 承诺)——逐条直发;斜杠命令直接执行(保序);回合后的续发由递归层同循环续取。
|
|
340
341
|
while (state.queue.length > 0 && !state.processing) {
|
|
341
342
|
const head = state.queue.shift()
|
|
343
|
+
// F16(TUI.md §7.5):消费回执——queued dim 行(消费事实的可见锚;对位 [continuing…])
|
|
344
|
+
pushLine("[sending queued message]", C.tool)
|
|
342
345
|
// 残项斜杠命令直接执行——保序、绝不合并
|
|
343
346
|
if (head.text.startsWith("/")) {
|
|
344
347
|
await handleSlash(head.text)
|
package/src/tui/cmd-advisor.mjs
CHANGED
|
@@ -27,7 +27,7 @@ export async function handleAdvisorCommand(ctx) {
|
|
|
27
27
|
// Other advisor keys (model/thinking/effort/timeout) stay config-scoped — persist() only.
|
|
28
28
|
const persistGuard = async () => {
|
|
29
29
|
try {
|
|
30
|
-
const p = slotPath(agent.cwd, activeSlot(agent.cwd))
|
|
30
|
+
const p = slotPath(agent.cwd, agent._slot ?? activeSlot(agent.cwd))
|
|
31
31
|
const data = JSON.parse(readFileSync(p, "utf8"))
|
|
32
32
|
if (data && typeof data === "object" && Array.isArray(data.history)) {
|
|
33
33
|
data.advisor = { ...(typeof data.advisor === "object" && data.advisor !== null ? data.advisor : {}), guard: cfg.guard === true }
|
package/src/tui/cmd-eng.mjs
CHANGED
|
@@ -91,7 +91,8 @@ export async function handleEngCommand(ctx) {
|
|
|
91
91
|
* 把 plan-active 推回 UI(半状态复活面;验收判据 = 「内存 + 槽位」双清零)。OFF 方向零改。
|
|
92
92
|
*/
|
|
93
93
|
async function persistEngineering(agent) {
|
|
94
|
-
|
|
94
|
+
// #167:绑定优先(先例 = cmd-session.mjs)——粘性槽优先于 activeSlot(后者有认领副作用)。
|
|
95
|
+
const slot = agent._slot ?? activeSlot(agent.cwd)
|
|
95
96
|
try {
|
|
96
97
|
const p = slotPath(agent.cwd, slot)
|
|
97
98
|
const data = JSON.parse(readFileSync(p, "utf8"))
|
package/src/tui/cmd-mcp-form.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { C } from "./ansi.mjs"
|
|
2
|
+
// #58(hygiene-sweep 批):headers/env 现值脱敏判据 = 核 settings 同源单点(不再各自为政)。
|
|
3
|
+
import { isSensitiveKey } from "@thincoder/core/agent-tools/settings.mjs"
|
|
2
4
|
|
|
3
5
|
/** MCP.md §5 v2(D-1):edit/add 统一字段 picker 表单机制。
|
|
4
6
|
* fieldPicker 循环:picker 列字段行(label + 当前值打码)+ `✓ Save & test` 末行;
|
|
@@ -111,15 +113,19 @@ function formEntries(entry, transport, mode) {
|
|
|
111
113
|
]
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
/**
|
|
116
|
+
/** #58(hygiene-sweep 批):headers/env 现值列示——敏感键名(谓词 = 核 settings 同源
|
|
117
|
+
* `isSensitiveKey`)的值位一律 `••••`(人读面不再明文);非敏感键名保可读(`k=v`)。 */
|
|
118
|
+
function currentPairs(v) {
|
|
119
|
+
const pairs = Object.entries(v ?? {}).map(([k, val]) => (isSensitiveKey(k) ? `${k}=••••` : `${k}=${val}`))
|
|
120
|
+
return pairs.length ? pairs.join(", ") : "none"
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** 字段输入提示 `(current: …)`——token 打码(maskToken)、headers/env 列键值对(敏感值位遮)、
|
|
115
124
|
* args 空格串接;空值 → "none"。 */
|
|
116
125
|
function currentText(entry, field) {
|
|
117
126
|
const v = entry[field]
|
|
118
127
|
if (field === "token") return v ? maskToken(v) : "none"
|
|
119
|
-
if (field === "headers" || field === "env")
|
|
120
|
-
const pairs = Object.entries(v ?? {}).map(([k, val]) => `${k}=${val}`)
|
|
121
|
-
return pairs.length ? pairs.join(", ") : "none"
|
|
122
|
-
}
|
|
128
|
+
if (field === "headers" || field === "env") return currentPairs(v)
|
|
123
129
|
if (field === "args") return (v ?? []).length ? v.join(" ") : "none"
|
|
124
130
|
return String(v ?? "") || "none"
|
|
125
131
|
}
|