@antaif3ng/til-work 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +573 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +7 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/core/agent.d.ts +78 -0
  7. package/dist/core/agent.d.ts.map +1 -0
  8. package/dist/core/agent.js +372 -0
  9. package/dist/core/agent.js.map +1 -0
  10. package/dist/core/compaction.d.ts +40 -0
  11. package/dist/core/compaction.d.ts.map +1 -0
  12. package/dist/core/compaction.js +228 -0
  13. package/dist/core/compaction.js.map +1 -0
  14. package/dist/core/config.d.ts +54 -0
  15. package/dist/core/config.d.ts.map +1 -0
  16. package/dist/core/config.js +257 -0
  17. package/dist/core/config.js.map +1 -0
  18. package/dist/core/llm.d.ts +29 -0
  19. package/dist/core/llm.d.ts.map +1 -0
  20. package/dist/core/llm.js +553 -0
  21. package/dist/core/llm.js.map +1 -0
  22. package/dist/core/markdown.d.ts +20 -0
  23. package/dist/core/markdown.d.ts.map +1 -0
  24. package/dist/core/markdown.js +173 -0
  25. package/dist/core/markdown.js.map +1 -0
  26. package/dist/core/memory.d.ts +30 -0
  27. package/dist/core/memory.d.ts.map +1 -0
  28. package/dist/core/memory.js +163 -0
  29. package/dist/core/memory.js.map +1 -0
  30. package/dist/core/pricing.d.ts +21 -0
  31. package/dist/core/pricing.d.ts.map +1 -0
  32. package/dist/core/pricing.js +70 -0
  33. package/dist/core/pricing.js.map +1 -0
  34. package/dist/core/session-manager.d.ts +83 -0
  35. package/dist/core/session-manager.d.ts.map +1 -0
  36. package/dist/core/session-manager.js +250 -0
  37. package/dist/core/session-manager.js.map +1 -0
  38. package/dist/core/session.d.ts +76 -0
  39. package/dist/core/session.d.ts.map +1 -0
  40. package/dist/core/session.js +270 -0
  41. package/dist/core/session.js.map +1 -0
  42. package/dist/core/skills.d.ts +49 -0
  43. package/dist/core/skills.d.ts.map +1 -0
  44. package/dist/core/skills.js +232 -0
  45. package/dist/core/skills.js.map +1 -0
  46. package/dist/core/system-prompt.d.ts +17 -0
  47. package/dist/core/system-prompt.d.ts.map +1 -0
  48. package/dist/core/system-prompt.js +77 -0
  49. package/dist/core/system-prompt.js.map +1 -0
  50. package/dist/core/tool-permissions.d.ts +12 -0
  51. package/dist/core/tool-permissions.d.ts.map +1 -0
  52. package/dist/core/tool-permissions.js +71 -0
  53. package/dist/core/tool-permissions.js.map +1 -0
  54. package/dist/core/types.d.ts +157 -0
  55. package/dist/core/types.d.ts.map +1 -0
  56. package/dist/core/types.js +21 -0
  57. package/dist/core/types.js.map +1 -0
  58. package/dist/extensions/builtin/mcp.d.ts +61 -0
  59. package/dist/extensions/builtin/mcp.d.ts.map +1 -0
  60. package/dist/extensions/builtin/mcp.js +407 -0
  61. package/dist/extensions/builtin/mcp.js.map +1 -0
  62. package/dist/extensions/index.d.ts +4 -0
  63. package/dist/extensions/index.d.ts.map +1 -0
  64. package/dist/extensions/index.js +3 -0
  65. package/dist/extensions/index.js.map +1 -0
  66. package/dist/extensions/loader.d.ts +19 -0
  67. package/dist/extensions/loader.d.ts.map +1 -0
  68. package/dist/extensions/loader.js +118 -0
  69. package/dist/extensions/loader.js.map +1 -0
  70. package/dist/extensions/runner.d.ts +28 -0
  71. package/dist/extensions/runner.d.ts.map +1 -0
  72. package/dist/extensions/runner.js +77 -0
  73. package/dist/extensions/runner.js.map +1 -0
  74. package/dist/extensions/types.d.ts +84 -0
  75. package/dist/extensions/types.d.ts.map +1 -0
  76. package/dist/extensions/types.js +6 -0
  77. package/dist/extensions/types.js.map +1 -0
  78. package/dist/index.d.ts +21 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +15 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/main.d.ts +5 -0
  83. package/dist/main.d.ts.map +1 -0
  84. package/dist/main.js +355 -0
  85. package/dist/main.js.map +1 -0
  86. package/dist/modes/interactive.d.ts +6 -0
  87. package/dist/modes/interactive.d.ts.map +1 -0
  88. package/dist/modes/interactive.js +961 -0
  89. package/dist/modes/interactive.js.map +1 -0
  90. package/dist/modes/oneshot.d.ts +8 -0
  91. package/dist/modes/oneshot.d.ts.map +1 -0
  92. package/dist/modes/oneshot.js +71 -0
  93. package/dist/modes/oneshot.js.map +1 -0
  94. package/dist/tools/bash.d.ts +3 -0
  95. package/dist/tools/bash.d.ts.map +1 -0
  96. package/dist/tools/bash.js +104 -0
  97. package/dist/tools/bash.js.map +1 -0
  98. package/dist/tools/edit.d.ts +3 -0
  99. package/dist/tools/edit.d.ts.map +1 -0
  100. package/dist/tools/edit.js +63 -0
  101. package/dist/tools/edit.js.map +1 -0
  102. package/dist/tools/file-manager.d.ts +3 -0
  103. package/dist/tools/file-manager.d.ts.map +1 -0
  104. package/dist/tools/file-manager.js +85 -0
  105. package/dist/tools/file-manager.js.map +1 -0
  106. package/dist/tools/index.d.ts +17 -0
  107. package/dist/tools/index.d.ts.map +1 -0
  108. package/dist/tools/index.js +42 -0
  109. package/dist/tools/index.js.map +1 -0
  110. package/dist/tools/read.d.ts +3 -0
  111. package/dist/tools/read.d.ts.map +1 -0
  112. package/dist/tools/read.js +65 -0
  113. package/dist/tools/read.js.map +1 -0
  114. package/dist/tools/system-info.d.ts +3 -0
  115. package/dist/tools/system-info.d.ts.map +1 -0
  116. package/dist/tools/system-info.js +101 -0
  117. package/dist/tools/system-info.js.map +1 -0
  118. package/dist/tools/web-fetch.d.ts +3 -0
  119. package/dist/tools/web-fetch.d.ts.map +1 -0
  120. package/dist/tools/web-fetch.js +117 -0
  121. package/dist/tools/web-fetch.js.map +1 -0
  122. package/dist/tools/web-search.d.ts +9 -0
  123. package/dist/tools/web-search.d.ts.map +1 -0
  124. package/dist/tools/web-search.js +124 -0
  125. package/dist/tools/web-search.js.map +1 -0
  126. package/dist/tools/write.d.ts +3 -0
  127. package/dist/tools/write.d.ts.map +1 -0
  128. package/dist/tools/write.js +30 -0
  129. package/dist/tools/write.js.map +1 -0
  130. package/dist/utils/autocomplete.d.ts +23 -0
  131. package/dist/utils/autocomplete.d.ts.map +1 -0
  132. package/dist/utils/autocomplete.js +191 -0
  133. package/dist/utils/autocomplete.js.map +1 -0
  134. package/dist/utils/file-processor.d.ts +19 -0
  135. package/dist/utils/file-processor.d.ts.map +1 -0
  136. package/dist/utils/file-processor.js +86 -0
  137. package/dist/utils/file-processor.js.map +1 -0
  138. package/dist/utils/path.d.ts +8 -0
  139. package/dist/utils/path.d.ts.map +1 -0
  140. package/dist/utils/path.js +60 -0
  141. package/dist/utils/path.js.map +1 -0
  142. package/dist/utils/shell.d.ts +6 -0
  143. package/dist/utils/shell.d.ts.map +1 -0
  144. package/dist/utils/shell.js +64 -0
  145. package/dist/utils/shell.js.map +1 -0
  146. package/dist/utils/truncate.d.ts +12 -0
  147. package/dist/utils/truncate.d.ts.map +1 -0
  148. package/dist/utils/truncate.js +46 -0
  149. package/dist/utils/truncate.js.map +1 -0
  150. package/package.json +58 -0
