Skip to content

chore(ADR-0039): spur as the repository's command runner - #7

Merged
Danrley-Ruan-Saquetti merged 12 commits into
masterfrom
chore/spur-command-runner
Oct 1, 2026
Merged

Danrley-Ruan-Saquetti merged 12 commits into
masterfrom
chore/spur-command-runner

Conversation

@Danrley-Ruan-Saquetti

@Danrley-Ruan-Saquetti Danrley-Ruan-Saquetti commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Summary

Makes the vendored ./spur the single place where each command of this repository is defined, and the way a person, an agent and CI run it. Design: docs/superpowers/specs/2026-09-30-spur-command-runner-design.md; plan: docs/superpowers/plans/2026-09-30-spur-command-runner.md.

Decisions

  • ADR-0039 — spur, vendored and pinned to a tag, is the repository's command runner. Opened as draft, accepted by a human. It replaces one clause of ADR-0036: the project package.json no longer holds the scripts. ADR-0036 is not edited.
  • RNF-0002 — the toolchain now includes a POSIX shell with awk to run ./spur (on Windows, Git Bash or WSL).

What changes

  • The runner — spur v0.3.1 at the root, executable and LF (.gitattributes), owned in .ownership.yml and CODEOWNERS, outside Prettier. Never edited by hand: updating it is replacing the file from another tag.
  • One Spurfile per plugin — ownership and living-docs own install, test, typecheck, lint, lint-check, format, format-check and check, calling node, tsc, ESLint and Prettier directly. test puts its arguments before the file pattern, where Node reads them.
  • The root Spurfile — install, plugins, validate [base], marketplace and check [base]. It only delegates, in the order written in PLUGINS.
  • A plugin owes the root nothing — a plugin with no Spurfile, or without the delegated task, is skipped with a notice on stderr. A name in PLUGINS that is not a directory still fails, and a failing plugin still stops the run with its exit code. CONTRIBUTING.md no longer requires the eight tasks: a plugin has the tasks it needs, and the root knows only install and check.
  • Callers — CONTRIBUTING.md, README.md, plugins/living-docs/CLAUDE.md, the new-plugin skill and the three workflows run ./spur tasks, one CI step per task. The container path is bin/dev ../../spur test.
  • package.json — the scripts objects are gone from both plugin projects; development dependencies and lockfiles are unchanged.

Nothing under plugins/<name>/plugin/ changes, so no CHANGELOG entry: every commit carries Changelog: none with its reason. The hooks never go through the runner.

Test plan

No test targets the runner or a Spurfile, by decision (ADR-0039): running the tasks is what exercises them.

  • ./spur plugins — exit 0: ownership 211/211; living-docs 490 passed of 491, 0 failed
  • ./spur validate and ./spur validate origin/master — exit 0
  • ./spur marketplace — exit 0, 5/5
  • Tolerant delegation, in a throwaway copy of the layout: a plugin with no Spurfile and one without check are skipped with a notice (exit 0); a failing plugin stops the run with its exit code; a name in PLUGINS that is not a directory fails
  • The three workflows on this PR — all jobs pass, on the push and on the pull request event
  • bin/dev ../../spur test through the container — the container job in CI passes; not run on a local machine

🤖 Generated with Claude Code

Danrley-Ruan-Saquetti and others added 12 commits September 30, 2026 15:14
Changelog: none — a design document; nothing a consumer installs changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Seven tasks: ADR-0039 (draft) and the RNF-0002 revision, vendoring spur v0.3.1, one Spurfile per plugin, the root Spurfile, the written callers, the workflows, and removing the npm scripts after comparing each task with spur -n. Pinned to v0.3.1 because v0.3.0's recursion guard stopped same-name delegation across Spurfiles. No test targets the runner or a Spurfile: running the tasks exercises them.

Changelog: none — a plan document; nothing a consumer installs changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nner (draft)

Records the choice and the alternatives (npm scripts, make, just, Task), composition by delegation, and the clause of ADR-0036 it replaces: the project package.json no longer holds the scripts. Draft; acceptance is a human act.

Changelog: none — a decision record; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…./spur

Follows ADR-0039: dependencies come in through ../../spur install, and the hooks stay outside the runner.

Changelog: none — a requirement of whoever works on the toolkit, not of whoever installs it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The file is the upstream one at the tag, executable and LF, owned in .ownership.yml and CODEOWNERS, and outside Prettier.

Changelog: none — repository tooling; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
install, test, typecheck, lint, lint-check, format, format-check and check, calling node, tsc, ESLint and Prettier directly. test puts its arguments before the file pattern, where Node reads them. living-docs' install installs the core first (TDR-0003).

Changelog: none — repository tooling; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…licit order

install, plugins, validate [base-ref], marketplace and check [base-ref]. PLUGINS names the order, the core first.

Changelog: none — repository tooling; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… ./spur tasks

The Definition of Done block is five ./spur lines, which the done-check skill executes unchanged. The container path runs bin/dev ../../spur <task>. Adding a plugin states the Spurfile convention, and the new-plugin skill points to it. The format hook's comment no longer mentions scripts.

Changelog: none — contributor documentation; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Same checks as before: install, test, type-check and lint per plugin; the container job through bin/dev ../../spur test; the marketplace check with its tests, and both validators with and without the PR base. The runner and the plugin Spurfiles trigger the workflows and the container job.

Docs: none — the Definition of Done names checks, not commands, and the checks are the same.

Changelog: none — CI of this repository; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Each command is a task of the plugin's Spurfile, and every caller runs the task. Compared one by one with spur -n: no step was lost in translation. The development dependencies and lockfiles are unchanged.

Changelog: none — repository tooling; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Accepted by the human owner; RNF-0002 stays active.

Changelog: none — a decision record; nothing a plugin ships changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
each ran the task in every plugin of PLUGINS and broke on a plugin with no Spurfile (spur finds the root one in the parent directories) or without the task (exit 67). It now skips both with a notice on stderr; a name in PLUGINS that is not a directory still fails, and a failing plugin still stops the run with its exit code. CONTRIBUTING no longer requires the eight tasks: a plugin has the tasks it needs, and the root knows only install and check, requiring neither.

Changelog: none — repository tooling; nothing a plugin ships changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Danrley-Ruan-Saquetti
Danrley-Ruan-Saquetti merged commit 1373f20 into master Oct 1, 2026
12 checks passed
@Danrley-Ruan-Saquetti
Danrley-Ruan-Saquetti deleted the chore/spur-command-runner branch October 1, 2026 12:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant