@thebattlearena/corner 0.9.1-beta.70 → 0.10.1-beta.78

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.
Files changed (58) hide show
  1. package/README.md +46 -26
  2. package/package.json +1 -1
  3. package/plugin/.claude-plugin/plugin.json +1 -1
  4. package/ring/agents/cornerman.md +32 -6
  5. package/ring/agents/rudo.md +2 -1
  6. package/ring/agents/wrestler.md +19 -4
  7. package/ring/hooks/hooks.json +42 -0
  8. package/ring/scripts/bout-stats-render.mjs +366 -0
  9. package/ring/scripts/bout-stats.mjs +360 -0
  10. package/ring/scripts/brief-build.mjs +130 -0
  11. package/ring/scripts/brief-guard.mjs +154 -0
  12. package/ring/scripts/brief.mjs +272 -0
  13. package/ring/scripts/compact-hook.mjs +110 -0
  14. package/ring/scripts/config.mjs +25 -1
  15. package/ring/scripts/contract-endpoints.mjs +163 -0
  16. package/ring/scripts/contract-preview.mjs +34 -14
  17. package/ring/scripts/fight.mjs +27 -0
  18. package/ring/scripts/findings.mjs +82 -3
  19. package/ring/scripts/format-gate.mjs +723 -0
  20. package/ring/scripts/format-worker.mjs +120 -0
  21. package/ring/scripts/front-routes.mjs +345 -0
  22. package/ring/scripts/judges-card.mjs +324 -3
  23. package/ring/scripts/lookout.mjs +22 -4
  24. package/ring/scripts/mask-guard.mjs +34 -1
  25. package/ring/scripts/page-embed.mjs +112 -0
  26. package/ring/scripts/play-by-play.mjs +155 -7
  27. package/ring/scripts/preparation-collect.mjs +177 -0
  28. package/ring/scripts/preparation.mjs +547 -0
  29. package/ring/scripts/round-bell.mjs +9 -2
  30. package/ring/scripts/rule-ids.mjs +124 -0
  31. package/ring/scripts/tech-plan-log.mjs +81 -0
  32. package/ring/scripts/tech-plan.mjs +191 -0
  33. package/ring/scripts/verdicts-log.mjs +75 -0
  34. package/ring/scripts/verdicts.mjs +205 -0
  35. package/ring/skills/play-by-play/SKILL.md +235 -33
  36. package/ring/skills/play-by-play/templates/blocks.css +196 -0
  37. package/ring/skills/play-by-play/templates/chronicle.html +358 -55
  38. package/ring/skills/play-by-play/templates/endpoints-view.js +1153 -0
  39. package/ring/skills/play-by-play/templates/interview-form.js +516 -0
  40. package/ring/skills/play-by-play/templates/now-panel.js +719 -0
  41. package/ring/skills/referee/SKILL.md +181 -56
  42. package/ring/skills/referee/references/api-diagram.md +56 -0
  43. package/ring/skills/referee/references/precedents.md +11 -0
  44. package/ring/skills/referee/references/rulebook.md +97 -6
  45. package/ring/skills/referee/templates/api-diagram.html +115 -0
  46. package/ring/skills/referee/templates/cornerman-batch.md +17 -11
  47. package/ring/skills/referee/templates/cornerman-concept.md +28 -30
  48. package/ring/skills/referee/templates/cornerman-range.md +16 -11
  49. package/ring/skills/referee/templates/escalation.md +7 -1
  50. package/ring/skills/referee/templates/round-bell-body.md +4 -0
  51. package/ring/skills/referee/templates/wrestler-brief.md +28 -41
  52. package/ring/skills/referee/templates/wrestler-cutoff.md +4 -0
  53. package/ring/skills/referee/templates/wrestler-resume.md +4 -0
  54. package/ring/skills/sparring/SKILL.md +13 -4
  55. package/ring/skills/sparring/templates/contrato.md +29 -0
  56. package/ring/skills/sparring/templates/rudo-brief.md +7 -0
  57. package/ring/skills/title-defense/SKILL.md +2 -2
  58. package/ring/skills/weigh-in/SKILL.md +6 -0
