diff --git a/CHANGELOG.md b/CHANGELOG.md index f30e80c..c2873df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ Format: [Keep a Changelog](https://keepachangelog.com). Versioning: semver — for skills *and* for this CLI, breaking prompt changes are breaking changes. +## [0.24.1] — 2026-08-12 + +### Fixed +- **A skill name with a doubled or trailing hyphen was only ever flagged for Zed.** KSF's own name rule permits `tidy--commits` and `tidy-`, but the [Agent Skills spec](https://agentskills.io/specification) — the shared authority every skills-directory target defers to, Claude Code, Codex, Copilot, Cline, Zed, Gemini CLI and Agent Plugins alike — forbids a leading, trailing or consecutive hyphen outright. So a name that only Zed complained about could in fact be refused by all of them, and several refuse without saying anything. It is now reported once against the skill, at `install`, `lint` and `test`, naming the spec rather than a single target. A warning, not a failure: the name is valid KSF and still compiles, and `--strict` escalates it like any other warning. + ## [0.24.0] — 2026-08-12 A verification pass over every claim the compiler makes about the agents it targets, checked against each client's own source or documentation. **All eleven loading modes are correct** — the 14×–47× standing-cost benchmark stands — but three claims around them were overstated, and one of them was in the published numbers. diff --git a/README.md b/README.md index d239a85..a420ca9 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Already have skills? A plain SKILL.md folder — the skills.sh / Claude Skills c Already carrying a hand-written `CLAUDE.md`, `.cursor/rules/`, `AGENTS.md`, and the rest of the copy-per-agent set? `kitbash import` reads them back into a single skill, measures what each one costs in standing context, and reports where the copies have drifted apart — so `kitbash compile` can regenerate them all from that one source. It touches nothing on disk until you remove the originals yourself. -**Status.** v0.24.0, on npm and Homebrew, zero runtime dependencies, Node 20+. The KSF core is frozen and additive-only within the major version ([RFC 0002](rfcs/0002-ksf-1.0-stabilization.md)). Everything around it is early and labeled as such: `init`, `import`, `install`, `remove`, `list`, `compile`, `doctor`, `update`, `diff`, `lint`, `preview`, `explain`, and `test` work today; `audit`, `gate`, `search`, `publish`, `lore`, and `run` exit `7` and are on the [roadmap](docs/roadmap.md). One first-party skill ships (`prereview`); six more are specified but not built. Adoption is single-digit stars — if the measurement above is what you want, you are early. +**Status.** v0.24.1, on npm and Homebrew, zero runtime dependencies, Node 20+. The KSF core is frozen and additive-only within the major version ([RFC 0002](rfcs/0002-ksf-1.0-stabilization.md)). Everything around it is early and labeled as such: `init`, `import`, `install`, `remove`, `list`, `compile`, `doctor`, `update`, `diff`, `lint`, `preview`, `explain`, and `test` work today; `audit`, `gate`, `search`, `publish`, `lore`, and `run` exit `7` and are on the [roadmap](docs/roadmap.md). One first-party skill ships (`prereview`); six more are specified but not built. Adoption is single-digit stars — if the measurement above is what you want, you are early.

npm version diff --git a/packages/cli/package.json b/packages/cli/package.json index 4e4f837..b24e262 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "kitbash", - "version": "0.24.0", + "version": "0.24.1", "description": "The package manager and compiler for AI agent skills — write once, run in every coding agent", "license": "Apache-2.0", "author": "Harsh Singh", diff --git a/packages/cli/scripts/test.mjs b/packages/cli/scripts/test.mjs index 0083046..e5f5288 100644 --- a/packages/cli/scripts/test.mjs +++ b/packages/cli/scripts/test.mjs @@ -1921,6 +1921,36 @@ try { rmSync(nameTmp, { recursive: true, force: true }); } +// ── the Agent Skills naming rule, checked once per skill ──────────────────── +// KSF permits `tidy--commits` and `tidy-`; the Agent Skills spec every skills +// directory target follows does not. Several hosts drop such a skill silently, +// so it is worth saying once about the skill rather than once per target. +const nmTmp = mkdtempSync(join(tmpdir(), "kitbash-specname-")); +try { + const bad = join(nmTmp, "bad"); + mkdirSync(bad, { recursive: true }); + writeFileSync(join(bad, "skill.toml"), '[skill]\nname = "tidy--commits"\nversion = "1.0.0"\ndescription = "A skill whose name has a doubled hyphen"\n[context]\nbudget = 1500\n'); + writeFileSync(join(bad, "SKILL.md"), "# Tidy\n\nBody.\n"); + const l = run(["lint", `file:${bad}`], nmTmp); + check("spec-name: a doubled hyphen is reported", l.out.includes("name-convention"), l.out); + check("spec-name: it warns rather than fails", l.status === 0 && l.out.includes("0 failure(s)"), l.out); + check("spec-name: --strict escalates it", run(["lint", "--strict", `file:${bad}`], nmTmp).status === 1); + + const trail = join(nmTmp, "trail"); + mkdirSync(trail, { recursive: true }); + writeFileSync(join(trail, "skill.toml"), '[skill]\nname = "tidy-"\nversion = "1.0.0"\ndescription = "A skill whose name ends with a hyphen"\n[context]\nbudget = 1500\n'); + writeFileSync(join(trail, "SKILL.md"), "# Tidy\n\nBody.\n"); + check("spec-name: a trailing hyphen is reported", run(["lint", `file:${trail}`], nmTmp).out.includes("name-convention")); + + const ok = join(nmTmp, "ok"); + mkdirSync(ok, { recursive: true }); + writeFileSync(join(ok, "skill.toml"), '[skill]\nname = "tidy-commits"\nversion = "1.0.0"\ndescription = "A skill with a spec-clean name"\n[context]\nbudget = 1500\n'); + writeFileSync(join(ok, "SKILL.md"), "# Tidy\n\nBody.\n"); + check("spec-name: a clean name is silent", !run(["lint", `file:${ok}`], nmTmp).out.includes("name-convention")); +} finally { + rmSync(nmTmp, { recursive: true, force: true }); +} + if (failures) { console.error(`\n${failures} test(s) failed`); process.exit(1); diff --git a/packages/cli/src/commands.ts b/packages/cli/src/commands.ts index 6224a50..2ecfac7 100644 --- a/packages/cli/src/commands.ts +++ b/packages/cli/src/commands.ts @@ -27,6 +27,15 @@ const VERSION: string = createRequire(import.meta.url)("../package.json").versio */ // "mcp" is here because a declared MCP server is a request to run third-party // code with the agent's permissions — a heavier ask than anything in a body. +/** + * The Agent Skills naming rule (agentskills.io/specification): 1-64 chars, + * lowercase alphanumerics and hyphens, no leading, trailing or consecutive + * hyphen. KSF's NAME_RE is stricter in some ways (must start with a letter, + * capped at 41) and looser in exactly one: it permits `tidy--commits` and + * `tidy-`. This is the spec's rule, used to warn about that gap. + */ +const SPEC_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/; + const SAFETY_LINTS = new Set(["visible-text", "dynamic-context", "remote-exec", "secrets", "mcp"]); const INIT_CONFIG = `# kitbash project configuration — https://github.com/singhharsh1708/kitbash @@ -1115,6 +1124,22 @@ function staticChecks(skill: LoadedSkill): Check[] { checks.push({ name: "manifest", ok: true, warn: skill.bare, detail: skill.bare ? "unmanifested (SKILL.md only) — defaults applied" : `${m.skill.name}@${m.skill.version}` }); + // KSF's own name rule is looser than the Agent Skills spec every skills + // directory target follows: the spec forbids a leading, trailing or doubled + // hyphen, so `tidy--commits` and `tidy-` are legal KSF names that Claude Code, + // Codex, Copilot, Cline, Zed, Gemini and Agent Plugins may all refuse. Some of + // them refuse silently, which makes this worth saying once about the skill + // rather than once per target. A warning, not a failure — the name is valid + // KSF, and the compiler will still emit it. + if (!SPEC_NAME_RE.test(m.skill.name)) { + checks.push({ + name: "name-convention", + ok: true, + warn: true, + detail: `"${m.skill.name}" has a leading, trailing or doubled hyphen. The Agent Skills spec allows neither, so hosts reading a skills directory may drop it — several without saying so.`, + }); + } + // templates / dead references let body: string | undefined; try { diff --git a/site/changelog.html b/site/changelog.html index ab8a636..213f8a0 100644 --- a/site/changelog.html +++ b/site/changelog.html @@ -91,7 +91,7 @@

Changelog

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.24.0Current CLI version
+
v0.24.1Current CLI version
8Compile targets
Apache-2.0License
@@ -105,10 +105,19 @@

Changelog

Confirm with kitbash --version, which reads the installed package.json. Install and uninstall routes are covered on the installation page.

+
+
+

v0.24.1

+ 2026-08-12latest +
+

Fixed

+ +
+

v0.24.0

- 2026-08-12latest + 2026-08-12

A verification pass over every claim the compiler makes about the agents it targets, checked against each client's own source or documentation. All eleven loading modes are correct — the 14×–47× standing-cost benchmark stands — but three claims around them were overstated, and one of them was in the published numbers.

Fixed

diff --git a/site/index.html b/site/index.html index cd8c0d5..54b3c85 100644 --- a/site/index.html +++ b/site/index.html @@ -151,7 +151,7 @@ -

Open format for AI agent skills · v0.24.0 · stable spec (RFC 0002)

+

Open format for AI agent skills · v0.24.1 · stable spec (RFC 0002)

Write an agent skill once. Run it everywhere.