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
1 change: 1 addition & 0 deletions internal-skills/cli-runtime/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Task defaults:
- Run the companion command as one blocking foreground shell-tool call, not as a background terminal/session.
- Do not request a shell session id, poll a shell session later, or return before the companion command exits.
- If the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call.
- When using `exec_command`, pass `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested task.` on that one call. Do not first try the companion command in the default network-disabled sandbox.
- If the parent supplied a non-empty parent thread id for background completion, allow at most one success-only `send_input` notification before finishing.
- Mention the tool name `send_input` literally when describing that notification path.
- Use the exact tool shape `send_input({ target: <parent-thread-id>, message: <steering-message> })`.
Expand Down
2 changes: 2 additions & 0 deletions internal-skills/review-runtime/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Foreground contract:
- Foreground command:
- `review --view-state on-success ...`
- `adversarial-review --view-state on-success ...`
- Run the companion command with `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested review.` Do not first try the companion command in the default network-disabled sandbox.
- Return companion stdout faithfully and do not add review execution commentary around it.

Background contract:
Expand All @@ -38,6 +39,7 @@ Background contract:
- run the companion command as one blocking foreground shell-tool call, not as a background terminal/session
- do not request a shell session id, poll a shell session later, or return before the companion command exits
- if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call
- when using `exec_command`, pass `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested review.` on that one call; do not first try the companion command in the default network-disabled sandbox
- use at most one `send_input` completion notification on success
- mention the tool name `send_input` literally in the child instructions
- use the exact tool shape `send_input({ target: <parent-thread-id>, message: <steering-message> })`
Expand Down
2 changes: 2 additions & 0 deletions skills/adversarial-review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Argument handling:
Foreground flow:
- Run:
`node "<plugin-root>/scripts/claude-companion.mjs" adversarial-review --view-state on-success <arguments with --wait/--background removed>`
- Run that companion command with `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested review.` Do not first try the companion command in the default network-disabled sandbox.
- Foreground adversarial review belongs to the main Codex thread. Do not spawn a review subagent, do not invoke a generic review-runner role, and do not proxy this foreground path through any background worker abstraction.
- Do not fall back to raw `claude`, `claude-code`, `claude review`, `bash -lc ...claude...`, or any other direct Claude CLI syntax when the companion path is available. The foreground syntax contract here is the resolved companion command above, not a hand-rolled Claude invocation.
- If the resolved companion command fails, surface that failure. Do not silently retry foreground adversarial review through a different CLI shape, a generic review runner, or a custom shell wrapper.
Expand Down Expand Up @@ -90,6 +91,7 @@ Background flow:
- run that command as one blocking foreground shell-tool call, not as a background terminal/session
- do not request a shell session id, poll a shell session later, or return before the companion command exits
- if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call
- when using `exec_command`, pass `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested review.` on that one call; do not first try the companion command in the default network-disabled sandbox
- include `--owner-session-id <owner-session-id>` only when the parent resolved a non-empty owner session id
- include `--job-id <reserved-job-id>` when the parent reserved one
- include the matching `--cwd <workspace-root>` whenever the command includes that reserved `--job-id`
Expand Down
1 change: 1 addition & 0 deletions skills/rescue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ Subagent launch:
- run that command as one blocking foreground shell-tool call, not as a background terminal/session
- do not request a shell session id, poll a shell session later, or return before the companion command exits
- if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call
- when using `exec_command`, pass `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested task.` on that one call; do not first try the companion command in the default network-disabled sandbox
- for foreground rescue only, tell the child to return that command's stdout text exactly, with no preamble, summary, code fence, trimming, normalization, or punctuation changes
- tell the child to ignore stderr progress chatter such as `[cc] ...` lines and preserve only the stdout-equivalent final result text
- if a parent thread id is provided for experimental background notification, allow one extra `send_input` call after a successful shell result and before finishing
Expand Down
2 changes: 2 additions & 0 deletions skills/review/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Argument handling:
Foreground flow:
- Run:
`node "<plugin-root>/scripts/claude-companion.mjs" review --view-state on-success <arguments with --wait/--background removed>`
- Run that companion command with `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested review.` Do not first try the companion command in the default network-disabled sandbox.
- Foreground review belongs to the main Codex thread. Do not spawn a review subagent, do not invoke a generic review-runner role, and do not proxy this foreground path through any background worker abstraction.
- Do not fall back to raw `claude`, `claude-code`, `claude review`, `bash -lc ...claude...`, or any other direct Claude CLI syntax when the companion path is available. The foreground syntax contract here is the resolved companion command above, not a hand-rolled Claude invocation.
- If the resolved companion command fails, surface that failure. Do not silently retry foreground review through a different CLI shape, a generic review runner, or a custom shell wrapper.
Expand Down Expand Up @@ -88,6 +89,7 @@ Background flow:
- run that command as one blocking foreground shell-tool call, not as a background terminal/session
- do not request a shell session id, poll a shell session later, or return before the companion command exits
- if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call
- when using `exec_command`, pass `sandbox_permissions: "require_escalated"` and the justification `Allow the Claude Code companion to contact the Claude API for this requested review.` on that one call; do not first try the companion command in the default network-disabled sandbox
- include `--owner-session-id <owner-session-id>` only when the parent resolved a non-empty owner session id
- include `--job-id <reserved-job-id>` when the parent reserved one
- include the matching `--cwd <workspace-root>` whenever the command includes that reserved `--job-id`
Expand Down
15 changes: 15 additions & 0 deletions tests/e2e/codex-skills-e2e.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,7 @@ function startMockProvider({
"Run that command as one blocking foreground shell-tool call, not as a background terminal or session.\n" +
"Do not request a shell session id, poll a shell session later, or return before the command exits.\n" +
"If the shell tool is exec_command, call it once in non-interactive mode and wait for exit in that same call.\n" +
"Use sandbox_permissions: \"require_escalated\" with a justification that allows the Claude Code companion to contact the Claude API. Do not first try the companion command in the default network-disabled sandbox.\n" +
"Return only that command's stdout text exactly.\n" +
"Ignore stderr progress chatter such as [cc] lines.\n" +
"If the tool output includes both stderr progress and a final stdout-style result, preserve only the final stdout-equivalent result text.\n" +
Expand Down Expand Up @@ -963,6 +964,18 @@ function startMockProvider({
"built-in child should be told to preserve the exact task text in the command"
);
}
assert.ok(
bodyText.includes("sandbox_permissions") && bodyText.includes("require_escalated"),
"built-in child should request targeted escalation for Claude API access"
);
assert.ok(
bodyText.includes("contact the Claude API"),
"built-in child should receive a scoped network justification"
);
assert.ok(
bodyText.includes("Do not first try the companion command in the default network-disabled sandbox."),
"built-in child should avoid the known ENOTFOUND first attempt"
);
assert.doesNotMatch(
bodyText,
/claude-companion\.mjs"\s+task\s+--background|claude-companion\.mjs"\s+task\s+--wait|claude-companion\.mjs\s+task\s+--background|claude-companion\.mjs\s+task\s+--wait/,
Expand Down Expand Up @@ -1812,6 +1825,7 @@ describe("Codex direct-skill E2E", () => {
"Run that command as one blocking foreground shell-tool call, not as a background terminal or session.\n" +
"Do not request a shell session id, poll a shell session later, or return before the command exits.\n" +
"If the shell tool is exec_command, call it once in non-interactive mode and wait for exit in that same call.\n" +
"Use sandbox_permissions: \"require_escalated\" with the justification Allow the Claude Code companion to contact the Claude API for this requested review. Do not first try the companion command in the default network-disabled sandbox.\n" +
"If the command succeeds and a parent thread id is available, send exactly this notification to the parent thread before finishing: " +
JSON.stringify(notificationMessage) + "\n" +
"Use that same sentence as your own final assistant message.\n" +
Expand Down Expand Up @@ -2025,6 +2039,7 @@ describe("Codex direct-skill E2E", () => {
"Run that command as one blocking foreground shell-tool call, not as a background terminal or session.\n" +
"Do not request a shell session id, poll a shell session later, or return before the command exits.\n" +
"If the shell tool is exec_command, call it once in non-interactive mode and wait for exit in that same call.\n" +
"Use sandbox_permissions: \"require_escalated\" with the justification Allow the Claude Code companion to contact the Claude API for this requested review. Do not first try the companion command in the default network-disabled sandbox.\n" +
"If the command succeeds and a parent thread id is available, send exactly this notification to the parent thread before finishing: " +
JSON.stringify(notificationMessage) + "\n" +
"Use that same sentence as your own final assistant message.\n" +
Expand Down
15 changes: 15 additions & 0 deletions tests/skills-contracts.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ test("internal runtime references keep the active-root and notification invarian
assert.match(reviewRuntime, /blocking foreground shell-tool call, not as a background terminal\/session/i);
assert.match(reviewRuntime, /Do not request a shell session id, poll a shell session later, or return before the companion command exits/i);
assert.match(reviewRuntime, /if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call/i);
assert.match(reviewRuntime, /`sandbox_permissions: "require_escalated"`/i);
assert.match(reviewRuntime, /contact the Claude API for this requested review/i);
assert.match(reviewRuntime, /Do not first try the companion command in the default network-disabled sandbox/i);
assert.match(reviewRuntime, /mention the tool name `send_input` literally/i);
assert.match(reviewRuntime, /exact tool shape `send_input\(\{ target: <parent-thread-id>, message: <steering-message> \}\)`/i);
assert.match(reviewRuntime, /do not silently drop the completion notification path when the parent provided a non-empty parent thread id/i);
Expand All @@ -64,6 +67,9 @@ test("internal runtime references keep the active-root and notification invarian
assert.match(rescueRuntime, /blocking foreground shell-tool call, not as a background terminal\/session/i);
assert.match(rescueRuntime, /Do not request a shell session id, poll a shell session later, or return before the companion command exits/i);
assert.match(rescueRuntime, /if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call/i);
assert.match(rescueRuntime, /`sandbox_permissions: "require_escalated"`/i);
assert.match(rescueRuntime, /contact the Claude API for this requested task/i);
assert.match(rescueRuntime, /Do not first try the companion command in the default network-disabled sandbox/i);
assert.match(rescueRuntime, /allow at most one success-only `send_input` notification before finishing/i);
assert.match(rescueRuntime, /Mention the tool name `send_input` literally/i);
assert.match(rescueRuntime, /exact tool shape `send_input\(\{ target: <parent-thread-id>, message: <steering-message> \}\)`/i);
Expand Down Expand Up @@ -115,6 +121,9 @@ test("review skills keep background execution outside the companion command", ()
assert.match(review, /blocking foreground shell-tool call, not as a background terminal\/session/i);
assert.match(review, /Do not request a shell session id, poll a shell session later, or return before the companion command exits/i);
assert.match(review, /if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call/i);
assert.match(review, /`sandbox_permissions: "require_escalated"`/i);
assert.match(review, /contact the Claude API for this requested review/i);
assert.match(review, /do not first try the companion command in the default network-disabled sandbox/i);
assert.match(review, /allow one extra `send_input` call after a successful shell result/i);
assert.match(review, /must mention the tool name `send_input` literally/i);
assert.match(review, /must target the provided parent thread id/i);
Expand Down Expand Up @@ -169,6 +178,9 @@ test("review skills keep background execution outside the companion command", ()
assert.match(adversarial, /blocking foreground shell-tool call, not as a background terminal\/session/i);
assert.match(adversarial, /Do not request a shell session id, poll a shell session later, or return before the companion command exits/i);
assert.match(adversarial, /if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call/i);
assert.match(adversarial, /`sandbox_permissions: "require_escalated"`/i);
assert.match(adversarial, /contact the Claude API for this requested review/i);
assert.match(adversarial, /do not first try the companion command in the default network-disabled sandbox/i);
assert.match(adversarial, /allow one extra `send_input` call after a successful shell result/i);
assert.match(adversarial, /must mention the tool name `send_input` literally/i);
assert.match(adversarial, /must target the provided parent thread id/i);
Expand Down Expand Up @@ -255,6 +267,9 @@ test("rescue skill documents the experimental built-in-agent forwarding path", (
assert.match(rescue, /blocking foreground shell-tool call, not as a background terminal\/session/i);
assert.match(rescue, /Do not request a shell session id, poll a shell session later, or return before the companion command exits/i);
assert.match(rescue, /if the available shell tool is `exec_command`, call it once in non-interactive mode and wait for command exit in that same call/i);
assert.match(rescue, /`sandbox_permissions: "require_escalated"`/i);
assert.match(rescue, /contact the Claude API for this requested task/i);
assert.match(rescue, /do not first try the companion command in the default network-disabled sandbox/i);
assert.match(rescue, /prefer these steering messages over embedding the raw result text/i);
assert.match(rescue, /do not embed the raw Claude result inside the notification message/i);
assert.match(rescue, /do not include any other prose in that notification message/i);
Expand Down