Files
openprose__prose/scripts/bump-version.sh
T
Jose Montes de Oca 93e91325d7 feat: ship OpenProse as first-class Claude + Codex plugin (#46)
OpenProse already installed as a Claude Code plugin via
`npx skills add openprose/prose`, but the packaging surface was
uneven: missing manifest fields, no native Codex envelope, no
plugin-track release process, and a couple of doc/audience
inconsistencies. This commit closes those gaps without changing
skill behavior.

OpenProse now ships from the repo root as a dual-host plugin
envelope — `.claude-plugin/` for Claude Code, `.codex-plugin/`
plus `.agents/plugins/` for Codex — with `skills/open-prose/`
as the shared core and `prose ...` as the only user-facing
command surface.

Codex envelope:
- .codex-plugin/plugin.json with first-class catalog metadata
  (displayName, developer, descriptions, category, capabilities,
  defaultPrompt, privacy/terms URLs).
- .agents/plugins/marketplace.json local-source catalog, installable
  by anyone who clones this repo.

Claude Code manifest hygiene:
- Added license, homepage, and skills: ./skills so the plugin is
  self-describing.
- Added marketplace.json metadata.description, clearing the sole
  `claude plugin validate` warning.
- Deleted the stale .claude-plugin/README.md.

Skill metadata:
- Added license: MIT to skills/open-prose/SKILL.md frontmatter
  (no top-level version — Claude Code strips unrecognized top-level
  frontmatter keys; see anthropics/claude-code#13005).
- Fixed an inconsistent parse-table cell pair in
  skills/open-prose/deps.md.

Audience boundaries:
- AGENTS.md is now contributor-only per agents.md.
- Recommended consumer [agents] Codex config moved to README.md
  alongside the Quickstart.

Release process:
- scripts/bump-version.sh + .version-bump.json bump both manifests
  atomically, with a --check mode for CI. The Claude Code
  marketplace deduplicates by version, so a forgotten bump silently
  strands users on cached copies; this gate prevents that.
- scripts/extract-changelog.sh pulls a single `## [X.Y.Z]` block
  out of CHANGELOG.md.
- RELEASE.md documents the manual flow.
- .github/workflows/release.yml verifies declared versions match
  on `v*` tag push and publishes a GitHub Release.

CI:
- New plugin-manifest.yml: every-PR gate validating both plugin.json
  files, asserting declared skills paths resolve, and running
  bump-version.sh --check.
- cli-skills-smoke.yml: added `npx skills list openprose/prose`
  discoverability check alongside the existing install smoke.
- openprose-smoke/run.ts: removed a dead commands/prose-*.md regex.
2026-04-30 20:31:48 -07:00

73 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Bump the OpenProse plugin version atomically across declared files.
#
# Usage:
# ./scripts/bump-version.sh 0.11.0 # bump every declared file to 0.11.0
# ./scripts/bump-version.sh --check # exit 0 iff every declared file matches
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONFIG="$REPO_ROOT/.version-bump.json"
if [[ ! -f "$CONFIG" ]]; then
echo "error: $CONFIG not found" >&2
exit 2
fi
mode="${1:-}"
if [[ -z "$mode" ]]; then
echo "usage: $0 <version> | --check" >&2
exit 2
fi
read_field() {
local path="$1" field="$2"
jq -r ".${field}" "$REPO_ROOT/$path"
}
write_field() {
local path="$1" field="$2" value="$3"
local tmp
tmp="$(mktemp)"
jq --arg v "$value" ".${field} = \$v" "$REPO_ROOT/$path" > "$tmp"
mv "$tmp" "$REPO_ROOT/$path"
}
case "$mode" in
--check)
declared_versions=()
while IFS= read -r entry; do
path="$(jq -r '.path' <<<"$entry")"
field="$(jq -r '.field' <<<"$entry")"
v="$(read_field "$path" "$field")"
echo "$path:$field = $v"
declared_versions+=("$v")
done < <(jq -c '.files[]' "$CONFIG")
first="${declared_versions[0]}"
for v in "${declared_versions[@]}"; do
if [[ "$v" != "$first" ]]; then
echo "error: declared versions disagree (saw $v, expected $first)" >&2
exit 1
fi
done
echo "ok: all declared files at $first"
;;
--*)
echo "unknown mode: $mode" >&2
exit 2
;;
*)
new="$mode"
if [[ ! "$new" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "error: version must be X.Y.Z (got $new)" >&2
exit 2
fi
while IFS= read -r entry; do
path="$(jq -r '.path' <<<"$entry")"
field="$(jq -r '.field' <<<"$entry")"
write_field "$path" "$field" "$new"
echo "bumped $path:$field = $new"
done < <(jq -c '.files[]' "$CONFIG")
;;
esac