@shelken/pi-co-authored-by 0.2.12 → 0.2.13

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": "@shelken/pi-co-authored-by",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "agent 执行 git commit 时自动追加 Co-Authored-By / Generated-By trailer",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/commit.ts CHANGED
@@ -30,9 +30,15 @@ export function wrapBashWithCommitHook(
30
30
  hooksDir: string,
31
31
  modelName: string,
32
32
  piVersion: string,
33
+ options?: {
34
+ generatorName?: string;
35
+ coAuthorEmail?: string;
36
+ },
33
37
  ): string {
34
- const coAuthor = `${CO_AUTHOR_NAME}: ${modelName} <noreply@pi.dev>`;
35
- const generatedBy = `${GENERATED_BY_NAME}: pi ${piVersion}`;
38
+ const generatorName = options?.generatorName || "pi";
39
+ const email = options?.coAuthorEmail || "noreply@pi.dev";
40
+ const coAuthor = `${CO_AUTHOR_NAME}: ${modelName} <${email}>`;
41
+ const generatedBy = `${GENERATED_BY_NAME}: ${generatorName} ${piVersion}`;
36
42
  const runPath = join(hooksDir, "run");
37
43
 
38
44
  return [
package/src/config.ts ADDED
@@ -0,0 +1,54 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+
5
+ export const DEFAULT_CO_AUTHOR_EMAIL = "noreply@pi.dev";
6
+
7
+ export function resolveGeneratorName(configDirName?: string | null): "omp" | "pi" {
8
+ return configDirName === ".omp" ? "omp" : "pi";
9
+ }
10
+
11
+ /**
12
+ * 从宿主 agent 目录读取配置邮箱。
13
+ * agentDir 由宿主 API(getAgentDir())注入,绝不自行拼接硬编码宿主路径。
14
+ * 任何缺失或解析失败均平滑回退默认邮箱,不抛错。
15
+ */
16
+ export function resolveCoAuthorEmail(
17
+ configDirName: string | null | undefined,
18
+ agentDir: string,
19
+ ): string {
20
+ const envEmail = process.env.PI_CO_AUTHORED_BY_EMAIL || process.env.CO_AUTHORED_BY_EMAIL;
21
+ if (envEmail?.trim()) return envEmail.trim();
22
+
23
+ const filename =
24
+ configDirName === ".omp" ? "config.yml" : configDirName === ".pi" ? "settings.json" : null;
25
+ if (!filename) return DEFAULT_CO_AUTHOR_EMAIL;
26
+
27
+ try {
28
+ const text = readFileSync(join(agentDir, filename), "utf8");
29
+ const match = text.match(/coAuthor[\s\S]*?email["':\s]+([^\s"',}]+)/);
30
+ return match?.[1]?.trim() || DEFAULT_CO_AUTHOR_EMAIL;
31
+ } catch {
32
+ return DEFAULT_CO_AUTHOR_EMAIL;
33
+ }
34
+ }
35
+
36
+ export function resolveHostVersion(
37
+ generatorName: "omp" | "pi",
38
+ fallbackVersion: string,
39
+ execFn?: (cmd: string) => string,
40
+ ): string {
41
+ try {
42
+ const raw = execFn
43
+ ? execFn(generatorName)
44
+ : execFileSync(generatorName, ["--version"], {
45
+ encoding: "utf8",
46
+ timeout: 1500,
47
+ stdio: ["ignore", "pipe", "ignore"],
48
+ });
49
+ const match = raw.match(/([0-9]+\.[0-9]+(?:\.[0-9]+[^\s]*)?)/);
50
+ return match?.[1] || fallbackVersion;
51
+ } catch {
52
+ return fallbackVersion;
53
+ }
54
+ }
package/src/index.ts CHANGED
@@ -1,14 +1,16 @@
1
1
  import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
- import { isToolCallEventType, VERSION } from "@earendil-works/pi-coding-agent";
2
+ import { CONFIG_DIR_NAME, getAgentDir, isToolCallEventType, VERSION } from "@earendil-works/pi-coding-agent";
3
3
  import {
4
4
  createCommitHookDirectory,
5
5
  removeCommitHookDirectory,
6
6
  wrapBashWithCommitHook,
7
7
  } from "./commit.ts";
8
+ import { resolveCoAuthorEmail, resolveGeneratorName, resolveHostVersion } from "./config.ts";
8
9
  import { isGitCommitCommand } from "./git-commit.ts";
9
10
 
10
11
  export default function (pi: ExtensionAPI) {
11
12
  let hooksDir: string | undefined;
13
+ let cachedHostVersion: string | undefined;
12
14
 
13
15
  function ensureHooksDir(): string {
14
16
  hooksDir ??= createCommitHookDirectory();
@@ -21,6 +23,7 @@ export default function (pi: ExtensionAPI) {
21
23
 
22
24
  pi.on("session_shutdown", async () => {
23
25
  removeCommitHookDirectory(hooksDir);
26
+ cachedHostVersion = undefined;
24
27
  hooksDir = undefined;
25
28
  });
26
29
 
@@ -32,11 +35,19 @@ export default function (pi: ExtensionAPI) {
32
35
  const model = ctx.model;
33
36
  const modelName = model ? (model.name || `${model.provider}/${model.id}`) : "unknown";
34
37
 
38
+ const generatorName = resolveGeneratorName(CONFIG_DIR_NAME);
39
+ const coAuthorEmail = resolveCoAuthorEmail(CONFIG_DIR_NAME, getAgentDir());
40
+ cachedHostVersion ??= resolveHostVersion(generatorName, VERSION);
41
+
35
42
  event.input.command = wrapBashWithCommitHook(
36
43
  event.input.command,
37
44
  ensureHooksDir(),
38
45
  modelName,
39
- VERSION,
46
+ cachedHostVersion,
47
+ {
48
+ generatorName,
49
+ coAuthorEmail,
50
+ },
40
51
  );
41
52
  });
42
53
  }