speckit-companion: Command for Claude Code

.claude/commands/publish-canvas.md

publish-canvas is a command for Claude Code from alfredoperez/speckit-companion. It costs 32 tokens per session (1,536 once invoked), scanned A, original, MIT.

A release command for the GitHub Copilot app canvas that validates the files and opens or updates a pull request in GitHub's `awesome-copilot` repository.

In plain words
What is it for?
Use it to check a Copilot canvas, prepare its upstream files, and submit or update its catalogue pull request.
Why use it?
It turns the repository's local canvas into the layout and review request expected by the upstream catalogue, while keeping the final push under the user's control.

Command for Claude Code

Written for Claude Code: allowed-tools in frontmatter. Also seen: reads .claude/ paths; names the AskUserQuestion tool.

This is alfredoperez/speckit-companion's own configuration. It tells Claude Code how to work on speckit-companion itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything speckit-companion configures →

Reuse

Borrowing it

Nothing to install: this file belongs to alfredoperez/speckit-companion. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/alfredoperez/speckit-companion/main/.claude/commands/publish-canvas.md
Clone the repo
git clone --depth 1 https://github.com/alfredoperez/speckit-companion

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for publish-canvas

README.md
[![agentmods](https://agentmods.dev/badge/commands/alfredoperez/speckit-companion/publish-canvas/github.svg)](https://agentmods.dev/commands/alfredoperez/speckit-companion/publish-canvas)
Your own site
<a href="https://agentmods.dev/commands/alfredoperez/speckit-companion/publish-canvas"><img src="https://agentmods.dev/badge/commands/alfredoperez/speckit-companion/publish-canvas/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for publish-canvas

Your own site · 80×15
<a href="https://agentmods.dev/commands/alfredoperez/speckit-companion/publish-canvas"><img src="https://agentmods.dev/badge/commands/alfredoperez/speckit-companion/publish-canvas.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 32 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 1,536 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00032 $0.01536
Opus 5.5 $0.00013 $0.00614
Sonnet 5.5 $0.00006 $0.00307
Haiku 4.5 $0.00003 $0.00154

Measured 11d ago against content hash c07c7ef41980, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade A, and why

publish-canvas scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 11d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

.claude/commands/publish-canvas.md · 55 lines

How it starts

The opening of the file, as written. The whole thing — 55 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Context

  • Git status: !git status --porcelain | head
  • Current branch: !git branch --show-current
  • Canvas version: !node -p "require('./apps/copilot-canvas/plugin.json').version"
  • Latest canvas tags: !git tag --list 'canvas-v*' --sort=-version:refname | head -3
  • Our listing upstream: !gh api repos/github/awesome-copilot/contents/plugins/external.json --jq .content | base64 -d | node -e "const e=JSON.parse(require('fs').readFileSync(0,'utf8')).find(p=>p.name==='speckit-companion');console.log(e?JSON.stringify(e.source)+' v'+e.version:'not listed')"
  • Our issues and pull requests upstream: !gh search issues --repo github/awesome-copilot --author @me speckit-companion --limit 5

Your task

Release the GitHub Copilot app canvas (apps/copilot-canvas/). It is listed on github/awesome-copilot as an external plugin: the code stays in this repo, and their plugins/external.json names this repo, the path apps/copilot-canvas, a tag and a commit SHA. No file is copied into their repo. Their contributing guide sets the rules: read that section again on every run and follow it where it differs from this file.

The layout their checks read is plugin.json at the plugin root and the board in com.github.copilot/extensions/speckit-companion/, with extension.mjs at its root.

Nothing leaves this machine before the user says go. Steps 1 to 4 are local. The pushes and the submission are step 6.

Steps

  1. QA gate. Apply the Release gate in .claude/commands/release-qa.md. If it does not pass, stop and tell the user to run /release-qa; continue only on their explicit override. Skip it when /publish-all already ran it in its preflight.
  2. Preflight. The working tree is clean and the branch is main, or abort.
  3. Version. Ask for the new version, showing the current one; a first listing may keep it. Skip the question when /publish-all passed one in. Their site lists the version, so an update with the old number looks like no update.
  4. Bump and build. Set version in apps/copilot-canvas/plugin.json and apps/copilot-canvas/package.json, run npm run test:canvas (it rebuilds vendor/ first), and commit apps/copilot-canvas/ locally as chore(canvas): release v<X.Y.Z>. Do not push yet.
  5. Check the layout their canvas gate reads, at the commit about to be tagged:
    P=apps/copilot-canvas
    git cat-file -e "HEAD:$P/plugin.json" && git cat-file -e "HEAD:$P/com.github.copilot/extensions/speckit-companion/extension.mjs" && git cat-file -e "HEAD:$P/assets/preview.png" && echo layout ok
    git grep -n -E "from '\.\./|import\('\.\./" HEAD -- "$P/com.github.copilot" ; echo "(no line above: the board imports nothing outside its folder)"
    
    Their gate fails a board that imports a file outside its own folder, so a hit on the second line is fixed here first.
  6. Show and wait. Show the user what will be sent: the version, the tag canvas-v<X.Y.Z>, the SHA of the release commit, and either the filled issue form (first listing) or the plugins/external.json diff (update). Then stop until the user answers with an explicit go. A go from earlier in the conversation, or one given to /publish-all for the release as a whole, does not count.
  7. Send, only after the go:
    V=<X.Y.Z>
    git push origin main
    git tag -a "canvas-v$V" -m "Copilot canvas v$V" && git push origin "canvas-v$V"
    SHA=$(git rev-parse "canvas-v$V^{commit}")
    
    • Not listed yet: open their external plugin issue form with the name speckit-companion, the description from plugin.json, the repository alfredoperez/speckit-companion, the path apps/copilot-canvas, the ref canvas-v$V, the SHA, the version, MIT, the author, the homepage and the keywords from plugin.json (canvas must be one). A pull request that adds a new entry to plugins/external.json is rejected: the form is the only way in. Their bots answer on the issue; after a fix here, tag again and comment /rerun-intake.
    • Already listed: an update is a pull request that edits our entry in plugins/external.json: version, source.ref and source.sha, nothing else. Branch from their main in the checkout under the sandbox root (. .claude/sandboxes-env.sh, then $SANDBOXES_DIR/awesome-copilot), run their npm ci && npm start so the generated files follow, push to the fork and open the pull request titled Update SpecKit Companion canvas to v<X.Y.Z>.
  8. Report the issue or pull request URL, the canvas-v<X.Y.Z> tag and SHA, the labels their bots set (ready-for-review or requires-submitter-fixes), and how people install it once listed: from Customize → Canvas in the Copilot app.

Read the full file on GitHub · 55 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 11d ago Changed · -22 lines scan C → A c07c7ef41980
  2. 18d ago Changed · +2 lines 50d6f1b07c4e
  3. 19d ago Changed · +2 lines c00a9313abe8
  4. 21d ago First seen · 73 lines · 32 tokens per session scan C 9472040ca953

Subscribe to this mod's changes

publish-canvas is a command published in the GitHub repository alfredoperez/speckit-companion (99 stars, last pushed 6d ago), licensed MIT. It adds 32 tokens to every session and 1,536 once invoked, about $0.0001 per session on Opus 5.5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-10-04.