@ia-ccun/code-agent-cli 0.0.51 → 0.0.52-release

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 (37) hide show
  1. package/bin/cli.js +11 -10
  2. package/config/agent/extensions/aicode-advisor.ts +707 -0
  3. package/config/agent/extensions/aicode-btw.ts +2273 -0
  4. package/config/agent/extensions/aicode-plan.ts +903 -0
  5. package/config/agent/extensions/aicode-tips.ts +1 -2
  6. package/config/agent/extensions/bash-check.ts +1 -1
  7. package/config/agent/extensions/context-monitor.ts +1 -1
  8. package/config/agent/extensions/context.ts +3 -3
  9. package/config/agent/extensions/custom-footer.ts +22 -4
  10. package/config/agent/extensions/custom.ts +24 -20
  11. package/config/agent/extensions/error-monitor.ts +1 -1
  12. package/config/agent/extensions/goal.ts +450 -0
  13. package/config/agent/extensions/msg-debug.ts +49 -10
  14. package/config/agent/extensions/review.ts +3 -3
  15. package/config/agent/extensions/working-msg.ts +2 -2
  16. package/config/agent/help.md +25 -0
  17. package/config/agent/settings.json +0 -2
  18. package/dist/banner.d.ts +5 -1
  19. package/dist/banner.d.ts.map +1 -1
  20. package/dist/banner.js +106 -7
  21. package/dist/banner.js.map +1 -1
  22. package/dist/config-loader.d.ts +2 -0
  23. package/dist/config-loader.d.ts.map +1 -1
  24. package/dist/config-loader.js +81 -7
  25. package/dist/config-loader.js.map +1 -1
  26. package/dist/config.js +1 -1
  27. package/dist/config.js.map +1 -1
  28. package/dist/index.d.ts +1 -2
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/security-logger.d.ts +69 -0
  33. package/dist/security-logger.d.ts.map +1 -0
  34. package/dist/security-logger.js +178 -0
  35. package/dist/security-logger.js.map +1 -0
  36. package/package.json +18 -7
  37. package/scripts/postinstall.js +130 -50
@@ -3,7 +3,7 @@
3
3
  * Msg Debug Extension - Log LLM request/response messages to file
4
4
  *
5
5
  * This extension logs all requests and responses sent to/from the LLM provider
6
- * for debugging purposes. Logs are saved to ./.aicode-cli/debug-logs/
6
+ * for debugging purposes. Logs are saved to ~/.aicode-cli/logs/
7
7
  *
8
8
  * Features:
9
9
  * - Logs before_provider_request: messages, parameters, raw payload
@@ -13,9 +13,10 @@
13
13
  * - Session-based log files (one file per session)
14
14
  */
15
15
 
