@alisio/plugin-swarm 0.0.0-stage → 0.1.1

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 (266) hide show
  1. package/.agents/agents/swarm-architect.md +20 -0
  2. package/.agents/agents/swarm-cleaner.md +20 -0
  3. package/.agents/agents/swarm-coder.md +20 -0
  4. package/.agents/agents/swarm-hardener.md +20 -0
  5. package/.agents/agents/swarm-lieutenant.md +20 -0
  6. package/.agents/agents/swarm-qa.md +20 -0
  7. package/.agents/agents/swarm-refactorer.md +20 -0
  8. package/.agents/agents/swarm-specifier.md +20 -0
  9. package/.agents/skills/swarm-architecture-rules/SKILL.md +43 -0
  10. package/.agents/skills/swarm-clarification/SKILL.md +42 -0
  11. package/.agents/skills/swarm-cleaner-metrics/SKILL.md +44 -0
  12. package/.agents/skills/swarm-engineering-constitution/SKILL.md +44 -0
  13. package/.agents/skills/swarm-gherkin-spec/SKILL.md +43 -0
  14. package/.agents/skills/swarm-handoff-protocol/SKILL.md +45 -0
  15. package/.agents/skills/swarm-lieutenant/SKILL.md +41 -0
  16. package/.agents/skills/swarm-mutation-hardening/SKILL.md +43 -0
  17. package/.agents/skills/swarm-qa-acceptance/SKILL.md +42 -0
  18. package/.agents/skills/swarm-tdd-slice/SKILL.md +44 -0
  19. package/.agents/skills/swarm-toolchain-profile/SKILL.md +41 -0
  20. package/LICENSE +21 -0
  21. package/README.es.md +337 -0
  22. package/README.md +322 -2
  23. package/assets/approval-flow.svg +1 -0
  24. package/assets/architecture.svg +1 -0
  25. package/assets/audit-states.svg +1 -0
  26. package/assets/dashboard.css +964 -0
  27. package/assets/dashboard.html +123 -0
  28. package/assets/dashboard.js +965 -0
  29. package/assets/dashboard.svg +1 -0
  30. package/assets/handoff-sequence.svg +1 -0
  31. package/assets/pack-pipelines.svg +1 -0
  32. package/assets/packs/four-pack/pack.json +18 -0
  33. package/assets/packs/six-pack/pack.json +22 -0
  34. package/assets/packs/two-pack/pack.json +14 -0
  35. package/assets/screenshots/dashboard-board-dark.png +0 -0
  36. package/assets/screenshots/dashboard-board-light.png +0 -0
  37. package/assets/screenshots/dashboard-documents-diff.png +0 -0
  38. package/assets/screenshots/dashboard-empty-state.png +0 -0
  39. package/assets/screenshots/dashboard-phone.png +0 -0
  40. package/assets/screenshots/dashboard-reject-dialog.png +0 -0
  41. package/assets/screenshots/dashboard-transcript-tail.png +0 -0
  42. package/assets/screenshots/dashboard-work-queue.png +0 -0
  43. package/assets/task-states.svg +1 -0
  44. package/assets/toolchains/node-ts.json +61 -0
  45. package/cover.svg +46 -0
  46. package/dist/adapters/child-session-runner.d.ts +36 -0
  47. package/dist/adapters/child-session-runner.d.ts.map +1 -0
  48. package/dist/adapters/child-session-runner.js +156 -0
  49. package/dist/adapters/child-session-runner.js.map +1 -0
  50. package/dist/adapters/fs-board-store.d.ts +11 -0
  51. package/dist/adapters/fs-board-store.d.ts.map +1 -0
  52. package/dist/adapters/fs-board-store.js +27 -0
  53. package/dist/adapters/fs-board-store.js.map +1 -0
  54. package/dist/adapters/fs-handoff-store.d.ts +36 -0
  55. package/dist/adapters/fs-handoff-store.d.ts.map +1 -0
  56. package/dist/adapters/fs-handoff-store.js +254 -0
  57. package/dist/adapters/fs-handoff-store.js.map +1 -0
  58. package/dist/adapters/fs-task-state-store.d.ts +16 -0
  59. package/dist/adapters/fs-task-state-store.d.ts.map +1 -0
  60. package/dist/adapters/fs-task-state-store.js +66 -0
  61. package/dist/adapters/fs-task-state-store.js.map +1 -0
  62. package/dist/adapters/git-worktree.d.ts +31 -0
  63. package/dist/adapters/git-worktree.d.ts.map +1 -0
  64. package/dist/adapters/git-worktree.js +209 -0
  65. package/dist/adapters/git-worktree.js.map +1 -0
  66. package/dist/adapters/process-exec.d.ts +36 -0
  67. package/dist/adapters/process-exec.d.ts.map +1 -0
  68. package/dist/adapters/process-exec.js +138 -0
  69. package/dist/adapters/process-exec.js.map +1 -0
  70. package/dist/adapters/process-gate-runner.d.ts +39 -0
  71. package/dist/adapters/process-gate-runner.d.ts.map +1 -0
  72. package/dist/adapters/process-gate-runner.js +242 -0
  73. package/dist/adapters/process-gate-runner.js.map +1 -0
  74. package/dist/adapters/unavailable-runner.d.ts +4 -0
  75. package/dist/adapters/unavailable-runner.d.ts.map +1 -0
  76. package/dist/adapters/unavailable-runner.js +12 -0
  77. package/dist/adapters/unavailable-runner.js.map +1 -0
  78. package/dist/app/audit.d.ts +23 -0
  79. package/dist/app/audit.d.ts.map +1 -0
  80. package/dist/app/audit.js +9 -0
  81. package/dist/app/audit.js.map +1 -0
  82. package/dist/app/budget.d.ts +29 -0
  83. package/dist/app/budget.d.ts.map +1 -0
  84. package/dist/app/budget.js +78 -0
  85. package/dist/app/budget.js.map +1 -0
  86. package/dist/app/chat-store.d.ts +18 -0
  87. package/dist/app/chat-store.d.ts.map +1 -0
  88. package/dist/app/chat-store.js +48 -0
  89. package/dist/app/chat-store.js.map +1 -0
  90. package/dist/app/documents.d.ts +33 -0
  91. package/dist/app/documents.d.ts.map +1 -0
  92. package/dist/app/documents.js +63 -0
  93. package/dist/app/documents.js.map +1 -0
  94. package/dist/app/forge.d.ts +106 -0
  95. package/dist/app/forge.d.ts.map +1 -0
  96. package/dist/app/forge.js +420 -0
  97. package/dist/app/forge.js.map +1 -0
  98. package/dist/app/operator.d.ts +46 -0
  99. package/dist/app/operator.d.ts.map +1 -0
  100. package/dist/app/operator.js +168 -0
  101. package/dist/app/operator.js.map +1 -0
  102. package/dist/app/pidfile.d.ts +18 -0
  103. package/dist/app/pidfile.d.ts.map +1 -0
  104. package/dist/app/pidfile.js +56 -0
  105. package/dist/app/pidfile.js.map +1 -0
  106. package/dist/app/project.d.ts +93 -0
  107. package/dist/app/project.d.ts.map +1 -0
  108. package/dist/app/project.js +291 -0
  109. package/dist/app/project.js.map +1 -0
  110. package/dist/app/prompts.d.ts +48 -0
  111. package/dist/app/prompts.d.ts.map +1 -0
  112. package/dist/app/prompts.js +88 -0
  113. package/dist/app/prompts.js.map +1 -0
  114. package/dist/app/pump.d.ts +144 -0
  115. package/dist/app/pump.d.ts.map +1 -0
  116. package/dist/app/pump.js +707 -0
  117. package/dist/app/pump.js.map +1 -0
  118. package/dist/app/services.d.ts +112 -0
  119. package/dist/app/services.d.ts.map +1 -0
  120. package/dist/app/services.js +323 -0
  121. package/dist/app/services.js.map +1 -0
  122. package/dist/app/state.d.ts +70 -0
  123. package/dist/app/state.d.ts.map +1 -0
  124. package/dist/app/state.js +96 -0
  125. package/dist/app/state.js.map +1 -0
  126. package/dist/args.d.ts +10 -0
  127. package/dist/args.d.ts.map +1 -0
  128. package/dist/args.js +33 -0
  129. package/dist/args.js.map +1 -0
  130. package/dist/coordinator.d.ts +80 -0
  131. package/dist/coordinator.d.ts.map +1 -0
  132. package/dist/coordinator.js +481 -0
  133. package/dist/coordinator.js.map +1 -0
  134. package/dist/dashboard/api.d.ts +28 -0
  135. package/dist/dashboard/api.d.ts.map +1 -0
  136. package/dist/dashboard/api.js +178 -0
  137. package/dist/dashboard/api.js.map +1 -0
  138. package/dist/dashboard/auth.d.ts +13 -0
  139. package/dist/dashboard/auth.d.ts.map +1 -0
  140. package/dist/dashboard/auth.js +36 -0
  141. package/dist/dashboard/auth.js.map +1 -0
  142. package/dist/dashboard/open.d.ts +7 -0
  143. package/dist/dashboard/open.d.ts.map +1 -0
  144. package/dist/dashboard/open.js +17 -0
  145. package/dist/dashboard/open.js.map +1 -0
  146. package/dist/dashboard/server.d.ts +28 -0
  147. package/dist/dashboard/server.d.ts.map +1 -0
  148. package/dist/dashboard/server.js +176 -0
  149. package/dist/dashboard/server.js.map +1 -0
  150. package/dist/doctor.d.ts +28 -0
  151. package/dist/doctor.d.ts.map +1 -0
  152. package/dist/doctor.js +108 -0
  153. package/dist/doctor.js.map +1 -0
  154. package/dist/domain/attention.d.ts +20 -0
  155. package/dist/domain/attention.d.ts.map +1 -0
  156. package/dist/domain/attention.js +41 -0
  157. package/dist/domain/attention.js.map +1 -0
  158. package/dist/domain/envelope.d.ts +37 -0
  159. package/dist/domain/envelope.d.ts.map +1 -0
  160. package/dist/domain/envelope.js +106 -0
  161. package/dist/domain/envelope.js.map +1 -0
  162. package/dist/domain/handoff.d.ts +57 -0
  163. package/dist/domain/handoff.d.ts.map +1 -0
  164. package/dist/domain/handoff.js +191 -0
  165. package/dist/domain/handoff.js.map +1 -0
  166. package/dist/domain/identifiers.d.ts +18 -0
  167. package/dist/domain/identifiers.d.ts.map +1 -0
  168. package/dist/domain/identifiers.js +70 -0
  169. package/dist/domain/identifiers.js.map +1 -0
  170. package/dist/domain/pack.d.ts +45 -0
  171. package/dist/domain/pack.d.ts.map +1 -0
  172. package/dist/domain/pack.js +207 -0
  173. package/dist/domain/pack.js.map +1 -0
  174. package/dist/domain/pipeline.d.ts +33 -0
  175. package/dist/domain/pipeline.d.ts.map +1 -0
  176. package/dist/domain/pipeline.js +50 -0
  177. package/dist/domain/pipeline.js.map +1 -0
  178. package/dist/domain/task.d.ts +26 -0
  179. package/dist/domain/task.d.ts.map +1 -0
  180. package/dist/domain/task.js +154 -0
  181. package/dist/domain/task.js.map +1 -0
  182. package/dist/domain/taskstate.d.ts +37 -0
  183. package/dist/domain/taskstate.d.ts.map +1 -0
  184. package/dist/domain/taskstate.js +98 -0
  185. package/dist/domain/taskstate.js.map +1 -0
  186. package/dist/gates/dry.d.ts +14 -0
  187. package/dist/gates/dry.d.ts.map +1 -0
  188. package/dist/gates/dry.js +71 -0
  189. package/dist/gates/dry.js.map +1 -0
  190. package/dist/gates/parsers.d.ts +34 -0
  191. package/dist/gates/parsers.d.ts.map +1 -0
  192. package/dist/gates/parsers.js +120 -0
  193. package/dist/gates/parsers.js.map +1 -0
  194. package/dist/index.d.ts +45 -0
  195. package/dist/index.d.ts.map +1 -0
  196. package/dist/index.js +207 -0
  197. package/dist/index.js.map +1 -0
  198. package/dist/options.d.ts +13 -0
  199. package/dist/options.d.ts.map +1 -0
  200. package/dist/options.js +27 -0
  201. package/dist/options.js.map +1 -0
  202. package/dist/panel.d.ts +5 -0
  203. package/dist/panel.d.ts.map +1 -0
  204. package/dist/panel.js +52 -0
  205. package/dist/panel.js.map +1 -0
  206. package/dist/ports/agent-runner.d.ts +51 -0
  207. package/dist/ports/agent-runner.d.ts.map +1 -0
  208. package/dist/ports/agent-runner.js +2 -0
  209. package/dist/ports/agent-runner.js.map +1 -0
  210. package/dist/ports/board-store.d.ts +7 -0
  211. package/dist/ports/board-store.d.ts.map +1 -0
  212. package/dist/ports/board-store.js +2 -0
  213. package/dist/ports/board-store.js.map +1 -0
  214. package/dist/ports/clock.d.ts +5 -0
  215. package/dist/ports/clock.d.ts.map +1 -0
  216. package/dist/ports/clock.js +2 -0
  217. package/dist/ports/clock.js.map +1 -0
  218. package/dist/ports/gate-runner.d.ts +34 -0
  219. package/dist/ports/gate-runner.d.ts.map +1 -0
  220. package/dist/ports/gate-runner.js +2 -0
  221. package/dist/ports/gate-runner.js.map +1 -0
  222. package/dist/ports/handoff-store.d.ts +39 -0
  223. package/dist/ports/handoff-store.d.ts.map +1 -0
  224. package/dist/ports/handoff-store.js +2 -0
  225. package/dist/ports/handoff-store.js.map +1 -0
  226. package/dist/ports/isolation.d.ts +43 -0
  227. package/dist/ports/isolation.d.ts.map +1 -0
  228. package/dist/ports/isolation.js +2 -0
  229. package/dist/ports/isolation.js.map +1 -0
  230. package/dist/ports/notifier.d.ts +28 -0
  231. package/dist/ports/notifier.d.ts.map +1 -0
  232. package/dist/ports/notifier.js +2 -0
  233. package/dist/ports/notifier.js.map +1 -0
  234. package/dist/ports/task-state-store.d.ts +10 -0
  235. package/dist/ports/task-state-store.d.ts.map +1 -0
  236. package/dist/ports/task-state-store.js +2 -0
  237. package/dist/ports/task-state-store.js.map +1 -0
  238. package/dist/refs.d.ts +10 -0
  239. package/dist/refs.d.ts.map +1 -0
  240. package/dist/refs.js +19 -0
  241. package/dist/refs.js.map +1 -0
  242. package/dist/resources.d.ts +55 -0
  243. package/dist/resources.d.ts.map +1 -0
  244. package/dist/resources.js +255 -0
  245. package/dist/resources.js.map +1 -0
  246. package/dist/status.d.ts +18 -0
  247. package/dist/status.d.ts.map +1 -0
  248. package/dist/status.js +60 -0
  249. package/dist/status.js.map +1 -0
  250. package/dist/storage.d.ts +18 -0
  251. package/dist/storage.d.ts.map +1 -0
  252. package/dist/storage.js +79 -0
  253. package/dist/storage.js.map +1 -0
  254. package/dist/toolchains/profile.d.ts +21 -0
  255. package/dist/toolchains/profile.d.ts.map +1 -0
  256. package/dist/toolchains/profile.js +60 -0
  257. package/dist/toolchains/profile.js.map +1 -0
  258. package/dist/toolchains/thresholds.d.ts +29 -0
  259. package/dist/toolchains/thresholds.d.ts.map +1 -0
  260. package/dist/toolchains/thresholds.js +45 -0
  261. package/dist/toolchains/thresholds.js.map +1 -0
  262. package/dist/version.d.ts +2 -0
  263. package/dist/version.d.ts.map +1 -0
  264. package/dist/version.js +3 -0
  265. package/dist/version.js.map +1 -0
  266. package/package.json +51 -3
