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 GitHub

Trust Signals

Scorecard Score
not yet scored
Maintenance Recency
Stale
License
None
namedescriptionrequireddefault
commandcowork-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.noreplay
pathCassette/scenario/SKILL.md/skill-dir to check (positional argument to the command)yes
versionnpm 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.)nolatest
strictPass --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.nofalse
fail-on-skill-driftPass --fail-on-skill-drift — REPLAY ONLY (fail on skill/shared-root staleness classes); not forwarded to any other command.nofalse
extra-argsAdditional 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""
summaryWrite the verdict table to $GITHUB_STEP_SUMMARYnotrue
anthropic-api-keyAPI 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""
namedescription
ok"true"/"false" — the envelope-level pass/fail (mirrors the command's exit code)
envelope-pathPath to the raw JSON envelope file, for a caller that wants to post-process it further
summary-mdThe 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.