Skip to content

feat(cli): skillforge update <path> --bump|--new-version for SKILL.md version bumps - #12

Merged
adityachilka1 merged 1 commit into
mainfrom
feat/update
May 23, 2026
Merged

feat(cli): skillforge update <path> --bump|--new-version for SKILL.md version bumps#12
adityachilka1 merged 1 commit into
mainfrom
feat/update

Conversation

@adityachilka1

Copy link
Copy Markdown
Owner

What

skillforge update <path> — bump the version: field of a SKILL.md without hand-editing the frontmatter. Fifth piece of the authoring workflow after init, validate, pack, install, and lint.

# Bump by direction
skillforge update ./code-review --bump patch
# ✓ ./code-review/SKILL.md: 0.1.0 → 0.1.1

# Or set an explicit version
skillforge update ./code-review/SKILL.md --new-version 1.0.0
# ✓ ./code-review/SKILL.md: 0.1.1 → 1.0.0

# Preview without writing
skillforge update ./code-review --bump minor --dry-run
# dry-run ./code-review/SKILL.md: 0.1.1 → 0.2.0 (nothing written)

Semantics

Case Behaviour
--bump patch from 1.2.3 1.2.4
--bump minor from 1.2.3 1.3.0
--bump major from 1.2.3 2.0.0
--bump <any> from 1.2.3-beta drops prerelease, then bumps (matches npm version)
--bump patch with no version: field treats baseline as 0.0.1 (schema default), result 0.0.2
--new-version 2.0.0-rc.1 sets verbatim, prerelease respected
--new-version notsemver exits 1 with error
both --bump and --new-version exits 1 with error (mutually exclusive)
neither flag exits 1 with error
missing file / directory without SKILL.md exits 1 with error
resulting frontmatter fails schema refuses to write, file untouched

--dry-run reports the would-be new version and writes nothing.

Body preservation

gray-matter.stringify() re-emits YAML through js-yaml, which has opinions about quoting, block-scalar style, and key spacing. Round-tripping a human-authored SKILL.md through it almost always changes something — fine for newly-scaffolded files, lossy for files a human just edited.

So update does NOT round-trip. It parses the file with gray-matter only to read the current version, then performs a line-surgical edit of just the version: line in the original raw text. Body bytes, field order, comments, and the rest of the YAML formatting are preserved byte-for-byte. If there's no version: line at all (schema-default case), one is inserted immediately after the opening --- fence so it sits next to name:/description:.

A dedicated test (leaves the body bytes byte-for-byte identical (prose + code blocks + lists)) writes a rich body (italics, bold, nested bullets, ordered list, fenced python code, blockquote, link, trailing line) and asserts byte equality after a patch bump.

Validation

The proposed frontmatter is validated against SkillFrontmatterSchema before anything hits disk. If the file already had a problem the bump can't fix (e.g. a description under 20 chars), the command exits 1 with the schema error and the file is left untouched — never a half-written, schema-invalid SKILL.md on disk.

Exit codes

Situation Exit
Successful bump or dry-run 0
Any failure (bad flags, missing file, bad semver, schema fail) 1

Same posture as init/validate/pack/install/lint.

Surface

  • src/update.tsupdateSkillVersion() + bumpVersion() + line-surgical writer. ~190 LOC.
  • src/update.test.ts — 27 tests covering each bump direction, schema-default baseline, prerelease stripping, dry-run, --new-version happy + sad paths, rich-body preservation, frontmatter field-order + colon-spacing preservation, file-not-found, dir-without-SKILL.md, mutual exclusion (both flags + neither), schema-refusal.
  • src/cli.ts — new update subcommand with --bump, --new-version, --dry-run.
  • src/index.ts — re-exports updateSkillVersion, bumpVersion, BumpKind, UpdateOptions, UpdateResult.
  • README.md — new ### skillforge update <path> section; status line updated.
  • CHANGELOG.mdUnreleased entry (no version-section migration; that's a release-prep PR).

No new runtime deps — reuses gray-matter, zod, kleur, cac already on the tree. Lockfile untouched.

Test plan

Check Status
pnpm typecheck (tsc --noEmit) clean
pnpm lint (biome) clean
pnpm test (vitest) 84/84 pass (27 new + 57 existing)
pnpm build (tsup) ESM + DTS build success
Smoke: ./dist/cli.js update ./tmp-skill --bump patch --dry-run dry-run … 0.4.2 → 0.4.3 (nothing written), file unchanged
Smoke: ./dist/cli.js update … --bump minor 0.4.2 → 0.5.0, file version: 0.5.0
Smoke: ./dist/cli.js update … --new-version 1.0.0 0.5.0 → 1.0.0
Smoke: ./dist/cli.js update … --new-version notsemver exit 1, schema error
Smoke: ./dist/cli.js update … --bump patch --new-version 1.2.3 exit 1, mutex error

On a --fix / autocommit follow-up

Out of scope here. Natural next step is a --commit flag that opens an editor on the resulting frontmatter (or just git add SKILL.md && git commit -m "chore: bump to vX.Y.Z"), but the v1 of this command should stay a pure file rewrite — composes cleanly with whatever VCS workflow the author already has.

Declaration of AI-Tools / LLMs usage

  • Claude (Opus) for design, implementation, tests, commit message, this PR body — reviewed by @adityachilka1 before push.

Fifth piece of the SKILL.md authoring workflow after init, validate,

pack, install, and lint. Bumps the version: field of a SKILL.md in

one shot — either --bump <patch|minor|major> or --new-version <semver>,

mutually exclusive. Pre-release tags drop on any bump (npm-style). A

missing version field is treated as the schema default 0.0.1 so patch

on a freshly-scaffolded skill produces 0.0.2. Validates the proposed

frontmatter against the schema before touching disk; line-surgical

write preserves body bytes and YAML formatting byte-for-byte.
@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@adityachilka1, we couldn't start this review because you've used your available PR reviews for now.

Your plan currently allows 1 review/hour. Refill in 31 minutes and 46 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 724d08b0-dd2b-4b06-9a13-e1650507087c

📥 Commits

Reviewing files that changed from the base of the PR and between 0e613f3 and b1d8788.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • README.md
  • src/cli.ts
  • src/index.ts
  • src/update.test.ts
  • src/update.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/update

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 and usage tips.

@adityachilka1
adityachilka1 merged commit acbd282 into main May 23, 2026
4 checks passed
@adityachilka1
adityachilka1 deleted the feat/update branch May 23, 2026 10:59
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.

2 participants