16
- import { appendFileSync, existsSync, mkdirSync } from "node:fs";
16
+ import { appendFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from "node:fs";
17
17
  import { join } from "node:path";
18
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
18
+ import os from "node:os";
19
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
19
20
 
20
21
  // 北京时间格式化函数 (UTC+8)
21
22
  function formatBeijingTime(date: Date = new Date()): string {
@@ -31,16 +32,39 @@ function formatDateStr(date: Date = new Date()): string {
31
32
  return `${year}-${month}-${day}`;
32
33
  }
33
34
 
34
- export default function (pi: ExtensionAPI) {
35
- // Create log directory in project root: ./.aicode-cli/debug-logs
36
- const logDir = join(process.cwd(), ".aicode-cli", "debug-logs");
37
- if (!existsSync(logDir)) {
38
- mkdirSync(logDir, { recursive: true });
35
+ // 日志目录配置(与 error-monitor.ts 保持一致)
36
+ const LOG_DIR = join(os.homedir(), ".aicode-cli", "logs");
37
+ const KEEP_DAYS = 2; // 保留最近2天
38
+
39
+ // 确保日志目录存在
40
+ function ensureLogDir(): void {
41
+ if (!existsSync(LOG_DIR)) {
42
+ mkdirSync(LOG_DIR, { recursive: true });
39
43
  }
40
-
44
+ }
45
+
46
+ // 清理过期日志文件
47
+ function cleanOldLogs(): void {
48
+ if (!existsSync(LOG_DIR)) return;
49
+ const now = new Date(new Date().toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" }));
50
+ for (const file of readdirSync(LOG_DIR)) {
51
+ if (!file.startsWith("llm-requests-") || !file.endsWith(".log")) continue;
52
+ const match = file.match(/llm-requests-(\d{4})-(\d{2})-(\d{2})\.log/);
53
+ if (!match) continue;
54
+ const fileDate = new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]));
55
+ const diffDays = Math.floor((now.getTime() - fileDate.getTime()) / (1000 * 60 * 60 * 24));
56
+ if (diffDays > KEEP_DAYS) {
57
+ unlinkSync(join(LOG_DIR, file));
58
+ }
59
+ }
60
+ }
61
+
62
+ export default function (pi: ExtensionAPI) {
63
+ ensureLogDir();
64
+ cleanOldLogs();
41
65
  // Format date as YYYY-MM-DD for daily log files
42
66
  const dateStr = formatDateStr();
43
- const logFile = join(logDir, `llm-requests-${dateStr}.log`);
67
+ const logFile = join(LOG_DIR, `llm-requests-${dateStr}.log`);
44
68
 
45
69
  // Filter to only log user and assistant messages
46
70
  const ALLOWED_ROLES = ["user", "assistant"];
@@ -125,6 +149,21 @@ ${JSON.stringify({ ...payload, messages: filteredMessages }, null, 2)}
125
149
  const timestamp = formatBeijingTime();
126
150
  const { response, usage, cached } = event;
127
151
 
152
+ // Check if response is defined
153
+ if (!response) {
154
+ const logEntry = `
155
+ ================================================================================
156
+ [${timestamp}] AFTER PROVIDER RESPONSE
157
+ ================================================================================
158
+ Cached: ${cached ? "YES" : "NO"}
159
+ Error: Response is undefined
160
+
161
+ ================================================================================
162
+ `;
163
+ appendFileSync(logFile, logEntry, "utf8");
164
+ return;
165
+ }
166
+
128
167
  const logEntry = `
129
168
  ================================================================================
130
169
  [${timestamp}] AFTER PROVIDER RESPONSE
@@ -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 "@mariozechner/pi-coding-agent";
31
- import { DynamicBorder, BorderedLoader } from "@mariozechner/pi-coding-agent";
32
- import { Container, type SelectItem, SelectList, Text } from "@mariozechner/pi-tui";
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 "@mariozechner/pi-coding-agent";
9
- import type { AssistantMessage } from "@mariozechner/pi-ai";
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";
@@ -4,6 +4,29 @@
4
4
 
5
5
  ---
6
6
 
7
+ ## 📖 帮助命令
8
+
9
+ 查看 aicode-cli 的使用帮助:
10
+
11
+ ```bash
12
+ /help
13
+ ```
14
+
15
+ 快速帮助:
16
+ - `/help` - 查看本完整文档
17
+ - `/models` - 查看模型列表
18
+ - `/tools` - 查看可用工具
19
+ - `/skill:<name>` - 激活指定技能
20
+ - `Ctrl+Alt+P` - 切换计划模式
21
+ - `/goal` - 设置持续目标
22
+
23
+ ---
24
+ # aicode-cli 使用指南
25
+
26
+ > 全面掌握 AI 编程助手的各项功能与配置
27
+
28
+ ---
29
+
7
30
  ## 目录
8
31
 
9
32
  1. [快速开始](#1-快速开始)
@@ -457,3 +480,5 @@ aicode-cli --verbose
457
480
  ---
458
481
 
459
482
  *世界那么哒 · AI 实践落地 @2026*
483
+
484
+ **作者**: xujianjiang
@@ -15,11 +15,9 @@
15
15
  "packages":[
16
16
  "npm:pi-subagents@0.17.1",
17
17
  "npm:pi-rewind@0.5.0",
18
- "npm:pi-btw@0.2.1",
19
18
  "npm:pi-mcp-adapter@2.4.0",
20
19
  "npm:@juicesharp/rpiv-todo",
21
20
  "npm:@juicesharp/rpiv-ask-user-question",
22
- "npm:@juicesharp/rpiv-advisor",
23
21
  "npm:@samfp/pi-memory@1.1.1"
24
22
  ],
25
23
  "memory": {
package/dist/banner.d.ts CHANGED
@@ -2,7 +2,11 @@
2
2
  * Banner 生成器 - AI Code Agent
3
3
  */
4
4
  declare let defaultBanner: string;
5
- export { defaultBanner };
5
+ /**
6
+ * 根据星期几轮转颜色主题
7
+ */
8
+ declare function getRotatedColorTheme(): string;
9
+ export { defaultBanner, getRotatedColorTheme };
6
10
  /**
7
11
  * 生成带颜色的 Banner
8
12
  * @param colorTheme 主题色 (hex 格式,如 #49bccf)
@@ -1 +1 @@
1
- {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../src/banner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,QAAA,IAAI,aAAa,QAAK,CAAC;AASvB,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,GAAE,MAAkB,GAAG,MAAM,CAGrE"}
1
+ {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../src/banner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,QAAA,IAAI,aAAa,QAAK,CAAC;AAoBvB;;GAEG;AACH,iBAAS,oBAAoB,IAAI,MAAM,CAGtC;AAED,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,CAAC;AAc/C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,GAAE,MAAkB,GAAG,MAAM,CA8FrE"}
package/dist/banner.js CHANGED
@@ -16,20 +16,28 @@ catch {
16
16
  // fallback
17
17
  defaultBanner = ``;
18
18
  }
19
- export { defaultBanner };
19
+ // 预置颜色主题 — 围绕 #49bccf 的渐变色(不同明度)
20
+ const COLOR_THEMES = [
21
+ { name: 'deep-cyan', hex: '#2e7d8c' }, // 周一 - 最深
22
+ { name: 'dark-cyan', hex: '#399aad' }, // 周二 - 深
23
+ { name: 'cyan', hex: '#49bccf' }, // 周三 - 基准色
24
+ { name: 'light-cyan', hex: '#5ec9db' }, // 周四 - 亮
25
+ { name: 'bright-cyan', hex: '#73d6e8' }, // 周五 - 最亮
26
+ { name: 'pale-cyan', hex: '#8ae3f0' }, // 周六 - 极亮
27
+ { name: 'faint-cyan', hex: '#a0f0f8' }, // 周日 - 最浅
28
+ ];
20
29
  /**
21
- * 生成带颜色的 Banner
22
- * @param colorTheme 主题色 (hex 格式,如 #49bccf)
30
+ * 根据星期几轮转颜色主题
23
31
  */
24
- export function generateBanner(colorTheme = '#49bccf') {
25
- const rgb = hexToRgb(colorTheme);
26
- return `\x1b[38;2;${rgb.r};${rgb.g};${rgb.b}m${defaultBanner}\x1b[0m`;
32
+ function getRotatedColorTheme() {
33
+ const dayOfWeek = new Date().getDay(); // 0=周日, 1=周一, ..., 6=周六
34
+ return COLOR_THEMES[dayOfWeek % COLOR_THEMES.length].hex;
27
35
  }
36
+ export { defaultBanner, getRotatedColorTheme };
28
37
  /**
29
38
  * 将 Hex 颜色转换为 RGB 对象
30
39
  */
31
40
  function hexToRgb(hex) {
32
- // 去掉 # 前缀
33
41
  hex = hex.replace('#', '');
34
42
  return {
35
43
  r: parseInt(hex.slice(0, 2), 16),
@@ -37,4 +45,95 @@ function hexToRgb(hex) {
37
45
  b: parseInt(hex.slice(4, 6), 16)
38
46
  };
39
47
  }
48
+ /**
49
+ * 生成带颜色的 Banner
50
+ * @param colorTheme 主题色 (hex 格式,如 #49bccf)
51
+ */
52
+ export function generateBanner(colorTheme = '#49bccf') {
53
+ // 如果传入 'random' 或 'rotate' 则使用按星期轮转的颜色
54
+ const theme = (colorTheme === 'random' || colorTheme === 'rotate') ? getRotatedColorTheme() : colorTheme;
55
+ const rgb = hexToRgb(theme);
56
+ const version = process.env.AICODE_CLI_VERSION || '';
57
+ const cwd = process.cwd().replace(process.env.HOME || process.env.USERPROFILE || '', '~');
58
+ const color = (text) => `\x1b[38;2;${rgb.r};${rgb.g};${rgb.b}m${text}\x1b[0m`;
59
+ const dim = (text) => `\x1b[2m${text}\x1b[0m`;
60
+ const bold = (text) => `\x1b[1m${text}\x1b[0m`;
61
+ // 去除 ANSI 转义码获取实际可见长度
62
+ const stripAnsi = (text) => text.replace(/\x1b\[[\d;]*m/g, '');
63
+ // 生成固定宽度的列(左侧用空格填充到指定宽度)
64
+ const padCol = (text, width) => {
65
+ const visible = stripAnsi(text).length;
66
+ return text + ' '.repeat(Math.max(0, width - visible));
67
+ };
68
+ // 列宽定义
69
+ const COL_WIDTH = 28; // 每列总宽度(命令 + 2空格 + 描述 + 填充)
70
+ // 生成一列文本(命令 + 2空格 + 描述,右侧空白补齐到固定宽度)
71
+ const col = (cmd, desc) => {
72
+ const text = `${cmd} ${desc}`;
73
+ return padCol(text, COL_WIDTH);
74
+ };
75
+ // 生成一行(1-3 列)
76
+ const row = (cmd1, desc1, cmd2, desc2, cmd3, desc3) => {
77
+ const c1 = col(cmd1, desc1);
78
+ const c2 = cmd2 && desc2 ? col(cmd2, desc2) : '';
79
+ const c3 = cmd3 && desc3 ? col(cmd3, desc3) : '';
80
+ return ` ${c1}${c2}${c3}`;
81
+ };
82
+ // 解析 banner.txt 为行数组
83
+ const bannerLines = defaultBanner.split('\n');
84
+ const maxBannerWidth = Math.max(...bannerLines.map(line => line.replace(/\x1b\[[\d;]*m/g, '').length));
85
+ // 右侧信息行 (参考 Claude Code 布局)
86
+ const infoLines = [
87
+ `${color(bold('AICODE CLI'))} ${dim(`v${version}`)}`,
88
+ `${dim('Dir:')} ${dim(cwd)}`,
89
+ ];
90
+ // 将 banner 和右侧信息合并为多行
91
+ const maxLines = Math.max(bannerLines.length, infoLines.length);
92
+ const headerLines = [];
93
+ for (let i = 0; i < maxLines; i++) {
94
+ const bannerLine = bannerLines[i] || '';
95
+ const infoLine = infoLines[i] || '';
96
+ if (i === 0) {
97
+ headerLines.push(`${bannerLine} ${infoLine}`);
98
+ }
99
+ else if (i < infoLines.length && bannerLine.trim() === '') {
100
+ // banner 的空白行填充信息
101
+ headerLines.push(`${' '.repeat(maxBannerWidth)} ${infoLine}`);
102
+ }
103
+ else if (i < bannerLines.length) {
104
+ headerLines.push(bannerLine);
105
+ }
106
+ else {
107
+ headerLines.push(`${' '.repeat(maxBannerWidth)} ${infoLine}`);
108
+ }
109
+ }
110
+ return [
111
+ headerLines.join('\n'),
112
+ '',
113
+ dim('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'),
114
+ dim(' 直接用自然语言描述需求即可 • 复杂任务先用 /plan 生成计划 • @文件路径 指定文件'),
115
+ dim('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'),
116
+ '',
117
+ bold(' 常用命令'),
118
+ row(color('/model'), '切换模型', color('/settings'), 'aicode设置', color('/compact'), '压缩上下文'),
119
+ row(color('/new'), '新会话', color('/reload'), '重载配置', color('/resume'), '恢复会话'),
120
+ row(color('/bugs'), '已知bug修复', color('/goal'), '目标导向', color('/plan'), '计划模式(只读)'),
121
+ '',
122
+ bold(' 常用提示词 (Prompts)'),
123
+ row(color('/workflow'), '六阶段工作流', color('/feat'), '新功能开发', color('/git-commit'), 'Git提交'),
124
+ row(color('/code-simplifier'), '代码简化', color('/init-project'), '项目初始化'),
125
+ '',
126
+ bold(' 常用技能 (Skills)'),
127
+ row(color('/code-review'), '代码审查', color('/skill-creator'), '创建技能', color('/commit'), 'Git提交'),
128
+ row(color('/frontend-design'), '前端设计', color('/brainstorming'), '头脑风暴'),
129
+ '',
130
+ bold(' 会话管理'),
131
+ row(color('/export'), '导出会话', color('/tree'), '浏览对话历史'),
132
+ '',
133
+ dim(' • npm i -g @ia-ccun/code-agent-cli • @文件路径 指定文件'),
134
+ '',
135
+ dim('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'),
136
+ '',
137
+ ].join('\n');
138
+ }
40
139
  //# sourceMappingURL=banner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"banner.js","sourceRoot":"","sources":["../src/banner.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,+BAA+B;AAC/B,IAAI,aAAa,GAAG,EAAE,CAAC;AACvB,IAAI,CAAC;IACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAClE,aAAa,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC;AAAC,MAAM,CAAC;IACP,WAAW;IACX,aAAa,GAAG,EAAE,CAAC;AACrB,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB,SAAS;IAC3D,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,aAAa,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,aAAa,SAAS,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,GAAW;IAC3B,UAAU;IACV,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAE3B,OAAO;QACL,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QAChC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QAChC,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;KACjC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../src/banner.ts"],"names":[],"mappings":"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"}
@@ -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;;GAEG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAgBrC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,SAAS,CAyBtC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAErC"}
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"}
@@ -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
- return homedir();
22
+ resolvedPath = homedir();
19
23
  }
20
- if (configDir.startsWith("~/")) {
21
- return join(homedir(), configDir.slice(2));
24
+ else if (configDir.startsWith("~/")) {
25
+ resolvedPath = join(homedir(), configDir.slice(2));
22
26
  }
23
- return configDir;
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;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,IAAI,YAAY,GAAqB,IAAI,CAAC;AAE1C;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,gCAAgC;IAChC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAEpD,IAAI,SAAS,EAAE,CAAC;QACd,aAAa;QACb,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,OAAO,OAAO,EAAE,CAAC;QACnB,CAAC;QACD,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;IAEvD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,YAAY,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,UAAU,EAAE,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,YAAY,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,qCAAqC;IACrC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,QAAQ,CAAC;IAEnD,OAAO,YAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE1F,IAAI,YAAY,GAAqB,IAAI,CAAC;AAE1C;;;GAGG;AACH,MAAM,UAAU,YAAY;IAC1B,gCAAgC;IAChC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAEpD,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,YAAoB,CAAC;QAEzB,aAAa;QACb,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,YAAY,GAAG,OAAO,EAAE,CAAC;QAC3B,CAAC;aAAM,IAAI,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACjC,YAAY,GAAG,SAAS,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,iBAAiB;YACjB,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAED,sBAAsB;QACtB,MAAM,UAAU,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;QAE3C,oBAAoB;QACpB,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,WAAW,CAAC,iBAAiB,CAAC,sBAAsB,EAAE;gBACpD,aAAa,EAAE,SAAS;gBACxB,cAAc,EAAE,UAAU;gBAC1B,MAAM,EAAE,kBAAkB;gBAC1B,MAAM,EAAE,4BAA4B;aACrC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACvC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC;QAED,+BAA+B;QAC/B,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,WAAW,CAAC,iBAAiB,CAAC,eAAe,EAAE;gBAC7C,aAAa,EAAE,SAAS;gBACxB,cAAc,EAAE,UAAU;gBAC1B,OAAO,EAAE,OAAO;gBAChB,MAAM,EAAE,6BAA6B;gBACrC,MAAM,EAAE,4BAA4B;aACrC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,gBAAgB,UAAU,eAAe,CAAC,CAAC;YACxD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,WAAW,CAAC,iBAAiB,CAAC,eAAe,EAAE;gBAC7C,aAAa,EAAE,SAAS;gBACxB,cAAc,EAAE,UAAU;gBAC1B,MAAM,EAAE,sBAAsB;gBAC9B,MAAM,EAAE,4BAA4B;aACrC,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACxC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;QAClD,CAAC;QAED,WAAW;QACX,WAAW,CAAC,iBAAiB,CAAC,eAAe,EAAE;YAC7C,aAAa,EAAE,SAAS;YACxB,cAAc,EAAE,UAAU;YAC1B,MAAM,EAAE,UAAU;SACnB,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;IAEvD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACvC,YAAY,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,UAAU,EAAE,CAAC;YAEnD,aAAa;YACb,WAAW,CAAC,iBAAiB,CAAC,WAAW,EAAE;gBACzC,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,IAAI;gBACb,aAAa,EAAE,IAAI;aACpB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa;YACb,QAAQ,CAAC,6BAA6B,EAAE,KAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAC9E,WAAW,CAAC,iBAAiB,CAAC,YAAY,EAAE;gBAC1C,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAG,KAAe,CAAC,OAAO;gBAC/B,MAAM,EAAE,sBAAsB;aAC/B,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAClB,YAAY,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;QACtC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,eAAe;QACf,WAAW,CAAC,iBAAiB,CAAC,WAAW,EAAE;YACzC,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,sBAAsB;SAC/B,CAAC,CAAC;QACH,YAAY,GAAG,EAAE,GAAG,aAAa,EAAE,CAAC;IACtC,CAAC;IAED,qCAAqC;IACrC,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,QAAQ,CAAC;IAEnD,OAAO,YAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
package/dist/config.js CHANGED
@@ -6,7 +6,7 @@
6
6
  export const defaultConfig = {
7
7
  name: 'aicode-cli',
8
8
  banner: '__default__', // 使用默认值
9
- themeColor: '#49bccf',
9
+ themeColor: 'rotate',
10
10
  configDir: '.aicode-cli'
11
11
  };
12
12
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,aAAa,EAAG,QAAQ;IAChC,UAAU,EAAE,SAAS;IACrB,SAAS,EAAE,aAAa;CACzB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH,MAAM,CAAC,MAAM,aAAa,GAAc;IACtC,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,aAAa,EAAG,QAAQ;IAChC,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,aAAa;CACzB,CAAC"}
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 '@mariozechner/pi-coding-agent';
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,+BAA+B,CAAC;AAG9C,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"}
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
- // 重新导出 pi-coding-agent 的核心功能
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;;;;;GAKG;AAEH,6BAA6B;AAC7B,cAAc,+BAA+B,CAAC;AAE9C,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"}
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"}