package/README.md ADDED
@@ -0,0 +1,573 @@
1
+ # TIL work agent 工具
2
+
3
+ > 运行在终端里的个人电脑 AI 助手,类似 Codex CLI / Claude Code。
4
+
5
+ TIL work 是一个基于大语言模型的命令行 Agent 工具。它可以直接操作你的文件系统、执行命令、编辑代码、搜索网页,并通过对话式交互帮你完成各种电脑任务。
6
+
7
+ ## 核心能力
8
+
9
+ | 能力 | 说明 |
10
+ |------|------|
11
+ | **命令执行** | 在你的系统上直接运行 bash 命令 |
12
+ | **文件管理** | 读取、创建、编辑、复制、移动、删除文件 |
13
+ | **代码编辑** | 精确替换代码片段(类似 sed,但更智能) |
14
+ | **系统信息** | 查看 CPU、内存、磁盘、网络等系统状态 |
15
+ | **网页搜索** | 实时搜索互联网获取最新信息 |
16
+ | **记忆系统** | 跨对话记住上下文(MEMORY.md + AGENTS.md) |
17
+ | **技能系统** | 通过 SKILL.md 扩展 Agent 的专业能力 |
18
+ | **会话持久化** | 退出后可恢复上次对话(`--resume` / `--continue`) |
19
+ | **Context 压缩** | 长对话自动摘要压缩,防止 token 溢出 |
20
+ | **用量追踪** | 实时显示 Token 消耗和费用估算 |
21
+ | **安全拦截** | 自动检测并拦截 `rm -rf`、`sudo` 等危险命令 |
22
+ | **Markdown 渲染** | 终端内代码高亮、标题、列表等富文本显示 |
23
+ | **多模型** | 支持 Anthropic、OpenAI、Google Gemini 及任意兼容接口 |
24
+
25
+ ## 前置要求
26
+
27
+ - **Node.js** >= 20.6.0(推荐 22+)
28
+ - **npm** >= 9
29
+ - **至少一个 LLM API Key**(Anthropic / OpenAI / Google / 智谱等 OpenAI 兼容接口)
30
+
31
+ 检查 Node.js 版本:
32
+
33
+ ```bash
34
+ node -v # 需要 v20.6.0 或更高
35
+ ```
36
+
37
+ 如果未安装,推荐用 [nvm](https://github.com/nvm-sh/nvm) 安装:
38
+
39
+ ```bash
40
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
41
+ nvm install 22
42
+ ```
43
+
44
+ ## 安装
45
+
46
+ ### 方式一:npm 全局安装(推荐)
47
+
48
+ ```bash
49
+ npm install -g til-cli
50
+ ```
51
+
52
+ ### 方式二:从源码安装
53
+
54
+ ```bash
55
+ git clone https://github.com/your-org/til-cli.git
56
+ cd til-cli
57
+ npm install
58
+ npm run build
59
+ npm link # 注册 til 命令到全局
60
+ ```
61
+
62
+ ## 快速开始
63
+
64
+ ### 1. 首次配置
65
+
66
+ ```bash
67
+ til --setup
68
+ ```
69
+
70
+ 按提示输入 API Key 和选择默认模型。配置保存在 `~/.til/config.json`。
71
+
72
+ 你也可以通过环境变量配置:
73
+
74
+ ```bash
75
+ # Anthropic
76
+ export ANTHROPIC_API_KEY=sk-ant-xxxxx
77
+
78
+ # OpenAI
79
+ export OPENAI_API_KEY=sk-xxxxx
80
+
81
+ # Google Gemini
82
+ export GOOGLE_API_KEY=AIza-xxxxx
83
+
84
+ # OpenAI 兼容接口(如智谱、DeepSeek、Ollama 等)
85
+ export OPENAI_API_KEY=your-key
86
+ export OPENAI_BASE_URL=https://open.bigmodel.cn/api/paas/v4
87
+ ```
88
+
89
+ ### 2. 启动交互模式
90
+
91
+ ```bash
92
+ til
93
+ ```
94
+
95
+ 你会看到:
96
+
97
+ ```
98
+ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
99
+ ┃ >_ 欢迎使用千岛湖 Agent 工具 TIL v0.1.0 ┃
100
+ ┃ model: gpt-4o /model 切换 ┃
101
+ ┃ directory: ~/dev/my-project ┃
102
+ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
103
+ ```
104
+
105
+ 输入 `/` 查看所有可用命令,按 Tab 自动补全。
106
+
107
+ ### 3. 单次执行模式
108
+
109
+ ```bash
110
+ # 直接给出提示
111
+ til "列出当前目录的所有 TypeScript 文件"
112
+
113
+ # 通过参数传入
114
+ til -p "解释这个错误日志" < error.log
115
+
116
+ # 管道输入
117
+ cat README.md | til "总结一下这个文件"
118
+ ```
119
+
120
+ ## 命令参考
121
+
122
+ ### CLI 参数
123
+
124
+ ```
125
+ til [options] [prompt]
126
+
127
+ 选项:
128
+ -p, --prompt <text> 单次执行模式
129
+ -m, --model <model> 指定模型(如 gpt-4o, claude-sonnet-4-20250514, gemini-2.5-pro-preview-06-05)
130
+ --base-url <url> 覆盖 API 地址
131
+ --tools <list> 指定启用的工具(逗号分隔)
132
+ --skill <path> 加载技能文件或目录(可重复)
133
+ --no-skills 禁用自动技能加载
134
+ --continue 恢复当前目录下的最近一次会话
135
+ --resume [sessionId] 恢复指定 ID 的会话(不传 ID 等同于 --continue)
136
+ --setup 运行配置向导
137
+ -h, --help 显示帮助
138
+ -v, --version 显示版本
139
+ ```
140
+
141
+ ### 交互模式命令
142
+
143
+ 在交互模式中输入 `/` 即可看到所有命令(支持自动补全):
144
+
145
+ | 命令 | 说明 |
146
+ |------|------|
147
+ | `/help` | 显示帮助信息 |
148
+ | `/model <id>` | 切换模型 |
149
+ | `/models` | 查看可用模型列表 |
150
+ | `/skills` | 查看已加载的技能 |
151
+ | `/skill:<name>` | 查看某个技能的详细内容 |
152
+ | `/memory` | 查看当前记忆内容 |
153
+ | `/usage` | 查看本次会话的 Token 用量和费用 |
154
+ | `/sessions` | 查看会话历史列表 |
155
+ | `/config` | 查看当前配置 |
156
+ | `/clear` | 清空对话历史 |
157
+ | `/exit` | 退出 |
158
+
159
+ ## 内置工具
160
+
161
+ | 工具 | 说明 |
162
+ |------|------|
163
+ | `bash` | 执行 bash 命令(ls, grep, git, curl 等) |
164
+ | `read` | 读取文件内容(支持偏移和行数限制) |
165
+ | `write` | 创建或覆盖文件 |
166
+ | `edit` | 精确查找替换(修改文件中的特定文本) |
167
+ | `file_manager` | 高级文件操作(复制、移动、删除、列目录、获取信息) |
168
+ | `system_info` | 获取系统信息(OS、CPU、内存、网络、环境变量) |
169
+ | `web_search` | 搜索互联网获取实时信息 |
170
+
171
+ ## 配置
172
+
173
+ 配置文件位于 `~/.til/config.json`,结构如下:
174
+
175
+ ```json
176
+ {
177
+ "providers": {
178
+ "anthropic": {
179
+ "apiKey": "sk-ant-xxxxx"
180
+ },
181
+ "openai": {
182
+ "apiKey": "sk-xxxxx",
183
+ "baseUrl": "https://open.bigmodel.cn/api/paas/v4"
184
+ },
185
+ "google": {
186
+ "apiKey": "AIza-xxxxx"
187
+ }
188
+ },
189
+ "defaultModel": {
190
+ "provider": "openai",
191
+ "id": "glm-5"
192
+ },
193
+ "customModels": {
194
+ "glm-5": {
195
+ "provider": "openai",
196
+ "name": "GLM-5",
197
+ "contextWindow": 128000
198
+ }
199
+ },
200
+ "compaction": {
201
+ "thresholdRatio": 0.7,
202
+ "keepRecentTokens": 4000,
203
+ "reserveTokens": 8000
204
+ }
205
+ }
206
+ ```
207
+
208
+ ### 支持的模型提供商
209
+
210
+ | 提供商 | 说明 | 配置方式 |
211
+ |--------|------|---------|
212
+ | **Anthropic** | Claude 系列 | `ANTHROPIC_API_KEY` |
213
+ | **OpenAI** | GPT 系列 | `OPENAI_API_KEY` |
214
+ | **Google** | Gemini 系列 | `GOOGLE_API_KEY` |
215
+ | **智谱 (GLM)** | GLM 系列 | OpenAI 兼容接口 + 自定义 base_url |
216
+ | **DeepSeek** | DeepSeek 系列 | OpenAI 兼容接口 + 自定义 base_url |
217
+ | **Ollama** | 本地模型 | OpenAI 兼容接口 (`http://localhost:11434/v1`) |
218
+ | **其他** | 任意 OpenAI 兼容接口 | `--base-url` 或配置 |
219
+
220
+ ### 内置模型及 Context Window
221
+
222
+ | 模型 | 提供商 | Context Window |
223
+ |------|--------|----------------|
224
+ | `claude-sonnet-4-20250514` | Anthropic | 200k |
225
+ | `claude-3-5-haiku-20241022` | Anthropic | 200k |
226
+ | `gpt-4o` | OpenAI | 128k |
227
+ | `gpt-4o-mini` | OpenAI | 128k |
228
+ | `o3-mini` | OpenAI | 200k |
229
+ | `gemini-2.0-flash` | Google | 1M |
230
+ | `gemini-2.5-pro-preview-06-05` | Google | 1M |
231
+
232
+ ## 会话持久化
233
+
234
+ TIL 自动保存每次对话为会话文件(JSONL 格式),可随时恢复。
235
+
236
+ ### 自动保存
237
+
238
+ 每次对话的消息都会实时追加写入 `~/.til/sessions/` 目录。退出时会显示会话 ID 和恢复命令:
239
+
240
+ ```
241
+ Bye! session: abc12345
242
+ 恢复此会话: til --resume abc12345
243
+ ```
244
+
245
+ ### 恢复会话
246
+
247
+ ```bash
248
+ # 恢复最近的会话
249
+ til --continue
250
+
251
+ # 恢复指定的会话
252
+ til --resume abc12345
253
+
254
+ # 在交互模式中查看会话列表
255
+ /sessions
256
+ ```
257
+
258
+ 恢复后会自动加载之前的完整对话历史,并显示上下文摘要。
259
+
260
+ ## Context 压缩(Compaction)
261
+
262
+ 当长对话接近模型的上下文窗口上限时,TIL 会自动触发压缩:
263
+
264
+ 1. **阈值检测** — 当已用 token 超过 `contextWindow * thresholdRatio`(默认 70%)时触发
265
+ 2. **溢出兜底** — 如果模型返回上下文溢出错误,自动压缩后重试
266
+ 3. **智能切分** — 保留最近的对话(默认 4000 token),将历史部分交给 LLM 生成摘要
267
+ 4. **增量更新** — 后续压缩会基于前一次的摘要进行增量更新,不丢失关键信息
268
+
269
+ 交互界面会实时显示上下文使用率:
270
+
271
+ ```
272
+ ↑12.3k ↓1.2k ctx: 35% # 绿色 < 50%
273
+ ↑45.0k ↓8.5k ctx: 72% # 黄色 50-80%
274
+ ↑98.0k ↓15.2k ctx: 95% # 红色 > 80%
275
+ ```
276
+
277
+ ### 配置压缩参数
278
+
279
+ 在 `~/.til/config.json` 中:
280
+
281
+ ```json
282
+ {
283
+ "compaction": {
284
+ "thresholdRatio": 0.7,
285
+ "keepRecentTokens": 4000,
286
+ "reserveTokens": 8000
287
+ }
288
+ }
289
+ ```
290
+
291
+ | 参数 | 默认值 | 说明 |
292
+ |------|--------|------|
293
+ | `thresholdRatio` | 0.7 | 触发压缩的 token 占比阈值 |
294
+ | `keepRecentTokens` | 4000 | 压缩时保留最近多少 token 不被摘要 |
295
+ | `reserveTokens` | 8000 | 为模型输出预留的 token 空间 |
296
+
297
+ ## Token 用量和费用追踪
298
+
299
+ TIL 实时追踪每次对话的 token 消耗和费用估算。
300
+
301
+ ### 实时显示
302
+
303
+ 每轮对话结束后会显示当前轮的用量:
304
+
305
+ ```
306
+ ↑12.3k ↓1.2k R8.0k ctx: 35%
307
+ ```
308
+
309
+ - `↑` 输入 token
310
+ - `↓` 输出 token
311
+ - `R` 缓存命中 token
312
+ - `ctx` 上下文占用率
313
+
314
+ ### 累计用量
315
+
316
+ 使用 `/usage` 命令查看本次会话的累计数据:
317
+
318
+ ```
319
+ 📊 Token 用量统计
320
+ 输入: 45,230 tokens
321
+ 输出: 12,891 tokens
322
+ 缓存: 38,100 tokens
323
+ 总计: 58,121 tokens
324
+ 费用: ≈ $0.15
325
+ 上下文: 58,121 / 200,000 (29%)
326
+ ```
327
+
328
+ ### 支持的计费模型
329
+
330
+ 内置 Anthropic(Claude)、OpenAI(GPT/o3)、Google(Gemini)主流模型的价格数据。对于自定义模型,显示 token 数量但不估算费用。
331
+
332
+ ## 工具安全拦截
333
+
334
+ TIL 内置危险命令检测,在执行前自动拦截以下类型的命令:
335
+
336
+ | 危险类型 | 示例 |
337
+ |----------|------|
338
+ | 递归删除 | `rm -rf /`, `rm -rf ~` |
339
+ | 提权操作 | `sudo ...`, `su root` |
340
+ | 磁盘格式化 | `mkfs`, `dd if=... of=/dev/...` |
341
+ | 权限修改 | `chmod 777`, `chown root` |
342
+ | 进程操作 | `kill -9`, `killall` |
343
+ | 网络操作 | `iptables`, `curl \| sh` |
344
+
345
+ 拦截时会显示提示并要求确认:
346
+
347
+ ```
348
+ ⚠️ 检测到危险命令: rm -rf /tmp/important
349
+ 原因: 包含递归删除操作
350
+ 确认执行? (y/N)
351
+ ```
352
+
353
+ 在非交互模式下(单次执行),危险命令将直接被阻止。
354
+
355
+ ## Markdown 终端渲染
356
+
357
+ TIL 的回答会以富文本格式渲染在终端中,包括:
358
+
359
+ - **标题** — 带颜色和粗体的层级标题
360
+ - **代码块** — 语法高亮(支持 TypeScript、Python、Bash 等多种语言)
361
+ - **行内代码** — 反引号高亮
362
+ - **列表** — 有序/无序列表缩进
363
+ - **引用块** — 带边框的引用
364
+ - **链接** — 下划线 + URL 显示
365
+ - **粗体/斜体/删除线** — 终端 ANSI 样式
366
+
367
+ ## 记忆系统
368
+
369
+ TIL 使用双层记忆系统在对话之间保持上下文:
370
+
371
+ ### MEMORY.md(工作记忆)
372
+
373
+ 由 AI 自动写入,跨对话持久化:
374
+
375
+ | 文件 | 作用 |
376
+ |------|------|
377
+ | `~/.til/MEMORY.md` | 全局记忆(偏好、通用模式) |
378
+ | `.til/MEMORY.md` | 项目记忆(架构决策、进行中的工作) |
379
+
380
+ ### AGENTS.md(项目上下文)
381
+
382
+ 手动维护的项目指令和约定:
383
+
384
+ | 文件 | 作用 |
385
+ |------|------|
386
+ | `~/.til/AGENTS.md` | 全局指令(编码风格、通用约定) |
387
+ | `<项目>/AGENTS.md` | 项目指令(技术栈、架构规范) |
388
+
389
+ 也支持 `CLAUDE.md` 文件名(兼容 Claude Code 的约定)。
390
+
391
+ ## 技能系统
392
+
393
+ 技能是 `SKILL.md` 文件,用于扩展 Agent 的专业能力。
394
+
395
+ ### 技能存放位置
396
+
397
+ | 路径 | 作用 |
398
+ |------|------|
399
+ | `~/.til/skills/` | 全局技能 |
400
+ | `.til/skills/` | 项目级技能 |
401
+ | `--skill <path>` | CLI 指定的技能 |
402
+
403
+ ### 技能文件格式
404
+
405
+ ```markdown
406
+ ---
407
+ name: deploy-helper
408
+ description: 帮助部署应用到生产环境
409
+ triggers:
410
+ - deploy
411
+ - 部署
412
+ ---
413
+
414
+ # 部署助手
415
+
416
+ 当用户需要部署时,按照以下步骤操作:
417
+ 1. 检查 git 状态,确保代码已提交
418
+ 2. 运行测试
419
+ 3. 构建项目
420
+ 4. 执行部署命令
421
+ ```
422
+
423
+ ### 查看和使用技能
424
+
425
+ ```
426
+ /skills # 列出所有已加载技能
427
+ /skill:deploy # 查看 deploy 技能详情
428
+ ```
429
+
430
+ ## 常见问题
431
+
432
+ ### 安装后提示 permission denied
433
+
434
+ ```bash
435
+ chmod +x $(which til)
436
+ # 或重新 link
437
+ cd til-cli && npm link
438
+ ```
439
+
440
+ ### 提示 No API key found
441
+
442
+ ```bash
443
+ # 方法 1:环境变量
444
+ export OPENAI_API_KEY=your-key
445
+
446
+ # 方法 2:配置向导
447
+ til --setup
448
+ ```
449
+
450
+ ### 如何使用 Google Gemini
451
+
452
+ ```bash
453
+ export GOOGLE_API_KEY=AIza-xxxxx
454
+ til -m gemini-2.5-pro-preview-06-05
455
+ ```
456
+
457
+ 或在 `~/.til/config.json` 中配置:
458
+
459
+ ```json
460
+ {
461
+ "providers": {
462
+ "google": { "apiKey": "AIza-xxxxx" }
463
+ },
464
+ "defaultModel": { "provider": "google", "id": "gemini-2.5-pro-preview-06-05" }
465
+ }
466
+ ```
467
+
468
+ ### 如何使用国内 LLM(智谱/DeepSeek 等)
469
+
470
+ 运行 `til --setup`,在 CUSTOM PROVIDER 部分填入:
471
+
472
+ - Base URL:如 `https://open.bigmodel.cn/api/paas/v4`
473
+ - API Key:你的 API Key
474
+ - Model ID:如 `glm-5`
475
+
476
+ 或者直接编辑 `~/.til/config.json`。
477
+
478
+ ### 如何使用本地模型(Ollama)
479
+
480
+ ```bash
481
+ # 启动 Ollama
482
+ ollama serve
483
+
484
+ # 配置 TIL
485
+ til --setup
486
+ # Base URL 填 http://localhost:11434/v1
487
+ # Model ID 填 llama3.1:8b(或其他已 pull 的模型)
488
+ ```
489
+
490
+ ### 对话太长会不会丢信息
491
+
492
+ 不会。TIL 内置 Context 压缩机制,当对话接近上下文窗口上限时,会自动将历史对话摘要化,保留关键信息的同时腾出空间。你也可以通过 `/usage` 查看当前上下文使用率。
493
+
494
+ ### 会话断了怎么恢复
495
+
496
+ ```bash
497
+ # 恢复最近一次会话
498
+ til --continue
499
+
500
+ # 恢复指定会话
501
+ til --resume <sessionId>
502
+ ```
503
+
504
+ 退出时会自动显示恢复命令。
505
+
506
+ ### 如何关闭危险命令拦截
507
+
508
+ 目前不支持全局关闭。TIL 在执行可能破坏性的命令前会要求确认,这是安全设计。在交互模式下可以选择 `y` 确认执行。
509
+
510
+ ## 开发
511
+
512
+ ```bash
513
+ git clone https://github.com/your-org/til-cli.git
514
+ cd til-cli
515
+ npm install
516
+ npm run dev # 监听模式编译
517
+ npm run build # 一次性编译
518
+ npm start # 运行
519
+ ```
520
+
521
+ ### 运行测试
522
+
523
+ ```bash
524
+ npm test # 运行全部测试
525
+ npm run test:watch # 监听模式
526
+ ```
527
+
528
+ 测试使用 [Vitest](https://vitest.dev/),覆盖所有核心模块:
529
+
530
+ - `tests/core/` — Agent、Config、LLM、Session、Compaction、Pricing、Memory、Skills、Markdown、Tool Permissions
531
+ - `tests/tools/` — Bash、Read、Write、Edit 工具
532
+
533
+ ### 项目结构
534
+
535
+ ```
536
+ til-cli/
537
+ ├── src/
538
+ │ ├── main.ts # CLI 入口
539
+ │ ├── index.ts # 公共 API 导出
540
+ │ ├── core/
541
+ │ │ ├── agent.ts # 双层循环 Agent 引擎
542
+ │ │ ├── llm.ts # LLM 提供商抽象(Anthropic/OpenAI/Google)
543
+ │ │ ├── config.ts # 配置管理
544
+ │ │ ├── session.ts # 会话包装(工具 + 系统提示)
545
+ │ │ ├── session-manager.ts # 会话持久化(JSONL)
546
+ │ │ ├── types.ts # 核心类型定义
547
+ │ │ ├── compaction.ts # Context 压缩 & 溢出检测
548
+ │ │ ├── pricing.ts # Token 计费 & 用量格式化
549
+ │ │ ├── tool-permissions.ts # 危险命令拦截
550
+ │ │ ├── markdown.ts # 终端 Markdown 渲染
551
+ │ │ ├── memory.ts # 记忆系统
552
+ │ │ ├── skills.ts # 技能系统
553
+ │ │ └── system-prompt.ts # 系统提示词组装
554
+ │ ├── modes/
555
+ │ │ ├── interactive.ts # 交互 REPL 模式
556
+ │ │ └── oneshot.ts # 单次执行模式
557
+ │ └── tools/ # 内置工具实现
558
+ │ ├── bash.ts
559
+ │ ├── read.ts
560
+ │ ├── write.ts
561
+ │ ├── edit.ts
562
+ │ ├── file-manager.ts
563
+ │ ├── system-info.ts
564
+ │ └── web-search.ts
565
+ ├── tests/ # 单元测试
566
+ ├── package.json
567
+ ├── tsconfig.json
568
+ └── vitest.config.ts
569
+ ```
570
+
571
+ ## 许可证
572
+
573
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "./main.js";
3
+ main(process.argv.slice(2)).catch((err) => {
4
+ console.error("Fatal error:", err.message || err);
5
+ process.exit(1);
6
+ });
7
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACzC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Agent runtime: drives the LLM ↔ tool execution loop.
3
+ * Dual-loop architecture matching pi-mono:
4
+ * Outer loop — processes follow-up messages after agent would stop
5
+ * Inner loop — processes tool calls + steering (interrupt) messages
6
+ */
7
+ import { type CompactionSettings } from "./compaction.js";
8
+ import type { AgentEvent, AgentState, AgentTool, Message, ModelConfig, ThinkingLevel } from "./types.js";
9
+ export interface AgentOptions {
10
+ systemPrompt: string;
11
+ model: ModelConfig;
12
+ tools?: AgentTool[];
13
+ thinkingLevel?: ThinkingLevel;
14
+ maxTurns?: number;
15
+ contextWindow?: number;
16
+ compactionSettings?: CompactionSettings;
17
+ /**
18
+ * Called between tool executions. If it returns messages, the remaining
19
+ * tool calls are skipped and the returned messages are injected before
20
+ * the next LLM turn (steering / interrupt).
21
+ */
22
+ getSteeringMessages?: () => Promise<Message[]>;
23
+ /**
24
+ * Called after the agent would normally stop (no more tool calls).
25
+ * If it returns messages, the agent continues with a new outer-loop
26
+ * iteration (follow-up / continuation).
27
+ */
28
+ getFollowUpMessages?: () => Promise<Message[]>;
29
+ /**
30
+ * Called before a tool is executed. Return { block: true } to prevent execution.
31
+ */
32
+ onToolCallRequest?: (toolName: string, args: Record<string, any>) => Promise<{
33
+ block: boolean;
34
+ reason?: string;
35
+ }>;
36
+ }
37
+ export declare class Agent {
38
+ private state;
39
+ private listeners;
40
+ private abortController?;
41
+ private maxTurns;
42
+ private contextWindow;
43
+ private compactionSettings;
44
+ private compactionSummary?;
45
+ private getSteeringMessages?;
46
+ private getFollowUpMessages?;
47
+ private onToolCallRequest?;
48
+ constructor(opts: AgentOptions);
49
+ get currentState(): AgentState;
50
+ subscribe(fn: (e: AgentEvent) => void): () => void;
51
+ setSystemPrompt(prompt: string): void;
52
+ setModel(model: ModelConfig): void;
53
+ setTools(tools: AgentTool[]): void;
54
+ clearMessages(): void;
55
+ /**
56
+ * Replace the message history (used when restoring a persisted session).
57
+ */
58
+ setMessages(messages: Message[]): void;
59
+ abort(): void;
60
+ /**
61
+ * Start a new agent loop with a user prompt.
62
+ */
63
+ prompt(input: string): Promise<void>;
64
+ /**
65
+ * Continue the agent loop from the current context without adding a
66
+ * new message. Used for retry / resume scenarios.
67
+ */
68
+ continue(): Promise<void>;
69
+ private runLoop;
70
+ private streamAssistantResponse;
71
+ private executeToolCalls;
72
+ private skipToolCall;
73
+ private makeToolResult;
74
+ private checkThresholdCompaction;
75
+ private runCompaction;
76
+ private emit;
77
+ }
78
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/core/agent.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAMN,KAAK,kBAAkB,EAEvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EACX,UAAU,EACV,UAAU,EACV,SAAS,EAET,OAAO,EACP,WAAW,EAEX,aAAa,EAGb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/C;;OAEG;IACH,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClH;AAED,qBAAa,KAAK;IACjB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,eAAe,CAAC,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,mBAAmB,CAAC,CAA2B;IACvD,OAAO,CAAC,mBAAmB,CAAC,CAA2B;IACvD,OAAO,CAAC,iBAAiB,CAAC,CAAgG;gBAE9G,IAAI,EAAE,YAAY;IAiB9B,IAAI,YAAY,IAAI,UAAU,CAE7B;IAED,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI;IAKlD,eAAe,CAAC,MAAM,EAAE,MAAM;IAI9B,QAAQ,CAAC,KAAK,EAAE,WAAW;IAI3B,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE;IAI3B,aAAa;IAIb;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE;IAI/B,KAAK;IAIL;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1C;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAgBjB,OAAO;YA4IP,uBAAuB;YAqCvB,gBAAgB;IAuF9B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,cAAc;YAiBR,wBAAwB;YAYxB,aAAa;IAwC3B,OAAO,CAAC,IAAI;CAKZ"}