@shelken/pi-co-authored-by 0.2.9 → 0.2.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 CHANGED
@@ -7,13 +7,14 @@ Co-Authored-By: <model> <noreply@pi.dev>
7
7
  Generated-By: pi <version>
8
8
  ```
9
9
 
10
- 实现:bash 期间在真实 hooks 目录临时安装 `prepare-commit-msg`(不改 `core.hooksPath`);pid 引用计数,shell 退出时最后一个引用卸装并恢复原 hook。
10
+ 实现:识别 bash 命令中直接执行的 `git commit`(支持常见前缀与组合,脚本内间接 commit 不算),将命令交给外部 runner 在真实 hooks 目录临时安装 `prepare-commit-msg`(不改 `core.hooksPath`);pid 引用计数,shell 退出时最后一个引用卸装并恢复原 hook。非 commit 命令原样放行,不影响其他扩展。
11
11
 
12
12
  初始 fork 自 [bruno-garcia/pi-co-authored-by](https://github.com/bruno-garcia/pi-co-authored-by)。
13
13
 
14
14
  ## 功能
15
15
 
16
16
  - 只挂钩 `bash` 工具调用
17
+ - 只处理直接执行的 `git commit`;`printf`、`git status`、脚本内 commit 等一律不改
17
18
  - 模型名取当前 session;没有则 `unknown`
18
19
  - 与仓库已有 hook 兼容(先跑临时 hook,再链式原 hook)
19
20
 
package/index.ts CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  removeCommitHookDirectory,
6
6
  wrapBashWithCommitHook,
7
7
  } from "./lib/commit.ts";
8
+ import { isGitCommitCommand } from "./lib/git-commit.ts";
8
9
 
9
10
  export default function (pi: ExtensionAPI) {
10
11
  let hooksDir: string | undefined;
@@ -25,6 +26,8 @@ export default function (pi: ExtensionAPI) {
25
26
 
26
27
  pi.on("tool_call", async (event, ctx) => {
27
28
  if (!isToolCallEventType("bash", event)) return;
29
+ // 只包装直接执行的 git commit;其他命令原样放行,避免影响其他扩展
30
+ if (!isGitCommitCommand(event.input.command)) return;
28
31
 
29
32
  const model = ctx.model;
30
33
  const modelName = model ? (model.name || `${model.provider}/${model.id}`) : "unknown";
package/lib/commit.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
1
+ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
 
@@ -8,9 +8,10 @@ export const GENERATED_BY_NAME = "Generated-By";
8
8
  /** Create a session-scoped Git hooks directory for commit trailer injection. */
9
9
  export function createCommitHookDirectory(): string {
10
10
  const hooksDir = mkdtempSync(join(tmpdir(), "pi-co-authored-by-hooks-"));
11
- const hookPath = join(hooksDir, "prepare-commit-msg");
12
- writeFileSync(hookPath, buildPrepareCommitMsgHook(), { mode: 0o755 });
13
- chmodSync(hookPath, 0o755);
11
+ writeFileSync(join(hooksDir, "prepare-commit-msg"), buildPrepareCommitMsgHook(), {
12
+ mode: 0o755,
13
+ });
14
+ writeFileSync(join(hooksDir, "run"), buildRunnerScript(), { mode: 0o755 });
14
15
  return hooksDir;
15
16
  }
16
17
 
@@ -21,8 +22,8 @@ export function removeCommitHookDirectory(hooksDir: string | undefined): void {
21
22
  }
22
23
 
23
24
  /**
24
- * 注入 trailer 元数据,并在当前仓库临时安装 prepare-commit-msg。
25
- * 不设置 core.hooksPath,避免污染 git config;shell 退出时恢复原 hook。
25
+ * 用外部 runner 包裹 git commit:其他改写器只能看到不可拆的 wrapper 调用,
26
+ * 不会二次解析内部 shell;元数据经环境变量传入,命令作为单个引号参数。
26
27
  */
27
28
  export function wrapBashWithCommitHook(
28
29
  cmd: string,
@@ -32,19 +33,20 @@ export function wrapBashWithCommitHook(
32
33
  ): string {
33
34
  const coAuthor = `${CO_AUTHOR_NAME}: ${modelName} <noreply@pi.dev>`;
34
35
  const generatedBy = `${GENERATED_BY_NAME}: pi ${piVersion}`;
35
-
36
- return `${buildEnvironmentPrefix(hooksDir, coAuthor, generatedBy)}\n${cmd}`;
36
+ const runPath = join(hooksDir, "run");
37
+
38
+ return [
39
+ `PI_CO_AUTHORED_BY_CO_AUTHOR=${shellQuote(coAuthor)}`,
40
+ `PI_CO_AUTHORED_BY_GENERATED_BY=${shellQuote(generatedBy)}`,
41
+ shellQuote(runPath),
42
+ shellQuote(cmd),
43
+ ].join(" ");
37
44
  }
38
45
 
39
- function buildEnvironmentPrefix(
40
- hooksDir: string,
41
- coAuthor: string,
42
- generatedBy: string,
43
- ): string {
44
- const hookSrc = join(hooksDir, "prepare-commit-msg");
45
- return `export PI_CO_AUTHORED_BY_CO_AUTHOR=${shellQuote(coAuthor)}
46
- export PI_CO_AUTHORED_BY_GENERATED_BY=${shellQuote(generatedBy)}
47
- export PI_CO_AUTHORED_BY_HOOK_SRC=${shellQuote(hookSrc)}
46
+ function buildRunnerScript(): string {
47
+ return `#!/bin/bash
48
+ # PI_CO_AUTHORED_BY_RUNNER
49
+ export PI_CO_AUTHORED_BY_HOOK_SRC="$(dirname "$0")/prepare-commit-msg"
48
50
 
49
51
  __pi_co_authored_by_installed_hooks=""
50
52
 
@@ -152,7 +154,10 @@ __pi_co_authored_by_ensure_hook
152
154
  git() {
153
155
  __pi_co_authored_by_ensure_hook
154
156
  command git "$@"
155
- }`;
157
+ }
158
+
159
+ eval "$1"
160
+ `;
156
161
  }
157
162
 
158
163
  function buildPrepareCommitMsgHook(): string {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shelken/pi-co-authored-by",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "agent 执行 git commit 时自动追加 Co-Authored-By / Generated-By trailer",
5
5
  "type": "module",
6
6
  "license": "MIT",