@ia-ccun/code-agent-cli 0.0.50 → 0.0.51-beta.10
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 +92 -12
- package/bin/cli.js +7 -7
- package/config/agent/agents/agent-example.md +88 -0
- package/config/agent/extensions/aicode-plan.ts +897 -0
- package/config/agent/extensions/aicode-tips.ts +16 -1
- package/config/agent/extensions/bash-check.ts +1 -1
- package/config/agent/extensions/context-monitor.ts +1 -1
- package/config/agent/extensions/context.ts +3 -3
- package/config/agent/extensions/custom-footer.ts +22 -3
- package/config/agent/extensions/custom.ts +24 -20
- package/config/agent/extensions/error-monitor.ts +4 -3
- package/config/agent/extensions/goal.ts +450 -0
- package/config/agent/extensions/msg-debug.ts +16 -1
- package/config/agent/extensions/review.ts +3 -3
- package/config/agent/extensions/working-msg.ts +2 -2
- package/config/agent/help.md +116 -19
- package/config/agent/settings.json +44 -5
- package/dist/config-loader.d.ts +2 -0
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +81 -7
- package/dist/config-loader.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/security-logger.d.ts +69 -0
- package/dist/security-logger.d.ts.map +1 -0
- package/dist/security-logger.js +178 -0
- package/dist/security-logger.js.map +1 -0
- package/package.json +17 -6
- package/scripts/postinstall.js +130 -50
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
* Note: PR review requires a clean working tree (no uncommitted changes to tracked files).
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
-
import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@
|
|
31
|
-
import { DynamicBorder, BorderedLoader } from "@
|
|
32
|
-
import { Container, type SelectItem, SelectList, Text } from "@
|
|
30
|
+
import type { ExtensionAPI, ExtensionContext, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
31
|
+
import { DynamicBorder, BorderedLoader } from "@earendil-works/pi-coding-agent";
|
|
32
|
+
import { Container, type SelectItem, SelectList, Text } from "@earendil-works/pi-tui";
|
|
33
33
|
import path from "node:path";
|
|
34
34
|
import { promises as fs } from "node:fs";
|
|
35
35
|
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* 自定义工作消息,格式类似 Claude Code: ✶ xxx… (时间 · tokens)
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { ExtensionAPI, TurnEndEvent } from "@
|
|
9
|
-
import type { AssistantMessage } from "@
|
|
8
|
+
import type { ExtensionAPI, TurnEndEvent } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
10
10
|
|
|
11
11
|
// 主题色 #49bccf
|
|
12
12
|
const accentColor = "\x1b[38;2;73;188;207m";
|
package/config/agent/help.md
CHANGED
|
@@ -31,6 +31,8 @@ npm install -g @ia-ccun/code-agent-cli
|
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
33
|
aicode-cli
|
|
34
|
+
# 或
|
|
35
|
+
aicode
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
### 基本对话
|
|
@@ -66,6 +68,15 @@ Ctrl+Q
|
|
|
66
68
|
Enter
|
|
67
69
|
```
|
|
68
70
|
|
|
71
|
+
### Git Worktree 支持
|
|
72
|
+
|
|
73
|
+
使用 `/skill:using-git-worktrees` 在多工作区间高效切换:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
/skill:using-git-worktrees
|
|
77
|
+
帮我创建一个新的 worktree 来开发登录功能
|
|
78
|
+
```
|
|
79
|
+
|
|
69
80
|
---
|
|
70
81
|
|
|
71
82
|
## 3. 核心命令
|
|
@@ -90,6 +101,13 @@ Enter
|
|
|
90
101
|
|
|
91
102
|
思考级别:`off` → `minimal` → `low` → `medium` → `high` → `xhigh`
|
|
92
103
|
|
|
104
|
+
### 技能相关
|
|
105
|
+
|
|
106
|
+
| 命令 | 说明 |
|
|
107
|
+
|------|------|
|
|
108
|
+
| `/skill:<name>` | 激活指定技能 |
|
|
109
|
+
| `/skills` | 列出所有可用技能 |
|
|
110
|
+
|
|
93
111
|
---
|
|
94
112
|
|
|
95
113
|
## 4. 快捷键
|
|
@@ -224,16 +242,71 @@ Skill 是预置的 AI 技能模块,针对特定场景优化。
|
|
|
224
242
|
|
|
225
243
|
### 可用 Skills
|
|
226
244
|
|
|
245
|
+
#### 代码开发
|
|
246
|
+
|
|
247
|
+
| Skill | 说明 | 激活方式 |
|
|
248
|
+
|-------|------|----------|
|
|
249
|
+
| `code-review` | 代码审查 | `/skill:code-review` |
|
|
250
|
+
| `refactor` | 代码重构 | `/skill:refactor` |
|
|
251
|
+
| `unit-test` | 单元测试 | `/skill:unit-test` |
|
|
252
|
+
| `test-driven-development` | 测试驱动开发 | `/skill:test-driven-development` |
|
|
253
|
+
| `frontend-design` | 前端设计 | `/skill:frontend-design` |
|
|
254
|
+
| `owasp-security` | OWASP 安全编码 | `/skill:owasp-security` |
|
|
255
|
+
|
|
256
|
+
#### Git 相关
|
|
257
|
+
|
|
258
|
+
| Skill | 说明 | 激活方式 |
|
|
259
|
+
|-------|------|----------|
|
|
260
|
+
| `commit` | Git 提交消息生成 | `/skill:commit` |
|
|
261
|
+
| `using-git-worktrees` | Git Worktree 管理 | `/skill:using-git-worktrees` |
|
|
262
|
+
|
|
263
|
+
#### 数据分析
|
|
264
|
+
|
|
265
|
+
| Skill | 说明 | 激活方式 |
|
|
266
|
+
|-------|------|----------|
|
|
267
|
+
| `csv-data-summarizer` | CSV 数据分析 | `/skill:csv-data-summarizer` |
|
|
268
|
+
| `design-md` | Markdown 设计文档 | `/skill:design-md` |
|
|
269
|
+
|
|
270
|
+
#### UI/UX 设计
|
|
271
|
+
|
|
272
|
+
| Skill | 说明 | 激活方式 |
|
|
273
|
+
|-------|------|----------|
|
|
274
|
+
| `ui-ux-pro-max` | UI/UX 专业设计 | `/skill:ui-ux-pro-max` |
|
|
275
|
+
| `impeccable/*` | 完美界面系列技能 | `/skill:impeccable:polish` 等 |
|
|
276
|
+
|
|
277
|
+
#### 多媒体
|
|
278
|
+
|
|
279
|
+
| Skill | 说明 | 激活方式 |
|
|
280
|
+
|-------|------|----------|
|
|
281
|
+
| `video-generation` | 视频生成 | `/skill:video-generation` |
|
|
282
|
+
| `aliyun-tts` | 阿里云 TTS | `/skill:aliyun-tts` |
|
|
283
|
+
| `xiaomi-tts` | 小米 TTS | `/skill:xiaomi-tts` |
|
|
284
|
+
|
|
285
|
+
#### 写作与内容
|
|
286
|
+
|
|
287
|
+
| Skill | 说明 | 激活方式 |
|
|
288
|
+
|-------|------|----------|
|
|
289
|
+
| `khazix-writer` | 公众号长文写作 | `/skill:khazix-writer` |
|
|
290
|
+
| `hv-analysis` | 横纵分析法深度研究 | `/skill:hv-analysis` |
|
|
291
|
+
|
|
292
|
+
#### 开发流程
|
|
293
|
+
|
|
294
|
+
| Skill | 说明 | 激活方式 |
|
|
295
|
+
|-------|------|----------|
|
|
296
|
+
| `brainstorming` | 头脑风暴 | `/skill:brainstorming` |
|
|
297
|
+
| `writing-plans` | 编写实施计划 | `/skill:writing-plans` |
|
|
298
|
+
| `executing-plans` | 执行计划 | `/skill:executing-plans` |
|
|
299
|
+
| `dispatching-parallel-agents` | 并行任务分发 | `/skill:dispatching-parallel-agents` |
|
|
300
|
+
| `systematic-debugning` | 系统性调试 | `/skill:systematic-debugging` |
|
|
301
|
+
| `verification-before-completion` | 完成前验证 | `/skill:verification-before-completion` |
|
|
302
|
+
|
|
303
|
+
#### 技能管理
|
|
304
|
+
|
|
227
305
|
| Skill | 说明 | 激活方式 |
|
|
228
306
|
|-------|------|----------|
|
|
229
|
-
|
|
|
230
|
-
|
|
|
231
|
-
|
|
|
232
|
-
| refactor | 代码重构 | `/skill:refactor` |
|
|
233
|
-
| unit-test | 单元测试 | `/skill:unit-test` |
|
|
234
|
-
| csv-data-summarizer | CSV 数据分析 | `/skill:csv-data-summarizer` |
|
|
235
|
-
| frontend-design | 前端设计 | `/skill:frontend-design` |
|
|
236
|
-
| ui-ux-pro-max | UI/UX 设计 | `/skill:ui-ux-pro-max` |
|
|
307
|
+
| `skill-creator` | 创建/编辑技能 | `/skill:skill-creator` |
|
|
308
|
+
| `session-learning` | 会话学习总结 | `/skill:session-learning` |
|
|
309
|
+
| `find-skills` | 查找技能 | `/skill:find-skills` |
|
|
237
310
|
|
|
238
311
|
### 使用方法
|
|
239
312
|
|
|
@@ -254,13 +327,11 @@ Prompt 是预置的工作流模板,用于特定任务。
|
|
|
254
327
|
|
|
255
328
|
| Prompt | 说明 |
|
|
256
329
|
|--------|------|
|
|
257
|
-
| `/bmad-init` | 初始化 BMAD 项目 |
|
|
258
330
|
| `/init-project` | 初始化新项目 |
|
|
259
331
|
| `/feat` | 新增功能开发流程 |
|
|
260
332
|
| `/git-commit` | Git 提交 |
|
|
261
|
-
| `/git-rollback` | Git 回滚 |
|
|
262
|
-
| `/git-worktree` | Git Worktree 管理 |
|
|
263
333
|
| `/workflow` | 复杂工作流 |
|
|
334
|
+
| `/code-simplifier` | 代码简化 |
|
|
264
335
|
|
|
265
336
|
### 使用示例
|
|
266
337
|
|
|
@@ -273,6 +344,9 @@ Prompt 是预置的工作流模板,用于特定任务。
|
|
|
273
344
|
|
|
274
345
|
# Git 提交
|
|
275
346
|
/git-commit
|
|
347
|
+
|
|
348
|
+
# 复杂工作流
|
|
349
|
+
/workflow
|
|
276
350
|
```
|
|
277
351
|
|
|
278
352
|
---
|
|
@@ -293,9 +367,11 @@ Prompt 是预置的工作流模板,用于特定任务。
|
|
|
293
367
|
|
|
294
368
|
| 主题 | 说明 |
|
|
295
369
|
|------|------|
|
|
296
|
-
|
|
|
297
|
-
|
|
298
|
-
|
|
370
|
+
| `catppuccin-mocha` | Catppuccin Mocha 暗色主题(推荐) |
|
|
371
|
+
|
|
372
|
+
### 自定义主题
|
|
373
|
+
|
|
374
|
+
主题文件位于 `~/.aicode-cli/agent/themes/`,可自定义颜色和样式。
|
|
299
375
|
|
|
300
376
|
---
|
|
301
377
|
|
|
@@ -320,6 +396,12 @@ Prompt 是预置的工作流模板,用于特定任务。
|
|
|
320
396
|
2. **先审后改**:重要修改前先让 AI 解释代码
|
|
321
397
|
3. **备份优先**:关键文件操作前手动备份
|
|
322
398
|
|
|
399
|
+
### Git 工作流
|
|
400
|
+
|
|
401
|
+
1. **使用 Worktree**:多分支并行开发时使用 Git Worktree
|
|
402
|
+
2. **规范提交**:使用 `/skill:commit` 生成规范提交消息
|
|
403
|
+
3. **代码审查**:重要变更使用 `/skill:code-review` 审查
|
|
404
|
+
|
|
323
405
|
---
|
|
324
406
|
|
|
325
407
|
## 10. 故障排除
|
|
@@ -328,10 +410,11 @@ Prompt 是预置的工作流模板,用于特定任务。
|
|
|
328
410
|
|
|
329
411
|
| 问题 | 解决方案 |
|
|
330
412
|
|------|----------|
|
|
331
|
-
| 启动慢 |
|
|
332
|
-
| 模型连接失败 | 核对 models.json
|
|
333
|
-
| 扩展不生效 | 运行 `/reload`
|
|
413
|
+
| 启动慢 | 检查网络连接,确认模型 API 可达 |
|
|
414
|
+
| 模型连接失败 | 核对 `models.json` 配置和 API Key |
|
|
415
|
+
| 扩展不生效 | 运行 `/reload` 重载配置 |
|
|
334
416
|
| Token 溢出 | 使用 `/clear` 清理上下文 |
|
|
417
|
+
| Skills 找不到 | 确认技能已安装到 `~/.aicode-cli/agent/skills/` |
|
|
335
418
|
|
|
336
419
|
### 详细模式
|
|
337
420
|
|
|
@@ -339,6 +422,12 @@ Prompt 是预置的工作流模板,用于特定任务。
|
|
|
339
422
|
aicode-cli --verbose
|
|
340
423
|
```
|
|
341
424
|
|
|
425
|
+
### 查看上下文
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
/context
|
|
429
|
+
```
|
|
430
|
+
|
|
342
431
|
---
|
|
343
432
|
|
|
344
433
|
## 附录
|
|
@@ -347,8 +436,8 @@ aicode-cli --verbose
|
|
|
347
436
|
|
|
348
437
|
| 变量 | 说明 |
|
|
349
438
|
|------|------|
|
|
350
|
-
| `AICODE_CLI_CONFIG_DIR` |
|
|
351
|
-
| `AICODE_CLI_CODING_AGENT_DIR` | Agent
|
|
439
|
+
| `AICODE_CLI_CONFIG_DIR` | 配置目录路径 |
|
|
440
|
+
| `AICODE_CLI_CODING_AGENT_DIR` | Agent 配置目录路径 |
|
|
352
441
|
|
|
353
442
|
### 命令行参数
|
|
354
443
|
|
|
@@ -359,6 +448,14 @@ aicode-cli --verbose
|
|
|
359
448
|
| `--model <name>` | 指定模型 |
|
|
360
449
|
| `--clear` | 启动时清理会话 |
|
|
361
450
|
|
|
451
|
+
### 相关资源
|
|
452
|
+
|
|
453
|
+
- **项目仓库**: https://github.com/ia-ccun/code-agent-cli
|
|
454
|
+
- **npm 包**: https://www.npmjs.com/package/@ia-ccun/code-agent-cli
|
|
455
|
+
- **pi-coding-agent**: 底层 Agent 框架
|
|
456
|
+
|
|
362
457
|
---
|
|
363
458
|
|
|
364
459
|
*世界那么哒 · AI 实践落地 @2026*
|
|
460
|
+
|
|
461
|
+
**作者**: xujianjiang
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"quietStartup":true,
|
|
3
|
+
"defaultProvider": "aicode",
|
|
4
|
+
"defaultModel": "qwen3.5-35b-a3b",
|
|
3
5
|
"theme":"light",
|
|
4
6
|
"extensions":[
|
|
5
7
|
"~/.aicode-cli/agent/extensions/bash-check.ts",
|
|
@@ -11,9 +13,46 @@
|
|
|
11
13
|
"~/.aicode-cli/agent/extensions/working-msg.ts"
|
|
12
14
|
],
|
|
13
15
|
"packages":[
|
|
14
|
-
"npm:pi-subagents",
|
|
15
|
-
"npm:pi-rewind",
|
|
16
|
-
"npm:pi-btw",
|
|
17
|
-
"npm:pi-mcp-adapter"
|
|
18
|
-
|
|
16
|
+
"npm:pi-subagents@0.17.1",
|
|
17
|
+
"npm:pi-rewind@0.5.0",
|
|
18
|
+
"npm:pi-btw@0.2.1",
|
|
19
|
+
"npm:pi-mcp-adapter@2.4.0",
|
|
20
|
+
"npm:@juicesharp/rpiv-todo",
|
|
21
|
+
"npm:@juicesharp/rpiv-ask-user-question",
|
|
22
|
+
"npm:@juicesharp/rpiv-advisor",
|
|
23
|
+
"npm:@samfp/pi-memory@1.1.1"
|
|
24
|
+
],
|
|
25
|
+
"memory": {
|
|
26
|
+
"localPath": "~/.aicode-cli/memory",
|
|
27
|
+
"lessonInjection": "selective",
|
|
28
|
+
"consolidationModel": "qwen3.5-35b-a3b"
|
|
29
|
+
},
|
|
30
|
+
"subagents": {
|
|
31
|
+
"agentOverrides": {
|
|
32
|
+
"scout": {
|
|
33
|
+
"model": "qwen3.5-35b-a3b"
|
|
34
|
+
},
|
|
35
|
+
"researcher": {
|
|
36
|
+
"model": "qwen3.5-35b-a3b"
|
|
37
|
+
},
|
|
38
|
+
"planner": {
|
|
39
|
+
"model": "qwen3.5-35b-a3b"
|
|
40
|
+
},
|
|
41
|
+
"worker": {
|
|
42
|
+
"model": "qwen3.5-35b-a3b"
|
|
43
|
+
},
|
|
44
|
+
"reviewer": {
|
|
45
|
+
"model": "qwen3.5-35b-a3b"
|
|
46
|
+
},
|
|
47
|
+
"context-builder": {
|
|
48
|
+
"model": "qwen3.5-35b-a3b"
|
|
49
|
+
},
|
|
50
|
+
"oracle": {
|
|
51
|
+
"model": "qwen3.5-35b-a3b"
|
|
52
|
+
},
|
|
53
|
+
"delegate": {
|
|
54
|
+
"model": "qwen3.5-35b-a3b"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
19
58
|
}
|
package/dist/config-loader.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 配置加载器
|
|
3
|
+
* 🔒 Security: Validate path to prevent path traversal attacks
|
|
3
4
|
*/
|
|
4
5
|
import type { AppConfig } from './config.js';
|
|
5
6
|
/**
|
|
6
7
|
* 获取配置目录
|
|
8
|
+
* 🔒 Security: Validate path to prevent path traversal attacks
|
|
7
9
|
*/
|
|
8
10
|
export declare function getConfigDir(): string;
|
|
9
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM7C;;;GAGG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAuErC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,SAAS,CA8CtC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAErC"}
|
package/dist/config-loader.js
CHANGED
|
@@ -1,26 +1,80 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 配置加载器
|
|
3
|
+
* 🔒 Security: Validate path to prevent path traversal attacks
|
|
3
4
|
*/
|
|
4
5
|
import { homedir } from 'os';
|
|
5
|
-
import { join } from 'path';
|
|
6
|
+
import { join, normalize, resolve, isAbsolute } from 'path';
|
|
6
7
|
import { existsSync, readFileSync } from 'fs';
|
|
7
8
|
import { defaultConfig } from './config.js';
|
|
9
|
+
import { logSecurity, logError, SecurityEventType, LogLevel } from './security-logger.js';
|
|
8
10
|
let cachedConfig = null;
|
|
9
11
|
/**
|
|
10
12
|
* 获取配置目录
|
|
13
|
+
* 🔒 Security: Validate path to prevent path traversal attacks
|
|
11
14
|
*/
|
|
12
15
|
export function getConfigDir() {
|
|
13
|
-
//
|
|
16
|
+
// 优先级:环境变量 > 命令行参数 (后续实现) > 默认值
|
|
14
17
|
const configDir = process.env.AICODE_CLI_CONFIG_DIR;
|
|
15
18
|
if (configDir) {
|
|
19
|
+
let resolvedPath;
|
|
16
20
|
// 展开环境变量中的路径
|
|
17
21
|
if (configDir === "~") {
|
|
18
|
-
|
|
22
|
+
resolvedPath = homedir();
|
|
19
23
|
}
|
|
20
|
-
if (configDir.startsWith("~/")) {
|
|
21
|
-
|
|
24
|
+
else if (configDir.startsWith("~/")) {
|
|
25
|
+
resolvedPath = join(homedir(), configDir.slice(2));
|
|
22
26
|
}
|
|
23
|
-
|
|
27
|
+
else if (isAbsolute(configDir)) {
|
|
28
|
+
resolvedPath = configDir;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// 相对路径:相对于当前工作目录
|
|
32
|
+
resolvedPath = resolve(configDir);
|
|
33
|
+
}
|
|
34
|
+
// 🔒 规范化路径(消除 .. 和 .)
|
|
35
|
+
const normalized = normalize(resolvedPath);
|
|
36
|
+
// 🔒 安全检查 1: 防止路径遍历
|
|
37
|
+
if (normalized.includes('..')) {
|
|
38
|
+
logSecurity(SecurityEventType.PATH_TRAVERSAL_BLOCKED, {
|
|
39
|
+
attemptedPath: configDir,
|
|
40
|
+
normalizedPath: normalized,
|
|
41
|
+
reason: 'Path contains ..',
|
|
42
|
+
action: 'Rejected and using default',
|
|
43
|
+
}, LogLevel.WARN);
|
|
44
|
+
console.warn('[安全警告] 配置路径包含 ..,使用默认值');
|
|
45
|
+
return join(homedir(), defaultConfig.configDir);
|
|
46
|
+
}
|
|
47
|
+
// 🔒 安全检查 2: 限制在家目录内(防止写入系统目录)
|
|
48
|
+
const homeDir = homedir();
|
|
49
|
+
if (!normalized.startsWith(homeDir)) {
|
|
50
|
+
logSecurity(SecurityEventType.PATH_VALIDATION, {
|
|
51
|
+
attemptedPath: configDir,
|
|
52
|
+
normalizedPath: normalized,
|
|
53
|
+
homeDir: homeDir,
|
|
54
|
+
reason: 'Path outside home directory',
|
|
55
|
+
action: 'Rejected and using default',
|
|
56
|
+
}, LogLevel.WARN);
|
|
57
|
+
console.warn(`[安全警告] 配置目录 (${normalized}) 在家目录外,使用默认值`);
|
|
58
|
+
return join(homedir(), defaultConfig.configDir);
|
|
59
|
+
}
|
|
60
|
+
// 🔒 安全检查 3: 确保是绝对路径
|
|
61
|
+
if (!isAbsolute(normalized)) {
|
|
62
|
+
logSecurity(SecurityEventType.PATH_VALIDATION, {
|
|
63
|
+
attemptedPath: configDir,
|
|
64
|
+
normalizedPath: normalized,
|
|
65
|
+
reason: 'Path is not absolute',
|
|
66
|
+
action: 'Rejected and using default',
|
|
67
|
+
}, LogLevel.WARN);
|
|
68
|
+
console.warn('[安全警告] 配置路径不是绝对路径,使用默认值');
|
|
69
|
+
return join(homedir(), defaultConfig.configDir);
|
|
70
|
+
}
|
|
71
|
+
// ✅ 路径验证通过
|
|
72
|
+
logSecurity(SecurityEventType.PATH_VALIDATION, {
|
|
73
|
+
attemptedPath: configDir,
|
|
74
|
+
normalizedPath: normalized,
|
|
75
|
+
action: 'Accepted',
|
|
76
|
+
});
|
|
77
|
+
return normalized;
|
|
24
78
|
}
|
|
25
79
|
return join(homedir(), defaultConfig.configDir);
|
|
26
80
|
}
|
|
@@ -37,12 +91,32 @@ export function loadConfig() {
|
|
|
37
91
|
const content = readFileSync(configPath, 'utf-8');
|
|
38
92
|
const userConfig = JSON.parse(content);
|
|
39
93
|
cachedConfig = { ...defaultConfig, ...userConfig };
|
|
94
|
+
// ✅ 记录配置加载成功
|
|
95
|
+
logSecurity(SecurityEventType.CONFIG_LOAD, {
|
|
96
|
+
path: configPath,
|
|
97
|
+
success: true,
|
|
98
|
+
hasUserConfig: true,
|
|
99
|
+
});
|
|
40
100
|
}
|
|
41
|
-
catch {
|
|
101
|
+
catch (error) {
|
|
102
|
+
// ❌ 记录配置解析错误
|
|
103
|
+
logError('Failed to parse config.json', error, { path: configPath });
|
|
104
|
+
logSecurity(SecurityEventType.CONFIG_ERROR, {
|
|
105
|
+
path: configPath,
|
|
106
|
+
error: error.message,
|
|
107
|
+
action: 'Using default config',
|
|
108
|
+
}, LogLevel.WARN);
|
|
42
109
|
cachedConfig = { ...defaultConfig };
|
|
43
110
|
}
|
|
44
111
|
}
|
|
45
112
|
else {
|
|
113
|
+
// ⚠️ 记录配置文件不存在
|
|
114
|
+
logSecurity(SecurityEventType.CONFIG_LOAD, {
|
|
115
|
+
path: configPath,
|
|
116
|
+
success: true,
|
|
117
|
+
exists: false,
|
|
118
|
+
action: 'Using default config',
|
|
119
|
+
});
|
|
46
120
|
cachedConfig = { ...defaultConfig };
|
|
47
121
|
}
|
|
48
122
|
// 设置环境变量,让 pi-coding-agent 使用我们的配置目录
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
* aicode-cli
|
|
3
3
|
* AI Coding Agent CLI
|
|
4
4
|
*
|
|
5
|
-
* 基于 @mariozechner/pi-coding-agent 的封装
|
|
6
5
|
*/
|
|
7
|
-
export * from '@
|
|
6
|
+
export * from '@earendil-works/pi-coding-agent';
|
|
8
7
|
export { defaultConfig, type AppConfig } from './config.js';
|
|
9
8
|
export { getConfig, getConfigDir, loadConfig } from './config-loader.js';
|
|
10
9
|
export { defaultBanner, generateBanner } from './banner.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iCAAiC,CAAC;AAGhD,OAAO,EAAE,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGzE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,10 +2,8 @@
|
|
|
2
2
|
* aicode-cli
|
|
3
3
|
* AI Coding Agent CLI
|
|
4
4
|
*
|
|
5
|
-
* 基于 @mariozechner/pi-coding-agent 的封装
|
|
6
5
|
*/
|
|
7
|
-
|
|
8
|
-
export * from '@mariozechner/pi-coding-agent';
|
|
6
|
+
export * from '@earendil-works/pi-coding-agent';
|
|
9
7
|
// 导出配置相关
|
|
10
8
|
export { defaultConfig } from './config.js';
|
|
11
9
|
export { getConfig, getConfigDir, loadConfig } from './config-loader.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iCAAiC,CAAC;AAEhD,SAAS;AACT,OAAO,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzE,YAAY;AACZ,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 安全日志模块
|
|
3
|
+
* 🔒 Security: Structured logging for security events
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 日志级别
|
|
7
|
+
*/
|
|
8
|
+
export declare enum LogLevel {
|
|
9
|
+
INFO = "info",
|
|
10
|
+
WARN = "warn",
|
|
11
|
+
ERROR = "error"
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 安全事件类型
|
|
15
|
+
*/
|
|
16
|
+
export declare enum SecurityEventType {
|
|
17
|
+
CONFIG_LOAD = "config_load",
|
|
18
|
+
CONFIG_ERROR = "config_error",
|
|
19
|
+
PATH_VALIDATION = "path_validation",
|
|
20
|
+
PATH_TRAVERSAL_BLOCKED = "path_traversal_blocked",
|
|
21
|
+
FILE_MODIFIED = "file_modified",
|
|
22
|
+
FILE_ACCESS = "file_access",
|
|
23
|
+
DEPENDENCY_CHECK = "dependency_check",
|
|
24
|
+
VERSION_CHECK = "version_check",
|
|
25
|
+
INSTALL_START = "install_start",
|
|
26
|
+
INSTALL_COMPLETE = "install_complete",
|
|
27
|
+
SYMLINK_CREATE = "symlink_create",
|
|
28
|
+
SUSPICIOUS_ACTIVITY = "suspicious_activity"
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 日志条目接口
|
|
32
|
+
*/
|
|
33
|
+
export interface LogEntry {
|
|
34
|
+
timestamp: string;
|
|
35
|
+
level: LogLevel;
|
|
36
|
+
event?: SecurityEventType;
|
|
37
|
+
message: string;
|
|
38
|
+
details?: Record<string, unknown>;
|
|
39
|
+
pid: number;
|
|
40
|
+
version?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 记录安全事件
|
|
44
|
+
* @param event 事件类型
|
|
45
|
+
* @param details 事件详情
|
|
46
|
+
* @param level 日志级别(默认 info)
|
|
47
|
+
*/
|
|
48
|
+
export declare function logSecurity(event: SecurityEventType, details: Record<string, unknown>, level?: LogLevel): void;
|
|
49
|
+
/**
|
|
50
|
+
* 记录错误
|
|
51
|
+
* @param message 错误消息
|
|
52
|
+
* @param error 错误对象
|
|
53
|
+
* @param context 上下文信息
|
|
54
|
+
*/
|
|
55
|
+
export declare function logError(message: string, error: Error, context?: Record<string, unknown>): void;
|
|
56
|
+
/**
|
|
57
|
+
* 获取日志文件路径
|
|
58
|
+
*/
|
|
59
|
+
export declare function getLogPaths(): {
|
|
60
|
+
security: string;
|
|
61
|
+
error: string;
|
|
62
|
+
dir: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* 清除旧日志(可选的维护功能)
|
|
66
|
+
* @param maxAge 最大保留天数(默认 30 天)
|
|
67
|
+
*/
|
|
68
|
+
export declare function rotateLogs(maxAge?: number): void;
|
|
69
|
+
//# sourceMappingURL=security-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-logger.d.ts","sourceRoot":"","sources":["../src/security-logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH;;GAEG;AACH,oBAAY,QAAQ;IAClB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,KAAK,UAAU;CAChB;AAED;;GAEG;AACH,oBAAY,iBAAiB;IAE3B,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAG7B,eAAe,oBAAoB;IACnC,sBAAsB,2BAA2B;IAGjD,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAG3B,gBAAgB,qBAAqB;IACrC,aAAa,kBAAkB;IAG/B,aAAa,kBAAkB;IAC/B,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;IAGjC,mBAAmB,wBAAwB;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyCD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,GAAE,QAAwB,GAC9B,IAAI,CAmBN;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI,CAuBN;AAoBD;;GAEG;AACH,wBAAgB,WAAW,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAM9E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,GAAE,MAAW,GAAG,IAAI,CAoBpD"}
|