@zhushanwen/pi-extension-logger 0.2.0 → 0.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhushanwen/pi-extension-logger",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Shared logging helper for Pi extensions — three-channel routing (AI realtime / audit / debug) (shared library, not a Pi extension - no install.mjs needed)",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -17,9 +17,10 @@
17
17
  "index.ts"
18
18
  ],
19
19
  "peerDependencies": {
20
- "@earendil-works/pi-coding-agent": "*"
20
+ "@earendil-works/pi-coding-agent": "^0.84.1"
21
21
  },
22
22
  "devDependencies": {
23
+ "@vitest/coverage-v8": "^4.1.9",
23
24
  "vitest": "^4.1.8"
24
25
  },
25
26
  "scripts": {
@@ -24,7 +24,7 @@ describe("extension-logger", () => {
24
24
  afterEach(() => {
25
25
  setPiHandle(undefined);
26
26
  vi.restoreAllMocks();
27
- // 还原环境变量,避免文件日志测试的 PI_EXT_DEBUG/PI_CODING_AGENT_DIR 泄漏到其它用例
27
+ // 还原环境变量,避免文件日志测试的 XYZ_AGENT_DEBUG/PI_CODING_AGENT_DIR 泄漏到其它用例
28
28
  process.env = { ...prevEnv };
29
29
  });
30
30
 
@@ -137,7 +137,7 @@ describe("extension-logger", () => {
137
137
  });
138
138
  });
139
139
 
140
- describe("PI_EXT_DEBUG 文件日志", () => {
140
+ describe("XYZ_AGENT_DEBUG 文件日志", () => {
141
141
  // 文件日志的 agentDir 通过 getAgentDir() 推导(读 PI_CODING_AGENT_DIR,
142
142
  // 默认 ~/.pi/agent)。设 PI_CODING_AGENT_DIR 到 tmpdir 子目录,与组 A 的
143
143
  // arch-boundary 改动(fileLog 用 getAgentDir())保持一致。
@@ -156,15 +156,15 @@ describe("extension-logger", () => {
156
156
  }
157
157
  });
158
158
 
159
- it("PI_EXT_DEBUG 未设时 debug 是 no-op(不抛错即可)", () => {
160
- delete process.env.PI_EXT_DEBUG;
159
+ it("XYZ_AGENT_DEBUG 未设时 debug 是 no-op(不抛错即可)", () => {
160
+ delete process.env.XYZ_AGENT_DEBUG;
161
161
  const logger = createLogger("test", pi);
162
162
  expect(() => logger.debug("no-op")).not.toThrow();
163
163
  });
164
164
 
165
165
  // ---- Suggestion #8:fileLog 实际写入路径 ----
166
- it("PI_EXT_DEBUG=1 时 debug 写入日志文件,内容含 [debug] 与序列化 data", () => {
167
- process.env.PI_EXT_DEBUG = "1";
166
+ it("XYZ_AGENT_DEBUG=1 时 debug 写入日志文件,内容含 [debug] 与序列化 data", () => {
167
+ process.env.XYZ_AGENT_DEBUG = "1";
168
168
  // 固定日期 → 文件名 <extName>-2026-08-01.log
169
169
  vi.setSystemTime(new Date("2026-08-01T12:34:56.789Z"));
170
170
 
@@ -187,8 +187,8 @@ describe("extension-logger", () => {
187
187
  expect(appendSpy).not.toHaveBeenCalled();
188
188
  });
189
189
 
190
- it("PI_EXT_DEBUG=1 时 warn 既写文件又走 appendEntry(文件内容含 [warn])", () => {
191
- process.env.PI_EXT_DEBUG = "1";
190
+ it("XYZ_AGENT_DEBUG=1 时 warn 既写文件又走 appendEntry(文件内容含 [warn])", () => {
191
+ process.env.XYZ_AGENT_DEBUG = "1";
192
192
  vi.setSystemTime(new Date("2026-08-01T12:34:56.789Z"));
193
193
 
194
194
  const logger = createLogger("warn-ext", pi);
@@ -204,8 +204,8 @@ describe("extension-logger", () => {
204
204
  expect(appendSpy).toHaveBeenCalledOnce();
205
205
  });
206
206
 
207
- it("PI_EXT_DEBUG=1 写失败(只读目录)不 throw", () => {
208
- process.env.PI_EXT_DEBUG = "1";
207
+ it("XYZ_AGENT_DEBUG=1 写失败(只读目录)不 throw", () => {
208
+ process.env.XYZ_AGENT_DEBUG = "1";
209
209
  vi.setSystemTime(new Date("2026-08-01T12:34:56.789Z"));
210
210
 
211
211
  // 已存在的 logs 目录改为只读,让 mkdirSync/appendFileSync 失败。
@@ -240,13 +240,13 @@ describe("extension-logger", () => {
240
240
  const [, entry] = appendSpy.mock.calls[0]!;
241
241
  // appendEntry payload 的 data 字段保留原对象(safeStringify 仅在文件日志路径用)
242
242
  expect(entry).toMatchObject({ level: "warn" });
243
- // 验证 safeStringify 的 fallback 分支:用 PI_EXT_DEBUG=1 触发 fileLog,
243
+ // 验证 safeStringify 的 fallback 分支:用 XYZ_AGENT_DEBUG=1 触发 fileLog,
244
244
  // 文件内 data 应是 String() 形式(含 [object Object] 或循环结构字符串)
245
245
  expect(() => JSON.stringify(cyclic)).toThrow(); // 对照:原对象确实不可序列化
246
246
  });
247
247
 
248
248
  it("BigInt:warn 不崩,文件日志路径走 String fallback", () => {
249
- process.env.PI_EXT_DEBUG = "1";
249
+ process.env.XYZ_AGENT_DEBUG = "1";
250
250
  const tmpAgentDir = mkdtempSync(join(tmpdir(), "pi-ext-bigint-"));
251
251
  process.env.PI_CODING_AGENT_DIR = tmpAgentDir;
252
252
  vi.setSystemTime(new Date("2026-08-01T12:34:56.789Z"));
package/src/index.ts CHANGED
@@ -10,7 +10,7 @@
10
10
  // 三层通道:
11
11
  // 1. AI 实时 → tool result / block reason(pi 原生,本模块不涉及)
12
12
  // 2. 事后排查 → pi.appendEntry(custom entry 不进 LLM 上下文,不显 TUI)
13
- // 3. 开发者调试 → 文件日志(PI_EXT_DEBUG=1 时写 ~/.pi/agent/logs/,默认 no-op)
13
+ // 3. 开发者调试 → 文件日志(XYZ_AGENT_DEBUG=1 时写 ~/.pi/agent/logs/,默认 no-op)
14
14
  //
15
15
  // notify(用户操作反馈)刻意不封装——它是 UI 决策,留给各 extension 在命令/视图层
16
16
  // 直接调 ctx.ui.notify。
@@ -38,7 +38,7 @@ export type LogLevel = "debug" | "warn" | "error";
38
38
  * 自建太重)。warn/error 走 appendEntry 持久化;debug 默认 no-op。
39
39
  */
40
40
  export interface ExtensionLogger {
41
- /** 开发调试日志。默认 no-op;PI_EXT_DEBUG=1 时写文件日志。不进 appendEntry。 */
41
+ /** 开发调试日志。默认 no-op;XYZ_AGENT_DEBUG=1 时写文件日志。不进 appendEntry。 */
42
42
  debug(msg: string, data?: unknown): void;
43
43
  /** 内部降级/竞态/IO 失败——appendEntry 持久化,不显 TUI,不进 LLM。 */
44
44
  warn(msg: string, data?: unknown): void;
@@ -178,7 +178,7 @@ function prefixMsg(extName: string, msg: string): string {
178
178
  /**
179
179
  * 写文件日志到 `<agentDir>/logs/<extName>-YYYY-MM-DD.log`。
180
180
  *
181
- * 仅在 PI_EXT_DEBUG 环境变量为 "1" 时写入(默认 no-op,生产环境零开销)。
181
+ * 仅在 XYZ_AGENT_DEBUG 环境变量为 "1" 时写入(默认 no-op,生产环境零开销)。
182
182
  * agentDir 通过 pi 的 SSOT `getAgentDir()` 推导(读
183
183
  * `PI_CODING_AGENT_DIR`/`${APP_NAME}_CODING_AGENT_DIR`,默认 `~/.pi/agent`),
184
184
  * 与其它 extension 的路径派生保持一致。
@@ -188,7 +188,7 @@ function prefixMsg(extName: string, msg: string): string {
188
188
  * 行可能交错(可接受——debug 日志不要求严格顺序)。
189
189
  */
190
190
  function fileLog(extName: string, level: LogLevel, msg: string, data?: unknown): void {
191
- if (process.env.PI_EXT_DEBUG !== "1") return;
191
+ if (process.env.XYZ_AGENT_DEBUG !== "1") return;
192
192
  try {
193
193
  const agentDir = getAgentDir();
194
194
  const logDir = join(agentDir, "logs");