package/README.md CHANGED
@@ -123,28 +123,28 @@ El detalle (esquema, íconos y colores válidos) está en «Monitores del repo»
123
123
  Con la fuente Battle Arena Icons instalada (la pone `install`), estos símbolos se dibujan con sus
124
124
  glifos; sin ella, con el carácter de la tabla.
125
125
 
126
- | Ícono | Dónde | Significa |
127
- | --- | --- | --- |
128
- | ✓ | punto, banda | entregado |
129
- | ↻ | punto, banda | en curso: tiene tiempo hoy |
130
- | ↷ | punto, banda | desplazado por un emergente |
131
- | ○ | punto, banda | por hacer: sin tiempo todavía |
132
- | ● | punto, en el cierre | avanzó pero no se entregó |
133
- | ⚠ | banda, riesgos | riesgo abierto; en una ficha, «va con avisos» |
134
- | ✗ | ficha | un paso falló |
135
- | ✎ | emergente, banda | falta responder el motivo |
136
- | ✋ | riesgo | levantar la mano: avisa a tu líder |
137
- | 👍 👎 | riesgo | si el aviso de riesgo acertó o no (ajusta la detección) |
138
- | 📅 | punto | reunión ligada |
139
- | 💡 | punto, complemento | tiempo en cabina |
140
- | 🧪 | punto, complemento | sesión de Tape |
141
- | ▸ ▾ ▴ | filas | desplegar, contraer, cerrar el detalle |
142
- | ↗ | ligas | abrir en la web |
143
- | ♪ ▶ ⏸ ▲ | radio | la canción, escuchar, dejar de escuchar, votar |
144
- | spinner | ring | alguien del combate está trabajando |
145
- | ■ (ámbar) | ring | te toca decidir |
146
- | 👊N (rojo) | ring | Copilot dejó N hilos |
147
- | ◣ | ficha de Copilot | en la esquina: Copilot está revisando |
126
+ | Ícono | Dónde | Significa |
127
+ | ---------- | ------------------- | ------------------------------------------------------- |
128
+ | ✓ | punto, banda | entregado |
129
+ | ↻ | punto, banda | en curso: tiene tiempo hoy |
130
+ | ↷ | punto, banda | desplazado por un emergente |
131
+ | ○ | punto, banda | por hacer: sin tiempo todavía |
132
+ | ● | punto, en el cierre | avanzó pero no se entregó |
133
+ | ⚠ | banda, riesgos | riesgo abierto; en una ficha, «va con avisos» |
134
+ | ✗ | ficha | un paso falló |
135
+ | ✎ | emergente, banda | falta responder el motivo |
136
+ | ✋ | riesgo | levantar la mano: avisa a tu líder |
137
+ | 👍 👎 | riesgo | si el aviso de riesgo acertó o no (ajusta la detección) |
138
+ | 📅 | punto | reunión ligada |
139
+ | 💡 | punto, complemento | tiempo en cabina |
140
+ | 🧪 | punto, complemento | sesión de Tape |
141
+ | ▸ ▾ ▴ | filas | desplegar, contraer, cerrar el detalle |
142
+ | ↗ | ligas | abrir en la web |
143
+ | ♪ ▶ ⏸ ▲ | radio | la canción, escuchar, dejar de escuchar, votar |
144
+ | spinner | ring | alguien del combate está trabajando |
145
+ | ■ (ámbar) | ring | te toca decidir |
146
+ | 👊N (rojo) | ring | Copilot dejó N hilos |
147
+ | ◣ | ficha de Copilot | en la esquina: Copilot está revisando |
148
148
 
149
149
  Las fichas del ring son el **árbitro**, el **luchador**, el **esquinero**, la **campana** (round-bell),
150
150
  **Copilot** y el **juez** (tú). Su borde dice el estado: gris quieta, azul trabajando, morada en la
