@dsalazardev/ai-hub-cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,200 @@
1
+ # skill-migration-brief — how to move one skill to the Claude-5-era rubric
2
+
3
+ This is the working brief for the catalog-wide migration. One agent, one skill, one worktree, one
4
+ branch, one PR. `scripts/skill-rubric.md` is the spec; this is how to apply it to an existing skill.
5
+
6
+ ## Why this exists
7
+
8
+ Anthropic's *The new rules of context engineering for Claude 5 generation models* (Jul 2026) reports
9
+ that >80% of Claude Code's system prompt was removed with no measurable eval loss, and names the
10
+ patterns that stopped paying: **repeating yourself across layers**, **over-constraining with rules
11
+ where judgment suffices**, and **enumerating examples where an expressive interface would do**.
12
+
13
+ Applied here: a skill's `description` is in context on **every turn it is installed**, invoked or
14
+ not. Across 257 skills that was 207 KB. The body is loaded when the skill fires. Both are paid for
15
+ by every user, so length is a cost, never a credit.
16
+
17
+ ## The pass
18
+
19
+ 1. `git checkout -b skill/<id>`
20
+ 2. Read `scripts/skill-rubric.md`, then `skills/<id>/SKILL.md`.
21
+
22
+ ### The description
23
+
24
+ Shape: **what it does · when to use it · an explicit `NOT <x> (that is \`sibling\`)` boundary.**
25
+
26
+ - Delete any `Triggers: '…', '…'` phrase list. The model matches by meaning; keyword lists in three
27
+ languages are pure per-turn cost, and the body usually instructs semantic matching right next to
28
+ them — a self-contradiction.
29
+ - Name a **real** sibling in the boundary. Verify it exists under `skills/`.
30
+ - Target ≤350 chars. Hard limit 1024 (schema-enforced). Third person, opens with "Use when/to".
31
+ - The test is **discrimination, not coverage**: could a reader choose this skill over its nearest
32
+ sibling from the description alone?
33
+
34
+ ### The body
35
+
36
+ The goal is the smallest body that still routes correctly. 400 lines is a ceiling; there is no floor.
37
+
38
+ **Remove:**
39
+
40
+ - Rule banks that restate the flow — "Iron rules (non-negotiable)", "Rationalizations — STOP".
41
+ A rule worth keeping moves next to the step it governs, and says *why* it is absolute instead of
42
+ shouting NON-NEGOTIABLE. A rule in an appendix is skimmed; a rule in context is followed.
43
+ - Re-teaching of what another skill owns. The register (`technical_level` in the profile, set by `init`) and
44
+ the voice that applies it belong to `orient`; the SDD method belongs to `sdd`. Read the profile and point; do not restate, or the two drift apart.
45
+ - "When to use" sections that restate the description, and trailing reference indexes whose links
46
+ already appear inline at point of use.
47
+
48
+ **Keep — these are not padding:**
49
+
50
+ - The **anti-patterns table**. The rubric requires one, and it is a different animal from a
51
+ rationalization table: it names concrete failure modes, not rules already stated above it.
52
+
53
+ **The hybrid case, which is common:** a table titled something like *"Anti-patterns /
54
+ rationalizations — STOP"*, with an *Excuse → Reality* framing. Do not delete it and do not leave
55
+ it as-is. **Keep every row, re-column it to `Anti-pattern | Do instead`, and drop the STOP /
56
+ excuse framing.** The rows are the value; the borrowed urgency wrapper is what dimension 7
57
+ forbids. Handling this the same way everywhere is what keeps the catalog consistent — deleting it
58
+ in one skill and keeping it in the next is worse than either choice applied uniformly.
59
+ - Decision tables where the flow genuinely branches.
60
+ - Tables specific to *this* skill's phase (e.g. what to show at each checkpoint) — that is not the
61
+ retired verbosity levels.
62
+ - Worked bad/good pairs that teach judgment by demonstration.
63
+ - Result-envelope blocks, chain position, and output contracts where they already exist. Do **not**
64
+ add one that was never there: that is a content change, not a format change.
65
+
66
+ **Invariant:** every file under `skills/<id>/references/` must be linked from the body. An unlinked
67
+ reference is never loaded, so it is dead weight in the package. Folding a tail index into inline
68
+ mentions is fine — the link just has to survive. `scripts/`, `evals/` and `assets/` need no link.
69
+
70
+ **Preserve substance exactly.** This is a context-engineering pass, not a content rewrite. Do not
71
+ change recommendations, versions, commands, figures, or add claims.
72
+
73
+ ## Verify
74
+
75
+ Your worktree has **no `node_modules`**, so:
76
+
77
+ - Run: `bash scripts/eval-lint.sh 2>&1 | grep -i '^<id>'` → must report PASS.
78
+ - Check the description length and that every `references/` file is linked.
79
+ - Do **not** run `npm test` or `npm run validate` — they need dependencies you do not have. The
80
+ orchestrator runs them once, globally, after merge.
81
+ - Do **not** edit `manifest.json`. It is derived, and parallel edits from hundreds of agents would
82
+ all conflict on the same lines. The orchestrator regenerates it once at the end.
83
+
84
+ ## Ship
85
+
86
+ Commit only `skills/<id>/`. Subject `refactor(<id>): <what you actually did>`. The body says what you
87
+ removed **and why**, and — just as important — what you deliberately **kept** and why.
88
+
89
+ **Authorship belongs to Daner Alejandro Salazar Colorado; never attribute a commit to an AI.** No `Co-Authored-By` for any AI, no "Generated with Claude Code"
90
+ footer, nothing attributing the work to a tool — in the commit *or* the PR body. This is the hard
91
+ rule the `ship` skill enforces (`skills/ship/SKILL.md`), and it applies to this migration like
92
+ everything else in the repo. Verify before pushing:
93
+
94
+ ```bash
95
+ git log -1 --format='%b' | grep -iE 'co-authored-by.*(claude|anthropic|ai)|generated with|claude code' \
96
+ && echo "AUTHORSHIP VIOLATION — strip it" || echo "authorship clean"
97
+ ```
98
+
99
+ Then `git push -u origin skill/<id>` and `gh pr create`. The PR body carries before/after description
100
+ chars, before/after body bytes, what went, what stayed, and the eval-lint result — and no AI
101
+ attribution line.
102
+
103
+ ## Judgment
104
+
105
+ If the skill already meets the rubric, **say so and change only the description.** A small honest
106
+ diff beats a large invented one. Several skills in the pilot needed 5-line diffs; that is a good
107
+ outcome, not a failed pass. Never pad, and never cut substance to hit a number.
108
+
109
+ ---
110
+
111
+ # For the orchestrator
112
+
113
+ Everything above is for the agent doing one skill. This half is for whoever is driving the fleet.
114
+
115
+ ## Resuming, from nothing
116
+
117
+ There is no state file to keep in sync, on purpose. **The content is the ledger** — a migrated skill
118
+ no longer carries a `Triggers:` list in its description:
119
+
120
+ ```bash
121
+ node -e "const fs=require('fs');const out=[];for(const d of fs.readdirSync('skills')){const p='skills/'+d+'/SKILL.md';if(!fs.existsSync(p))continue;const m=/^---\n([\s\S]*?)\n---/.exec(fs.readFileSync(p,'utf8'));if(m&&/Triggers:/i.test(m[1]))out.push(d)}console.log(out.join('\n'))"
122
+ ```
123
+
124
+ So a cold session resumes with: *read this brief, run that, launch one agent per remaining skill in
125
+ its own worktree.* Nothing from any previous conversation is required.
126
+
127
+ **An earlier version of this section said the remote `skill/*` branches were the ledger. They are
128
+ not, and the failure is instructive**: once integration PRs started merging with `--delete-branch`,
129
+ the branches for finished skills vanished, so a branch-based check re-offered work that was already
130
+ on main — and an agent duly re-migrated `harness` a second time before anyone noticed. The
131
+ instruction was true when written and was invalidated by a later change to the merge flow, with
132
+ nothing to catch the drift. That is the same failure this whole migration keeps finding in the
133
+ catalog; the brief was not exempt from it. Prefer a check against the artifact over a check against
134
+ bookkeeping that something else can quietly change.
135
+
136
+ ## Order: by profile, not alphabetically
137
+
138
+ A skill's `description` is in context for everyone who installs it, so migrate by blast radius:
139
+
140
+ 1. `minimal` profile — in every ai-hub install.
141
+ 2. `core` profile — the default install (the SDD chain plus the control plane).
142
+ 3. High-install stack skills — `nextjs`, `react`, `fastapi`, `postgresdb`, `design`, `typescript`,
143
+ `python`, `go`, `flutter`, `secure-coding`, `deployment`.
144
+ 4. Everything else.
145
+
146
+ If a run is cut short, this ordering means the part that was finished is the part that everyone pays for.
147
+
148
+ ## Sharp edges (each one cost a real mistake)
149
+
150
+ - **`manifest.json` is derived.** Agents must never touch it — hundreds of parallel edits collide on
151
+ the same lines. Regenerate once, centrally, with `npm run manifest` after merging.
152
+ - **A fresh worktree has no `node_modules`** (it is gitignored, so it is not checked out). `npm test`
153
+ and `npm run validate` cannot run there. `scripts/eval-lint.sh` can — it uses python3.
154
+ - **Result-envelope blocks are asymmetric.** `specify`, `tasks`, `implement`, `verify`, `ship`,
155
+ `parallel` and `sdd` have one; `plan`, `analyze`, `clarify`, `constitution`, `review` and `debug`
156
+ do not. Tell each agent which case it is in, or it will helpfully invent one.
157
+ - **`author-skill` is special.** It teaches how to write skills, so it documented the *old*
158
+ conventions. There, rewriting the guidance IS the migration — and the change has to reach its
159
+ `references/` and `evals/`, which graded produced skills against the old rubric.
160
+ - **Short ids break greps.** `go`, `rag`, `php` match half of `eval-lint`'s output. Give those agents
161
+ an anchored pattern (`grep -E '^go +'`).
162
+ - **Compound bash commands are denied whole.** The `ship-guard` hook rejects the entire call if any
163
+ part matches `git checkout main`, so a chained `commit && push && checkout main` runs *nothing*.
164
+ Split them.
165
+ - **The id `parallel` is unusable in a git command.** A sandbox guard aimed at GNU `parallel` matches
166
+ the substring, so `git checkout -b skill/parallel` is refused. That skill's branch has to be
167
+ created from the pushed commit with `gh api` instead. Any future id containing a blocked tool name
168
+ will behave the same way.
169
+
170
+ ## Content problems found while migrating — do NOT fix them in a format pass
171
+
172
+ Agents surfaced these and correctly left them alone. They need their own change:
173
+
174
+ - `sdd` claims every phase ends with a parseable envelope; six phases have none (see above).
175
+ - **`evals/cases.yaml` files carry stale claims about what the catalog contains, in both
176
+ directions.** Three agents hit this independently: `course-storytelling` routes a negative to
177
+ `deep-research`, which does not exist; `flutter` routes its Compose/SwiftUI negatives to `"none"`
178
+ on the grounds those skills are "not in this catalog", though `compose-multiplatform` and
179
+ `swift-ios` now are; `postgresdb` said the same of ORM traps, stale since `prisma-orm` and
180
+ `drizzle-orm` shipped. This drifts every time the catalog grows.
181
+
182
+ The root cause is that `eval-lint` does not actually verify a `route_to` names a real skill,
183
+ even though the rubric lists exactly that as a deterministic gate — so the gate is decorative.
184
+ (The 1024-char description limit had the same problem; that one is now enforced in
185
+ `schema/frontmatter.schema.json`.) Fixing the linter is worth more than fixing the instances:
186
+ it converts a recurring drift into a build error.
187
+ - `clarify`'s body calls itself "the fourth phase" while the chain it prints puts it third.
188
+ - `cold-outreach` never names `linkedin-outreach` in its route table, though the reverse link exists.
189
+ - `data-policy` says "walk five columns" and then lists six.
190
+ - `marketing/references/seo-geo.md` (20 KB) and marketing's landing-section material substantially
191
+ duplicate the standalone `seo-geo` and `landing-copy` skills. Three skills, one body of content,
192
+ paid for three times by anyone who installs all three. Needs a content-level de-duplication pass,
193
+ not a format one.
194
+
195
+ ## Return value
196
+
197
+ ```json
198
+ {"skill":"<id>","pr":"<url|null>","descBefore":0,"descAfter":0,"bytesBefore":0,"bytesAfter":0,
199
+ "evalLint":"PASS|FAIL","removed":["…"],"kept":["…"],"notes":"anything the orchestrator must know"}
200
+ ```
@@ -0,0 +1,40 @@
1
+ # skill-rubric — the objective test every ai-hub skill must pass before shipping
2
+
3
+ This is **the test, written before any skill is built.** A reviewer scores a finished skill
4
+ 0–10 on seven weighted dimensions, then the deterministic gates run (pass/fail, not gradeable).
5
+ A skill **ships only at a weighted score ≥ 8.5 AND all deterministic gates green.** The reviewer
6
+ is adversarial and independent of the author; it must cite evidence (line counts, char counts,
7
+ quoted source dates), never vibes. No grade inflation — an honest 7.0 that drives a fix beats a
8
+ dishonest 9.
9
+
10
+ ## Weighted dimensions (0–10 each)
11
+
12
+ | # | Dimension | Weight | What a 10 looks like |
13
+ |---|---|---|---|
14
+ | 1 | **Triggering & description** | 0.15 | Third-person, `Use when …` lead, an explicit `NOT … (that is <sibling>)` boundary, and nothing else it can do without. Judged on **discriminative power, not coverage**: could a reader pick this skill over its nearest sibling from the description alone? Aim ≤350 chars; ≤1024 is the hard limit. Parses as single-line quoted YAML. |
15
+ | 2 | **Scope & boundary** | 0.10 | One job. Body never drifts into a sibling's territory; it delegates by name. Near-miss prompts route to the correct existing sibling. |
16
+ | 3 | **Body craft & progressive disclosure** | 0.15 | **The smallest body that routes correctly** — ≤400 lines is a ceiling, not a target, and there is no minimum: a skill that does its job in 60 lines scores higher than the same skill padded to 200. Every `references/` file is pointed to inline from this body (an unlinked reference is never loaded, so it is dead weight). ai-hub voice, every fence language-tagged, a checklist/decision table only where the flow branches, an anti-patterns table present. |
17
+ | 4 | **Correctness, grounding & freshness** | **0.25** | Every load-bearing claim is accurate and **current (2025–2026)**: real library/API versions, no hallucinated flags/endpoints. The spec cites **authoritative sources with dates**; nothing rests on stale or invented facts. This is the heaviest dimension by design. |
18
+ | 5 | **Actionability** | 0.15 | Concrete and runnable: real numbers, paths, commands, decision rules — not adjectives. A practitioner could act from it without leaving the skill. |
19
+ | 6 | **Evals quality** | 0.10 | ≥5 `should_trigger` (incl. non-obvious), ≥4 `should_not_trigger` each with a `route_to` that resolves — a **real** catalog id, `none`, or `external:<name>` (enforced by `eval-lint`), ≥1 `capability` with a meaningful `must_include` rubric. The cases are genuine, not filler. |
20
+ | 7 | **Originality & safety** | 0.10 | ai-hub voice, not a clone of any external catalog (no borrowed urgency blocks / rationalization tables / `*-reviewer-prompt.md` conventions / verbatim flowcharts). `verify.sh` present iff there is a checkable artifact. No destructive or unsafe advice presented without guardrails. |
21
+
22
+ **Weighted score** = Σ(subscore × weight), rounded to 1 decimal. **Ship gate: ≥ 8.5.**
23
+
24
+ ## Deterministic gates (pass/fail — not part of the 0–10, but block shipping)
25
+
26
+ 1. `name` matches the directory id; `origin: ai-hub` present.
27
+ 2. Frontmatter validates against `schema/frontmatter.schema.json` (`node scripts/build-manifest.js --validate`).
28
+ 3. Every `recommends` id is a **real** skill in the catalog (no dangling refs — `--validate` enforces).
29
+ 4. `scripts/eval-lint.sh` reports PASS for the skill (≥5/≥4/≥1 and the keys are lists).
30
+ 5. Every `../<sibling>/SKILL.md` link resolves to a skill that exists.
31
+ 6. `description` is ≤ 1024 characters and parses as YAML.
32
+ 7. If a `scripts/verify.sh` exists, it is executable, read-only by default, and exits 0 on a clean/empty target (no false failure).
33
+
34
+ ## How the reviewer must work (anti-cheat)
35
+
36
+ - **Independent pass.** Review the artifact as written; do not assume the author's intent filled a gap.
37
+ - **Evidence, not vibes.** For dimension 1 quote the char count **and name the sibling the description distinguishes this skill from**; for 3 quote the SKILL.md line count **and name anything that could be cut without losing routing**; for 4 quote at least two source titles **with their dates** from the spec and name any claim you could not verify; for 6 count the entries.
38
+ - **Length is a cost, never a credit.** Do not reward a longer description or body for being thorough. Every line is paid for in context on every turn the skill is installed, whether or not it is invoked. If two versions route the same, the shorter one scores higher.
39
+ - **Freshness is mandatory.** If the skill names a version, API, or pricing that is plausibly out of date, dimension 4 is capped at 6 until a current source is cited. "Looks right" is not a source.
40
+ - **Fix loop.** Below 8.5, return a concrete `mustFix` list; the author applies it and re-scores. Up to two fix rounds. If still < 8.5, **record the real score and flag it** — never round up to pass.
@@ -107,6 +107,7 @@
107
107
  "additionalProperties": false,
