diff --git a/CHANGELOG.md b/CHANGELOG.md index 89207de8..a3e3559d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,28 @@ new version heading in the same commit. ## [Unreleased] +## [0.330.0] — 2026-08-09 +### Added +- **Five new featured skill sources in the console's "Install from GitHub" dialog** — engineering and + design libraries alongside the existing marketing set: `addyosmani/agent-skills` (24), `google/skills` + (88), `emilkowalski/skills` (9), `Nutlope/hallmark` (anti-AI-slop design) and `tt-a1i/archify` + (architecture diagrams). A preset is only a POINTER — nothing is vendored, `browseRepo` lists the + repo's `SKILL.md` folders at click time and an owner/admin picks what to install — so this is reach, + not new trust surface. All five verified to resolve through `browseRepo` before being added; a repo of + agent *personas* (0 `SKILL.md` folders, e.g. `msitarzewski/agency-agents`) was rejected by that check. +- **`scripts/skill-presets-test.cjs`** (wired into `npm run test:governance`) — pins the two mechanical + ways a featured source breaks: a `repo` that isn't the plain `owner/repo` form (dead button) and a + duplicate entry. Offline by design; live resolution stays a documented manual check, since it needs + GitHub's unauthenticated 60/hr budget. + +### Fixed +- **Featured-source skill counts were stale or overstated.** The hand-written counts had drifted + (`anthropics/skills` ⭐157k→167k, `mattpocock/skills` ⭐151k→211k) and, more usefully, the raw + `SKILL.md` count overstates what a user actually gets: `browseRepo` dedupes skills by folder name, + so `alirezarezvani/claude-skills` is 439 installable, not 798. Every count is now the deduped figure + the browse dialog itself shows. + + ## [0.329.1] — 2026-08-09 ### Changed - **Round 2 of the derived-outcome falsifier: the honest out-of-sample number is 52%, not 63%, and diff --git a/package-lock.json b/package-lock.json index 1d9242fa..fa2b2298 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "agent-os", - "version": "0.329.1", + "version": "0.330.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "agent-os", - "version": "0.329.1", + "version": "0.330.0", "license": "MIT", "bin": { "agent-os": "bin/agent-os" diff --git a/package.json b/package.json index ad8e0a73..599d2045 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agent-os", - "version": "0.329.1", + "version": "0.330.0", "description": "A generic, governed operating system for running autonomous agents safely across brands. Ships with a local web console.", "license": "MIT", "type": "commonjs", @@ -27,7 +27,7 @@ "check-deps": "bash scripts/install-deps.sh --check", "dev": "ts-node src/cli.ts serve", "demo:dev": "ts-node src/demo.ts", - "test:governance": "node scripts/governance-conformance.cjs && node scripts/tier-a-policy-test.cjs && node scripts/capability-registry-test.cjs && node scripts/idle-reaper-test.cjs && node scripts/dm-continuity-test.cjs && node scripts/alert-staleness-test.cjs && node scripts/run-as-identity-test.cjs && node scripts/deps-freshness-test.cjs && node scripts/runtime-account-test.cjs && node scripts/runtime-login-test.cjs && node scripts/claude-config-seed-test.cjs && node scripts/verbosity-test.cjs && node scripts/chain-model-test.cjs && node scripts/tuning-patch-test.cjs && node scripts/task-runs-test.cjs && node scripts/task-resume-test.cjs && node scripts/warm-chat-test.cjs && node scripts/agent-edit-guard-test.cjs && node scripts/goal-update-guard-test.cjs && node scripts/insights-signal-test.cjs && node scripts/outcome-derivation-test.cjs && node scripts/turn-lifecycle-test.cjs && node scripts/outcome-vocabulary-test.cjs", + "test:governance": "node scripts/governance-conformance.cjs && node scripts/tier-a-policy-test.cjs && node scripts/capability-registry-test.cjs && node scripts/idle-reaper-test.cjs && node scripts/dm-continuity-test.cjs && node scripts/alert-staleness-test.cjs && node scripts/run-as-identity-test.cjs && node scripts/deps-freshness-test.cjs && node scripts/runtime-account-test.cjs && node scripts/runtime-login-test.cjs && node scripts/claude-config-seed-test.cjs && node scripts/verbosity-test.cjs && node scripts/chain-model-test.cjs && node scripts/tuning-patch-test.cjs && node scripts/task-runs-test.cjs && node scripts/task-resume-test.cjs && node scripts/warm-chat-test.cjs && node scripts/agent-edit-guard-test.cjs && node scripts/goal-update-guard-test.cjs && node scripts/insights-signal-test.cjs && node scripts/outcome-derivation-test.cjs && node scripts/turn-lifecycle-test.cjs && node scripts/outcome-vocabulary-test.cjs && node scripts/skill-presets-test.cjs", "test:alert-staleness": "node scripts/alert-staleness-test.cjs", "test:deps": "node scripts/deps-freshness-test.cjs && node scripts/runtime-account-test.cjs && node scripts/runtime-login-test.cjs && node scripts/claude-config-seed-test.cjs", "test:dm-continuity": "node scripts/dm-continuity-test.cjs", diff --git a/scripts/skill-presets-test.cjs b/scripts/skill-presets-test.cjs new file mode 100644 index 00000000..080b79e7 --- /dev/null +++ b/scripts/skill-presets-test.cjs @@ -0,0 +1,53 @@ +#!/usr/bin/env node +/** + * Featured skill-source test — the console's one-click preset list (`PRESET_SOURCES`). + * + * A preset is only a POINTER: clicking it calls `browseRepo(repo)`, which lists the repo's + * `SKILL.md` folders live, and an owner/admin picks what to install. So a broken entry is a dead + * button, not a bad install — but it's still a shipped promise, and the two ways it goes wrong are + * both mechanical: + * + * 1. the `repo` string doesn't parse as `owner/repo` (the browse errors out), and + * 2. a duplicate repo (two chips, same target). + * + * Both are checked here OFFLINE, so the suite stays hermetic. What this deliberately does NOT check + * is that the repo still exists and still contains SKILL.md folders — that needs the network and + * GitHub's unauthenticated 60/hr budget. Re-verify that by hand when adding a preset: + * + * node -e "require('./dist/governance/skill-registry').browseRepo('owner/repo').then(c=>console.log(c.skills.length))" + * + * A repo of agent *personas* (no SKILL.md anywhere) resolves to 0 skills and must not be added. + * + * npm run build && node scripts/skill-presets-test.cjs + */ +const path = require('path'); +const { PRESET_SOURCES, parseRepo } = require(path.resolve(__dirname, '..', 'dist/governance/skill-registry')); + +let pass = 0; +const failures = []; +const check = (name, cond) => { if (cond) pass++; else failures.push(name); }; + +check('there is at least one featured source', Array.isArray(PRESET_SOURCES) && PRESET_SOURCES.length > 0); + +for (const p of PRESET_SOURCES) { + const id = p && p.repo ? p.repo : JSON.stringify(p); + check(`${id}: parses as owner/repo`, (() => { + try { const { owner, repo } = parseRepo(p.repo); return Boolean(owner && repo); } catch { return false; } + })()); + check(`${id}: has a non-empty label`, typeof p.label === 'string' && p.label.trim().length > 0); + check(`${id}: has a non-empty description`, typeof p.description === 'string' && p.description.trim().length > 0); + // The chip shows `repo` verbatim under the label, so a URL/ref form would render wrong even though + // parseRepo tolerates it. Featured entries are the plain two-segment form. + check(`${id}: is the plain owner/repo form (no URL, no @ref)`, /^[\w.-]+\/[\w.-]+$/.test(p.repo || '')); +} + +const repos = PRESET_SOURCES.map((p) => p.repo); +check('no duplicate repos', new Set(repos).size === repos.length); +check('no duplicate labels', new Set(PRESET_SOURCES.map((p) => p.label)).size === PRESET_SOURCES.length); + +if (failures.length) { + console.error(`skill-presets-test: ${failures.length} FAILED (${pass} passed)`); + for (const f of failures) console.error(' ✗ ' + f); + process.exit(1); +} +console.log(`skill-presets-test: ${pass} checks passed across ${PRESET_SOURCES.length} featured sources`); diff --git a/src/governance/skill-registry.ts b/src/governance/skill-registry.ts index b05cbb9f..41cf4851 100644 --- a/src/governance/skill-registry.ts +++ b/src/governance/skill-registry.ts @@ -16,22 +16,31 @@ */ import { parseFrontmatter, validSkillName } from './skills'; -/** A featured one-click source shown in the console. The marketing set + a skills.sh starter. */ +/** + * A featured one-click source shown in the console — marketing, engineering & design sets plus a + * skills.sh starter. A preset is only ever a POINTER: nothing is vendored here, `browseRepo` fetches + * the repo's `SKILL.md` folders at click time and an owner/admin picks what to install. So the bar + * for adding one is just: public repo, permissive licence, and it actually contains SKILL.md folders + * (a repo of agent *personas* has none and would present an empty browse — verify before adding). + * + * Skill/star counts are hand-written and drift; they're a rough size signal, not a live figure. + * Last verified 2026-08-09. + */ export const PRESET_SOURCES: { repo: string; label: string; description: string }[] = [ { repo: 'coreyhaines31/marketingskills', label: 'Marketing Skills', - description: '45 marketing playbooks — SEO, CRO, copywriting, ads, lifecycle & growth (Corey Haines, MIT, ⭐36k).', + description: '49 marketing playbooks — SEO, CRO, copywriting, ads, lifecycle & growth (Corey Haines, MIT, ⭐44k).', }, { repo: 'OpenClaudia/openclaudia-skills', label: 'OpenClaudia Marketing', - description: '67 open marketing skills — SEO, content, email, ads, analytics, growth (MIT).', + description: '75 open marketing skills — SEO, content, email, ads, analytics, growth (MIT).', }, { repo: 'AgriciDaniel/claude-seo', label: 'Claude SEO', - description: '31 deep-SEO skills — technical, E-E-A-T, schema, GEO/AEO, local & intl (MIT, ⭐10k).', + description: '31 deep-SEO skills — technical, E-E-A-T, schema, GEO/AEO, local & intl (MIT, ⭐14k).', }, { repo: 'rampstackco/claude-skills', @@ -40,18 +49,43 @@ export const PRESET_SOURCES: { repo: string; label: string; description: string }, { repo: 'alirezarezvani/claude-skills', - label: 'Claude Skills (420)', - description: 'Broad library — engineering, marketing, product, compliance, finance & ops (MIT, ⭐19k).', + label: 'Claude Skills (439)', + description: 'Broad library — engineering, marketing, product, compliance, finance & ops (MIT, ⭐24k).', }, { repo: 'anthropics/skills', label: 'Anthropic Official', - description: 'Official Anthropic skills — docx/pdf/pptx/xlsx, artifacts & frontend design (⭐157k).', + description: 'Official Anthropic skills — docx/pdf/pptx/xlsx, artifacts & frontend design (⭐167k).', + }, + { + repo: 'addyosmani/agent-skills', + label: 'Addy Osmani · Agent Skills', + description: '24 production-grade engineering skills for AI coding agents — review, perf, testing & debugging (MIT, ⭐85k).', + }, + { + repo: 'google/skills', + label: 'Google', + description: '88 skills for Google products & technologies — Cloud, Android, web & AI tooling (Apache-2.0, ⭐17k).', + }, + { + repo: 'emilkowalski/skills', + label: 'Emil Kowalski · Design', + description: '9 skills for designers & engineers — animation, interaction & UI craft (MIT, ⭐27k).', + }, + { + repo: 'Nutlope/hallmark', + label: 'Hallmark · Anti-slop Design', + description: 'One design skill that steers agents away from generic AI-looking UI (MIT, ⭐23k).', + }, + { + repo: 'tt-a1i/archify', + label: 'Archify · Diagrams', + description: 'One skill for verifiable architecture, workflow & data-flow diagrams as self-contained HTML (MIT, ⭐11k).', }, { repo: 'mattpocock/skills', label: 'Matt Pocock · Engineering', - description: 'Engineering craft — TDD, refactoring, debugging & architecture (MIT, ⭐151k).', + description: '35 engineering-craft skills — TDD, refactoring, debugging & architecture (MIT, ⭐211k).', }, ];