Skip to content
4 changes: 3 additions & 1 deletion .github/skills/add-community-extension/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Process an extension submission issue and add or update it in the community cata
### 1. Fetch the submission issue

Read the GitHub issue to extract all metadata:

- Extension ID, name, version, description, author
- Repository URL, download URL, homepage, documentation, changelog
- License, required spec-kit version, optional tool dependencies
Expand Down Expand Up @@ -114,7 +115,7 @@ python3 -c "import json; json.load(open('extensions/catalog.community.json')); p

Determine the category and effect from the extension's behavior:

```
```markdown
| <Name> | <Description> | `<category>` | <Effect> | [<repo-name>](<repository-url>) |
```

Expand Down Expand Up @@ -158,6 +159,7 @@ git push origin <branch-name>
```

Then create a PR to `upstream` (`github/spec-kit`) with:

- **Title:** `Add <Name> extension to community catalog` (or `Update <Name> extension to v<version>`)
- **Body:** Include validation summary, `Closes #<issue-number>`, and `cc @<issue-author>`
- **Head:** `<fork-owner>:<branch-name>`
Expand Down
14 changes: 13 additions & 1 deletion .github/workflows/RELEASE-PROCESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This separation ensures that git tags always point to commits with the correct v
The CHANGELOG is **automatically generated** from your git commit messages:

1. **During Development**: Write clear, descriptive commit messages:

