yaniv-golan/cowork-harness
Test Claude Code skills under Claude Cowork's runtime in CI — token-free replay/lint, or a live scenario run.
View on GitHubTrust Signals
- Scorecard Score
- not yet scored
- Maintenance Recency
- Stale
- License
- None
Inputs
| name | description | required | default |
|---|---|---|---|
| command | cowork-harness subcommand to run: replay | lint | lint-skill | analyze-skill | verify-cassettes | run. `lint` and `lint-skill` are thin passthroughs to the bundled `scenario.py` (needs python3 on the runner — preinstalled on ubuntu-latest); `analyze-skill` is a pure-TS static scan (no python3 needed). This is a description, not a validated allowlist — `path`/`extra-args` are built verbatim into the invocation for any subcommand the installed `cowork-harness` accepts. | no | replay |
| path | Cassette/scenario/SKILL.md/skill-dir to check (positional argument to the command) | yes | — |
| version | npm version or dist-tag of cowork-harness to install. The `latest` default is intentional so copy-paste recipes track the current release; for reproducible CI, pin an exact version here. (This differs from the companion skill's `@>=1.7.0` floor guidance, which targets ad-hoc CLI installs where an accidental older resolve should fail loud rather than silently downgrade.) | no | latest |
| strict | Pass --strict — fail on any finding instead of just the default gate: for `replay`, any cassette-staleness finding (not just skill/shared-root drift); for `lint`/`lint-skill`, any WARN/INFO finding (not just ERROR); for `analyze-skill`, any advisory finding at all (it's exit-0 by default). `verify-cassettes`/`run` don't accept `--strict` (unknown-flag usage error), so it is IGNORED (not forwarded) for those two commands. | no | false |
| fail-on-skill-drift | Pass --fail-on-skill-drift — REPLAY ONLY (fail on skill/shared-root staleness classes); not forwarded to any other command. | no | false |
| extra-args | Additional CLI arguments appended verbatim after the standard flags. TWO accepted forms: (1) PREFERRED — a JSON array of strings, e.g. `["--answer", ".*=Option A"]`; each element is passed as one argument with quoting/spaces/regex metacharacters preserved exactly. (2) LEGACY — a plain space-separated string, e.g. `--assert-from path/to.yaml`; split on whitespace, so it CANNOT carry an argument that itself contains spaces (use the JSON-array form for that). The value is passed to the runner via the environment, never interpolated into the shell body. | no | "" |
| summary | Write the verdict table to $GITHUB_STEP_SUMMARY | no | true |
| anthropic-api-key | API key for the live `run` lane. Unused by replay/lint/verify-cassettes. This action does NOT stage the agent binary or build the Docker image for you, by design, not an oversight — a live `run` needs both already available on the runner. Staging the binary is a call about your own relationship with Anthropic's distribution terms, so it stays a step in YOUR workflow, not something this action automates on your behalf. See the README's "Packaged GitHub Action" section for a worked self-hosted-runner example. | no | "" |
Outputs
| name | description |
|---|---|
| ok | "true"/"false" — the envelope-level pass/fail (mirrors the command's exit code) |
| envelope-path | Path to the raw JSON envelope file, for a caller that wants to post-process it further |
| summary-md | The rendered markdown verdict table (same content appended to $GITHUB_STEP_SUMMARY when `summary: true`). Exposed as an output — not just the step summary file — because $GITHUB_STEP_SUMMARY is scoped to this action's own invocation; a caller's later step gets a fresh, empty file and can't read back what this step wrote. |