Changelog
Every release of the Kitbash CLI, newest first. Nothing is summarised here โ this is the shipped record.
Releases follow Keep a Changelog and semver โ for skills and for this CLI, breaking prompt changes are breaking changes. The CLI is published to npm as kitbash and to Homebrew via singhharsh1708/tap. Tagged builds are on the GitHub releases page.
v0.9.0Current CLI version
8Compile targets
Apache-2.0License
To move to the current version:
# npm
npm install -g kitbash@latest
# Homebrew
brew update && brew upgrade kitbash
Confirm with kitbash --version, which reads the installed package.json. Install and uninstall routes are covered on the installation page.
Conformance and honesty release. A codebase audit found a consistent pattern: the JSON schema was treated as the contract, but the loader enforced almost none of it, and several layers advertised enforcement they never delivered. This closes that gap.
Fixed
- Adapters no longer claim capabilities they don't deliver.
claude-code declared scripts/hooks/subagents and the skill-directory adapters declared scripts, but emit() only writes SKILL.md โ no scripts/ copied, no hook, no subagent. Because the capability was in the set, degradation was computed as empty and explain/--strict reported full support for output referencing files that were never produced โ the exact silent capability loss spec ยง2 forbids. Capability sets are now empty until the emit code that delivers a capability exists; a skill that requires one now correctly reports degraded. - The manifest loader enforces the schema instead of silently coercing. A scalar where the schema types an array (
commands = "/deploy") became [] (a slash command that never registered, permissions that evaporated); a fractional budget passed the range check; an unknown disclosure silently became lazy. These are now hard errors, and an unknown targets.mode warns at test (forward-compatible table, per RFC 0002). - Safety lints scan the whole skill, not just
SKILL.md. The three install-blocking lints read only the body while install copies the entire directory โ a curl โฆ | sh in scripts/setup.sh, or hidden text in a sibling file, sailed straight through. Every non-binary file is now scanned; a symlink is flagged (it points outside the reviewed files). - A malformed installed manifest no longer bricks every command. One hand-edited
skill.toml made list/compile/doctor exit before processing valid siblings โ and doctor threw before the integrity check that exists to catch exactly that tamper. doctor now reports the load failure, counts it, and still runs drift detection. compile refuses to run with zero resolved targets (e.g. targets = []) rather than pruning every generated file while writing nothing back.- Pruning removes only the generated file, never a user file colocated in a generated skill directory (a
NOTES.md beside SKILL.md survives). - Integrity hashing is symlink-aware.
walk() skipped symlinks entirely, so repointing one inside an installed skill was invisible drift; the link target is now hashed without being followed. preview errors on a bad [project].targets instead of silently falling back to every adapter.
Added
- Declared permissions are compiled into the instruction body. Spec ยง2 requires permissions be enforced natively or compiled into the instructions; only the install-review third was done, so a teammate who pulled the generated file saw no restriction. Non-default permissions now render a block into every target's output (prose, not native frontmatter โ the KSF tool grammar is provisional).
gate-verdict check: a mode = "gate" skill with no scripts/ and no declared artifact โ nothing to produce a deterministic verdict โ now fails lint/test.
Security fix. The pre-install review gate did not actually block what it flagged.
Fixed
- Safety lints now block
install, not just lint/test. The two hard-fail lints shipped in 0.8.0 (visible-text, dynamic-context) were printed at install as warnings and never stopped it โ so a skill with hidden instructions installed cleanly for anyone without a kitbash.toml, since only a [policy] violation returned non-zero. Failed safety lints are now a hard gate at install: non-bypassable by --yes, enforced with or without a policy file, before anything is written. Schema and quality checks (a malformed artifact ref, a non-slash command) are unchanged โ they still surface at kitbash test and never block an install.
Added
remote-exec lint โ a third hard-fail that catches download-and-execute pipelines hidden in a skill's prose (a "Prerequisites" section, a fenced example): curl โฆ | sh, eval "$(curl โฆ)", base64 -d | sh, PowerShell iex/iwr, save-then-chmod +x-then-run, and remote-archive extract-run. This is the ClawHavoc / ClickFix family โ payloads that live in documentation, not in the manifest a structural lint reads. It is a heuristic, not a proof (c=curl; $c url | sh evades a regex on prose); it raises attacker cost at the point where one skill fans out to nine files. Verified against benign installs (npm install, pip install, curl -o file) to keep false positives out.deny_remote_exec in [policy] โ defaults to on; set false to consciously exempt a trusted internal skill from the remote-exec block. The hidden-text and dynamic-context lints are never exemptible.
Every target that can lazy-load now does. Two adapters were still emitting always-on files for agents that had since grown proper skill directories.
Changed
copilot compiles to .github/skills/<name>/SKILL.md instead of a .github/instructions/*.instructions.md file with applyTo: "**". Copilot reads agentskills.io skills and loads only the frontmatter until the skill is needed; the old form applied to every single request.gemini compiles to .gemini/skills/<name>/SKILL.md instead of merging into GEMINI.md. Gemini CLI injects only each skill's name and description at session start and pulls the body in via its activate_skill tool; Google's own docs describe GEMINI.md as persistent workspace-wide background.- Six of nine targets now lazy-load โ claude-code, cursor, agents, copilot, windsurf/devin, gemini. The eager holdouts are cline, aider and the AGENTS.md floor.
Fixed
- Stale sections in a marker-merged file are now pruned whenever nothing wrote to that file during a compile, not only when the owning skill was uninstalled. Without this, a
GEMINI.md from an older Kitbash kept its generated section forever after the adapter moved. Upgrading cleans up the old GEMINI.md sections and .github/instructions/ files on the next kitbash compile; your own content in those files is untouched.
Added
.github/workflows/release.yml โ a pushed v* tag verifies the tag against the manifest, re-runs the full gate suite, publishes to npm via OIDC trusted publishing (no stored token, provenance attached automatically), and bumps the Homebrew formula.
Ecosystem-correctness release. Two of Kitbash's assumptions about the agent landscape had gone stale, and one of them was flattering its own headline number.
Added
agents adapter โ .agents/skills/<name>/SKILL.md, the vendor-neutral Agent Skills path read by Codex (its only repo path), Cursor, Copilot, Gemini CLI, Roo, Amp, OpenCode, Zed and Antigravity. Lazy-loaded; detected when .agents/ or .codex/ exists. Nine targets total.- Two hard lint failures for instructions a reviewer cannot see or that run before the model reads anything:
visible-text rejects zero-width characters, bidi overrides and the Unicode Tags block; dynamic-context rejects backtick command substitution in a skill body. Both fail lint and test with exit 1, no --strict needed โ Kitbash fans one skill out to nine files, several of them permanently in context. node site/build.mjs --check verifies the committed site output is current; gated in CI, and Vercel now runs the build instead of serving whatever was committed.
Changed
windsurf is lazy, not eager. Windsurf became Devin Desktop on 2026-06-02: the adapter now writes .devin/rules/<name>.md when .devin/ exists (falling back to .windsurf/rules/) and emits trigger: model_decision, so the description sits in context and the body loads on demand.- The benchmark reads each target's loading mode from the adapters themselves rather than a second hardcoded map โ the copy is exactly how published numbers drift from what the compiler emits. Regenerated: four targets now lazy-load, five are eager-only.
- Standing-tax framing corrected throughout: Kitbash compiles to the cheapest loading mode each target actually supports, and the tax is what it costs on targets whose only mode is eager. The 12x/46x gap still holds, measured against the corrected matrix.
Trust & review release: installing a skill means letting someone else's instructions run with your agent's permissions โ this release makes that reviewable and governable.
Added
- Pre-install review gate:
kitbash install prints a review block (permissions incl. network/write, budget, standing, capability requirements, lint warnings incl. injection heuristics) before writing anything, and prompts install? [y/N] on a TTY. --yes/-y skips the prompt; non-interactive runs (CI) proceed as before. [policy] in kitbash.toml โ org-level allowlists: allow_sources (globs matched against gh:owner/repo[/path][@ref] / file: sources), deny_network, deny_write, max_budget. Policy is a hard gate at install (--yes does not bypass it) and doctor rechecks it against already-installed skills.- Remote sources for
preview, lint, and explain: kitbash preview gh:owner/repo/path fetches to a temp dir and renders the exact compiled output per agent โ skills are fully readable before install, no side effects.
Changed
install output: the summary (budget/standing/permissions) moved from after the copy to the review block before it; the post-install lines now just confirm the pin.explain/lint/preview "not found" errors now mention that a source (gh:owner/repo, file:path) is accepted.
Added
- Three v0.2-roadmap commands:
kitbash lint [skill-or-path] [--strict] (full static check suite, works pre-install), kitbash explain <skill-or-path> <adapter> (why a compilation degraded, with the token cost of eager targets), and kitbash preview <skill-or-path> (each adapter's compiled output with per-target token counts, before installing). aider adapter โ marker-merged CONVENTIONS.md (detected via an existing CONVENTIONS.md or .aider.conf.yml) โ 8 targets total.- CI runs on Windows and macOS alongside Linux; fixed the platform-dependent subpath test so the suite is green on all three.
- Site: live terminal replay in the hero and an interactive per-target compile preview.
Fixed
- TOML parser hardening: quoted strings and keys, signed numbers, spaced table headers, invalid-escape guard (
TomlError instead of raw exceptions), plus edge cases around inline values. gh: installer: directory-traversal guard on subpaths; two skills writing the same output path now warn instead of silently overwriting.- Schema bounds enforced (budget โค 20000, standing โค 500, description โค 200 chars); YAML frontmatter values escaped so descriptions with quotes/colons stay valid.
- Cross-platform deterministic integrity hashing โ
kitbash.lock hashes are CRLF/LF-insensitive and path-order stable. doctor flags a missing lockfile and installed-but-unpinned skills.- Standing stub skips markdown headers; unresolved
{{template}} variables error at compile instead of leaking. - UTF-8 BOM stripped from manifests; stray subdirectories under the skills dir no longer crash
list/doctor.
Added
- Homebrew install:
brew install singhharsh1708/tap/kitbash; README install/update/uninstall guide.
Fixed
- Every eager target now reports the standing token cost of a lazy-authored skill, not just the shared-file ones.
Added
- Four new adapters โ
copilot (.github/instructions/*.instructions.md), cline (.clinerules/), windsurf (.windsurf/rules/), gemini (GEMINI.md marker merge) โ 7 targets total. - Commands compilation:
triggers.commands now emit native slash commands (Claude Code .claude/commands/*.md shims). - Generalized marker-merge for shared files (AGENTS.md, GEMINI.md): user content preserved, sections idempotent, stale sections pruned.
- Pruning generalized to written-set semantics across all managed output locations โ covers removed skills and renamed commands.
- README: badges, status-quo-vs-kitbash comparison, FAQ; social preview asset; demo regenerated from a real 7-target session.
Added
kitbash.lock: content-hash pins (sha256 over the skill directory) written on install, dropped on remove.- Integrity drift detection in
kitbash doctor โ exits 1 when installed files differ from the lock. - SKILL.md-only interop (skills.sh / Claude Skills convention): installs directly, manifest synthesized with conservative defaults, flagged
unmanifested at install/list/compile. Verified against real third-party repos. owner/repo shorthand sources (resolve as gh:).- Stale-output pruning on
compile: generated outputs of removed skills are deleted โ only files bearing the generated header are ever touched. kitbash.toml [project].targets honored; unknown targets error.- Animated real-session demo in the README; launch plan in
docs/launch.md.
Changed
- Bare (unmanifested) skills report budget violations as warnings instead of build failures โ their authors never declared those limits.
--version reads package.json.
Added
- KSF spec draft v0.1 (
spec/SPEC.md) with JSON schema; RFC process (rfcs/); RFC-0001. - Working thin slice, zero runtime dependencies:
init, install (gh:/file:), remove, list, compile, doctor. - Adapters:
claude-code, cursor, agentsmd floor (idempotent marker merge). - Context budget and standing-stub enforcement at compile; visible degradation warnings;
--strict. - Template resolution:
{{artifact.*}}/{{lore.*}} compile to path references, {{prompt.*}} inlines. - End-to-end test suite in CI.
- Reference skill
prereview; manifesto; landing page; docs.