@jiangyuan1209/yuan-claw 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 (45) hide show
  1. package/.env.example +28 -0
  2. package/README.md +441 -0
  3. package/dist/agent/build-system-prompt.js +46 -0
  4. package/dist/agent/message-types.js +1 -0
  5. package/dist/agent/message-utils.js +239 -0
  6. package/dist/agent/parse-agent-response.js +48 -0
  7. package/dist/agent/prompts.js +27 -0
  8. package/dist/agent/protocol.js +1 -0
  9. package/dist/agent/read-approval.js +45 -0
  10. package/dist/agent/read-confirmation.js +17 -0
  11. package/dist/agent/run-local-agent-loop.js +272 -0
  12. package/dist/cli/help.js +24 -0
  13. package/dist/cli/main.js +108 -0
  14. package/dist/cli/parse-args.js +75 -0
  15. package/dist/cli/repl.js +188 -0
  16. package/dist/config/config-path.js +9 -0
  17. package/dist/config/init-user-config.js +39 -0
  18. package/dist/config/load-config.js +46 -0
  19. package/dist/config.js +29 -0
  20. package/dist/events/event-bus.js +62 -0
  21. package/dist/lib/initGlobalProxy.js +52 -0
  22. package/dist/memory/session-store.js +43 -0
  23. package/dist/memory/types.js +1 -0
  24. package/dist/model/client.js +7 -0
  25. package/dist/model/providers/openai-compatible.js +42 -0
  26. package/dist/scripts/test-brave.js +16 -0
  27. package/dist/security/network-policy.js +19 -0
  28. package/dist/security/path-guards.js +18 -0
  29. package/dist/security/shell-policy.js +40 -0
  30. package/dist/shared/utils.js +1 -0
  31. package/dist/tools/file/grep-text.js +85 -0
  32. package/dist/tools/file/list-files.js +52 -0
  33. package/dist/tools/file/read-file.js +39 -0
  34. package/dist/tools/file/write-file.js +37 -0
  35. package/dist/tools/git/git-diff.js +54 -0
  36. package/dist/tools/git/git-status.js +44 -0
  37. package/dist/tools/registry.js +41 -0
  38. package/dist/tools/shell/shell-exec.js +41 -0
  39. package/dist/tools/types.js +1 -0
  40. package/dist/tools/web/extract-readable-text.js +54 -0
  41. package/dist/tools/web/http-fetch.js +55 -0
  42. package/dist/tools/web/index.js +4 -0
  43. package/dist/tools/web/search-providers/brave.js +31 -0
  44. package/dist/tools/web/web-search.js +33 -0
  45. package/package.json +26 -0