package/README.es.md ADDED
@@ -0,0 +1,337 @@
1
+ # @alisio/plugin-swarm
2
+
3
+ ![Swarm](./cover.svg)
4
+
5
+ > English: [README.md](./README.md). Ambos README deben actualizarse en conjunto.
6
+
7
+ Swarm para Alisio ejecuta una cadena de agentes especializados. Cada agente trabaja en su propio
8
+ worktree de git y entrega el trabajo confirmado al siguiente mediante archivos de traspaso duraderos.
9
+ El código determinista controla el enrutamiento, el estado y las compuertas de calidad; los agentes
10
+ solo devuelven sobres JSON estrictos que el código valida.
11
+
12
+ > **Estado: versión preliminar.** Todo lo descrito está implementado y probado con simulaciones,
13
+ > incluido el panel local. El ejecutor de sesiones hijas de Alisio, la ejecución en segundo plano y el
14
+ > panel aún no se han probado contra un host real de Alisio; consulta «Uso real».
15
+
16
+ ## Arquitectura
17
+
18
+ ![Arquitectura de Swarm: los frentes llaman a una capa de servicios sobre puertos y adaptadores](./assets/architecture.svg)
19
+
20
+ Los comandos, las herramientas, el panel y el árbol TUI son frentes delgados sobre una única capa de
21
+ servicios, que maneja el dominio puro mediante puertos (ejecutor de agentes, aislamiento, almacenes y
22
+ ejecutor de compuertas).
23
+
24
+ ## Requisitos
25
+
26
+ - Node.js 22.16 o superior y `@alisio/sdk` de 0.3 a 0.6.
27
+ - `git` 2.28 o superior en el `PATH`. Ejecuta `/swarm:doctor` para comprobarlo.
28
+ - No requiere credenciales ni acceso a la red, salvo al clonar un repositorio de GitHub.
29
+
30
+ ## Instalación
31
+
32
+ ```sh
33
+ alisio install npm:@alisio/plugin-swarm
34
+ ```
35
+
36
+ ## Inicio rápido
37
+
38
+ ```text
39
+ /swarm:init
40
+ /swarm:doctor
41
+ /swarm:pack list
42
+ /swarm:project new demo --pack two-pack -- Una aplicación pequeña de tareas
43
+ /swarm:task demo new -- Añadir un formulario para crear tareas
44
+ /swarm:status
45
+ /swarm:dashboard
46
+ ```
47
+
48
+ ## Comandos
49
+
50
+ | Comando | Propósito |
51
+ | --- | --- |
52
+ | `/swarm:init` | Crea la fragua bajo `.alisio/swarm` en el espacio de trabajo. |
53
+ | `/swarm:doctor` | Comprueba Node.js, git, los comandos de la cadena de herramientas y el espacio de trabajo. |
54
+ | `/swarm:pack list` / `show <nombre>` | Lista los paquetes incluidos y los del espacio de trabajo, o muestra uno. |
55
+ | `/swarm:project new <nombre> [--pack <p>] [--github <owner/repo>] -- <misión>` | Crea y abre un proyecto. |
56
+ | `/swarm:project open <nombre>` / `close <nombre>` / `list` | Abre, cierra o lista proyectos. Cerrar nunca modifica los archivos del proyecto. |
57
+ | `/swarm:task <proyecto> new [nombre] -- <texto>` | Crea una tarjeta de tarea y la encola para el primer rol. |
58
+ | `/swarm:task <proyecto> retry <nombre>` / `delete <nombre>` / `accept <nombre>` | Reintenta una tarea atascada, la archiva y elimina, o acepta su trabajo tal cual. |
59
+ | `/swarm:status [proyecto]` | Muestra carriles, tareas y elementos que requieren tu atención. |
60
+ | `/swarm:approve <proyecto>/<tarea>` | Aprueba el traspaso retenido en la compuerta de aprobación. Queda deshabilitado mientras existan comentarios sobre documentos. |
61
+ | `/swarm:reject <proyecto>/<tarea> retry\|delete\|accept [-- comentarios]` | Reintentar (el commit rechazado se conserva en `refs/swarm/rejected/<tarea>`, se restaura la base y el rol se ejecuta de nuevo con tus observaciones), eliminar o aceptar sin cambios. |
62
+ | `/swarm:comment <proyecto>/<tarea> <documento> -- <texto>` / `<proyecto>/<tarea> clear` | Comenta un documento de una tarea pendiente de aprobación, o borra los comentarios. |
63
+ | `/swarm:answer <proyecto>/<tarea> -- <texto>` | Responde a una pregunta de aclaración de un rol. |
64
+ | `/swarm:chat [proyecto] -- <mensaje>` | Conversa con el Lieutenant de un proyecto (solo lectura). |
65
+ | `/swarm:stop <proyecto>` | Cancela los agentes del proyecto y detiene su bomba; el proyecto sigue abierto. |
66
+ | `/swarm:run <proyecto> [--seconds <1-3600>]` | Ejecuta la bomba en primer plano hasta que el proyecto quede inactivo (consulta «Uso real»). |
67
+ | `/swarm:budget` / `budget raise <tokens>` | Muestra el presupuesto de tokens del enjambre o sube el límite. |
68
+ | `/swarm:dashboard [proyecto\|proyecto/tarea]` | Inicia el panel de seguimiento local e imprime su enlace (consulta «Panel»). |
69
+ | `/swarm:teardown --confirm TEARDOWN` | Cancela todos los agentes y detiene todos los proyectos. Los archivos se conservan. |
70
+
71
+ Una referencia es `<proyecto>/<tarea>` o el identificador de un elemento que requiere tu atención
72
+ (`approval:<proyecto>:<tarea>`). En una sesión interactiva, `approve`, `reject` y `teardown` preguntan
73
+ con `ui.askQuestions` cuando falta un argumento; sin interfaz, las formas de comando anteriores son el
74
+ contrato.
75
+
76
+ Las herramientas `swarm_status`, `swarm_task_new`, `swarm_gate_run` y `swarm_doctor` exponen los mismos
77
+ servicios a los agentes. `swarm_gate_run` ejecuta una compuerta de calidad para un rol y devuelve su
78
+ informe.
79
+
80
+ ## Agentes
81
+
82
+ Todos los agentes llevan el prefijo `swarm-` (`swarm-specifier`, `swarm-coder`, `swarm-cleaner`,
83
+ `swarm-refactorer`, `swarm-architect`, `swarm-hardener`, `swarm-qa`, `swarm-lieutenant`) para que el
84
+ catálogo de agentes del host nunca choque con otro plugin que incluya un `specifier` o un `coder`. Los
85
+ identificadores de rol de los paquetes siguen siendo cortos (`coder`, `qa`); un único mapa del plugin
86
+ convierte el identificador de rol en el nombre del agente. Cada archivo de agente declara sus
87
+ herramientas, límite de turnos, tiempo máximo y presupuesto de salida; los hijos nunca pueden llamar a
88
+ `task`, `delegate`, `subagent` ni `sessions_create`, y los roles de solo lectura se ejecutan con
89
+ `readOnly: true`.
90
+
91
+ ## Paquetes
92
+
93
+ Un paquete son datos: los roles en orden, qué rol trabaja en la copia principal, la compuerta de
94
+ aprobación, las compuertas de calidad y los umbrales. Los paquetes se distribuyen con el plugin y
95
+ también pueden vivir en `.alisio/swarm/packs/<nombre>.json` dentro del espacio de trabajo; un paquete
96
+ del espacio de trabajo reemplaza a uno incluido con el mismo nombre.
97
+
98
+ ![Las cadenas de two-pack, four-pack y six-pack](./assets/pack-pipelines.svg)
99
+
100
+ Las cadenas incluidas, en orden; la compuerta de aprobación va tras el especificador en four-pack y six-pack.
101
+
102
+ | Paquete | Cadena |
103
+ | --- | --- |
104
+ | `two-pack` | coder, cleaner |
105
+ | `four-pack` | specifier, coder, refactorer, architect (aprobación tras el specifier) |
106
+ | `six-pack` | specifier, coder, cleaner, architect, hardener, qa (aprobación tras el specifier) |
107
+
108
+ El traspaso del último rol se difunde, solo para fusionar, a todos los demás roles y mueve la tarjeta a
109
+ Hecho. Los umbrales por defecto (cobertura 80 %, complejidad 6, CRAP 8, mutación 80 %) son datos del
110
+ paquete y se pueden cambiar en cada uno. La fórmula de CRAP es la publicada:
111
+ `CC^2 * (1 - cobertura)^3 + CC`.
112
+
113
+ ## Cómo funciona
114
+
115
+ - **Worktrees.** El rol maestro trabaja en la copia principal del proyecto. Cada uno de los demás roles
116
+ recibe un worktree en la rama `swarm/<proyecto>/<rol>`. Un hook `commit-msg` añade `By <rol>.`.
117
+ - **Traspasos.** El trabajo viaja como un identificador de commit de diez caracteres dentro de un
118
+ archivo con encabezado y cuerpo bajo `<proyecto>/.alisio/swarm/handoffs/<rol>/`. Los archivos son la
119
+ fuente de verdad: tras una caída, la bomba reenvía la bandeja de salida y el tablero se reconstruye a
120
+ partir de ellos.
121
+ - **Fusiones.** El coordinador fusiona el commit del emisor en el worktree del receptor antes de que
122
+ este se ejecute. Los conflictos se entregan al rol receptor como parte de su tarea.
123
+ - **Protocolo de auditoría.** El primer sobre de traspaso queda en espera, se pide a la misma sesión que
124
+ verifique de nuevo y un segundo sobre sin cambios lo libera.
125
+ - **Sobres estrictos.** La salida inválida (incluida la cortada por el límite de turnos) se rechaza,
126
+ nunca se repara, y se reintenta como máximo una vez antes de que la tarjeta quede bloqueada y aparezca
127
+ en lo que requiere tu atención.
128
+ - **Compuerta de aprobación.** En los paquetes con `approval.after`, el traspaso de ese rol queda
129
+ retenido hasta que lo apruebes. Rechazar ofrece reintentar, eliminar o aceptar sin cambios.
130
+ - **Aclaraciones.** Un rol puede hacer una pregunta; la tarjeta pasa a `clarifying` y la pregunta se
131
+ persiste, de modo que sobrevive a un reinicio. Tu respuesta reanuda la misma sesión (o una nueva con la
132
+ pregunta repetida tras un reinicio).
133
+ - **Las retenciones sobreviven a los reinicios.** Se persisten las aclaraciones, los bloqueos que
134
+ informa un agente, los fallos de compuertas, las aprobaciones y sus comentarios. Un fallo de ejecución
135
+ (por ejemplo, salida rechazada dos veces) se reintenta tras un reinicio.
136
+
137
+ ## Traspasos, auditorías y estados de tarea
138
+
139
+ ![Un traspaso, desde el sobre del emisor hasta la fusión del receptor](./assets/handoff-sequence.svg)
140
+
141
+ Un traspaso se retiene, se audita con un segundo sobre, pasa las compuertas del código y luego se entrega y fusiona.
142
+
143
+ ![Estados de las tarjetas y sus transiciones](./assets/task-states.svg)
144
+
145
+ Una tarjeta está `queued`, `working`, `merging`, `waiting_approval`, `clarifying`, `blocked`, `rejected` o `done`.
146
+
147
+ ![El protocolo de auditoría en dos pasadas](./assets/audit-states.svg)
148
+
149
+ La auditoría libera un traspaso solo si el segundo sobre nombra el mismo commit y las compuertas pasan.
150
+
151
+ ![La compuerta de aprobación y el flujo de aclaraciones](./assets/approval-flow.svg)
152
+
153
+ La aprobación se bloquea mientras existan comentarios; rechazar ofrece reintentar, eliminar o aceptar sin cambios.
154
+
155
+ ## Compuertas de calidad
156
+
157
+ Cuando la auditoría no cambia, el coordinador ejecuta las compuertas del rol definidas en el paquete
158
+ (bloque `gates`) con el perfil de la cadena de herramientas `node-ts`. Una compuerta que falla devuelve
159
+ su informe al mismo rol, que lo corrige y vuelve a pasar la auditoría. Tras `limits.maxBounces` fallos
160
+ (2 por defecto) la tarea queda bloqueada y tú decides: reintentar (con margen renovado), aceptar tal cual
161
+ o eliminar.
162
+
163
+ | Compuerta | Qué comprueba |
164
+ | --- | --- |
165
+ | `tests-green` | El comando `test` del perfil termina con código 0. |
166
+ | `test-first` | Un archivo de pruebas forma parte del diff del rol desde su commit base. |
167
+ | `coverage` | La cobertura global de líneas del resumen cumple `thresholds.coverage`. |
168
+ | `crap` | En las funciones modificadas, la complejidad y CRAP (`CC^2 * (1 - cobertura)^3 + CC`, con la cobertura del archivo) se mantienen bajo `thresholds.complexity` y `thresholds.crap`. |
169
+ | `dry` | Ningún bloque de 6 líneas significativas idénticas se duplica frente a un archivo modificado. |
170
+ | `mutation` | Diferencial: Stryker se ejecuta solo sobre los archivos fuente modificados y la puntuación cumple `thresholds.mutation`. |
171
+ | `acceptance` | El comando `acceptance` del perfil (o `test` si no existe) termina con código 0. |
172
+ | `structure` | Se omite indicando el motivo: todavía no hay un verificador determinista de estructura. |
173
+
174
+ Los umbrales vienen del paquete, nunca de constantes. Los procesos de las compuertas se ejecutan con
175
+ vectores de argumentos, un tiempo máximo, un límite de salida y un entorno depurado. Una compuerta que
176
+ no puede ejecutarse en absoluto (herramienta ausente, informe ilegible) no devuelve el trabajo al rol:
177
+ bloquea la tarea indicando el motivo.
178
+
179
+ Rechazo de QA: cuando el último rol informa `blocked`, sus hallazgos vuelven al coder por defecto (o al
180
+ rol indicado por `rejectTo` en ese rol, o por una línea `route: <rol>` en los hallazgos), limitado por
181
+ `maxBounces`. Un paquete puede declarar etapas `parallel` (roles adyacentes que no sean el maestro ni el
182
+ último): se ejecutan a la vez y el siguiente rol recibe todos sus commits, fusionados en el orden del
183
+ paquete, cuando todos los roles de la etapa han entregado.
184
+
185
+ ## Configuración de la cadena de herramientas
186
+
187
+ La versión 1 incluye un único perfil, `node-ts` (`assets/toolchains/node-ts.json`). Declara vectores de
188
+ argumentos y analizadores de salida, nunca cadenas de shell. Tu proyecto debe ofrecer:
189
+
190
+ | Entrada de la compuerta | Comando | Requiere |
191
+ | --- | --- | --- |
192
+ | pruebas | `npm test --silent` | un script `test` |
193
+ | cobertura | `npx vitest run --coverage --coverage.reporter=json-summary` | Vitest con proveedor de cobertura |
194
+ | complejidad (CRAP) | `npx eslint --format json --rule complexity ...` | ESLint |
195
+ | mutación | `npx stryker run --incremental` | Stryker con el reporte JSON |
196
+ | aceptación | `npm run --if-present test:acceptance --silent` | script opcional; si falta se usa `test` |
197
+
198
+ `/swarm:doctor` indica qué comandos faltan. Los umbrales y límites (`coverage`, `complexity`, `crap`,
199
+ `mutation`, `maxBounces`, `maxAuditRounds`) son datos del paquete. No se incluyen otras cadenas de
200
+ herramientas (go, java, python, clojure) en la versión 1.
201
+
202
+ ## Presupuesto de tokens
203
+
204
+ `options.tokenBudget` es un límite flexible del total de tokens del enjambre. Al alcanzarlo, las bombas
205
+ dejan de iniciar ejecuciones nuevas (las que están en curso terminan) y aparece una decisión en lo que
206
+ requiere tu atención. Sube el límite con `/swarm:budget raise <tokens>`. Los roles inactivos nunca se
207
+ ejecutan: no hay agentes ansiosos.
208
+
209
+ ## Uso real
210
+
211
+ Las sesiones hijas se crean bajo demanda a partir de la sesión que emitió el último comando `/swarm`,
212
+ con el worktree del rol como espacio de trabajo, y se cancelan al cerrar, detener, hacer teardown y
213
+ liberar el plugin. La bomba se ejecuta en segundo plano dentro del proceso del host. Aún no se ha
214
+ verificado contra un host real si una promesa que sobrevive a su comando sigue ejecutándose, cómo
215
+ programa el host las ejecuciones hijas concurrentes ni cómo se comporta `permission: ask` sin interfaz.
216
+ Si la bomba en segundo plano se detiene, `/swarm:run <proyecto>` la ejecuta en primer plano hasta una
217
+ hora; un pulso de seguridad de un segundo reinicia el trabajo detenido mientras el proceso siga vivo. Un
218
+ archivo pid bajo `.alisio/swarm` señala un proceso anterior que terminó sin limpiar.
219
+
220
+ ## Opciones
221
+
222
+ Defínelas en `pluginOverrides.swarm.options` dentro de la configuración de Alisio:
223
+
224
+ | Opción | Valor por defecto | Significado |
225
+ | --- | --- | --- |
226
+ | `maxConcurrent` | `3` | Roles que se ejecutan a la vez (de 1 a 8). |
227
+ | `roles.<rol>.model` | modelo de la sesión | Modelo para un rol concreto. |
228
+ | `tokenBudget` | ninguno | Límite flexible del total de tokens (mínimo 1000). |
229
+
230
+ ## Panel
231
+
232
+ El panel es una **vista de seguimiento** del enjambre que se ejecuta en tu espacio de trabajo. El
233
+ trabajo se inicia y se gestiona desde el chat de Alisio con comandos `/swarm:*`; la página solo ofrece
234
+ lo que el chat hace peor: ver muchos roles a la vez, leer evidencias y tomar decisiones de revisión
235
+ junto a ellas. Todos los roles, incluido el Lieutenant, se ejecutan como sesiones hijas de Alisio.
236
+
237
+ `/swarm:dashboard [proyecto | proyecto/tarea]` inicia una página web local en `127.0.0.1` (puerto
238
+ efímero), imprime su enlace e intenta abrir el navegador; el argumento opcional enlaza directamente a
239
+ un proyecto o tarjeta (`#proyecto/tarea`). Si no hay nada en ejecución, la página indica que empieces
240
+ desde el chat (`/swarm:project new`, `/swarm:task <proyecto> new`).
241
+
242
+ El tablero con la franja de atención, en el tema claro. Una aprobación, una aclaración y una
243
+ compuerta fallida esperan tu decisión; la tarjeta `shuffle` aparece resaltada mientras se fusiona.
244
+
245
+ ![Panel del enjambre en tema claro: barra superior, franja de atención con aprobación, aclaración y compuerta fallida, y un tablero con una banda por proyecto](./assets/screenshots/dashboard-board-light.png)
246
+
247
+ La misma vista en el tema oscuro, que sigue el ajuste del sistema salvo que lo cambies a mano.
248
+
249
+ ![Panel del enjambre en tema oscuro con el mismo tablero, franja de atención, cola de trabajo y registro de actividad](./assets/screenshots/dashboard-board-dark.png)
250
+
251
+ La cola de trabajo lista cada rol con un marcador live, idle o none (con etiqueta de texto además
252
+ del color), un medidor de actividad y su id de sesión de Alisio; el registro de actividad recoge
253
+ traspasos, fusiones, compuertas y rebotes.
254
+
255
+ ![Cola de trabajo con roles live, idle y none, y el registro de actividad](./assets/screenshots/dashboard-work-queue.png)
256
+
257
+ Selecciona un rol para leer el final de su sesión de Alisio: los últimos prompts y respuestas.
258
+
259
+ ![Diálogo de transcripción del rol coder con un prompt y una respuesta](./assets/screenshots/dashboard-transcript-tail.png)
260
+
261
+ Documentos muestra los archivos retenidos para aprobación, un diff lado a lado desde la base del rol
262
+ hasta el commit retenido y tus comentarios. Approve queda deshabilitado mientras existan comentarios.
263
+
264
+ ![Diálogo de documentos con un archivo de la tarea, un comentario y un diff lado a lado](./assets/screenshots/dashboard-documents-diff.png)
265
+
266
+ Reject permite reintentar con tus comentarios, eliminar la tarea o aceptar el trabajo sin cambios.
267
+
268
+ ![Diálogo Reject con las opciones de reintentar, eliminar y aceptar, y un comentario escrito](./assets/screenshots/dashboard-reject-dialog.png)
269
+
270
+ Cuando no hay nada en ejecución, la página indica que empieces desde el chat de Alisio.
271
+
272
+ ![Panel vacío que indica iniciar un proyecto desde el chat de Alisio con /swarm:project new](./assets/screenshots/dashboard-empty-state.png)
273
+
274
+ También funciona en pantallas de teléfono.
275
+
276
+ ![Panel en ancho de teléfono con los elementos de atención apilados sobre el tablero](./assets/screenshots/dashboard-phone.png)
277
+
278
+ Todas las capturas usan datos de demostración sintéticos servidos por `demo/dashboard-demo.mjs`.
279
+
280
+ | Parte | Qué muestra o hace |
281
+ | --- | --- |
282
+ | Barra superior | Indicador de estado, contador de «requiere tu decisión» (también en el título de la pestaña y el icono), presupuesto de tokens, pausa de actualización, tema y aviso sonoro. |
283
+ | Filtros | Proyecto, rol y estado; pausa la actualización mientras lees un diff o una transcripción largos. |
284
+ | Franja de atención | Elementos de aprobación, aclaración, bloqueo y compuerta fallida con Documents, Approve, Reject, Answer, Retry y Delete, más un botón que copia el comando equivalente del chat. |
285
+ | Tablero | Una banda por proyecto en ejecución, una columna por rol del paquete más DONE; las tarjetas muestran auditorías, un resumen del estado, resaltado al fusionar y un botón para copiar el comando. |
286
+ | Cola de trabajo | Tarea, rol, antigüedad, marcador live/idle/none con etiqueta de texto, medidor de actividad de 0 a 6, el id de sesión de Alisio con botón de copia y los últimos prompts y respuestas de un rol. |
287
+ | Actividad | Traspasos, fusiones, resultados de compuertas, rebotes y esperas de aprobación recientes. |
288
+ | Documentos | Archivos de la tarea, un diff lado a lado o unificado desde la base del rol hasta el commit retenido y comentarios por documento (Approve queda deshabilitado mientras existan comentarios). |
289
+
290
+ Respeta el tema claro u oscuro del sistema (con opción manual), usa tokens de diseño alineados con la
291
+ aplicación web de Alisio, funciona en pantallas de teléfono y nunca depende solo del color. Los únicos
292
+ cambios que puede hacer son las decisiones anteriores, que llaman a los mismos servicios que los
293
+ comandos. No puede crear, abrir, cerrar ni desmontar proyectos o tareas, y no incluye chat: es una
294
+ decisión del propietario, de modo que la página nunca duplica un comando.
295
+
296
+ ![Diseño y API del panel](./assets/dashboard.svg)
297
+
298
+ La página consulta `/api/state` cada dos segundos. Sin un host que pueda mostrarlo, los mismos datos
299
+ están en `/swarm:status` (tablas y una cadena en mermaid), un árbol `ui.panel` (proyectos, roles,
300
+ tareas) y la vista de datos de solo lectura `swarm-board`; cada uno se registra solo si el host lo
301
+ ofrece. Para inspeccionar la interfaz sin un host, desde una copia del repositorio compila el paquete y ejecuta
302
+ `node demo/dashboard-demo.mjs`: sirve la página con datos sintéticos.
303
+
304
+ ## Seguridad
305
+
306
+ Los comandos de git y de las compuertas se ejecutan con vectores de argumentos y un entorno depurado,
307
+ nunca mediante un shell. Los identificadores y las rutas se validan, las rutas de un proyecto no pueden
308
+ salir de su raíz mediante enlaces simbólicos, y los archivos persistentes se escriben de forma atómica
309
+ con permisos privados y versión de esquema.
310
+
311
+ El panel escucha solo en loopback. Cada petición exige un token aleatorio de 256 bits (cookie para
312
+ leer, cabecera para modificar), un `Host` de loopback y, si existe, un `Origin` local; no hay CORS, la
313
+ política de seguridad de contenido es `default-src 'self'`, los cuerpos se limitan a 256 KiB, todo
314
+ identificador se valida y el texto de agentes y tareas se muestra siempre como texto. El enlace que
315
+ imprime el comando lleva el token: no lo compartas. Los documentos se leen del almacén de objetos de
316
+ git, así que ninguna ruta puede salir del repositorio. El plugin nunca hace push ni abre pull requests.
317
+
318
+ ## Límites
319
+
320
+ - Sin verificar contra un host real: la bomba en segundo plano, las ejecuciones hijas concurrentes,
321
+ `permission: ask` sin interfaz y un espacio de trabajo hijo que sea un worktree (consulta «Uso real»).
322
+ - El SDK no ofrece API de transcripciones: la actividad de un rol en el panel es lo que el plugin
323
+ registró (prompts y respuestas acotados), no la transcripción del host.
324
+ - Los agentes hijos no pueden llamar a herramientas del plugin; solo responden con sobres JSON.
325
+ - La versión 1 solo incluye la cadena `node-ts`; la compuerta `structure` se omite con un motivo explícito.
326
+ - Sin tmux ni agentes CLI externos; sin push ni pull requests; Windows no es un objetivo más allá de no fallar.
327
+ - Los umbrales son valores por defecto nuestros, no de SwarmForge, que no publica ninguno.
328
+
329
+ ## Atribución
330
+
331
+ Inspirado en SwarmForge, de Robert C. Martin (`unclebob/swarm-forge`). Es una implementación
332
+ independiente de las ideas; no se copia texto ni código del original y la licencia del proyecto
333
+ original no se ha confirmado.
334
+
335
+ ## Licencia
336
+
337
+ MIT