xonecode 0.3.0 → 0.5.0

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 (406) hide show
  1. package/README.md +49 -7
  2. package/THIRD_PARTY_NOTICES.md +128 -0
  3. package/apps/web/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  4. package/apps/web/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  5. package/apps/web/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  6. package/apps/web/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  7. package/apps/web/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  8. package/apps/web/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  9. package/apps/web/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  10. package/apps/web/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  11. package/apps/web/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  12. package/apps/web/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  13. package/apps/web/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  14. package/apps/web/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  15. package/apps/web/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  16. package/apps/web/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  17. package/apps/web/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  18. package/apps/web/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  19. package/apps/web/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  20. package/apps/web/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  21. package/apps/web/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  22. package/apps/web/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  23. package/apps/web/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  24. package/apps/web/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  25. package/apps/web/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  26. package/apps/web/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  27. package/apps/web/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  28. package/apps/web/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  29. package/apps/web/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  30. package/apps/web/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  31. package/apps/web/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  32. package/apps/web/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  33. package/apps/web/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  34. package/apps/web/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  35. package/apps/web/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  36. package/apps/web/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  37. package/apps/web/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  38. package/apps/web/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  39. package/apps/web/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  40. package/apps/web/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  41. package/apps/web/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  42. package/apps/web/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  43. package/apps/web/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  44. package/apps/web/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  45. package/apps/web/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  46. package/apps/web/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  47. package/apps/web/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  48. package/apps/web/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  49. package/apps/web/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  50. package/apps/web/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  51. package/apps/web/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  52. package/apps/web/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  53. package/apps/web/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  54. package/apps/web/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  55. package/apps/web/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  56. package/apps/web/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  57. package/apps/web/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  58. package/apps/web/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  59. package/apps/web/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  60. package/apps/web/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  61. package/apps/web/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  62. package/apps/web/dist/assets/c-BIGW1oBm.js +1 -0
  63. package/apps/web/dist/assets/cpp-DddhVWhK.js +1 -0
  64. package/apps/web/dist/assets/csharp-DSvCPggb.js +1 -0
  65. package/apps/web/dist/assets/css-CLj8gQPS.js +1 -0
  66. package/apps/web/dist/assets/go-C27-OAKa.js +1 -0
  67. package/apps/web/dist/assets/html-CfGypltT.js +1 -0
  68. package/apps/web/dist/assets/index-BB3SamhR.css +1 -0
  69. package/apps/web/dist/assets/index-CFYAoHdw.js +477 -0
  70. package/apps/web/dist/assets/ini-BEwlwnbL.js +1 -0
  71. package/apps/web/dist/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  72. package/apps/web/dist/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  73. package/apps/web/dist/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  74. package/apps/web/dist/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  75. package/apps/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  76. package/apps/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  77. package/apps/web/dist/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  78. package/apps/web/dist/assets/java-CylS5w8V.js +1 -0
  79. package/apps/web/dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  80. package/apps/web/dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  81. package/apps/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  82. package/apps/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  83. package/apps/web/dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  84. package/apps/web/dist/assets/kotlin-BdnUsdx6.js +1 -0
  85. package/apps/web/dist/assets/less-B1dDrJ26.js +1 -0
  86. package/apps/web/dist/assets/lua-BaeVxFsk.js +1 -0
  87. package/apps/web/dist/assets/markdown-Cvjx9yec.js +1 -0
  88. package/apps/web/dist/assets/mdx-Cmh6b_Ma.js +1 -0
  89. package/apps/web/dist/assets/php-D_2--9WK.js +1 -0
  90. package/apps/web/dist/assets/python-B6aJPvgy.js +1 -0
  91. package/apps/web/dist/assets/ruby-DSHSDbk1.js +1 -0
  92. package/apps/web/dist/assets/rust-B1yitclQ.js +1 -0
  93. package/apps/web/dist/assets/scss-D5BDwBP9.js +1 -0
  94. package/apps/web/dist/assets/sql-CRqJ_cUM.js +1 -0
  95. package/apps/web/dist/assets/swift-C2oV4EkX.js +1 -0
  96. package/apps/web/dist/assets/toml-vGWfd6FD.js +1 -0
  97. package/apps/web/dist/assets/xml-sdJ4AIDG.js +1 -0
  98. package/apps/web/dist/assets/yaml-Buea-lGh.js +1 -0
  99. package/apps/web/dist/iconos/xonecode.png +0 -0
  100. package/apps/web/dist/index.html +20 -0
  101. package/dist/agent/agentesEnDisco.js +539 -0
  102. package/dist/agent/agentesEnDisco.js.map +1 -0
  103. package/dist/agent/arbolDeProyecto.js +245 -0
  104. package/dist/agent/arbolDeProyecto.js.map +1 -0
  105. package/dist/agent/artefactosEnDisco.js +139 -0
  106. package/dist/agent/artefactosEnDisco.js.map +1 -0
  107. package/dist/agent/aumentador.js +175 -0
  108. package/dist/agent/aumentador.js.map +1 -0
  109. package/dist/agent/authEnDisco.js +76 -1
  110. package/dist/agent/authEnDisco.js.map +1 -1
  111. package/dist/agent/busquedaRegex.js +92 -0
  112. package/dist/agent/busquedaRegex.js.map +1 -0
  113. package/dist/agent/catalogoModelos.js +345 -0
  114. package/dist/agent/catalogoModelos.js.map +1 -0
  115. package/dist/agent/checkpointer.js +127 -0
  116. package/dist/agent/checkpointer.js.map +1 -0
  117. package/dist/agent/cloudstudioClient.js +194 -0
  118. package/dist/agent/cloudstudioClient.js.map +1 -0
  119. package/dist/agent/cloudstudioMcp.js +722 -0
  120. package/dist/agent/cloudstudioMcp.js.map +1 -0
  121. package/dist/agent/configEnDisco.js +309 -11
  122. package/dist/agent/configEnDisco.js.map +1 -1
  123. package/dist/agent/consumoExterno.js +99 -0
  124. package/dist/agent/consumoExterno.js.map +1 -0
  125. package/dist/agent/descarga.js +149 -0
  126. package/dist/agent/descarga.js.map +1 -0
  127. package/dist/agent/diagnosticoDeTools.js +51 -0
  128. package/dist/agent/diagnosticoDeTools.js.map +1 -0
  129. package/dist/agent/dispositivosEnMaquina.js +596 -0
  130. package/dist/agent/dispositivosEnMaquina.js.map +1 -0
  131. package/dist/agent/escrituraDeCodex.js +134 -0
  132. package/dist/agent/escrituraDeCodex.js.map +1 -0
  133. package/dist/agent/escrituraDeOpencode.js +80 -0
  134. package/dist/agent/escrituraDeOpencode.js.map +1 -0
  135. package/dist/agent/escrituraExterna.js +742 -0
  136. package/dist/agent/escrituraExterna.js.map +1 -0
  137. package/dist/agent/gemini.js +81 -0
  138. package/dist/agent/gemini.js.map +1 -0
  139. package/dist/agent/git.js +83 -0
  140. package/dist/agent/git.js.map +1 -0
  141. package/dist/agent/gitSync.js +441 -0
  142. package/dist/agent/gitSync.js.map +1 -0
  143. package/dist/agent/hotswap.js +448 -0
  144. package/dist/agent/hotswap.js.map +1 -0
  145. package/dist/agent/instalacionEnMaquina.js +252 -0
  146. package/dist/agent/instalacionEnMaquina.js.map +1 -0
  147. package/dist/agent/instantanea.js +7 -10
  148. package/dist/agent/instantanea.js.map +1 -1
  149. package/dist/agent/interrupts.js +11 -2
  150. package/dist/agent/interrupts.js.map +1 -1
  151. package/dist/agent/juezDeTarea.js +345 -0
  152. package/dist/agent/juezDeTarea.js.map +1 -0
  153. package/dist/agent/lanzamientoEnMaquina.js +377 -0
  154. package/dist/agent/lanzamientoEnMaquina.js.map +1 -0
  155. package/dist/agent/manifiesto.js +59 -0
  156. package/dist/agent/manifiesto.js.map +1 -0
  157. package/dist/agent/memoriaDeProyecto.js +60 -0
  158. package/dist/agent/memoriaDeProyecto.js.map +1 -0
  159. package/dist/agent/modelos.js +105 -17
  160. package/dist/agent/modelos.js.map +1 -1
  161. package/dist/agent/modelosDeMotor.js +204 -0
  162. package/dist/agent/modelosDeMotor.js.map +1 -0
  163. package/dist/agent/paqueteDelProyecto.js +181 -0
  164. package/dist/agent/paqueteDelProyecto.js.map +1 -0
  165. package/dist/agent/perfiles.js +92 -31
  166. package/dist/agent/perfiles.js.map +1 -1
  167. package/dist/agent/persona.js +40 -0
  168. package/dist/agent/persona.js.map +1 -0
  169. package/dist/agent/procesosEnMaquina.js +204 -0
  170. package/dist/agent/procesosEnMaquina.js.map +1 -0
  171. package/dist/agent/proyecto.js +311 -13
  172. package/dist/agent/proyecto.js.map +1 -1
  173. package/dist/agent/puente.js +63 -6
  174. package/dist/agent/puente.js.map +1 -1
  175. package/dist/agent/resumenDeContexto.js +30 -0
  176. package/dist/agent/resumenDeContexto.js.map +1 -0
  177. package/dist/agent/resumenDeTool.js +64 -18
  178. package/dist/agent/resumenDeTool.js.map +1 -1
  179. package/dist/agent/sesionGit.js +481 -0
  180. package/dist/agent/sesionGit.js.map +1 -0
  181. package/dist/agent/settingsEnDisco.js +189 -0
  182. package/dist/agent/settingsEnDisco.js.map +1 -0
  183. package/dist/agent/subagenteCodex.js +368 -0
  184. package/dist/agent/subagenteCodex.js.map +1 -0
  185. package/dist/agent/subagenteExterno.js +423 -0
  186. package/dist/agent/subagenteExterno.js.map +1 -0
  187. package/dist/agent/subagenteOpencode.js +389 -0
  188. package/dist/agent/subagenteOpencode.js.map +1 -0
  189. package/dist/agent/subida.js +202 -0
  190. package/dist/agent/subida.js.map +1 -0
  191. package/dist/agent/tareasEnDisco.js +466 -0
  192. package/dist/agent/tareasEnDisco.js.map +1 -0
  193. package/dist/agent/turnoReal.js +663 -50
  194. package/dist/agent/turnoReal.js.map +1 -1
  195. package/dist/agent/versionEnDisco.js +48 -0
  196. package/dist/agent/versionEnDisco.js.map +1 -0
  197. package/dist/agent/xoneAgent.js +290 -49
  198. package/dist/agent/xoneAgent.js.map +1 -1
  199. package/dist/agent/zip.js +52 -0
  200. package/dist/agent/zip.js.map +1 -0
  201. package/dist/cli/acuseDeModelo.js +30 -0
  202. package/dist/cli/acuseDeModelo.js.map +1 -0
  203. package/dist/cli/aprobar.js +55 -2
  204. package/dist/cli/aprobar.js.map +1 -1
  205. package/dist/cli/config.js +9 -13
  206. package/dist/cli/config.js.map +1 -1
  207. package/dist/cli/consola.js +750 -19
  208. package/dist/cli/consola.js.map +1 -1
  209. package/dist/cli/main.js +740 -81
  210. package/dist/cli/main.js.map +1 -1
  211. package/dist/cli/markdown.js +188 -2
  212. package/dist/cli/markdown.js.map +1 -1
  213. package/dist/cli/run.js +32 -4
  214. package/dist/cli/run.js.map +1 -1
  215. package/dist/cli/stdio.js +46 -19
  216. package/dist/cli/stdio.js.map +1 -1
  217. package/dist/cli/tema.js +96 -8
  218. package/dist/cli/tema.js.map +1 -1
  219. package/dist/cli/tokens.js +29 -0
  220. package/dist/cli/tokens.js.map +1 -0
  221. package/dist/cli/tui/app.js +171 -0
  222. package/dist/cli/tui/app.js.map +1 -0
  223. package/dist/cli/tui/aprobarTui.js +80 -0
  224. package/dist/cli/tui/aprobarTui.js.map +1 -0
  225. package/dist/cli/tui/barra.js +37 -0
  226. package/dist/cli/tui/barra.js.map +1 -0
  227. package/dist/cli/tui/correrTui.js +478 -0
  228. package/dist/cli/tui/correrTui.js.map +1 -0
  229. package/dist/cli/tui/entrada.js +166 -0
  230. package/dist/cli/tui/entrada.js.map +1 -0
  231. package/dist/cli/tui/filas.js +24 -0
  232. package/dist/cli/tui/filas.js.map +1 -0
  233. package/dist/cli/tui/logo.js +49 -0
  234. package/dist/cli/tui/logo.js.map +1 -0
  235. package/dist/cli/tui/pielTui.js +14 -0
  236. package/dist/cli/tui/pielTui.js.map +1 -0
  237. package/dist/cli/tui/raton.js +126 -0
  238. package/dist/cli/tui/raton.js.map +1 -0
  239. package/dist/cli/tui/sidebar.js +86 -0
  240. package/dist/cli/tui/sidebar.js.map +1 -0
  241. package/dist/cli/tui/store.js +143 -0
  242. package/dist/cli/tui/store.js.map +1 -0
  243. package/dist/cli/tui/tarjeta.js +19 -0
  244. package/dist/cli/tui/tarjeta.js.map +1 -0
  245. package/dist/cli/tui/temaInk.js +114 -0
  246. package/dist/cli/tui/temaInk.js.map +1 -0
  247. package/dist/cli/tui/transcript.js +254 -0
  248. package/dist/cli/tui/transcript.js.map +1 -0
  249. package/dist/cli/wizardInicial.js +240 -0
  250. package/dist/cli/wizardInicial.js.map +1 -0
  251. package/dist/core/actos.js +113 -0
  252. package/dist/core/actos.js.map +1 -0
  253. package/dist/core/adjuntos.js +97 -0
  254. package/dist/core/adjuntos.js.map +1 -0
  255. package/dist/core/agentes.js +227 -0
  256. package/dist/core/agentes.js.map +1 -0
  257. package/dist/core/artefactos.js +149 -0
  258. package/dist/core/artefactos.js.map +1 -0
  259. package/dist/core/cloudstudio.js +7 -0
  260. package/dist/core/cloudstudio.js.map +1 -0
  261. package/dist/core/config.js +212 -5
  262. package/dist/core/config.js.map +1 -1
  263. package/dist/core/contextos.js +53 -1
  264. package/dist/core/contextos.js.map +1 -1
  265. package/dist/core/descargas.js +106 -0
  266. package/dist/core/descargas.js.map +1 -0
  267. package/dist/core/descriptoresDeApp.js +279 -0
  268. package/dist/core/descriptoresDeApp.js.map +1 -0
  269. package/dist/core/dispositivos.js +466 -0
  270. package/dist/core/dispositivos.js.map +1 -0
  271. package/dist/core/entrega.js +141 -0
  272. package/dist/core/entrega.js.map +1 -0
  273. package/dist/core/entrelazar.js +90 -0
  274. package/dist/core/entrelazar.js.map +1 -0
  275. package/dist/core/esqueleto.js +10 -0
  276. package/dist/core/esqueleto.js.map +1 -1
  277. package/dist/core/modelos.js +235 -3
  278. package/dist/core/modelos.js.map +1 -1
  279. package/dist/core/notify.js +27 -9
  280. package/dist/core/notify.js.map +1 -1
  281. package/dist/core/planDeSubida.js +127 -0
  282. package/dist/core/planDeSubida.js.map +1 -0
  283. package/dist/core/ports.js +189 -1
  284. package/dist/core/ports.js.map +1 -1
  285. package/dist/core/puedeLanzarse.js +239 -0
  286. package/dist/core/puedeLanzarse.js.map +1 -0
  287. package/dist/core/rutaVirtual.js +42 -0
  288. package/dist/core/rutaVirtual.js.map +1 -0
  289. package/dist/core/settings.js +246 -0
  290. package/dist/core/settings.js.map +1 -0
  291. package/dist/core/tareas.js +230 -0
  292. package/dist/core/tareas.js.map +1 -0
  293. package/dist/core/textos.js +36 -0
  294. package/dist/core/textos.js.map +1 -0
  295. package/dist/core/turno.js +56 -8
  296. package/dist/core/turno.js.map +1 -1
  297. package/dist/core/version.js +31 -0
  298. package/dist/core/version.js.map +1 -0
  299. package/dist/vendor/tokenTracking.js +22 -1
  300. package/dist/vendor/tokenTracking.js.map +1 -1
  301. package/dist/web/servidor/arranque.js +3964 -0
  302. package/dist/web/servidor/arranque.js.map +1 -0
  303. package/dist/web/servidor/consolaDeTarea.js +161 -0
  304. package/dist/web/servidor/consolaDeTarea.js.map +1 -0
  305. package/dist/web/servidor/consolaWeb.js +389 -0
  306. package/dist/web/servidor/consolaWeb.js.map +1 -0
  307. package/dist/web/servidor/corredorDeTareas.js +1119 -0
  308. package/dist/web/servidor/corredorDeTareas.js.map +1 -0
  309. package/dist/web/servidor/pielWeb.js +269 -0
  310. package/dist/web/servidor/pielWeb.js.map +1 -0
  311. package/dist/web/servidor/servidor.js +257 -0
  312. package/dist/web/servidor/servidor.js.map +1 -0
  313. package/dist/web/servidor/sesiones.js +440 -0
  314. package/dist/web/servidor/sesiones.js.map +1 -0
  315. package/dist/web/servidor/transporte.js +169 -0
  316. package/dist/web/servidor/transporte.js.map +1 -0
  317. package/dist/web/servidor/vestibulo.js +1276 -0
  318. package/dist/web/servidor/vestibulo.js.map +1 -0
  319. package/package.json +30 -8
  320. package/skills/archify/LICENSE +22 -0
  321. package/skills/archify/SKILL.md +109 -0
  322. package/skills/archify/THIRD_PARTY_NOTICES.md +56 -0
  323. package/skills/archify/assets/template.html +14787 -0
  324. package/skills/archify/bin/archify.mjs +1990 -0
  325. package/skills/archify/bin/open-artifact.mjs +86 -0
  326. package/skills/archify/bin/preview.mjs +648 -0
  327. package/skills/archify/bin/visual-check.mjs +829 -0
  328. package/skills/archify/brand-marks/README.md +31 -0
  329. package/skills/archify/brand-marks/catalog.json +131 -0
  330. package/skills/archify/delta/architecture-delta.mjs +1214 -0
  331. package/skills/archify/examples/agent-run.lifecycle.json +71 -0
  332. package/skills/archify/examples/agent-tool-call.workflow.json +94 -0
  333. package/skills/archify/examples/async-job-roundtrip.sequence.json +61 -0
  334. package/skills/archify/examples/brand-aware-delivery.architecture.json +47 -0
  335. package/skills/archify/examples/cache-miss-request.sequence.json +81 -0
  336. package/skills/archify/examples/checkout-platform.base.architecture.json +31 -0
  337. package/skills/archify/examples/checkout-platform.head.architecture.json +31 -0
  338. package/skills/archify/examples/dataflow-product-analytics.html +14898 -0
  339. package/skills/archify/examples/deployment-release.lifecycle.json +49 -0
  340. package/skills/archify/examples/event-stream.dataflow.json +57 -0
  341. package/skills/archify/examples/incident-response.workflow.json +64 -0
  342. package/skills/archify/examples/lifecycle-agent-run.html +14847 -0
  343. package/skills/archify/examples/product-analytics.dataflow.json +76 -0
  344. package/skills/archify/examples/production-deployment.architecture.json +71 -0
  345. package/skills/archify/examples/release-delivery.workflow.json +62 -0
  346. package/skills/archify/examples/sequence-cache-miss-request.html +14913 -0
  347. package/skills/archify/examples/web-app-rendered.html +14862 -0
  348. package/skills/archify/examples/web-app.architecture.json +46 -0
  349. package/skills/archify/examples/workflow-agent-tool-call-rendered.html +14904 -0
  350. package/skills/archify/migrations/workflow-v2.mjs +279 -0
  351. package/skills/archify/package.json +17 -0
  352. package/skills/archify/recipes/scenarios.mjs +391 -0
  353. package/skills/archify/references/authoring-contract.md +198 -0
  354. package/skills/archify/references/brand-marks.md +69 -0
  355. package/skills/archify/references/delivery-contract.md +116 -0
  356. package/skills/archify/references/viewer-runtime.md +45 -0
  357. package/skills/archify/renderers/architecture/grid.mjs +62 -0
  358. package/skills/archify/renderers/architecture/render-architecture.mjs +1078 -0
  359. package/skills/archify/renderers/dataflow/README.md +104 -0
  360. package/skills/archify/renderers/dataflow/render-dataflow.mjs +483 -0
  361. package/skills/archify/renderers/lifecycle/README.md +115 -0
  362. package/skills/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
  363. package/skills/archify/renderers/sequence/README.md +114 -0
  364. package/skills/archify/renderers/sequence/render-sequence.mjs +453 -0
  365. package/skills/archify/renderers/shared/brand-marks.mjs +563 -0
  366. package/skills/archify/renderers/shared/cli.mjs +218 -0
  367. package/skills/archify/renderers/shared/desktop-readability.mjs +26 -0
  368. package/skills/archify/renderers/shared/diagnostics.mjs +127 -0
  369. package/skills/archify/renderers/shared/engineering-profiles.mjs +157 -0
  370. package/skills/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
  371. package/skills/archify/renderers/shared/generated-validators.mjs +13 -0
  372. package/skills/archify/renderers/shared/geometry.mjs +1423 -0
  373. package/skills/archify/renderers/shared/i18n.mjs +594 -0
  374. package/skills/archify/renderers/shared/layout-report.mjs +40 -0
  375. package/skills/archify/renderers/shared/legend.mjs +217 -0
  376. package/skills/archify/renderers/shared/output-path.mjs +321 -0
  377. package/skills/archify/renderers/shared/repository-evidence.mjs +235 -0
  378. package/skills/archify/renderers/shared/text-fit.mjs +49 -0
  379. package/skills/archify/renderers/shared/utils.mjs +232 -0
  380. package/skills/archify/renderers/shared/validator.mjs +86 -0
  381. package/skills/archify/renderers/workflow/README.md +223 -0
  382. package/skills/archify/renderers/workflow/render-workflow.mjs +35 -0
  383. package/skills/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
  384. package/skills/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
  385. package/skills/archify/schemas/README.md +211 -0
  386. package/skills/archify/schemas/architecture.schema.json +176 -0
  387. package/skills/archify/schemas/common.schema.json +115 -0
  388. package/skills/archify/schemas/dataflow.schema.json +243 -0
  389. package/skills/archify/schemas/lifecycle.schema.json +266 -0
  390. package/skills/archify/schemas/sequence.schema.json +223 -0
  391. package/skills/archify/schemas/workflow.schema.json +428 -0
  392. package/skills/archify/scripts/check-render-output.mjs +835 -0
  393. package/skills/archify/scripts/check-update.mjs +1667 -0
  394. package/skills/archify/scripts/render-examples.mjs +26 -0
  395. package/skills/archify/scripts/update-contract.mjs +182 -0
  396. package/skills/archify/skill-release.json +10 -0
  397. package/skills/artifacts-builder/SKILL.md +120 -0
  398. package/skills/artifacts-builder/reference/diagramas.md +123 -0
  399. package/skills/artifacts-builder/reference/estilo.md +123 -0
  400. package/skills/artifacts-builder/reference/exportar-pdf.md +56 -0
  401. package/skills/artifacts-builder/reference/graficas.md +22 -0
  402. package/skills/artifacts-builder/scripts/bundle_artifact.py +109 -0
  403. package/skills/artifacts-builder/scripts/validate_artifact.py +345 -0
  404. package/skills/xone-hotswap/SKILL.md +185 -0
  405. package/skills/xone-hotswap/references/comandos.md +706 -0
  406. package/skills/xone-hotswap/references/conexion-y-despliegue.md +226 -0
