x7-code-line
v1.2.0
Published
Install Cursor, Codex, and git hooks for x7 code line workflows.
Readme
x7-code-line
x7-code-line 是一个用于安装 Cursor、Codex 和 Git hooks 的 npm 模块。它用于在 agent 工作流中区分普通用户已有改动和 AI 生成改动,并在提交信息中自动追加 AI 行数 trailer。
功能概览
- 安装 Cursor 项目 hooks:写入当前安装目录的
.cursor/hooks.json。 - 安装 Codex 项目 hooks:写入当前安装目录的
.codex/hooks.json。 - 安装 Git hooks:为目标项目写入
.git/hooks/pre-commit和.git/hooks/commit-msg。 - 初始化中心缓存目录:写入当前安装目录的
.x7-code-line/。 - 支持多项目:多项目配置只用于替换目标项目的 Git hooks,以及在
prompt-submit/stop时遍历读取这些项目的git diff。 - 记录 prompt 前快照:prompt 提交时保存当前已编辑文件的快照,作为区分用户已有改动和 AI 后续改动的基线。
- 记录 AI diff 行:agent 结束时对比快照和当前文件,或回退读取
git diff,把 AI 新增行写入 DB 缓存。 - 计算提交 AI 行数:
pre-commit对比当前仓库 staged diff 和中心 AI 缓存,计算本次提交真实包含的 AI diff 行数。 - 写入 commit trailer:
commit-msg追加或替换x7-ai-lines: <数量>。
安装行为
安装基目录与目标项目
- 安装基目录:执行
x7-code-line install时所在的目录(或INIT_CWD/postinstall触发时的当前目录)。.cursor/、.codex/、.x7-code-line/只写在这里。 - 目标项目:通过
--dir/X7_CODE_LINE_DIRS配置的 Git 仓库目录。只为这些目录写入.git/hooks/*。
全局安装(npm install -g)
npm install -g x7-code-line这只更新全局 CLI 包(例如 Windows 下 %APPDATA%\npm\node_modules\x7-code-line\),不会自动写入任何项目或 baselib 下的 hooks。
全局安装完成后,需要进入安装基目录手动执行:
cd /path/to/install-base
x7-code-line install --dir /abs/path/repo-a [--dir /abs/path/repo-b ...]postinstall 自动安装
作为项目依赖安装,或带环境变量的全局安装时,postinstall 会尝试执行与 install 相同的逻辑。安装基目录取 INIT_CWD(执行 npm install 时所在的目录)。
只有在设置了 X7_CODE_LINE_DIRS 或 X7_CODE_LINE_CONFIG 时,postinstall 才会继续;否则直接 no-op,不写任何文件:
# macOS / Linux
X7_CODE_LINE_DIRS="/abs/repo-a:/abs/repo-b" npm install -g x7-code-line
# Windows PowerShell(在 install-base 目录下执行)
$env:X7_CODE_LINE_DIRS = "D:\repo-a;D:\repo-b"
npm install -g x7-code-lineinstall 会创建或覆盖
安装基目录:
.x7-code-line/install.json # 安装时间与 moduleRoot(每次 install 重写)
.x7-code-line/projects.json # 项目列表(install 整表替换,addDir 追加合并)
.cursor/hooks.json # 从模板复制
.codex/hooks.json # 按当前 OS / Node 路径动态生成(见下文)
~/.x7-code-line-base.json # 全局安装基指针目标项目(存在 .git 时):
.git/hooks/pre-commit
.git/hooks/commit-msginstall 不会清除的数据
以下文件若已存在,install 重装时保留:
.x7-code-line/line-id-cache.db中的 AI / normal / snapshot 缓存.x7-code-line/hook-state.json中的gitHooksEnabled开关.x7-code-line/x7-code-line.log等运行日志
版本升级
npm install -g x7-code-line@latest仅升级全局 CLI,不会更新 baselib 里的 install.json、.codex/hooks.json 等。判断方式:若 .x7-code-line/install.json 的 installedAt 仍是旧时间,说明安装基目录尚未刷新。
推荐升级流程:
npm install -g x7-code-line@latest
cd /path/to/install-base
x7-code-line install --dir /abs/path/repo-a [--dir ...]升级后若使用 Codex,请在 TUI 中执行 /hooks 重新 trust(hook 内容变更后 hash 会变)。
多项目配置只影响两类行为:
- 为配置中的项目目录替换
.git/hooks/pre-commit和.git/hooks/commit-msg。 - 执行
prompt-submit/stop时遍历配置中的项目目录读取git diff。
.cursor/hooks.json、.codex/hooks.json 和 .x7-code-line/ 只会写入当前安装目录,不会写入每个多项目目标目录。
Cursor Hooks
install 从模板复制 .cursor/hooks.json:
{
"version": 1,
"hooks": {
"beforeSubmitPrompt": [
{
"command": "npx --no-install x7-code-line prompt-submit"
}
],
"stop": [
{
"command": "npx --no-install x7-code-line stop"
}
]
}
}Cursor 与 Codex 的 hook schema 不同:Cursor 使用 beforeSubmitPrompt / stop;Codex 使用 UserPromptSubmit / Stop。
Codex Hooks
install 会动态生成 .codex/hooks.json(不是简单复制模板)。macOS / Linux 与 Windows 写法不同。
非 Windows(command 直接使用 npx)
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "npx --no-install x7-code-line prompt-submit",
"timeout": 30,
"statusMessage": "Logging UserPromptSubmit hook"
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "npx --no-install x7-code-line stop",
"timeout": 30,
"statusMessage": "Logging Stop hook"
}
]
}
]
}
}Windows(额外写入 commandWindows)
Codex hook 子进程的 PATH 通常比终端更短,直接 npx 可能找不到(Windows 上可执行文件为 npx.cmd)。install 在 Windows 上会额外生成 commandWindows:通过 cmd /c 把当前 node.exe 所在目录和 %APPDATA%\npm 加入 PATH 后再调用 npx。
{
"type": "command",
"command": "npx --no-install x7-code-line prompt-submit",
"commandWindows": "cmd /c \"set \"PATH=C:\\Program Files\\nodejs;C:\\Users\\you\\AppData\\Roaming\\npm;%PATH%\"&& npx --no-install x7-code-line prompt-submit\"",
"timeout": 30,
"statusMessage": "Logging UserPromptSubmit hook"
}实际路径由 install 时运行的 Node 决定(process.execPath 所在目录)。Codex 在 Windows 上优先使用 commandWindows;其他平台使用 command。
Codex 使用前注意
- Trust:非托管 command hook 需在 Codex TUI 中
/hooks审核并 trust,未 trust 的 hook 会被跳过。 - 项目 trust:项目级
.codex/hooks.json仅在项目.codex层被 trust 后加载。 - 启动目录:Codex 会话 cwd 应为安装基目录(或其中已配置的目标项目),否则可能加载不到 hooks。
- 升级后 re-trust:
install重写 hooks 后需重新 trust。
Codex hook 排查
| 现象 | 可能原因 |
|------|----------|
| .x7-code-line/x7-code-line.log 无任何输出 | hook 未 trust、未触发,或 npx/Node 在子进程中未启动 |
| 终端手动 npx --no-install x7-code-line prompt-submit 有 log | CLI 正常,问题在 Codex hook 执行环境 |
| install.json 的 installedAt 未更新 | 只做了 npm install -g,未在 install-base 执行 x7-code-line install |
探测 hook 是否执行(临时改 UserPromptSubmit 的 command / commandWindows):
"commandWindows": "cmd /c echo codex-hook-ran>> .x7-code-line\\codex-probe.txt"发一条 prompt 后检查 install-base/.x7-code-line/codex-probe.txt。有内容说明 hook 能跑,问题在 npx;无内容则查 trust / 加载路径。
调试日志路径:
<install-base>/.x7-code-line/x7-code-line.log设置 X7_CODE_LINE_DEBUG=1 可在 install / CLI 路径输出更多 [x7-code-line] 信息。
Diff 行缓存
AI 行标识缓存集中写入当前安装目录的 DB 文件:
.x7-code-line/line-id-cache.db该 DB 文件内部按逻辑 bucket 保存 ai-diff-line-ids.json、normal-diff-line-ids.json 和 snapshots.json 三类数据。AI 行标识缓存只读写该 DB 文件,不再读写旧的同名 JSON 缓存文件。
prompt-submit 会进入每个已缓存的项目目录,收集当前正在编辑的文件:
git diff --no-ext-diff --unified=0 --no-color
git diff --cached --no-ext-diff --unified=0 --no-color
git ls-files --others --exclude-standard -z随后把这些文件复制到 .x7-code-line/snapshots/ 下,并把快照索引写入 line-id-cache.db 的 snapshots.json bucket。同时,prompt-submit 会把当时已经存在的新增行记录写入 normal-diff-line-ids.json bucket,作为人工已有改动的基线。
stop 会读取 prompt 阶段保存的快照,使用以下命令对比快照文件和当前文件:
git diff --no-index --unified=0 --no-color <snapshot-file> <current-file>如果某个文件没有快照,stop 会回退读取当前项目的普通 diff,并包含未跟踪文件:
git diff --no-ext-diff --unified=0 --no-color
git ls-files --others --exclude-standard -z变更行会生成稳定记录。记录 ID 由以下信息生成:
- 项目绝对路径
- 文件路径
- 变更类型:
add或delete - 行内容 hash
- 同一项目、文件、变更类型和内容 hash 下的出现序号
stop 最终只保留 add 类型记录,并写入 line-id-cache.db 的 ai-diff-line-ids.json bucket。缓存按项目绝对路径分组,bucket 结构类似:
{
"projects": {
"/path/to/repo-a": [{ "content": "line-a" }],
"/path/to/repo-b": [{ "content": "line-b" }]
}
}提交时,pre-commit 会读取当前仓库的 staged diff:
git diff --cached --no-ext-diff --unified=0 --no-color然后使用不含出现序号的消费 key(项目绝对路径、文件路径、变更类型、行内容 hash)按多重集合扣除 normal-diff-line-ids.json bucket 中的人工基线记录,再对比 ai-diff-line-ids.json bucket 中的 AI 行记录,计算本次提交真正包含的 AI 新增行数。这样人工在 prompt 前新增了和 AI 相同内容的一行时,最终只提交人工行不会被误计为 AI 行。
Git Hooks
安装器会生成 shell hook,并写入中心缓存目录:
X7_CODE_LINE_BASE='<当前安装目录>'
export X7_CODE_LINE_BASE
npx --no-install x7-code-line git-pre-commitpre-commit 会读取当前仓库的 staged diff:
git diff --cached --no-ext-diff --unified=0 --no-color然后使用当前仓库绝对路径从中心缓存中取出对应项目的人工基线记录和 AI 行记录,通过不含出现序号的消费 key 先扣除人工基线,再计算本次提交真正包含的 AI diff 行数,并写入:
.x7-code-line/pending-commit.json计算完成后,只会从 line-id-cache.db 的 AI / normal bucket 中消费本次 staged diff 实际匹配到的记录:
ai-diff-line-ids.json
normal-diff-line-ids.json同一仓库中未 staged 的剩余 AI / normal 记录会保留,后续提交仍可继续统计。当前仓库的 snapshot 索引会在每次 pre-commit 后清理,避免提交边界后的旧快照把已提交行重新计算为 AI 行。其他项目的缓存不会被修改。
commit-msg 会读取该结果,并追加或替换 trailer:
x7-ai-lines: 3如果没有命中 AI diff 行,则写入:
x7-ai-lines: 0多项目安装
install 至少需要传入一个目录;0 目录场景会直接失败。默认要求绝对路径。
推荐:进入安装基目录后使用 CLI:
cd /path/to/install-base
x7-code-line install --dir /abs/path/repo-a --dir /abs/path/repo-bWindows 示例(install-base 在 C 盘,目标仓库在 D 盘):
cd C:\x7-tools\install-base
x7-code-line install --dir D:\work\repo-a --dir D:\work\repo-b相对路径必须显式传 --relative(基于当前目录解析):
cd /path/to/install-base
x7-code-line install --relative --dir ../repo-a --dir ../repo-b也可通过 postinstall + 环境变量 在 npm install -g 时自动安装(须先在 install-base 目录下执行,并设置目标目录):
cd /path/to/install-base
X7_CODE_LINE_DIRS="/abs/repo-a:/abs/repo-b" npm install -g x7-code-line若通过环境变量或配置文件传相对路径,需同时设置 X7_CODE_LINE_RELATIVE_PATHS=1。
macOS / Linux:
cd /path/to/install-base
X7_CODE_LINE_RELATIVE_PATHS=1 X7_CODE_LINE_DIRS="../repo-a:../repo-b" npm install -g x7-code-lineWindows(; 分隔):
cd C:\path\to\install-base
$env:X7_CODE_LINE_RELATIVE_PATHS = "1"
$env:X7_CODE_LINE_DIRS = "..\repo-a;..\repo-b"
npm install -g x7-code-line注意:npm install -g x7-code-line@latest 不带上述环境变量时,不会更新 install-base 内任何文件;升级 CLI 后仍需单独执行 x7-code-line install --dir ...。
配置文件
可以通过 --config 或 X7_CODE_LINE_CONFIG 指定 JSON 配置文件:
{
"dirs": ["../repo-a", "../repo-b"],
"gitDirs": [".git"]
}字段说明:
dirs:目标项目目录列表。install与addDir均可用;addDir可只传配置文件中的dirs,不必再写--dir。gitDirs:相对于每个目标项目目录的 Git 目录列表。
macOS 适配说明
macOS 下整体可以直接使用,但需要注意以下几点:
- Git hooks 使用
#!/bin/sh,macOS 自带/bin/sh,无需额外安装 shell。 - 安装器会对生成的 hook 文件执行
chmod 755。如果你手动复制 hook 文件,也需要执行:
chmod +x .git/hooks/pre-commit .git/hooks/commit-msg- macOS / Linux 的多项目环境变量使用
:分隔目录;不要使用 Windows 的;。 - Cursor / Codex hook 中的
npx:若从 GUI 启动而非终端,子进程可能拿不到 shell 的PATH,npx会找不到。优先从终端启动,或改用node绝对路径调用bin/x7-code-line.js。 - 使用 nvm / fnm / asdf 时,GUI 应用通常不会加载 shell 初始化脚本,Codex hook 里直接
npx失败较常见。可尝试:- 从终端启动 Codex;
- hook 使用 login shell 包装:
/bin/zsh -lc 'npx --no-install x7-code-line prompt-submit'; - 或在
~/.codex/config.toml中通过[shell_environment_policy]补充PATH(是否作用于 lifecycle hook 因 Codex 版本而异,建议以 probe 验证)。
- 如果项目路径包含空格,安装器生成的 Git hook 会对
X7_CODE_LINE_BASE做 shell quote,通常可以正常工作。
建议在 hook 环境中确认:
which node
which npm
which npxWindows 适配说明
- Git for Windows 会用 Git Bash 执行
.git/hooks/*,因此#!/bin/shhook 可以运行。 - PowerShell 下设置多项目环境变量时使用
$env:X7_CODE_LINE_DIRS。 - Windows 目录分隔符使用
;,例如:
$env:X7_CODE_LINE_DIRS = "D:\repo-a;D:\repo-b"npx在 Windows 上是npx.cmd,位于 Node 安装目录(如C:\Program Files\nodejs\npx.cmd),与node.exe同级。- Codex hook 子进程 PATH 不完整是 Windows 上 hook 静默失败的常见原因:hook 能执行(如
cmd /c echo ...有输出),但npx找不到,.x7-code-line/x7-code-line.log无任何内容。install已通过commandWindows+cmd /c补 PATH 缓解;若仍失败,可改为node绝对路径:
"commandWindows": "\"C:\\Program Files\\nodejs\\node.exe\" \"<moduleRoot>\\bin\\x7-code-line.js\" prompt-submit"<moduleRoot> 见 install-base/.x7-code-line/install.json。
增量添加目录
在已经完成安装的当前安装目录下,可以使用 addDir 增量添加新的项目目录:
x7-code-line addDir --dir /abs/path/repo-c
x7-code-line addDir --config /abs/path/add-dir.json--config 中的 dirs 与 --dir 会合并;仅传配置文件时,dirs 需写在 JSON 里。
这个命令只做两件事:
- 把新目录追加合并到
.x7-code-line/projects.json(不会删除已有项目) - 为新目录安装
.git/hooks/pre-commit和.git/hooks/commit-msg
它不会重写 install-base 的 .cursor/hooks.json、.codex/hooks.json 或 install.json。升级 hook 模板后请使用 install。
addDir 会沿用与 install 相同的严格校验:
- 目录必须真实存在
- 目录必须可访问
- 目录必须包含可用的
.git目录
任一新增目录不满足条件时,命令直接失败,不会继续追加。
默认只接受绝对路径;如果需要解析相对路径,需要显式传入:
x7-code-line addDir --relative --dir ../repo-cinstall 和 addDir 成功后,会输出:
[x7-code-line] D:\your-repo configured successfully.CLI 命令
x7-code-line install --dir <absolute-path> [--dir ...] [--config path] [--relative]
x7-code-line addDir --dir <absolute-path> [--dir ...] [--config path] [--relative]
x7-code-line enable # 启用已安装项目的 Git hooks
x7-code-line disable # 禁用已安装项目的 Git hooks
x7-code-line prompt-submit # Cursor beforeSubmitPrompt / Codex UserPromptSubmit
x7-code-line stop # Cursor stop / Codex Stop
x7-code-line git-pre-commit
x7-code-line git-commit-msg <commit-msg-file>Hook 别名(供编辑器直接调用):cursor-before-submit-prompt、codex-user-prompt-submit、cursor-stop、codex-stop。
prompt-submit 和 stop 执行时,会优先按以下顺序定位主目录中的 .x7-code-line 缓存:
X7_CODE_LINE_BASE- 当前目录本身的
.x7-code-line/install.json - 当前 Git 仓库
.git/hooks/pre-commit或.git/hooks/commit-msg中写入的X7_CODE_LINE_BASE INIT_CWD对应目录本身的.x7-code-line/install.json- 当前目录向上查找
.x7-code-line/install.json INIT_CWD向上查找.x7-code-line/install.json- 安装时写入的全局 base 指针
因此即使在其他目录手动执行命令,也会优先读取主目录缓存,而不是把执行目录当作缓存目录。
如果在目标 Git 项目中执行:
npx x7-code-line prompt-submit仍提示无法定位 install base,通常表示当前项目的 Git hooks 不是新版安装器生成的,或 hooks 中没有 X7_CODE_LINE_BASE。在主安装目录重新执行:
x7-code-line addDir --dir <absolute-path-to-git-repo>或直接显式传入:
X7_CODE_LINE_BASE=<install-base> npx x7-code-line prompt-submit本地验证
npm test
npm pack --dry-run发布到 npm
首次发布和后续更新都建议先在本地完成校验:
npm test
npm pack --dry-run确认当前登录的 npm 账号:
npm whoami如果还没有登录:
npm login首次发布
确认 package.json 中的包名和版本号正确后,执行:
npm publish --access public如果 npm 账号开启了 2FA,通常需要附带 OTP:
npm publish --otp <6位验证码>如果将来改为 scope 包并需要公开发布,则使用:
npm publish --access public --otp <6位验证码>更新已发布版本
每次发布新版本前,手动修改package.json版本号或命令提升版本号:
npm version patch也可以按需要使用:
npm version minor
npm version major然后重新发布:
npm publish --otp <6位验证码>常见发布流程
npm test
npm pack --dry-run
npm version patch
npm publish --otp <6位验证码>2FA 与 token
如果 npm 账号开启了两步验证,发布时需要满足以下任一条件:
- 直接在
npm publish时传入--otp。 - 使用具备 publish 权限并允许 bypass 2FA 的 npm access token。
手动在本机发布时,最直接的方式通常是:
npm publish --otp <当前验证码>