@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 CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![npm](https://img.shields.io/npm/v/@damiangilgonzalez/harness?color=63d68a&labelColor=12161c&label=npm)](https://www.npmjs.com/package/@damiangilgonzalez/harness)
10
10
  [![downloads](https://img.shields.io/npm/dm/@damiangilgonzalez/harness?color=63d68a&labelColor=12161c&label=downloads)](https://www.npmjs.com/package/@damiangilgonzalez/harness)
11
- [![skills](https://img.shields.io/badge/skills-291-63d68a?labelColor=12161c)](#the-catalog)
11
+ [![skills](https://img.shields.io/badge/skills-294-63d68a?labelColor=12161c)](#the-catalog)
12
12
  [![license](https://img.shields.io/badge/license-MIT-63d68a?labelColor=12161c)](LICENSE)
13
13
  [![stars](https://img.shields.io/github/stars/ericrisco/rsc-harness?color=63d68a&labelColor=12161c)](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
- 291 skills · one CLI · zero bloat
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 291 skills)
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
- 291 skills, grouped by what you're trying to do. Click any skill to read its
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 one ticket from `to-tickets`. Ordinary work runs `superpowers:executing-plans` instead. |
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.14",
2
+ "version": "1.3.16",
3
3
  "counts": {
4
- "skills": 291,
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 refine the project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to keep the domain model up to date.",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damiangilgonzalez/harness",
3
- "version": "1.3.14",
3
+ "version": "1.3.16",
4
4
  "description": "A guided harness builder that turns your goal into a minimal, verified AI-agent setup using strict best practices.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
- const declared = declaredRaw.length ? withDefaultSkillFloor(declaredRaw) : declaredRaw;
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
+ }
@@ -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 CONTEXT.md
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 `CONTEXT.md` en la raíz del repo.
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 `CONTEXT-MAP.md` en la raíz lista los contextos, dónde viven y cómo se relacionan entre sí:
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/CONTEXT.md) — recibe y rastrea los pedidos de clientes
44
- - [Billing](./src/billing/CONTEXT.md) — genera facturas y procesa pagos
45
- - [Fulfillment](./src/fulfillment/CONTEXT.md) — gestiona el picking y el envío en el almacén
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 `CONTEXT-MAP.md`, léelo para encontrar los contextos
57
- - Si solo existe un `CONTEXT.md` en la raíz, es contexto único
58
- - Si no existe ninguno, crea un `CONTEXT.md` en la raíz de forma perezosa cuando se resuelva el primer término
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 refine the project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to keep the domain model up to date."
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* `CONTEXT.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.)
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
- ├── CONTEXT.md
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 `CONTEXT-MAP.md` en la raíz, el repo tiene varios contextos. El mapa indica dónde vive cada uno:
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
- ├── CONTEXT-MAP.md
31
+ ├── GLOSSARY-MAP.md
32
32
  ├── docs/
33
33
  │ └── adr/ ← decisiones de todo el sistema
34
34
  ├── src/
35
35
  │ ├── ordering/
36
- │ │ ├── CONTEXT.md
36
+ │ │ ├── GLOSSARY.md
37
37
  │ │ └── docs/adr/ ← decisiones específicas del contexto
38
38
  │ └── billing/
39
- │ ├── CONTEXT.md
39
+ │ ├── GLOSSARY.md
40
40
  │ └── docs/adr/
41
41
  ```
42
42
 
43
- Crea los ficheros de forma perezosa: solo cuando tengas algo que escribir. Si no existe `CONTEXT.md`, créalo cuando se resuelva el primer término. Si no existe `docs/adr/`, créalo cuando haga falta el primer ADR.
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 `CONTEXT.md`, señálalo de inmediato. "Tu glosario define 'cancelación' como X, pero parece que te refieres a Y — ¿cuál es?"
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 CONTEXT.md sobre la marcha
65
+ ### Actualiza GLOSSARY.md sobre la marcha
64
66
 
65
- Cuando un término quede resuelto, actualiza `CONTEXT.md` ahí mismo. No los acumules — captúralos según ocurren. Usa el formato de [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md).
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
- `CONTEXT.md` debe estar totalmente libre de detalles de implementación. No trates `CONTEXT.md` como una especificación, un borrador, ni un repositorio de decisiones de implementación. Es un glosario y nada más.
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"
@@ -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` (after `wayfinder`: `to-tickets` -> `implement`) -> `code-review`.
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 `CONTEXT.md` (sigue `CONTEXT-MAP.md` hasta el correcto si el repo tiene más de uno).
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).
@@ -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\` when it came out of \`wayfinder\`), and review it with \`code-review\` before merging (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`
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') : '';
@@ -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\`. Solo el trabajo que
105
- salio de \`wayfinder\` va con \`to-tickets\` -> \`implement\`, ticket a ticket.
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
- return { ok: true, out: execFileSync('git', args, { windowsHide: true, cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], maxBuffer: 2 * 1024 * 1024 }).trim() };
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
- const firstSnapshot = snapshot(here, null);
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
- const repo = snapshot(here, anchor.baselineHead);
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