```bash
git commit -m "feat: Add new authentication feature"
git commit -m "fix: Resolve timeout issue in API client (#123)"
Expand All @@ -35,13 +36,15 @@ The CHANGELOG is **automatically generated** from your git commit messages:
### Commit Message Best Practices

Good commit messages make good changelogs:

- **Be descriptive**: "Add user authentication" not "Update files"
- **Reference issues/PRs**: Include `(#123)` for automated linking
- **Use conventional commits** (optional): `feat:`, `fix:`, `docs:`, `chore:`
- **Keep it concise**: One line is ideal, details go in commit body

**Example commits that become good changelog entries:**
```

```text
fix: prepend YAML frontmatter to Cursor .mdc files (#1699)
feat: add generic agent support with customizable command directories (#1639)
docs: document dual-catalog system for extensions (#1689)
Expand All @@ -57,6 +60,7 @@ docs: document dual-catalog system for extensions (#1689)
4. Click **Run workflow**

The workflow will:

- Auto-increment the patch version (e.g., `0.1.10` → `0.1.11`)
- Update `pyproject.toml`
- Update `CHANGELOG.md` by adding a new section for the release based on commits since the last tag
Expand All @@ -73,6 +77,7 @@ The workflow will:
4. Click **Run workflow**

The workflow will:

- Use your specified version
- Update `pyproject.toml`
- Update `CHANGELOG.md` by adding a new section for the release based on commits since the last tag
Expand Down Expand Up @@ -105,6 +110,7 @@ Once the release trigger workflow completes:
**Permissions Required**: `contents: write`

**Steps**:

1. Checkout repository
2. Determine version (manual or auto-increment)
3. Check if tag already exists (prevents duplicates)
Expand All @@ -124,6 +130,7 @@ Once the release trigger workflow completes:
**Permissions Required**: `contents: write`

**Steps**:

1. Checkout repository at tag
2. Extract version from tag name
3. Check if release already exists
Expand Down Expand Up @@ -155,6 +162,7 @@ Once the release trigger workflow completes:
### No Commits Since Last Release

If you run the release trigger workflow when there are no new commits since the last tag:

- The workflow will still succeed
- The CHANGELOG will show "- Initial release" if it's the first release
- Or it will be empty if there are no commits
Expand All @@ -165,25 +173,29 @@ If you run the release trigger workflow when there are no new commits since the
### Tag Already Exists

If you see "Error: Tag vX.Y.Z already exists!", you need to:

- Choose a different version number, or
- Delete the existing tag if it was created in error

### Release Workflow Didn't Trigger

Check that:

- The release trigger workflow completed successfully
- The tag was pushed (check repository tags)
- The release workflow is enabled in Actions settings

### Version Mismatch

If `pyproject.toml` doesn't match the latest tag:

- Run the release trigger workflow to sync versions
- Or manually update `pyproject.toml` and push changes before running the release trigger

## Legacy Behavior (Pre-v0.1.10)

Before this change, the release workflow:

- Created tags automatically on main branch pushes
- Updated `pyproject.toml` AFTER creating the tag
- Resulted in tags pointing to commits with outdated versions
Expand Down
18 changes: 15 additions & 3 deletions .github/workflows/add-community-extension.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,23 @@ Run **all** of the following validation checks. Collect all results before
deciding pass/fail:

### 2a. Extension ID format

- Must match regex: `^[a-z][a-z0-9-]*$`
- Must be lowercase with hyphens only

### 2b. Version format

- Must follow semver: `X.Y.Z` (digits only, no `v` prefix)

### 2c. Repository validation

- Fetch the repository URL — confirm it exists and is publicly accessible
- Confirm the repository contains an `extension.yml` file
- Confirm the repository contains a `README.md` file
- Confirm the repository contains a `LICENSE` file

### 2d. Release and download URL validation

- The download URL MUST belong to the submitted repository
(`https://github.com/<owner>/<repo>/...` with the same `<owner>/<repo>` as
the Repository URL). Reject URLs for any other GitHub repository.
Expand All @@ -136,18 +140,21 @@ deciding pass/fail:
- Verify a GitHub release exists for that tag.

### 2e. Submission checklists

- Confirm that all required checkboxes in the Testing Checklist and Submission
Requirements sections are checked (`[x]`)

### Validation outcome

If **any** validation fails:

1. Add a comment on the issue listing each failed check with a clear explanation
of what's wrong and how to fix it
2. Add the `validation-failed` label
3. **Stop — do not proceed further**

If all validations pass:

1. Add the `validation-passed` label
2. Continue to Step 3

Expand Down Expand Up @@ -234,18 +241,20 @@ Extensions table.

Insert a new row in **alphabetical order by extension name**:

```
```markdown
| <Name> | <Description> | `<category>` | <Effect> | [<repo-name>](<repository-url>) |
```

Determine the category from the extension's behavior:

- `docs` — reads, validates, or generates spec artifacts
- `code` — reviews, validates, or modifies source code
- `process` — orchestrates workflow across phases
- `integration` — syncs with external platforms
- `visibility` — reports on project health or progress

Determine the effect:

- `Read-only` — produces reports only
- `Read+Write` — modifies project files

Expand All @@ -263,7 +272,8 @@ Create a pull request with the changes. Use this branch naming convention:
### Commit message

For a new extension:
```

```text
Add <Name> extension to community catalog

Add <id> extension submitted by @<issue-author> to:
Expand All @@ -274,7 +284,8 @@ Closes #<issue-number>
```

For an update:
```

```text
Update <Name> extension to v<version>

Update <id> extension submitted by @<issue-author>:
Expand All @@ -287,6 +298,7 @@ Closes #<issue-number>
### PR description

Include:

- A summary of what changed
- Validation results (all checks passed)
- `Closes #${{ github.event.issue.number }}`
Expand Down
18 changes: 15 additions & 3 deletions .github/workflows/add-community-preset.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,16 @@ Run **all** of the following validation checks. Collect all results before
deciding pass/fail:

### 2a. Preset ID format

- Must match regex: `^[a-z][a-z0-9-]*$`
- Must be lowercase with hyphens only

### 2b. Version format

- Must follow semver: `X.Y.Z` (digits only, no `v` prefix)

### 2c. Repository validation

- Fetch the repository URL — confirm it exists and is publicly accessible
- Confirm the repository contains a `preset.yml` file
- Confirm the repository contains a `LICENSE` file
Expand Down Expand Up @@ -163,6 +166,7 @@ preset** — not just any file named `README.md`, and not a product/framework pi
`specify preset add ...` command for this preset; otherwise it fails check 2d above.

### 2e. Release and download URL validation

- The download URL MUST belong to the submitted repository
(`https://github.com/<owner>/<repo>/...` with the same `<owner>/<repo>` as
the Repository URL). Reject URLs for any other GitHub repository.
Expand All @@ -187,18 +191,21 @@ preset** — not just any file named `README.md`, and not a product/framework pi
- Verify a GitHub release exists for that tag.

### 2f. Submission checklists

- Confirm that all required checkboxes in the Testing Checklist and Submission
Requirements sections are checked (`[x]`)

### Validation outcome

If **any** validation fails:

1. Add a comment on the issue listing each failed check with a clear explanation
of what's wrong and how to fix it
2. Add the `validation-failed` label
3. **Stop — do not proceed further**

If all validations pass:

1. Add the `validation-passed` label
2. Continue to Step 3

Expand Down Expand Up @@ -267,6 +274,7 @@ Replace only the changed fields (typically `version`, `download_url`,
### Counting templates and commands

Parse the "Templates Provided" and "Commands Provided" issue fields:

- Count the number of list items (lines starting with `-`)
- If the field says "None", the count is 0

Expand All @@ -292,11 +300,12 @@ Presets table.

Insert a new row in **alphabetical order by preset name**:

```
```markdown
| <Name> | <Description> | <N> templates, <N> commands | <Requires> | [<repo-name>](<repository-url>) |
```

For the Requires column:

- Use `—` if no extensions are required
- List required extension names if any (e.g., `AIDE extension`)

Expand All @@ -316,7 +325,8 @@ Create a pull request with the changes. Use this branch naming convention:
### Commit message

For a new preset:
```

```text
Add <Name> preset to community catalog

Add <id> preset submitted by @<issue-author> to:
Expand All @@ -327,7 +337,8 @@ Closes #<issue-number>
```

For an update:
```

```text
Update <Name> preset to v<version>

Update <id> preset submitted by @<issue-author>:
Expand All @@ -340,6 +351,7 @@ Closes #<issue-number>
### PR description

Include:

- A summary of what changed
- Validation results (all checks passed)
- `Closes #${{ github.event.issue.number }}`
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
uses: DavidAnson/markdownlint-cli2-action@21c1be1b93ad9ed58fa840aacc3f279cde2a72ff # v24.2.0
with:
globs: |
'**/*.md'
**/*.md
Comment thread
Copilot marked this conversation as resolved.
Outdated
!extensions/**/*.md

shellcheck:
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ Disclosure is **continuous**, not a one-time event. A single AI-disclosure parag

- **Every commit you author must carry an `Assisted-by:` trailer** identifying the agent and whether it acted autonomously or under direct human supervision, for example:

```
```text
Assisted-by: GitHub Copilot (model: <name-if-known>, autonomous)
```

Expand Down
Loading