Skip to content

feat(skills): publish workflow skills to skills.sh#1357

Merged
clay-good merged 5 commits into
Fission-AI:mainfrom
clay-good:feat/skills-sh-distribution
Jul 17, 2026
Merged

feat(skills): publish workflow skills to skills.sh#1357
clay-good merged 5 commits into
Fission-AI:mainfrom
clay-good:feat/skills-sh-distribution

Conversation

@clay-good

@clay-good clay-good commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

What was missing: Multiple requests (#1258) to install OpenSpec skills via skills.sh, which reads static SKILL.md files from a repo — but OpenSpec generates its skills at openspec init time, so none existed in the tree.

What it does: Commits the 12 workflow skills under skills/ so npx skills add Fission-AI/OpenSpec works. The files are generated from the existing skill templates (pnpm generate:skills), not hand-copied, and a parity test keeps them in sync. The volatile generatedBy frontmatter line is stripped so the committed copies stay byte-stable across releases (no per-release regen churn).

Proof it works:

  • New skillssh-parity.test.ts + existing golden-hash tests (skill-templates-parity, skill-generation) pass — 34 tests.
  • Negative check: appending junk to a committed skill makes the parity test fail with … is stale — run pnpm generate:skills.
  • Full suite: only the 17 known environment-only zsh-installer (oh-my-zsh) failures; 1859 others pass.

Notes / scope:

  • Skills drive the openspec CLI and assume an openspec/ project, so openspec init remains the fuller setup — skills/README.md states this.
  • skills/ is not in the npm files list, so it doesn't bloat the published package (skills.sh reads from GitHub, not npm).

Closes #1258

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added multiple OpenSpec workflow skills (explore mode, new/propose/continue/verify/update/apply changes, fast-forward, sync specs, archive single, bulk archive).
    • Added corresponding skills.sh distribution entries and installation guidance.
  • Documentation
    • Updated the skills README with setup commands and regeneration guidance.
  • Bug Fixes
    • Improved delta-spec syncing behavior (choosing “Cancel” now stops) and refined success/warning reporting formatting.
  • Tests
    • Expanded parity and generator filesystem-safety guard coverage; updated template/content hash expectations.
  • Chores
    • Added a generate:skills regeneration script and normalized skills line endings to LF for consistent output.

@clay-good
clay-good requested a review from TabishB as a code owner July 14, 2026 16:45
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds skills.sh-compatible OpenSpec skills, a generator with filesystem safeguards, workflow template updates, line-ending normalization, onboarding documentation, and parity tests for committed generated files.

Changes

Skills.sh publication

Layer / File(s) Summary
Generation and parity validation
.gitattributes, package.json, scripts/*, skills/README.md, test/core/templates/*
Adds the generate:skills command, safe skill generation, LF normalization, publication guidance, and exact parity/structure checks.
Change implementation workflows
skills/openspec-{new,propose,continue,ff,apply}-change/*
Adds schema-driven skills for creating, proposing, continuing, fast-forwarding, and applying changes.
Archive and specification synchronization
skills/openspec-{archive,bulk-archive,sync-specs}-change/*, skills/openspec-sync-specs/*
Adds archive, bulk archive, conflict handling, reporting, and delta-spec synchronization workflows.
Exploration and onboarding guidance
skills/openspec-{explore,onboard}/*
Adds exploration guidance and an end-to-end onboarding workflow.
Change update and verification workflows
skills/openspec-{update,verify}-change/*
Adds planning-artifact update rules and implementation verification procedures.
Workflow template outputs
src/core/templates/workflows/*, test/core/templates/skill-templates-parity.test.ts
Stops archive execution on cancellation, formats embedded examples, and updates generated-content hash baselines.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: tabishb, alfred-openspec

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects publishing workflow skills to skills.sh.
Linked Issues check ✅ Passed The PR adds and validates the skills.sh skill tree needed to publish OpenSpec skills, matching issue #1258.
Out of Scope Changes check ✅ Passed The changes are all tied to publishing, generating, documenting, or safeguarding the skills.sh skill tree.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Commit the 12 OpenSpec workflow skills as static skills/<name>/SKILL.md so
`npx skills add Fission-AI/OpenSpec` can install them (skills.sh reads static
files from the repo; OpenSpec otherwise only generates skills at init time).

Files are generated from the existing templates via `pnpm generate:skills`,
not hand-copied, and skillssh-parity.test.ts fails CI if a template changes
without regenerating. The volatile generatedBy frontmatter line is stripped so
the committed copies stay byte-stable across releases.

Closes Fission-AI#1258

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@clay-good
clay-good force-pushed the feat/skills-sh-distribution branch from 2c0ebb7 to 5115467 Compare July 14, 2026 16:46
The skills.sh distribution files are generated LF-only and compared
byte-for-byte by skillssh-parity.test.ts. Windows autocrlf checked them
out as CRLF, failing the parity assertion. A scoped .gitattributes pins
them to LF on checkout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (2)
skills/openspec-explore/SKILL.md (1)

56-56: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add language identifiers to fenced blocks.

markdownlint reports MD040 for these fences. Use identifiers such as text, bash, or markdown consistently for the displayed examples.

Also applies to: 150-150, 173-173, 204-204, 221-221, 262-262

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/openspec-explore/SKILL.md` at line 56, Add explicit language
identifiers to every fenced code block in SKILL.md, including the blocks around
the referenced examples. Use appropriate identifiers such as text, bash, or
markdown consistently so all fences satisfy markdownlint MD040.

Source: Linters/SAST tools

skills/openspec-onboard/SKILL.md (1)

40-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add language identifiers to fenced blocks.

markdownlint reports MD040 for these fences. Add identifiers such as text, bash, powershell, or markdown to the examples.

Also applies to: 85-85, 118-118, 139-139, 148-148, 169-169, 183-183, 193-193, 203-203, 213-213, 252-252, 263-263, 279-279, 308-308, 318-318, 353-353, 363-363, 391-391, 409-409, 425-425, 439-439, 449-449, 502-502, 518-518

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/openspec-onboard/SKILL.md` at line 40, Add language identifiers to
every fenced code block in SKILL.md, including the listed locations, choosing
appropriate tags such as text, bash, powershell, or markdown based on each
block’s contents. Preserve all example content while ensuring no unlabeled
fences remain.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@skills/openspec-apply-change/SKILL.md`:
- Line 14: Executable command examples omit the selected store flag, allowing
operations to target the wrong repository. Update the command examples in
skills/openspec-apply-change/SKILL.md:14,
skills/openspec-continue-change/SKILL.md:14,
skills/openspec-ff-change/SKILL.md:14, skills/openspec-new-change/SKILL.md:14,
and skills/openspec-propose/SKILL.md:23 to include --store <id> on every listed
command that reads or writes specs or changes, while leaving commands that do
not support the flag unchanged.

In `@skills/openspec-archive-change/SKILL.md`:
- Line 107: Update the final success summary in the archive workflow so it
reflects the actual completion status tracked by the logic in Lines 38–52.
Report incomplete artifacts or tasks when archiving unfinished work, while
preserving the existing “All artifacts complete. All tasks complete.” message
only when both are actually complete.
- Around line 65-69: Update the archive decision flow in the prompt options so
selecting “Cancel” immediately aborts the operation and does not archive the
change. Only proceed to archive after the user selects a sync or archive action,
while preserving the existing sync behavior for sync choices.
- Line 61: Make main-spec resolution store-aware in both instruction sites: in
skills/openspec-archive-change/SKILL.md:61, compare each delta spec with the
selected store’s resolved main-spec path instead of hardcoding openspec/specs;
in skills/openspec-sync-specs/SKILL.md:55, read and write the main spec using
the status/store context and its resolved path rather than the current
repository path.
- Line 99: Replace each remaining unlabeled Markdown code fence with an
appropriate language-identified fence: update
skills/openspec-archive-change/SKILL.md at 99-99;
skills/openspec-bulk-archive-change/SKILL.md at 57-57, 88-88, 98-98, 104-104,
145-145, 162-162, 170-170, 185-185, 202-202, 216-216, and 231-231; and
skills/openspec-sync-specs/SKILL.md at 90-90. Preserve the existing fenced
content and choose the identifier matching each block’s syntax.

In `@skills/openspec-explore/SKILL.md`:
- Around line 84-110: Propagate the selected store through every OpenSpec
workflow command by adding --store <selected store> to list and status in
skills/openspec-explore/SKILL.md lines 84-110, and to new change (177-180),
proposal instructions (246-250), specs instructions (271-275), design
instructions (344-347), task instructions (382-385), and archive (433-436) in
skills/openspec-onboard/SKILL.md; preserve each command’s existing arguments and
workflow.

In `@skills/openspec-update-change/SKILL.md`:
- Around line 20-22: Propagate the selected store ID through every documented
command sequence: update `skills/openspec-update-change/SKILL.md` ranges 20-22,
34-46, and 59-65 to include the store flag in `openspec list`, `openspec
status`, and `openspec instructions`; update
`skills/openspec-verify-change/SKILL.md` ranges 20-22, 30-37, and 39-45
similarly for `openspec list`, `openspec status`, and `openspec instructions
apply`. Preserve the existing command flow while ensuring each command targets
the selected OpenSpec store.

In `@skills/openspec-verify-change/SKILL.md`:
- Around line 116-125: Update the fenced code block in the Verification Report
template to declare the markdown language using a markdown-labeled fence, while
preserving the report example content unchanged.

---

Nitpick comments:
In `@skills/openspec-explore/SKILL.md`:
- Line 56: Add explicit language identifiers to every fenced code block in
SKILL.md, including the blocks around the referenced examples. Use appropriate
identifiers such as text, bash, or markdown consistently so all fences satisfy
markdownlint MD040.

In `@skills/openspec-onboard/SKILL.md`:
- Line 40: Add language identifiers to every fenced code block in SKILL.md,
including the listed locations, choosing appropriate tags such as text, bash,
powershell, or markdown based on each block’s contents. Preserve all example
content while ensuring no unlabeled fences remain.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a7a2c8ea-0cb7-40c2-9029-77392cccece6

📥 Commits

Reviewing files that changed from the base of the PR and between 0a99f41 and d1a67a4.

📒 Files selected for processing (18)
  • .gitattributes
  • package.json
  • scripts/generate-skillssh.mjs
  • scripts/skillssh-shared.mjs
  • skills/README.md
  • skills/openspec-apply-change/SKILL.md
  • skills/openspec-archive-change/SKILL.md
  • skills/openspec-bulk-archive-change/SKILL.md
  • skills/openspec-continue-change/SKILL.md
  • skills/openspec-explore/SKILL.md
  • skills/openspec-ff-change/SKILL.md
  • skills/openspec-new-change/SKILL.md
  • skills/openspec-onboard/SKILL.md
  • skills/openspec-propose/SKILL.md
  • skills/openspec-sync-specs/SKILL.md
  • skills/openspec-update-change/SKILL.md
  • skills/openspec-verify-change/SKILL.md
  • test/core/templates/skillssh-parity.test.ts

Comment thread skills/openspec-apply-change/SKILL.md
Comment thread skills/openspec-archive-change/SKILL.md Outdated
Comment thread skills/openspec-archive-change/SKILL.md Outdated
Comment thread skills/openspec-archive-change/SKILL.md Outdated
Comment thread skills/openspec-archive-change/SKILL.md Outdated
Comment thread skills/openspec-explore/SKILL.md
Comment thread skills/openspec-update-change/SKILL.md
Comment thread skills/openspec-verify-change/SKILL.md Outdated

@alfred-openspec alfred-openspec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current parity test only iterates expected templates, so an extra or renamed skills directory remains publishable with green CI, and the generator follows a pre-existing symlinked skill directory when writing. Please assert the exact owned directory and file set and reject symlinked or non-contained outputs before cleanup and writes, with focused tests.

clay-good and others added 2 commits July 17, 2026 10:40
Review feedback (alfred): the parity test only visited expected templates,
so an extra or renamed skills/ directory shipped with green CI, and the
generator would write through a pre-existing symlinked skill directory to
anywhere on disk.

- generator: refuse to run if skills/ contains any symlink (checked before
  any deletion, so a bad tree is left intact), validate dirNames against a
  path-segment allowlist, and lstat the target before writing.
- parity test: assert skills/ holds exactly README.md plus one real
  directory per template, each containing a single real SKILL.md.
- focused tests cover symlink refusal (no partial deletion), traversal
  names, and stale-directory cleanup.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CodeRabbit review on Fission-AI#1357, fixed at the template source and regenerated:

- archive-change: choosing "Cancel" at the sync prompt now stops the flow
  instead of archiving anyway (skill + command templates).
- archive-change skill: the success output no longer hardcodes "All
  artifacts complete. All tasks complete." when archiving incomplete work.
- archive/bulk-archive/sync-specs/verify-change: language identifiers on
  previously plain code fences (MD040), skill and command twins alike.

Golden hashes in skill-templates-parity.test.ts recomputed from dist/;
skills/ regenerated via pnpm generate:skills.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@clay-good

Copy link
Copy Markdown
Collaborator Author

@alfred-openspec Both points addressed in af6eded:

Exact owned file set. skillssh-parity.test.ts now asserts the committed tree is exactly what the generator owns: skills/ holds README.md plus one real directory per template (extra or renamed directories fail with a set diff), each directory contains only a regular SKILL.md, and no entry anywhere is a symlink. Verified negatively: adding a rogue skills/openspec-rogue/ makes the test fail.

Symlink / containment guards in the generator. The cleanup + write logic moved into shared helpers (scripts/skillssh-shared.mjs) used by the script and unit-tested directly:

  • cleanup scans the whole tree for symlinks before deleting anything and refuses with a clear error, leaving a tampered tree fully intact;
  • dirNames must match a path-segment allowlist (^[a-z0-9][a-z0-9-]*$), so no traversal or absolute paths;
  • each write target is lstat-checked to be a real directory before SKILL.md is written, so a pre-existing symlinked skill directory can never redirect a write outside skills/.

Focused tests in test/core/templates/skillssh-generator-guards.test.ts cover symlink refusal (including no-partial-deletion), traversal names, stale-directory cleanup, and the happy path. Also verified end-to-end: with a symlinked skills/openspec-evil in place, pnpm generate:skills exits 1 without touching anything.

@alfred-openspec alfred-openspec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The symlink, containment, and exact-set guards resolve my original review, but the committed skills still contain the store-unaware archive and sync paths fixed by open PR #1360. Please merge #1360 first, then rebase and regenerate this distribution, or incorporate that fix here, so the two PRs cannot leave main with stale published skills and a failing parity contract.

@alfred-openspec

Copy link
Copy Markdown
Collaborator

Still blocked on the same head (71205f8): #1360 is now merged, and merging current main produces a parity-hash conflict while the committed archive/sync skills remain store-unaware. Please rebase onto main, resolve the template hashes, regenerate skills/, and rerun CI; I’ll approve the resulting head once it is green.

Regenerate the parity hashes and the committed skills/ distribution from
the merged templates, picking up the store-aware archive/sync paths
(Fission-AI#1360) and the re-read-dependencies guidance (Fission-AI#1368) alfred flagged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@clay-good

Copy link
Copy Markdown
Collaborator Author

Fixed up per the review (097425e): merged main (post the 2026-07-17 merge train) and regenerated both the parity hashes and the committed skills/ distribution from the merged templates. The 5 affected skills now carry the store-aware archive/sync paths from #1360 and the re-read-dependencies guidance from #1368 — e.g. openspec-archive-change now compares delta specs against <planningHome.root>/openspec/specs/… instead of the hardcoded repo path. The symlink/containment/exact-set guards are unchanged. Full suite passes locally (1,948 passing; only the 17 known env-only zsh-installer failures). Lockfile untouched.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
skills/openspec-ff-change/SKILL.md (1)

4-4: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align the allowlists with the workflow requirements. Both skills require AskUserQuestion and TodoWrite, but allowed-tools only includes Bash(openspec:*); add the missing tools or remove those requirements.

  • skills/openspec-ff-change/SKILL.md#L4
  • skills/openspec-propose/SKILL.md#L4
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@skills/openspec-ff-change/SKILL.md` at line 4, Update the allowed-tools
declarations in skills/openspec-ff-change/SKILL.md at line 4 and
skills/openspec-propose/SKILL.md at line 4 to include AskUserQuestion and
TodoWrite alongside Bash(openspec:*), keeping both skill allowlists aligned with
their workflow requirements.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@skills/openspec-ff-change/SKILL.md`:
- Line 4: Update the allowed-tools declarations in
skills/openspec-ff-change/SKILL.md at line 4 and
skills/openspec-propose/SKILL.md at line 4 to include AskUserQuestion and
TodoWrite alongside Bash(openspec:*), keeping both skill allowlists aligned with
their workflow requirements.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dce530f9-1f68-46f5-a36d-00788703c816

📥 Commits

Reviewing files that changed from the base of the PR and between 71205f8 and 097425e.

📒 Files selected for processing (8)
  • skills/openspec-archive-change/SKILL.md
  • skills/openspec-continue-change/SKILL.md
  • skills/openspec-ff-change/SKILL.md
  • skills/openspec-propose/SKILL.md
  • skills/openspec-sync-specs/SKILL.md
  • src/core/templates/workflows/archive-change.ts
  • src/core/templates/workflows/sync-specs.ts
  • test/core/templates/skill-templates-parity.test.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/core/templates/workflows/sync-specs.ts
  • src/core/templates/workflows/archive-change.ts
  • skills/openspec-continue-change/SKILL.md
  • skills/openspec-archive-change/SKILL.md
  • skills/openspec-sync-specs/SKILL.md

@alfred-openspec alfred-openspec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the rebase/regeneration resolves both prior blockers: the static distribution now includes #1360’s store-aware archive/sync paths and #1368’s fresh disk-read guidance, while the exact-set, symlink, and containment guards remain intact with focused coverage. Parity, Windows, Nix, and the full CI gate are green, and the PR is mergeable.

@clay-good
clay-good added this pull request to the merge queue Jul 17, 2026
Merged via the queue into Fission-AI:main with commit 46a4d78 Jul 17, 2026
11 checks passed
@clay-good
clay-good deleted the feat/skills-sh-distribution branch July 17, 2026 21:45
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.

Publish skills to skills.sh

2 participants