package/.env.example ADDED
@@ -0,0 +1,28 @@
1
+ # =========================
2
+ # 模型服务配置(推荐)
3
+ # =========================
4
+
5
+ MODEL_API_KEY=
6
+ MODEL_BASE_URL=
7
+ MODEL_NAME=
8
+
9
+ # =========================
10
+ # OpenAI 风格兼容变量(可选)
11
+ # =========================
12
+
13
+ OPENAI_API_KEY=
14
+ OPENAI_BASE_URL=
15
+ OPENAI_MODEL=
16
+
17
+ # =========================
18
+ # 网页搜索配置
19
+ # =========================
20
+
21
+ BRAVE_SEARCH_API_KEY=
22
+
23
+ # =========================
24
+ # 代理配置(可选)
25
+ # =========================
26
+
27
+ HTTP_PROXY=
28
+ HTTPS_PROXY=
package/README.md ADDED
@@ -0,0 +1,441 @@
1
+ # yuan-claw
2
+
3
+ 一个基于 **Node.js + TypeScript** 的本地 CLI Agent。
4
+ 它可以在命令行中使用大模型完成任务,并按需调用网页搜索、HTTP 抓取、网页正文提取以及本地工具。
5
+
6
+ ## Features
7
+
8
+ - 🤖 本地命令行智能体
9
+ - 🧠 基于大模型的任务执行与推理
10
+ - 🔧 可扩展的工具调用机制
11
+ - 🌐 支持 Brave Search 网页搜索
12
+ - 📄 支持 HTTP 抓取与网页正文提取
13
+ - 💬 支持多轮会话
14
+ - 🖥️ 支持交互式 REPL
15
+ - ✅ 支持工具执行前确认(approval)
16
+ - ⌨️ 支持 `↑ / ↓ / Enter` 选择确认项
17
+ - 🔁 支持会话级“总是允许”模式
18
+ - 🔌 支持代理配置
19
+ - 🛠️ 基于 TypeScript,便于二次开发
20
+
21
+ ---
22
+
23
+ ## Requirements
24
+
25
+ - Node.js >= 20
26
+ - npm >= 9
27
+
28
+ ---
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ git clone https://github.com/your-name/yuan-claw.git
34
+ cd yuan-claw
35
+ npm install
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ### 1. 配置环境变量
43
+
44
+ 在项目根目录创建 `.env` 文件:
45
+
46
+ ```env
47
+ MODEL_API_KEY=
48
+ MODEL_BASE_URL=
49
+ MODEL_NAME=
50
+
51
+ BRAVE_SEARCH_API_KEY=
52
+
53
+ HTTP_PROXY=
54
+ HTTPS_PROXY=
55
+ ```
56
+
57
+ 最小可用配置通常只需要:
58
+
59
+ ```env
60
+ MODEL_API_KEY=your_api_key
61
+ MODEL_BASE_URL=https://api.openai.com/v1
62
+ MODEL_NAME=gpt-4o-mini
63
+ ```
64
+
65
+ ---
66
+
67
+ ### 2. 开发模式运行
68
+
69
+ #### 单次命令
70
+
71
+ ```bash
72
+ npm run dev -- "帮我搜索 OpenAI 最新消息"
73
+ ```
74
+
75
+ #### 交互式 REPL
76
+
77
+ ```bash
78
+ npm run dev
79
+ ```
80
+
81
+ 启动后你会看到:
82
+
83
+ ```txt
84
+ Welcome to yuan-claw!
85
+ Type /help for commands, /exit to quit.
86
+ Approval mode is shown in the prompt: [ask] or [always].
87
+
88
+ yuan-claw[ask]>
89
+ ```
90
+
91
+ ---
92
+
93
+ ### 3. 编译后运行
94
+
95
+ ```bash
96
+ npm run build
97
+ npm run start
98
+ ```
99
+
100
+ 单次命令模式:
101
+
102
+ ```bash
103
+ npm run start -- "帮我总结这个项目的功能"
104
+ ```
105
+
106
+ ---
107
+
108
+ ## REPL Usage
109
+
110
+ 不传入 prompt 时,程序会进入 REPL 模式。你可以连续输入多轮指令,例如:
111
+
112
+ ```txt
113
+ yuan-claw[ask]> 帮我总结这个项目
114
+ yuan-claw[ask]> 再简短一点
115
+ yuan-claw[ask]> 输出成要点列表
116
+ ```
117
+
118
+ 支持的内置命令:
119
+
120
+ ```txt
121
+ /help 显示帮助
122
+ /exit 退出
123
+ /quit 退出
124
+ /clear 清空当前会话历史,并重置 approval 模式
125
+ /save 保存当前会话
126
+ /reset 将 approval 模式重置为 ask
127
+ /status 查看当前会话状态
128
+ ```
129
+
130
+ ---
131
+
132
+ ## Approval / 工具执行确认
133
+
134
+ 某些工具调用在执行前需要你的确认,例如执行本地命令时:
135
+
136
+ ```txt
137
+ 我需要执行 `pwd` 命令来显示当前工作目录。是否允许执行?
138
+ ```
139
+
140
+ 此时可以使用:
141
+
142
+ - `↑ / ↓`:切换选项
143
+ - `Enter`:确认
144
+ - `Ctrl+C`:拒绝
145
+
146
+ 可选项包括:
147
+
148
+ - **不允许**
149
+ - **允许**
150
+ - **总是允许**
151
+
152
+ 如果选择 **总是允许**,当前会话后续的相关工具调用将自动通过,提示符也会变为:
153
+
154
+ ```txt
155
+ yuan-claw[always]>
156
+ ```
157
+
158
+ 如需恢复逐次确认,可执行:
159
+
160
+ ```txt
161
+ /reset
162
+ ```
163
+
164
+ ---
165
+
166
+ ## Scripts
167
+
168
+ ```json
169
+ {
170
+ "scripts": {
171
+ "dev": "tsx src/cli/main.ts",
172
+ "build": "tsc -p tsconfig.json",
173
+ "start": "node dist/cli/main.js",
174
+ "check": "tsc --noEmit"
175
+ }
176
+ }
177
+ ```
178
+
179
+ ### 脚本说明
180
+
181
+ - `npm run dev`:开发模式运行源码
182
+ - `npm run build`:编译到 `dist/`
183
+ - `npm run start`:运行编译后的 CLI
184
+ - `npm run check`:执行 TypeScript 类型检查
185
+
186
+ 说明:
187
+
188
+ - `npm run dev` / `npm run start`
189
+ - 不传参数:进入 REPL
190
+ - 传入参数:执行单次命令
191
+
192
+ ---
193
+
194
+ ## CLI Usage
195
+
196
+ 项目在 `package.json` 中定义了可执行命令:
197
+
198
+ ```json
199
+ "bin": {
200
+ "yuan-claw": "./dist/cli/main.js"
201
+ }
202
+ ```
203
+
204
+ 构建并安装后,可以直接使用:
205
+
206
+ ```bash
207
+ yuan-claw
208
+ ```
209
+
210
+ 或:
211
+
212
+ ```bash
213
+ yuan-claw "帮我搜索 AI 新闻"
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Environment Variables
219
+
220
+ 项目使用 **OpenAI-compatible API**,按以下优先级读取配置:
221
+
222
+ ### API Key
223
+
224
+ 1. `MODEL_API_KEY`
225
+ 2. `OPENAI_API_KEY`
226
+
227
+ ### Base URL
228
+
229
+ 1. `MODEL_BASE_URL`
230
+ 2. `OPENAI_BASE_URL`
231
+
232
+ ### Model Name
233
+
234
+ 1. `MODEL_NAME`
235
+ 2. `OPENAI_MODEL`
236
+ 3. 默认值:`gpt-4o-mini`
237
+
238
+ ### OpenAI 风格兼容变量
239
+
240
+ 如果你更习惯 OpenAI 风格变量名,也可以使用:
241
+
242
+ ```env
243
+ OPENAI_API_KEY=
244
+ OPENAI_BASE_URL=
245
+ OPENAI_MODEL=
246
+ ```
247
+
248
+ ---
249
+
250
+ ## Web Search
251
+
252
+ 如果你希望启用网页搜索工具,请配置:
253
+
254
+ ```env
255
+ BRAVE_SEARCH_API_KEY=your_brave_search_api_key
256
+ ```
257
+
258
+ 未配置时,`web_search` 工具会被禁用。
259
+
260
+ ---
261
+
262
+ ## Proxy
263
+
264
+ 如需通过代理访问模型服务或外部网站,可以配置:
265
+
266
+ ```env
267
+ HTTP_PROXY=http://127.0.0.1:33210
268
+ HTTPS_PROXY=http://127.0.0.1:33210
269
+ ```
270
+
271
+ 程序会自动读取以下变量:
272
+
273
+ - `HTTP_PROXY`
274
+ - `HTTPS_PROXY`
275
+ - `http_proxy`
276
+ - `https_proxy`
277
+
278
+ ---
279
+
280
+ ## Recommended `.env.example`
281
+
282
+ 建议在仓库中提供如下 `.env.example`:
283
+
284
+ ```env
285
+ # =========================
286
+ # 模型服务配置(推荐)
287
+ # =========================
288
+
289
+ MODEL_API_KEY=
290
+ MODEL_BASE_URL=
291
+ MODEL_NAME=
292
+
293
+ # =========================
294
+ # OpenAI 风格兼容变量(可选)
295
+ # =========================
296
+
297
+ OPENAI_API_KEY=
298
+ OPENAI_BASE_URL=
299
+ OPENAI_MODEL=
300
+
301
+ # =========================
302
+ # 网页搜索配置
303
+ # =========================
304
+
305
+ BRAVE_SEARCH_API_KEY=
306
+
307
+ # =========================
308
+ # 代理配置(可选)
309
+ # =========================
310
+
311
+ HTTP_PROXY=
312
+ HTTPS_PROXY=
313
+ ```
314
+
315
+ ---
316
+
317
+ ## Examples
318
+
319
+ ### 普通问答
320
+
321
+ ```bash
322
+ npm run dev -- "帮我总结这个项目的功能"
323
+ ```
324
+
325
+ ### 搜索最新消息
326
+
327
+ ```bash
328
+ npm run dev -- "帮我搜索 OpenAI 最新消息"
329
+ ```
330
+
331
+ ### 进入 REPL
332
+
333
+ ```bash
334
+ npm run dev
335
+ ```
336
+
337
+ ### 编译后运行
338
+
339
+ ```bash
340
+ npm run build
341
+ npm run start -- "帮我搜索 AI 新闻"
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Troubleshooting
347
+
348
+ ### `Missing MODEL_API_KEY / OPENAI_API_KEY in environment variables.`
349
+
350
+ 说明模型 API Key 未配置。请至少设置其一:
351
+
352
+ ```env
353
+ MODEL_API_KEY=your_api_key
354
+ ```
355
+
356
+ 或:
357
+
358
+ ```env
359
+ OPENAI_API_KEY=your_api_key
360
+ ```
361
+
362
+ ---
363
+
364
+ ### `web_search disabled: set BRAVE_SEARCH_API_KEY`
365
+
366
+ 说明未配置 Brave Search API Key。请添加:
367
+
368
+ ```env
369
+ BRAVE_SEARCH_API_KEY=your_key
370
+ ```
371
+
372
+ ---
373
+
374
+ ### 无法访问外部服务 / 请求超时
375
+
376
+ 请检查是否需要代理:
377
+
378
+ ```env
379
+ HTTP_PROXY=http://127.0.0.1:33210
380
+ HTTPS_PROXY=http://127.0.0.1:33210
381
+ ```
382
+
383
+ ---
384
+
385
+ ### 某些网页返回 403 / Forbidden
386
+
387
+ 这通常是目标站点的反爬策略导致的,不一定是程序错误。
388
+ 建议优先使用搜索 API 或可信数据源。
389
+
390
+ ---
391
+
392
+ ### `npm run start` 无法运行
393
+
394
+ 请先执行:
395
+
396
+ ```bash
397
+ npm run build
398
+ ```
399
+
400
+ 因为 `start` 依赖编译输出文件:
401
+
402
+ ```txt
403
+ dist/cli/main.js
404
+ ```
405
+
406
+ ---
407
+
408
+ ## Development
409
+
410
+ ```bash
411
+ npm run check
412
+ npm run dev
413
+ ```
414
+
415
+ ---
416
+
417
+ ## Roadmap
418
+
419
+ - [ ] 优化 approval 菜单显示体验
420
+ - [ ] 增强搜索结果验证能力
421
+ - [ ] 优化网页正文提取效果
422
+ - [ ] 增加更多内置工具
423
+ - [ ] 支持更多模型服务商
424
+ - [ ] 完善自动化测试
425
+ - [ ] 增加 Docker 部署支持
426
+
427
+ ---
428
+
429
+ ## License
430
+
431
+ MIT
432
+ ```
433
+
434
+
435
+ ## `.gitignore`
436
+
437
+ ```gitignore
438
+ node_modules
439
+ dist
440
+ .env
441
+ ```
@@ -0,0 +1,46 @@
1
+ function formatToolsForPrompt(tools) {
2
+ if (tools.length === 0) {
3
+ return "- No tools available.";
4
+ }
5
+ return tools
6
+ .map((tool) => {
7
+ const risk = tool.riskLevel ?? "safe";
8
+ return `- ${tool.name} [${risk}]: ${tool.description}`;
9
+ })
10
+ .join("\n");
11
+ }
12
+ export function buildSystemPrompt(tools) {
13
+ return [
14
+ "You are a local CLI coding agent.",
15
+ "You do not have direct filesystem, shell, git, or network access unless you use the provided tools.",
16
+ "Use tools to inspect files, search code, read git state, fetch web content, write files, and run shell commands.",
17
+ "",
18
+ "CRITICAL OUTPUT RULES:",
19
+ "You must respond with exactly one JSON object and nothing else.",
20
+ "Do not output markdown.",
21
+ "Do not output code fences.",
22
+ "Do not output explanations outside the JSON object.",
23
+ "",
24
+ "Allowed response formats:",
25
+ '1. {"type":"tool_call","toolName":"<tool name>","args":{}}',
26
+ '2. {"type":"final","message":"<answer>"}',
27
+ '3. {"type":"ask_confirmation","message":"<question for the user>"}',
28
+ "",
29
+ "TOOL RULES:",
30
+ "- Use tools when you need real information from files, git, shell, or the web.",
31
+ "- Call at most one tool per response.",
32
+ "- Never invent tool results.",
33
+ "- If a tool is marked [confirm] or [dangerous], ask for confirmation before calling it.",
34
+ "- Prefer safe read-only inspection before making changes.",
35
+ "- If the task is complete, return a final response.",
36
+ "- Always return valid JSON.",
37
+ "",
38
+ "AVAILABLE TOOLS:",
39
+ formatToolsForPrompt(tools),
40
+ "",
41
+ "Examples:",
42
+ '{"type":"tool_call","toolName":"read_file","args":{"path":"package.json"}}',
43
+ '{"type":"ask_confirmation","message":"I need to overwrite README.md. Do you want me to continue?"}',
44
+ '{"type":"final","message":"I found the issue in src/main.ts and explained it."}',
45
+ ].join("\n");
46
+ }
@@ -0,0 +1 @@
1
+ export {};