From 9399304e4f96f944e25601199a49b8efd6674ee2 Mon Sep 17 00:00:00 2001 From: jinku Date: Mon, 13 Apr 2026 18:19:02 -0700 Subject: [PATCH] Release 1.0.8 --- .codex-plugin/plugin.json | 2 +- CHANGELOG.md | 7 +++ package-lock.json | 4 +- package.json | 2 +- skills/adversarial-review/SKILL.md | 8 +-- skills/rescue/SKILL.md | 1 + skills/review/SKILL.md | 8 +-- tests/e2e/codex-skills-e2e.test.mjs | 79 +++++++++++++++++++++++++++++ tests/skills-contracts.test.mjs | 13 +++-- 9 files changed, 110 insertions(+), 14 deletions(-) diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index b0d7d8e..9737db3 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "cc", - "version": "1.0.7", + "version": "1.0.8", "description": "Claude Code Plugin for Codex. Delegate code reviews, investigations, and tracked tasks to Claude Code from inside Codex.", "author": { "name": "Sendbird, Inc.", diff --git a/CHANGELOG.md b/CHANGELOG.md index ecec9f2..473c966 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## v1.0.8 + +- Clarify the routing boundary between `$cc:review`, `$cc:adversarial-review`, and `$cc:rescue`, including the rule that ordinary code-review requests default to `review`, stronger scrutiny plus custom focus text belongs to `adversarial-review`, and rescue is only for Claude-owned follow-through work. +- Add E2E coverage that injects both review skills together and verifies the focus-text distinction is surfaced to the parent turn while the adversarial focus path still reaches Claude end to end. +- Refresh the macOS integration concurrency test so aggressive concurrent polling no longer flakes when some jobs finish slightly later than the initial polling window. +- Update development dependencies with the merged Dependabot patch bumps for `@types/node` and `globals`. + ## v1.0.7 - Add GitHub CI coverage across Windows, macOS, and Linux, with a portable cross-platform test suite plus Linux-only full integration/E2E coverage. diff --git a/package-lock.json b/package-lock.json index 83c5322..77c2748 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cc-plugin-codex", - "version": "1.0.7", + "version": "1.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cc-plugin-codex", - "version": "1.0.7", + "version": "1.0.8", "license": "Apache-2.0", "bin": { "cc-plugin-codex": "scripts/installer-cli.mjs" diff --git a/package.json b/package.json index 849ac31..5ba628c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cc-plugin-codex", - "version": "1.0.7", + "version": "1.0.8", "description": "Claude Code Plugin for Codex by Sendbird", "type": "module", "author": { diff --git a/skills/adversarial-review/SKILL.md b/skills/adversarial-review/SKILL.md index ef3df05..403852f 100644 --- a/skills/adversarial-review/SKILL.md +++ b/skills/adversarial-review/SKILL.md @@ -1,15 +1,17 @@ --- name: adversarial-review -description: 'Run a design-challenging Claude Code review of local git changes in this repository. Args: --wait, --background, --base , --scope , --model , [focus text]. Use when the user wants stronger scrutiny, tradeoff analysis, risky-change review, or custom review focus text.' +description: 'Run a design-challenging Claude Code review of local git changes in this repository. Args: --wait, --background, --base , --scope , --model , [focus text]. Use only when the user wants stronger scrutiny than a normal review, such as explicit tradeoff challenge, risky-change review, or custom focus text.' --- # Claude Code Adversarial Review Use this skill when the user wants Claude Code to challenge the implementation approach, design choices, assumptions, or tradeoffs in this repository. -Prefer `$cc:adversarial-review` over `$cc:review` when the change touches configuration, infrastructure, templating, rollout mechanics, migrations, safety controls, or "this should remove mismatch/drift" style refactors. -Use it even without extra focus text when the real question is "did this actually eliminate the risk or just move it around?" +Do not treat `$cc:adversarial-review` as the default review path. Use it only when the user explicitly wants stronger scrutiny than a normal code review. +Good triggers include requests to challenge the design, challenge tradeoffs, pressure-test a risky change, question whether a migration/config/template change really removed the risk, or honor custom focus text that asks for harsher review. If the user wants Claude Code to go beyond review and perform investigation, validation edits, or implementation work, route to `$cc:rescue` instead. +If the user asks for a local review plus a separate Claude background review and then wants the main Codex thread to aggregate the findings and apply fixes, keep the delegated Claude portion on `$cc:review` unless the user explicitly asks for the adversarial angle. +Unlike `$cc:review`, this skill accepts custom focus text after the flags. The moment the user wants to steer Claude toward a specific angle or risk question, prefer `$cc:adversarial-review`. Do not derive the companion path from this skill file or any cache directory. Always run the installed copy: `node "/scripts/claude-companion.mjs" adversarial-review ...` diff --git a/skills/rescue/SKILL.md b/skills/rescue/SKILL.md index 6a249fe..dbd2b98 100644 --- a/skills/rescue/SKILL.md +++ b/skills/rescue/SKILL.md @@ -14,6 +14,7 @@ Use this skill when the user wants Claude Code to investigate, implement, or con Prefer `$cc:rescue` when the user wants Claude Code to diagnose the issue, validate a risky change by actually editing or testing, apply fixes from a prior review, or carry a task forward across multiple steps. Do not use rescue for "just review this diff" unless the user also wants follow-through work beyond review findings. +Do not use rescue merely because the main Codex thread plans to fix things after combining its own review with a separate Claude review. Rescue is only the right delegation when Claude itself is supposed to investigate, edit, test, or otherwise own the follow-through work. Do not derive the companion path from this skill file or any cache directory. Always run the installed copy: `node "/scripts/claude-companion.mjs" task ...` diff --git a/skills/review/SKILL.md b/skills/review/SKILL.md index 3c41787..c6ef1f2 100644 --- a/skills/review/SKILL.md +++ b/skills/review/SKILL.md @@ -1,15 +1,17 @@ --- name: review -description: 'Run a standard Claude Code review of local git changes in this repository. Args: --wait, --background, --base , --scope , --model . Use for straightforward correctness-oriented diff review when the user wants findings only, not custom focus text, adversarial framing, or implementation work.' +description: 'Run a standard Claude Code review of local git changes in this repository. Args: --wait, --background, --base , --scope , --model . Use as the default path for ordinary code-review requests when the user did not explicitly ask for stronger adversarial scrutiny or for Claude to own the implementation work.' --- # Claude Code Review Use this skill when the user wants Claude Code to review the current working tree or a branch diff in this repository. -Choose `$cc:review` only for straightforward review requests where the user mainly wants correctness findings on the current diff. -If the user wants stronger challenge on design, rollout risk, migration risk, configuration behavior, template mismatch elimination, or any custom focus text, route to `$cc:adversarial-review` instead. +Use `$cc:review` as the default when the user asks for code review, asks you to have Claude review something, or wants a second review pass without explicitly asking for stronger adversarial scrutiny. +If the user asks for stronger challenge on design, tradeoffs, rollout risk, migration risk, configuration behavior, or provides custom review focus text, route to `$cc:adversarial-review` instead. If the user wants Claude Code to investigate, validate by changing code, or actually fix/implement something, route to `$cc:rescue` instead. +If the overall request is "you review it too, also ask Claude to review in the background, then you aggregate and fix it", keep the delegated Claude part on `$cc:review` unless the user explicitly asks for a harsher or more adversarial review. +`$cc:review` does not accept custom focus text. If the user wants to steer Claude toward a particular angle, question, subsystem, or risk area, that is a signal to use `$cc:adversarial-review` instead. Do not derive the companion path from this skill file or any cache directory. Always run the installed copy: `node "/scripts/claude-companion.mjs" review ...` diff --git a/tests/e2e/codex-skills-e2e.test.mjs b/tests/e2e/codex-skills-e2e.test.mjs index 8bd3ffa..99a881c 100644 --- a/tests/e2e/codex-skills-e2e.test.mjs +++ b/tests/e2e/codex-skills-e2e.test.mjs @@ -334,6 +334,23 @@ function buildSkillPrompt(name, skillPath, userRequest) { ].join("\n"); } +function buildMultiSkillPrompt(skills, userRequest) { + return [ + ...skills.flatMap(({ name, path: skillPath }) => { + const skillBody = fs.readFileSync(skillPath, "utf8").trim(); + return [ + "", + `${name}`, + `${skillPath}`, + skillBody, + "", + "", + ]; + }), + userRequest, + ].join("\n"); +} + function eventCreated(id) { return { type: "response.created", @@ -1846,6 +1863,68 @@ describe("Codex direct-skill E2E", () => { } }); + it("injects review-versus-adversarial focus routing guidance when both skills are available", async (t) => { + if (!codexAvailable()) { + t.skip("codex CLI is not available in this environment"); + return; + } + + const testEnv = createEnvironment(); + const workspaceDir = path.join(testEnv.rootDir, "focus-routing-workspace"); + fs.mkdirSync(workspaceDir, { recursive: true }); + setupGitWorkspace(workspaceDir); + fs.writeFileSync( + path.join(workspaceDir, "app.js"), + "export function value() {\n return 7;\n}\n", + "utf8" + ); + + const userRequest = + "$cc:review --wait --scope working-tree --model haiku focus on race conditions"; + const provider = startDirectSkillProvider({ + userRequest, + expectedNeedles: [ + "`$cc:review` does not accept custom focus text", + "Unlike `$cc:review`, this skill accepts custom focus text after the flags", + "keep the delegated Claude part on `$cc:review`", + ], + shellCommands: [ + `node ${JSON.stringify(COMPANION_SCRIPT)} adversarial-review --view-state on-success --scope working-tree --model haiku focus on race conditions`, + ], + cwd: workspaceDir, + }); + testEnv.providerPort = await provider.listen(); + installHooks(testEnv); + writeConfigToml(testEnv, testEnv.providerPort); + + try { + const execResult = await runCodexExec( + testEnv, + buildMultiSkillPrompt( + [ + { name: "cc:review", path: REVIEW_SKILL_PATH }, + { name: "cc:adversarial-review", path: ADVERSARIAL_REVIEW_SKILL_PATH }, + ], + userRequest + ), + { cwd: workspaceDir } + ); + + assert.equal(execResult.status, 0, execResult.stderr || execResult.stdout); + const finalMessage = fs.readFileSync(testEnv.outputFile, "utf8"); + assert.match(finalMessage, /Adversarial Review/); + + const claudeInvocations = readClaudeInvocations(testEnv.claudeLogFile); + assert.ok( + claudeInvocations.some((entry) => entry.prompt.includes("focus on race conditions")), + "focus-routing e2e should preserve the user focus text when the adversarial path is selected" + ); + } finally { + await provider.close(); + cleanupEnvironment(testEnv); + } + }); + it("routes $cc:adversarial-review --background through the built-in path with notification steering", async (t) => { if (!codexAvailable()) { t.skip("codex CLI is not available in this environment"); diff --git a/tests/skills-contracts.test.mjs b/tests/skills-contracts.test.mjs index 43355d8..8ac0ab1 100644 --- a/tests/skills-contracts.test.mjs +++ b/tests/skills-contracts.test.mjs @@ -22,9 +22,11 @@ test("review skills keep background execution outside the companion command", () const installedRootPattern = /\/scripts\/claude-companion\.mjs/i; assert.match(review, /Do not derive the companion path from this skill file or any cache directory/i); - assert.match(review, /Choose `\$cc:review` only for straightforward review requests where the user mainly wants correctness findings on the current diff/i); - assert.match(review, /If the user wants stronger challenge on design, rollout risk, migration risk, configuration behavior, template mismatch elimination, or any custom focus text, route to `\$cc:adversarial-review` instead/i); + assert.match(review, /Use `\$cc:review` as the default when the user asks for code review, asks you to have Claude review something, or wants a second review pass without explicitly asking for stronger adversarial scrutiny/i); + assert.match(review, /If the user asks for stronger challenge on design, tradeoffs, rollout risk, migration risk, configuration behavior, or provides custom review focus text, route to `\$cc:adversarial-review` instead/i); assert.match(review, /If the user wants Claude Code to investigate, validate by changing code, or actually fix\/implement something, route to `\$cc:rescue` instead/i); + assert.match(review, /If the overall request is "you review it too, also ask Claude to review in the background, then you aggregate and fix it", keep the delegated Claude part on `\$cc:review` unless the user explicitly asks for a harsher or more adversarial review/i); + assert.match(review, /`\$cc:review` does not accept custom focus text/i); assert.match(review, installedRootPattern); assert.match(review, /Treat `--wait` and `--background` as Codex-side execution controls only/i); assert.match(review, /Strip them before calling the companion command/i); @@ -63,9 +65,11 @@ test("review skills keep background execution outside the companion command", () assert.doesNotMatch(review, /claude-companion\.mjs" review \$ARGUMENTS/i); assert.match(adversarial, /Do not derive the companion path from this skill file or any cache directory/i); - assert.match(adversarial, /Prefer `\$cc:adversarial-review` over `\$cc:review` when the change touches configuration, infrastructure, templating, rollout mechanics, migrations, safety controls, or "this should remove mismatch\/drift" style refactors/i); - assert.match(adversarial, /Use it even without extra focus text when the real question is "did this actually eliminate the risk or just move it around\?"/i); + assert.match(adversarial, /Do not treat `\$cc:adversarial-review` as the default review path/i); + assert.match(adversarial, /Good triggers include requests to challenge the design, challenge tradeoffs, pressure-test a risky change, question whether a migration\/config\/template change really removed the risk, or honor custom focus text that asks for harsher review/i); assert.match(adversarial, /If the user wants Claude Code to go beyond review and perform investigation, validation edits, or implementation work, route to `\$cc:rescue` instead/i); + assert.match(adversarial, /If the user asks for a local review plus a separate Claude background review and then wants the main Codex thread to aggregate the findings and apply fixes, keep the delegated Claude portion on `\$cc:review` unless the user explicitly asks for the adversarial angle/i); + assert.match(adversarial, /Unlike `\$cc:review`, this skill accepts custom focus text after the flags/i); assert.match(adversarial, installedRootPattern); assert.match(adversarial, /Treat `--wait` and `--background` as Codex-side execution controls only/i); assert.match(adversarial, /Strip them before calling the companion command/i); @@ -111,6 +115,7 @@ test("rescue skill keeps --background and --wait as host-side controls only", () assert.match(rescue, /Do not derive the companion path from this skill file or any cache directory/i); assert.match(rescue, /Prefer `\$cc:rescue` when the user wants Claude Code to diagnose the issue, validate a risky change by actually editing or testing, apply fixes from a prior review, or carry a task forward across multiple steps/i); assert.match(rescue, /Do not use rescue for "just review this diff" unless the user also wants follow-through work beyond review findings/i); + assert.match(rescue, /Do not use rescue merely because the main Codex thread plans to fix things after combining its own review with a separate Claude review/i); assert.match(rescue, installedRootPattern); assert.match(rescue, /`--background` and `--wait` are Codex-side execution controls only/i); assert.match(rescue, /Never satisfy background rescue by launching `claude-companion\.mjs task` itself as a detached shell process/i);