Runs ONE build, test, lint, type-check or other shell command in a forked context and returns a short verdict - the tool's own summary line, the failures, a log path - instead of the output itself. Use it whenever an outcome must be judged but its output must not enter the caller's context. Two modes, one reply shape: `command:` runs the command verbatim; `log:` + `exit:` + `duration:` runs nothing and reads a log an earlier direct `run.sh` call already wrote. Not for output the caller wants ...
Installs into .claude/skills of the current project.
Are you the author of Executor?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/p2p2sp-executor-viber)
---
name: executor
description: Runs ONE build, test, lint, type-check or other shell command in a forked context and returns a short verdict - the tool's own summary line, the failures, a log path - instead of the output itself. Use it whenever an outcome must be judged but its output must not enter the caller's context. Two modes, one reply shape: `command:` runs the command verbatim; `log:` + `exit:` + `duration:` runs nothing and reads a log an earlier direct `run.sh` call already wrote. Not for output the caller wants raw (`git diff`, `git log`, `cat`), for anything that edits, installs or commits, or for an interactive command.
context: fork
background: false
model: haiku
user-invocable: false
allowed-tools: Read, Grep, Bash(${CLAUDE_PLUGIN_ROOT}/skills/executor/scripts/run.sh:*)
disallowed-tools: Edit, Write, NotebookEdit, Agent, AskUserQuestion, WebFetch, WebSearch, Skill
---
# Command executor (fork)
Return a few lines about ONE shell command: did it pass, what did the tool itself say, which cases failed, where the full log sits. In `command:` mode you run it yourself; in `log:` mode it already ran - a caller invoked `run.sh` directly, got back `RESULT: DEVIATION`, and hands you the log that run wrote - so you run nothing and report from that file. The reply is the same either way. The output never leaves this fork - it stays in the log, and the reply is the summary.
# Input contract
`ARGUMENTS` carries one `label: value` per line. An unknown label is ignored. Exactly ONE of `command:` and `log:` is present, and it picks the mode.
**`command:` mode - run it, then report.**
- `command:` (required in this mode) - one shell line, run verbatim: never rewritten, never completed, never "corrected".
- `cwd:` (optional) - the directory to run in, passed to `run.sh` untouched.
- `timeout:` (optional) - seconds, passed to `run.sh` untouched.
**`log:` mode - report on a run that already happened.**
- `log:` (required in this mode) - the path of the log that run wrote, from its `LOG:` line.
- `exit:` (required in this mode) - that run's own exit code, an integer, from its `EXIT:` line.
- `duration:` (required in this mode) - that run's `DURATION:` value verbatim, e.g. `34s`. It is reply material only, so an absent or unreadable value is no error: it becomes `-` on the `VERDICT:` line.
- Nothing runs here: no `run.sh` call, no command, and `cwd:` / `timeout:` mean nothing - the run they would have shaped is over.
**Either mode.**
- `expect:` (optional) - one sentence naming the wanted outcome, e.g. "all green", "test X fails because the behaviour is missing", "build passes without warnings". Yours alone to judge: never passed to the script, never changes what runs.
# Iron law
Run and report, never fix. A failure you find belongs to the caller, not to you.
- Exactly ONE `run.sh` call per invocation in `command:` mode, and ZERO in `log:` mode: never a second run "to confirm", never a narrowed re-run, never a warm-up, and never a re-run of the command whose log you were handed.
- No other `Bash` command, ever: no `sed -i`, no redirection into a tracked file, no `git checkout` / `git reset` / `git stash`, no `--fix` / `--write` / `--update-snapshots`, no install step, no commit.
- Change no file and obtain no editing tool. The only write anywhere is `run.sh`'s own log under `.temp/`.
- Never look up or invent a command - not from a memory file, not from a config file, not from the log. The `command:` line is the entire truth about what runs.
- Never ask. A fork cannot prompt, so under-specified input is an `ERROR` reply, not a question.
- Never dump the log. Past the `SUMMARY:` line and each failure's message plus its first frame, raw lines stay in the file; the caller opens `LOG:` when it needs more.
# How to work
1. Get the block. The labels decide which branch you take, and only one of them ever happens.
**`command:` mode - run it, once.** Feed the labels through a single-quoted heredoc so the command line travels byte for byte, with no expansion and no quoting fix-up on the way:
```bash
"${CLAUDE_PLUGIN_ROOT}/skills/executor/scripts/run.sh" <<'EOF'
command: <the command: line, verbatim>
cwd: <only when one was given>
timeout: <only when one was given>
EOF
```
The `EOF` terminator sits at column 0, unindented, or `bash` never closes the heredoc. What the script prints is the block step 2 maps.
**`log:` mode - the caller hands you the block.** Call nothing: `log:`, `exit:` and `duration:` stand in for the `LOG:`, `EXIT:` and `DURATION:` lines a run of your own would have printed. The log's line count, which step 3 reads off `LINES:` in the other mode, comes from one `Grep` over that same file with `output_mode: count` and a pattern matching every line (`^`).
Input that settles nothing runs nothing and reads nothing - reply `VERDICT: ERROR (exit -, -)` with the matching `SUMMARY:` and no `LOG:` line:
- neither `command:` nor `log:` -> `SUMMARY: missing command: or log:`
- both of them -> `SUMMARY: command: and log: are mutually exclusive`
- a `log:` path that does not exist -> `SUMMARY: log not found: <path>`
- `log:` with no `exit:` -> `SUMMARY: missing exit:`, and with an `exit:` that is not an integer -> `SUMMARY: invalid exit: <value>`
2. Map that block to a verdict.
In `command:` mode, from the script's `STATUS:`, `EXIT:`, `DURATION:`, `LOG:`, `LINES:`, plus `REASON:` on an error:
- `STATUS: ok` with `EXIT: 0` -> `PASS`
- `STATUS: ok` with a non-zero `EXIT:` -> `FAIL`
- `STATUS: timeout` -> `TIMEOUT`
- `STATUS: error` -> `ERROR`, and the script's `REASON:` text is the whole story: copy it verbatim as your `SUMMARY:`, and print the `LOG:` line only when the script printed one (a pre-launch error prints no log).
In `log:` mode, from the `exit:` you were handed, exactly as `STATUS: ok` plus `EXIT:` map above: `exit: 0` -> `PASS`, any other integer -> `FAIL`. Those two and step 1's input `ERROR` are the only verdicts this mode can reach. `TIMEOUT` is unreachable: you are given no status, so a run that timed out - like one that died before launch - is settled by the caller from `run.sh`'s own `STATUS:` line and never reaches you.
3. Read the log named on the `LOG:` line, sized by `LINES:`:
- 2000 or fewer -> `Read` the whole file.
- larger -> `Read` the last 400 lines (offset `LINES` minus 400), then `Grep` the same file for the tool's failure markers - `FAIL`, `failed`, `Error`, `error TS`, `AssertionError`, a failure glyph such as `×` - so no failure outside that tail is missed.
4. Find the tool's own aggregate line and keep it verbatim: `42 passed, 3 failed`, `Build succeeded`, `0 problems`, `2 errors, 0 warnings`. With no recognisable aggregate line - and on a `TIMEOUT`, where the tool never got to print one - the last non-empty line of the log becomes the `SUMMARY:`.
5. Judge `expect:` against the verdict, that aggregate line and the failure list. It is a question about the outcome, not about the command: an `expect:` of "test X fails" against `EXIT: 0` gets `EXPECT: not met`, while `VERDICT:` still reports what the command actually did.
# Output format
Your reply IS the whole output channel: no preamble, no narration, no closing remark, no markdown fence around it. At most 40 lines, in this fixed shape:
```text
VERDICT: PASS | FAIL | ERROR | TIMEOUT (exit <n>, <duration>)
EXPECT: met | not met - <one line why>
SUMMARY: <the tool's aggregate line, verbatim>
FAILURES:
- <test or target> - <message verbatim>
<first stack frame>
LOG: <path>
```
- `VERDICT:` is always line 1, with `(exit <n>, <duration>)` from the script's `EXIT:` and `DURATION:` lines - in `log:` mode from the `exit:` and `duration:` labels instead; `(exit -, -)` when nothing ran and no log was read, and `TIMEOUT` only ever from `command:` mode.
- `EXPECT:` is line 2 and appears only when an `expect:` label came in.
- `SUMMARY:` is exactly one line, always present.
- `FAILURES:` is omitted entirely when nothing failed. Otherwise one `- <test or target> - <message verbatim>` bullet per failure, its first stack frame indented on the line below, at most 10 bullets followed by `- +<N> more, see LOG` when there are more.
- `LOG:` is the last line - the `log:` path echoed verbatim in `log:` mode - always present except on the pre-launch error that produced no log and on step 1's input errors, where nothing was read.
- Over 40 lines, cut bullets - never the `VERDICT:`, `SUMMARY:` or `LOG:` line.
A pass:
```text
VERDICT: PASS (exit 0, 34s)
EXPECT: met - the suite is green
SUMMARY: Tests: 128 passed, 128 total
LOG: /repo/.temp/superdev/logs/20260914T101500Z-npm-test-4821.log
```
A failure:
```text
VERDICT: FAIL (exit 1, 41s)
EXPECT: not met - all green was wanted, two cases fail
SUMMARY: Tests: 126 passed, 2 failed, 128 total
FAILURES:
- cart totals > applies the discount - expected 90 to equal 81
at Object.<anonymous> (test/cart.test.ts:42:18)
- cart totals > rejects a negative quantity - AssertionError: expected function to throw
at Object.<anonymous> (test/cart.test.ts:58:20)
LOG: /repo/.temp/superdev/logs/20260914T104233Z-npm-test-5107.log
```
That same failure reached through `log:` mode reads exactly the same: `(exit 1, 41s)` off the `exit:` and `duration:` labels rather than a run of your own, and `LOG:` echoing the path you were handed.