Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,15 @@ jobs:
with:
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 0
# setup-node@v5 默认 package-manager-cache=true,看到 pnpm-lock.yaml 就找
# pnpm 来确定 cache 目录;所以 pnpm/action-setup 必须先于 setup-node。
# PR #7 dogfood 揭示的第 4 个 bug(无 pnpm → setup-node 报 'Unable to
# locate executable file: pnpm')。
- uses: pnpm/action-setup@v5
- uses: actions/setup-node@v5
with:
node-version: '22'
cache: pnpm

- name: Resolve PR number from workflow_run
id: pr
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ coverage/
*.tsbuildinfo
packages/*/.teamagent/
.teamagent/
# Required-mode hook generated by `teamagent init`(与 .teamagent/required.json 同流程,
# 同样应忽略;之前漏了让 CI 的「Working tree must be clean」检查炸。issue #3 Gap 2 dogfood 揭示。)
.claude/hooks/check-teamagent.sh
.worktrees/
.claude/worktrees/
.codex/worktrees/
Expand Down
11 changes: 10 additions & 1 deletion packages/cli/src/__tests__/codex-hooks-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ function findRepoRoot(): string {
const repoRoot = findRepoRoot();
const hooksJsonPath = path.join(repoRoot, ".codex", "hooks.json");

// Matrix baseline 是 history-stripped fork(2026-05-14),没把 TeamBrain 的
// .codex/ 目录(Codex CLI hook adapter,issue #290 范围)带过来。本测试套件
// 来自上游,但 target 文件不存在,在 Matrix 上跑会 7 个全挂 ENOENT。
//
// 用 describe.skipIf 自适应:.codex/hooks.json 存在 → 测试激活(TeamBrain 路径);
// 不存在 → 整个 describe block 跳过(Matrix 路径)。无须 Matrix 维护这套 fixture,
// 也无须删测试丢上游 contract 文档。issue #3 Gap 2 收尾。
const codexHooksExist = existsSync(hooksJsonPath);

interface CodexHookEntry {
matcher?: string;
hooks: Array<{ type: string; command: string; timeout?: number }>;
Expand All @@ -50,7 +59,7 @@ function loadConfig(): CodexHooksConfig {
return JSON.parse(readFileSync(hooksJsonPath, "utf8")) as CodexHooksConfig;
}

describe(".codex/hooks.json (issue #290)", () => {
describe.skipIf(!codexHooksExist)(".codex/hooks.json (issue #290)", () => {
it("registers SessionStart, PreToolUse, and Stop events", () => {
const cfg = loadConfig();
expect(Object.keys(cfg.hooks).sort()).toEqual([
Expand Down
30 changes: 19 additions & 11 deletions scripts/review/post-pr-comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,33 @@ function parseArgv(argv: string[]): CliOpts {
}

function postOrUpdateComment(pr: number, body: string): void {
// 找现有的 marker 评论
const list = spawnSync("gh", ["pr", "view", String(pr), "--json", "comments"], { encoding: "utf-8" });
if (list.status !== 0) throw new Error(`gh pr view 失败: ${list.stderr}`);
const parsed = JSON.parse(list.stdout) as { comments?: Array<{ id?: string; body?: string }> };
const comments = parsed.comments ?? [];
const repo = process.env["GITHUB_REPOSITORY"];
if (!repo) throw new Error("GITHUB_REPOSITORY env 未设");
// 一定要走 REST API 列评论 —— `gh pr view --json comments` 返回的是 GraphQL
// node id (IC_kwDOI...),不能喂给 `gh api /repos/.../issues/comments/{id}`
// 的 PATCH(那个要 REST integer id),否则 404。本 session PR #7 v2 翻车
// 揭示的 bug;PR #2/#4 每个 PR 只跑过一次 → 只走 CREATE 路径 → 没暴露。
const list = spawnSync("gh", [
"api", `repos/${repo}/issues/${pr}/comments?per_page=100`,
], { encoding: "utf-8" });
if (list.status !== 0) throw new Error(`list comments 失败: ${list.stderr}`);
const comments = JSON.parse(list.stdout) as Array<{ id?: number; body?: string }>;
const existing = comments.find((c) => (c.body ?? "").startsWith(COMMENT_MARKER));
if (existing && existing.id) {
// gh 不直接支持 update comment,用 API
const repo = process.env["GITHUB_REPOSITORY"];
if (!repo) throw new Error("GITHUB_REPOSITORY env 未设");
if (existing && existing.id !== undefined) {
const r = spawnSync("gh", [
"api", "--method", "PATCH",
`repos/${repo}/issues/comments/${existing.id}`,
"-f", `body=${body}`,
], { encoding: "utf-8" });
if (r.status !== 0) throw new Error(`update comment 失败: ${r.stderr}`);
} else {
const r = spawnSync("gh", ["pr", "comment", String(pr), "--body", body], { encoding: "utf-8" });
if (r.status !== 0) throw new Error(`gh pr comment 失败: ${r.stderr}`);
// 也走 REST API 保持对称(REST ids → 下次能正确 UPDATE)。
const r = spawnSync("gh", [
"api", "--method", "POST",
`repos/${repo}/issues/${pr}/comments`,
"-f", `body=${body}`,
], { encoding: "utf-8" });
if (r.status !== 0) throw new Error(`create comment 失败: ${r.stderr}`);
}
}

Expand Down
Loading