thatgfsj-code 3.0.3 → 3.0.6
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/README.md +64 -21
- package/dist/app/index.d.ts +93 -22
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +232 -40
- package/dist/app/index.js.map +1 -1
- package/dist/cache/smartModel.d.ts +29 -22
- package/dist/cache/smartModel.d.ts.map +1 -1
- package/dist/cache/smartModel.js +33 -40
- package/dist/cache/smartModel.js.map +1 -1
- package/dist/cmd/index.d.ts +12 -20
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +192 -146
- package/dist/cmd/index.js.map +1 -1
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +9 -6
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.d.ts +5 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/llm/anthropic.d.ts +1 -1
- package/dist/llm/anthropic.d.ts.map +1 -1
- package/dist/llm/anthropic.js +116 -84
- package/dist/llm/anthropic.js.map +1 -1
- package/dist/llm/gemini.d.ts +27 -3
- package/dist/llm/gemini.d.ts.map +1 -1
- package/dist/llm/gemini.js +196 -73
- package/dist/llm/gemini.js.map +1 -1
- package/dist/llm/index.d.ts +20 -1
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +71 -10
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/openai.d.ts +5 -1
- package/dist/llm/openai.d.ts.map +1 -1
- package/dist/llm/openai.js +96 -56
- package/dist/llm/openai.js.map +1 -1
- package/dist/mcp/client.d.ts +84 -34
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +291 -126
- package/dist/mcp/client.js.map +1 -1
- package/dist/session/compactor.d.ts +27 -7
- package/dist/session/compactor.d.ts.map +1 -1
- package/dist/session/compactor.js +78 -23
- package/dist/session/compactor.js.map +1 -1
- package/dist/session/index.d.ts +96 -33
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/index.js +278 -60
- package/dist/session/index.js.map +1 -1
- package/dist/tools/file.d.ts +10 -2
- package/dist/tools/file.d.ts.map +1 -1
- package/dist/tools/file.js +54 -5
- package/dist/tools/file.js.map +1 -1
- package/dist/tools/git.d.ts +16 -2
- package/dist/tools/git.d.ts.map +1 -1
- package/dist/tools/git.js +61 -18
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/nwt.d.ts.map +1 -1
- package/dist/tools/nwt.js +8 -1
- package/dist/tools/nwt.js.map +1 -1
- package/dist/tools/search.d.ts +8 -1
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +105 -34
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/shell.d.ts +0 -4
- package/dist/tools/shell.d.ts.map +1 -1
- package/dist/tools/shell.js +11 -26
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/types.d.ts +7 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/tui/app.d.ts.map +1 -1
- package/dist/tui/app.js +90 -18
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components/ChatMessage.d.ts.map +1 -1
- package/dist/tui/components/ChatMessage.js +9 -2
- package/dist/tui/components/ChatMessage.js.map +1 -1
- package/dist/tui/components/ConfirmPrompt.d.ts +21 -0
- package/dist/tui/components/ConfirmPrompt.d.ts.map +1 -0
- package/dist/tui/components/ConfirmPrompt.js +45 -0
- package/dist/tui/components/ConfirmPrompt.js.map +1 -0
- package/dist/tui/components/Header.d.ts +10 -5
- package/dist/tui/components/Header.d.ts.map +1 -1
- package/dist/tui/components/Header.js +13 -5
- package/dist/tui/components/Header.js.map +1 -1
- package/dist/tui/components/InitWizard.d.ts.map +1 -1
- package/dist/tui/components/InitWizard.js +8 -13
- package/dist/tui/components/InitWizard.js.map +1 -1
- package/dist/tui/components/StatusBar.d.ts +7 -0
- package/dist/tui/components/StatusBar.d.ts.map +1 -1
- package/dist/tui/components/StatusBar.js +8 -3
- package/dist/tui/components/StatusBar.js.map +1 -1
- package/dist/tui/components/Thinking.d.ts +5 -0
- package/dist/tui/components/Thinking.d.ts.map +1 -1
- package/dist/tui/components/Thinking.js +24 -2
- package/dist/tui/components/Thinking.js.map +1 -1
- package/dist/tui/components/ToolCall.d.ts +6 -1
- package/dist/tui/components/ToolCall.d.ts.map +1 -1
- package/dist/tui/components/ToolCall.js +50 -22
- package/dist/tui/components/ToolCall.js.map +1 -1
- package/dist/tui/components/UserInput.d.ts +5 -0
- package/dist/tui/components/UserInput.d.ts.map +1 -1
- package/dist/tui/components/UserInput.js +9 -13
- package/dist/tui/components/UserInput.js.map +1 -1
- package/dist/tui/hooks/useChat.d.ts +1 -0
- package/dist/tui/hooks/useChat.d.ts.map +1 -1
- package/dist/tui/hooks/useChat.js +36 -16
- package/dist/tui/hooks/useChat.js.map +1 -1
- package/dist/tui/hooks/useCommands.d.ts +7 -1
- package/dist/tui/hooks/useCommands.d.ts.map +1 -1
- package/dist/tui/hooks/useCommands.js +83 -49
- package/dist/tui/hooks/useCommands.js.map +1 -1
- package/dist/tui/theme.d.ts +34 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +34 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/tui/welcome.d.ts.map +1 -1
- package/dist/tui/welcome.js +9 -7
- package/dist/tui/welcome.js.map +1 -1
- package/dist/types.d.ts +16 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/diff.d.ts +5 -0
- package/dist/utils/diff.d.ts.map +1 -1
- package/dist/utils/diff.js +15 -0
- package/dist/utils/diff.js.map +1 -1
- package/dist/version.d.ts +12 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +29 -0
- package/dist/version.js.map +1 -0
- package/package.json +19 -7
- package/CHANGELOG.md +0 -192
- package/DEVELOPMENT.md +0 -286
- package/ROADMAP.md +0 -91
- package/docs/API_KEY_GUIDE.md +0 -236
- package/docs/FAQ.md +0 -182
- package/install.bat +0 -63
- package/install.ps1 +0 -238
- package/install.sh +0 -113
- package/src/app/index.ts +0 -197
- package/src/cache/fingerprint.ts +0 -101
- package/src/cache/index.ts +0 -21
- package/src/cache/smartModel.ts +0 -145
- package/src/cache/stats.ts +0 -199
- package/src/cache/volatile.ts +0 -47
- package/src/cmd/index.tsx +0 -288
- package/src/config/index.ts +0 -158
- package/src/config/providers.ts +0 -234
- package/src/config/types.ts +0 -71
- package/src/hooks/index.ts +0 -111
- package/src/llm/anthropic.ts +0 -413
- package/src/llm/gemini.ts +0 -169
- package/src/llm/index.ts +0 -302
- package/src/llm/openai.ts +0 -243
- package/src/llm/provider.ts +0 -71
- package/src/mcp/client.ts +0 -330
- package/src/prompts/index.ts +0 -260
- package/src/session/compactor.ts +0 -103
- package/src/session/index.ts +0 -181
- package/src/session/message.ts +0 -42
- package/src/skills/brainstorming.ts +0 -43
- package/src/skills/code-review.ts +0 -45
- package/src/skills/executing-plans.ts +0 -27
- package/src/skills/frontend-design.ts +0 -35
- package/src/skills/git-workflow.ts +0 -36
- package/src/skills/improve-architecture.ts +0 -38
- package/src/skills/index.ts +0 -136
- package/src/skills/neuroweave.ts +0 -47
- package/src/skills/playwright.ts +0 -72
- package/src/skills/prototype.ts +0 -30
- package/src/skills/subagent.ts +0 -28
- package/src/skills/supabase.ts +0 -44
- package/src/skills/systematic-debugging.ts +0 -44
- package/src/skills/tdd.ts +0 -39
- package/src/skills/triage.ts +0 -35
- package/src/skills/verification.ts +0 -31
- package/src/skills/writing-plans.ts +0 -42
- package/src/tools/file.ts +0 -143
- package/src/tools/git.ts +0 -132
- package/src/tools/index.ts +0 -111
- package/src/tools/nwt.ts +0 -598
- package/src/tools/search.ts +0 -263
- package/src/tools/shell.ts +0 -136
- package/src/tools/types.ts +0 -122
- package/src/tui/app.tsx +0 -159
- package/src/tui/components/ChatList.tsx +0 -41
- package/src/tui/components/ChatMessage.tsx +0 -54
- package/src/tui/components/Header.tsx +0 -66
- package/src/tui/components/InitWizard.tsx +0 -251
- package/src/tui/components/Markdown.tsx +0 -35
- package/src/tui/components/ModelSelector.tsx +0 -107
- package/src/tui/components/StatusBar.tsx +0 -30
- package/src/tui/components/Thinking.tsx +0 -17
- package/src/tui/components/ToolCall.tsx +0 -102
- package/src/tui/components/UserInput.tsx +0 -151
- package/src/tui/hooks/useChat.ts +0 -287
- package/src/tui/hooks/useCommands.ts +0 -273
- package/src/tui/index.ts +0 -6
- package/src/tui/welcome.ts +0 -177
- package/src/types.ts +0 -104
- package/src/utils/diff.ts +0 -71
- package/src/utils/project.ts +0 -99
- package/src/utils/stableStringify.ts +0 -47
- package/src/utils/thinking.ts +0 -119
- package/tests/cache/fingerprint.test.ts +0 -75
- package/tests/cache/providerCatalog.test.ts +0 -31
- package/tests/cache/smartModel.test.ts +0 -112
- package/tests/cache/stableStringify.test.ts +0 -43
- package/tests/cache/stats.test.ts +0 -146
- package/tests/cache/volatile.test.ts +0 -75
- package/tests/smoke-pollution.mjs +0 -78
- package/tests/smoke-thinking.mjs +0 -110
- package/tests/smoke-tool-stream.mjs +0 -69
- package/tests/smoke-tool.mjs +0 -117
- package/tsconfig.json +0 -21
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thatgfsj-code",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.6",
|
|
4
4
|
"description": "Thatgfsj Code - AI Coding Assistant with Reasonix-style prompt caching",
|
|
5
5
|
"main": "dist/cmd/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -8,13 +8,29 @@
|
|
|
8
8
|
"thatgfsj": "./dist/cmd/index.js",
|
|
9
9
|
"gfcode": "./dist/cmd/index.js"
|
|
10
10
|
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20.19"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/Thatgfsj/thatgfsj-code.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/Thatgfsj/thatgfsj-code/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/Thatgfsj/thatgfsj-code#readme",
|
|
11
25
|
"scripts": {
|
|
12
26
|
"build": "tsc",
|
|
13
27
|
"start": "node dist/cmd/index.js",
|
|
14
28
|
"dev": "tsc && node dist/cmd/index.js",
|
|
15
29
|
"link": "npm link",
|
|
16
30
|
"test": "vitest run",
|
|
17
|
-
"test:watch": "vitest"
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"smoke": "npm run build && node tests/smoke-tool.mjs && node tests/smoke-tool-stream.mjs && node tests/smoke-pollution.mjs && node tests/smoke-thinking.mjs",
|
|
33
|
+
"prepublishOnly": "npm run build && npm test"
|
|
18
34
|
},
|
|
19
35
|
"keywords": [
|
|
20
36
|
"ai",
|
|
@@ -30,13 +46,9 @@
|
|
|
30
46
|
"ink": "^7.1.0",
|
|
31
47
|
"ink-select-input": "^6.2.0",
|
|
32
48
|
"ink-text-input": "^6.0.0",
|
|
33
|
-
"inquirer": "^13.3.2",
|
|
34
49
|
"marked": "^15.0.12",
|
|
35
50
|
"marked-terminal": "^7.3.0",
|
|
36
|
-
"
|
|
37
|
-
"playwright": "^1.61.1",
|
|
38
|
-
"react": "^19.2.7",
|
|
39
|
-
"readline": "^1.3.0"
|
|
51
|
+
"react": "^19.2.7"
|
|
40
52
|
},
|
|
41
53
|
"devDependencies": {
|
|
42
54
|
"@types/marked-terminal": "^6.1.1",
|
package/CHANGELOG.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to **Thatgfsj Code** are documented here. The format follows
|
|
4
|
-
[Keep a Changelog](https://keepachangelog.com/) and the project adheres to
|
|
5
|
-
[Semantic Versioning](https://semver.org/).
|
|
6
|
-
|
|
7
|
-
## [3.0.0 / 产品 0.5.0] - 2026-08-08 - Reasonix 风格 Prompt Caching 架构
|
|
8
|
-
|
|
9
|
-
> **重大版本变更**:流式协议 `AsyncGenerator<string>` → `AsyncGenerator<StreamChunk>`。
|
|
10
|
-
> 自定义依赖 `LLMService.chatStream` / `App.streamResponse` 的下游代码需要适配。
|
|
11
|
-
>
|
|
12
|
-
> 参考:DeepSeek-Reasonix (esengine/DeepSeek-Reasonix) 的"不可变前缀 + 追加日志 + 易变草稿"三支柱。
|
|
13
|
-
|
|
14
|
-
### Added
|
|
15
|
-
- **M1 — 流式协议重构**:干掉 `@@TOOL@@` 哨兵字符串;`StreamChunk` 升级为结构化 union(text / tool_calls / thinking / usage)。
|
|
16
|
-
- **M2 — Anthropic prompt cache**:`system` 改为 block 数组,最后一块挂 `cache_control: { type: 'ephemeral' }`;工具列表最后一个也挂 marker;新增 `anthropic-beta: prompt-caching-2024-07-31` header;修「第二条 system 消息被丢弃」bug。
|
|
17
|
-
- **M3 — 缓存统计与 UI**:`CacheStatsStore` 持久化到 `~/.thatgfsj/cache-stats.json`;TUI Header 显示 `⚡ 命中率 87%`;新增 `/cache` 命令显示 24h 命中率曲线。
|
|
18
|
-
- **M4 — 高级特性**:`VolatileScratch` 隔离 thinking;Tool-call Repair(append `[TOOL_REPAIR]` 而非修改既有消息);`smartModel.shouldDowngrade` 智能路由;`Config.cache` 字段 + InitWizard 两步缓存配置。
|
|
19
|
-
- **OpenAI provider 缓存友好**:`stableStringify` 保证 JSON 字节级稳定;流末尾 yield `{ type: 'usage' }` chunk。
|
|
20
|
-
- **28 个 vitest 单元测试**(`tests/cache/`)。
|
|
21
|
-
|
|
22
|
-
### Changed
|
|
23
|
-
- `SessionManager.autoCompact` 不再 mutate messages,改为通过 `onSuggestNewSession` 回调通知用户调 `/new`。Reasonix 原则:超长开新会话,保护上游缓存前缀。
|
|
24
|
-
- `system prompt` 片段顺序调整:NWT history 和 Date 移到末尾(易变区),前 6 段是 Immutable Prefix。
|
|
25
|
-
- `LLMService.fromConfig` 接收 `Config.cache` 透传给 provider。
|
|
26
|
-
|
|
27
|
-
## [2.2.7 / 产品 0.4.4] - 2026-07-06 - 烟囱测试驱动的 anti-pollution 过滤收紧
|
|
28
|
-
|
|
29
|
-
> 双版本号方案:
|
|
30
|
-
>
|
|
31
|
-
> | 位置 | 版本 | 含义 |
|
|
32
|
-
> |---|---|---|
|
|
33
|
-
> | `package.json` `"version"` | `2.2.7` | npm 包版本,正常递增 (+0.0.1) |
|
|
34
|
-
> | `src/cmd/index.tsx` `.version(...)` | `0.4.4` | **产品版本** (`gfcode --version` 看到的) |
|
|
35
|
-
|
|
36
|
-
### Fixed
|
|
37
|
-
|
|
38
|
-
**Pollution 过滤误杀正常对话** — v2.2.4 引入的 anti-pollution 过滤
|
|
39
|
-
(`SessionManager.looksPolluted`) 有两条过宽的模式:
|
|
40
|
-
|
|
41
|
-
- `/\u5df2\u4e2d\u65ad[^\n]{0,40}/` — 把所有包含"已中断"字样的中文
|
|
42
|
-
都当污染,包括 `我看到这个进程已中断了` 这种合法对话
|
|
43
|
-
- `/response (was )?truncated/i` — 把所有提到"response truncated"的句子
|
|
44
|
-
都当污染,包括用户问 `Why was the response truncated last time?`
|
|
45
|
-
|
|
46
|
-
烟囱测试 `tests/smoke-pollution.mjs` 直接捕获了这两个误杀。
|
|
47
|
-
|
|
48
|
-
### 修复策略 — 两层模式分级
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
STRONG (always drop):
|
|
52
|
-
[已中断] 必有方括号,模型原样输出
|
|
53
|
-
[interrupted] English 等价
|
|
54
|
-
|
|
55
|
-
WEAK (drop only when ALL gates pass):
|
|
56
|
-
^...\[已中断\] 行首标记 (带可选 markdown 装饰)
|
|
57
|
-
^...\[interrupted\] 行首标记
|
|
58
|
-
\bresponse (was )?(truncated|cut off|interrupted)\b
|
|
59
|
-
\boutput (was )?(truncated|cut off|interrupted)\b
|
|
60
|
-
|
|
61
|
-
+ 消息长度 < 200 字符 (截断的响应通常较短)
|
|
62
|
-
+ 不以 ? 结尾 (疑问句是用户讨论过往行为)
|
|
63
|
-
+ 不包含 "last time" / "earlier" / "before" / "previously" / "yesterday"
|
|
64
|
-
(时间副词表明用户在回顾过去,不是污染)
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Smoke 测试新增
|
|
68
|
-
|
|
69
|
-
- `tests/smoke-thinking.mjs` — 28 个用例覆盖 `splitThinking` / `compressThinking`
|
|
70
|
-
所有边缘情况 (空输入、多 delimiter、Chinese/English 混合、tag 跨行)
|
|
71
|
-
- `tests/smoke-tool.mjs` — 18 个用例覆盖 ToolCall 渲染路径 (空结果、
|
|
72
|
-
pending、截断计数、错误、超长单行)
|
|
73
|
-
- `tests/smoke-pollution.mjs` — 17 个用例覆盖 anti-pollution 过滤的
|
|
74
|
-
drop / keep 双向场景
|
|
75
|
-
|
|
76
|
-
### Test summary (本 patch 后)
|
|
77
|
-
```
|
|
78
|
-
thinking: 28 / 28 pass
|
|
79
|
-
tool: 18 / 18 pass
|
|
80
|
-
pollution: 17 / 17 pass
|
|
81
|
-
total: 63 / 63 pass
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## [2.2.6 / 产品 0.4.3] - 2026-07-06 - 修复工具结果不显示
|
|
87
|
-
|
|
88
|
-
> 双版本号方案:
|
|
89
|
-
>
|
|
90
|
-
> | 位置 | 版本 | 含义 |
|
|
91
|
-
> |---|---|---|
|
|
92
|
-
> | `package.json` `"version"` | `2.2.6` | npm 包版本,正常递增 (+0.0.1) |
|
|
93
|
-
> | `src/cmd/index.tsx` `.version(...)` | `0.4.3` | **产品版本** (`gfcode --version` 看到的) |
|
|
94
|
-
|
|
95
|
-
### Fixed
|
|
96
|
-
|
|
97
|
-
**Bug: 工具调用结果不显示** — 在 1.0.4 源码栈下用户报告"⚙ shell date" 这条
|
|
98
|
-
命令发起后,**结果完全看不到**,只看到 AI 后续的文字回复 ("好嘞,那我给你
|
|
99
|
-
演示一组工具——并行调用"). 模型明明看到了工具结果 (因为它的后续回复引用了
|
|
100
|
-
结果),但 UI 上不显示结果文本。
|
|
101
|
-
|
|
102
|
-
通过代码 review + 单测复现,定位到三个潜在原因,全部修复:
|
|
103
|
-
|
|
104
|
-
1. **`src/tui/components/ToolCall.tsx`** — `tool.result ? ... : null` 用 truthy
|
|
105
|
-
判断,**空字符串结果被当 falsy 跳过渲染**。改成 `tool.result !== undefined ? ... : null`。
|
|
106
|
-
同样修复: `wrap="truncate"` 在 Ink 里会把超长行**静默切掉不显示**,
|
|
107
|
-
改成 `wrap="wrap"` 让长行自动换行。还把 `result.truncated` 的指示从
|
|
108
|
-
模糊的 `"..."` 改成 `(+N more lines)` 显示实际被截掉的行数。
|
|
109
|
-
2. **加 ⏳ pending 指示器** — 工具调用发起到结果返回之间的中间状态,
|
|
110
|
-
之前没有视觉反馈,看起来像是"卡住了"。现在显示 `⏳ running...`
|
|
111
|
-
3. **`src/tui/hooks/useChat.ts`** — 流结束 push 到 messages 时,assemble
|
|
112
|
-
一个 `[tool: name → result]` 摘要附加到 assistant 的 content 里。
|
|
113
|
-
这是 belt-and-suspenders 兜底: 即使 Ink 的 `<ToolCall/>` 渲染路径
|
|
114
|
-
因为任何边缘 case 失败 (例如太长的输出 wrap 问题),用户依然能在
|
|
115
|
-
AI 的文字回复里看到工具结果。
|
|
116
|
-
|
|
117
|
-
### 仍然不修的 (但要意识到)
|
|
118
|
-
- 用户的 paste 里还有另一条命令 `echo "=== 当前时间 ===" && date && echo
|
|
119
|
-
"=== 系统信息 ===" && system` — 这里 `system` 不是合法命令,
|
|
120
|
-
会返回错误。这不是代码 bug,是用户/模型自己写的命令有问题。本次 patch
|
|
121
|
-
不修改这个。
|
|
122
|
-
|
|
123
|
-
### 不在本次范围
|
|
124
|
-
- Anthropic / Gemini provider 的 `delta.tool_calls` 流式解析 (仍是 TODO)
|
|
125
|
-
- 工具输入参数命名前缀 (`command` vs `cmd` 不一致) — 下次 patch
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## [2.2.5 / 产品 0.4.2] - 2026-07-06 - 压缩 <think> 思考块 (类似 opencode)
|
|
130
|
-
|
|
131
|
-
> 双版本号方案:
|
|
132
|
-
>
|
|
133
|
-
> | 位置 | 版本 | 含义 |
|
|
134
|
-
> |---|---|---|
|
|
135
|
-
> | `package.json` `"version"` | `2.2.5` | npm 包版本,正常递增 (+0.0.1) |
|
|
136
|
-
> | `src/cmd/index.tsx` `.version(...)` | `0.4.2` | **产品版本** (`gfcode --version` 看到的) |
|
|
137
|
-
|
|
138
|
-
### Fixed
|
|
139
|
-
|
|
140
|
-
**Bug: 思考过程太长,刷屏** — 在 1.0.4 源码栈下,即使是"非推理"模型
|
|
141
|
-
(Qwen / DeepSeek-V3 chat / Kimi 等) 也会在回复里发整段 `<think>...</think>`
|
|
142
|
-
块,经常是几十行内部独白。这块内容对用户来说没有可读价值,只
|
|
143
|
-
是噪音 — 用户在 v2.2.4 的会话日志里能看到这问题特别严重。
|
|
144
|
-
|
|
145
|
-
参考 opencode 的做法 (`packages/opencode/src/session/prompt.ts:244`
|
|
146
|
-
里的 `<think>[\s\S]*?<\/think>` 正则),引入压缩模式:
|
|
147
|
-
|
|
148
|
-
- 新文件 `src/utils/thinking.ts`,导出三个 helper:
|
|
149
|
-
- `splitThinking(content)` — 把 `<think>...` / `<reasoning>...</reasoning>` /
|
|
150
|
-
`[THINK]...[/THINK]` 三种块格式剥离开,返回 `{thinking, conclusion,
|
|
151
|
-
thinkingLines, thinkingHint}`。
|
|
152
|
-
- `summarizeThinking(split)` — 输出 `💭 thought for N lines: <first hint>`
|
|
153
|
-
单行摘要。
|
|
154
|
-
- `compressThinking(content, showThinking)` — `showThinking=false` 时把
|
|
155
|
-
思考块压成一行 + 结论;`showThinking=true` 时原样返回。
|
|
156
|
-
- 三个调用点全部接入压缩:
|
|
157
|
-
- `src/cmd/index.tsx`: 流式阶段**不**实时打印 AI 文字 (避免半个 <think>
|
|
158
|
-
块被切到屏幕上),流结束后用 `splitThinking + summarizeThinking` 输出
|
|
159
|
-
一行摘要 + 结论。**持久化时只保存结论**,让 history 不被思考块撑大。
|
|
160
|
-
- `src/app/index.ts:runPrompt`: 持久化前 `compressThinking(fullResponse,
|
|
161
|
-
showThinking)`。
|
|
162
|
-
- `src/tui/hooks/useChat.ts`: 同上,持久化 + 显示内容都走压缩。
|
|
163
|
-
|
|
164
|
-
### Added
|
|
165
|
-
|
|
166
|
-
- **CLI flag `--show-thinking`**: 在命令行下开启完整思考块显示 (调试用)
|
|
167
|
-
- **`App.showThinking` 字段**: 默认 `false`,可通过 REPL 命令切换
|
|
168
|
-
- **REPL 命令 `/thinking on|off`** (中文别名 `/思考`): 在 Ink TUI 模式下
|
|
169
|
-
切换思考块显示
|
|
170
|
-
|
|
171
|
-
### 设计选择
|
|
172
|
-
|
|
173
|
-
为什么不沿用 opencode 的"协议级分离 reasoning"?
|
|
174
|
-
- opencode 把 reasoning 当成单独的 stream part 处理 (`MessageV2.ReasoningPart`),
|
|
175
|
-
那需要模型支持 reasoning API (Anthropic extended thinking / OpenAI o1-style)。
|
|
176
|
-
- 我们用的多数 provider (Qwen / DeepSeek / Kimi) 把 reasoning 直接当作
|
|
177
|
-
content 的一部分输出,所以必须在**显示层**做正则剥离。
|
|
178
|
-
|
|
179
|
-
为什么不实时 (mid-stream) 压缩?
|
|
180
|
-
- 流式 chunk 是任意切分的,`<think>` 标签可能跨 chunk。实时检测需要
|
|
181
|
-
state machine,延迟和边界处理都很脆弱。
|
|
182
|
-
- 流结束后压缩更可靠,而且不影响用户对结论的实时阅读(用户其实只在乎结论)。
|
|
183
|
-
|
|
184
|
-
### 不在本次范围
|
|
185
|
-
- `/thinking` 命令目前是全局开关,不支持 per-message 切换
|
|
186
|
-
- 没有提供"展开"按钮 — 用户要看完整内容只能 `--show-thinking` 跑一遍
|
|
187
|
-
- 持久化时去掉了 thinking 内容,这意味着**重放历史时也看不到完整思考**;
|
|
188
|
-
这是有意为之 (context window 优先),如需调试可以 `app.showThinking = true` 后
|
|
189
|
-
重新发起对话
|
|
190
|
-
- Anthropic / Gemini SSE tool_call 流式解析 仍是 TODO
|
|
191
|
-
|
|
192
|
-
---
|
package/DEVELOPMENT.md
DELETED
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
# Development Guide — Thatgfsj Code
|
|
2
|
-
|
|
3
|
-
This document is for contributors / maintainers. End users should read
|
|
4
|
-
[`README.md`](./README.md) instead.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 1. Overview
|
|
9
|
-
|
|
10
|
-
**Thatgfsj Code** is a Claude Code–style interactive AI coding assistant that
|
|
11
|
-
runs entirely in your terminal. It is written in TypeScript, published as an
|
|
12
|
-
ESM npm package, distributed under MIT, and targets **Node.js ≥ 18**.
|
|
13
|
-
|
|
14
|
-
The tool exposes:
|
|
15
|
-
|
|
16
|
-
- A non-interactive single-shot CLI (`gfcode "..."`).
|
|
17
|
-
- An interactive REPL (`gfcode` with no args).
|
|
18
|
-
- Subcommands: `init`, `explain`, `debug`, `chat`, `template`.
|
|
19
|
-
|
|
20
|
-
The release pipeline is: **bug fix → docs → smoke test → git commit + tag →
|
|
21
|
-
push → GitHub release → `npm publish`**. Everything in `src/` compiles to
|
|
22
|
-
`dist/` via `tsc`; the `package.json` `files` whitelist decides what ships
|
|
23
|
-
in the npm tarball.
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## 2. Architecture
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
┌──────────────────────────────────────────────────────────────┐
|
|
31
|
-
│ src/index.ts │
|
|
32
|
-
│ CLI entry · commander program · subcommand dispatch │
|
|
33
|
-
│ (init / explain / debug / chat / template / default REPL) │
|
|
34
|
-
└─────────────────────────┬────────────────────┬───────────────┘
|
|
35
|
-
│ │
|
|
36
|
-
┌───────────▼──────────┐ ┌───────▼─────────────┐
|
|
37
|
-
│ AI Engine + Tools │ │ REPL Loop │
|
|
38
|
-
│ src/core/ai-engine │ │ src/repl/{loop,...} │
|
|
39
|
-
│ src/tools/{file,…} │ │ @inquirer/input │
|
|
40
|
-
└───────────┬──────────┘ └───────┬─────────────┘
|
|
41
|
-
│ │
|
|
42
|
-
┌───────────▼────────────────────▼───────────────┐
|
|
43
|
-
│ Core / Utils / Agent / MCP │
|
|
44
|
-
│ src/core/{config,session,types,subagent,…} │
|
|
45
|
-
│ src/utils/{diff-preview,memory,project-…} │
|
|
46
|
-
│ src/agent/{core,intent,streaming} │
|
|
47
|
-
│ src/mcp/client.ts │
|
|
48
|
-
└────────────────────────────────────────────────┘
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
### Module responsibilities
|
|
52
|
-
|
|
53
|
-
| Layer | Files | Job |
|
|
54
|
-
|-----------|----------------------------------------------|--------------------------------------------------------------------|
|
|
55
|
-
| Entry | `src/index.ts` | commander program, subcommand handlers, REPL bootstrap |
|
|
56
|
-
| REPL | `src/repl/{input,output,loop,welcome}.ts` | interactive prompt, ANSI output, SIGINT, welcome/init wizard |
|
|
57
|
-
| Core | `src/core/{ai-engine,config,session,…}.ts` | AI provider abstraction, config loading, session state |
|
|
58
|
-
| Tools | `src/tools/{file,shell,git,search}.ts` | file I/O, shell exec, git ops, code search |
|
|
59
|
-
| Agent | `src/agent/{core,intent,streaming}.ts` | intent classification, agent loop, streamed terminal output |
|
|
60
|
-
| Utils | `src/utils/{diff-preview,memory,…}.ts` | side-effect-free helpers |
|
|
61
|
-
| MCP | `src/mcp/client.ts` | Model Context Protocol stdio client |
|
|
62
|
-
|
|
63
|
-
### Data flow on a single prompt
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
User ──▶ commander ──▶ executeTask(prompt)
|
|
67
|
-
│
|
|
68
|
-
├─▶ ConfigManager.load() (process.env + ~/.thatgfsj/config.json)
|
|
69
|
-
│
|
|
70
|
-
├─▶ AIEngine.chatStream(messages) ──▶ provider base URL /v1/chat/completions
|
|
71
|
-
│ or Anthropic /messages
|
|
72
|
-
│ or Gemini :generateContent
|
|
73
|
-
│
|
|
74
|
-
└─▶ process.stdout.write(chunks) ──▶ terminal (scrollable history)
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## 3. Build & install
|
|
80
|
-
|
|
81
|
-
### Prerequisites
|
|
82
|
-
|
|
83
|
-
- Node.js ≥ 18 (project uses native `fetch`, `AbortController`, top-level `await`,
|
|
84
|
-
`node --test`).
|
|
85
|
-
- npm ≥ 9 (so `npm publish` understands the `files` whitelist).
|
|
86
|
-
- Git (for the install scripts and during release).
|
|
87
|
-
|
|
88
|
-
### Local development
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
git clone https://github.com/Thatgfsj/thatgfsj-code.git
|
|
92
|
-
cd thatgfsj-code
|
|
93
|
-
npm install
|
|
94
|
-
npm run build # produces ./dist
|
|
95
|
-
npm test # node --test tests/
|
|
96
|
-
npm start # node dist/index.js (interactive REPL)
|
|
97
|
-
npm run dev # tsc && node dist/index.js
|
|
98
|
-
|
|
99
|
-
# Optional: link globally so `gfcode` is in your PATH
|
|
100
|
-
npm link
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
`npm install` after cloning will trigger `prepublishOnly` if you have it
|
|
104
|
-
configured (we do). Always run `npm run build` after editing source so the
|
|
105
|
-
`dist/` matches `src/`.
|
|
106
|
-
|
|
107
|
-
### Platform notes
|
|
108
|
-
|
|
109
|
-
- **Windows**: `src/index.ts` invokes `chcp 65001` synchronously before any
|
|
110
|
-
output to force UTF-8 in the legacy Windows console. Done via
|
|
111
|
-
`createRequire(import.meta.url)` so it works under `"type": "module"`.
|
|
112
|
-
- **Numeric keypad arrows**: the REPL uses `@inquirer/input` instead of Node's
|
|
113
|
-
built-in `readline.question()` because the latter doesn't reliably translate
|
|
114
|
-
numeric-keypad ANSI escape sequences on Windows terminals (Bug #1 history).
|
|
115
|
-
- **Streaming output**: `process.stdout.write` directly, never `rl.question`
|
|
116
|
-
inside the loop — the latter would reset the terminal and lose scrollback.
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## 4. Adding a provider
|
|
121
|
-
|
|
122
|
-
1. Add the env-var map to `src/core/config.ts` (`envKeys`).
|
|
123
|
-
2. Add a `*_MODELS` array to `src/repl/welcome.ts` and wire it through
|
|
124
|
-
`getModelsForProvider()` and `interactiveSetup()` (numbered choice).
|
|
125
|
-
3. Update `WelcomeScreen.hasApiKey()` in `src/repl/welcome.ts` to include the
|
|
126
|
-
new env-var name.
|
|
127
|
-
4. If the provider uses a non-OpenAI request format, extend the dispatcher
|
|
128
|
-
in `src/core/ai-engine.ts::streamRequest`.
|
|
129
|
-
5. Update `docs/API_KEY_GUIDE.md` and `README.md`'s provider list.
|
|
130
|
-
|
|
131
|
-
No other files should care about the specific provider.
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## 5. Adding a built-in CLI command
|
|
136
|
-
|
|
137
|
-
`src/index.ts` is the single `commander` program. Register a new command
|
|
138
|
-
**before** `program.parse(process.argv)`:
|
|
139
|
-
|
|
140
|
-
```ts
|
|
141
|
-
program
|
|
142
|
-
.command('foo')
|
|
143
|
-
.description('...')
|
|
144
|
-
.argument('<bar>', '...')
|
|
145
|
-
.action(async (bar) => { /* ... */ });
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
For REPL-internal slash-style commands (visible only inside the interactive
|
|
149
|
-
loop), add a new `case` to `src/repl/loop.ts::handleCommand`.
|
|
150
|
-
|
|
151
|
-
### Built-in REPL commands (current)
|
|
152
|
-
|
|
153
|
-
| Command | Behavior |
|
|
154
|
-
| ---------------- | -------------------------------------------------------------------------------- |
|
|
155
|
-
| `help` | Show built-in command list |
|
|
156
|
-
| `exit` / `quit` | Leave the REPL |
|
|
157
|
-
| `clear` | Clear the screen |
|
|
158
|
-
| `context` | Show the current project context |
|
|
159
|
-
| `history` | Show the command history for this session |
|
|
160
|
-
| `tools` | List registered tools |
|
|
161
|
-
| `models` | Read-only listing of the current provider's models |
|
|
162
|
-
| `providers` | Read-only listing of all providers |
|
|
163
|
-
| `/model` | **Interactive picker — actually switches the active model** for the current provider. Persists to `~/.thatgfsj/config.json` and calls `AIEngine.updateConfig()`. |
|
|
164
|
-
| `/provider` | **Interactive picker — switches provider + chains into `/model`** for the new one. Warns if the corresponding env-var / saved API key is missing. |
|
|
165
|
-
| `Ctrl+C` | Aborts the in-flight stream once, exits after two empty-prompt cancels. |
|
|
166
|
-
|
|
167
|
-
Both `/model` and `/provider` accept either a numeric index or the exact
|
|
168
|
-
provider/model id; pressing Enter with no input keeps the current value. After
|
|
169
|
-
a switch, `REPLLoop` injects a one-line `[system: ... switched to ...]`
|
|
170
|
-
message into the session so the LLM can see the change in the next turn.
|
|
171
|
-
|
|
172
|
-
---
|
|
173
|
-
|
|
174
|
-
## 6. Adding a tool
|
|
175
|
-
|
|
176
|
-
Tools implement the `Tool` interface declared in `src/core/types.ts`:
|
|
177
|
-
|
|
178
|
-
```ts
|
|
179
|
-
export interface Tool {
|
|
180
|
-
name: string;
|
|
181
|
-
description: string;
|
|
182
|
-
parameters: ToolParameter[];
|
|
183
|
-
execute(params: any, ctx: ToolContext): Promise<ToolResult>;
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Steps:
|
|
188
|
-
1. Create `src/tools/<name>.ts` exporting a class implementing `Tool`.
|
|
189
|
-
2. Register it in `src/tools/index.ts::getBuiltInTools()` so both the REPL
|
|
190
|
-
`REPLLoop.init` and `executeTask` pick it up automatically.
|
|
191
|
-
|
|
192
|
-
> **Known limitation (0.2.2):** `src/core/ai-engine.ts::extractToolCalls`
|
|
193
|
-
> currently returns `undefined`. Tools are registered but never actually
|
|
194
|
-
> invoked from a streamed response. Wiring this up requires parsing each
|
|
195
|
-
> provider's native `tool_calls` delta and is tracked under "Unreleased" in
|
|
196
|
-
> `CHANGELOG.md`. Until then, `ToolRegistry` is a forward-compatible seam.
|
|
197
|
-
|
|
198
|
-
---
|
|
199
|
-
|
|
200
|
-
## 7. MCP integration
|
|
201
|
-
|
|
202
|
-
`src/mcp/client.ts` defines a small stdio MCP client. It spawns a child
|
|
203
|
-
process and exchanges JSON-RPC via newline-delimited messages. The current
|
|
204
|
-
shape is intentionally minimal — see the file for the protocol mapping.
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## 8. Cross-platform & UX details
|
|
209
|
-
|
|
210
|
-
- **Encoding**: Windows-only `chcp 65001` in `src/index.ts:9-15`. Skipped
|
|
211
|
-
silently if it fails.
|
|
212
|
-
- **Color**: `chalk` v5 is ESM-only; the project is `"type": "module"` so
|
|
213
|
-
this is fine.
|
|
214
|
-
- **Spinner**: `ora` v7 with `dots` spinner; cyan.
|
|
215
|
-
- **History**: local to a single REPL session (not persisted across runs).
|
|
216
|
-
|
|
217
|
-
---
|
|
218
|
-
|
|
219
|
-
## 9. Tests
|
|
220
|
-
|
|
221
|
-
```bash
|
|
222
|
-
npm test # runs node --test tests/ (full TAP output)
|
|
223
|
-
npm run test:silent # dot reporter, for noisy CI logs
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
Tests live in `tests/` and use Node's built-in `node:test` runner — no
|
|
227
|
-
vitest / jest dev-dep. They cover:
|
|
228
|
-
|
|
229
|
-
- Smoke tests of the compiled `dist/index.js` binary (`--version`, `--help`,
|
|
230
|
-
subcommand empty-arg guards, `bash -n install.sh`).
|
|
231
|
-
- Boundary tests of pure modules (`SessionManager`, `DiffPreview`,
|
|
232
|
-
`REPLOutput`) — empty input, unicode, CRLF, very long input.
|
|
233
|
-
- No network. No mocked API keys. No shell-out side-effects other than the
|
|
234
|
-
install script's `bash -n` parse-check.
|
|
235
|
-
|
|
236
|
-
CI integration: if you set this up later, run `npm test && npm run build`
|
|
237
|
-
in the job; the `prepublishOnly` script already chains them.
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## 10. Release process
|
|
242
|
-
|
|
243
|
-
1. Edit `package.json` `version` (semver).
|
|
244
|
-
2. Add a new section at the top of `CHANGELOG.md`.
|
|
245
|
-
3. `npm test && npm run build` locally — make sure both are green.
|
|
246
|
-
4. `git add -A && git commit -m "release: vX.Y.Z"`
|
|
247
|
-
5. `git tag vX.Y.Z`
|
|
248
|
-
6. `git push origin main --follow-tags`
|
|
249
|
-
7. `gh release create vX.Y.Z --title "vX.Y.Z" --notes-file CHANGELOG.md`
|
|
250
|
-
(the section for the new version is the top entry; trim if needed).
|
|
251
|
-
8. `npm publish --access public` (a `prepublishOnly` step in `package.json`
|
|
252
|
-
re-runs tests + build, so you can't accidentally publish a stale build).
|
|
253
|
-
|
|
254
|
-
### Semver policy
|
|
255
|
-
|
|
256
|
-
- **patch** (`Z`): bug fixes, docs, refactors, no public API change.
|
|
257
|
-
- **minor** (`Y`): new public command, new provider, new tool.
|
|
258
|
-
- **major** (`X`): breaking change to the CLI surface or the JS API surface
|
|
259
|
-
(currently no JS API is stable).
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## 11. Troubleshooting
|
|
264
|
-
|
|
265
|
-
### `ReferenceError: require is not defined`
|
|
266
|
-
|
|
267
|
-
You're editing TypeScript and accidentally called `require(...)` outside of a
|
|
268
|
-
`createRequire(import.meta.url)` shim. The project is ESM. Use `import x from 'y'`
|
|
269
|
-
at the top of the file.
|
|
270
|
-
|
|
271
|
-
### `npm publish` ships no `dist/`
|
|
272
|
-
|
|
273
|
-
You forgot to run `npm run build` (or the `prepublishOnly` script was
|
|
274
|
-
removed). The `files` whitelist in `package.json` requires the `dist/`
|
|
275
|
-
directory to exist locally when publishing.
|
|
276
|
-
|
|
277
|
-
### `gfcode --version` shows the wrong number
|
|
278
|
-
|
|
279
|
-
Edit it in `package.json` only — `src/index.ts` and `src/repl/output.ts` both
|
|
280
|
-
read `VERSION` from `package.json` via `import pkg from '../package.json' …`.
|
|
281
|
-
|
|
282
|
-
### REPL keypresses / Ctrl+C misbehave on Windows
|
|
283
|
-
|
|
284
|
-
Make sure you're on Windows Terminal or any TTY that emits ANSI escape
|
|
285
|
-
sequences natively. The legacy `cmd.exe` console has incomplete ANSI
|
|
286
|
-
support — upgrade to Windows Terminal or use PowerShell.
|
package/ROADMAP.md
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Thatgfsj Code - Development Roadmap
|
|
2
|
-
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
## ✅ v0.9.0 - 稳定版 (当前版本)
|
|
6
|
-
|
|
7
|
-
### 核心架构
|
|
8
|
-
- [x] Ink (React) TUI 框架
|
|
9
|
-
- [x] LLM Provider 抽象层 (OpenAI/Anthropic/Gemini)
|
|
10
|
-
- [x] 15 个 Provider + 自定义中转站
|
|
11
|
-
- [x] 模块化目录结构 (cmd/app/config/llm/session/tools/tui/skills/hooks/prompts)
|
|
12
|
-
|
|
13
|
-
### 工具系统
|
|
14
|
-
- [x] file (读/写/列表/删除)
|
|
15
|
-
- [x] shell (执行命令)
|
|
16
|
-
- [x] git (操作)
|
|
17
|
-
- [x] search (搜索)
|
|
18
|
-
- [x] nwt (项目记忆,30天自动归档)
|
|
19
|
-
|
|
20
|
-
### Skills 系统
|
|
21
|
-
- [x] 16 个内置 Skills (规划/调试/TDD/架构/浏览器等)
|
|
22
|
-
- [x] /skills 命令管理
|
|
23
|
-
- [x] 自动激活
|
|
24
|
-
|
|
25
|
-
### UI/UX
|
|
26
|
-
- [x] Ink TUI 流式输出
|
|
27
|
-
- [x] Markdown 渲染 (marked-terminal)
|
|
28
|
-
- [x] 工具调用显示 (opencode 风格)
|
|
29
|
-
- [x] 状态栏
|
|
30
|
-
- [x] 命令系统 (/model, /new, /compact, /skills, /mcp, /help)
|
|
31
|
-
- [x] /model 交互式选择框
|
|
32
|
-
|
|
33
|
-
### 智能功能
|
|
34
|
-
- [x] 自动读取 CLAUDE.md/SKILLS.md (通用路径)
|
|
35
|
-
- [x] NWT 项目历史自动注入系统提示
|
|
36
|
-
- [x] 上下文自动压缩 (超限触发)
|
|
37
|
-
- [x] API 错误检测 (401/403/429)
|
|
38
|
-
- [x] 启动时检测 API Key
|
|
39
|
-
|
|
40
|
-
### 安装
|
|
41
|
-
- [x] npm install -g thatgfsj-code
|
|
42
|
-
- [x] Windows PowerShell 一键安装
|
|
43
|
-
- [x] Linux/macOS Bash 一键安装
|
|
44
|
-
- [x] 自动下载 Node.js (如果没有)
|
|
45
|
-
|
|
46
|
-
### 测试通过
|
|
47
|
-
- [x] 简单任务: 读文件 + 回答
|
|
48
|
-
- [x] 中等任务: 修改文件 + 验证
|
|
49
|
-
- [x] 困难任务: 多步骤 + NWT 记录
|
|
50
|
-
- [x] Git + Search + NWT 联合测试
|
|
51
|
-
- [x] 多文件创建和修改
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## 📋 未来计划
|
|
56
|
-
|
|
57
|
-
### v1.0.0
|
|
58
|
-
- [ ] SQLite 会话持久化
|
|
59
|
-
- [ ] Token 使用量显示
|
|
60
|
-
- [ ] 命令 Tab 补全
|
|
61
|
-
- [ ] 多会话管理
|
|
62
|
-
- [ ] LSP 集成
|
|
63
|
-
- [ ] 图片支持
|
|
64
|
-
|
|
65
|
-
---
|
|
66
|
-
|
|
67
|
-
## 历史版本
|
|
68
|
-
|
|
69
|
-
### ✅ v0.8.0 - 命令系统
|
|
70
|
-
- /model, /new, /compact, /skills, /mcp 命令
|
|
71
|
-
|
|
72
|
-
### ✅ v0.7.0 - Skills + NWT
|
|
73
|
-
- 16 个内置 Skills, NWT 项目记忆
|
|
74
|
-
|
|
75
|
-
### ✅ v0.6.0 - Ink TUI
|
|
76
|
-
- React 组件化 UI, Markdown 渲染
|
|
77
|
-
|
|
78
|
-
### ✅ v0.5.0 - Provider 重写
|
|
79
|
-
- 15 个 Provider, 自定义中转站
|
|
80
|
-
|
|
81
|
-
### ✅ v0.4.0 - UI 优化
|
|
82
|
-
- 流式输出, 工具调用显示
|
|
83
|
-
|
|
84
|
-
### ✅ v0.3.0 - 架构重构
|
|
85
|
-
- 模块化目录, Provider 抽象
|
|
86
|
-
|
|
87
|
-
### ✅ v0.2.0 - 工具 + LLM
|
|
88
|
-
- Git/搜索工具, 多 Provider
|
|
89
|
-
|
|
90
|
-
### ✅ v0.1.0 - REPL 基础
|
|
91
|
-
- 彩色 UI, 命令提示符
|