Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
"plugins": [
{
"name": "firstdraft",
"source": "./skills/create-full-stack-app",
"strict": false,
"skills": [
"./"
],
"version": "0.1.0-alpha.3",
"source": {
"source": "npm",
"package": "@firstdraft.com/claude-code",
"version": "0.1.0-alpha.3",
"registry": "https://registry.npmjs.org/"
},
"displayName": "First Draft",
"description": "Experimental Foundation Plan authoring and bounded Rails application creation with First Draft",
"author": {
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
Expand All @@ -34,6 +35,7 @@ jobs:
fetch-depth: 0
path: tmp/firstdraft-cli
persist-credentials: false
- run: git -C tmp/firstdraft-cli merge-base --is-ancestor f55edffc9e88924f9a4c95f41c4d0bc9b72422f8 HEAD
- run: git -C tmp/firstdraft-cli checkout --detach f55edffc9e88924f9a4c95f41c4d0bc9b72422f8
- run: git -C tmp/firstdraft-cli merge-base --is-ancestor e53eb38d7e8254e6ba1e660b38c5d32d0314be17 HEAD
- run: git -C tmp/firstdraft-cli checkout --detach e53eb38d7e8254e6ba1e660b38c5d32d0314be17
- run: node script/check-cli-contract.mjs tmp/firstdraft-cli
- run: node script/check-claude-plugin-package.mjs --cli-root tmp/firstdraft-cli
127 changes: 127 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: Publish Claude plugin

on:
push:
tags: ["claude-v*"]

permissions: {}

concurrency:
group: claude-plugin-npm-publish
cancel-in-progress: false

jobs:
verify:
name: Verify release
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.18.0
package-manager-cache: false
- name: Verify tag and source commit
run: |
set -euo pipefail
test "$GITHUB_REPOSITORY" = "firstdraft/skills"
test "$GITHUB_EVENT_NAME" = "push"
test "$GITHUB_REF_TYPE" = "tag"
test "$GITHUB_REF_PROTECTED" = "true"
release_sha="$(git rev-parse 'HEAD^{commit}')"
event_sha="$(git rev-parse "${GITHUB_SHA}^{commit}")"
test "$release_sha" = "$event_sha"
git fetch --force --no-tags origin \
"+refs/heads/main:refs/remotes/origin/main" \
"+refs/tags/${GITHUB_REF_NAME}:refs/release-check/tag"
test "$release_sha" = "$(git rev-parse 'refs/release-check/tag^{commit}')"
package_version="$(node --print 'JSON.parse(require("node:fs").readFileSync("packages/claude-plugin/package.template.json", "utf8")).version')"
test "$GITHUB_REF_NAME" = "claude-v$package_version"
git rev-list --first-parent refs/remotes/origin/main > "$RUNNER_TEMP/main-first-parent"
grep -Fqx "$release_sha" "$RUNNER_TEMP/main-first-parent"
- run: npm ci --ignore-scripts
- run: npm audit
- run: npm run check
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: firstdraft/cli
ref: main
fetch-depth: 0
path: tmp/firstdraft-cli
persist-credentials: false
- run: git -C tmp/firstdraft-cli merge-base --is-ancestor e53eb38d7e8254e6ba1e660b38c5d32d0314be17 HEAD
- run: git -C tmp/firstdraft-cli checkout --detach e53eb38d7e8254e6ba1e660b38c5d32d0314be17
- run: node script/claude-plugin-package.mjs pack "$RUNNER_TEMP/plugin" --cli-root tmp/firstdraft-cli

publish:
name: Publish to npm
needs: verify
runs-on: ubuntu-latest
timeout-minutes: 10
environment: npm
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: 24.18.0
package-manager-cache: false
registry-url: https://registry.npmjs.org/
- name: Verify approved release
env:
NPM_RELEASE_ENABLED: ${{ vars.NPM_RELEASE_ENABLED }}
run: |
set -euo pipefail
test "$NPM_RELEASE_ENABLED" = "true"
test "$GITHUB_REPOSITORY" = "firstdraft/skills"
test "$GITHUB_EVENT_NAME" = "push"
test "$GITHUB_REF_TYPE" = "tag"
test "$GITHUB_REF_PROTECTED" = "true"
release_sha="$(git rev-parse 'HEAD^{commit}')"
event_sha="$(git rev-parse "${GITHUB_SHA}^{commit}")"
test "$release_sha" = "$event_sha"
git fetch --force --no-tags origin \
"+refs/heads/main:refs/remotes/origin/main" \
"+refs/tags/${GITHUB_REF_NAME}:refs/release-check/tag"
test "$release_sha" = "$(git rev-parse 'refs/release-check/tag^{commit}')"
package_version="$(node --print 'JSON.parse(require("node:fs").readFileSync("packages/claude-plugin/package.template.json", "utf8")).version')"
test "$GITHUB_REF_NAME" = "claude-v$package_version"
git rev-list --first-parent refs/remotes/origin/main > "$RUNNER_TEMP/main-first-parent"
grep -Fqx "$release_sha" "$RUNNER_TEMP/main-first-parent"
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: firstdraft/cli
ref: main
fetch-depth: 0
path: tmp/firstdraft-cli
persist-credentials: false
- run: git -C tmp/firstdraft-cli merge-base --is-ancestor e53eb38d7e8254e6ba1e660b38c5d32d0314be17 HEAD
- run: git -C tmp/firstdraft-cli checkout --detach e53eb38d7e8254e6ba1e660b38c5d32d0314be17
- name: Verify CLI release is published
run: |
set -euo pipefail
cli_version="$(node --print 'JSON.parse(require("node:fs").readFileSync("tmp/firstdraft-cli/package.json", "utf8")).version')"
test "$(npm view "@firstdraft.com/cli@$cli_version" version)" = "$cli_version"
- run: node script/claude-plugin-package.mjs pack "$RUNNER_TEMP/plugin" --cli-root tmp/firstdraft-cli
- name: Verify publication bytes
run: |
set -euo pipefail
package_version="${GITHUB_REF_NAME#claude-v}"
tarball="$RUNNER_TEMP/plugin/firstdraft.com-claude-code-$package_version.tgz"
expected="$(node --print 'JSON.parse(require("node:fs").readFileSync("release/compatibility.json", "utf8")).plugin_source.tarball_sha256')"
actual="$(shasum -a 256 "$tarball" | awk '{print $1}')"
test "$actual" = "$expected"
- name: Publish verified package
run: npm publish "$RUNNER_TEMP/plugin/firstdraft.com-claude-code-${GITHUB_REF_NAME#claude-v}.tgz" --access public --tag next --provenance --ignore-scripts
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
18 changes: 18 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Agent Instructions — First Draft Skills

## Release coordination

- Treat a merge to `main` as integration, not release authorization. After merging, report the exact merged SHA and
ask whether to coordinate a candidate across `firstdraft`, `cli`, and `skills` and promote it.
- SemVer compatibility establishes candidate eligibility only. Record the exact SHA of every repository and the
packed Claude plugin SHA-256, then follow [`RELEASING.md`](RELEASING.md).
- Do not publish npm packages, deploy First Draft, or release the plugin without explicit user approval. If the user
declines promotion, identify the merged SHA as unpromoted.
- Never reuse a published npm version or marketplace SemVer with different package bytes. Revisions and corrections
use a new version.
- Keep deployment, package publication, marketplace promotion, and replay mutations serialized through one
operator. Reconcile an ambiguous publication or push outcome read-only before retrying.
- Before pushing a `claude-v*` publication tag, verify its protection ruleset, the `npm` environment's required
reviewers, and the deliberately enabled `NPM_RELEASE_ENABLED` gate.
- The installable Claude package is assembled from the canonical Skill during packing. Do not commit a second
editable copy under `packages/`.
Loading