@@ -167,8 +167,8 @@ Se invocan escribiendo el comando o pidiéndolo con tus palabras («arma mi plan
167
167
 
168
168
  ### Comandos
169
169
 
170
- | Comando | Para qué sirve |
171
- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
170
+ | Comando | Para qué sirve |
171
+ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
172
172
  | `/ringside` | Abre **Ringside**: la pelea de tu día junto al chat. Tu plan con el avance y el tiempo de cada punto contra lo comprometido (semáforo verde · amarillo · rojo), los emergentes (clic para ver su motivo), los riesgos siempre visibles con ✋ Levantar la mano y 👍/👎, y el pie con Plan · Reuniones · Fuera · Total. Pestaña **Semana** con tus hábitos. Sin datos, te dice el **siguiente paso** (instalar, armar el plan, entrar a la daily). `/scorecard`, su nombre anterior, lo sigue abriendo con un aviso. |
173
173
 
174
174
  Arriba del prompt sale además una **banda** compacta de Ringside (`LER-640 ✓ 1 ↻ 1 ↷ 1 ⚠ 1 Abrir`, cada contador con su color).
@@ -374,8 +374,28 @@ rama. El contrato para el proyecto está en `ring/skills/sparring/references/hos
374
374
  **Config del repo** (`.claude/ring.json`, opcional): `gates` (typecheck, tests por ruta con
375
375
  `{paths}`, lint), `validateCommand`, `rulebook` (por defecto el genérico del plugin),
376
376
  `protectedBranches`, `forbidAiTrailers` (por defecto `true`), `heavyCommands`, `delegation`,
377
- `precedents` y `monitors` (ver «Monitores del repo»). Sin el archivo, `ring` usa los gates que detecta en `package.json`, `pyproject.toml`,
378
- `go.mod` y el `Makefile`.
377
+ `precedents`, `monitors` (ver «Monitores del repo»), `briefGuard` (`warn`, `block` u `off`) y `agents` (modelo y esfuerzo por rol; por
378
+ defecto el luchador y el rudo en `sonnet` con esfuerzo `high` y el esquinero en `opus` con `high`,
379
+ p. ej. `"agents": { "wrestler": { "model": "opus" } }`). Sin el archivo, `ring` usa los gates que
380
+ detecta en `package.json`, `pyproject.toml`, `go.mod` y el `Makefile`.
381
+
382
+ **Briefs generados, no escritos**: el árbitro no le escribe a mano las instrucciones al luchador
383
+ ni al esquinero. `ring/scripts/brief.mjs` las arma desde los templates con el reglamento y los
384
+ precedentes embebidos completos (abriendo con un checklist de arquitectura: lo que más se escapa en
385
+ una revisión línea por línea), las decisiones que importan (todas las faltas, las de esos archivos
386
+ y las últimas 20) y los commits del rango; las sella y las registra en
387
+ `<combate>/briefs/index.jsonl`. El árbitro sólo pone sus valores (el encargo, las invariantes…).
388
+ Todo hallazgo de un esquinero o de una revisión tuya cita una regla del reglamento
389
+ (`<archivo:línea> — R11 — …`): `findings.mjs add` rechaza el que no la trae, y uno que ninguna regla
390
+ cubre lleva `X0` y queda como propuesta para el reglamento.
391
+ El árbitro lanza al luchador y al esquinero con `prompt: "ring-brief: <archivo>"`: el hook
392
+ `brief-guard` revisa el sello (generado por `brief.mjs`, sin editar, con las reglas de hoy, de este
393
+ combate y de ese rol), pone el texto del archivo como instrucción y el modelo y esfuerzo del rol.
394
+ Con `briefGuard: "warn"` (el default en `.claude/ring.json`) un brief que no cumple pasa y el árbitro
395
+ recibe el aviso; con `"block"` se rechaza con el comando que lo genera; `"off"` lo apaga. Cada
396
+ decisión queda en `<combate>/brief-guard.jsonl`. Y cuando la sesión del árbitro se compacta, el hook
397
+ `compact-hook` le devuelve (en menos de 10 000 caracteres) el combate, el checklist, sus faltas y el
398
+ «cómo reanudar» de la tarjeta.
379
399
 
380
400
  **Delegación y precedentes**: con `delegation: "referee"` (el default) el árbitro decide él mismo
381
401
  las dudas de diseño con el reglamento y los precedentes, anota por qué en `decisions.md` y sigue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thebattlearena/corner",
3
- "version": "0.9.1-beta.70",
3
+ "version": "0.10.1-beta.78",
4
4
  "description": "Corner: tu esquina de Battle Arena en Claude Code (el plugin `battlearena`). Hooks de tracking, objetivo del turno, plan de batalla /battlearena:conquer, Ringside (el panel de tu día), el ring y la radio. Zero-dependency.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "battlearena",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Corner, tu esquina de Battle Arena en Claude Code: tus sesiones al colector, el objetivo del turno, el plan de batalla /battlearena:conquer y Ringside, el panel de tu día junto al chat.",
5
5
  "author": {
6
6
  "name": "Battle Arena"
@@ -2,6 +2,7 @@
2
2
  name: cornerman
3
3
  description: The ring's read-only reviewer. Reviews a fixed commit range against the rulebook in one of three modes the referee names in its brief, range (≤15 lines of findings), concept (numbered behavior invariants, tests on a `git archive` copy) or batch (≤20 files through the lenses of the bout's venue). Never edits, commits or touches anyone's index. Launched by `/ring:referee` at high effort.
4
4
  tools: Read, Grep, Glob, Bash
5
+ model: opus
5
6
  effort: high
6
7
  ---
7
8
 
@@ -10,9 +11,14 @@ command that writes the index or the tree of someone else's worktree. You read w
10
11
  `git -C <worktree> log|show|diff <refs>` and with file reads. Your cwd resets between commands,
11
12
  so every git command carries `-C`.
12
13
 
13
- Your brief names the **mode**, the worktree, the base, the exact range, the rulebook path and the
14
- decisions file. The base is a remote ref (`origin/main`); if the brief names a bare branch, use
15
- its `origin/` ref, never the local branch, which may be behind. Read the rulebook and the decisions in full first. Review **only the lines the
14
+ Your brief names the **mode**, the worktree, the base and the exact range, and carries the
15
+ decisions and then the rules in full at its end (`brief.mjs` embeds them: the architecture
16
+ checklist first, then the rulebook and the precedents). If your prompt is only `ring-brief:
17
+ <path>`, read that file whole: it is your brief. The base is a remote ref (`origin/main`); if the
18
+ brief names a bare branch, use its `origin/` ref, never the local branch, which may be behind.
19
+ Read the rules and the decisions first, the checklist before anything: what slips past a
20
+ line-by-line review is there. **Every finding cites the rule it breaks in its second field**, or
21
+ `X0` when no rule covers it; the referee's ledger refuses a finding without one. Review **only the lines the
16
22
  range adds or changes**: no taste, no debt that was already there.
17
23
 
18
24
  The referee filters your report against the base before acting on it, so be exact: every finding
@@ -38,6 +44,15 @@ Per commit of the range (`git -C <wt> show <sha>`). Output, at most **15 lines**
38
44
 
39
45
  BLOCKERS first. A commit that complies gets "<sha>: no findings".
40
46
 
47
+ **Format, in every mode:** `node "<ring>/scripts/format-gate.mjs" check <wt> --range <A>..<B>`
48
+ (read-only: it formats a copy of each file of the range as it is at B and compares; never
49
+ `sort-imports --check`, which reports false positives). Each file in `unclean` is one finding:
50
+ `<file> — format — not as sort-imports + prettier leave it — the wrestler runs format-gate fix
51
+ --range <A>..<B> and commits the result`. **Exit 2 (`verified: false`) is NOT VERIFIED, never
52
+ clean:** sort-imports or prettier is not installed (`missing`), so the files in `files` were not
53
+ checked. Report it as its own line, `format — NO VERIFICADO — falta <missing> — <files>`, never as
54
+ "no findings".
55
+
41
56
  ## Mode: concept
42
57
 
43
58
  A deep review when a concept closes. The brief lists the commits with what each claims to do and a
@@ -71,12 +86,23 @@ bout's venue). For a `backend` bout they are these 8:
71
86
 
72
87
  1. Layer and dependency direction.
73
88
  2. Coupling.
74
- 3. Duplication, looking at both places.
89
+ 3. Duplication, looking at both places: the same condition in several files is a finding even
90
+ when each piece works (R11); repeated conditionals by type, state or provider come with the
91
+ pattern that removes them or the reason none is simpler (R22).
75
92
  4. Single responsibility and the rest of SOLID.
76
- 5. Domain model (rich or anemic, value objects, invariants where they belong).
93
+ 5. Domain model (rich or anemic, value objects, invariants where they belong): every new file
94
+ with its business sentence (R15), the backend shaped by the business and not by a screen
95
+ (R16), every optional with its reason (R17), aggregates born valid (R18), no primitives
96
+ crossing commands, events or ports (R19), no new endpoint an existing one covers (R20), names
97
+ that do not collide with another context (R21), no ternary or optional filling a gap that
98
+ should not exist (R23), types derived from their source (R24), provider responses through an
99
+ anti-corruption layer (R25), business metrics apart from monitoring (R26), a cross-cutting
100
+ precondition checked once (R27). A deviation from a pattern the host's rules fix is a BLOCKER
101
+ (P14).
77
102
  6. Errors: does it fail open or closed, who catches what.
78
103
  7. Expressiveness: names, more than 3 parameters, control booleans.
79
- 8. Production risk: concurrency, idempotency, volume, reversibility.
104
+ 8. Production risk: concurrency, idempotency, volume, reversibility, and a new infrastructure
105
+ resource counted against the provider's quota over the base (F13).
80
106
 
81
107
  Return per file the findings with rule and precedent ids, then the **open design questions**,
82
108
  each with two options, their cost and your recommendation, numbered so they can be answered as
@@ -2,7 +2,8 @@
2
2
  name: rudo
3
3
  description: The ring's sparring executor. Builds a quick, deliberately low-quality draft of a feature in its own worktree, only to prove whether it is worth building; never merged. Launched and directed by the ring referee from `/ring:sparring`; takes every doubt to the referee (never to the human), works inside a timebox and lists every shortcut it took. Suspends the style and test rules, never the live-operation ones.
4
4
  tools: Read, Grep, Glob, Edit, Write, Bash
5
- effort: medium
5
+ model: sonnet
6
+ effort: high
6
7
  ---
7
8
 
8
9
  You are the rudo: in lucha libre the rudo wins however he can, the técnico wins clean. You are
@@ -2,7 +2,8 @@
2
2
  name: wrestler
3
3
  description: The ring's executor. Applies a refactor or a correction package in its own worktree, one concept at a time, without changing behavior, with the host repo's gates and small thematic commits. Launched and directed by the ring referee (`/ring:referee`); receives rebounds by message, takes every doubt to the referee (never to the human) and never decides design or scope on its own. Does not review its own work with reviewers and does not open ready PRs.
4
4
  tools: Read, Grep, Glob, Edit, Write, Bash
5
- effort: medium
5
+ model: sonnet
6
+ effort: high
6
7
  ---
7
8
 
8
9
  You write code; someone else reviews it. Your job is to leave each concept small, clean and with
@@ -11,11 +12,14 @@ decided is not debated: it is applied.
11
12
 
12
13
  ## Sources
13
14
 
14
- - Your brief: the assignment, the worktree, the branch, the base, the order of concepts, the
15
+ - Your brief (if your prompt is only `ring-brief: <path>`, read that file whole: it is your
16
+ brief): the assignment, the worktree, the branch, the base, the order of concepts, the
15
17
  frozen zones, the decisions already taken, what waits on the human, and the absolute path of the
16
18
  ring scripts (`<ring>/scripts`).
17
- - The rulebook and the precedents the brief names, read in full. Rules are cited by number (R, T,
18
- F, P), precedents by id (PRn bundled, HPn the host's).
19
+ - The rules, embedded in full at the end of your brief by `brief.mjs`: the architecture checklist
20
+ first, then the rulebook and the precedents. They are the ones in force; apply them while you
21
+ write and check the checklist before every commit. Rules are cited by number (R, T, F, P),
22
+ precedents by id (PRn bundled, HPn the host's).
19
23
  - Every doubt goes to the referee in your report, never to the human: the referee decides it or
20
24
  escalates it.
21
25
  - The host repo's own instructions (`AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md` if present).
@@ -80,6 +84,17 @@ edit after approval needs a new one.
80
84
  staged, run the gates on a copy of the index under `<bout dir>/tools/`
81
85
  (`git checkout-index -a --prefix=<bout dir>/tools/staged/`), never by stashing the rest: the
82
86
  stash is shared by every worktree on the machine, and `stash@{0}` may be another session's.
87
+ **Then the format gate, always, last before staging:**
88
+ `node "<ring>/scripts/format-gate.mjs" fix <worktree>` (sort-imports with the repo's tsconfig,
89
+ then prettier, on the changed files; the repo's own `fix:changed` when it has one). Ring also
90
+ formats every file you edit or write from the shell while the bout is active, but a commit
91
+ never relies on that: run `fix` and stage what it left. If it says the binaries are not
92
+ installed, install the dependencies in your worktree or tell the referee; never commit without
93
+ it.
94
+ When a rebound says files already committed are not formatted, in this order: run
95
+ `format-gate.mjs fix <worktree> --range <base>..HEAD`, commit what it changed, and only then
96
+ `format-gate.mjs check <worktree> --range <base>..HEAD`. A check before that commit still
97
+ exits 1: it reads the range as committed, not the worktree.
83
98
  5. Commits: stage by explicit paths (never `git add -A` or `.`), a conventional message that says
84
99
  the business reason, in plain words, in the language of the branch's previous commits (read
85
100
  `git log` once before the first commit and keep it for the whole bout): never bout ids (D12, P7,
@@ -10,6 +10,16 @@
10
10
  }
11
11
  ]
12
12
  },
13
+ {
14
+ "matcher": "Agent|Task",
15
+ "hooks": [
16
+ {
17
+ "type": "command",
18
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/brief-guard.mjs\"",
19
+ "timeout": 10
20
+ }
21
+ ]
22
+ },
13
23
  {
14
24
  "matcher": "Agent|Task|AskUserQuestion|Bash",
15
25
  "hooks": [
@@ -22,6 +32,26 @@
22
32
  }
23
33
  ],
24
34
  "PostToolUse": [
35
+ {
36
+ "matcher": "Edit|Write|MultiEdit",
37
+ "hooks": [
38
+ {
39
+ "type": "command",
40
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/format-gate.mjs\" edit-hook",
41
+ "timeout": 30
42
+ }
43
+ ]
44
+ },
45
+ {
46
+ "matcher": "Bash",
47
+ "hooks": [
48
+ {
49
+ "type": "command",
50
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/format-gate.mjs\" shell-hook",
51
+ "timeout": 60
52
+ }
53
+ ]
54
+ },
25
55
  {
26
56
  "matcher": "Agent|Task|AskUserQuestion|Bash",
27
57
  "hooks": [
@@ -77,6 +107,18 @@
77
107
  }
78
108
  ]
79
109
  }
110
+ ],
111
+ "SessionStart": [
112
+ {
113
+ "matcher": "compact",
114
+ "hooks": [
115
+ {
116
+ "type": "command",
117
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/compact-hook.mjs\"",
118
+ "timeout": 10
119
+ }
120
+ ]
121
+ }
80
122
  ]
81
123
  }
82
124
  }