@damiangilgonzalez/harness 1.3.14 → 1.3.16
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 +10 -7
- package/manifest.json +51 -3
- package/package.json +1 -1
- package/scripts/install-apply.js +12 -3
- package/scripts/lib/default-skill-floor.js +14 -0
- package/scripts/lib/domains.js +1 -1
- package/skills/domain-modeling/{CONTEXT-FORMAT.md → GLOSSARY-FORMAT.md} +9 -9
- package/skills/domain-modeling/SKILL.md +14 -12
- package/skills/implement-spec/SKILL.md +43 -0
- package/skills/implement-spec/evals/cases.yaml +33 -0
- package/skills/pr/CREDITS.md +3 -0
- package/skills/pr/SKILL.md +173 -0
- package/skills/pr/evals/cases.yaml +33 -0
- package/skills/retro/SKILL.md +47 -0
- package/skills/retro/evals/cases.yaml +32 -0
- package/skills/suggest/SKILL.md +1 -1
- package/skills/wait-what/SKILL.md +1 -1
- package/targets/_md-block.js +1 -1
- package/targets/hook-once.mjs +5 -3
- package/targets/session-memory-core.mjs +18 -4
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/@damiangilgonzalez/harness)
|
|
10
10
|
[](https://www.npmjs.com/package/@damiangilgonzalez/harness)
|
|
11
|
-
[](#the-catalog)
|
|
12
12
|
[](LICENSE)
|
|
13
13
|
[](https://github.com/ericrisco/rsc-harness/stargazers)
|
|
14
14
|
|
|
@@ -205,7 +205,7 @@ $ rsc onboard
|
|
|
205
205
|
██████╗ ███████╗ ██████╗ ← animated gradient wordmark
|
|
206
206
|
██╔══██╗██╔════╝██╔════╝
|
|
207
207
|
██████╔╝███████╗██║
|
|
208
|
-
|
|
208
|
+
294 skills · one CLI · zero bloat
|
|
209
209
|
|
|
210
210
|
How technical should the conversation be?
|
|
211
211
|
How much accompaniment do you want?
|
|
@@ -244,7 +244,7 @@ rsc add youtube-api remotion-video # …grow a channel, edit with Remotion
|
|
|
244
244
|
rsc add fastapi --target claude,codex # install into several assistants at once
|
|
245
245
|
rsc install --profile minimal # the base: orient + suggest + bro + unslop + show-me + eli5 + harness + init + teach
|
|
246
246
|
rsc install --profile core # floor + the full SDD workflow
|
|
247
|
-
rsc install --profile full # everything (all
|
|
247
|
+
rsc install --profile full # everything (all 294 skills)
|
|
248
248
|
rsc install --profile full --without go
|
|
249
249
|
rsc consult "I want to launch a SaaS" # recommend only, no install
|
|
250
250
|
rsc registry refresh # write .rsc/skill-registry.{json,md}
|
|
@@ -408,7 +408,7 @@ just asks in plain language.
|
|
|
408
408
|
|
|
409
409
|
## The catalog
|
|
410
410
|
|
|
411
|
-
|
|
411
|
+
294 skills, grouped by what you're trying to do. Click any skill to read its
|
|
412
412
|
`SKILL.md`. It fires on its own when a task matches.
|
|
413
413
|
|
|
414
414
|
### 🧭 Core & control plane
|
|
@@ -587,7 +587,8 @@ inside `grill-with-docs`.
|
|
|
587
587
|
|
|
588
588
|
| Skill | What it does |
|
|
589
589
|
|---|---|
|
|
590
|
-
| [implement](skills/implement/) | Builds
|
|
590
|
+
| [implement-spec](skills/implement-spec/) | Builds a whole spec from its `to-tickets` graph: parallel subagents in worktrees, one integration branch, `code-review` at the end. |
|
|
591
|
+
| [implement](skills/implement/) | Builds one loose ticket from `to-tickets`. Ordinary work runs `superpowers:executing-plans` instead. |
|
|
591
592
|
|
|
592
593
|
#### 3 · Interface
|
|
593
594
|
|
|
@@ -621,14 +622,15 @@ When the work touches a screen. Sixteen overlapping skills; pick the one that ma
|
|
|
621
622
|
|
|
622
623
|
| The work | Order |
|
|
623
624
|
|---|---|
|
|
624
|
-
| Did not touch a screen | `code-review` |
|
|
625
|
-
| Touched a screen | `revision-de-cambios` → `revision-interfaz` → `code-review` |
|
|
625
|
+
| Did not touch a screen | `code-review` → `pr` |
|
|
626
|
+
| Touched a screen | `revision-de-cambios` → `revision-interfaz` → `code-review` → `pr` |
|
|
626
627
|
|
|
627
628
|
| Skill | What it does |
|
|
628
629
|
|---|---|
|
|
629
630
|
| [code-review](skills/code-review/) | Two axes in parallel: the repo's standards and the spec. |
|
|
630
631
|
| [revision-de-cambios](skills/revision-de-cambios/) | Reviews the change, reads the removed lines and classifies each finding. Only if it touched a screen. |
|
|
631
632
|
| [revision-interfaz](skills/revision-interfaz/) | Runs the six `mejor-*` skills as one report with a verdict. Only if it touched a screen. |
|
|
633
|
+
| [pr](skills/pr/) | Writes the PR body: a visual summary, before/after evidence, and the merge danger (one-way or two-way door, blast radius). |
|
|
632
634
|
| [handoff](skills/handoff/) | Compacts the session into a handoff document. Optional. |
|
|
633
635
|
|
|
634
636
|
#### 9 · Other
|
|
@@ -638,6 +640,7 @@ When the work touches a screen. Sixteen overlapping skills; pick the one that ma
|
|
|
638
640
|
| [teach](skills/teach/) | Teaching across sessions. |
|
|
639
641
|
| [muscle-memory](skills/muscle-memory/) | A Python kata gym. |
|
|
640
642
|
| [wait-what](skills/wait-what/) | Handbrake: stop and restate. |
|
|
643
|
+
| [retro](skills/retro/) | Retrospective on a session: what to change in the agent's environment. You approve every change. |
|
|
641
644
|
| [writing-for-agents](skills/writing-for-agents/) | How to write documents an agent consumes. |
|
|
642
645
|
|
|
643
646
|
---
|
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
2
|
+
"version": "1.3.16",
|
|
3
3
|
"counts": {
|
|
4
|
-
"skills":
|
|
4
|
+
"skills": 294,
|
|
5
5
|
"agents": 34,
|
|
6
6
|
"commands": 43,
|
|
7
7
|
"fixedCommands": 10
|
|
@@ -1395,7 +1395,7 @@
|
|
|
1395
1395
|
},
|
|
1396
1396
|
{
|
|
1397
1397
|
"id": "domain-modeling",
|
|
1398
|
-
"description": "Build and
|
|
1398
|
+
"description": "Build and sharpen the project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR.",
|
|
1399
1399
|
"tags": [
|
|
1400
1400
|
"domain-modeling",
|
|
1401
1401
|
"glossary",
|
|
@@ -2467,6 +2467,23 @@
|
|
|
2467
2467
|
"full"
|
|
2468
2468
|
]
|
|
2469
2469
|
},
|
|
2470
|
+
{
|
|
2471
|
+
"id": "implement-spec",
|
|
2472
|
+
"description": "Implement the result of /to-spec and /to-tickets in code, orchestrating parallel implementer subagents over the ticket graph.",
|
|
2473
|
+
"tags": [
|
|
2474
|
+
"implementation",
|
|
2475
|
+
"spec",
|
|
2476
|
+
"tickets",
|
|
2477
|
+
"subagents",
|
|
2478
|
+
"orchestration"
|
|
2479
|
+
],
|
|
2480
|
+
"recommends": [],
|
|
2481
|
+
"profiles": [
|
|
2482
|
+
"core",
|
|
2483
|
+
"ui",
|
|
2484
|
+
"full"
|
|
2485
|
+
]
|
|
2486
|
+
},
|
|
2470
2487
|
{
|
|
2471
2488
|
"id": "ingeniero-diseno-web",
|
|
2472
2489
|
"description": "Build or redesign polished visual artifacts that render in a browser with HTML/CSS/JavaScript/React — pages, dashboards, prototypes, presentations, animations, UI mockups, and data visualizations. Use for visual front-end creation, design-system exploration, design critique, or explicit browser-based acceptance/QA. Not for back-end, CLI, non-visual code, or converting sources into long-form articles.",
|
|
@@ -3786,6 +3803,22 @@
|
|
|
3786
3803
|
"full"
|
|
3787
3804
|
]
|
|
3788
3805
|
},
|
|
3806
|
+
{
|
|
3807
|
+
"id": "pr",
|
|
3808
|
+
"description": "Use when writing a PR body: a visual summary, before/after evidence, and the merge danger (one-way or two-way door, blast radius).",
|
|
3809
|
+
"tags": [
|
|
3810
|
+
"pull-request",
|
|
3811
|
+
"review",
|
|
3812
|
+
"evidence",
|
|
3813
|
+
"risk"
|
|
3814
|
+
],
|
|
3815
|
+
"recommends": [],
|
|
3816
|
+
"profiles": [
|
|
3817
|
+
"core",
|
|
3818
|
+
"ui",
|
|
3819
|
+
"full"
|
|
3820
|
+
]
|
|
3821
|
+
},
|
|
3789
3822
|
{
|
|
3790
3823
|
"id": "presentations",
|
|
3791
3824
|
"description": "Use when building, theming, or exporting a presentation deck — pitch, sales, keynote, board/QBR, leave-behind one-pager — from slide structure to a token-based theme to PDF or editable PPTX (Marp, Slidev, python-pptx). NOT the words (that is `marketing`), NOT the visual tokens (that is `design`), NOT the investor story arc (that is `pitch-deck`).",
|
|
@@ -4288,6 +4321,21 @@
|
|
|
4288
4321
|
],
|
|
4289
4322
|
"profiles": []
|
|
4290
4323
|
},
|
|
4324
|
+
{
|
|
4325
|
+
"id": "retro",
|
|
4326
|
+
"description": "Conduct a retrospective on a coding session: find what in the agent's environment (navigation, checks, standards, steering files, tooling) should change so future runs go better.",
|
|
4327
|
+
"tags": [
|
|
4328
|
+
"retrospective",
|
|
4329
|
+
"session-review",
|
|
4330
|
+
"agent-environment"
|
|
4331
|
+
],
|
|
4332
|
+
"recommends": [],
|
|
4333
|
+
"profiles": [
|
|
4334
|
+
"core",
|
|
4335
|
+
"ui",
|
|
4336
|
+
"full"
|
|
4337
|
+
]
|
|
4338
|
+
},
|
|
4291
4339
|
{
|
|
4292
4340
|
"id": "review-management",
|
|
4293
4341
|
"description": "Use when a public review needs an on-voice reply, when you need to earn more reviews legally, or when an aggregate rating is slipping across Google Business Profile, Trustpilot, the App Store or Google Play — including deciding reply versus flag, getting an unfair one-star removed rather than merely answered, and wiring programmatic replies. NOT a private support ticket against an SLA (that is `customer-support`), NOT churn, NPS or save plays (that is `retention`).",
|
package/package.json
CHANGED
package/scripts/install-apply.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '../targets/agents.js';
|
|
13
13
|
import { projectOptOuts } from '../targets/opt-outs.js';
|
|
14
14
|
import { readState, writeState } from './lib/state.js';
|
|
15
|
-
import { withDefaultSkillFloor } from './lib/default-skill-floor.js';
|
|
15
|
+
import { withCodeFlowFloor, withDefaultSkillFloor } from './lib/default-skill-floor.js';
|
|
16
16
|
import { readManifest, writeManifest } from './lib/manifest-file.js';
|
|
17
17
|
import { createBackup } from './lib/backups.js';
|
|
18
18
|
import {
|
|
@@ -354,6 +354,11 @@ export function ignoreLocalState(cwd = process.cwd(), target) {
|
|
|
354
354
|
if (target) {
|
|
355
355
|
const paths = targetPaths(target, undefined, cwd);
|
|
356
356
|
const rel = (abs) => relative(cwd, abs).split(sep).join('/');
|
|
357
|
+
// `.claude/worktrees/` is where Claude Code puts the checkout of each isolated branch. Nothing
|
|
358
|
+
// ignored it, so every file of every worktree showed up as untracked: noise in `git status`, a
|
|
359
|
+
// `git add .` away from being committed, and the memory hook fingerprinted them all on each turn
|
|
360
|
+
// (54 s on a project with 964 of them, against a 5 s timeout).
|
|
361
|
+
if (target === 'claude') wanted.push(CLAUDE_WORKTREES);
|
|
357
362
|
for (const id of Object.keys(readState(paths.stateFile).skills || {})) wanted.push(rel(paths.skillDir(id)));
|
|
358
363
|
// The per-file ledger is derived AND platform-shaped (symlink here, real copy on
|
|
359
364
|
// Windows), so committing it puts two incompatible inventories of one thing in one
|
|
@@ -530,7 +535,7 @@ export async function uninstall({ skillIds = [], agentIds = [], target, home, cw
|
|
|
530
535
|
export function removeTargetInstall({ target, home, cwd = process.cwd() }) {
|
|
531
536
|
const paths = targetPaths(target, home, cwd);
|
|
532
537
|
const state = readState(paths.stateFile);
|
|
533
|
-
const ignored = [paths.stateFile];
|
|
538
|
+
const ignored = [paths.stateFile, ...(target === 'claude' ? [join(cwd, CLAUDE_WORKTREES)] : [])];
|
|
534
539
|
const ownedIgnoreEntries = new Set(state.ignoreEntriesAdded || []);
|
|
535
540
|
const owned = [
|
|
536
541
|
...Object.values(state.skills || {}).flatMap((entry) => entry.files || []),
|
|
@@ -626,7 +631,10 @@ export async function syncInstalled({ target, home, cwd = process.cwd(), dryRun
|
|
|
626
631
|
// mandatory never reaches an existing harness: `add` and `install` apply the floor, sync did
|
|
627
632
|
// not, and sync is the only one an upgrade runs. Applied only to a harness that already declares
|
|
628
633
|
// something: a directory declaring nothing is not a harness missing its floor.
|
|
629
|
-
|
|
634
|
+
// Lo mismo con el flujo del gate: si el gate está conectado, sus skills llegan con el update.
|
|
635
|
+
const declared = declaredRaw.length
|
|
636
|
+
? withCodeFlowFloor(withDefaultSkillFloor(declaredRaw), manifest?.onboarding?.plan?.policy)
|
|
637
|
+
: declaredRaw;
|
|
630
638
|
const declaredAgents = state.explicitAgents?.length ? state.explicitAgents : (manifest?.agents || []);
|
|
631
639
|
if (!declared.length && !declaredAgents.length) return dryRun ? { dryRun: true, synced: [], syncedAgents: [], paths: [] } : { synced: [], syncedAgents: [], backup: null };
|
|
632
640
|
if (dryRun) {
|
|
@@ -656,6 +664,7 @@ export async function syncInstalled({ target, home, cwd = process.cwd(), dryRun
|
|
|
656
664
|
// own knowledge — kept unless `withDocs` is set. Returns the paths touched.
|
|
657
665
|
// Note: backups live under `.rsc/backups/`, which this removes — so purge does not
|
|
658
666
|
// snapshot (a pre-purge backup would delete itself). It is the deliberate escape hatch.
|
|
667
|
+
const CLAUDE_WORKTREES = '.claude/worktrees/';
|
|
659
668
|
const RSC_IGNORE_HEADER = '# rsc local state (hooks, seals, logs) and managed skill links — machine-local';
|
|
660
669
|
|
|
661
670
|
// Merge consecutive rsc blocks into the first: drop a repeated header and the blank seam before it
|
|
@@ -9,3 +9,17 @@ export const DEFAULT_SKILL_FLOOR = Object.freeze(['orient', 'suggest', 'bro']);
|
|
|
9
9
|
export function withDefaultSkillFloor(skillIds = []) {
|
|
10
10
|
return [...new Set([...DEFAULT_SKILL_FLOOR, ...skillIds])];
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
// Las skills del flujo que nombra el gate de código (targets/hook-once.mjs), más `retro`.
|
|
14
|
+
// Un proyecto con el gate conectado tiene que tenerlas todas: si el gate cambia y nombra una
|
|
15
|
+
// skill nueva (`implement-spec`, `pr`), el update la trae en vez de dejar el gate apuntando a
|
|
16
|
+
// algo que no está. Un proyecto sin gate (`codeHooks: false`) no recibe ninguna.
|
|
17
|
+
export const CODE_FLOW_FLOOR = Object.freeze([
|
|
18
|
+
'grill-with-docs', 'wayfinder', 'to-spec', 'write-adr', 'to-tickets',
|
|
19
|
+
'implement-spec', 'implement', 'code-review', 'pr', 'retro',
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
export function withCodeFlowFloor(skillIds = [], policy) {
|
|
23
|
+
if (policy?.codeHooks === false) return skillIds;
|
|
24
|
+
return [...new Set([...skillIds, ...CODE_FLOW_FLOOR])];
|
|
25
|
+
}
|
package/scripts/lib/domains.js
CHANGED
|
@@ -27,7 +27,7 @@ export const DOMAINS = [
|
|
|
27
27
|
{ title: 'Motion & interface craft', ids: ['motion-craft', 'ui-engineering', 'variant-explorer'] },
|
|
28
28
|
{ title: 'Design & content craft', ids: ['design-loop', 'design', 'design-dna', 'presentations', 'course-storytelling', 'course-builder', 'technical-writing', 'translation-l10n'] },
|
|
29
29
|
{ title: 'Knowledge & meta', ids: ['knowledge-ops', 'codebase-onboarding', 'research-ops', 'continuous-learning', 'skill-scout', 'context-budget', 'roast-me', 'show-me', 'eli5', 'fable-operator'] },
|
|
30
|
-
{ title: 'Personal catalog — workflow (Spanish)', ids: ['grill-me', 'grill-with-docs', 'grilling', 'wayfinder', 'to-spec', 'to-tickets', 'to-questionnaire', 'implement', 'revision-de-cambios', 'code-review', 'research', 'prototype', 'domain-modeling', 'handoff', 'write-adr', 'wait-what', 'writing-for-agents', 'claude-project-setup', 'muscle-memory', 'teach'] },
|
|
30
|
+
{ title: 'Personal catalog — workflow (Spanish)', ids: ['grill-me', 'grill-with-docs', 'grilling', 'wayfinder', 'to-spec', 'to-tickets', 'to-questionnaire', 'implement', 'implement-spec', 'pr', 'retro', 'revision-de-cambios', 'code-review', 'research', 'prototype', 'domain-modeling', 'handoff', 'write-adr', 'wait-what', 'writing-for-agents', 'claude-project-setup', 'muscle-memory', 'teach'] },
|
|
31
31
|
{ title: 'Personal catalog — interface design (Spanish)', ids: ['flujo-interfaz', 'animar', 'diseno-apple', 'diseno-landing', 'ingeniero-diseno-web', 'leyes-de-percepcion', 'leyes-de-retencion', 'mejor-accesibilidad', 'mejor-colores', 'mejor-layout', 'mejor-redaccion', 'mejor-tipografia', 'mejor-ui', 'sitios-calidad-premio', 'tastemaker', 'video-a-superprompt', 'vocabulario-animacion', 'revision-interfaz'] },
|
|
32
32
|
];
|
|
33
33
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Formato de
|
|
1
|
+
# Formato de GLOSSARY.md
|
|
2
2
|
|
|
3
3
|
## Estructura
|
|
4
4
|
|
|
@@ -31,18 +31,18 @@ _Evitar_: Comprador, usuario, cuenta
|
|
|
31
31
|
|
|
32
32
|
## Repos de contexto único vs. múltiple
|
|
33
33
|
|
|
34
|
-
**Contexto único (la mayoría de los repos):** Un solo `
|
|
34
|
+
**Contexto único (la mayoría de los repos):** Un solo `GLOSSARY.md` en la raíz del repo.
|
|
35
35
|
|
|
36
|
-
**Múltiples contextos:** Un `
|
|
36
|
+
**Múltiples contextos:** Un `GLOSSARY-MAP.md` en la raíz lista los contextos, dónde viven y cómo se relacionan entre sí:
|
|
37
37
|
|
|
38
38
|
```md
|
|
39
39
|
# Mapa de Contextos
|
|
40
40
|
|
|
41
41
|
## Contextos
|
|
42
42
|
|
|
43
|
-
- [Ordering](./src/ordering/
|
|
44
|
-
- [Billing](./src/billing/
|
|
45
|
-
- [Fulfillment](./src/fulfillment/
|
|
43
|
+
- [Ordering](./src/ordering/GLOSSARY.md) — recibe y rastrea los pedidos de clientes
|
|
44
|
+
- [Billing](./src/billing/GLOSSARY.md) — genera facturas y procesa pagos
|
|
45
|
+
- [Fulfillment](./src/fulfillment/GLOSSARY.md) — gestiona el picking y el envío en el almacén
|
|
46
46
|
|
|
47
47
|
## Relaciones
|
|
48
48
|
|
|
@@ -53,8 +53,8 @@ _Evitar_: Comprador, usuario, cuenta
|
|
|
53
53
|
|
|
54
54
|
La skill infiere qué estructura aplica:
|
|
55
55
|
|
|
56
|
-
- Si existe `
|
|
57
|
-
- Si solo existe un `
|
|
58
|
-
- Si no existe ninguno, crea un `
|
|
56
|
+
- Si existe `GLOSSARY-MAP.md`, léelo para encontrar los contextos
|
|
57
|
+
- Si solo existe un `GLOSSARY.md` en la raíz, es contexto único
|
|
58
|
+
- Si no existe ninguno, crea un `GLOSSARY.md` en la raíz de forma perezosa cuando se resuelva el primer término
|
|
59
59
|
|
|
60
60
|
Cuando existen múltiples contextos, infiere a cuál corresponde el tema actual. Si no está claro, pregunta.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: domain-modeling
|
|
3
|
-
description: "Build and
|
|
3
|
+
description: "Build and sharpen the project's domain model. Use when discussing codebase terminology, writing or editing a GLOSSARY.md, or recording or editing an ADR."
|
|
4
4
|
tags: ["domain-modeling", "glossary", "architecture"]
|
|
5
5
|
profiles: [core, ui, full]
|
|
6
6
|
origin: damiangil
|
|
@@ -8,7 +8,7 @@ origin: damiangil
|
|
|
8
8
|
|
|
9
9
|
# Modelado de Dominio
|
|
10
10
|
|
|
11
|
-
Construye y afina activamente el modelo de dominio del proyecto a medida que diseñas. Esta es la disciplina *activa*: cuestionar términos, inventar escenarios límite y escribir el glosario y las decisiones en el momento en que se cristalizan. (Simplemente *leer* `
|
|
11
|
+
Construye y afina activamente el modelo de dominio del proyecto a medida que diseñas. Esta es la disciplina *activa*: cuestionar términos, inventar escenarios límite y escribir el glosario y las decisiones en el momento en que se cristalizan. (Simplemente *leer* `GLOSSARY.md` para sacar vocabulario no es esta skill — eso es un hábito de una línea que cualquier skill puede hacer. Esta skill es para cuando estás *cambiando* el modelo, no solo consumiéndolo.)
|
|
12
12
|
|
|
13
13
|
## Estructura de ficheros
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ La mayoría de los repos tienen un único contexto:
|
|
|
16
16
|
|
|
17
17
|
```
|
|
18
18
|
/
|
|
19
|
-
├──
|
|
19
|
+
├── GLOSSARY.md
|
|
20
20
|
├── docs/
|
|
21
21
|
│ └── adr/
|
|
22
22
|
│ ├── 0001-orders-event-sourced.md
|
|
@@ -24,29 +24,31 @@ La mayoría de los repos tienen un único contexto:
|
|
|
24
24
|
└── src/
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Si existe un `
|
|
27
|
+
Si existe un `GLOSSARY-MAP.md` en la raíz, el repo tiene varios contextos. El mapa indica dónde vive cada uno:
|
|
28
28
|
|
|
29
29
|
```
|
|
30
30
|
/
|
|
31
|
-
├──
|
|
31
|
+
├── GLOSSARY-MAP.md
|
|
32
32
|
├── docs/
|
|
33
33
|
│ └── adr/ ← decisiones de todo el sistema
|
|
34
34
|
├── src/
|
|
35
35
|
│ ├── ordering/
|
|
36
|
-
│ │ ├──
|
|
36
|
+
│ │ ├── GLOSSARY.md
|
|
37
37
|
│ │ └── docs/adr/ ← decisiones específicas del contexto
|
|
38
38
|
│ └── billing/
|
|
39
|
-
│ ├──
|
|
39
|
+
│ ├── GLOSSARY.md
|
|
40
40
|
│ └── docs/adr/
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
Si el repo todavía tiene un `CONTEXT.md` (o `CONTEXT-MAP.md`) de antes del cambio de nombre, renómbralo con `git mv` a `GLOSSARY.md` (o `GLOSSARY-MAP.md`) antes de seguir, y díselo al usuario en una línea.
|
|
44
|
+
|
|
45
|
+
Crea los ficheros de forma perezosa: solo cuando tengas algo que escribir. Si no existe `GLOSSARY.md`, créalo cuando se resuelva el primer término. Si no existe `docs/adr/`, créalo cuando haga falta el primer ADR.
|
|
44
46
|
|
|
45
47
|
## Durante la sesión
|
|
46
48
|
|
|
47
49
|
### Contrasta contra el glosario
|
|
48
50
|
|
|
49
|
-
Cuando el usuario use un término que entre en conflicto con el lenguaje ya existente en `
|
|
51
|
+
Cuando el usuario use un término que entre en conflicto con el lenguaje ya existente en `GLOSSARY.md`, señálalo de inmediato. "Tu glosario define 'cancelación' como X, pero parece que te refieres a Y — ¿cuál es?"
|
|
50
52
|
|
|
51
53
|
### Afina el lenguaje difuso
|
|
52
54
|
|
|
@@ -60,11 +62,11 @@ Cuando se estén discutiendo relaciones del dominio, ponlas a prueba con escenar
|
|
|
60
62
|
|
|
61
63
|
Cuando el usuario afirme cómo funciona algo, comprueba si el código coincide. Si encuentras una contradicción, sácala a la luz: "Tu código cancela Pedidos enteros, pero acabas de decir que la cancelación parcial es posible — ¿cuál es la correcta?"
|
|
62
64
|
|
|
63
|
-
### Actualiza
|
|
65
|
+
### Actualiza GLOSSARY.md sobre la marcha
|
|
64
66
|
|
|
65
|
-
Cuando un término quede resuelto, actualiza `
|
|
67
|
+
Cuando un término quede resuelto, actualiza `GLOSSARY.md` ahí mismo. No los acumules — captúralos según ocurren. Usa el formato de [GLOSSARY-FORMAT.md](./GLOSSARY-FORMAT.md).
|
|
66
68
|
|
|
67
|
-
`
|
|
69
|
+
`GLOSSARY.md` debe estar totalmente libre de detalles de implementación. No trates `GLOSSARY.md` como una especificación, un borrador, ni un repositorio de decisiones de implementación. Es un glosario y nada más.
|
|
68
70
|
|
|
69
71
|
### Ofrece ADRs con moderación
|
|
70
72
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: implement-spec
|
|
3
|
+
description: "Implement the result of /to-spec and /to-tickets in code, orchestrating parallel implementer subagents over the ticket graph."
|
|
4
|
+
tags: ["implementation", "spec", "tickets", "subagents", "orchestration"]
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
profiles: [core, ui, full]
|
|
7
|
+
origin: damiangil
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Te han dado una spec. Esa spec debería tener tickets asociados que describen cómo implementarla.
|
|
11
|
+
|
|
12
|
+
El issue tracker debería estar descrito en `docs/agents/issue-tracker.md`. Si falta, pregunta al usuario dónde viven los tickets y cómo se cierra el trabajo (PR, issue, fichero).
|
|
13
|
+
|
|
14
|
+
El objetivo es la spec entera implementada en una sola **rama de integración**, con cada ticket resuelto de la forma en que el issue tracker cierra el trabajo.
|
|
15
|
+
|
|
16
|
+
Los tickets no son una lista de pasos. Son un **grafo de tareas** con relaciones de bloqueo entre ellos. Eso significa que siempre hay una **frontera** de tickets listos para cogerse.
|
|
17
|
+
|
|
18
|
+
La comunicación con los subagentes debe ser escasa. Comunica sobre todo con **punteros de contexto**: a la spec, a los tickets, a las notas de investigación y a los commits anteriores. No dupliques información que ya está disponible a través de un puntero.
|
|
19
|
+
|
|
20
|
+
Lanza los **subagentes implementadores** en segundo plano siempre que se pueda, para tener la máxima concurrencia.
|
|
21
|
+
|
|
22
|
+
## Pasos
|
|
23
|
+
|
|
24
|
+
1. Lee la spec y los tickets para entender el grafo de tareas.
|
|
25
|
+
|
|
26
|
+
2. (opcional) Usa un **subagente explorador** para la exploración que pidan los tickets: ficheros relevantes del código o documentación externa. Asegúrate de que puede guardar ficheros: debe dejar sus notas en Markdown en una carpeta fuera del repo, accesible para todos los subagentes siguientes. Así los **subagentes implementadores** se centran en implementar y no en explorar.
|
|
27
|
+
|
|
28
|
+
3. Crea la rama de integración. Si el issue tracker cierra el trabajo con PRs, o el usuario pide una, abre una PR en borrador después del primer merge del paso 5 (una rama sin commits por delante de main no puede abrirla), marcada como que cierra la spec y los tickets.
|
|
29
|
+
|
|
30
|
+
4. Usa **subagentes implementadores** para implementar cada ticket, cada uno en su propio worktree y en su propia rama (`superpowers:using-git-worktrees`). Cada subagente implementador:
|
|
31
|
+
- confirma que su worktree parte de la rama de integración antes de empezar, y se reinicia sobre ella si no;
|
|
32
|
+
- llama a la herramienta Skill con `superpowers:test-driven-development` para construir el ticket;
|
|
33
|
+
- fusiona la punta de la rama de integración en su propia rama antes de decir que ha terminado.
|
|
34
|
+
|
|
35
|
+
5. Cuando un **subagente implementador** termina, fusiona su trabajo en la rama de integración con un **subagente fusionador**.
|
|
36
|
+
|
|
37
|
+
6. Si eso cambia la **frontera** de tickets disponibles, lanza más **subagentes implementadores** para los tickets nuevos. Así se mantiene la máxima concurrencia.
|
|
38
|
+
|
|
39
|
+
7. Cuando todos los tickets estén completos, llama a la herramienta Skill con `code-review` sobre la rama de integración. Arregla todo lo que salga de la revisión en un único **subagente implementador**.
|
|
40
|
+
|
|
41
|
+
8. Si existe una PR en borrador, márcala como lista para revisar y escribe su cuerpo con `pr`. Si no, resuelve cada ticket de la forma en que el issue tracker cierra el trabajo e informa de la rama de integración.
|
|
42
|
+
|
|
43
|
+
9. Limpia todos los worktrees de los **subagentes implementadores**.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
skill: implement-spec
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Implementa la spec entera con sus tickets, en paralelo."
|
|
5
|
+
why: "Disparador directo de implement-spec: la spec completa sobre el grafo de tickets."
|
|
6
|
+
- prompt: "Ya tenemos la spec y los tickets; orquesta subagentes para construirlo todo."
|
|
7
|
+
why: "Disparador directo de implement-spec."
|
|
8
|
+
- prompt: "Lanza implementadores en worktrees para cada ticket de la spec y júntalo en una rama de integración."
|
|
9
|
+
why: "Disparador directo de implement-spec."
|
|
10
|
+
- prompt: "Implement the whole spec from /to-spec and /to-tickets."
|
|
11
|
+
why: "Disparador directo de implement-spec."
|
|
12
|
+
- prompt: "Construye todos los tickets de esta spec respetando los bloqueos entre ellos."
|
|
13
|
+
why: "Disparador directo de implement-spec: la frontera del grafo de tareas."
|
|
14
|
+
|
|
15
|
+
should_not_trigger:
|
|
16
|
+
- prompt: "Implementa solo este ticket."
|
|
17
|
+
route_to: "implement"
|
|
18
|
+
why: "Un único ticket es el trabajo de implement, no de implement-spec."
|
|
19
|
+
- prompt: "Escribe la spec antes de implementar nada."
|
|
20
|
+
route_to: "to-spec"
|
|
21
|
+
why: "Escribir la spec es el trabajo de to-spec, no de implement-spec."
|
|
22
|
+
- prompt: "Descompón la spec en tickets primero."
|
|
23
|
+
route_to: "to-tickets"
|
|
24
|
+
why: "Descomponer en tickets es el trabajo de to-tickets, no de implement-spec."
|
|
25
|
+
- prompt: "Revisa el código de la rama de integración."
|
|
26
|
+
route_to: "code-review"
|
|
27
|
+
why: "Revisar el código es el trabajo de code-review, no de implement-spec."
|
|
28
|
+
|
|
29
|
+
capability:
|
|
30
|
+
- scenario: "El usuario tiene una spec con tickets y quiere implementarla entera con subagentes en paralelo."
|
|
31
|
+
must_include:
|
|
32
|
+
- "rama de integración"
|
|
33
|
+
- "frontera"
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
# Créditos
|
|
2
|
+
|
|
3
|
+
El menú de visuales de la sección **Resumen** (pseudocódigo, árboles de llamadas, árboles de componentes, árboles de ficheros, Mermaid, diffs) y su guía de colocación vienen de la skill [`show-me`](https://github.com/humanlayer/humanlayer) de [Dex Horthy](https://github.com/dexhorthy), reproducida casi palabra por palabra y aplicada a un diff en lugar de a una conversación en vivo. La skill llega a este catálogo a través de `pr` en [mattpocock/skills](https://github.com/mattpocock/skills) (v1.3.1). `pr` no depende de `show-me` como skill (una dependencia rompería las instalaciones sueltas), así que el contenido va copiado en lugar de enlazado; este fichero es la atribución que llevaría esa dependencia.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pr
|
|
3
|
+
description: "Use when writing a PR body: a visual summary, before/after evidence, and the merge danger (one-way or two-way door, blast radius)."
|
|
4
|
+
tags: ["pull-request", "review", "evidence", "risk"]
|
|
5
|
+
profiles: [core, ui, full]
|
|
6
|
+
origin: damiangil
|
|
7
|
+
metadata:
|
|
8
|
+
credits:
|
|
9
|
+
skill: show-me
|
|
10
|
+
author: Dex Horthy
|
|
11
|
+
organisation: Humanlayer
|
|
12
|
+
url: "https://github.com/humanlayer/skills/blob/main/plugins/show-me/skills/show-me/SKILL.md"
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
Usa esta plantilla para escribir el cuerpo de la PR:
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
## Resumen
|
|
19
|
+
|
|
20
|
+
<diagrama, esbozo de diff o árbol>
|
|
21
|
+
|
|
22
|
+
## Evidencia
|
|
23
|
+
|
|
24
|
+
- **Antes:** <captura/salida/ejecución de test que falla>
|
|
25
|
+
**Después:** <captura/salida/ejecución de test que pasa>
|
|
26
|
+
|
|
27
|
+
## Peligro de fusión
|
|
28
|
+
|
|
29
|
+
**Puerta:** <de un sentido o de dos sentidos>
|
|
30
|
+
|
|
31
|
+
<opcional: descripción>
|
|
32
|
+
|
|
33
|
+
**Radio de impacto:** <descripción en una palabra>
|
|
34
|
+
|
|
35
|
+
<opcional: posibles consecuencias de fusionar>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Secciones
|
|
39
|
+
|
|
40
|
+
Sáltate los preámbulos y deja la prosa breve. Usa el lenguaje del dominio del usuario que está en `GLOSSARY.md`.
|
|
41
|
+
|
|
42
|
+
### Resumen
|
|
43
|
+
|
|
44
|
+
Elige la vista más pequeña que deje clara la idea clave.
|
|
45
|
+
|
|
46
|
+
- Muestra una lógica o un algoritmo como pseudocódigo:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
on(save)
|
|
50
|
+
if content is unchanged
|
|
51
|
+
return cached result
|
|
52
|
+
write new content
|
|
53
|
+
return fresh result
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- Muestra el flujo de control en ejecución como un árbol de llamadas:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
submitForm
|
|
60
|
+
createSession
|
|
61
|
+
persistPrompt
|
|
62
|
+
launchAgent
|
|
63
|
+
navigateToSession
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- Muestra la estructura de la UI como un árbol de componentes, con el estado y los límites de módulo que importan:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
<SessionPage> (apps/example/src/routes/session.tsx)
|
|
70
|
+
useSessionEvents()
|
|
71
|
+
<SessionToolbar>
|
|
72
|
+
<RunSkillButton> (packages/ui)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- Muestra de qué se encarga cada fichero, o un refactor amplio, como un árbol de ficheros poco profundo:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
src/
|
|
79
|
+
├── commands/ # interpreta las acciones del usuario
|
|
80
|
+
├── sessions/ # guarda el estado de la sesión
|
|
81
|
+
└── transport/ # envía las peticiones a la API
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- Muestra la interacción entre componentes, el flujo de control o el flujo de datos con Mermaid:
|
|
85
|
+
|
|
86
|
+
```mermaid
|
|
87
|
+
sequenceDiagram
|
|
88
|
+
participant User
|
|
89
|
+
participant UI
|
|
90
|
+
participant Daemon
|
|
91
|
+
User->>UI: choose command
|
|
92
|
+
UI->>Daemon: send expanded prompt
|
|
93
|
+
Daemon-->>UI: stream result
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
- Usa `diff` cuando lo importante es qué cambia y la forma de alrededor ya existe. Ajusta la forma del diff al tema.
|
|
97
|
+
|
|
98
|
+
Para un cambio de componente:
|
|
99
|
+
|
|
100
|
+
```diff
|
|
101
|
+
<SessionPage>
|
|
102
|
+
useSessionEvents()
|
|
103
|
+
<SessionToolbar>
|
|
104
|
+
+ <RunSkillButton />
|
|
105
|
+
<SessionTimeline>
|
|
106
|
+
+ <SkillResultCard />
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Para un cambio en la disposición de ficheros:
|
|
110
|
+
|
|
111
|
+
```diff
|
|
112
|
+
src/
|
|
113
|
+
├── commands/
|
|
114
|
+
+│ └── show-me.ts # expande el slash command
|
|
115
|
+
├── sessions/
|
|
116
|
+
-└── transport.ts
|
|
117
|
+
+└── transport/
|
|
118
|
+
+ ├── client.ts
|
|
119
|
+
+ └── stream.ts
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Para un cambio en un árbol o pila de llamadas:
|
|
123
|
+
|
|
124
|
+
```diff
|
|
125
|
+
submitForm
|
|
126
|
+
createSession
|
|
127
|
+
persistPrompt
|
|
128
|
+
+ expandSkillMention
|
|
129
|
+
launchAgent
|
|
130
|
+
- navigateToSession
|
|
131
|
+
+ navigateToSession
|
|
132
|
+
+ subscribeToEvents
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Para un cambio de estado o de flujo de control:
|
|
136
|
+
|
|
137
|
+
```diff
|
|
138
|
+
on(save)
|
|
139
|
+
- write content
|
|
140
|
+
+ if content is unchanged
|
|
141
|
+
+ return cached result
|
|
142
|
+
+ write new content
|
|
143
|
+
+ invalidate cache
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
- Muestra el bloque entero cuando casi todo es nuevo, cuando omitir contexto escondería de quién es algo o en qué orden va, o cuando el usuario necesita una forma objetivo que pueda copiar:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
function expandSkill(command: string): string {
|
|
150
|
+
const skillName = command.slice(1);
|
|
151
|
+
return `use the ${skillName} skill`;
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Guía
|
|
156
|
+
|
|
157
|
+
Pon cada visual junto al texto corto al que apoya. Quédate solo con las llamadas, ficheros, props, estados y límites que hacen falta para responder a la pregunta actual del usuario, o a las opciones para resolver el punto que se está discutiendo.
|
|
158
|
+
|
|
159
|
+
Puedes usar uno de estos, puedes usar varios; es poco probable que uses todos. Usa tu criterio y no abrumes al usuario.
|
|
160
|
+
|
|
161
|
+
### Evidencia
|
|
162
|
+
|
|
163
|
+
Pruebas concretas de que el cambio funciona. Muestra un antes y un después.
|
|
164
|
+
|
|
165
|
+
Las capturas de pantalla son lo mejor, cuando el entorno lo permite y el cambio es visual.
|
|
166
|
+
|
|
167
|
+
La evidencia basada en ejecución va justo detrás: resultados de tests, salida de consola. Muestra el test exacto que antes fallaba y ahora pasa, en pseudocódigo.
|
|
168
|
+
|
|
169
|
+
### Peligro de fusión
|
|
170
|
+
|
|
171
|
+
Di si es una puerta de un sentido o de dos sentidos. Por una puerta de dos sentidos se puede volver atrás; por una de un sentido, no. Una PR que es barata de revertir tiene menos riesgo. Los cambios que implican acciones destructivas o decisiones difíciles de revertir son puertas de un sentido.
|
|
172
|
+
|
|
173
|
+
El radio de impacto es el alcance posible de los efectos que introduce la PR. Considera todas las posibilidades. Ejemplos: saltos de layout, roturas para quien consume el código, el comportamiento en móvil, etc.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
skill: pr
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Escribe el cuerpo de la PR de esta rama."
|
|
5
|
+
why: "Disparador directo de pr."
|
|
6
|
+
- prompt: "Abre la PR y explica el cambio con un diagrama y el antes y después."
|
|
7
|
+
why: "Disparador directo de pr: resumen visual y evidencia."
|
|
8
|
+
- prompt: "Write the PR description for these changes."
|
|
9
|
+
why: "Disparador directo de pr."
|
|
10
|
+
- prompt: "Prepara la descripción del pull request con el riesgo de fusionarlo."
|
|
11
|
+
why: "Disparador directo de pr: peligro de fusión y radio de impacto."
|
|
12
|
+
- prompt: "¿Qué pongo en la PR para que se revise rápido?"
|
|
13
|
+
why: "Disparador directo de pr."
|
|
14
|
+
|
|
15
|
+
should_not_trigger:
|
|
16
|
+
- prompt: "Revisa el código de esta PR."
|
|
17
|
+
route_to: "code-review"
|
|
18
|
+
why: "Revisar el código es el trabajo de code-review, no de pr."
|
|
19
|
+
- prompt: "Haz el commit de estos cambios con un buen mensaje."
|
|
20
|
+
route_to: "git-workflow"
|
|
21
|
+
why: "El mensaje de commit es el trabajo de git-workflow, no de pr."
|
|
22
|
+
- prompt: "Implementa la spec entera."
|
|
23
|
+
route_to: "implement-spec"
|
|
24
|
+
why: "Implementar la spec es el trabajo de implement-spec, no de pr."
|
|
25
|
+
- prompt: "Escribe la spec de esta funcionalidad antes de tocar código."
|
|
26
|
+
route_to: "to-spec"
|
|
27
|
+
why: "Redactar la spec es el trabajo de to-spec, no de pr."
|
|
28
|
+
|
|
29
|
+
capability:
|
|
30
|
+
- scenario: "El usuario quiere el cuerpo de una PR que se revise de un vistazo."
|
|
31
|
+
must_include:
|
|
32
|
+
- "Peligro de fusión"
|
|
33
|
+
- "Radio de impacto"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: retro
|
|
3
|
+
description: "Conduct a retrospective on a coding session: find what in the agent's environment (navigation, checks, standards, steering files, tooling) should change so future runs go better."
|
|
4
|
+
tags: ["retrospective", "session-review", "agent-environment"]
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
profiles: [core, ui, full]
|
|
7
|
+
origin: damiangil
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
El usuario ha pedido una **retrospectiva**. Vas a proponer mejoras en el **entorno** del agente de código para que las próximas ejecuciones salgan mejor.
|
|
11
|
+
|
|
12
|
+
## Pasos
|
|
13
|
+
|
|
14
|
+
1. Llama a la herramienta Skill con `writing-for-agents` para tener la guía de estilo.
|
|
15
|
+
|
|
16
|
+
2. Lee las fuentes primarias de la sesión que indique el usuario. Puede que tengas que buscar en los registros de sesión de esta máquina (en Claude Code, `~/.claude/projects/`). Si el usuario no indica ninguna, usa la sesión actual.
|
|
17
|
+
|
|
18
|
+
3. Busca candidatos a mejora en estas categorías:
|
|
19
|
+
|
|
20
|
+
- **Navegación**: ¿le costó al agente encontrar los ficheros correctos? ¿Hay dependencias ocultas entre ficheros? ¿Un **puntero de navegación** lo pondría más fácil? _Úsalo cuando_ la sesión tardó mucho en encontrar una información.
|
|
21
|
+
- **Comprobaciones automáticas**: ¿hay comprobaciones automáticas que pillarían los errores que cometió el agente? Linting, tipos, tests, linters del sistema de ficheros. Lee primero el comando de comprobación del propio repo (los scripts `lint`/`check` de su `package.json` o de su herramienta de build, su workflow de CI), para que el hallazgo sea una comprobación que ya existe pero está sin conectar o rota en silencio, y no una reinvención. Un repo sin ninguna **barrera** (ni hook de pre-commit ni job de CI que ejecute su lint/typecheck/test) es en sí un hallazgo: un repo sin lint es una oportunidad perdida permanente, no un punto de partida neutro. _Úsalo cuando_ el agente cometió un error que una comprobación automática habría pillado, o el repo no tiene ninguna barrera.
|
|
22
|
+
- **Estándares de código**: ¿hay que darle al **agente revisor** una regla nueva que haga cumplir? ¿Hay que quitar o aclarar una regla existente? Clasifica primero la infracción: una **mecánica** (un patrón sintáctico fijo, una API prohibida, una forma de import, una regla de ubicación de ficheros) lleva una comprobación determinista, sin más: una regla propia en el linter del repo, un hook de pre-commit nuevo o un job de CI nuevo, lo que salga más barato según el lenguaje y la barrera que ya tenga el repo. Por defecto, construye la comprobación antes que escribir la regla. Reserva `CODING_STANDARDS.md` para las **decisiones de criterio** de verdad (coherencia entre ficheros, "encaja con el estilo de alrededor", cualquier cosa que ninguna barrera pueda sustituir). _Úsalo cuando_ el agente revisor no pilló un error.
|
|
23
|
+
- **AGENTS.md / CLAUDE.md global**: ¿hay instrucciones de dirección que deberían pasar a los estándares de código (o a comprobaciones automáticas)? _Úsalo cuando_ el fichero es especialmente grande, en el repo O en el ámbito global del usuario.
|
|
24
|
+
- **Economía de herramientas**: ¿hizo el agente llamadas a herramientas caras que se podrían simplificar? ¿Hay alguna herramienta propia (CLIs, MCPs) que gaste muchos tokens? _Úsalo cuando_ el agente hizo una llamada cara.
|
|
25
|
+
- **Instrucciones sin efecto**: busca instrucciones en los ficheros de dirección que no cambian el comportamiento del agente. _Úsalo cuando_ los ficheros de dirección son grandes y difíciles de manejar.
|
|
26
|
+
- **Acceso a la información**: busca formas de darle al agente más acceso a la información. Volcar los logs del servidor de desarrollo, acceso de solo lectura a servicios de terceros. _Úsalo cuando_ el agente no tenía una información clave.
|
|
27
|
+
|
|
28
|
+
4. Presenta estos candidatos al usuario, ordenados por gravedad. Tú no aplicas nada: el usuario decide qué se cambia.
|
|
29
|
+
|
|
30
|
+
## Referencia
|
|
31
|
+
|
|
32
|
+
### Implementación frente a revisión
|
|
33
|
+
|
|
34
|
+
Recuerda que todo el trabajo pasa por dos fases: implementación y revisión. El agente que implementa es el que más **presión de contexto** tiene: se encarga de explorar, escribir el código y depurar los fallos.
|
|
35
|
+
|
|
36
|
+
El agente revisor es el que menos presión de contexto tiene: recibe un diff, así que no tiene que explorar. Muchas veces no necesita escribir código ni depurar.
|
|
37
|
+
|
|
38
|
+
Eso significa que el agente revisor debe ser el responsable de hacer cumplir los estándares de código, no el que implementa.
|
|
39
|
+
|
|
40
|
+
### Ficheros
|
|
41
|
+
|
|
42
|
+
Tienes acceso a varios ficheros en el repo:
|
|
43
|
+
|
|
44
|
+
- `CLAUDE.md`/`AGENTS.md`: estos ficheros entran en la ventana de contexto de cualquier agente que trabaje en el repo. Hay que usarlos con muchísima moderación, normalmente solo para **punteros de navegación** a otros ficheros.
|
|
45
|
+
- `CODING_STANDARDS.md`: este fichero se lee durante la revisión, no durante la implementación. Añade **punteros de navegación** a carpetas de docs si el fichero de estándares pasa de 1.000 líneas.
|
|
46
|
+
- Docs: usa los docs como ficheros de referencia, señalados desde otros ficheros. Busca docs existentes antes de escribir otros nuevos.
|
|
47
|
+
- Skills: usa skills para docs (porque su descripción entra en la ventana de contexto del agente) o para comandos que invoca el usuario. Sigue los consejos de la skill `writing-for-agents`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
skill: retro
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Haz una retrospectiva de esta sesión."
|
|
5
|
+
why: "Disparador directo de retro."
|
|
6
|
+
- prompt: "Revisa la conversación de ayer y dime qué falló en el entorno del agente."
|
|
7
|
+
why: "Disparador directo de retro: leer sesiones pasadas."
|
|
8
|
+
- prompt: "Run a retro on the last coding session."
|
|
9
|
+
why: "Disparador directo de retro."
|
|
10
|
+
- prompt: "¿Qué hooks o comprobaciones habrían evitado los errores de esta sesión?"
|
|
11
|
+
why: "Disparador directo de retro: comprobaciones automáticas."
|
|
12
|
+
- prompt: "Audita la sesión y propón mejoras para el CLAUDE.md y las herramientas."
|
|
13
|
+
why: "Disparador directo de retro."
|
|
14
|
+
|
|
15
|
+
should_not_trigger:
|
|
16
|
+
- prompt: "Revisa el código de esta rama."
|
|
17
|
+
route_to: "code-review"
|
|
18
|
+
why: "Revisar código es el trabajo de code-review, no de retro."
|
|
19
|
+
- prompt: "Resume la conversación para que otro agente siga."
|
|
20
|
+
route_to: "handoff"
|
|
21
|
+
why: "El traspaso de la sesión es el trabajo de handoff, no de retro."
|
|
22
|
+
- prompt: "Escribe una skill nueva para esto."
|
|
23
|
+
route_to: "writing-for-agents"
|
|
24
|
+
why: "Escribir documentos para agentes es el trabajo de writing-for-agents, no de retro."
|
|
25
|
+
- prompt: "Escribe el cuerpo de la PR de esta rama."
|
|
26
|
+
route_to: "pr"
|
|
27
|
+
why: "El cuerpo de la PR es el trabajo de pr, no de retro."
|
|
28
|
+
|
|
29
|
+
capability:
|
|
30
|
+
- scenario: "El usuario quiere saber qué cambiar en el entorno del agente tras una sesión."
|
|
31
|
+
must_include:
|
|
32
|
+
- "gravedad"
|
package/skills/suggest/SKILL.md
CHANGED
|
@@ -56,7 +56,7 @@ pairs with test-driven development and a verification pass before anything is ca
|
|
|
56
56
|
|
|
57
57
|
Exact skill names and order: `grill-with-docs` or `wayfinder` -> `superpowers:brainstorming` or
|
|
58
58
|
`to-spec` (and `write-adr` for decisions) -> `superpowers:writing-plans` ->
|
|
59
|
-
`superpowers:executing-plans` (
|
|
59
|
+
`superpowers:executing-plans` (big spec: `to-tickets` -> `implement-spec`) -> `code-review` -> `pr`.
|
|
60
60
|
On Claude Code this rule also arrives as a per-turn hook; the brevity here is deduplication,
|
|
61
61
|
not relaxation.
|
|
62
62
|
|
|
@@ -7,4 +7,4 @@ profiles: [core, ui, full]
|
|
|
7
7
|
origin: damiangil
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
Espera, no entiendo a dónde has llegado con esto. Vuelve a plantearlo: dame algo de contexto, habla en Inglés Técnico Simplificado ASD-STE100 (aplícalo igual en español: frases cortas, una idea por frase, vocabulario consistente), y usa el lenguaje ubicuo de `
|
|
10
|
+
Espera, no entiendo a dónde has llegado con esto. Vuelve a plantearlo: dame algo de contexto, habla en Inglés Técnico Simplificado ASD-STE100 (aplícalo igual en español: frases cortas, una idea por frase, vocabulario consistente), y usa el lenguaje ubicuo de `GLOSSARY.md` (sigue `GLOSSARY-MAP.md` hasta el correcto si el repo tiene más de uno).
|
package/targets/_md-block.js
CHANGED
|
@@ -21,7 +21,7 @@ export function writeSkill(id, fromDir, toPath) {
|
|
|
21
21
|
export function wireHook(paths, sourceMd, policy = {}) {
|
|
22
22
|
const full = stripFrontmatter(readFileSync(sourceMd, 'utf8'));
|
|
23
23
|
const body = policy.codeHooks === false
|
|
24
|
-
? `# rsc-suggest — always-on operations layer\n\nRead \`docs/wiki/harness/user-profile.md\` before acting. If the user wants to build, add or change something, route it through \`grill-with-docs\` or \`wayfinder\`, then write the spec with \`superpowers:brainstorming\` or \`to-spec\` (decisions go to \`write-adr\`) before any code, then build it with \`superpowers:writing-plans\` (or \`to-tickets\` then \`implement\`
|
|
24
|
+
? `# rsc-suggest — always-on operations layer\n\nRead \`docs/wiki/harness/user-profile.md\` before acting. If the user wants to build, add or change something, route it through \`grill-with-docs\` or \`wayfinder\`, then write the spec with \`superpowers:brainstorming\` or \`to-spec\` (decisions go to \`write-adr\`) before any code, then build it with \`superpowers:writing-plans\` (or \`to-tickets\` then \`implement-spec\` for a big spec or one that came out of \`wayfinder\`), and review it with \`code-review\` before merging, writing the PR body with \`pr\` (si toca pantalla, \`flujo-interfaz\` dice que skill de diseno manda) — unless it is a one-line change, typo, or config bump, which skips the chain. Use \`orient\` to keep the user situated and \`suggest\` to offer a missing skill only when the current task needs it. Close with the configured orientation block.\n`
|
|
25
25
|
: full;
|
|
26
26
|
const block = `${MARK_START}\n${body}\n${MARK_END}`;
|
|
27
27
|
let doc = existsSync(paths.hookTarget) ? readFileSync(paths.hookTarget, 'utf8') : '';
|
package/targets/hook-once.mjs
CHANGED
|
@@ -101,10 +101,12 @@ el que esta claro y el usuario ha dado el visto bueno.
|
|
|
101
101
|
Cada decision dificil de revertir se registra con \`write-adr\`, en docs/adr/.
|
|
102
102
|
2. Escribir la spec: \`to-spec\`, o \`superpowers:brainstorming\` para cerrarla por secciones.
|
|
103
103
|
Sin spec escrita no se programa.
|
|
104
|
-
3. Construir: \`superpowers:writing-plans\` -> \`superpowers:executing-plans\`.
|
|
105
|
-
salio de \`wayfinder\`
|
|
104
|
+
3. Construir: \`superpowers:writing-plans\` -> \`superpowers:executing-plans\`. Spec grande o que
|
|
105
|
+
salio de \`wayfinder\` -> \`to-tickets\` -> \`implement-spec\` (subagentes en paralelo sobre el
|
|
106
|
+
grafo de tickets); un solo ticket suelto -> \`implement\`.
|
|
106
107
|
Si la tarea toca pantalla, invoca ademas \`flujo-interfaz\`: dice que skill de diseno manda.
|
|
107
|
-
4. Antes de fusionar: \`code-review\` (estandares del repo + lo que pedia la spec)
|
|
108
|
+
4. Antes de fusionar: \`code-review\` (estandares del repo + lo que pedia la spec), y el cuerpo
|
|
109
|
+
de la PR con \`pr\` (resumen visual, evidencia antes/despues, peligro de fusion).
|
|
108
110
|
Siempre: \`superpowers:test-driven-development\` y \`superpowers:verification-before-completion\`
|
|
109
111
|
antes de dar nada por terminado. Los bugs entran por \`superpowers:systematic-debugging\`.
|
|
110
112
|
Cambio de una linea, typo o ajuste de configuracion -> hazlo y di que te saltas la cadena.
|
|
@@ -46,9 +46,10 @@ function cleanId(value, prefix = 'session') {
|
|
|
46
46
|
return `${prefix}-${hash}`;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function git(cwd, args) {
|
|
49
|
+
function git(cwd, args, input) {
|
|
50
50
|
try {
|
|
51
|
-
|
|
51
|
+
const stdin = input === undefined ? 'ignore' : 'pipe';
|
|
52
|
+
return { ok: true, out: execFileSync('git', args, { windowsHide: true, cwd, input, encoding: 'utf8', stdio: [stdin, 'pipe', 'ignore'], maxBuffer: 16 * 1024 * 1024 }).trim() };
|
|
52
53
|
} catch {
|
|
53
54
|
return { ok: false, out: '' };
|
|
54
55
|
}
|
|
@@ -162,7 +163,15 @@ function parseStatus(output) {
|
|
|
162
163
|
return files;
|
|
163
164
|
}
|
|
164
165
|
|
|
166
|
+
// One `git` for every file, not one per file. Spawning a process costs ~25 ms on Windows, and this
|
|
167
|
+
// runs on every hook event: a few hundred dirty files were enough to blow the 5 s hook timeout.
|
|
168
|
+
// `--stdin-paths` stops at the first path it cannot read (a deleted file), so on failure each file
|
|
169
|
+
// is hashed on its own, which keeps the old per-file `null` for the unreadable ones.
|
|
165
170
|
function fingerprintFiles(worktree, files) {
|
|
171
|
+
if (!files.length) return {};
|
|
172
|
+
const batch = git(worktree, ['hash-object', '--no-filters', '--stdin-paths'], `${files.join('\n')}\n`);
|
|
173
|
+
const hashes = batch.ok ? batch.out.split('\n') : [];
|
|
174
|
+
if (hashes.length === files.length) return Object.fromEntries(files.map((path, i) => [path, hashes[i]]));
|
|
166
175
|
return Object.fromEntries(files.map((path) => {
|
|
167
176
|
const result = git(worktree, ['hash-object', '--no-filters', '--', path]);
|
|
168
177
|
return [path, result.ok ? result.out : null];
|
|
@@ -305,7 +314,8 @@ export function capture(input = {}) {
|
|
|
305
314
|
const recordPath = join(store.root, 'sessions', `${storageId}.json`);
|
|
306
315
|
let anchor = readJson(anchorPath);
|
|
307
316
|
let existing = readJson(recordPath);
|
|
308
|
-
|
|
317
|
+
// The first snapshot only seeds a new anchor; an existing one already has its baseline.
|
|
318
|
+
const firstSnapshot = anchor ? null : snapshot(here, null);
|
|
309
319
|
if (!anchor) {
|
|
310
320
|
anchor = {
|
|
311
321
|
sessionId,
|
|
@@ -318,7 +328,11 @@ export function capture(input = {}) {
|
|
|
318
328
|
}
|
|
319
329
|
if (input.event === 'start' && !existing) return { record: null, path: null, notice: null, compactionHint: false };
|
|
320
330
|
|
|
321
|
-
|
|
331
|
+
// Against its own HEAD as baseline there is nothing committed to diff, so a fresh anchor's
|
|
332
|
+
// snapshot already is the repo state: reuse it instead of walking the tree a second time.
|
|
333
|
+
const repo = firstSnapshot && anchor.baselineHead === firstSnapshot.head
|
|
334
|
+
? firstSnapshot
|
|
335
|
+
: snapshot(here, anchor.baselineHead);
|
|
322
336
|
// Count what CHANGED, not which tool changed it. `editDelta` is +1 per Edit/Write tool event, and
|
|
323
337
|
// on its own it was blind to everything done through the shell — a heredoc, `sed -i`, a script, a
|
|
324
338
|
// formatter — which is how automated sessions work. The session that found this had touched dozens
|