@@ -0,0 +1,648 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import fs from 'node:fs';
4
+ import http from 'node:http';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ import { openLoopbackUrl } from './open-artifact.mjs';
9
+ import { resolveOutputPath } from '../renderers/shared/output-path.mjs';
10
+
11
+ const here = path.dirname(fileURLToPath(import.meta.url));
12
+ const cliPath = path.join(here, 'archify.mjs');
13
+ const loopbackHost = '127.0.0.1';
14
+ const defaultDebounceMs = 400;
15
+ const defaultPollMs = 800;
16
+ const defaultStopGraceMs = 3000;
17
+ const defaultStopKillMs = 750;
18
+ const diagramTypes = new Set(['architecture', 'workflow', 'sequence', 'dataflow', 'lifecycle']);
19
+
20
+ function sha256(value) {
21
+ return createHash('sha256').update(value).digest('hex');
22
+ }
23
+
24
+ function sourceDigest(inputPath) {
25
+ try {
26
+ const bytes = fs.readFileSync(inputPath);
27
+ return { hash: sha256(bytes), bytes, missing: false };
28
+ } catch (error) {
29
+ return { hash: `unreadable:${error.code || 'unknown'}`, bytes: null, missing: true };
30
+ }
31
+ }
32
+
33
+ function initialAuthoredOutput(inputPath) {
34
+ try {
35
+ const source = JSON.parse(fs.readFileSync(inputPath, 'utf8'));
36
+ if (typeof source?.meta?.output === 'string' && source.meta.output) {
37
+ return source.meta.output;
38
+ }
39
+ } catch {
40
+ // An invalid initial source still gets a status shell. Its output target is
41
+ // fixed to the same fallback that `deliver` would use after repair.
42
+ }
43
+ return undefined;
44
+ }
45
+
46
+ function previewPage() {
47
+ return `<!doctype html>
48
+ <html lang="en">
49
+ <head>
50
+ <meta charset="utf-8">
51
+ <meta name="viewport" content="width=device-width,initial-scale=1">
52
+ <title>Archify Live Preview</title>
53
+ <style>
54
+ :root { color-scheme: light dark; font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
55
+ * { box-sizing: border-box; }
56
+ html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: #0b111b; }
57
+ body { display: grid; grid-template-rows: auto minmax(0, 1fr); color: #e8edf5; }
58
+ header { position: relative; z-index: 2; display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 7px 12px; border-bottom: 1px solid #253248; background: rgba(11, 17, 27, .96); box-shadow: 0 8px 22px rgba(0,0,0,.18); }
59
+ .brand { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #9cadc6; }
60
+ #status { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; min-height: 30px; padding: 5px 10px; border: 1px solid #33435d; border-radius: 999px; background: #111b2a; font-size: 12px; white-space: nowrap; }
61
+ #status::before { content: ''; width: 8px; height: 8px; border-radius: 50%; background: #6f819d; }
62
+ body[data-state="checking"] #status::before { background: #f3b44b; box-shadow: 0 0 0 4px rgba(243,180,75,.12); }
63
+ body[data-state="verified"] #status::before { background: #45d6a8; box-shadow: 0 0 0 4px rgba(69,214,168,.12); }
64
+ body[data-state="needs-fix"] #status::before { background: #ff6f78; box-shadow: 0 0 0 4px rgba(255,111,120,.12); }
65
+ details { max-width: min(62vw, 760px); }
66
+ summary { cursor: pointer; color: #ffbdc2; font-size: 12px; }
67
+ .diagnostic { position: absolute; top: 38px; right: 12px; width: min(760px, calc(100vw - 24px)); max-height: min(44vh, 360px); overflow: auto; padding: 14px; border: 1px solid #6a3440; border-radius: 10px; background: #17131b; box-shadow: 0 14px 48px rgba(0,0,0,.42); }
68
+ pre { margin: 0 0 10px; white-space: pre-wrap; overflow-wrap: anywhere; font: 11px/1.55 ui-monospace, SFMono-Regular, Menlo, monospace; color: #f2dfe2; }
69
+ button { min-height: 32px; padding: 5px 10px; border: 1px solid #4a5d79; border-radius: 7px; background: #1a273a; color: #eef4ff; cursor: pointer; }
70
+ main { position: relative; min-height: 0; }
71
+ iframe { display: none; width: 100%; height: 100%; border: 0; background: #fff; }
72
+ body[data-has-artifact="true"] iframe { display: block; }
73
+ #empty { position: absolute; inset: 0; display: grid; place-items: center; padding: 32px; color: #91a2bc; text-align: center; background: radial-gradient(circle at 50% 38%, #15233a 0, #0b111b 55%); }
74
+ body[data-has-artifact="true"] #empty { display: none; }
75
+ @media (prefers-reduced-motion: reduce) { * { scroll-behavior: auto !important; } }
76
+ </style>
77
+ </head>
78
+ <body data-state="checking" data-has-artifact="false">
79
+ <header>
80
+ <span class="brand">Archify Preview</span>
81
+ <details id="failure" hidden>
82
+ <summary role="button" aria-controls="diagnostic-panel">View diagnostic</summary>
83
+ <div class="diagnostic" id="diagnostic-panel"><pre id="diagnostic"></pre><button id="copy" type="button">Copy diagnostic</button></div>
84
+ </details>
85
+ <span id="status" role="status" aria-live="polite">Checking · generation 1</span>
86
+ </header>
87
+ <main>
88
+ <div id="empty">Waiting for the first verified diagram. Invalid input will stay here with an exact diagnostic.</div>
89
+ <iframe id="artifact" title="Verified Archify diagram"></iframe>
90
+ </main>
91
+ <script>
92
+ (function () {
93
+ 'use strict';
94
+ var body = document.body;
95
+ var status = document.getElementById('status');
96
+ var failure = document.getElementById('failure');
97
+ var diagnostic = document.getElementById('diagnostic');
98
+ var artifact = document.getElementById('artifact');
99
+ var lastRevision = 0;
100
+
101
+ function render(state) {
102
+ body.dataset.state = state.status;
103
+ if (state.status === 'verified') {
104
+ status.textContent = 'Verified · rev ' + state.revision;
105
+ failure.hidden = true;
106
+ failure.open = false;
107
+ if (state.revision !== lastRevision) {
108
+ lastRevision = state.revision;
109
+ artifact.src = '/artifact.html?revision=' + encodeURIComponent(state.revision) + '&sha=' + encodeURIComponent(state.lastVerified.sha256.slice(0, 12));
110
+ body.dataset.hasArtifact = 'true';
111
+ }
112
+ } else if (state.status === 'needs-fix') {
113
+ status.textContent = 'Needs fix · ' + (state.revision ? 'showing rev ' + state.revision : 'no verified revision');
114
+ diagnostic.textContent = 'Generation ' + state.generation + ' · ' + state.failure.stage + '\\n\\n' + state.failure.message;
115
+ failure.hidden = false;
116
+ } else {
117
+ status.textContent = 'Checking · generation ' + state.generation;
118
+ failure.hidden = true;
119
+ }
120
+ }
121
+
122
+ document.getElementById('copy').addEventListener('click', function () {
123
+ if (navigator.clipboard && navigator.clipboard.writeText) {
124
+ navigator.clipboard.writeText(diagnostic.textContent).catch(function () {});
125
+ }
126
+ });
127
+
128
+ var events = new EventSource('/events');
129
+ events.addEventListener('state', function (event) {
130
+ try { render(JSON.parse(event.data)); } catch (_) {}
131
+ });
132
+ }());
133
+ </script>
134
+ </body>
135
+ </html>`;
136
+ }
137
+
138
+ function compactMessage(value) {
139
+ let text = String(value || 'Preview build failed without a diagnostic.').trim();
140
+ const lines = text.split(/\r?\n/);
141
+ const errorLine = lines.findIndex((line) => /^Error:\s/.test(line));
142
+ if (errorLine > 0) text = lines.slice(errorLine).join('\n');
143
+ const relevant = text.split(/\r?\n/);
144
+ const stackLine = relevant.findIndex((line, index) => index > 0 && /^\s*at\s/.test(line));
145
+ if (stackLine > 0) text = relevant.slice(0, stackLine).join('\n');
146
+ return text.length > 6000 ? `${text.slice(0, 6000)}\n… diagnostic truncated` : text;
147
+ }
148
+
149
+ function redactDiagnostic(value, paths) {
150
+ let text = compactMessage(value);
151
+ for (const [absolutePath, replacement] of paths) {
152
+ if (!absolutePath) continue;
153
+ text = text.split(absolutePath).join(replacement);
154
+ }
155
+ return text;
156
+ }
157
+
158
+ function safeJson(value) {
159
+ return JSON.stringify(value).replace(/</g, '\\u003c');
160
+ }
161
+
162
+ function responseHeaders(contentType) {
163
+ return {
164
+ 'Cache-Control': 'no-store',
165
+ 'Content-Type': contentType,
166
+ 'Cross-Origin-Resource-Policy': 'same-origin',
167
+ 'Referrer-Policy': 'no-referrer',
168
+ 'X-Content-Type-Options': 'nosniff',
169
+ 'X-Frame-Options': 'SAMEORIGIN',
170
+ };
171
+ }
172
+
173
+ function parseReceipt(stdout) {
174
+ try {
175
+ return JSON.parse(stdout);
176
+ } catch {
177
+ return null;
178
+ }
179
+ }
180
+
181
+ export async function startPreview(options) {
182
+ const type = options.type;
183
+ if (!diagramTypes.has(type)) throw new Error(`Unknown diagram type "${type}".`);
184
+ if (options.quality && !['standard', 'showcase'].includes(options.quality)) {
185
+ throw new Error(`Unknown quality profile "${options.quality}".`);
186
+ }
187
+ const inputPath = path.resolve(options.input);
188
+ const outputRequest = {
189
+ requestedOutput: options.output,
190
+ authoredOutput: initialAuthoredOutput(inputPath),
191
+ defaultOutput: `${type}.html`,
192
+ inputPaths: [inputPath],
193
+ inputDescription: 'its JSON input',
194
+ cwd: options.cwd || process.cwd(),
195
+ };
196
+ const { outputPath } = resolveOutputPath(outputRequest);
197
+ const outputDirectory = path.dirname(outputPath);
198
+ const debounceMs = Number.isFinite(options.debounceMs) ? options.debounceMs : defaultDebounceMs;
199
+ const pollMs = Number.isFinite(options.pollMs) ? options.pollMs : defaultPollMs;
200
+ const stopGraceMs = Number.isFinite(options.stopGraceMs) ? Math.max(0, options.stopGraceMs) : defaultStopGraceMs;
201
+ const stopKillMs = Number.isFinite(options.stopKillMs) ? Math.max(0, options.stopKillMs) : defaultStopKillMs;
202
+ const shouldOpen = options.open !== false;
203
+
204
+ fs.mkdirSync(outputDirectory, { recursive: true });
205
+ const stagingDirectory = fs.mkdtempSync(path.join(outputDirectory, '.archify-preview-'));
206
+
207
+ let port = 0;
208
+ let watcher;
209
+ let debounceTimer;
210
+ let pollTimer;
211
+ let stopGraceTimer;
212
+ let stopKillTimer;
213
+ let child;
214
+ let stopping = false;
215
+ let stopped = false;
216
+ let serverClosing = false;
217
+ let serverClosed = false;
218
+ let queuedHash = null;
219
+ let activeHash = null;
220
+ let lastGoodSourceHash = null;
221
+ let sourceEpoch = 0;
222
+ let activeEpoch = 0;
223
+ let pendingBuild = false;
224
+ let artifactBuffer = null;
225
+ const clients = new Set();
226
+ const state = {
227
+ schemaVersion: 1,
228
+ status: 'checking',
229
+ generation: 0,
230
+ revision: 0,
231
+ lastVerified: null,
232
+ failure: null,
233
+ };
234
+
235
+ let resolveClosed;
236
+ const closed = new Promise((resolve) => { resolveClosed = resolve; });
237
+
238
+ function publicState() {
239
+ return JSON.parse(JSON.stringify(state));
240
+ }
241
+
242
+ function sendState(res) {
243
+ res.write(`event: state\ndata: ${safeJson(publicState())}\n\n`);
244
+ }
245
+
246
+ function broadcast() {
247
+ for (const res of clients) sendState(res);
248
+ }
249
+
250
+ const page = Buffer.from(previewPage());
251
+ const server = http.createServer((req, res) => {
252
+ const expectedHost = `${loopbackHost}:${port}`;
253
+ if (req.headers.host !== expectedHost) {
254
+ res.writeHead(403, responseHeaders('text/plain; charset=utf-8'));
255
+ res.end('Forbidden host');
256
+ return;
257
+ }
258
+ if (req.method !== 'GET' && req.method !== 'HEAD') {
259
+ res.writeHead(405, { ...responseHeaders('text/plain; charset=utf-8'), Allow: 'GET, HEAD' });
260
+ res.end('Method not allowed');
261
+ return;
262
+ }
263
+
264
+ let url;
265
+ try {
266
+ url = new URL(req.url, `http://${expectedHost}`);
267
+ } catch {
268
+ res.writeHead(400, responseHeaders('text/plain; charset=utf-8'));
269
+ res.end('Bad request');
270
+ return;
271
+ }
272
+
273
+ if (url.pathname === '/') {
274
+ res.writeHead(200, {
275
+ ...responseHeaders('text/html; charset=utf-8'),
276
+ 'Content-Security-Policy': "default-src 'none'; frame-src 'self'; connect-src 'self'; script-src 'unsafe-inline'; style-src 'unsafe-inline'",
277
+ 'Content-Length': page.byteLength,
278
+ });
279
+ if (req.method === 'HEAD') res.end();
280
+ else res.end(page);
281
+ return;
282
+ }
283
+ if (url.pathname === '/state') {
284
+ const body = Buffer.from(`${safeJson(publicState())}\n`);
285
+ res.writeHead(200, { ...responseHeaders('application/json; charset=utf-8'), 'Content-Length': body.byteLength });
286
+ if (req.method === 'HEAD') res.end();
287
+ else res.end(body);
288
+ return;
289
+ }
290
+ if (url.pathname === '/artifact.html') {
291
+ if (!artifactBuffer) {
292
+ res.writeHead(404, responseHeaders('text/plain; charset=utf-8'));
293
+ res.end('No verified artifact yet');
294
+ return;
295
+ }
296
+ res.writeHead(200, { ...responseHeaders('text/html; charset=utf-8'), 'Content-Length': artifactBuffer.byteLength });
297
+ if (req.method === 'HEAD') res.end();
298
+ else res.end(artifactBuffer);
299
+ return;
300
+ }
301
+ if (url.pathname === '/events' && req.method === 'GET') {
302
+ res.writeHead(200, {
303
+ ...responseHeaders('text/event-stream; charset=utf-8'),
304
+ Connection: 'keep-alive',
305
+ });
306
+ res.write('retry: 1000\n\n');
307
+ clients.add(res);
308
+ sendState(res);
309
+ req.on('close', () => clients.delete(res));
310
+ return;
311
+ }
312
+
313
+ res.writeHead(404, responseHeaders('text/plain; charset=utf-8'));
314
+ res.end('Not found');
315
+ });
316
+
317
+ try {
318
+ await new Promise((resolve, reject) => {
319
+ server.once('error', reject);
320
+ server.listen(0, loopbackHost, () => {
321
+ server.off('error', reject);
322
+ port = server.address().port;
323
+ resolve();
324
+ });
325
+ });
326
+ } catch (error) {
327
+ try { server.close(); } catch {}
328
+ fs.rmSync(stagingDirectory, { recursive: true, force: true });
329
+ throw error;
330
+ }
331
+
332
+ const url = `http://${loopbackHost}:${port}/`;
333
+
334
+ function finishStop() {
335
+ if (stopped || child || !serverClosed) return;
336
+ stopped = true;
337
+ clearTimeout(debounceTimer);
338
+ clearInterval(pollTimer);
339
+ clearTimeout(stopGraceTimer);
340
+ clearTimeout(stopKillTimer);
341
+ try {
342
+ fs.rmSync(stagingDirectory, { recursive: true, force: true });
343
+ } finally {
344
+ resolveClosed();
345
+ }
346
+ }
347
+
348
+ function signalActiveChild(signal) {
349
+ if (!child || child.exitCode !== null || child.signalCode !== null) return;
350
+ try {
351
+ if (process.platform !== 'win32' && child.pid) process.kill(-child.pid, signal);
352
+ else child.kill(signal);
353
+ } catch (error) {
354
+ if (error.code === 'ESRCH') return;
355
+ try { child.kill(signal); } catch {}
356
+ }
357
+ }
358
+
359
+ function closeServer() {
360
+ if (serverClosing) return;
361
+ serverClosing = true;
362
+ for (const res of clients) res.end();
363
+ clients.clear();
364
+ server.close(() => {
365
+ serverClosed = true;
366
+ finishStop();
367
+ });
368
+ server.closeIdleConnections?.();
369
+ }
370
+
371
+ function startBoundedChildDrain() {
372
+ if (!child || stopGraceTimer || stopKillTimer) return;
373
+ stopGraceTimer = setTimeout(() => {
374
+ stopGraceTimer = undefined;
375
+ if (!child) return finishStop();
376
+ signalActiveChild('SIGTERM');
377
+ stopKillTimer = setTimeout(() => {
378
+ stopKillTimer = undefined;
379
+ signalActiveChild('SIGKILL');
380
+ }, stopKillMs);
381
+ }, stopGraceMs);
382
+ }
383
+
384
+ async function stop({ force = false } = {}) {
385
+ if (!stopping) {
386
+ stopping = true;
387
+ clearTimeout(debounceTimer);
388
+ clearInterval(pollTimer);
389
+ watcher?.close();
390
+ closeServer();
391
+ }
392
+ if (child && force) {
393
+ clearTimeout(stopGraceTimer);
394
+ clearTimeout(stopKillTimer);
395
+ stopGraceTimer = undefined;
396
+ stopKillTimer = undefined;
397
+ signalActiveChild('SIGKILL');
398
+ } else if (child) {
399
+ startBoundedChildDrain();
400
+ } else {
401
+ finishStop();
402
+ }
403
+ return closed;
404
+ }
405
+
406
+ function publishFailure(receipt, stdout, stderr, candidatePath, snapshotPath) {
407
+ const repairDetails = receipt?.diagnostics
408
+ ?.slice(0, 12)
409
+ .map((entry) => {
410
+ const fix = entry.supportedFixes?.length ? `\nFix: ${entry.supportedFixes.join('; ')}` : '';
411
+ return `[${entry.code}] ${entry.message}${fix}`;
412
+ }) || [];
413
+ const checkerDetails = receipt?.checker?.checks
414
+ ?.filter((check) => !check.ok)
415
+ .flatMap((check) => check.details || [])
416
+ .filter(Boolean)
417
+ .slice(0, 12) || [];
418
+ const diagnostic = [
419
+ receipt?.error,
420
+ ...(repairDetails.length ? repairDetails : checkerDetails),
421
+ ].filter(Boolean).join('\n') || stderr || stdout;
422
+ state.status = 'needs-fix';
423
+ state.failure = {
424
+ stage: receipt?.stage || 'render',
425
+ message: redactDiagnostic(
426
+ diagnostic,
427
+ [
428
+ [inputPath, '<input.json>'],
429
+ [outputPath, '<output.html>'],
430
+ [snapshotPath, '<input.json>'],
431
+ [candidatePath, '<candidate.html>'],
432
+ [stagingDirectory, '<preview-staging>'],
433
+ [path.resolve(here, '..'), '<archify-skill>'],
434
+ [path.resolve(options.cwd || process.cwd()), '<working-directory>'],
435
+ ...(options.repoRoot ? [[path.resolve(options.repoRoot), '<repo-root>']] : []),
436
+ ],
437
+ ),
438
+ };
439
+ broadcast();
440
+ }
441
+
442
+ function commitCandidate(candidatePath, receipt, generationHash) {
443
+ let candidate;
444
+ try {
445
+ candidate = fs.readFileSync(candidatePath);
446
+ const digest = sha256(candidate);
447
+ if (digest !== receipt?.artifact?.sha256) {
448
+ throw new Error('Verified candidate bytes do not match the delivery receipt.');
449
+ }
450
+ resolveOutputPath(outputRequest);
451
+ const sameArtifact = state.lastVerified?.sha256 === digest;
452
+ let outputMatches = false;
453
+ if (sameArtifact) {
454
+ try { outputMatches = sha256(fs.readFileSync(outputPath)) === digest; } catch {}
455
+ }
456
+ const currentSource = sourceDigest(inputPath);
457
+ if (currentSource.hash !== generationHash) {
458
+ return { committed: false, supersededBy: currentSource };
459
+ }
460
+ if (!sameArtifact || !outputMatches) fs.renameSync(candidatePath, outputPath);
461
+ artifactBuffer = candidate;
462
+ lastGoodSourceHash = generationHash;
463
+ state.status = 'verified';
464
+ if (!sameArtifact) {
465
+ state.revision += 1;
466
+ state.lastVerified = {
467
+ sha256: digest,
468
+ bytes: candidate.byteLength,
469
+ checksPassed: receipt.validation.checksPassed,
470
+ checkCount: receipt.validation.checkCount,
471
+ compositionProfile: receipt.validation.compositionProfile,
472
+ compositionStatus: receipt.validation.compositionStatus,
473
+ };
474
+ }
475
+ state.failure = null;
476
+ broadcast();
477
+ return { committed: true, supersededBy: null };
478
+ } catch (error) {
479
+ publishFailure({ stage: 'commit', error: `Could not publish the verified preview: ${error.message}` }, '', '', candidatePath);
480
+ return { committed: false, supersededBy: null };
481
+ }
482
+ }
483
+
484
+ function beginBuild(digest, epoch) {
485
+ if (stopping || child) return;
486
+ activeHash = digest.hash;
487
+ activeEpoch = epoch;
488
+ state.generation += 1;
489
+ state.status = 'checking';
490
+ state.failure = null;
491
+ broadcast();
492
+
493
+ const candidatePath = path.join(stagingDirectory, `generation-${state.generation}.html`);
494
+ const snapshotPath = path.join(stagingDirectory, `generation-${state.generation}.json`);
495
+ if (digest.bytes !== null) {
496
+ try {
497
+ fs.writeFileSync(snapshotPath, digest.bytes, { flag: 'wx', mode: 0o600 });
498
+ } catch (error) {
499
+ publishFailure(
500
+ { stage: 'prepare', error: `Could not snapshot the observed input: ${error.message}` },
501
+ '',
502
+ '',
503
+ candidatePath,
504
+ snapshotPath,
505
+ );
506
+ return;
507
+ }
508
+ }
509
+ const args = [options.deliveryCli || cliPath, 'deliver', type, snapshotPath, candidatePath, '--json'];
510
+ if (options.quality) args.push('--quality', options.quality);
511
+ if (options.repoRoot) args.push('--repo-root', path.resolve(options.repoRoot));
512
+ let stdout = '';
513
+ let stderr = '';
514
+ child = spawn(process.execPath, args, {
515
+ cwd: options.cwd || process.cwd(),
516
+ env: process.env,
517
+ stdio: ['ignore', 'pipe', 'pipe'],
518
+ detached: process.platform !== 'win32',
519
+ });
520
+ child.stdout.setEncoding('utf8');
521
+ child.stderr.setEncoding('utf8');
522
+ child.stdout.on('data', (chunk) => { stdout += chunk; });
523
+ child.stderr.on('data', (chunk) => { stderr += chunk; });
524
+ child.on('error', (error) => { stderr += error.message; });
525
+ child.on('close', (code) => {
526
+ const receipt = parseReceipt(stdout);
527
+ const generationEpoch = activeEpoch;
528
+ const generationHash = activeHash;
529
+ const stale = generationEpoch !== sourceEpoch;
530
+ let supersededBy = null;
531
+ child = null;
532
+ clearTimeout(stopGraceTimer);
533
+ clearTimeout(stopKillTimer);
534
+ stopGraceTimer = undefined;
535
+ stopKillTimer = undefined;
536
+ if (!stopping && !stale && code === 0 && receipt?.ok) {
537
+ ({ supersededBy } = commitCandidate(candidatePath, receipt, generationHash));
538
+ } else if (!stopping && !stale) {
539
+ publishFailure(receipt, stdout, stderr, candidatePath, snapshotPath);
540
+ }
541
+ try { fs.rmSync(candidatePath, { force: true }); } catch {}
542
+ try { fs.rmSync(snapshotPath, { force: true }); } catch {}
543
+
544
+ if (stopping) {
545
+ finishStop();
546
+ } else if (pendingBuild || stale || supersededBy) {
547
+ pendingBuild = false;
548
+ if (supersededBy && sourceEpoch === generationEpoch) sourceEpoch += 1;
549
+ const digest = supersededBy || sourceDigest(inputPath);
550
+ queueStableBuild(digest.hash, true);
551
+ }
552
+ });
553
+ }
554
+
555
+ function queueStableBuild(hash, immediate = false) {
556
+ queuedHash = hash;
557
+ clearTimeout(debounceTimer);
558
+ const launch = () => {
559
+ if (stopping) return;
560
+ const digest = sourceDigest(inputPath);
561
+ if (digest.hash !== queuedHash) {
562
+ queueStableBuild(digest.hash);
563
+ return;
564
+ }
565
+ if (digest.hash === lastGoodSourceHash) {
566
+ if (state.status !== 'verified' && state.lastVerified) {
567
+ state.status = 'verified';
568
+ state.failure = null;
569
+ broadcast();
570
+ }
571
+ return;
572
+ }
573
+ if (child) {
574
+ pendingBuild = true;
575
+ return;
576
+ }
577
+ beginBuild(digest, sourceEpoch);
578
+ };
579
+ debounceTimer = setTimeout(launch, immediate ? 0 : debounceMs);
580
+ }
581
+
582
+ function observeSource({ immediate = false } = {}) {
583
+ const digest = sourceDigest(inputPath);
584
+ if (!immediate && digest.hash === queuedHash) return;
585
+ sourceEpoch += 1;
586
+ queueStableBuild(digest.hash, immediate);
587
+ }
588
+
589
+ if (options.watch !== false) {
590
+ try {
591
+ watcher = fs.watch(path.dirname(inputPath), (event, filename) => {
592
+ if (!filename || filename.toString() === path.basename(inputPath)) observeSource();
593
+ });
594
+ } catch (error) {
595
+ await stop();
596
+ throw new Error(`Could not watch the input directory: ${error.message}`);
597
+ }
598
+ }
599
+ pollTimer = setInterval(() => observeSource(), pollMs);
600
+
601
+ let opener = null;
602
+ if (shouldOpen) {
603
+ try {
604
+ opener = openLoopbackUrl(url);
605
+ } catch {
606
+ opener = { requested: true, status: 'unsupported', target: url, method: null };
607
+ }
608
+ }
609
+
610
+ observeSource({ immediate: true });
611
+
612
+ return {
613
+ url,
614
+ input: inputPath,
615
+ output: outputPath,
616
+ opener,
617
+ state: publicState,
618
+ stop,
619
+ closed,
620
+ };
621
+ }
622
+
623
+ export async function runPreview(options) {
624
+ const preview = await startPreview(options);
625
+ console.log(`preview ${preview.url}`);
626
+ console.log(`watching ${preview.input}`);
627
+ console.log(`output ${preview.output}`);
628
+ if (preview.opener && preview.opener.status !== 'opened') {
629
+ console.error(`Could not open the preview (${preview.opener.status}). Open it manually: ${preview.url}`);
630
+ }
631
+
632
+ let signalCount = 0;
633
+ const stop = () => {
634
+ signalCount += 1;
635
+ if (signalCount === 1) {
636
+ console.log('\nstopping preview…');
637
+ preview.stop();
638
+ } else {
639
+ console.log('\nforcing preview shutdown…');
640
+ preview.stop({ force: true });
641
+ }
642
+ };
643
+ process.on('SIGINT', stop);
644
+ process.on('SIGTERM', stop);
645
+ await preview.closed;
646
+ process.off('SIGINT', stop);
647
+ process.off('SIGTERM', stop);
648
+ }