skilldrop-cli 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.
- package/LICENSE +21 -0
- package/README.md +413 -0
- package/bin/skilldrop.js +338 -0
- package/model-routing.json +147 -0
- package/package.json +36 -0
- package/packs.json +90 -0
- package/skills/accessibility-audit/SKILL.md +74 -0
- package/skills/accessibility-audit/examples/login-form.md +76 -0
- package/skills/accessibility-audit/manifest.json +11 -0
- package/skills/accessibility-audit/reference.md +69 -0
- package/skills/adr-generator/SKILL.md +49 -0
- package/skills/adr-generator/manifest.json +11 -0
- package/skills/adr-generator/templates/madr.md +56 -0
- package/skills/adr-generator/templates/nygard.md +19 -0
- package/skills/ai-usage-report/SKILL.md +111 -0
- package/skills/ai-usage-report/examples/weekly-engineering-team.md +133 -0
- package/skills/ai-usage-report/manifest.json +11 -0
- package/skills/ai-usage-report/scripts/build_report.py +436 -0
- package/skills/ai-usage-report/templates/report-per-user.md +42 -0
- package/skills/ai-usage-report/templates/report-team-rollup.md +49 -0
- package/skills/ai-usage-report/templates/usage-event-schema.md +76 -0
- package/skills/api-contract-draft/SKILL.md +69 -0
- package/skills/api-contract-draft/manifest.json +11 -0
- package/skills/api-contract-draft/reference.md +73 -0
- package/skills/api-contract-draft/templates/openapi-skeleton.yaml +148 -0
- package/skills/architecture-diagrams/SKILL.md +66 -0
- package/skills/architecture-diagrams/examples/aws-three-tier.md +44 -0
- package/skills/architecture-diagrams/examples/c4-container-saas.md +51 -0
- package/skills/architecture-diagrams/examples/microservices-sequence.md +49 -0
- package/skills/architecture-diagrams/manifest.json +28 -0
- package/skills/architecture-diagrams/templates/c4-container.puml +31 -0
- package/skills/architecture-diagrams/templates/mermaid-aws.md +52 -0
- package/skills/architecture-diagrams/templates/mermaid-flowchart.md +37 -0
- package/skills/architecture-diagrams/templates/mermaid-sequence.md +39 -0
- package/skills/audience-profile/SKILL.md +73 -0
- package/skills/audience-profile/manifest.json +11 -0
- package/skills/audience-profile/reference.md +175 -0
- package/skills/brief-intake/SKILL.md +78 -0
- package/skills/brief-intake/manifest.json +11 -0
- package/skills/brief-intake/templates/brief-adr.md +41 -0
- package/skills/brief-intake/templates/brief-decision-log.md +35 -0
- package/skills/brief-intake/templates/brief-deck.md +43 -0
- package/skills/brief-intake/templates/brief-design-doc.md +48 -0
- package/skills/brief-intake/templates/brief-exec-summary.md +47 -0
- package/skills/brief-intake/templates/brief-generic.md +45 -0
- package/skills/brief-intake/templates/brief-runbook.md +44 -0
- package/skills/brief-intake/templates/brief-tech-comparison.md +38 -0
- package/skills/bug-triage/SKILL.md +67 -0
- package/skills/bug-triage/manifest.json +11 -0
- package/skills/bug-triage/templates/bug-ticket.md +86 -0
- package/skills/business-case/SKILL.md +64 -0
- package/skills/business-case/manifest.json +11 -0
- package/skills/business-case/templates/business-case.md +60 -0
- package/skills/capacity-cost-model/SKILL.md +64 -0
- package/skills/capacity-cost-model/manifest.json +11 -0
- package/skills/capacity-cost-model/reference.md +54 -0
- package/skills/capacity-cost-model/templates/cost-model.md +68 -0
- package/skills/council-review/SKILL.md +106 -0
- package/skills/council-review/examples/redis-cache-decision.md +75 -0
- package/skills/council-review/manifest.json +11 -0
- package/skills/council-review/reference.md +76 -0
- package/skills/council-review/seats/architect.md +29 -0
- package/skills/council-review/seats/bench.md +39 -0
- package/skills/council-review/seats/operator.md +27 -0
- package/skills/council-review/seats/pragmatist.md +29 -0
- package/skills/council-review/seats/security-engineer.md +29 -0
- package/skills/council-review/seats/user-advocate.md +27 -0
- package/skills/council-review/templates/council-review.md +59 -0
- package/skills/data-contract/SKILL.md +67 -0
- package/skills/data-contract/manifest.json +11 -0
- package/skills/data-contract/reference.md +46 -0
- package/skills/data-contract/templates/data-contract.md +69 -0
- package/skills/db-schema-design/SKILL.md +68 -0
- package/skills/db-schema-design/manifest.json +11 -0
- package/skills/db-schema-design/reference.md +56 -0
- package/skills/db-schema-design/templates/schema-design.md +75 -0
- package/skills/decision-log/SKILL.md +67 -0
- package/skills/decision-log/manifest.json +11 -0
- package/skills/deck-builder/SKILL.md +114 -0
- package/skills/deck-builder/examples/exec-board-update.md +108 -0
- package/skills/deck-builder/manifest.json +17 -0
- package/skills/deck-builder/reference.md +92 -0
- package/skills/deck-builder/requirements.txt +1 -0
- package/skills/deck-builder/scripts/build_deck.py +309 -0
- package/skills/deck-builder/templates/deck-spec.json +97 -0
- package/skills/deck-builder/templates/palettes.json +59 -0
- package/skills/design-doc/SKILL.md +49 -0
- package/skills/design-doc/manifest.json +11 -0
- package/skills/design-doc/templates/design-doc.md +98 -0
- package/skills/devils-advocate/SKILL.md +142 -0
- package/skills/devils-advocate/lenses/adversarial-review.md +88 -0
- package/skills/devils-advocate/lenses/edge-cases.md +95 -0
- package/skills/devils-advocate/lenses/future-proofing.md +75 -0
- package/skills/devils-advocate/lenses/test-coverage.md +90 -0
- package/skills/devils-advocate/manifest.json +11 -0
- package/skills/devils-advocate/templates/challenge.md +118 -0
- package/skills/doc-critique/SKILL.md +119 -0
- package/skills/doc-critique/manifest.json +11 -0
- package/skills/doc-critique/rubrics/adr.md +36 -0
- package/skills/doc-critique/rubrics/decision-log.md +39 -0
- package/skills/doc-critique/rubrics/deck.md +45 -0
- package/skills/doc-critique/rubrics/design-doc.md +42 -0
- package/skills/doc-critique/rubrics/exec-summary.md +41 -0
- package/skills/doc-critique/rubrics/generic.md +40 -0
- package/skills/doc-critique/rubrics/runbook.md +42 -0
- package/skills/doc-critique/rubrics/tech-comparison.md +40 -0
- package/skills/doc-critique/templates/critique.md +49 -0
- package/skills/exec-summary/SKILL.md +45 -0
- package/skills/exec-summary/manifest.json +11 -0
- package/skills/exec-summary/templates/exec-summary.md +48 -0
- package/skills/feature-implement-loop/SKILL.md +83 -0
- package/skills/feature-implement-loop/manifest.json +11 -0
- package/skills/figma-diagrams/SKILL.md +85 -0
- package/skills/figma-diagrams/manifest.json +35 -0
- package/skills/figma-diagrams/reference.md +91 -0
- package/skills/figma-diagrams/requirements.txt +1 -0
- package/skills/figma-diagrams/scripts/_figma_client.py +71 -0
- package/skills/figma-diagrams/scripts/frame_to_mermaid.py +102 -0
- package/skills/figma-diagrams/scripts/inspect_file.py +46 -0
- package/skills/figma-diagrams/scripts/list_comments.py +35 -0
- package/skills/figma-diagrams/scripts/post_comment.py +52 -0
- package/skills/figma-diagrams/templates/figjam-import.json +20 -0
- package/skills/guide-builder/SKILL.md +76 -0
- package/skills/guide-builder/examples/local-setup-guide.md +127 -0
- package/skills/guide-builder/manifest.json +11 -0
- package/skills/guide-builder/templates/api-reference.md +120 -0
- package/skills/guide-builder/templates/design-walkthrough.md +72 -0
- package/skills/guide-builder/templates/setup-guide.md +109 -0
- package/skills/incident-comms/SKILL.md +68 -0
- package/skills/incident-comms/manifest.json +11 -0
- package/skills/incident-comms/reference.md +43 -0
- package/skills/incident-comms/templates/messages.md +82 -0
- package/skills/llm-eval-harness/SKILL.md +73 -0
- package/skills/llm-eval-harness/manifest.json +11 -0
- package/skills/llm-eval-harness/reference.md +58 -0
- package/skills/llm-eval-harness/templates/eval-plan.md +63 -0
- package/skills/llm-eval-harness/templates/golden-case.jsonl +5 -0
- package/skills/migration-plan/SKILL.md +68 -0
- package/skills/migration-plan/manifest.json +11 -0
- package/skills/migration-plan/templates/migration-plan.md +68 -0
- package/skills/nfr-spec/SKILL.md +63 -0
- package/skills/nfr-spec/manifest.json +11 -0
- package/skills/nfr-spec/reference.md +74 -0
- package/skills/nfr-spec/templates/nfr-spec.md +56 -0
- package/skills/observability-plan/SKILL.md +70 -0
- package/skills/observability-plan/manifest.json +11 -0
- package/skills/observability-plan/reference.md +67 -0
- package/skills/observability-plan/templates/observability-plan.md +62 -0
- package/skills/okr-cascade/SKILL.md +59 -0
- package/skills/okr-cascade/evals/eval_queries.json +12 -0
- package/skills/okr-cascade/evals/evals.json +28 -0
- package/skills/okr-cascade/manifest.json +11 -0
- package/skills/okr-cascade/templates/okr-cascade.md +46 -0
- package/skills/postmortem-generator/SKILL.md +65 -0
- package/skills/postmortem-generator/manifest.json +11 -0
- package/skills/postmortem-generator/templates/postmortem.md +67 -0
- package/skills/prd-draft/SKILL.md +62 -0
- package/skills/prd-draft/manifest.json +11 -0
- package/skills/prd-draft/templates/prd.md +66 -0
- package/skills/prfaq/SKILL.md +75 -0
- package/skills/prfaq/evals/eval_queries.json +13 -0
- package/skills/prfaq/evals/evals.json +32 -0
- package/skills/prfaq/manifest.json +11 -0
- package/skills/prfaq/templates/prfaq.md +60 -0
- package/skills/release-notes/SKILL.md +61 -0
- package/skills/release-notes/manifest.json +11 -0
- package/skills/release-notes/templates/release-notes.md +83 -0
- package/skills/requirements-interview/SKILL.md +61 -0
- package/skills/requirements-interview/manifest.json +11 -0
- package/skills/requirements-interview/templates/interview-kit.md +63 -0
- package/skills/reverse-architecture/SKILL.md +103 -0
- package/skills/reverse-architecture/manifest.json +11 -0
- package/skills/reverse-architecture/reference.md +150 -0
- package/skills/reverse-architecture/templates/description.md +52 -0
- package/skills/reverse-architecture/templates/extraction.md +55 -0
- package/skills/runbook-generator/SKILL.md +42 -0
- package/skills/runbook-generator/manifest.json +11 -0
- package/skills/runbook-generator/templates/runbook.md +109 -0
- package/skills/slide-outliner/SKILL.md +58 -0
- package/skills/slide-outliner/manifest.json +11 -0
- package/skills/slide-outliner/templates/deck-outline.md +131 -0
- package/skills/sonar-onboard/SKILL.md +170 -0
- package/skills/sonar-onboard/manifest.json +11 -0
- package/skills/sonar-onboard/reference.md +151 -0
- package/skills/sonar-onboard/templates/github-actions-sonar-server.yml.tmpl +50 -0
- package/skills/sonar-onboard/templates/github-actions-sonarcloud.yml.tmpl +53 -0
- package/skills/sonar-onboard/templates/readme-snippet.md +38 -0
- package/skills/sonar-onboard/templates/sonar-project.properties.tmpl +31 -0
- package/skills/sonar-review/SKILL.md +220 -0
- package/skills/sonar-review/lenses/bugs.md +48 -0
- package/skills/sonar-review/lenses/code-smells.md +64 -0
- package/skills/sonar-review/lenses/coverage-and-duplication.md +74 -0
- package/skills/sonar-review/lenses/security-hotspots.md +56 -0
- package/skills/sonar-review/lenses/vulnerabilities.md +52 -0
- package/skills/sonar-review/manifest.json +37 -0
- package/skills/sonar-review/reference.md +167 -0
- package/skills/sonar-review/templates/report.md +84 -0
- package/skills/strategy-analysis/SKILL.md +63 -0
- package/skills/strategy-analysis/evals/eval_queries.json +13 -0
- package/skills/strategy-analysis/evals/evals.json +36 -0
- package/skills/strategy-analysis/manifest.json +11 -0
- package/skills/success-metrics/SKILL.md +63 -0
- package/skills/success-metrics/evals/eval_queries.json +11 -0
- package/skills/success-metrics/evals/evals.json +27 -0
- package/skills/success-metrics/manifest.json +11 -0
- package/skills/success-metrics/templates/metrics-plan.md +55 -0
- package/skills/tech-comparison-matrix/SKILL.md +56 -0
- package/skills/tech-comparison-matrix/manifest.json +11 -0
- package/skills/tech-comparison-matrix/templates/matrix.md +45 -0
- package/skills/test-plan-generator/SKILL.md +59 -0
- package/skills/test-plan-generator/manifest.json +11 -0
- package/skills/test-plan-generator/templates/test-plan.md +83 -0
- package/skills/threat-model/SKILL.md +65 -0
- package/skills/threat-model/examples/document-upload.md +56 -0
- package/skills/threat-model/manifest.json +11 -0
- package/skills/threat-model/reference.md +69 -0
- package/skills/user-journey-map/SKILL.md +64 -0
- package/skills/user-journey-map/evals/eval_queries.json +12 -0
- package/skills/user-journey-map/evals/evals.json +30 -0
- package/skills/user-journey-map/examples/b2b-saas-onboarding.md +69 -0
- package/skills/user-journey-map/manifest.json +11 -0
- package/skills/user-journey-map/templates/journey-map.md +47 -0
- package/skills/user-story-splitter/SKILL.md +88 -0
- package/skills/user-story-splitter/examples/notifications-epic.md +123 -0
- package/skills/user-story-splitter/manifest.json +11 -0
- package/skills/user-story-splitter/templates/story.md +40 -0
package/bin/skilldrop.js
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* skilldrop — install portable AI-agent skills into Claude Code, Cursor, Kiro,
|
|
3
|
+
* or any directory, from the bundled catalog or any third-party catalog
|
|
4
|
+
* (--from <path | git-url[#ref]>). Zero dependencies; copy-only, never executes
|
|
5
|
+
* catalog content at install time.
|
|
6
|
+
* Design: skilldrop-cli-design/skilldrop-cli-design.md
|
|
7
|
+
* Scope: docs/rfcs/0002-skilldrop-cli.md, docs/rfcs/0003-third-party-catalogs.md
|
|
8
|
+
*/
|
|
9
|
+
"use strict";
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const os = require("os");
|
|
13
|
+
const { execFileSync } = require("child_process");
|
|
14
|
+
|
|
15
|
+
const ROOT = path.resolve(__dirname, "..");
|
|
16
|
+
const LEDGER = ".skilldrop.json";
|
|
17
|
+
const BUNDLED = "bundled";
|
|
18
|
+
|
|
19
|
+
const HELP = `skilldrop — portable AI-agent skills for Claude Code, Cursor, Kiro, and more
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
skilldrop list [--from <src>] all skills in a catalog (name, version, tier)
|
|
23
|
+
skilldrop info <skill> [--from <src>] description, related, packs, deps
|
|
24
|
+
skilldrop packs [--from <src>] role-based packs
|
|
25
|
+
skilldrop install <skill...> install skills (default: Claude Code, user scope)
|
|
26
|
+
skilldrop install --pack <name> install a whole pack
|
|
27
|
+
skilldrop install --all install every skill in the catalog
|
|
28
|
+
skilldrop update re-copy installed skills whose version changed
|
|
29
|
+
skilldrop outdated show installed vs current versions, change nothing
|
|
30
|
+
skilldrop uninstall <skill...> remove skills (and wiring files this tool wrote)
|
|
31
|
+
skilldrop validate [--from <src>] structural check of a catalog (for catalog authors)
|
|
32
|
+
|
|
33
|
+
Catalogs:
|
|
34
|
+
(default) the catalog bundled with this package
|
|
35
|
+
--from <dir> any local directory shaped like skills/<name>/{SKILL.md,manifest.json}
|
|
36
|
+
--from <git-url> any git repo with that shape; append #<branch-or-tag> to pin
|
|
37
|
+
|
|
38
|
+
Install/update/uninstall targets (pick one):
|
|
39
|
+
(default) ~/.claude/skills Claude Code, user scope
|
|
40
|
+
--project ./.claude/skills Claude Code, project scope
|
|
41
|
+
--ide cursor ./.cursor/skills + writes .cursor/rules/<skill>.mdc
|
|
42
|
+
--ide kiro ./.kiro/skills + writes .kiro/steering/<skill>.md
|
|
43
|
+
--dest <dir> any directory Codex / Continue / Cline / Aider (wiring tips printed)
|
|
44
|
+
|
|
45
|
+
Options:
|
|
46
|
+
--with-related also install each skill's related companions (one level)
|
|
47
|
+
`;
|
|
48
|
+
|
|
49
|
+
function die(msg) { console.error("error: " + msg); process.exit(1); }
|
|
50
|
+
function readJSON(p) { return JSON.parse(fs.readFileSync(p, "utf8")); }
|
|
51
|
+
|
|
52
|
+
function parseArgs(argv) {
|
|
53
|
+
const out = { _: [], flags: {} };
|
|
54
|
+
for (let i = 0; i < argv.length; i++) {
|
|
55
|
+
const a = argv[i];
|
|
56
|
+
if (a === "--pack" || a === "--ide" || a === "--dest" || a === "--from") out.flags[a.slice(2)] = argv[++i];
|
|
57
|
+
else if (a.startsWith("--")) out.flags[a.slice(2)] = true;
|
|
58
|
+
else out._.push(a);
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* ---------- catalogs ---------- */
|
|
64
|
+
|
|
65
|
+
const catalogCache = {};
|
|
66
|
+
function resolveCatalog(source) {
|
|
67
|
+
const key = source || BUNDLED;
|
|
68
|
+
if (catalogCache[key]) return catalogCache[key];
|
|
69
|
+
let dir;
|
|
70
|
+
if (!source) dir = ROOT;
|
|
71
|
+
else if (fs.existsSync(source)) dir = path.resolve(source);
|
|
72
|
+
else {
|
|
73
|
+
const [url, ref] = source.split("#");
|
|
74
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), "skilldrop-cat-"));
|
|
75
|
+
try {
|
|
76
|
+
execFileSync("git", ["clone", "--depth", "1", ...(ref ? ["--branch", ref] : []), url, dir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
77
|
+
} catch (e) {
|
|
78
|
+
die(`could not fetch catalog '${source}' — not a local path, and git clone failed`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const skillsDir = path.join(dir, "skills");
|
|
82
|
+
if (!fs.existsSync(skillsDir)) die(`'${source || dir}' is not a skilldrop catalog — no skills/ directory`);
|
|
83
|
+
return (catalogCache[key] = { dir, skillsDir, source: source || BUNDLED });
|
|
84
|
+
}
|
|
85
|
+
function skillsIn(cat) {
|
|
86
|
+
return fs.readdirSync(cat.skillsDir).filter((d) => fs.statSync(path.join(cat.skillsDir, d)).isDirectory()).sort();
|
|
87
|
+
}
|
|
88
|
+
function manifestOf(cat, s) { return readJSON(path.join(cat.skillsDir, s, "manifest.json")); }
|
|
89
|
+
function packsOf(cat) {
|
|
90
|
+
const p = path.join(cat.dir, "packs.json");
|
|
91
|
+
return fs.existsSync(p) ? readJSON(p).packs : null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Structural gate (RFC-0003): a skill must pass before it is copied anywhere. */
|
|
95
|
+
function checkSkill(cat, s) {
|
|
96
|
+
const problems = [];
|
|
97
|
+
const dir = path.join(cat.skillsDir, s);
|
|
98
|
+
if (!fs.existsSync(path.join(dir, "SKILL.md"))) problems.push("SKILL.md missing");
|
|
99
|
+
let m = null;
|
|
100
|
+
try { m = manifestOf(cat, s); } catch (e) { problems.push("manifest.json missing or invalid JSON"); }
|
|
101
|
+
if (m) {
|
|
102
|
+
if (m.name !== s) problems.push(`manifest name '${m.name}' != folder '${s}'`);
|
|
103
|
+
if (!m.description) problems.push("manifest missing description");
|
|
104
|
+
if (!m.version) problems.push("manifest missing version");
|
|
105
|
+
if (!m.model || !m.model.tier) problems.push("manifest missing model.tier");
|
|
106
|
+
const fmName = (() => {
|
|
107
|
+
try {
|
|
108
|
+
const fm = fs.readFileSync(path.join(dir, "SKILL.md"), "utf8").split("---")[1] || "";
|
|
109
|
+
const match = fm.match(/^name:\s*(\S+)/m);
|
|
110
|
+
return match && match[1];
|
|
111
|
+
} catch (e) { return null; }
|
|
112
|
+
})();
|
|
113
|
+
if (fmName && fmName !== s) problems.push(`SKILL.md frontmatter name '${fmName}' != folder '${s}'`);
|
|
114
|
+
}
|
|
115
|
+
return problems;
|
|
116
|
+
}
|
|
117
|
+
function gate(cat, names) {
|
|
118
|
+
let bad = 0;
|
|
119
|
+
for (const s of names) {
|
|
120
|
+
const problems = checkSkill(cat, s);
|
|
121
|
+
for (const p of problems) console.error(`refused ${s}: ${p}`);
|
|
122
|
+
if (problems.length) bad++;
|
|
123
|
+
}
|
|
124
|
+
if (bad) die(`${bad} skill(s) failed the structural check — nothing was installed`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* ---------- install targets & ledger ---------- */
|
|
128
|
+
|
|
129
|
+
function target(flags) {
|
|
130
|
+
if (flags.dest) return { dest: path.resolve(flags.dest), ide: "generic" };
|
|
131
|
+
const ide = flags.ide || "claude";
|
|
132
|
+
if (ide === "claude")
|
|
133
|
+
return flags.project
|
|
134
|
+
? { dest: path.resolve(".claude", "skills"), ide }
|
|
135
|
+
: { dest: path.join(os.homedir(), ".claude", "skills"), ide };
|
|
136
|
+
if (ide === "cursor") return { dest: path.resolve(".cursor", "skills"), ide };
|
|
137
|
+
if (ide === "kiro") return { dest: path.resolve(".kiro", "skills"), ide };
|
|
138
|
+
die(`unknown --ide '${ide}' (claude | cursor | kiro; use --dest for anything else)`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function ledger(dest) {
|
|
142
|
+
const p = path.join(dest, LEDGER);
|
|
143
|
+
return { path: p, data: fs.existsSync(p) ? readJSON(p) : {} };
|
|
144
|
+
}
|
|
145
|
+
function saveLedger(l) { fs.writeFileSync(l.path, JSON.stringify(l.data, null, 2) + "\n"); }
|
|
146
|
+
/* Ledger values: {version, source}; legacy plain strings mean a bundled install. */
|
|
147
|
+
function lver(v) { return typeof v === "string" ? v : v.version; }
|
|
148
|
+
function lsrc(v) { return typeof v === "string" ? BUNDLED : v.source || BUNDLED; }
|
|
149
|
+
|
|
150
|
+
function wiringPath(ide, dest, s) {
|
|
151
|
+
const base = path.dirname(dest); // .cursor/ or .kiro/
|
|
152
|
+
if (ide === "cursor") return path.join(base, "rules", `${s}.mdc`);
|
|
153
|
+
if (ide === "kiro") return path.join(base, "steering", `${s}.md`);
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
function writeWiring(ide, dest, s, desc) {
|
|
157
|
+
const p = wiringPath(ide, dest, s);
|
|
158
|
+
if (!p) return;
|
|
159
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
160
|
+
if (ide === "cursor")
|
|
161
|
+
fs.writeFileSync(p, `---\ndescription: ${desc.replace(/\n/g, " ")}\nglobs:\nalwaysApply: false\n---\nFollow the instructions in .cursor/skills/${s}/SKILL.md when the user requests this task.\n`);
|
|
162
|
+
else
|
|
163
|
+
fs.writeFileSync(p, `When the user requests the following, defer to the instructions in .kiro/skills/${s}/SKILL.md:\n\n${desc}\n`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* ---------- commands ---------- */
|
|
167
|
+
|
|
168
|
+
function expandNames(args, cat) {
|
|
169
|
+
if (args.flags.all) return skillsIn(cat);
|
|
170
|
+
if (args.flags.pack) {
|
|
171
|
+
const ps = packsOf(cat);
|
|
172
|
+
if (!ps) die(`catalog '${cat.source}' has no packs.json — install skills by name`);
|
|
173
|
+
const p = ps[args.flags.pack];
|
|
174
|
+
if (!p) die(`unknown pack '${args.flags.pack}' in catalog '${cat.source}'`);
|
|
175
|
+
return p.skills.slice();
|
|
176
|
+
}
|
|
177
|
+
if (!args._.length) die("nothing to install — pass skill names, --pack <name>, or --all");
|
|
178
|
+
for (const s of args._) if (!fs.existsSync(path.join(cat.skillsDir, s))) die(`unknown skill '${s}' in catalog '${cat.source}'`);
|
|
179
|
+
return args._.slice();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function copyOne(cat, s, dest, ide, l) {
|
|
183
|
+
const m = manifestOf(cat, s);
|
|
184
|
+
fs.cpSync(path.join(cat.skillsDir, s), path.join(dest, s), { recursive: true });
|
|
185
|
+
writeWiring(ide, dest, s, m.description);
|
|
186
|
+
l.data[s] = { version: m.version, source: cat.source };
|
|
187
|
+
return m;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function install(args) {
|
|
191
|
+
const cat = resolveCatalog(args.flags.from);
|
|
192
|
+
let names = expandNames(args, cat);
|
|
193
|
+
if (args.flags["with-related"]) {
|
|
194
|
+
const seen = new Set(names);
|
|
195
|
+
for (const s of names.slice()) {
|
|
196
|
+
let related = [];
|
|
197
|
+
try { related = manifestOf(cat, s).related || []; } catch (e) { /* gated below */ }
|
|
198
|
+
for (const r of related) if (!seen.has(r) && fs.existsSync(path.join(cat.skillsDir, r))) { seen.add(r); names.push(r); }
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
gate(cat, names);
|
|
202
|
+
const { dest, ide } = target(args.flags);
|
|
203
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
204
|
+
const l = ledger(dest);
|
|
205
|
+
const pipDeps = [], suggestions = new Set();
|
|
206
|
+
for (const s of names) {
|
|
207
|
+
const m = copyOne(cat, s, dest, ide, l);
|
|
208
|
+
if (fs.existsSync(path.join(cat.skillsDir, s, "requirements.txt"))) pipDeps.push(s);
|
|
209
|
+
for (const r of m.related || []) if (!names.includes(r) && !l.data[r]) suggestions.add(r);
|
|
210
|
+
console.log(`installed ${s}@${m.version} -> ${dest}`);
|
|
211
|
+
}
|
|
212
|
+
saveLedger(l);
|
|
213
|
+
console.log(`\n${names.length} skill(s) installed (${ide}).`);
|
|
214
|
+
if (cat.source !== BUNDLED)
|
|
215
|
+
console.log(`\nWARNING: third-party catalog '${cat.source}'. Skills are instructions your AI agent will follow — review each installed SKILL.md under ${dest} before first use. Install copied files only; nothing was executed.`);
|
|
216
|
+
if (ide === "generic")
|
|
217
|
+
console.log("wiring: attach each skill's SKILL.md to your agent (Continue/Cline: @file, Aider: /add, Codex: reference it from AGENTS.md) — see the repo README's per-IDE steps.");
|
|
218
|
+
for (const s of pipDeps)
|
|
219
|
+
console.log(`deps: ${s} needs Python packages — run: cd ${path.join(dest, s)} && python3 -m pip install -r requirements.txt`);
|
|
220
|
+
if (suggestions.size)
|
|
221
|
+
console.log(`related (not installed): ${[...suggestions].sort().join(", ")} — add --with-related or install by name.`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function installedRows(flags) {
|
|
225
|
+
const { dest, ide } = target(flags);
|
|
226
|
+
const l = ledger(dest);
|
|
227
|
+
const rows = Object.keys(l.data).sort().map((s) => {
|
|
228
|
+
const src = lsrc(l.data[s]);
|
|
229
|
+
let current = null, cat = null;
|
|
230
|
+
try {
|
|
231
|
+
cat = resolveCatalog(src === BUNDLED ? undefined : src);
|
|
232
|
+
if (fs.existsSync(path.join(cat.skillsDir, s))) current = manifestOf(cat, s).version;
|
|
233
|
+
} catch (e) { /* unreachable source: current stays null */ }
|
|
234
|
+
return { s, src, cat, installed: lver(l.data[s]), current };
|
|
235
|
+
});
|
|
236
|
+
return { dest, ide, l, rows };
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function update(args) {
|
|
240
|
+
const { dest, ide, l, rows } = installedRows(args.flags);
|
|
241
|
+
if (!rows.length) return console.log(`nothing installed at ${dest}`);
|
|
242
|
+
let n = 0;
|
|
243
|
+
for (const r of rows) {
|
|
244
|
+
if (!r.current) { console.log(`skip ${r.s}: source '${r.src}' unreachable or skill gone from it`); continue; }
|
|
245
|
+
if (r.current === r.installed) continue;
|
|
246
|
+
const problems = checkSkill(r.cat, r.s);
|
|
247
|
+
if (problems.length) { console.log(`skip ${r.s}: fails structural check in '${r.src}' (${problems[0]})`); continue; }
|
|
248
|
+
copyOne(r.cat, r.s, dest, ide, l);
|
|
249
|
+
console.log(`updated ${r.s} ${r.installed} -> ${r.current} (${r.src})`);
|
|
250
|
+
n++;
|
|
251
|
+
}
|
|
252
|
+
saveLedger(l);
|
|
253
|
+
console.log(n ? `\n${n} skill(s) updated.` : "everything up to date.");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function outdated(args) {
|
|
257
|
+
const { dest, rows } = installedRows(args.flags);
|
|
258
|
+
if (!rows.length) return console.log(`nothing installed at ${dest}`);
|
|
259
|
+
const stale = rows.filter((r) => r.current && r.current !== r.installed);
|
|
260
|
+
for (const r of stale) console.log(`${r.s}: installed ${r.installed}, current ${r.current} (${r.src})`);
|
|
261
|
+
console.log(stale.length ? `\n${stale.length} outdated — run: skilldrop update` : "everything up to date.");
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function uninstall(args) {
|
|
265
|
+
if (!args._.length) die("pass skill names to uninstall");
|
|
266
|
+
const { dest, ide } = target(args.flags);
|
|
267
|
+
const l = ledger(dest);
|
|
268
|
+
for (const s of args._) {
|
|
269
|
+
fs.rmSync(path.join(dest, s), { recursive: true, force: true });
|
|
270
|
+
const w = wiringPath(ide, dest, s);
|
|
271
|
+
if (w) fs.rmSync(w, { force: true });
|
|
272
|
+
delete l.data[s];
|
|
273
|
+
console.log(`removed ${s} from ${dest}`);
|
|
274
|
+
}
|
|
275
|
+
saveLedger(l);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function list(args) {
|
|
279
|
+
const cat = resolveCatalog(args.flags.from);
|
|
280
|
+
const rows = skillsIn(cat).map((s) => {
|
|
281
|
+
try { const m = manifestOf(cat, s); return [s, m.version || "?", (m.model && m.model.tier) || "?"]; }
|
|
282
|
+
catch (e) { return [s, "?", "?"]; }
|
|
283
|
+
});
|
|
284
|
+
const w = Math.max(...rows.map((r) => r[0].length));
|
|
285
|
+
for (const [s, v, t] of rows) console.log(`${s.padEnd(w)} ${v} ${t}`);
|
|
286
|
+
console.log(`\n${rows.length} skills in catalog '${cat.source}'. Details: skilldrop info <skill>`);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function info(args) {
|
|
290
|
+
const cat = resolveCatalog(args.flags.from);
|
|
291
|
+
const s = args._[0] || die("pass a skill name");
|
|
292
|
+
if (!fs.existsSync(path.join(cat.skillsDir, s))) die(`unknown skill '${s}' in catalog '${cat.source}'`);
|
|
293
|
+
const m = manifestOf(cat, s);
|
|
294
|
+
const ps = packsOf(cat) || {};
|
|
295
|
+
const inPacks = Object.entries(ps).filter(([, p]) => p.skills.includes(s)).map(([n]) => n);
|
|
296
|
+
console.log(`${m.name}@${m.version} (tier: ${m.model && m.model.tier})\n\n${m.description}\n`);
|
|
297
|
+
console.log(`catalog: ${cat.source}`);
|
|
298
|
+
console.log(`packs: ${inPacks.join(", ") || "-"}`);
|
|
299
|
+
console.log(`related: ${(m.related || []).join(", ") || "-"}`);
|
|
300
|
+
if (((m.deps || {}).pip || []).length || fs.existsSync(path.join(cat.skillsDir, s, "requirements.txt")))
|
|
301
|
+
console.log("deps: python (requirements.txt)");
|
|
302
|
+
if (((m.env || {}).required || []).length) console.log(`env: ${m.env.required.join(", ")} (required)`);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function listPacks(args) {
|
|
306
|
+
const cat = resolveCatalog(args.flags.from);
|
|
307
|
+
const ps = packsOf(cat);
|
|
308
|
+
if (!ps) return console.log(`catalog '${cat.source}' defines no packs.`);
|
|
309
|
+
const w = Math.max(...Object.keys(ps).map((n) => n.length));
|
|
310
|
+
for (const [n, p] of Object.entries(ps))
|
|
311
|
+
console.log(`${n.padEnd(w)} (${p.skills.length} skills) ${p.description}`);
|
|
312
|
+
console.log("\nInstall one: skilldrop install --pack <name>");
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function validateCmd(args) {
|
|
316
|
+
const cat = resolveCatalog(args.flags.from);
|
|
317
|
+
const names = skillsIn(cat);
|
|
318
|
+
let bad = 0;
|
|
319
|
+
for (const s of names) {
|
|
320
|
+
const problems = checkSkill(cat, s);
|
|
321
|
+
for (const p of problems) console.log(`FAIL ${s}: ${p}`);
|
|
322
|
+
if (problems.length) bad++;
|
|
323
|
+
}
|
|
324
|
+
const ps = packsOf(cat);
|
|
325
|
+
if (ps)
|
|
326
|
+
for (const [n, p] of Object.entries(ps))
|
|
327
|
+
for (const s of p.skills)
|
|
328
|
+
if (!names.includes(s)) { console.log(`FAIL packs.json: pack '${n}' lists unknown skill '${s}'`); bad++; }
|
|
329
|
+
if (bad) { console.log(`\n${bad} problem(s) in catalog '${cat.source}'.`); process.exit(1); }
|
|
330
|
+
console.log(`OK: ${names.length} skills in catalog '${cat.source}' pass the structural check.`);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const args = parseArgs(process.argv.slice(2));
|
|
334
|
+
const cmd = args._.shift();
|
|
335
|
+
const commands = { list, info, packs: listPacks, install, update, outdated, uninstall, validate: validateCmd };
|
|
336
|
+
if (!cmd || cmd === "help" || args.flags.help) console.log(HELP);
|
|
337
|
+
else if (commands[cmd]) commands[cmd](args);
|
|
338
|
+
else die(`unknown command '${cmd}' — run: skilldrop help`);
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Provider-neutral, cost-aware model routing for skilldrop skills. Skills declare an ABSTRACT tier (light/standard/heavy) describing how much reasoning the task needs. The `providers` map resolves that tier to a concrete model for whatever tool you use (Claude Code, Cursor, Codex, Kiro, ...). Set `active_provider` to your tool. Tier is decided ONCE per skill (the decision is stable), not re-derived per call — that keeps routing free. Runtime heuristics in `escalation_rules` handle the cases that actually vary.",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"active_provider": "claude-code",
|
|
5
|
+
"tiers": {
|
|
6
|
+
"light": {
|
|
7
|
+
"use_for": "Mechanical mapping, extraction, and lookup against a fixed rubric. Deterministic enough that a small/cheap model matches a large one.",
|
|
8
|
+
"relative_cost": 1
|
|
9
|
+
},
|
|
10
|
+
"standard": {
|
|
11
|
+
"use_for": "Most generation. Synthesizing a structured artifact from a brief, where quality matters but the reasoning is not adversarial. The default tier.",
|
|
12
|
+
"relative_cost": 4
|
|
13
|
+
},
|
|
14
|
+
"heavy": {
|
|
15
|
+
"use_for": "Adversarial reasoning and weighted judgment, where a cheaper model demonstrably misses edge cases, under-calls severity, or mis-weights tradeoffs. Spend here only when the hard thinking IS the value.",
|
|
16
|
+
"relative_cost": 20
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"providers": {
|
|
20
|
+
"claude-code": {
|
|
21
|
+
"label": "Claude Code (Anthropic)",
|
|
22
|
+
"models": {
|
|
23
|
+
"light": "claude-haiku-4-5-20251001",
|
|
24
|
+
"standard": "claude-sonnet-4-6",
|
|
25
|
+
"heavy": "claude-opus-4-8"
|
|
26
|
+
},
|
|
27
|
+
"select_via": "`/model <model-id>` in the session, or hand the skill to the model-router agent for automatic dispatch.",
|
|
28
|
+
"automation": ".claude/agents/model-router.md"
|
|
29
|
+
},
|
|
30
|
+
"cursor": {
|
|
31
|
+
"label": "Cursor",
|
|
32
|
+
"models": {
|
|
33
|
+
"light": "<your cheapest capable model, e.g. a small Claude/GPT/Gemini>",
|
|
34
|
+
"standard": "<your default model>",
|
|
35
|
+
"heavy": "<your most capable model>"
|
|
36
|
+
},
|
|
37
|
+
"select_via": "Pick the model in the chat/composer model dropdown before invoking the skill. Cursor rules cannot switch models programmatically — this is a manual lookup.",
|
|
38
|
+
"automation": null,
|
|
39
|
+
"note": "Cursor exposes whatever models your plan enables (Claude, GPT, Gemini). Fill in the three you actually use."
|
|
40
|
+
},
|
|
41
|
+
"openai-codex": {
|
|
42
|
+
"label": "OpenAI Codex CLI",
|
|
43
|
+
"models": {
|
|
44
|
+
"light": "<your cheapest OpenAI model>",
|
|
45
|
+
"standard": "<your default OpenAI model>",
|
|
46
|
+
"heavy": "<your most capable OpenAI model>"
|
|
47
|
+
},
|
|
48
|
+
"select_via": "Set the model via the Codex `--model` flag or its config before running the skill.",
|
|
49
|
+
"automation": null,
|
|
50
|
+
"note": "Fill in with the model identifiers your Codex install accepts. Model names change — verify against `codex --help` / your config."
|
|
51
|
+
},
|
|
52
|
+
"kiro": {
|
|
53
|
+
"label": "Kiro",
|
|
54
|
+
"models": {
|
|
55
|
+
"light": "<your cheapest capable model>",
|
|
56
|
+
"standard": "<your default model>",
|
|
57
|
+
"heavy": "<your most capable model>"
|
|
58
|
+
},
|
|
59
|
+
"select_via": "Select the model in Kiro's model picker, or pin it in the custom-agent / steering definition that loads the skill.",
|
|
60
|
+
"automation": null
|
|
61
|
+
},
|
|
62
|
+
"generic": {
|
|
63
|
+
"label": "Any other tool",
|
|
64
|
+
"models": {
|
|
65
|
+
"light": "<your cheapest capable model>",
|
|
66
|
+
"standard": "<your default model>",
|
|
67
|
+
"heavy": "<your most capable model>"
|
|
68
|
+
},
|
|
69
|
+
"select_via": "However your tool selects a model. The tier tells you which of your three to pick.",
|
|
70
|
+
"automation": null
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"escalation_rules": [
|
|
74
|
+
{
|
|
75
|
+
"id": "large-input",
|
|
76
|
+
"rule": "Escalate one tier (light→standard, standard→heavy) when the input the skill must reason over exceeds ~30 pages / ~20k words / ~15 source files. Large context degrades small models faster than large ones.",
|
|
77
|
+
"type": "heuristic_no_llm"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"id": "reasoning-floor",
|
|
81
|
+
"rule": "Never downgrade a skill whose tier is 'heavy'. These are the reasoning skills; downgrading defeats their purpose. The router may upgrade but never demote below the skill's declared tier.",
|
|
82
|
+
"type": "hard_constraint"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "ambiguous-input",
|
|
86
|
+
"rule": "Escalate one tier when the input is contradictory, underspecified, or the user explicitly asks for the most rigorous output ('be thorough', 'this is going to the board'). Do NOT escalate just because the topic sounds important.",
|
|
87
|
+
"type": "heuristic_no_llm"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"id": "downgrade-trivial",
|
|
91
|
+
"rule": "Downgrade one tier (never below 'light', never below the skill's declared floor) when the input is tiny and templated — e.g. a one-paragraph brief into adr-generator, a 3-line note into decision-log.",
|
|
92
|
+
"type": "heuristic_no_llm"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "user-override",
|
|
96
|
+
"rule": "An explicit user model choice always wins. The router reports what it would have picked, then honors the override.",
|
|
97
|
+
"type": "hard_constraint"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
"skills": {
|
|
101
|
+
"audience-profile": { "tier": "light", "rationale": "Maps a fixed set of audience archetypes to structural rules. Lookup against a rubric, not synthesis." },
|
|
102
|
+
"decision-log": { "tier": "light", "rationale": "Extracts decisions/owners/dates from notes. Pattern extraction; escalate on long transcripts via large-input rule." },
|
|
103
|
+
"sonar-onboard": { "tier": "light", "rationale": "Scaffolds config from detected language + a template. Deterministic fill-in; little judgment." },
|
|
104
|
+
"adr-generator": { "tier": "standard", "rationale": "Structures a decision into MADR/Nygard. Some judgment on title/consequences; not adversarial." },
|
|
105
|
+
"architecture-diagrams": { "tier": "standard", "rationale": "Translates prose to diagram syntax. Correctness matters; reasoning is bounded." },
|
|
106
|
+
"brief-intake": { "tier": "standard", "rationale": "Extraction + tagging [explicit]/[implied]/[inferred]. The tagging needs care — above light, below heavy." },
|
|
107
|
+
"deck-builder": { "tier": "standard", "rationale": "Generates pptx content + runs a script. Content shaping, not hard reasoning." },
|
|
108
|
+
"design-doc": { "tier": "standard", "rationale": "Synthesizes a design doc from a brief. Escalate to heavy via large-input or ambiguous-input when alternatives are genuinely contested." },
|
|
109
|
+
"exec-summary": { "tier": "standard", "rationale": "Compression to one page. Needs to keep the right signal; escalate on very long source docs." },
|
|
110
|
+
"figma-diagrams": { "tier": "standard", "rationale": "API calls + spec generation. Bounded transformation." },
|
|
111
|
+
"guide-builder": { "tier": "standard", "rationale": "Shapes notes into a styled guide. Generation, not adversarial review." },
|
|
112
|
+
"reverse-architecture": { "tier": "standard", "rationale": "Extracts architecture from code/IaC. Escalate to heavy on large codebases where cross-file inference is heavy." },
|
|
113
|
+
"runbook-generator": { "tier": "standard", "rationale": "Operational doc from service facts. Bounded synthesis." },
|
|
114
|
+
"slide-outliner": { "tier": "standard", "rationale": "Outlines a deck to a time budget. Structuring, not deep reasoning." },
|
|
115
|
+
"sonar-review": { "tier": "standard", "rationale": "Formats Sonar API findings into a report. The hard analysis is Sonar's; this is synthesis. Escalate on very large diffs." },
|
|
116
|
+
"ai-usage-report": { "tier": "standard", "rationale": "Tabulates telemetry into a report. Mostly mechanical, but the 'AI theater' effectiveness call needs judgment." },
|
|
117
|
+
"feature-implement-loop": { "tier": "standard", "rationale": "Code + test generation against acceptance criteria. The adversarial pass delegates to devils-advocate (heavy) where available; the loop itself is generation." },
|
|
118
|
+
"user-story-splitter": { "tier": "standard", "rationale": "Decomposes an epic into INVEST slices with testable ACs. Structured synthesis; escalation rules cover large or contradictory PRDs." },
|
|
119
|
+
"test-plan-generator": { "tier": "standard", "rationale": "Synthesizes a structured plan from a change description. Risk ranking needs judgment but is bounded; escalate via ambiguous-input on contested or high-stakes releases." },
|
|
120
|
+
"release-notes": { "tier": "standard", "rationale": "Classifies commits and rewrites them for a reader. The audience translation needs judgment; escalate via large-input on very long ranges." },
|
|
121
|
+
"postmortem-generator": { "tier": "standard", "rationale": "Synthesizes a structured doc from incident notes. Contributing-factor chains need judgment but are bounded; escalate via large-input on huge scrollbacks." },
|
|
122
|
+
"migration-plan": { "tier": "standard", "rationale": "Phased plan synthesis with a strong template. Ordering judgment is bounded by the expand/migrate/contract pattern; escalate via ambiguous-input on contested, high-stakes cutovers." },
|
|
123
|
+
"api-contract-draft": { "tier": "standard", "rationale": "Schema synthesis against fixed conventions. The resource modeling needs judgment; the conventions bound it. Escalate via ambiguous-input on contested multi-team contracts." },
|
|
124
|
+
"bug-triage": { "tier": "standard", "rationale": "Extraction plus judgment calls (severity vs priority, hypothesis ranking) — same shape as brief-intake: above light, below heavy." },
|
|
125
|
+
"prd-draft": { "tier": "standard", "rationale": "Synthesizes a structured requirements doc from a brief. The solution-language discipline needs care; bounded by the template. Escalate via ambiguous-input on contested scope." },
|
|
126
|
+
"nfr-spec": { "tier": "standard", "rationale": "Rubric-driven sweep with archetype defaults; the judgment is calibrating targets to business reality. Bounded by the catalog; escalate via ambiguous-input on contested SLOs." },
|
|
127
|
+
"success-metrics": { "tier": "standard", "rationale": "Structured measurement design; the primary-metric and counter-metric choices need judgment but the template bounds it. Escalate via ambiguous-input when the goal itself is contested." },
|
|
128
|
+
"requirements-interview": { "tier": "standard", "rationale": "Question banks are rubric-shaped, but ranking by design impact and deriving falsification conditions for the specific feature is synthesis — above light." },
|
|
129
|
+
"business-case": { "tier": "heavy", "rationale": "Weighted multi-option judgment with a committal recommendation — same failure mode as tech-comparison-matrix: cheaper models mis-weight costs, inflate benefits, and miss the flip-assumption. Never downgrade." },
|
|
130
|
+
"incident-comms": { "tier": "standard", "rationale": "Audience-segmented message generation under a strict don't-retract discipline. Same shape as exec-summary/audience-profile — translation and altitude, not adversarial reasoning." },
|
|
131
|
+
"data-contract": { "tier": "standard", "rationale": "Schema + SLA synthesis against fixed quality dimensions and an evolution matrix. Semantics capture needs care; bounded by the catalog. Escalate via large-input on wide schemas." },
|
|
132
|
+
"llm-eval-harness": { "tier": "standard", "rationale": "Methodology synthesis against a fixed decision tree and pitfall catalog. Grading-method and metric choices need judgment but are bounded; escalate via ambiguous-input on novel task types." },
|
|
133
|
+
"capacity-cost-model": { "tier": "standard", "rationale": "Quantitative projection from a demand model against a fixed cost catalog. Headroom and scaling-cliff judgment is bounded by the reference; escalate via ambiguous-input on novel architectures." },
|
|
134
|
+
"accessibility-audit": { "tier": "heavy", "rationale": "Adversarial review against WCAG success criteria — cheaper models fault alt-text presence over quality, under-call severity, miss focus-order/name-role-value issues, and claim AT passes from screenshots. Never downgrade." },
|
|
135
|
+
"db-schema-design": { "tier": "standard", "rationale": "Design synthesis from access patterns against a fixed paradigm/indexing/anti-pattern reference. Paradigm and denormalization judgment is bounded; escalate via ambiguous-input on contested scale/consistency tradeoffs." },
|
|
136
|
+
"observability-plan": { "tier": "standard", "rationale": "Methodology synthesis against fixed SRE practices (golden signals, burn-rate alerting, pillar split). SLO calibration needs judgment but is bounded; escalate via ambiguous-input on contested reliability targets." },
|
|
137
|
+
"council-review": { "tier": "heavy", "rationale": "Multi-perspective deliberation + weighted reconciliation across distinct expert seats. Cheaper models collapse the seats into one voice and either manufacture or miss the real cruxes. Never downgrade." },
|
|
138
|
+
"devils-advocate": { "tier": "heavy", "rationale": "Adversarial code review across four lenses. Cheaper models miss edge cases and under-call severity — the whole value is the hard thinking. Never downgrade." },
|
|
139
|
+
"doc-critique": { "tier": "heavy", "rationale": "Adversarial doc review against rubrics. Same as devils-advocate: the value is catching what a fast pass misses. Never downgrade." },
|
|
140
|
+
"tech-comparison-matrix": { "tier": "heavy", "rationale": "Weighted multi-criteria judgment with a recommendation. Mis-weighting is the failure mode; heavy is worth it. Never downgrade." },
|
|
141
|
+
"threat-model": { "tier": "heavy", "rationale": "Adversarial reasoning over a design — cheaper models emit checklist residue, miss authz/insider paths, and inflate severity. Never downgrade." },
|
|
142
|
+
"prfaq": { "tier": "standard", "rationale": "Synthesizes a press release and FAQs from a product concept against a fixed format. The specificity discipline needs care but the template bounds it; escalate via ambiguous-input when the concept itself is contested." },
|
|
143
|
+
"okr-cascade": { "tier": "standard", "rationale": "Structured derivation against a fixed roll-up discipline; the causal-sentence and gap judgments need care but the template bounds them. Escalate via ambiguous-input when the company objectives themselves are contested." },
|
|
144
|
+
"user-journey-map": { "tier": "standard", "rationale": "Structured synthesis into a fixed four-row stage model plus bounded ranking judgment. Escalate via ambiguous-input when the persona or outcome is contested or research inputs conflict." },
|
|
145
|
+
"strategy-analysis": { "tier": "heavy", "rationale": "Framework selection plus evidenced multi-factor judgment ending in a ranked, committal verdict. Cheaper models fill cells with generic filler, skip the TOWS crossings, and refuse to take a side. Never downgrade." }
|
|
146
|
+
}
|
|
147
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skilldrop-cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Portable AI-agent skills for the deliverables knowledge workers ship — diagrams, ADRs, PRDs, runbooks, decks, reviews — installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"skilldrop": "bin/skilldrop.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin/",
|
|
10
|
+
"skills/",
|
|
11
|
+
"packs.json",
|
|
12
|
+
"model-routing.json"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=16.7.0"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"claude",
|
|
19
|
+
"claude-code",
|
|
20
|
+
"cursor",
|
|
21
|
+
"kiro",
|
|
22
|
+
"codex",
|
|
23
|
+
"ai-agent",
|
|
24
|
+
"skills",
|
|
25
|
+
"prompts",
|
|
26
|
+
"adr",
|
|
27
|
+
"prd",
|
|
28
|
+
"runbook",
|
|
29
|
+
"diagrams"
|
|
30
|
+
],
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/sananthanarayan/skilldrop.git"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT"
|
|
36
|
+
}
|
package/packs.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Virtual skill packs — role-based bundles for one-command install. Packs are METADATA ONLY: skills stay in flat skills/<name> folders (golden rule: skills are discovered by path), a skill may belong to several packs, and every skill must belong to at least one (validate.py enforces both directions). Install a pack with `python3 pack.py <pack> --install`; see README. Rationale: docs/rfcs/0001-skill-packs.md.",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"packs": {
|
|
5
|
+
"solution-architect": {
|
|
6
|
+
"description": "Design-phase artifacts: diagrams, decision records, design docs, contracts, schemas, threat models, and the reviews that gate them.",
|
|
7
|
+
"skills": [
|
|
8
|
+
"brief-intake",
|
|
9
|
+
"architecture-diagrams",
|
|
10
|
+
"reverse-architecture",
|
|
11
|
+
"figma-diagrams",
|
|
12
|
+
"adr-generator",
|
|
13
|
+
"design-doc",
|
|
14
|
+
"tech-comparison-matrix",
|
|
15
|
+
"threat-model",
|
|
16
|
+
"api-contract-draft",
|
|
17
|
+
"data-contract",
|
|
18
|
+
"db-schema-design",
|
|
19
|
+
"nfr-spec",
|
|
20
|
+
"capacity-cost-model",
|
|
21
|
+
"council-review",
|
|
22
|
+
"doc-critique"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"product-manager": {
|
|
26
|
+
"description": "Direction to requirements: PR/FAQs, strategy frameworks, OKRs, PRDs, journey maps, story splitting, and success measurement.",
|
|
27
|
+
"skills": [
|
|
28
|
+
"brief-intake",
|
|
29
|
+
"prfaq",
|
|
30
|
+
"strategy-analysis",
|
|
31
|
+
"okr-cascade",
|
|
32
|
+
"business-case",
|
|
33
|
+
"requirements-interview",
|
|
34
|
+
"prd-draft",
|
|
35
|
+
"user-journey-map",
|
|
36
|
+
"user-story-splitter",
|
|
37
|
+
"success-metrics",
|
|
38
|
+
"exec-summary",
|
|
39
|
+
"doc-critique"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"dev-team": {
|
|
43
|
+
"description": "Build-and-ship loop: story implementation with adversarial review, test plans, triage, migrations, release notes, and code-quality gates.",
|
|
44
|
+
"skills": [
|
|
45
|
+
"user-story-splitter",
|
|
46
|
+
"feature-implement-loop",
|
|
47
|
+
"devils-advocate",
|
|
48
|
+
"council-review",
|
|
49
|
+
"test-plan-generator",
|
|
50
|
+
"bug-triage",
|
|
51
|
+
"migration-plan",
|
|
52
|
+
"release-notes",
|
|
53
|
+
"sonar-onboard",
|
|
54
|
+
"sonar-review",
|
|
55
|
+
"accessibility-audit"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"sre-oncall": {
|
|
59
|
+
"description": "Operate the service: runbooks, observability design, incident communications, postmortems, and capacity/cost models.",
|
|
60
|
+
"skills": [
|
|
61
|
+
"runbook-generator",
|
|
62
|
+
"observability-plan",
|
|
63
|
+
"incident-comms",
|
|
64
|
+
"postmortem-generator",
|
|
65
|
+
"capacity-cost-model"
|
|
66
|
+
]
|
|
67
|
+
},
|
|
68
|
+
"stakeholder-comms": {
|
|
69
|
+
"description": "Non-technical audiences: audience profiling, deck outlines and real .pptx decks, exec summaries, decision logs, and guides.",
|
|
70
|
+
"skills": [
|
|
71
|
+
"brief-intake",
|
|
72
|
+
"audience-profile",
|
|
73
|
+
"slide-outliner",
|
|
74
|
+
"deck-builder",
|
|
75
|
+
"exec-summary",
|
|
76
|
+
"decision-log",
|
|
77
|
+
"guide-builder",
|
|
78
|
+
"doc-critique"
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
"ai-engineering": {
|
|
82
|
+
"description": "Ship and measure AI features: eval harness design, AI-usage reporting, and the data contracts AI pipelines depend on.",
|
|
83
|
+
"skills": [
|
|
84
|
+
"llm-eval-harness",
|
|
85
|
+
"ai-usage-report",
|
|
86
|
+
"data-contract"
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|