mirror of
https://github.com/mattpocock/skills.git
synced 2026-09-12 18:38:06 +07:00
refactor: flatten skills/ and adopt Agent Plugins 1.0
The Agent Plugins standard reads only the immediate children of skills/ and cannot be pointed elsewhere, so a bucketed tree is invisible to every conformant client. Rather than generate a flat copy of the repo into a package directory — a builder, a validator, an allowlist, a drift CI job, and every skill committed twice — remove the buckets. - skills/ is flat and holds exactly the promoted 25 - in-progress/ -> drafts/, misc/ -> extras/, deprecated/ deleted - new root plugin.json (Agent Plugins 1.0) - .claude-plugin/plugin.json loses its 25-entry skills array - docs/ keeps its category folders; it is now the only place a skill's category lives Reasoning in .agents/adr/0003. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
84fdeffd12
commit
a16a2674bc
@@ -5,7 +5,8 @@ set -euo pipefail
|
||||
# It is not a supported installer. Modifications to it — or requests for
|
||||
# modifications — will not be approved.
|
||||
#
|
||||
# Links all skills in the repository into the local skill directories used by
|
||||
# Links every skill in the repository — promoted (`skills/`) as well as
|
||||
# unpromoted (`drafts/`, `extras/`) — into the local skill directories used by
|
||||
# each agent harness:
|
||||
# - ~/.claude/skills — Claude Code
|
||||
# - ~/.agents/skills — Codex and other Agent Skills-compatible harnesses
|
||||
@@ -22,7 +23,7 @@ while IFS= read -r -d '' skill_md; do
|
||||
src="$(dirname "$skill_md")"
|
||||
names+=("$(basename "$src")")
|
||||
srcs+=("$src")
|
||||
done < <(find "$REPO/skills" -name SKILL.md -not -path '*/node_modules/*' -not -path '*/deprecated/*' -print0)
|
||||
done < <(find "$REPO/skills" "$REPO/drafts" "$REPO/extras" -maxdepth 2 -name SKILL.md -not -path '*/node_modules/*' -print0)
|
||||
|
||||
for DEST in "${DESTS[@]}"; do
|
||||
# If $DEST is a symlink that resolves into this repo, we'd end up writing the
|
||||
|
||||
@@ -1,41 +1,55 @@
|
||||
#!/usr/bin/env node
|
||||
// Copies package.json's version into .claude-plugin/plugin.json.
|
||||
// Copies package.json's version into every plugin manifest:
|
||||
// plugin.json — the Agent Plugins 1.0 manifest
|
||||
// .claude-plugin/plugin.json — the Claude Code manifest
|
||||
// Runs as part of `npm run version`, immediately after `changeset version`.
|
||||
// With --check it changes nothing and exits 1 if the two versions differ.
|
||||
// With --check it changes nothing and exits 1 if any version differs.
|
||||
|
||||
import { readFileSync, writeFileSync } from "node:fs";
|
||||
import { dirname, join } from "node:path";
|
||||
import { dirname, join, relative } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const repo = join(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const pluginPath = join(repo, ".claude-plugin", "plugin.json");
|
||||
const manifests = [
|
||||
join(repo, "plugin.json"),
|
||||
join(repo, ".claude-plugin", "plugin.json"),
|
||||
];
|
||||
|
||||
const { version } = JSON.parse(readFileSync(join(repo, "package.json"), "utf8"));
|
||||
const source = readFileSync(pluginPath, "utf8");
|
||||
const plugin = JSON.parse(source);
|
||||
const check = process.argv.includes("--check");
|
||||
let failed = false;
|
||||
|
||||
if (plugin.version === version) {
|
||||
console.log(`plugin.json version is ${version} — already in sync`);
|
||||
process.exit(0);
|
||||
}
|
||||
for (const path of manifests) {
|
||||
const name = relative(repo, path);
|
||||
const source = readFileSync(path, "utf8");
|
||||
const manifest = JSON.parse(source);
|
||||
|
||||
if (process.argv.includes("--check")) {
|
||||
console.error(
|
||||
`plugin.json version is ${plugin.version}, package.json is ${version}. Run \`node scripts/sync-plugin-version.mjs\`.`,
|
||||
if (manifest.version === version) {
|
||||
console.log(`${name} version is ${version} — already in sync`);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (check) {
|
||||
console.error(
|
||||
`${name} version is ${manifest.version}, package.json is ${version}. Run \`node scripts/sync-plugin-version.mjs\`.`,
|
||||
);
|
||||
failed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Rewrite only the version line, to keep the key order and the formatting.
|
||||
const updated = source.replace(
|
||||
/("version"\s*:\s*")[^"]*(")/,
|
||||
`$1${version}$2`,
|
||||
);
|
||||
process.exit(1);
|
||||
|
||||
if (JSON.parse(updated).version !== version) {
|
||||
console.error(`Could not find a version field to replace in ${path}.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
writeFileSync(path, updated);
|
||||
console.log(`${name} version ${manifest.version} -> ${version}`);
|
||||
}
|
||||
|
||||
// Rewrite only the version line, to keep the key order and the formatting.
|
||||
const updated = source.replace(
|
||||
/("version"\s*:\s*")[^"]*(")/,
|
||||
`$1${version}$2`,
|
||||
);
|
||||
|
||||
if (JSON.parse(updated).version !== version) {
|
||||
console.error(`Could not find a version field to replace in ${pluginPath}.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
writeFileSync(pluginPath, updated);
|
||||
console.log(`plugin.json version ${plugin.version} -> ${version}`);
|
||||
process.exit(failed ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user