108
108
  "properties": {
109
109
  "source": { "type": "string", "minLength": 1 },
110
+ "selection": { "enum": ["full", "preset", "custom"] },
110
111
  "publish": { "type": "array", "uniqueItems": true, "items": { "type": "string" } }
111
112
  }
112
113
  },
@@ -116,6 +117,7 @@
116
117
  "additionalProperties": false,
117
118
  "properties": {
118
119
  "source": { "type": "string", "minLength": 1 },
120
+ "selection": { "enum": ["full", "preset", "custom"] },
119
121
  "publish": { "type": "array", "uniqueItems": true, "items": { "type": "string" } }
120
122
  }
121
123
  },
@@ -125,9 +127,19 @@
125
127
  "additionalProperties": false,
126
128
  "properties": {
127
129
  "source": { "type": "string", "minLength": 1 },
130
+ "selection": { "enum": ["full", "preset", "custom"] },
128
131
  "publish": { "type": "array", "uniqueItems": true, "items": { "type": "string" } }
129
132
  }
130
133
  },
134
+ "catalog": {
135
+ "type": "object",
136
+ "required": ["version", "hash"],
137
+ "additionalProperties": false,
138
+ "properties": {
139
+ "version": { "type": "string", "minLength": 1 },
140
+ "hash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }
141
+ }
142
+ },
131
143
  "mcp": {
132
144
  "type": "object",
133
145
  "required": ["source"],