swe-workflow-skills 0.2.0 → 0.4.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/README.md +8 -6
- package/VERSION +1 -1
- package/catalog.json +21 -6
- package/commands/role.md +46 -12
- package/install.mjs +114 -8
- package/package.json +2 -2
- package/roles.json +14 -0
- package/scripts/resolve.mjs +8 -3
- package/skills/ai-evaluation/SKILL.md +2 -1
- package/skills/code-reviewing/SKILL.md +13 -3
- package/skills/effort-estimation/SKILL.md +24 -67
- package/skills/exploratory-data-analysis/SKILL.md +110 -0
- package/skills/exploratory-data-analysis/evals/evals.json +43 -0
- package/skills/git-workflow/SKILL.md +21 -14
- package/skills/ml-pipeline-design/SKILL.md +8 -2
- package/skills/ml-pipeline-design/evals/evals.json +10 -0
- package/skills/notebook-to-production/SKILL.md +89 -0
- package/skills/notebook-to-production/evals/evals.json +42 -0
- package/skills/project-documentation/SKILL.md +7 -4
- package/skills/project-review/SKILL.md +13 -3
- package/skills/security-audit/SKILL.md +13 -2
- package/skills/skill-router/SKILL.md +11 -1
- package/skills/statistical-analysis/SKILL.md +93 -0
- package/skills/statistical-analysis/evals/evals.json +43 -0
- package/skills/strategic-review/SKILL.md +16 -2
- package/skills/technical-debt-review/SKILL.md +12 -2
- package/skills/writing-skills/SKILL.md +36 -20
- package/uninstall.mjs +27 -5
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# SWE Workflow Skills for Claude Code
|
|
2
2
|
|
|
3
3
|
[](https://github.com/SWEStash/swe-workflow-skills/actions/workflows/roles-check.yml)
|
|
4
|
-

|
|
5
5
|
[](LICENSE)
|
|
6
6
|
|
|
7
|
-
A curated library of **
|
|
7
|
+
A curated library of **65 Claude Code Agent Skills** that walk Claude through the
|
|
8
8
|
software lifecycle the way a disciplined senior engineer would — planning, design,
|
|
9
9
|
TDD, review, security, deployment, incidents, and the project-management work around
|
|
10
10
|
them.
|
|
@@ -43,8 +43,8 @@ full-SDLC breadth that popular collections don't cover:
|
|
|
43
43
|
know of aim for (they tend to go deep on the coding inner loop; see
|
|
44
44
|
[Acknowledgements](#acknowledgements)).
|
|
45
45
|
- **Role-scoped.** `/role backend` (or `frontend`, `devops`, `ml`, `ai`, `data`,
|
|
46
|
-
`security`, `architect`, `em`, `pm`, `strategy`, `qa`, `mobile`,
|
|
47
|
-
a working set to auto-trigger; the rest stay one route away.
|
|
46
|
+
`data-scientist`, `security`, `architect`, `em`, `pm`, `strategy`, `qa`, `mobile`,
|
|
47
|
+
`designer`) promotes a working set to auto-trigger; the rest stay one route away.
|
|
48
48
|
- **Cross-platform install.** The installer and SessionStart hook are **pure Node** — the
|
|
49
49
|
one runtime Claude Code already requires — so they run identically on Linux, macOS, and
|
|
50
50
|
Windows (no bash, Python, or `sed`).
|
|
@@ -62,7 +62,7 @@ web, claude.ai chat, and Cowork):
|
|
|
62
62
|
**Want the whole library with the orchestrator** (CLI) — no clone needed:
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
npx swe-workflow-skills install --global # all
|
|
65
|
+
npx swe-workflow-skills install --global # all 65 skills + router + /role + the SessionStart hook
|
|
66
66
|
```
|
|
67
67
|
|
|
68
68
|
Or from a clone: `node install.mjs --global`.
|
|
@@ -120,7 +120,7 @@ review) live in the `skill-router` skill and **[ROLES.md](docs/ROLES.md)**.
|
|
|
120
120
|
|
|
121
121
|
## What's included
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
65 skills — **[full catalog → SKILLS.md](docs/SKILLS.md)**:
|
|
124
124
|
|
|
125
125
|
| Area | Count | Examples |
|
|
126
126
|
|------|-------|----------|
|
|
@@ -130,6 +130,7 @@ review) live in the `skill-router` skill and **[ROLES.md](docs/ROLES.md)**.
|
|
|
130
130
|
| Design | 3 | ui-ux-design, frontend-architecture, accessibility-design |
|
|
131
131
|
| MLOps | 3 | ml-pipeline-design, ml-experiment-tracking, ml-model-deployment |
|
|
132
132
|
| AI Engineering | 2 | llm-app-engineering, ai-evaluation |
|
|
133
|
+
| Data Science | 3 | exploratory-data-analysis, statistical-analysis, notebook-to-production |
|
|
133
134
|
| Data Engineering | 2 | data-pipeline-design, data-quality |
|
|
134
135
|
| Mobile | 2 | mobile-architecture, mobile-release |
|
|
135
136
|
| Evaluation & Monitoring | 2 | observability-design, test-data-strategy |
|
|
@@ -143,6 +144,7 @@ review) live in the `skill-router` skill and **[ROLES.md](docs/ROLES.md)**.
|
|
|
143
144
|
- **[EVALS.md](docs/EVALS.md)** — how the skills are tested (RED/GREEN, pressure tests, CI gate).
|
|
144
145
|
- **[AUTHORING.md](docs/AUTHORING.md)** — write or modify a skill (descriptions, budget, progressive disclosure, evals).
|
|
145
146
|
- **[RELEASING.md](docs/RELEASING.md)** — versioning policy and how to cut a release. Changes are tracked in **[CHANGELOG.md](CHANGELOG.md)**.
|
|
147
|
+
- **[SECURITY.md](SECURITY.md)** — the security model: trust boundaries, what runs automatically, supply-chain guarantees, and how to report a vulnerability.
|
|
146
148
|
|
|
147
149
|
## Evaluation
|
|
148
150
|
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.4.0
|
package/catalog.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
{
|
|
10
10
|
"name": "ai-evaluation",
|
|
11
|
-
"description": "Define how to evaluate ML models and GenAI/LLM apps — golden datasets, offline metrics, RAG evaluation (faithfulness,
|
|
11
|
+
"description": "Define how to evaluate ML models and GenAI/LLM apps — golden datasets, offline metrics, RAG evaluation (faithfulness, relevance, context precision/recall) with ragas/deepeval/promptfoo, LLM-as-judge design and calibration, eval regression gates in CI, online A/B and human feedback. Logging/comparing runs → ml-experiment-tracking; building the app → llm-app-engineering; general experiment statistics → statistical-analysis. Triggers: evaluate the model, eval my chatbot, RAG evals, ragas, LLM as judge, golden dataset, eval suite, is the new prompt better, hallucination rate, benchmark our AI app.",
|
|
12
12
|
"path": "ai-evaluation/SKILL.md"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
@@ -121,6 +121,11 @@
|
|
|
121
121
|
"description": "Estimate engineering effort with agile techniques — story points, t-shirt sizing, three-point estimation, capacity planning. Triggers: estimate this, how long will this take, story points, t-shirt sizing, effort estimation, capacity planning, sprint planning, budget estimate, forecast, velocity, when will this be done.",
|
|
122
122
|
"path": "effort-estimation/SKILL.md"
|
|
123
123
|
},
|
|
124
|
+
{
|
|
125
|
+
"name": "exploratory-data-analysis",
|
|
126
|
+
"description": "Explore and profile an unfamiliar dataset before modeling or analysis — structural profiling, missingness structure, distributions and outliers, feature–target relationships, leakage awareness, and explicit hypothesis generation. Pipeline-level data trust (broken dashboards, tests, contracts, freshness) → data-quality; formal inference on the hypotheses → statistical-analysis. Triggers: explore this dataset, EDA, profile the data, what's in this data, first look at the data, understand this CSV, distributions, outliers, missing values, correlation, data leakage.",
|
|
127
|
+
"path": "exploratory-data-analysis/SKILL.md"
|
|
128
|
+
},
|
|
124
129
|
{
|
|
125
130
|
"name": "feature-planning",
|
|
126
131
|
"description": "Break features into well-scoped tasks with acceptance criteria, risk assessment, and dependency mapping. Triggers: plan this, break this down, scope this feature, create tasks for, sprint planning, how should I implement this feature, user stories, acceptance criteria, dependency mapping, feature breakdown. Creates the plan — executing an already-approved plan checkpoint by checkpoint → plan-execution.",
|
|
@@ -178,7 +183,7 @@
|
|
|
178
183
|
},
|
|
179
184
|
{
|
|
180
185
|
"name": "ml-pipeline-design",
|
|
181
|
-
"description": "Design reproducible ML training and data pipelines — ingestion, validation, feature engineering, training, evaluation, continuous training orchestration. Triggers: training pipeline, ML data pipeline, feature engineering, ETL for ML, continuous training, data validation, feature store, preprocessing, notebook to pipeline, orchestrate training, Kubeflow, pipeline DAG, point-in-time features.
|
|
186
|
+
"description": "Design reproducible ML training and data pipelines — ingestion, validation, feature engineering, training, evaluation, continuous training orchestration. Analytics/BI ELT and dbt warehouse pipelines → data-pipeline-design; refactoring general analysis/reporting notebooks (no model training) to production code → notebook-to-production. Triggers: training pipeline, ML data pipeline, feature engineering, ETL for ML, continuous training, data validation, feature store, preprocessing, notebook to training pipeline, orchestrate training, Kubeflow, pipeline DAG, point-in-time features.",
|
|
182
187
|
"path": "ml-pipeline-design/SKILL.md"
|
|
183
188
|
},
|
|
184
189
|
{
|
|
@@ -191,6 +196,11 @@
|
|
|
191
196
|
"description": "Ship mobile apps through the app stores — signing and provisioning, store review and rejection handling, phased/staged rollouts with halt criteria, crash monitoring, versioning and build numbers, beta channels (TestFlight, Play tracks), forced updates, and the no-instant-rollback reality of mobile. Triggers: app store release, publish to App Store, Play Store, TestFlight, staged rollout, app review rejected, code signing, provisioning profile, mobile release, hotfix a mobile bug. General semver/registry/library publishing → release-management.",
|
|
192
197
|
"path": "mobile-release/SKILL.md"
|
|
193
198
|
},
|
|
199
|
+
{
|
|
200
|
+
"name": "notebook-to-production",
|
|
201
|
+
"description": "Refactor analysis notebooks into production-grade code — triage what deserves productionizing, extract modules with tests, parameterize hardcoded values, pin environments for reproducibility, and schedule unattended runs with alerting. Owns general analysis/reporting notebooks; notebooks that feed model TRAINING (feature engineering + training DAGs, scheduled retraining) → ml-pipeline-design. Triggers: productionize this notebook, notebook to script, notebook to module, refactor my notebook, parameterize notebook, papermill, schedule this analysis, reproducible analysis, notebook is a mess.",
|
|
202
|
+
"path": "notebook-to-production/SKILL.md"
|
|
203
|
+
},
|
|
194
204
|
{
|
|
195
205
|
"name": "observability-design",
|
|
196
206
|
"description": "Design production observability — SLIs, SLOs, SLAs, error budgets, OpenTelemetry traces/metrics/logs, structured logging, alerting, dashboards. Triggers: SLO, SLI, SLA, error budget, observability, monitoring, OpenTelemetry, OTel, tracing, distributed tracing, structured logging, alerting, dashboard, metrics, correlation ID, alert fatigue.",
|
|
@@ -223,7 +233,7 @@
|
|
|
223
233
|
},
|
|
224
234
|
{
|
|
225
235
|
"name": "project-review",
|
|
226
|
-
"description": "Review a built project's execution health before a milestone — scope alignment, roadmap / execution-plan adherence, implementation maturity (what's production-ready vs stub/deferred), and the evidence it actually works (tests, coverage, validation results, changelog). Triggers: project review, execution review, are we on track, implementation vs roadmap, scope drift, readiness review, what's actually built, validation results review, pre-launch review.
|
|
236
|
+
"description": "Review a built project's execution health before a milestone — scope alignment, roadmap / execution-plan adherence, implementation maturity (what's production-ready vs stub/deferred), and the evidence it actually works (tests, coverage, validation results, changelog). Use strategic-review for vision/positioning/market; technical-debt-review for a pure code-health audit. Triggers: project review, execution review, are we on track, implementation vs roadmap, scope drift, readiness review, what's actually built, validation results review, pre-launch review.",
|
|
227
237
|
"path": "project-review/SKILL.md"
|
|
228
238
|
},
|
|
229
239
|
{
|
|
@@ -253,17 +263,22 @@
|
|
|
253
263
|
},
|
|
254
264
|
{
|
|
255
265
|
"name": "security-audit",
|
|
256
|
-
"description": "Comprehensive security analysis — OWASP Top 10, auth/authz flows, injection vulnerabilities, data exposure, secrets detection, dependency CVEs, hardening recommendations. Triggers: security audit, vulnerability, is this secure, security review, pentest prep, OWASP, harden this, check for vulnerabilities, injection, XSS, CSRF, auth security.
|
|
266
|
+
"description": "Comprehensive security analysis — OWASP Top 10, auth/authz flows, injection vulnerabilities, data exposure, secrets detection, dependency CVEs, hardening recommendations. Reviews EXISTING code/config — design-time analysis of a system not yet built → threat-modeling. Triggers: security audit, vulnerability, is this secure, security review, pentest prep, OWASP, harden this, check for vulnerabilities, injection, XSS, CSRF, auth security.",
|
|
257
267
|
"path": "security-audit/SKILL.md"
|
|
258
268
|
},
|
|
259
269
|
{
|
|
260
270
|
"name": "skill-router",
|
|
261
|
-
"description": "Orchestrator and entry point for the swe-workflow skills library — consult FIRST when starting any non-trivial software task; most skills load name-only and only activate when invoked here. Triggers: starting a feature, planning, an architecture or design decision, implementing, debugging, reviewing, refactoring, testing, security, deployment, an incident, shipping, or unsure which skill fits.
|
|
271
|
+
"description": "Orchestrator and entry point for the swe-workflow skills library — consult FIRST when starting any non-trivial software task; most skills load name-only and only activate when invoked here. Routes intent to the right skill(s) and invokes them by name; shows the Golden Path chains. Triggers: starting a feature, planning, an architecture or design decision, implementing, debugging, reviewing, refactoring, testing, security, deployment, an incident, shipping, or unsure which skill fits.",
|
|
262
272
|
"path": "skill-router/SKILL.md"
|
|
263
273
|
},
|
|
274
|
+
{
|
|
275
|
+
"name": "statistical-analysis",
|
|
276
|
+
"description": "Design and analyze experiments and statistical tests — test selection with stated assumptions, sample size and power, effect sizes and confidence intervals over bare p-values, and pitfall discipline (multiple comparisons, p-hacking, peeking/optional stopping). Owns experiment statistics generally; live A/B evaluation of AI/LLM apps (quality metrics, judges, feedback) → ai-evaluation. Triggers: hypothesis test, t-test, chi-square, p-value, statistical significance, confidence interval, sample size, power analysis, design an experiment, A/B test, multiple comparisons, is this difference real.",
|
|
277
|
+
"path": "statistical-analysis/SKILL.md"
|
|
278
|
+
},
|
|
264
279
|
{
|
|
265
280
|
"name": "strategic-review",
|
|
266
|
-
"description": "Review a project's strategic position before going public, launching, or raising — vision, mission, value proposition, scope positioning, the defensible wedge, and a live competitive / market comparative analysis. Triggers: strategic review, positioning, go public, go-to-market, market analysis, competitive landscape, value proposition, is there a moat, who are our competitors, platform absorption risk, market positioning, comparable products.
|
|
281
|
+
"description": "Review a project's strategic position before going public, launching, or raising — vision, mission, value proposition, scope positioning, the defensible wedge, and a live competitive / market comparative analysis. Use project-review for execution/roadmap/implementation health; delegates deep market scans to deep-research. Triggers: strategic review, positioning, go public, go-to-market, market analysis, competitive landscape, value proposition, is there a moat, who are our competitors, platform absorption risk, market positioning, comparable products.",
|
|
267
282
|
"path": "strategic-review/SKILL.md"
|
|
268
283
|
},
|
|
269
284
|
{
|
package/commands/role.md
CHANGED
|
@@ -8,27 +8,61 @@ disable-model-invocation: true
|
|
|
8
8
|
|
|
9
9
|
The user is managing the active swe-workflow skill role. The requested role argument is: `$ARGUMENTS`
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**Validate the argument before running anything — this is the security-critical
|
|
12
|
+
step.** It must be empty or match `^[a-z0-9_-]{1,32}$` (role keys are short
|
|
13
|
+
kebab-case names). If it contains ANYTHING else — a space, quote, `$`, backtick,
|
|
14
|
+
slash, semicolon, or any other character — the argument is invalid: do NOT run any
|
|
15
|
+
Bash command that contains the argument in any form (not in a variable, not as an
|
|
16
|
+
argument, not anywhere). Instead reply that the role name is invalid and list the
|
|
17
|
+
available roles by running only the fixed command `node "@@RESOLVE@@" roles` with
|
|
18
|
+
`ROLES_JSON="@@ROLES@@"` exported — that command does not reference the argument at
|
|
19
|
+
all.
|
|
20
|
+
|
|
21
|
+
If the argument is valid (or empty), run the setup block once, then run the ONE
|
|
22
|
+
branch below that matches, substituting the validated role for `__ROLE__` **only
|
|
23
|
+
where shown** (always inside double quotes as the final argument of a `node`
|
|
24
|
+
call — never assigned to a shell variable). Then report the result concisely (the
|
|
25
|
+
new active role, and that the change hot-reloads so it applies to the next
|
|
26
|
+
prompt):
|
|
12
27
|
|
|
13
28
|
```bash
|
|
14
|
-
|
|
29
|
+
# --- setup (no argument appears here) ---
|
|
15
30
|
RESOLVE="@@RESOLVE@@"; SKILLS="@@SKILLS@@"; SETTINGS="@@SETTINGS@@"
|
|
16
31
|
ROLES="@@ROLES@@"; ACTIVE="@@ACTIVE_ROLE@@"
|
|
17
32
|
export ROLES_JSON="$ROLES"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Empty argument (no role given) — show current + available, no substitution:
|
|
36
|
+
```bash
|
|
37
|
+
echo "Active role: $(cat "$ACTIVE" 2>/dev/null || echo 'baseline (none)')"
|
|
38
|
+
echo "Available roles:"; node "$RESOLVE" roles
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Argument is `all` or `none` — reset to baseline:
|
|
42
|
+
```bash
|
|
43
|
+
node "$RESOLVE" apply "$SETTINGS" "$SKILLS" none && rm -f "$ACTIVE"
|
|
44
|
+
echo "Reset to baseline — only the pinned skills auto-trigger now."
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Any other validated role — apply it. `resolve.mjs` rejects an unknown role with a
|
|
48
|
+
non-zero exit, so the `&&` short-circuits and the marker is only written for a role
|
|
49
|
+
that actually resolved:
|
|
50
|
+
```bash
|
|
51
|
+
if node "$RESOLVE" apply "$SETTINGS" "$SKILLS" "__ROLE__" && printf '%s\n' "__ROLE__" > "$ACTIVE"; then
|
|
52
|
+
echo "Active role set — its skills now auto-trigger."
|
|
27
53
|
else
|
|
28
|
-
echo "Unknown role
|
|
54
|
+
echo "Unknown role. Available roles:"; node "$RESOLVE" roles
|
|
29
55
|
fi
|
|
30
56
|
```
|
|
31
57
|
|
|
32
58
|
Notes:
|
|
33
59
|
- `skillOverrides` and the skill listing hot-reload when `settings.local.json` changes, so the new auto-trigger set takes effect on the next prompt without a restart.
|
|
34
60
|
- This command is for the full (all-skills) CLI install. Hard-subset (`--role`) installs and the per-role marketplace plugins don't need it.
|
|
61
|
+
- Security: `$ARGUMENTS` is never embedded directly (slash-command templates
|
|
62
|
+
interpolate it as text, so a crafted argument would execute in the shell). The
|
|
63
|
+
**primary control is the model-side regex validation above** — do it before
|
|
64
|
+
emitting any Bash. As a deterministic backstop, the validated value reaches the
|
|
65
|
+
shell only as the final quoted argv of a `node "$RESOLVE"` call, where
|
|
66
|
+
`resolve.mjs` (`roleOrDie`) rejects any string that is not a known role before
|
|
67
|
+
it is used — the value is never placed in a bare `ROLE=...` assignment. See
|
|
68
|
+
`SECURITY.md` for the residual (quote-escape) risk and why it is accepted.
|
package/install.mjs
CHANGED
|
@@ -52,6 +52,9 @@ Options:
|
|
|
52
52
|
-p, --prune After installing the selected set, remove previously-installed
|
|
53
53
|
library skills that are NOT in the new selection (never touches
|
|
54
54
|
your own custom skills). Use to narrow a prior all-skills install.
|
|
55
|
+
-f, --force Overwrite a same-named skill directory that this installer did
|
|
56
|
+
not create (by default such a collision is skipped, so your own
|
|
57
|
+
custom skill with a library name is never clobbered).
|
|
55
58
|
-k, --hook (default) Install the SessionStart hook that re-asserts the
|
|
56
59
|
name-only baseline each session + injects the router nudge
|
|
57
60
|
(prints the settings snippet; never edits settings)
|
|
@@ -106,6 +109,7 @@ function toPosix(p) {
|
|
|
106
109
|
let global = false;
|
|
107
110
|
let hook = true;
|
|
108
111
|
let prune = false;
|
|
112
|
+
let force = false;
|
|
109
113
|
let configDir = "";
|
|
110
114
|
let role = "";
|
|
111
115
|
const selected = [];
|
|
@@ -125,6 +129,7 @@ for (let i = 0; i < argv.length; i++) {
|
|
|
125
129
|
if (role === undefined) fatal("--role requires a role name");
|
|
126
130
|
} else if (a.startsWith("--role=")) role = a.slice("--role=".length);
|
|
127
131
|
else if (a === "-p" || a === "--prune") prune = true;
|
|
132
|
+
else if (a === "-f" || a === "--force") force = true;
|
|
128
133
|
else if (a === "-k" || a === "--hook") hook = true;
|
|
129
134
|
else if (a === "--no-hook") hook = false;
|
|
130
135
|
else if (a === "-l" || a === "--list") {
|
|
@@ -161,6 +166,17 @@ if (role) {
|
|
|
161
166
|
}
|
|
162
167
|
}
|
|
163
168
|
|
|
169
|
+
// Positional args must be exact skill names, never paths: a traversal like
|
|
170
|
+
// `install.mjs ../..` would pass the isDir guard below and the clean-copy rmSync
|
|
171
|
+
// would then delete outside the destination. Reject before touching anything.
|
|
172
|
+
if (selected.length > 0) {
|
|
173
|
+
const known = new Set(listSkillDirs());
|
|
174
|
+
const bad = selected.filter((s) => !known.has(s));
|
|
175
|
+
if (bad.length > 0) {
|
|
176
|
+
fatal(`unknown skill(s): ${bad.join(", ")}. Run 'install.mjs --list' to see skills.`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
164
180
|
// ---- resolve destination ---------------------------------------------------
|
|
165
181
|
|
|
166
182
|
let claudeDir;
|
|
@@ -181,9 +197,46 @@ if (skillSet.length === 0) {
|
|
|
181
197
|
skillSet = role ? resolvedSkills(rolesData, role) : listSkillDirs();
|
|
182
198
|
}
|
|
183
199
|
|
|
200
|
+
// ---- provenance manifest ---------------------------------------------------
|
|
201
|
+
// Records which skill directories THIS installer created, so uninstall/--prune
|
|
202
|
+
// only ever remove our own skills and a re-install never clobbers a user's custom
|
|
203
|
+
// skill that happens to share a library name. See docs SECURITY.md (LOW-003).
|
|
204
|
+
const MANIFEST = join(dest, ".swe-workflow-manifest.json");
|
|
205
|
+
|
|
206
|
+
function readManifestSkills() {
|
|
207
|
+
if (existsSync(MANIFEST)) {
|
|
208
|
+
try {
|
|
209
|
+
const m = JSON.parse(readFileSync(MANIFEST, "utf-8"));
|
|
210
|
+
if (Array.isArray(m.skills)) return new Set(m.skills);
|
|
211
|
+
} catch {
|
|
212
|
+
/* unreadable manifest -> treat as absent */
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return null; // null = no manifest present
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const priorManifest = readManifestSkills();
|
|
219
|
+
// A prior swe-workflow install (any version) leaves these machinery markers even
|
|
220
|
+
// before manifests existed. If neither a manifest nor a marker is present, the dest
|
|
221
|
+
// is not one we've installed into, so a same-named dir there must be the user's.
|
|
222
|
+
const priorInstall =
|
|
223
|
+
priorManifest !== null ||
|
|
224
|
+
existsSync(join(dest, ".roles.json")) ||
|
|
225
|
+
existsSync(join(claudeDir, "hooks", "resolve.mjs"));
|
|
226
|
+
|
|
227
|
+
// Do we own the skill dir currently at dest? Manifest is authoritative when present;
|
|
228
|
+
// otherwise fall back to "is this dest a prior swe install at all?" so pre-manifest
|
|
229
|
+
// upgrades still overwrite our own skills rather than skipping them.
|
|
230
|
+
function installerOwns(skill) {
|
|
231
|
+
if (priorManifest !== null) return priorManifest.has(skill);
|
|
232
|
+
return priorInstall;
|
|
233
|
+
}
|
|
234
|
+
|
|
184
235
|
// ---- copy skills -----------------------------------------------------------
|
|
185
236
|
|
|
186
237
|
let errors = 0;
|
|
238
|
+
const installedNow = [];
|
|
239
|
+
const skippedCollisions = [];
|
|
187
240
|
for (const skill of skillSet) {
|
|
188
241
|
const src = join(SKILLS_DIR, skill);
|
|
189
242
|
if (!isDir(src)) {
|
|
@@ -191,24 +244,59 @@ for (const skill of skillSet) {
|
|
|
191
244
|
errors++;
|
|
192
245
|
continue;
|
|
193
246
|
}
|
|
247
|
+
const destPath = join(dest, skill);
|
|
248
|
+
// Never clobber a same-named directory we didn't create unless --force.
|
|
249
|
+
if (isDir(destPath) && !force && !installerOwns(skill)) {
|
|
250
|
+
warn(
|
|
251
|
+
`skipping '${skill}': a skill of that name already exists and was not installed ` +
|
|
252
|
+
`by swe-workflow-skills. Use --force to overwrite it.`,
|
|
253
|
+
);
|
|
254
|
+
skippedCollisions.push(skill);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
194
257
|
// Clean copy: drop any prior version first so files removed upstream don't linger.
|
|
195
|
-
rmSync(
|
|
196
|
-
cpSync(src,
|
|
197
|
-
|
|
258
|
+
rmSync(destPath, { recursive: true, force: true });
|
|
259
|
+
cpSync(src, destPath, { recursive: true });
|
|
260
|
+
installedNow.push(skill);
|
|
261
|
+
log(`Installed: ${skill} -> ${destPath}`);
|
|
198
262
|
}
|
|
199
263
|
|
|
200
264
|
// --prune: narrow a prior install to the current selection. Only ever removes skills
|
|
201
|
-
// that exist in our source tree (so the user's own
|
|
265
|
+
// that exist in our source tree AND that this installer created (so the user's own
|
|
266
|
+
// custom skills — including any that share a library name — are never touched).
|
|
267
|
+
const pruned = new Set();
|
|
202
268
|
if (prune) {
|
|
203
269
|
const keep = new Set(skillSet);
|
|
204
270
|
for (const s of listSkillDirs()) {
|
|
205
|
-
if (!keep.has(s) && isDir(join(dest, s))) {
|
|
271
|
+
if (!keep.has(s) && isDir(join(dest, s)) && installerOwns(s)) {
|
|
206
272
|
rmSync(join(dest, s), { recursive: true, force: true });
|
|
273
|
+
pruned.add(s);
|
|
207
274
|
log(`Pruned: ${s} (not in selection)`);
|
|
208
275
|
}
|
|
209
276
|
}
|
|
210
277
|
}
|
|
211
278
|
|
|
279
|
+
// Rewrite the provenance manifest: every library skill we own that is still present.
|
|
280
|
+
// = (what we owned before) ∪ (installed this run) − (pruned this run), intersected
|
|
281
|
+
// with library skill dirs actually on disk. Skipped collisions never enter it.
|
|
282
|
+
const libNames = new Set(listSkillDirs());
|
|
283
|
+
const ownedSkills = new Set([...(priorManifest || []), ...installedNow]);
|
|
284
|
+
const manifestSkills = [...ownedSkills]
|
|
285
|
+
.filter((s) => !pruned.has(s) && libNames.has(s) && isDir(join(dest, s)))
|
|
286
|
+
.sort();
|
|
287
|
+
if (installedNow.length > 0 || priorManifest !== null || prune) {
|
|
288
|
+
let manifestVersion = "";
|
|
289
|
+
try {
|
|
290
|
+
manifestVersion = readFileSync(join(REPO_ROOT, "VERSION"), "utf-8").trim();
|
|
291
|
+
} catch {
|
|
292
|
+
/* VERSION is optional metadata in the manifest */
|
|
293
|
+
}
|
|
294
|
+
writeFileSync(
|
|
295
|
+
MANIFEST,
|
|
296
|
+
JSON.stringify({ installer: "swe-workflow-skills", version: manifestVersion, skills: manifestSkills }, null, 2) + "\n",
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
212
300
|
// ---- orchestrator machinery (only when skill-router is in the set) ---------
|
|
213
301
|
|
|
214
302
|
const hasRouter = skillSet.includes("skill-router");
|
|
@@ -292,21 +380,39 @@ if (hook) {
|
|
|
292
380
|
}
|
|
293
381
|
}
|
|
294
382
|
|
|
383
|
+
// Per-skill collision warnings scroll away during a full install; restate them once
|
|
384
|
+
// at the end so an unowned same-named skill that was left in place is not missed.
|
|
385
|
+
if (skippedCollisions.length > 0) {
|
|
386
|
+
warn(
|
|
387
|
+
`left ${skippedCollisions.length} existing skill(s) untouched (not installed by ` +
|
|
388
|
+
`swe-workflow-skills): ${skippedCollisions.join(", ")}. Re-run with --force to overwrite.`,
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
|
|
295
392
|
if (errors !== 0) process.exit(1);
|
|
296
393
|
|
|
297
394
|
function copyIfExists(src, destPath) {
|
|
298
395
|
if (existsSync(src)) cpSync(src, destPath);
|
|
299
396
|
}
|
|
300
397
|
|
|
301
|
-
//
|
|
302
|
-
//
|
|
398
|
+
// Double-quote a path for the POSIX shell that runs the hook command, escaping the
|
|
399
|
+
// chars that stay active inside double quotes (\ $ ` "). Without the $/` escapes, a
|
|
400
|
+
// config path containing e.g. `$(cmd)` would run that command substitution at every
|
|
401
|
+
// session start. For \ and " this produces exactly what JSON.stringify used to (so
|
|
402
|
+
// Windows paths render unchanged); cmd.exe keeps the backslash before $/`, but paths
|
|
403
|
+
// with those chars are effectively POSIX-only.
|
|
404
|
+
function shellQuote(p) {
|
|
405
|
+
return '"' + p.replace(/[\\$`"]/g, (c) => "\\" + c) + '"';
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// The SessionStart block to merge into settings.json.
|
|
303
409
|
function hookSnippet(path) {
|
|
304
410
|
const block = {
|
|
305
411
|
hooks: {
|
|
306
412
|
SessionStart: [
|
|
307
413
|
{
|
|
308
414
|
matcher: "startup|resume|clear|compact",
|
|
309
|
-
hooks: [{ type: "command", command: `node ${
|
|
415
|
+
hooks: [{ type: "command", command: `node ${shellQuote(path)}` }],
|
|
310
416
|
},
|
|
311
417
|
],
|
|
312
418
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swe-workflow-skills",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A curated library of
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "A curated library of Claude Code Agent Skills covering the full software lifecycle, with orchestrator-routed activation that scales past the skill-listing budget.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"swe-workflow-skills": "bin/cli.mjs"
|
package/roles.json
CHANGED
|
@@ -127,6 +127,20 @@
|
|
|
127
127
|
"observability-design"
|
|
128
128
|
]
|
|
129
129
|
},
|
|
130
|
+
"data-scientist": {
|
|
131
|
+
"label": "Data Scientist",
|
|
132
|
+
"description": "Skills for exploratory data analysis, statistical rigor, notebook productionization, and the experiment-tracking/data-quality/modeling work around them.",
|
|
133
|
+
"core": "technical",
|
|
134
|
+
"skills": [
|
|
135
|
+
"exploratory-data-analysis",
|
|
136
|
+
"statistical-analysis",
|
|
137
|
+
"notebook-to-production",
|
|
138
|
+
"ml-experiment-tracking",
|
|
139
|
+
"data-quality",
|
|
140
|
+
"data-modeling",
|
|
141
|
+
"ai-evaluation"
|
|
142
|
+
]
|
|
143
|
+
},
|
|
130
144
|
"security": {
|
|
131
145
|
"label": "Security Engineer",
|
|
132
146
|
"description": "Skills for design-time threat modeling, security audits, dependency/CVE management, blast-radius analysis, and incident handling.",
|
package/scripts/resolve.mjs
CHANGED
|
@@ -104,10 +104,15 @@ function sortKeysDeep(value) {
|
|
|
104
104
|
|
|
105
105
|
export function loadSettings(settingsPath) {
|
|
106
106
|
if (existsSync(settingsPath) && statSync(settingsPath).isFile()) {
|
|
107
|
+
const text = readFileSync(settingsPath, "utf-8");
|
|
107
108
|
try {
|
|
108
|
-
return JSON.parse(
|
|
109
|
-
} catch {
|
|
110
|
-
|
|
109
|
+
return JSON.parse(text) || {};
|
|
110
|
+
} catch (e) {
|
|
111
|
+
// A corrupt (e.g. hand-edited) file must NOT read as empty: downstream
|
|
112
|
+
// writers would rebuild it from {} and silently destroy the user's
|
|
113
|
+
// settings. Throw so callers skip the write (the SessionStart hook
|
|
114
|
+
// catches this and leaves the file alone; the CLI surfaces it).
|
|
115
|
+
throw new Error(`unparseable JSON in ${settingsPath} — fix or remove it (${e.message})`);
|
|
111
116
|
}
|
|
112
117
|
}
|
|
113
118
|
return {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ai-evaluation
|
|
3
|
-
description: "Define how to evaluate ML models and GenAI/LLM apps — golden datasets, offline metrics, RAG evaluation (faithfulness,
|
|
3
|
+
description: "Define how to evaluate ML models and GenAI/LLM apps — golden datasets, offline metrics, RAG evaluation (faithfulness, relevance, context precision/recall) with ragas/deepeval/promptfoo, LLM-as-judge design and calibration, eval regression gates in CI, online A/B and human feedback. Logging/comparing runs → ml-experiment-tracking; building the app → llm-app-engineering; general experiment statistics → statistical-analysis."
|
|
4
|
+
when_to_use: "Triggers: evaluate the model, eval my chatbot, RAG evals, ragas, LLM as judge, golden dataset, eval suite, is the new prompt better, hallucination rate, benchmark our AI app."
|
|
4
5
|
model: sonnet
|
|
5
6
|
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
7
|
---
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-reviewing
|
|
3
|
-
description: "Structured code reviews enforcing DRY, KISS, YAGNI, SRP, best practices, and project conventions.
|
|
3
|
+
description: "Structured code reviews enforcing DRY, KISS, YAGNI, SRP, best practices, and project conventions."
|
|
4
|
+
when_to_use: "Triggers: review this code, code review, check my code, what do you think of this implementation, review this PR, is this code good, feedback on my code, review staged changes before commit."
|
|
4
5
|
model: sonnet
|
|
5
6
|
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
7
|
---
|
|
@@ -13,10 +14,19 @@ Perform thorough, constructive code reviews that catch bugs, enforce principles,
|
|
|
13
14
|
|
|
14
15
|
### Step 1: Understand the Context
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Working-tree changes right now (live at skill load; empty when the tree is clean,
|
|
18
|
+
this isn't a git repo, or the review targets something else — e.g. pasted code or
|
|
19
|
+
a PR):
|
|
20
|
+
|
|
21
|
+
!`git diff --stat 2>/dev/null || true`
|
|
22
|
+
|
|
23
|
+
If the summary above is empty or irrelevant to what you were asked to review,
|
|
24
|
+
proceed with the code as provided. Before reviewing line-by-line, understand the
|
|
25
|
+
big picture:
|
|
17
26
|
|
|
18
27
|
- **What is this code supposed to do?** Read the PR description, linked issue, or ask the user.
|
|
19
|
-
- **What changed?** If reviewing a diff, understand the scope of changes
|
|
28
|
+
- **What changed?** If reviewing a diff, understand the scope of changes — run the
|
|
29
|
+
full `git diff` (or `git diff --staged`) when the stat summary isn't enough.
|
|
20
30
|
- **What's the surrounding code like?** Read adjacent files for conventions and patterns.
|
|
21
31
|
|
|
22
32
|
### Step 2: First Pass — Structural Review
|
|
@@ -1,92 +1,49 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: effort-estimation
|
|
3
|
-
description: "Estimate engineering effort with agile techniques — story points, t-shirt sizing, three-point estimation, capacity planning.
|
|
3
|
+
description: "Estimate engineering effort with agile techniques — story points, t-shirt sizing, three-point estimation, capacity planning."
|
|
4
|
+
when_to_use: "Triggers: estimate this, how long will this take, story points, t-shirt sizing, effort estimation, capacity planning, sprint planning, budget estimate, forecast, velocity, when will this be done."
|
|
4
5
|
model: haiku
|
|
5
6
|
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
# Effort Estimation
|
|
9
10
|
|
|
10
|
-
Produce honest, useful estimates
|
|
11
|
-
|
|
12
|
-
## Core Philosophy
|
|
13
|
-
|
|
14
|
-
**Estimates are forecasts, not commitments.** They communicate "based on what we know today, here's our best guess at the range of effort." They should always include uncertainty ranges, and they should improve as you learn more.
|
|
11
|
+
Produce honest, useful estimates without false precision. Estimates are forecasts,
|
|
12
|
+
not commitments — always ranges, always improving as you learn more.
|
|
15
13
|
|
|
16
14
|
## Workflow
|
|
17
15
|
|
|
18
16
|
### Step 1: Ensure Tasks Are Defined
|
|
19
17
|
|
|
20
|
-
You can't estimate undefined work.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Acceptance criteria exist for each task
|
|
24
|
-
- Technical approach is at least sketched (spikes completed for unknowns)
|
|
25
|
-
|
|
26
|
-
If the work is too vague to estimate, say so. "I can't estimate this until we do a spike" is a valid and responsible answer.
|
|
27
|
-
|
|
28
|
-
### Step 2: Choose the Estimation Method
|
|
29
|
-
|
|
30
|
-
| Method | Best For | Precision | Speed |
|
|
31
|
-
|--------|----------|-----------|-------|
|
|
32
|
-
| **T-shirt sizing** | Roadmap planning, early-stage sizing, large backlogs | Low (ranges) | Very fast |
|
|
33
|
-
| **Story points** (Fibonacci) | Sprint planning, velocity tracking, mature teams | Medium (relative) | Moderate |
|
|
34
|
-
| **Three-point estimation** | High-stakes estimates, budget requests, uncertain work | High (ranges with confidence) | Slow |
|
|
35
|
-
| **Time-based** | Well-understood tasks with low uncertainty | High (hours/days) | Moderate |
|
|
36
|
-
|
|
37
|
-
**Default recommendation**: T-shirt sizing for roadmap/quarter planning, story points for sprint planning. Three-point for budget requests and stakeholder communication.
|
|
18
|
+
You can't estimate undefined work. Tasks must be broken down (use `feature-planning`
|
|
19
|
+
if not), have acceptance criteria, and have at least a sketched technical approach.
|
|
20
|
+
"I can't estimate this until we do a spike" is a valid and responsible answer.
|
|
38
21
|
|
|
39
|
-
### Step
|
|
22
|
+
### Step 2: Choose the Method
|
|
40
23
|
|
|
41
|
-
|
|
24
|
+
T-shirt sizing for roadmap and early-stage sizing; story points (Fibonacci) for
|
|
25
|
+
sprint planning and velocity tracking; three-point estimation for budget requests
|
|
26
|
+
and high-uncertainty, high-stakes work; time-based only for well-understood tasks.
|
|
27
|
+
See [references/estimation-methods.md](references/estimation-methods.md) for
|
|
28
|
+
detailed guidance on each method.
|
|
42
29
|
|
|
43
|
-
|
|
30
|
+
### Step 3: Apply It
|
|
44
31
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
5. **Re-estimate when you learn more.** Initial estimates are educated guesses. Update them as spikes complete and requirements clarify.
|
|
32
|
+
Estimate per task, not the project as a single unit; relative to known work rather
|
|
33
|
+
than in absolute terms; as a team where possible (the familiarity gap between
|
|
34
|
+
estimators reveals hidden complexity); with uncertainty explicit. Re-estimate when
|
|
35
|
+
spikes complete or requirements clarify.
|
|
50
36
|
|
|
51
|
-
### Step 4:
|
|
37
|
+
### Step 4: Translate for Stakeholders
|
|
52
38
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
Estimated story points for the project: 85
|
|
58
|
-
Team velocity: ~30 points per sprint (2-week sprints)
|
|
59
|
-
Sprints needed: 85 / 30 = ~3 sprints = 6 weeks
|
|
60
|
-
|
|
61
|
-
Add buffer for unknowns (20-30%): 7-8 weeks
|
|
62
|
-
Communicate as range: "6-8 weeks with the current team"
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**From effort to cost:**
|
|
66
|
-
```
|
|
67
|
-
Effort estimate: 12-16 person-weeks
|
|
68
|
-
Team loaded cost: $X per person-week
|
|
69
|
-
Total: 12 × $X to 16 × $X
|
|
70
|
-
Communicate as range: "$A - $B"
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Always provide ranges, never single numbers.** A single number becomes a commitment; a range communicates confidence.
|
|
39
|
+
Convert to time or cost via team velocity or loaded cost, add a 20-30% buffer for
|
|
40
|
+
unknowns, and communicate a range in stakeholder language — weeks and dollars, not
|
|
41
|
+
story points. A single number becomes a commitment; a range communicates confidence.
|
|
74
42
|
|
|
75
43
|
### Step 5: Track and Calibrate
|
|
76
44
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
- Compare estimated vs actual effort
|
|
80
|
-
- Identify systematic patterns (always overestimate UI? Always underestimate integrations?)
|
|
81
|
-
- Adjust team velocity based on recent data (use the last 3-5 sprints, not all-time average)
|
|
82
|
-
|
|
83
|
-
## Common Estimation Traps
|
|
84
|
-
|
|
85
|
-
- **Anchoring**: The first number said influences everyone else. Use blind estimation (planning poker, simultaneous reveal).
|
|
86
|
-
- **Planning fallacy**: People consistently underestimate. Use historical data to calibrate.
|
|
87
|
-
- **Scope creep blindness**: Estimate the work as defined, then add buffer for scope growth — it always grows.
|
|
88
|
-
- **Hero planning**: Estimating based on the best-case scenario with the best developer with zero interruptions. Estimate for a typical day with meetings and context switches.
|
|
89
|
-
- **Precision theater**: Saying "47 hours" when you mean "roughly a week." False precision erodes trust faster than honest ranges.
|
|
45
|
+
Compare estimated vs actual each sprint, look for systematic bias, and recalibrate
|
|
46
|
+
velocity on the last 3-5 sprints, not the all-time average.
|
|
90
47
|
|
|
91
48
|
## Principles Applied
|
|
92
49
|
|