@ericrisco/rsc 0.1.24 → 0.1.26
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 +65 -2
- package/manifest.json +4 -4
- package/package.json +1 -1
- package/scripts/consult.js +75 -6
- package/scripts/lib/recommend.js +2 -1
- package/skills/building-agents/SKILL.md +2 -0
- package/skills/design/SKILL.md +2 -0
- package/skills/fastapi/SKILL.md +2 -0
- package/skills/flutter/SKILL.md +2 -0
- package/skills/go/SKILL.md +2 -0
- package/skills/nextjs/SKILL.md +2 -0
- package/skills/postgresdb/SKILL.md +2 -0
- package/skills/react/SKILL.md +2 -0
- package/skills/sdd/SKILL.md +1 -1
- package/skills/specify/SKILL.md +1 -1
- package/skills/suggest/SKILL.md +75 -3
- package/skills/suggest/evals/README.md +3 -0
- package/skills/suggest/evals/cases.yaml +27 -0
- package/targets/claude.js +18 -1
- package/targets/userprompt-gate.mjs +34 -0
package/README.md
CHANGED
|
@@ -32,6 +32,30 @@ npx @ericrisco/rsc # plain-language wizard — no jargon, installs wh
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
+
## 🤖 For agents: "install this harness"
|
|
36
|
+
|
|
37
|
+
If you're an AI coding agent (Claude Code, Cursor, Copilot, Codex, Gemini…) and your user
|
|
38
|
+
asked you to **install rsc / this harness / these skills**, run this in the **root of the
|
|
39
|
+
project they're equipping** — not inside a clone of this repo (see the note under *Install*):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npx @ericrisco/rsc@latest
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
That launches a plain-language wizard: it asks **which assistants** to target and **what the
|
|
46
|
+
user wants**, reads the repo, then installs the floor (`orient` + `rsc-suggest` + `harness` +
|
|
47
|
+
`init`) plus only the skills that fit — one at a time. No global install and no API key needed.
|
|
48
|
+
|
|
49
|
+
- **Choose assistants non-interactively:** `npx @ericrisco/rsc@latest --target claude` (comma-separate for several).
|
|
50
|
+
- **Already installed, just refreshing skills + hooks:** `rsc sync` (or re-run the command above).
|
|
51
|
+
- **Add one skill by id:** `rsc add <id>` · **browse the catalog:** `rsc consult "<what you want>"` or `rsc list`.
|
|
52
|
+
|
|
53
|
+
From then on it's self-driving: `rsc-suggest` proposes the next skill as tasks appear, and in
|
|
54
|
+
Claude Code a hook re-asserts the spec-first **new-feature gate** on every turn — so a feature
|
|
55
|
+
request routes through `specify` before any skill writes code.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
35
59
|
## Why this exists
|
|
36
60
|
|
|
37
61
|
Most skill packs dump hundreds of files into your context and call it a day. This
|
|
@@ -75,12 +99,21 @@ git clone https://github.com/ericrisco/rsc-harness.git ~/rsc-skills
|
|
|
75
99
|
cd ~/rsc-skills && npm install && npm link
|
|
76
100
|
```
|
|
77
101
|
|
|
102
|
+
> **Run it inside the project you're equipping — not inside this repo.** The
|
|
103
|
+
> catalog's own `package.json` is named `@ericrisco/rsc`, so `npx @ericrisco/rsc`
|
|
104
|
+
> *from within a `rsc-harness` clone* resolves to the local (unlinked) bin and
|
|
105
|
+
> dies with `sh: rsc: command not found`. Working on the catalog itself? Use
|
|
106
|
+
> `node scripts/rsc.js …`, the `npm link` above, or pin the published build with
|
|
107
|
+
> `npx @ericrisco/rsc@latest …`.
|
|
108
|
+
|
|
78
109
|
The first run asks **which assistants** you want — Claude Code, Codex, Copilot,
|
|
79
110
|
Cursor, Gemini, Windsurf, Cline and 11 more (pick any combination) — and installs
|
|
80
111
|
the **floor**:
|
|
81
112
|
`orient` + `rsc-suggest` (always-on) + `harness` + `init`. In Claude Code it
|
|
82
|
-
also wires a `SessionStart` hook so your assistant proposes new skills on its
|
|
83
|
-
own
|
|
113
|
+
also wires a `SessionStart` hook (so your assistant proposes new skills on its
|
|
114
|
+
own) and a `UserPromptSubmit` hook that re-asserts the **SDD new-feature gate**
|
|
115
|
+
on every turn — so a feature request, in any language, routes through `specify`
|
|
116
|
+
first, before any skill writes code. Opt out per project with `.rsc/.no-feature-gate`.
|
|
84
117
|
|
|
85
118
|
Everything stays **in the project**, and the real skill files are written
|
|
86
119
|
**once** to `.rsc/skills/<id>/`. Each assistant you pick gets a lightweight
|
|
@@ -160,6 +193,36 @@ rsc uninstall postgresdb --dry-run # preview a removal
|
|
|
160
193
|
|
|
161
194
|
---
|
|
162
195
|
|
|
196
|
+
## Update
|
|
197
|
+
|
|
198
|
+
`rsc` is an npm package, so updating is two steps — bump the package, then
|
|
199
|
+
re-sync what's already wired into your project:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npm install -g @ericrisco/rsc@latest # global install: pull the newest catalog
|
|
203
|
+
rsc sync # refresh managed skills + hooks (auto-detects your assistant)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Not sure what a bump touches? Preview the exact commands without writing anything:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
rsc upgrade --dry-run # prints the npm install + rsc sync lines for your target
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Running through `npx` (no global install)? There's nothing to upgrade —
|
|
213
|
+
`npx @ericrisco/rsc@latest` always fetches the latest published catalog; just run
|
|
214
|
+
`rsc sync` afterwards if the project already has skills installed.
|
|
215
|
+
|
|
216
|
+
Every sync snapshots the project first, so a bad update is always reversible:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
rsc backups # list project-local snapshots
|
|
220
|
+
rsc restore latest --dry-run # preview restoring the newest
|
|
221
|
+
rsc restore <snapshot-id> # restore it
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
163
226
|
## How recommendation works
|
|
164
227
|
|
|
165
228
|
Two faces, one catalog (`manifest.json`):
|
package/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.1.
|
|
2
|
+
"version": "0.1.26",
|
|
3
3
|
"counts": {
|
|
4
4
|
"skills": 231
|
|
5
5
|
},
|
|
@@ -3666,7 +3666,7 @@
|
|
|
3666
3666
|
},
|
|
3667
3667
|
{
|
|
3668
3668
|
"id": "sdd",
|
|
3669
|
-
"description": "Use when you want a disciplined, spec-driven path from a feature idea to shipped, verified software — the rsc-sdd dispatcher / front door. It states the SDD method, reads the accompaniment dial from 02-DOCS, and routes to the right phase skill: constitution -> specify -> clarify -> plan -> tasks -> analyze -> implement -> verify -> review -> ship, with debug / worktrees / parallel callable on demand. Use it to START a feature, when unsure which SDD phase you are in, or to govern the whole flow. Triggers: 'spec-driven development', 'sdd', 'build this feature properly', 'start a new feature', 'I have an idea, take it to production', 'which phase am I in', 'run the sdd flow', 'desarrollo dirigido por especificación', 'monta esta feature bien', 'de la idea a producción', 'per-phase model routing', 'use a cheaper model for implementation', 'qué modelo por fase'. NOT itself a single phase (it dispatches), NOT the workspace harness (harness), NOT a stack build skill.",
|
|
3669
|
+
"description": "Use when you want a disciplined, spec-driven path from a feature idea to shipped, verified software — the rsc-sdd dispatcher / front door. It states the SDD method, reads the accompaniment dial from 02-DOCS, and routes to the right phase skill: constitution -> specify -> clarify -> plan -> tasks -> analyze -> implement -> verify -> review -> ship, with debug / worktrees / parallel callable on demand. Use it to START a feature, when unsure which SDD phase you are in, or to govern the whole flow. Triggers: 'spec-driven development', 'sdd', 'build this feature properly', 'start a new feature', 'I have an idea, take it to production', 'which phase am I in', 'run the sdd flow', 'desarrollo dirigido por especificación', 'monta esta feature bien', 'munta aquesta feature bé', 'de la idea a producción', 'de la idea a producció', 'fem un SDD per X', 'quina fase soc', 'per-phase model routing', 'use a cheaper model for implementation', 'qué modelo por fase'. NOT itself a single phase (it dispatches), NOT the workspace harness (harness), NOT a stack build skill.",
|
|
3670
3670
|
"tags": [
|
|
3671
3671
|
"sdd",
|
|
3672
3672
|
"spec",
|
|
@@ -3971,7 +3971,7 @@
|
|
|
3971
3971
|
},
|
|
3972
3972
|
{
|
|
3973
3973
|
"id": "specify",
|
|
3974
|
-
"description": "Use when a feature, change, or product idea is still fuzzy and needs brainstorming into an APPROVED spec BEFORE any planning or code — the brainstorming front door of SDD. Turns a one-line intent into a WHAT/WHY spec (problem, goals, users, scope, behaviour, acceptance) with zero implementation detail, via one-question-at-a-time dialogue, 2-3 proposed approaches with a recommendation, and a design the user approves before anything gets built. Triggers: 'write a spec for…', 'spec this out', 'brainstorm this feature', 'especifica esta feature', 'I want to add X', 'tengo una idea', 'se me ha ocurrido', '¿y si…?', 'wouldn't it be nice if…', 'let's think this through', 'what should this feature do', 'draft a PRD', or any moment someone jumps to HOW before WHAT is agreed. NOT the technical plan (that's `plan`), NOT the de-risking ambiguity sweep (that's `clarify`), NOT project-wide principles (that's `constitution`).",
|
|
3974
|
+
"description": "Use when a feature, change, or product idea is still fuzzy and needs brainstorming into an APPROVED spec BEFORE any planning or code — the brainstorming front door of SDD. Turns a one-line intent into a WHAT/WHY spec (problem, goals, users, scope, behaviour, acceptance) with zero implementation detail, via one-question-at-a-time dialogue, 2-3 proposed approaches with a recommendation, and a design the user approves before anything gets built. Triggers: 'write a spec for…', 'spec this out', 'brainstorm this feature', 'especifica esta feature', 'm'agradaria afegir/posar X', 'voldria…', 'vull afegir/fer X', 'es podria afegir…', 'estaria bé que…', 'i si…?', 'I want to add X', 'tengo una idea', 'se me ha ocurrido', '¿y si…?', 'wouldn't it be nice if…', 'let's think this through', 'what should this feature do', 'draft a PRD', or any moment someone jumps to HOW before WHAT is agreed. NOT the technical plan (that's `plan`), NOT the de-risking ambiguity sweep (that's `clarify`), NOT project-wide principles (that's `constitution`).",
|
|
3975
3975
|
"tags": [
|
|
3976
3976
|
"sdd",
|
|
3977
3977
|
"spec",
|
|
@@ -4112,7 +4112,7 @@
|
|
|
4112
4112
|
},
|
|
4113
4113
|
{
|
|
4114
4114
|
"id": "suggest",
|
|
4115
|
-
"description": "Always-on. Use whenever the current
|
|
4115
|
+
"description": "Always-on. Use whenever the current user turn would clearly benefit from an rsc skill that is not yet installed — detect the gap during normal agent use, name the skill, and (with a one-word confirm) install it via `npx @ericrisco/rsc add <id>`. Triggers on capability intent in any language: building technology, creating content/assets, automating workflows, analyzing data, connecting tools, shipping/deploying, security, business ops, marketing, education, research, or company/documentation harness work.",
|
|
4116
4116
|
"tags": [
|
|
4117
4117
|
"suggest",
|
|
4118
4118
|
"detect",
|
package/package.json
CHANGED
package/scripts/consult.js
CHANGED
|
@@ -1,22 +1,37 @@
|
|
|
1
1
|
import initSqlJs from 'sql.js';
|
|
2
2
|
|
|
3
|
-
// Stopwords (es + en) — these match everywhere via LIKE and drown the signal.
|
|
3
|
+
// Stopwords (es + en + common EU words) — these match everywhere via LIKE and drown the signal.
|
|
4
4
|
const STOP = new Set([
|
|
5
5
|
'una', 'un', 'unos', 'unas', 'con', 'de', 'del', 'la', 'el', 'los', 'las', 'para',
|
|
6
6
|
'que', 'porque', 'en', 'mi', 'mis', 'me', 'quiero', 'tener', 'hacer', 'al', 'lo',
|
|
7
7
|
'su', 'sus', 'este', 'esta', 'esto', 'como', 'mas', 'más', 'algo', 'cosa', 'cosas',
|
|
8
|
+
'vull', 'vols', 'amb', 'segons', 'usuari', 'usuaris', 'aquesta', 'aquest',
|
|
9
|
+
'aixo', 'això', 'per', 'els', 'les', 'dels', 'segun', 'según', 'usuario',
|
|
10
|
+
'usuarios', 'tarea', 'tareas',
|
|
8
11
|
'the', 'and', 'or', 'to', 'of', 'in', 'for', 'with', 'my', 'want', 'build', 'it',
|
|
9
12
|
'need', 'have', 'make', 'create', 'add', 'new',
|
|
13
|
+
'le', 'des', 'du', 'pour', 'cette', 'cet', 'ce', 'mon', 'ma', 'mes',
|
|
14
|
+
'il', 'gli', 'questo', 'questa', 'mio', 'mia',
|
|
15
|
+
'o', 'a', 'os', 'as', 'essa', 'esse', 'minha', 'meu',
|
|
16
|
+
'der', 'die', 'das', 'den', 'dem', 'des', 'fur', 'fuer', 'für', 'diese', 'dieser',
|
|
17
|
+
'dit', 'deze', 'het', 'een', 'voor', 'mijn',
|
|
10
18
|
]);
|
|
11
19
|
|
|
12
20
|
// Spanish / colloquial terms → catalog tags. Lets non-programmers describe
|
|
13
21
|
// outcomes in their words and still hit the right (English-tagged) skill.
|
|
14
22
|
const SYNONYMS = {
|
|
15
|
-
web: ['web', 'frontend'], pagina: ['web'], 'página': ['web'
|
|
23
|
+
web: ['web', 'frontend', 'nextjs'], pagina: ['web', 'nextjs'], 'página': ['web', 'nextjs'],
|
|
24
|
+
website: ['web', 'nextjs'], site: ['web', 'nextjs'], landing: ['landing', 'web', 'nextjs'],
|
|
16
25
|
tienda: ['web', 'frontend'], ecommerce: ['web'], pagos: ['security', 'auth'], pago: ['security'],
|
|
17
26
|
datos: ['database', 'sql'], base: ['database'], guardar: ['database'], almacenar: ['database'],
|
|
18
27
|
publicar: ['deploy', 'docker'], publicarla: ['deploy'], publicarlo: ['deploy'], online: ['deploy'],
|
|
19
28
|
desplegar: ['deploy'], deploy: ['deploy'], servidor: ['backend', 'deploy'],
|
|
29
|
+
montar: ['bootstrap', 'start', 'setup', 'new'], monta: ['bootstrap', 'start', 'setup', 'new'],
|
|
30
|
+
montando: ['bootstrap', 'start', 'setup', 'new'], arrancar: ['bootstrap', 'start', 'setup', 'new'],
|
|
31
|
+
arranca: ['bootstrap', 'start', 'setup', 'new'], empezar: ['bootstrap', 'start', 'setup', 'new'],
|
|
32
|
+
empieza: ['bootstrap', 'start', 'setup', 'new'], iniciar: ['bootstrap', 'start', 'setup', 'new'],
|
|
33
|
+
inicia: ['bootstrap', 'start', 'setup', 'new'], start: ['bootstrap', 'start', 'setup', 'new'],
|
|
34
|
+
bootstrap: ['bootstrap', 'start', 'setup', 'new'], setup: ['bootstrap', 'start', 'setup', 'new'],
|
|
20
35
|
empresa: ['company', 'harness'], negocio: ['company', 'harness'], documentar: ['docs', 'wiki', 'harness'],
|
|
21
36
|
documenta: ['docs', 'harness'], documentacion: ['docs', 'harness'], 'documentación': ['docs', 'harness'],
|
|
22
37
|
conectar: ['connect', 'harness'], conecta: ['connect', 'harness'], herramientas: ['tools', 'harness'],
|
|
@@ -30,14 +45,67 @@ const SYNONYMS = {
|
|
|
30
45
|
marketing: ['marketing'], copy: ['copywriting'], texto: ['copywriting'], textos: ['copywriting'],
|
|
31
46
|
};
|
|
32
47
|
|
|
48
|
+
const SKILL_ROUTING_TERMS = ['suggest', 'detect', 'install', 'meta'];
|
|
49
|
+
|
|
50
|
+
const SKILL_NOUNS = new Set([
|
|
51
|
+
'skill', 'skills', 'habilidad', 'habilidades', 'habilitat', 'habilitats',
|
|
52
|
+
'competencia', 'competencias', 'competence', 'competences', 'competenza',
|
|
53
|
+
'competenze', 'habilidade', 'habilidades', 'fertigkeit', 'fertigkeiten',
|
|
54
|
+
'vaardigheid', 'vaardigheden',
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
const SKILL_ROUTING_VERBS = new Set([
|
|
58
|
+
'recommend', 'recommended', 'recommending', 'recommendation', 'recommendations',
|
|
59
|
+
'suggest', 'suggests', 'suggesting', 'advise', 'choose', 'select', 'find',
|
|
60
|
+
'detect', 'detects', 'detecting', 'route', 'routing', 'match', 'matching',
|
|
61
|
+
'install', 'installs', 'installing', 'add', 'use',
|
|
62
|
+
'recomendar', 'recomienda', 'recomiendas', 'recomiendame', 'recomendacion',
|
|
63
|
+
'recomendaciones', 'sugerir', 'sugiere', 'aconseja', 'elegir', 'elige',
|
|
64
|
+
'detectar', 'detecta', 'instalar', 'instala', 'usar',
|
|
65
|
+
'recomanar', 'recomana', 'recomanes', 'recomanen', 'recomanacio',
|
|
66
|
+
'recomanacions', 'suggerir', 'tria', 'trobar', 'detecti', 'installar',
|
|
67
|
+
'instal', 'afegir',
|
|
68
|
+
'recommande', 'recommander', 'recommandation', 'conseiller', 'choisir',
|
|
69
|
+
'trouver', 'detecter', 'installer', 'ajouter', 'utiliser',
|
|
70
|
+
'consiglia', 'consigliare', 'raccomanda', 'scegliere', 'trovare', 'rilevare',
|
|
71
|
+
'installare', 'aggiungi', 'usare',
|
|
72
|
+
'recomenda', 'recomendacao', 'recomendacoes', 'sugerir', 'escolher',
|
|
73
|
+
'encontrar', 'detectar', 'instalar', 'adicionar', 'usar',
|
|
74
|
+
'empfiehl', 'empfehlen', 'empfehlung', 'waehlen', 'wahlen', 'finden',
|
|
75
|
+
'erkennen', 'installiere', 'installieren', 'verwenden',
|
|
76
|
+
'aanbevelen', 'aanbeveling', 'kiezen', 'vinden', 'detecteren',
|
|
77
|
+
'installeer', 'installeren', 'gebruiken',
|
|
78
|
+
]);
|
|
79
|
+
|
|
80
|
+
const MIN_USEFUL_SCORE = 2;
|
|
81
|
+
const LOW_SIGNAL_TAG_TERMS = new Set(['web', 'frontend']);
|
|
82
|
+
|
|
83
|
+
function fold(term) {
|
|
84
|
+
return term.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
|
|
85
|
+
}
|
|
86
|
+
|
|
33
87
|
function expandedTerms(query) {
|
|
34
88
|
const raw = query.toLowerCase().replace(/[^\p{L}\p{N}\s]/gu, ' ').split(/\s+/)
|
|
35
|
-
.filter((t) => t.length > 1
|
|
36
|
-
const
|
|
89
|
+
.filter((t) => t.length > 1);
|
|
90
|
+
const tokens = [];
|
|
37
91
|
for (const t of raw) {
|
|
92
|
+
tokens.push(t);
|
|
93
|
+
const folded = fold(t);
|
|
94
|
+
if (folded !== t) tokens.push(folded);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const set = new Set();
|
|
98
|
+
const hasSkillNoun = tokens.some((t) => SKILL_NOUNS.has(t));
|
|
99
|
+
const hasSkillRoutingVerb = tokens.some((t) => SKILL_ROUTING_VERBS.has(t));
|
|
100
|
+
|
|
101
|
+
for (const t of tokens) {
|
|
102
|
+
if (STOP.has(t)) continue;
|
|
38
103
|
set.add(t);
|
|
39
104
|
for (const syn of SYNONYMS[t] || []) set.add(syn);
|
|
40
105
|
}
|
|
106
|
+
if (hasSkillNoun && hasSkillRoutingVerb) {
|
|
107
|
+
for (const term of SKILL_ROUTING_TERMS) set.add(term);
|
|
108
|
+
}
|
|
41
109
|
return [...set];
|
|
42
110
|
}
|
|
43
111
|
|
|
@@ -45,6 +113,7 @@ export async function rank(manifest, query) {
|
|
|
45
113
|
const terms = expandedTerms(query);
|
|
46
114
|
if (!terms.length) return [];
|
|
47
115
|
const scored = scoreRows(manifest.skills, terms);
|
|
116
|
+
if (!scored.length || Math.max(...scored.map((r) => r.score)) < MIN_USEFUL_SCORE) return [];
|
|
48
117
|
const SQL = await initSqlJs();
|
|
49
118
|
const db = new SQL.Database();
|
|
50
119
|
|
|
@@ -93,8 +162,8 @@ function scoreRows(skills, terms) {
|
|
|
93
162
|
let score = 0;
|
|
94
163
|
for (const term of terms) {
|
|
95
164
|
if (id === term) score += 20;
|
|
96
|
-
else if (id.includes(term)) score += 8;
|
|
97
|
-
if (tags.includes(term)) score += 10;
|
|
165
|
+
else if (!LOW_SIGNAL_TAG_TERMS.has(term) && id.includes(term)) score += 8;
|
|
166
|
+
if (tags.includes(term)) score += LOW_SIGNAL_TAG_TERMS.has(term) ? 3 : 10;
|
|
98
167
|
if (description.includes(` ${term} `)) score += 1;
|
|
99
168
|
}
|
|
100
169
|
return { id: skill.id, score };
|
package/scripts/lib/recommend.js
CHANGED
|
@@ -23,8 +23,9 @@ export function hasOutcome(id) {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
export function expandRecommends(manifest, chosen) {
|
|
26
|
-
const set = new Set(
|
|
26
|
+
const set = new Set();
|
|
27
27
|
for (const id of chosen) {
|
|
28
|
+
set.add(id);
|
|
28
29
|
const s = skillById(manifest, id);
|
|
29
30
|
for (const r of s?.recommends || []) set.add(r);
|
|
30
31
|
}
|
|
@@ -18,6 +18,8 @@ Build production LLM agents that are model-agnostic by construction — a thin p
|
|
|
18
18
|
|
|
19
19
|
## When to use / When NOT to use
|
|
20
20
|
|
|
21
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
22
|
+
|
|
21
23
|
**Use when:** starting any production-bound LLM feature; code is hardwired to one SDK and you want to swap/route/fallback models; adding tools/function calling, structured output, or streaming; standing up RAG over Postgres/`pgvector` or an external store; building an eval harness / CI quality gate; adding tracing, cost tracking, caching, or routing/cascades; building or hardening an MCP server.
|
|
22
24
|
|
|
23
25
|
**Do NOT use when:**
|
package/skills/design/SKILL.md
CHANGED
|
@@ -12,6 +12,8 @@ origin: risco
|
|
|
12
12
|
|
|
13
13
|
## When to use / When NOT to use
|
|
14
14
|
|
|
15
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
16
|
+
|
|
15
17
|
Use when:
|
|
16
18
|
|
|
17
19
|
- Building a new landing or marketing page.
|
package/skills/fastapi/SKILL.md
CHANGED
|
@@ -22,6 +22,8 @@ pip-audit 2.7+, PostgreSQL 16. (All lower bounds; install the latest in each lin
|
|
|
22
22
|
|
|
23
23
|
## When to use
|
|
24
24
|
|
|
25
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
26
|
+
|
|
25
27
|
- Writing or reviewing any FastAPI route, router, dependency, schema, or app factory.
|
|
26
28
|
- Designing async DB access (SQLAlchemy 2.0), migrations (Alembic), or eager-loading.
|
|
27
29
|
- Adding auth (OAuth2 password flow + JWT), RBAC, password hashing.
|
package/skills/flutter/SKILL.md
CHANGED
|
@@ -22,6 +22,8 @@ subproject — never the FastAPI/Go/Next.js siblings.
|
|
|
22
22
|
|
|
23
23
|
## When to use / When NOT to use
|
|
24
24
|
|
|
25
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
26
|
+
|
|
25
27
|
**Use when:**
|
|
26
28
|
|
|
27
29
|
- Building a new Flutter feature or screen, or choosing/refactoring state management.
|
package/skills/go/SKILL.md
CHANGED
|
@@ -16,6 +16,8 @@ logging, and fixed loop-variable semantics (no more `tt := tt`).
|
|
|
16
16
|
|
|
17
17
|
## When to use / When NOT to use
|
|
18
18
|
|
|
19
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
20
|
+
|
|
19
21
|
**Use when:**
|
|
20
22
|
|
|
21
23
|
- Authoring, reviewing, or testing any `.go` file.
|
package/skills/nextjs/SKILL.md
CHANGED
|
@@ -13,6 +13,8 @@ origin: risco
|
|
|
13
13
|
|
|
14
14
|
## When to use / When NOT to use
|
|
15
15
|
|
|
16
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
17
|
+
|
|
16
18
|
**Use when:**
|
|
17
19
|
|
|
18
20
|
- Editing or creating files under `app/` (pages, layouts, `route.ts`, server actions).
|
|
@@ -14,6 +14,8 @@ example is runnable.
|
|
|
14
14
|
|
|
15
15
|
## When to use / When NOT to use
|
|
16
16
|
|
|
17
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
18
|
+
|
|
17
19
|
**When to use:**
|
|
18
20
|
|
|
19
21
|
- Schema/DDL decisions: types, keys, constraints, generated/identity columns, enum-vs-lookup, jsonb-vs-column.
|
package/skills/react/SKILL.md
CHANGED
|
@@ -12,6 +12,8 @@ origin: risco
|
|
|
12
12
|
|
|
13
13
|
## When to use
|
|
14
14
|
|
|
15
|
+
> **⚠️ SDD new-feature gate — read this first.** If this skill fired on a **new, non-trivial feature or behaviour change** and there is **no approved spec + plan** under `02-DOCS/wiki/sdd/`, STOP — do **not** write feature code yet. Hand off to `../specify/SKILL.md` first: it runs brainstorm → spec → plan → tasks before any code, then routes back here once the plan is approved. Build here directly only for a genuinely one-line / low-risk change. Method: `../sdd/SKILL.md`.
|
|
16
|
+
|
|
15
17
|
- A repo with `vite.config.{ts,js}` + `react` + `react-dom` and **no** `next` and **no** `@react-router/dev` framework mode — i.e. an SPA.
|
|
16
18
|
- Creating components and deciding **where state lives** (local / lifted / URL / context / store).
|
|
17
19
|
- Wiring **server data**: queries, mutations, caching, optimistic UI.
|
package/skills/sdd/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sdd
|
|
3
|
-
description: "Use when you want a disciplined, spec-driven path from a feature idea to shipped, verified software — the rsc-sdd dispatcher / front door. It states the SDD method, reads the accompaniment dial from 02-DOCS, and routes to the right phase skill: constitution -> specify -> clarify -> plan -> tasks -> analyze -> implement -> verify -> review -> ship, with debug / worktrees / parallel callable on demand. Use it to START a feature, when unsure which SDD phase you are in, or to govern the whole flow. Triggers: 'spec-driven development', 'sdd', 'build this feature properly', 'start a new feature', 'I have an idea, take it to production', 'which phase am I in', 'run the sdd flow', 'desarrollo dirigido por especificación', 'monta esta feature bien', 'de la idea a producción', 'per-phase model routing', 'use a cheaper model for implementation', 'qué modelo por fase'. NOT itself a single phase (it dispatches), NOT the workspace harness (harness), NOT a stack build skill."
|
|
3
|
+
description: "Use when you want a disciplined, spec-driven path from a feature idea to shipped, verified software — the rsc-sdd dispatcher / front door. It states the SDD method, reads the accompaniment dial from 02-DOCS, and routes to the right phase skill: constitution -> specify -> clarify -> plan -> tasks -> analyze -> implement -> verify -> review -> ship, with debug / worktrees / parallel callable on demand. Use it to START a feature, when unsure which SDD phase you are in, or to govern the whole flow. Triggers: 'spec-driven development', 'sdd', 'build this feature properly', 'start a new feature', 'I have an idea, take it to production', 'which phase am I in', 'run the sdd flow', 'desarrollo dirigido por especificación', 'monta esta feature bien', 'munta aquesta feature bé', 'de la idea a producción', 'de la idea a producció', 'fem un SDD per X', 'quina fase soc', 'per-phase model routing', 'use a cheaper model for implementation', 'qué modelo por fase'. NOT itself a single phase (it dispatches), NOT the workspace harness (harness), NOT a stack build skill."
|
|
4
4
|
tags: [sdd, spec, workflow, plan]
|
|
5
5
|
recommends: [sdd-init, constitution, specify]
|
|
6
6
|
profiles: [core, full]
|
package/skills/specify/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: specify
|
|
3
|
-
description: "Use when a feature, change, or product idea is still fuzzy and needs brainstorming into an APPROVED spec BEFORE any planning or code — the brainstorming front door of SDD. Turns a one-line intent into a WHAT/WHY spec (problem, goals, users, scope, behaviour, acceptance) with zero implementation detail, via one-question-at-a-time dialogue, 2-3 proposed approaches with a recommendation, and a design the user approves before anything gets built. Triggers: 'write a spec for…', 'spec this out', 'brainstorm this feature', 'especifica esta feature', 'I want to add X', 'tengo una idea', 'se me ha ocurrido', '¿y si…?', 'wouldn't it be nice if…', 'let's think this through', 'what should this feature do', 'draft a PRD', or any moment someone jumps to HOW before WHAT is agreed. NOT the technical plan (that's `plan`), NOT the de-risking ambiguity sweep (that's `clarify`), NOT project-wide principles (that's `constitution`)."
|
|
3
|
+
description: "Use when a feature, change, or product idea is still fuzzy and needs brainstorming into an APPROVED spec BEFORE any planning or code — the brainstorming front door of SDD. Turns a one-line intent into a WHAT/WHY spec (problem, goals, users, scope, behaviour, acceptance) with zero implementation detail, via one-question-at-a-time dialogue, 2-3 proposed approaches with a recommendation, and a design the user approves before anything gets built. Triggers: 'write a spec for…', 'spec this out', 'brainstorm this feature', 'especifica esta feature', 'm'agradaria afegir/posar X', 'voldria…', 'vull afegir/fer X', 'es podria afegir…', 'estaria bé que…', 'i si…?', 'I want to add X', 'tengo una idea', 'se me ha ocurrido', '¿y si…?', 'wouldn't it be nice if…', 'let's think this through', 'what should this feature do', 'draft a PRD', or any moment someone jumps to HOW before WHAT is agreed. NOT the technical plan (that's `plan`), NOT the de-risking ambiguity sweep (that's `clarify`), NOT project-wide principles (that's `constitution`)."
|
|
4
4
|
tags: [sdd, spec, requirements]
|
|
5
5
|
recommends: [clarify, plan]
|
|
6
6
|
profiles: [core, full]
|
package/skills/suggest/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: suggest
|
|
3
|
-
description: "Always-on. Use whenever the current
|
|
3
|
+
description: "Always-on. Use whenever the current user turn would clearly benefit from an rsc skill that is not yet installed — detect the gap during normal agent use, name the skill, and (with a one-word confirm) install it via `npx @ericrisco/rsc add <id>`. Triggers on capability intent in any language: building technology, creating content/assets, automating workflows, analyzing data, connecting tools, shipping/deploying, security, business ops, marketing, education, research, or company/documentation harness work."
|
|
4
4
|
tags: [suggest, detect, install, meta, always-on]
|
|
5
5
|
recommends: []
|
|
6
6
|
profiles: [minimal, core, full]
|
|
@@ -8,7 +8,44 @@ profiles: [minimal, core, full]
|
|
|
8
8
|
|
|
9
9
|
# rsc-suggest — detect & install the skill the task needs
|
|
10
10
|
|
|
11
|
-
You are always loaded
|
|
11
|
+
You are always loaded — your body is injected into context at the start of **every** session, and again after every compaction, so you are the one piece guaranteed to be present *before any other skill is matched*. That makes you the **always-on layer**. You do two jobs, in this order:
|
|
12
|
+
|
|
13
|
+
1. **Route new-feature intent into SDD before any code is written** — the new-feature gate below. This is your first duty; it runs before everything else.
|
|
14
|
+
2. **Keep the session equipped** — detect when the task needs an rsc skill that is **not installed**, name it, and install it on confirm.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## The new-feature gate (always-on — runs before any other skill)
|
|
19
|
+
|
|
20
|
+
This is the **highest-precedence rule in the session.** It fires on **every** user turn, in **any language**, and runs **before you plan, answer, or invoke ANY other skill — no matter how many skills are installed or how strongly one of them matches the request.** That covers the stack skills (`nextjs`, `react`, `fastapi`, `flutter`, `go`, `postgresdb`, `building-agents`, `design`) **and any other skill that would build, create, scaffold, generate, or produce the feature** (e.g. `chatbot`, `course-builder`, `marketing`, automation/connector skills). A skill matching the request does **not** override this gate — it runs *inside* the SDD chain, after the plan is approved. There is no skill with priority over this check.
|
|
21
|
+
|
|
22
|
+
**The rule (non-negotiable).** The moment the user wants to **build, add, or change a feature**, you MUST route it into SDD via `specify` **first**. **No feature code is written — by ANY skill — until a spec AND a plan exist and the user has approved them.** A stack skill that matched the same request does **not** get to skip this: it builds only *after* the plan is approved.
|
|
23
|
+
|
|
24
|
+
**Where does this turn go? When unsure, choose `specify` — the safe default.**
|
|
25
|
+
|
|
26
|
+
| The turn is… | Route to |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| A new feature / capability / integration / UI, a behaviour change, a data-model or architecture change, "it should also…", anything non-trivial | **`specify`** → `clarify` → `plan` → `tasks` → `implement` (which fans work out to subagents via `parallel`) |
|
|
29
|
+
| A genuinely one-line / low-risk change: typo, copy tweak, config bump, rename, non-breaking dependency bump | Just do it inline, then verify — and **say out loud** you are skipping the chain |
|
|
30
|
+
| A bug fix that restores intended behaviour | **`debug`**, then resume |
|
|
31
|
+
| Ambiguous / in-between / you cannot tell | **`specify`** — a skipped spec is where drift hides |
|
|
32
|
+
|
|
33
|
+
**Triggers — detect the *intent*, never a fixed phrase, in ANY language.** What fires the gate is the **meaning**, not the words: the user wants something to exist or behave differently than it does now — build, add, create, change, replace, integrate, "it should also…", "wouldn't it be nice if…". This is judged **semantically**, so it holds in **any language** — Catalan, Spanish, English, Portuguese, French, Italian, German, Basque, Galician, or anything else, including a language with no example below. The lists that follow are **illustrative examples, NOT a checklist**: never wait for one of these phrases to appear before firing. If the meaning is feature-shaped, the gate fires — full stop.
|
|
34
|
+
- **CA:** "m'agradaria afegir/posar…", "vull fer/posar…", "es podria…", "i si…".
|
|
35
|
+
- **ES:** "quiero añadir/montar…", "me gustaría…", "se me ha ocurrido", "¿y si…?".
|
|
36
|
+
- **EN:** "I want to add…", "let's build…", "it should also…".
|
|
37
|
+
- A **URL plus a description of desired behaviour** ("on this page I'd like…") **is** a feature request — in any language.
|
|
38
|
+
|
|
39
|
+
**Stop rationalizing — every one of these is wrong:**
|
|
40
|
+
- *"I understand the feature, I'll just build it."* → That is the exact failure SDD prevents. Spec first; the artifact is the contract.
|
|
41
|
+
- *"A more specific skill matched (a stack skill, `chatbot`, `course-builder`, marketing…), so it takes precedence."* → **No skill outranks this gate.** Any builder skill **defers** to `specify` for new features and runs *inside* the chain, after the plan is approved. Route first.
|
|
42
|
+
- *"The user gave lots of detail / a URL, so they want code now."* → Detail feeds the spec, not the editor.
|
|
43
|
+
- *"The dial is L0, so I'll skip the gate to stay terse."* → L0 changes how many words and questions, **never** whether the gate fires.
|
|
44
|
+
- *"It's phrased in a language I have no example for, so maybe it isn't a feature request."* → The trigger lists are examples, not a closed set. Judge the **meaning**, not the keywords; any language with build/add/change intent fires the gate identically.
|
|
45
|
+
|
|
46
|
+
If `specify` / `sdd` are **not installed**, fall through to the install detector below and offer to add them *before* routing. The gate decides **where the turn goes**; the detector below only handles **missing** skills. Full method and phase map: `../sdd/SKILL.md`.
|
|
47
|
+
|
|
48
|
+
---
|
|
12
49
|
|
|
13
50
|
When the current task would clearly benefit from an rsc skill that is **not installed**:
|
|
14
51
|
|
|
@@ -24,6 +61,42 @@ Rules:
|
|
|
24
61
|
- Never recommend something already installed (`npx @ericrisco/rsc list`).
|
|
25
62
|
- One suggestion at a time. Don't interrupt the flow for nice-to-haves.
|
|
26
63
|
|
|
64
|
+
## Mid-task capability intent detector
|
|
65
|
+
|
|
66
|
+
This runs **inside the agent conversation**, not only in the `rsc` CLI. At the start of
|
|
67
|
+
each user turn, before planning, coding, writing, researching, or answering in depth,
|
|
68
|
+
check whether the user is asking to create, build, fix, connect, automate, analyze,
|
|
69
|
+
publish, sell, teach, govern, secure, deploy, or document something that maps to a
|
|
70
|
+
known rsc capability.
|
|
71
|
+
|
|
72
|
+
This is broader than "start a project". It includes mid-conversation requests such as:
|
|
73
|
+
|
|
74
|
+
- Technology: "quiero montar una pagina web", "necesito una API", "build me a mobile app", "conecta Stripe", "automatiza este flujo", "deploy this", "review security".
|
|
75
|
+
- Creation: "haz una landing que convierta", "write a cold email sequence", "crea un pitch deck", "monta un curso", "edita shorts", "make social posts".
|
|
76
|
+
- Data and AI: "analiza estos datos", "build a dashboard", "quiero un agente de IA", "haz RAG sobre mis documentos", "extrae datos de PDFs".
|
|
77
|
+
- Business and ops: "organiza mi empresa", "prepara facturas", "monta CRM/pipeline", "haz contratos", "reduce churn", "gestiona soporte".
|
|
78
|
+
- Knowledge and research: "documenta cómo funciona esto", "crea una wiki", "procesa este inbox", "research competitors", "turn this into SOPs".
|
|
79
|
+
- Other languages: any equivalent phrasing. Match the user's intent, not exact words.
|
|
80
|
+
|
|
81
|
+
When a capability intent appears:
|
|
82
|
+
|
|
83
|
+
1. Run `npx @ericrisco/rsc list` to know what is already installed.
|
|
84
|
+
2. Run `npx @ericrisco/rsc consult "<the user's exact intent>"`.
|
|
85
|
+
3. Read the ordered result as the install queue, but pick only the **first missing**
|
|
86
|
+
skill that is useful right now. Skip `suggest` and any installed skill.
|
|
87
|
+
4. Ask before installing: "Para esto instalaría `<id>`, que aún no tienes. ¿La instalo? (sí/no)".
|
|
88
|
+
5. On yes, run `npx @ericrisco/rsc add <id>` and then continue the original request.
|
|
89
|
+
|
|
90
|
+
Example: if the user says "quiero montar una pagina web para vender cursos online",
|
|
91
|
+
do not just start building. Check the installed list, consult that exact phrase, and
|
|
92
|
+
recommend the first missing skill from the returned queue. In a base install, `init`
|
|
93
|
+
and `harness` may already exist, so the first missing skill is usually `nextjs`. In a
|
|
94
|
+
bare install, `init` may be first. Install one skill at a time.
|
|
95
|
+
|
|
96
|
+
Example: if the user says "hazme una secuencia de cold emails para vender mi SaaS",
|
|
97
|
+
consult that exact phrase and recommend the first missing email/marketing skill rather
|
|
98
|
+
than writing generic copy with no specialist loaded.
|
|
99
|
+
|
|
27
100
|
## Onboarding gate (first contact)
|
|
28
101
|
|
|
29
102
|
Before handling the first request of the session, check the workspace state:
|
|
@@ -37,4 +110,3 @@ This is the universal layer every assistant reads. On Claude Code a SessionStart
|
|
|
37
110
|
## Orientación (siempre)
|
|
38
111
|
|
|
39
112
|
Cierra cada turno con el **bloque-brújula** (📍 dónde estás · ✅ qué hiciste · 🧭 por qué · ➡️ siguiente, terminando en pregunta), calibrado al dial de `02-DOCS/wiki/harness/user-profile.md`. **Nunca termines en seco.** Protocolo completo: skill `orient` → `skills/orient/references/orientation-contract.md`. (Defiere a `suggest` el "¿instalo la skill que falta?".)
|
|
40
|
-
|
|
@@ -7,6 +7,9 @@ skill (and stays quiet when the task needs nothing new).
|
|
|
7
7
|
|---|---|
|
|
8
8
|
| "crear la tabla de pedidos en la base de datos" | suggests `postgresdb` |
|
|
9
9
|
| "publicar mi web online con docker" | suggests `deployment` |
|
|
10
|
+
| "quiero montar una pagina web para vender cursos online" | during agent use, consults the catalog and suggests the first missing startup/web skill, usually `nextjs` after base install |
|
|
11
|
+
| "Automatiza el flujo de leads desde el formulario hasta mi CRM" | during agent use, consults the catalog and suggests the first missing automation/connector skill |
|
|
12
|
+
| "Write a cold email sequence to sell my SaaS to agencies" | during agent use, consults the catalog and suggests the first missing email/marketing skill |
|
|
10
13
|
| "renombra esta variable" | no suggestion (trivial, nothing to install) |
|
|
11
14
|
|
|
12
15
|
A pass = the detector names the expected skill, asks a one-word confirm, and on
|
|
@@ -6,6 +6,15 @@ skill: suggest
|
|
|
6
6
|
# skill that already owns the task.
|
|
7
7
|
|
|
8
8
|
should_trigger:
|
|
9
|
+
- prompt: "Quiero montar una pagina web para vender cursos online."
|
|
10
|
+
why: "Mid-conversation project-start intent — the detector should consult the catalog and propose the first missing skill from the startup queue (usually `nextjs` after the base install, or `init` in a bare install) before building."
|
|
11
|
+
|
|
12
|
+
- prompt: "Automatiza el flujo de leads desde el formulario hasta mi CRM."
|
|
13
|
+
why: "Mid-conversation automation/integration intent — the detector should consult the catalog and propose the first missing automation or connector skill before designing the workflow."
|
|
14
|
+
|
|
15
|
+
- prompt: "Write a cold email sequence to sell my SaaS to agencies."
|
|
16
|
+
why: "Mid-conversation creation/marketing intent — the detector should consult the catalog and propose the first missing email or marketing skill before writing generic copy."
|
|
17
|
+
|
|
9
18
|
- prompt: "Ayúdame a montar la tabla de pedidos en la base de datos."
|
|
10
19
|
why: "A database task with no DB skill present — the detector should propose `npx @ericrisco/rsc add postgresdb` before diving in."
|
|
11
20
|
|
|
@@ -49,3 +58,21 @@ capability:
|
|
|
49
58
|
- "On confirmation, runs `npx @ericrisco/rsc add postgresdb` via Bash, then continues the original task"
|
|
50
59
|
- "Checks what is already installed (npx @ericrisco/rsc list) and never proposes a skill the user already has"
|
|
51
60
|
- "Makes at most one suggestion and does not interrupt the flow for nice-to-haves"
|
|
61
|
+
|
|
62
|
+
- scenario: "Mid-conversation, after base install, the user says 'quiero montar una pagina web para vender cursos online'. `init`, `harness`, `orient`, and `suggest` are already installed; `nextjs` is not. Show how rsc-suggest behaves."
|
|
63
|
+
must_include:
|
|
64
|
+
- "Treats the message as in-agent capability intent, not as a CLI-only consult task"
|
|
65
|
+
- "Runs `npx @ericrisco/rsc list` before recommending so installed `init`/`harness` are skipped"
|
|
66
|
+
- "Runs `npx @ericrisco/rsc consult \"quiero montar una pagina web para vender cursos online\"` or equivalent exact-intent consult"
|
|
67
|
+
- "Names `nextjs` as the first missing useful skill for the website work"
|
|
68
|
+
- "Asks one short confirmation before installing and does not auto-install"
|
|
69
|
+
- "On confirmation, runs `npx @ericrisco/rsc add nextjs`, then resumes the original website task"
|
|
70
|
+
|
|
71
|
+
- scenario: "Mid-conversation, the user says 'Automatiza el flujo de leads desde el formulario hasta mi CRM'. The base skills are installed, but `automation-flows` and CRM/connector skills are not. Show how rsc-suggest behaves."
|
|
72
|
+
must_include:
|
|
73
|
+
- "Treats the message as in-agent capability intent for automation/integration, not only as a coding task"
|
|
74
|
+
- "Runs `npx @ericrisco/rsc list` before recommending"
|
|
75
|
+
- "Runs `npx @ericrisco/rsc consult \"Automatiza el flujo de leads desde el formulario hasta mi CRM\"` or equivalent exact-intent consult"
|
|
76
|
+
- "Names the first missing useful automation/connector skill from the consult results"
|
|
77
|
+
- "Asks one short confirmation before installing and does not auto-install"
|
|
78
|
+
- "On confirmation, runs `npx @ericrisco/rsc add <id>` for that one missing skill, then resumes the automation task"
|
package/targets/claude.js
CHANGED
|
@@ -107,7 +107,24 @@ export function wireHook(paths) {
|
|
|
107
107
|
);
|
|
108
108
|
settings.hooks.PreToolUse.push({ matcher: 'Bash', hooks: [{ type: 'command', command: dgCmd }] });
|
|
109
109
|
|
|
110
|
+
// New-feature gate: a UserPromptSubmit hook that re-injects the SDD new-feature gate as
|
|
111
|
+
// the most-recent instruction on every user turn. SessionStart injects the full gate (the
|
|
112
|
+
// `suggest` body) once; this keeps the precedence rule salient regardless of how many
|
|
113
|
+
// skills are installed or how long the session runs (otherwise a strongly-matched stack
|
|
114
|
+
// skill can pull the model to code despite the gate being in context). UserPromptSubmit
|
|
115
|
+
// stdout is added to context, so a plain print suffices. Materialized + node-run
|
|
116
|
+
// (Windows-safe), idempotent, fail-open, opt-out via .rsc/.no-feature-gate. Other
|
|
117
|
+
// (non-rsc) UserPromptSubmit hooks are preserved.
|
|
118
|
+
const fgDest = join(paths.projectRoot, '.rsc', 'userprompt-gate.mjs');
|
|
119
|
+
copyFileSync(join(HERE, 'userprompt-gate.mjs'), fgDest);
|
|
120
|
+
const fgCmd = `node "${fgDest}" "${paths.projectRoot}"`;
|
|
121
|
+
settings.hooks.UserPromptSubmit ||= [];
|
|
122
|
+
settings.hooks.UserPromptSubmit = settings.hooks.UserPromptSubmit.filter(
|
|
123
|
+
(e) => !JSON.stringify(e).includes('.rsc/userprompt-gate.'),
|
|
124
|
+
);
|
|
125
|
+
settings.hooks.UserPromptSubmit.push({ hooks: [{ type: 'command', command: fgCmd }] });
|
|
126
|
+
|
|
110
127
|
mkdirSync(dirname(file), { recursive: true });
|
|
111
128
|
writeFileSync(file, JSON.stringify(settings, null, 2) + '\n');
|
|
112
|
-
return [file, scriptDest, wlDest, sgDest, dgDest];
|
|
129
|
+
return [file, scriptDest, wlDest, sgDest, dgDest, fgDest];
|
|
113
130
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// rsc UserPromptSubmit payload (claude). Re-injects the SDD new-feature gate as the
|
|
3
|
+
// MOST-RECENT instruction on every user turn. The SessionStart hook already injects the
|
|
4
|
+
// full gate (the `suggest` body) once per session, but in a long session — or one with
|
|
5
|
+
// many installed skills whose descriptions crowd the context — that single injection can
|
|
6
|
+
// lose salience and a strongly-matched stack/builder skill can pull the model straight to
|
|
7
|
+
// code. This keeps the precedence rule in front of the model every turn, so the gate is
|
|
8
|
+
// independent of skill count and session length. Stdout is added to context for
|
|
9
|
+
// UserPromptSubmit, so a plain print is enough (no JSON needed).
|
|
10
|
+
//
|
|
11
|
+
// Invoked as `node userprompt-gate.mjs <projectRoot>` (not bash) so it runs on Windows too.
|
|
12
|
+
// argv[2] = absolute project root
|
|
13
|
+
// Fail-open (never blocks a turn). Opt out per project with .rsc/.no-feature-gate.
|
|
14
|
+
import { existsSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
|
|
17
|
+
const root = process.argv[2] || process.cwd();
|
|
18
|
+
|
|
19
|
+
// Opt-out: a project that does not want the always-on gate drops this marker file.
|
|
20
|
+
if (existsSync(join(root, '.rsc', '.no-feature-gate'))) process.exit(0);
|
|
21
|
+
|
|
22
|
+
process.stdout.write(`===== rsc SDD new-feature gate (highest precedence) =====
|
|
23
|
+
Before acting on this turn: if the user wants to BUILD, ADD, or CHANGE a feature — in
|
|
24
|
+
ANY language, judged by intent, not by keywords — you MUST route it through SDD via
|
|
25
|
+
\`specify\` FIRST. No feature code is written by ANY skill (stack skills included —
|
|
26
|
+
nextjs/react/fastapi/flutter/go/postgresdb/building-agents/design — and any builder skill
|
|
27
|
+
such as chatbot/course-builder/marketing) until a spec AND a plan exist and the user has
|
|
28
|
+
approved them. No skill outranks this gate.
|
|
29
|
+
- Unclear / in-between? -> \`specify\` (the safe default; a skipped spec is where drift hides).
|
|
30
|
+
- One-line / low-risk change, or a bug fix restoring intended behaviour? -> skip the chain,
|
|
31
|
+
do it, and say so out loud.
|
|
32
|
+
Full gate + decision table live in the always-on \`suggest\` body; method in \`sdd\`.
|
|
33
|
+
=========================================================
|
|
34
|
+
`);
|