nexakit 0.0.0-stage → 0.2.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 (438) hide show
  1. package/.claude-plugin/marketplace.json +28 -0
  2. package/LICENSE +26 -0
  3. package/README.md +79 -2
  4. package/agents/claude/docs-researcher.md +9 -0
  5. package/agents/claude/implementation-tutor.md +9 -0
  6. package/agents/claude/project-explorer.md +9 -0
  7. package/agents/claude/quality-reviewer.md +9 -0
  8. package/agents/claude/requirements-analyst.md +9 -0
  9. package/agents/claude/solution-architect.md +9 -0
  10. package/agents/codex/docs-researcher.toml +10 -0
  11. package/agents/codex/implementation-tutor.toml +10 -0
  12. package/agents/codex/project-explorer.toml +10 -0
  13. package/agents/codex/quality-reviewer.toml +10 -0
  14. package/agents/codex/requirements-analyst.toml +11 -0
  15. package/agents/codex/solution-architect.toml +10 -0
  16. package/assets/brand/README.md +38 -0
  17. package/assets/brand/agent-toolkit-mark.png +0 -0
  18. package/assets/brand/agent-toolkit-mark.svg +13 -0
  19. package/assets/brand/agent-toolkit-tui-hero.png +0 -0
  20. package/assets/brand/nexakit-readme-hero.png +0 -0
  21. package/assets/brand/nexakit-readme-hero.svg +21 -0
  22. package/assets/runtime/package-lock.json +1425 -0
  23. package/bin/agent-task.js +14 -0
  24. package/bin/agent-toolkit-gemini.js +13 -0
  25. package/bin/agent-toolkit-inbox.js +14 -0
  26. package/bin/agent-toolkit-mcp.js +17 -0
  27. package/bin/agent-toolkit.js +13 -0
  28. package/bin/nexakit.js +13 -0
  29. package/bin/project-memory-mcp.js +22 -0
  30. package/bin/project-memory.js +7 -0
  31. package/catalogs/skills/api-design-principles/LICENSE.txt +21 -0
  32. package/catalogs/skills/api-design-principles/SKILL.md +110 -0
  33. package/catalogs/skills/api-design-principles/assets/api-design-checklist.md +155 -0
  34. package/catalogs/skills/api-design-principles/assets/rest-api-template.py +185 -0
  35. package/catalogs/skills/api-design-principles/references/details.md +413 -0
  36. package/catalogs/skills/api-design-principles/references/graphql-schema-design.md +589 -0
  37. package/catalogs/skills/api-design-principles/references/rest-best-practices.md +408 -0
  38. package/catalogs/skills/nodejs-backend-patterns/LICENSE.txt +21 -0
  39. package/catalogs/skills/nodejs-backend-patterns/SKILL.md +45 -0
  40. package/catalogs/skills/nodejs-backend-patterns/references/advanced-patterns.md +430 -0
  41. package/catalogs/skills/nodejs-backend-patterns/references/details.md +599 -0
  42. package/catalogs/skills/supabase-postgres-best-practices/CHANGELOG.md +73 -0
  43. package/catalogs/skills/supabase-postgres-best-practices/LICENSE.txt +21 -0
  44. package/catalogs/skills/supabase-postgres-best-practices/SKILL.md +64 -0
  45. package/catalogs/skills/supabase-postgres-best-practices/references/_contributing.md +170 -0
  46. package/catalogs/skills/supabase-postgres-best-practices/references/_sections.md +39 -0
  47. package/catalogs/skills/supabase-postgres-best-practices/references/_template.md +34 -0
  48. package/catalogs/skills/supabase-postgres-best-practices/references/advanced-full-text-search.md +55 -0
  49. package/catalogs/skills/supabase-postgres-best-practices/references/advanced-jsonb-indexing.md +49 -0
  50. package/catalogs/skills/supabase-postgres-best-practices/references/conn-idle-timeout.md +46 -0
  51. package/catalogs/skills/supabase-postgres-best-practices/references/conn-limits.md +44 -0
  52. package/catalogs/skills/supabase-postgres-best-practices/references/conn-pooling.md +41 -0
  53. package/catalogs/skills/supabase-postgres-best-practices/references/conn-prepared-statements.md +46 -0
  54. package/catalogs/skills/supabase-postgres-best-practices/references/data-batch-inserts.md +54 -0
  55. package/catalogs/skills/supabase-postgres-best-practices/references/data-n-plus-one.md +53 -0
  56. package/catalogs/skills/supabase-postgres-best-practices/references/data-pagination.md +50 -0
  57. package/catalogs/skills/supabase-postgres-best-practices/references/data-upsert.md +50 -0
  58. package/catalogs/skills/supabase-postgres-best-practices/references/lock-advisory.md +56 -0
  59. package/catalogs/skills/supabase-postgres-best-practices/references/lock-deadlock-prevention.md +68 -0
  60. package/catalogs/skills/supabase-postgres-best-practices/references/lock-short-transactions.md +50 -0
  61. package/catalogs/skills/supabase-postgres-best-practices/references/lock-skip-locked.md +54 -0
  62. package/catalogs/skills/supabase-postgres-best-practices/references/monitor-explain-analyze.md +45 -0
  63. package/catalogs/skills/supabase-postgres-best-practices/references/monitor-pg-stat-statements.md +55 -0
  64. package/catalogs/skills/supabase-postgres-best-practices/references/monitor-vacuum-analyze.md +55 -0
  65. package/catalogs/skills/supabase-postgres-best-practices/references/query-composite-indexes.md +44 -0
  66. package/catalogs/skills/supabase-postgres-best-practices/references/query-covering-indexes.md +40 -0
  67. package/catalogs/skills/supabase-postgres-best-practices/references/query-index-types.md +48 -0
  68. package/catalogs/skills/supabase-postgres-best-practices/references/query-missing-indexes.md +43 -0
  69. package/catalogs/skills/supabase-postgres-best-practices/references/query-partial-indexes.md +45 -0
  70. package/catalogs/skills/supabase-postgres-best-practices/references/schema-constraints.md +80 -0
  71. package/catalogs/skills/supabase-postgres-best-practices/references/schema-data-types.md +46 -0
  72. package/catalogs/skills/supabase-postgres-best-practices/references/schema-foreign-key-indexes.md +59 -0
  73. package/catalogs/skills/supabase-postgres-best-practices/references/schema-lowercase-identifiers.md +55 -0
  74. package/catalogs/skills/supabase-postgres-best-practices/references/schema-partitioning.md +55 -0
  75. package/catalogs/skills/supabase-postgres-best-practices/references/schema-primary-keys.md +61 -0
  76. package/catalogs/skills/supabase-postgres-best-practices/references/security-privileges.md +54 -0
  77. package/catalogs/skills/supabase-postgres-best-practices/references/security-rls-basics.md +50 -0
  78. package/catalogs/skills/supabase-postgres-best-practices/references/security-rls-performance.md +63 -0
  79. package/catalogs/skills/vercel-composition-patterns/AGENTS.md +946 -0
  80. package/catalogs/skills/vercel-composition-patterns/LICENSE.txt +27 -0
  81. package/catalogs/skills/vercel-composition-patterns/README.md +60 -0
  82. package/catalogs/skills/vercel-composition-patterns/SKILL.md +89 -0
  83. package/catalogs/skills/vercel-composition-patterns/metadata.json +11 -0
  84. package/catalogs/skills/vercel-composition-patterns/rules/_sections.md +29 -0
  85. package/catalogs/skills/vercel-composition-patterns/rules/_template.md +24 -0
  86. package/catalogs/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  87. package/catalogs/skills/vercel-composition-patterns/rules/architecture-compound-components.md +112 -0
  88. package/catalogs/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  89. package/catalogs/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +100 -0
  90. package/catalogs/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
  91. package/catalogs/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
  92. package/catalogs/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +113 -0
  93. package/catalogs/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
  94. package/catalogs/skills/vercel-react-best-practices/AGENTS.md +3810 -0
  95. package/catalogs/skills/vercel-react-best-practices/LICENSE.txt +27 -0
  96. package/catalogs/skills/vercel-react-best-practices/README.md +123 -0
  97. package/catalogs/skills/vercel-react-best-practices/SKILL.md +149 -0
  98. package/catalogs/skills/vercel-react-best-practices/metadata.json +15 -0
  99. package/catalogs/skills/vercel-react-best-practices/rules/_sections.md +46 -0
  100. package/catalogs/skills/vercel-react-best-practices/rules/_template.md +28 -0
  101. package/catalogs/skills/vercel-react-best-practices/rules/advanced-effect-event-deps.md +56 -0
  102. package/catalogs/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  103. package/catalogs/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
  104. package/catalogs/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
  105. package/catalogs/skills/vercel-react-best-practices/rules/async-api-routes.md +38 -0
  106. package/catalogs/skills/vercel-react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
  107. package/catalogs/skills/vercel-react-best-practices/rules/async-defer-await.md +82 -0
  108. package/catalogs/skills/vercel-react-best-practices/rules/async-dependencies.md +51 -0
  109. package/catalogs/skills/vercel-react-best-practices/rules/async-parallel.md +28 -0
  110. package/catalogs/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
  111. package/catalogs/skills/vercel-react-best-practices/rules/bundle-analyzable-paths.md +63 -0
  112. package/catalogs/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +60 -0
  113. package/catalogs/skills/vercel-react-best-practices/rules/bundle-conditional.md +31 -0
  114. package/catalogs/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +49 -0
  115. package/catalogs/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  116. package/catalogs/skills/vercel-react-best-practices/rules/bundle-preload.md +50 -0
  117. package/catalogs/skills/vercel-react-best-practices/rules/client-event-listeners.md +74 -0
  118. package/catalogs/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +71 -0
  119. package/catalogs/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
  120. package/catalogs/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
  121. package/catalogs/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +107 -0
  122. package/catalogs/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
  123. package/catalogs/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
  124. package/catalogs/skills/vercel-react-best-practices/rules/js-cache-storage.md +70 -0
  125. package/catalogs/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
  126. package/catalogs/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
  127. package/catalogs/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +60 -0
  128. package/catalogs/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
  129. package/catalogs/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
  130. package/catalogs/skills/vercel-react-best-practices/rules/js-length-check-first.md +49 -0
  131. package/catalogs/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
  132. package/catalogs/skills/vercel-react-best-practices/rules/js-request-idle-callback.md +105 -0
  133. package/catalogs/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
  134. package/catalogs/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
  135. package/catalogs/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
  136. package/catalogs/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  137. package/catalogs/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +40 -0
  138. package/catalogs/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
  139. package/catalogs/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  140. package/catalogs/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  141. package/catalogs/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  142. package/catalogs/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +85 -0
  143. package/catalogs/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +68 -0
  144. package/catalogs/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
  145. package/catalogs/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  146. package/catalogs/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
  147. package/catalogs/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
  148. package/catalogs/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  149. package/catalogs/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
  150. package/catalogs/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +74 -0
  151. package/catalogs/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  152. package/catalogs/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  153. package/catalogs/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
  154. package/catalogs/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  155. package/catalogs/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +82 -0
  156. package/catalogs/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  157. package/catalogs/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
  158. package/catalogs/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
  159. package/catalogs/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +59 -0
  160. package/catalogs/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  161. package/catalogs/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
  162. package/catalogs/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
  163. package/catalogs/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
  164. package/catalogs/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
  165. package/catalogs/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
  166. package/catalogs/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +149 -0
  167. package/catalogs/skills/vercel-react-best-practices/rules/server-no-shared-module-state.md +50 -0
  168. package/catalogs/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
  169. package/catalogs/skills/vercel-react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
  170. package/catalogs/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
  171. package/catalogs/skills/webapp-testing/LICENSE.txt +202 -0
  172. package/catalogs/skills/webapp-testing/SKILL.md +96 -0
  173. package/catalogs/skills/webapp-testing/examples/console_logging.py +35 -0
  174. package/catalogs/skills/webapp-testing/examples/element_discovery.py +40 -0
  175. package/catalogs/skills/webapp-testing/examples/static_html_automation.py +33 -0
  176. package/catalogs/skills/webapp-testing/scripts/with_server.py +106 -0
  177. package/catalogs/skills.json +1115 -0
  178. package/docs/skills/evidencias/2026-10-28-evaluacion-inicial-mcp-seguridad.md +118 -0
  179. package/docs/skills/evidencias/2026-10-28-incorporacion-mcp-seguridad.json +152 -0
  180. package/docs/skills/evidencias/2026-10-28-recomendador-preparacion.md +50 -0
  181. package/package.json +73 -4
  182. package/plugins/nexakit-modelo/.claude-plugin/plugin.json +1 -0
  183. package/plugins/nexakit-modelo/hooks/hooks.json +1 -0
  184. package/plugins/nexakit-modelo/hooks/register.js +48 -0
  185. package/plugins/nexakit-modelo/hooks/status.js +8 -0
  186. package/plugins/nexakit-modelo/tests/register.test.ts +21 -0
  187. package/plugins/nexakit-panel/.claude-plugin/plugin.json +1 -0
  188. package/plugins/nexakit-panel/README.md +20 -0
  189. package/plugins/nexakit-panel/hooks/hooks.json +1 -0
  190. package/plugins/nexakit-panel/hooks/lienzo.js +382 -0
  191. package/plugins/nexakit-panel/hooks/panel.js +279 -0
  192. package/plugins/nexakit-panel/hooks/register.tsx +248 -0
  193. package/plugins/nexakit-panel/tests/lienzo.test.ts +142 -0
  194. package/plugins/nexakit-panel/tests/panel.test.ts +240 -0
  195. package/plugins/nexakit-panel/tests/register.test.ts +167 -0
  196. package/plugins/nexakit-panel/types/index.d.ts +41 -0
  197. package/plugins/nexakit-sesion/.claude-plugin/plugin.json +1 -0
  198. package/plugins/nexakit-sesion/README.md +12 -0
  199. package/plugins/nexakit-sesion/hooks/aviso.js +38 -0
  200. package/plugins/nexakit-sesion/hooks/hooks.json +1 -0
  201. package/plugins/nexakit-sesion/hooks/register.js +28 -0
  202. package/plugins/nexakit-sesion/tests/register.test.ts +96 -0
  203. package/plugins/niveles/.claude-plugin/plugin.json +5 -0
  204. package/plugins/niveles/agents/nivel-alto.md +13 -0
  205. package/plugins/niveles/agents/nivel-exigente.md +13 -0
  206. package/plugins/niveles/agents/nivel-ligero.md +13 -0
  207. package/plugins/niveles/agents/nivel-normal.md +13 -0
  208. package/schemas/agent-client-adapter.schema.json +786 -0
  209. package/schemas/agent-client-auth-diagnostic.schema.json +801 -0
  210. package/schemas/agent-client-isolated-variant.schema.json +105 -0
  211. package/schemas/agent-client-isolated-verification.schema.json +99 -0
  212. package/schemas/agent-client-managed-preferences-invocation.schema.json +67 -0
  213. package/schemas/agent-client-managed-preferences.schema.json +63 -0
  214. package/schemas/agent-client-native-diagnostics.schema.json +85 -0
  215. package/schemas/agent-client-native-evaluation.schema.json +171 -0
  216. package/schemas/agent-client-native-preflight.schema.json +90 -0
  217. package/schemas/agent-client-output.schema.json +551 -0
  218. package/schemas/agent-client-runtime-fixture.schema.json +90 -0
  219. package/schemas/agent-client-runtime-local.schema.json +95 -0
  220. package/schemas/agent-client-runtime.schema.json +1288 -0
  221. package/schemas/agent-client-selective-config.schema.json +77 -0
  222. package/schemas/agent-client-supervised-local.schema.json +135 -0
  223. package/schemas/agent-client-supervised.schema.json +186 -0
  224. package/schemas/agent-model-preference.schema.json +573 -0
  225. package/schemas/agent-model-selection.schema.json +311 -0
  226. package/schemas/agent-task-approvals.schema.json +362 -0
  227. package/schemas/agent-task-prepare.schema.json +1324 -0
  228. package/schemas/agent-task-verify.schema.json +198 -0
  229. package/schemas/project-memory-update.schema.json +33 -0
  230. package/schemas/project-memory.schema.json +298 -0
  231. package/schemas/skill-catalog.schema.json +246 -0
  232. package/schemas/task-workflow-plan-output.schema.json +35 -0
  233. package/scripts/prepare-package.js +6 -0
  234. package/scripts/validate-skill-catalog.js +41 -0
  235. package/skills/cerrar-avisens/SKILL.md +12 -0
  236. package/skills/cerrar-memoria/SKILL.md +96 -0
  237. package/skills/cerrar-memoria/references/cierre.md +76 -0
  238. package/skills/decision-records/SKILL.md +27 -0
  239. package/skills/decision-records/agents/openai.yaml +7 -0
  240. package/skills/decision-records/references/adr-template.md +35 -0
  241. package/skills/differential-review/LICENSE.txt +427 -0
  242. package/skills/differential-review/SKILL.md +225 -0
  243. package/skills/differential-review/adversarial.md +203 -0
  244. package/skills/differential-review/agents/openai.yaml +6 -0
  245. package/skills/differential-review/assets/trail-of-bits-mark.svg +1 -0
  246. package/skills/differential-review/methodology.md +234 -0
  247. package/skills/differential-review/patterns.md +300 -0
  248. package/skills/differential-review/reporting.md +369 -0
  249. package/skills/elegir-modelo/SKILL.md +68 -0
  250. package/skills/elegir-modelo/modelos.mjs +108 -0
  251. package/skills/frontend-design/LICENSE.txt +177 -0
  252. package/skills/frontend-design/SKILL.md +71 -0
  253. package/skills/gemini/SKILL.md +52 -0
  254. package/skills/imagen/SKILL.md +12 -0
  255. package/skills/investigar/SKILL.md +11 -0
  256. package/skills/mcp-builder/LICENSE.txt +202 -0
  257. package/skills/mcp-builder/SKILL.md +236 -0
  258. package/skills/mcp-builder/reference/evaluation.md +602 -0
  259. package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  260. package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  261. package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  262. package/skills/mcp-builder/scripts/connections.py +151 -0
  263. package/skills/mcp-builder/scripts/evaluation.py +373 -0
  264. package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  265. package/skills/mcp-builder/scripts/requirements.txt +2 -0
  266. package/skills/ordenar-proyecto/SKILL.md +56 -0
  267. package/skills/project-handoff/SKILL.md +53 -0
  268. package/skills/project-handoff/agents/openai.yaml +7 -0
  269. package/skills/project-handoff/references/handoff-template.md +35 -0
  270. package/skills/quality-gate/LICENSE.txt +26 -0
  271. package/skills/quality-gate/SKILL.md +44 -0
  272. package/skills/quality-gate/agents/openai.yaml +7 -0
  273. package/skills/quality-gate/references/review-checklist.md +42 -0
  274. package/skills/revisar/SKILL.md +11 -0
  275. package/skills/revisar-skill/LICENSE-find-skills.txt +26 -0
  276. package/skills/revisar-skill/SKILL.md +94 -0
  277. package/skills/revision-cruzada/SKILL.md +59 -0
  278. package/skills/web-design-guidelines/AGENTS.md +156 -0
  279. package/skills/web-design-guidelines/LICENSE.txt +21 -0
  280. package/skills/web-design-guidelines/SKILL.md +29 -0
  281. package/src/agent-models.js +131 -0
  282. package/src/brand.js +117 -0
  283. package/src/claude-code-runner.js +642 -0
  284. package/src/cli-executable.js +88 -0
  285. package/src/cli.js +778 -0
  286. package/src/client-adapter-plan.js +271 -0
  287. package/src/client-auth-diagnostic-parser.js +211 -0
  288. package/src/client-auth-diagnostic.js +257 -0
  289. package/src/client-isolated-variant.js +106 -0
  290. package/src/client-isolated-verification.js +130 -0
  291. package/src/client-local-platform.js +14 -0
  292. package/src/client-managed-preferences-invocation.js +209 -0
  293. package/src/client-managed-preferences.js +78 -0
  294. package/src/client-native-access.js +134 -0
  295. package/src/client-native-diagnostics.js +253 -0
  296. package/src/client-native-evaluation.js +106 -0
  297. package/src/client-native-preflight-files.js +68 -0
  298. package/src/client-native-preflight.js +95 -0
  299. package/src/client-output-json.js +118 -0
  300. package/src/client-output-parser.js +278 -0
  301. package/src/client-runtime-admission.js +80 -0
  302. package/src/client-runtime-coordinator.js +70 -0
  303. package/src/client-runtime-core.js +92 -0
  304. package/src/client-runtime-fixture-permit.js +20 -0
  305. package/src/client-runtime-fixture-protocol.js +39 -0
  306. package/src/client-runtime-state.js +67 -0
  307. package/src/client-runtime-store-files.js +91 -0
  308. package/src/client-runtime-store.js +239 -0
  309. package/src/client-runtime-supervisor.js +146 -0
  310. package/src/client-selective-config.js +195 -0
  311. package/src/client-selective-files.js +126 -0
  312. package/src/client-supervised-codes.js +32 -0
  313. package/src/client-supervised-contract.js +52 -0
  314. package/src/client-supervised-coordinator.js +36 -0
  315. package/src/client-supervised-permit.js +20 -0
  316. package/src/client-supervised-protocol.js +37 -0
  317. package/src/client-supervised-store.js +167 -0
  318. package/src/client-supervised-supervisor.js +167 -0
  319. package/src/client-supervised.js +160 -0
  320. package/src/codex-cli-runner.js +358 -0
  321. package/src/codex-delivery.js +101 -0
  322. package/src/connect.js +703 -0
  323. package/src/doctor.js +795 -0
  324. package/src/gemini-cli.js +76 -0
  325. package/src/gemini-files.js +45 -0
  326. package/src/gemini-tools.js +249 -0
  327. package/src/init.js +473 -0
  328. package/src/install-lock.js +127 -0
  329. package/src/install-registry.js +61 -0
  330. package/src/legacy-repair.js +71 -0
  331. package/src/level-agents.js +111 -0
  332. package/src/link-states.js +172 -0
  333. package/src/memory-connection-artifacts.js +192 -0
  334. package/src/memory-connection-descriptor.js +158 -0
  335. package/src/memory-connection-diagnostic.js +177 -0
  336. package/src/memory-connection-files.js +191 -0
  337. package/src/memory-connection-manifest.js +118 -0
  338. package/src/memory-connection-package.js +176 -0
  339. package/src/memory-connection-plan.js +211 -0
  340. package/src/memory-connection-skill.js +211 -0
  341. package/src/memory-connection-toml.js +153 -0
  342. package/src/memory-locator.js +118 -0
  343. package/src/memory-mcp-policy.js +181 -0
  344. package/src/memory-mcp-server.js +166 -0
  345. package/src/memory-mcp-transport.js +59 -0
  346. package/src/missing-dependencies.js +21 -0
  347. package/src/model-command.js +147 -0
  348. package/src/model-preference.js +235 -0
  349. package/src/model-selection.js +368 -0
  350. package/src/native/managed-preferences.c +100 -0
  351. package/src/native/managed-preferences.h +17 -0
  352. package/src/package-lock-path.js +13 -0
  353. package/src/panel-cli.js +182 -0
  354. package/src/peer-handoff.js +27 -0
  355. package/src/peer-inbox-cli.js +211 -0
  356. package/src/peer-review-mcp.js +210 -0
  357. package/src/peer-review-store.js +532 -0
  358. package/src/platform.js +24 -0
  359. package/src/project-root.js +41 -0
  360. package/src/project-signals.js +339 -0
  361. package/src/recommend-report.js +77 -0
  362. package/src/review-instructions.js +211 -0
  363. package/src/review-policy.js +35 -0
  364. package/src/revision-adapters.js +157 -0
  365. package/src/revision-context.js +86 -0
  366. package/src/revision-isolation.js +222 -0
  367. package/src/revision-process.js +103 -0
  368. package/src/revision-provenance.js +89 -0
  369. package/src/revision-snapshot.js +120 -0
  370. package/src/revision.js +242 -0
  371. package/src/runtime-fixtures/runtime-supervisor/child.cjs +3 -0
  372. package/src/runtime-fixtures/runtime-supervisor/fixture.cjs +49 -0
  373. package/src/runtime-fixtures/supervised/child.cjs +3 -0
  374. package/src/runtime-fixtures/supervised/fixture.cjs +47 -0
  375. package/src/sensitive-data.js +21 -0
  376. package/src/setup-apply.js +231 -0
  377. package/src/setup-plan.js +231 -0
  378. package/src/setup-state.js +277 -0
  379. package/src/setup-tui.js +555 -0
  380. package/src/skill-catalog-add.js +91 -0
  381. package/src/skill-catalog-audit.js +68 -0
  382. package/src/skill-catalog.js +170 -0
  383. package/src/skill-files.js +39 -0
  384. package/src/skill-recommendations.js +1673 -0
  385. package/src/skill-scan-report.js +14 -0
  386. package/src/skill-scan.js +178 -0
  387. package/src/stable-command.js +53 -0
  388. package/src/stable-install.js +222 -0
  389. package/src/status.js +200 -0
  390. package/src/superpowers.js +133 -0
  391. package/src/sync-apply.js +227 -0
  392. package/src/sync-files.js +109 -0
  393. package/src/sync-inspect.js +394 -0
  394. package/src/sync-ledger.js +94 -0
  395. package/src/sync-markdown.js +151 -0
  396. package/src/sync-proposal.js +84 -0
  397. package/src/sync-record.js +459 -0
  398. package/src/sync.js +360 -0
  399. package/src/task-approvals.js +367 -0
  400. package/src/task-cli.js +79 -0
  401. package/src/task-external-verifier.js +584 -0
  402. package/src/task-prepare-files.js +115 -0
  403. package/src/task-prepare.js +180 -0
  404. package/src/task-verify-cli.js +67 -0
  405. package/src/task-verify-files.js +188 -0
  406. package/src/task-verify.js +118 -0
  407. package/src/task-workflow-mcp.js +544 -0
  408. package/src/task-workflow-store.js +254 -0
  409. package/src/terminal-text.js +68 -0
  410. package/src/toolkit-cli.js +543 -0
  411. package/src/toolkit-commands-guide.js +107 -0
  412. package/src/toolkit-setup.js +614 -0
  413. package/src/usage-metrics.js +43 -0
  414. package/templates/agent-team/01-encargo.md +158 -0
  415. package/templates/agent-team/02-propuesta.md +132 -0
  416. package/templates/agent-team/03-revision.md +150 -0
  417. package/templates/agent-team/README.md +213 -0
  418. package/templates/model-inventory/01-inventario.md +154 -0
  419. package/templates/model-inventory/README.md +115 -0
  420. package/templates/project-memory/README.md +67 -0
  421. package/templates/project-memory/project-memory.example.json +53 -0
  422. package/templates/project-memory/skill/project-id/SKILL.md +37 -0
  423. package/templates/project-memory/skill/project-id/references/project-profile.md +44 -0
  424. package/templates/project-memory/vault/00-INICIO/Estado actual.md +44 -0
  425. package/templates/project-memory/vault/00-INICIO/Fuentes de verdad.md +30 -0
  426. package/templates/project-memory/vault/00-INICIO/Inicio del proyecto.md +44 -0
  427. package/templates/project-memory/vault/00-INICIO/Mantenimiento de la memoria.md +26 -0
  428. package/templates/project-memory/vault/00-INICIO/Mapa de la memoria.md +33 -0
  429. package/templates/project-memory/vault/00-INICIO/Registro de sincronizaci/303/263n.md" +28 -0
  430. package/templates/project-memory/vault/01-PRODUCTO/Producto.md +16 -0
  431. package/templates/project-memory/vault/02-ARQUITECTURA/Arquitectura.md +16 -0
  432. package/templates/project-memory/vault/03-IMPLEMENTACION/Implementaci/303/263n.md +15 -0
  433. package/templates/project-memory/vault/04-DECISIONES/Decisiones.md +19 -0
  434. package/templates/project-memory/vault/05-ENTREGAS/Entregas.md +12 -0
  435. package/templates/project-memory/vault/06-OPERACION/Operaci/303/263n.md +15 -0
  436. package/templates/project-memory/vault/07-AGENTES/Protocolo de agentes.md +33 -0
  437. package/templates/project-memory/vault/08-RECURSOS/Recursos.md +12 -0
  438. package/templates/project-memory/vault/09-ARCHIVO/README.md +5 -0
@@ -0,0 +1,367 @@
1
+ import { createHash } from "node:crypto";
2
+ import Ajv2020 from "ajv/dist/2020.js";
3
+ import { copyBytes, copyInertJson, decode, fail, parseEventJson, ParseFailure } from "./client-output-json.js";
4
+
5
+ export const APPROVALS_ID = "https://agent-toolkit.local/schemas/agent-task-approvals.schema.json";
6
+ export const LIMITS = Object.freeze({ maxBytes: 1_000_000, maxEvents: 256 });
7
+ const OPEN = ["reserved", "started", "indeterminate"];
8
+ const BAD_PATH = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}\\*?[\]{}]/u;
9
+
10
+ // Declared data only: nothing here proves who approved, what ran or what time it is.
11
+ class Refusal extends Error {
12
+ constructor(state, code) { super(code); this.state = state; this.code = code; }
13
+ }
14
+ const block = code => { throw new Refusal("blocked", code); };
15
+
16
+ function canonical(v) {
17
+ if (v === null || typeof v !== "object") return JSON.stringify(v);
18
+ if (Array.isArray(v)) return `[${v.map(canonical).join(",")}]`;
19
+ return `{${Object.keys(v).sort().map(k => `${JSON.stringify(k)}:${canonical(v[k])}`).join(",")}}`;
20
+ }
21
+ // Internal: input is already inert JSON (validated or copied), so no further checks.
22
+ const digest = v => createHash("sha256").update(canonical(v)).digest("hex");
23
+ /**
24
+ * Canonical SHA-256 of JSON data. It identifies content; it does not authenticate anyone.
25
+ * Only bounded inert JSON is accepted: getters, proxies, cycles, functions (toJSON) and
26
+ * non-plain objects are rejected by copyInertJson without invoking any callback.
27
+ */
28
+ export function approvalHash(value) { return digest(copyInertJson(value)); }
29
+ const same = (a, b) => canonical(a) === canonical(b);
30
+ function freeze(v) {
31
+ if (v && typeof v === "object") { Object.values(v).forEach(freeze); Object.freeze(v); }
32
+ return v;
33
+ }
34
+
35
+ function validTime(v) {
36
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/.test(v)) return false;
37
+ const t = Date.parse(v);
38
+ return Number.isFinite(t) && new Date(t).toISOString() === v.replace(/Z$/, ".000Z");
39
+ }
40
+ function validPath(p) {
41
+ if (typeof p !== "string" || p.length === 0 || p.length > 256 || p !== p.normalize("NFC") || BAD_PATH.test(p)) return false;
42
+ if (/^[A-Za-z]:/.test(p)) return false;
43
+ return p.split("/").every(s => s !== "" && s !== "." && s !== "..");
44
+ }
45
+ // Logical comparison only. Symlinks and physical aliases are out of scope for this core.
46
+ function pathFacts(items) {
47
+ const pairs = new Set(); const folded = new Map();
48
+ for (const { path, action } of items) {
49
+ if (!validPath(path)) fail("invalid-approval-path");
50
+ const pair = JSON.stringify([path, action]);
51
+ if (pairs.has(pair)) fail("duplicate-approval-path");
52
+ pairs.add(pair);
53
+ const key = path.normalize("NFKC").toLowerCase();
54
+ if (folded.has(key) && folded.get(key) !== path) fail("path-collision");
55
+ folded.set(key, path);
56
+ }
57
+ const keys = [...folded.keys()];
58
+ if (keys.some(k => keys.some(o => o.startsWith(`${k}/`)))) fail("path-file-directory-conflict");
59
+ }
60
+ // Effects must match what the actions and checks imply, in both directions. Never auto-added.
61
+ function effectFacts(items, checks, effects) {
62
+ if (items.some(i => i.action !== "read") !== effects.includes("workspace-write")) fail("effect-path-mismatch");
63
+ if ((checks.length > 0) !== effects.includes("test-execution")) fail("effect-check-mismatch");
64
+ }
65
+
66
+ const itemKey = i => JSON.stringify([i.path, i.action]);
67
+ // Identity of the work, not of its bookkeeping: ids, array order and the base do not matter,
68
+ // the concrete artifact does. A reviewed correction therefore is new work, not a repeat.
69
+ const workKey = (items, checks, effects, artifactSha256) =>
70
+ canonical([items.map(itemKey).sort(), [...checks].sort(), [...effects].sort(), artifactSha256]);
71
+ const within = (items, allowed, key = x => x) => {
72
+ const set = new Set(allowed.map(key));
73
+ return items.every(i => set.has(key(i)));
74
+ };
75
+ const live = r => r.ops.filter(o => o.state !== "released-declared");
76
+ const remaining = r => ({
77
+ operations: Math.max(0, r.scope.limits.maxOperations - live(r).length),
78
+ corrections: Math.max(0, r.scope.limits.maxCorrections - r.corrections),
79
+ retries: Math.max(0, r.scope.limits.maxRetries - r.retries)
80
+ });
81
+ // A new request may follow only requests that consumed nothing. Renewals after consumption,
82
+ // overlapping requests and other recipients need an accounting context RA-A does not have.
83
+ const pristine = r => r.status === "denied"
84
+ || ((r.status === "revoked" || r.status === "closed") && r.ops.length === 0 && r.corrections === 0);
85
+
86
+ function requestFacts(e, history) {
87
+ const { scope } = e;
88
+ if (scope.projectId !== history.projectId || scope.taskId !== history.taskId) fail("foreign-request-identity");
89
+ if (digest(scope) !== e.scopeSha256) fail("scope-hash-mismatch");
90
+ if (!validTime(scope.validFrom) || !validTime(scope.expiresAt) || Date.parse(scope.validFrom) >= Date.parse(scope.expiresAt)) fail("invalid-validity");
91
+ if (scope.limits.maxRetries >= scope.limits.maxOperations) fail("invalid-limits");
92
+ pathFacts(scope.paths);
93
+ effectFacts(scope.paths, scope.checks, scope.effects);
94
+ const seen = new Set();
95
+ for (const t of e.baseBinding.transitions) {
96
+ const key = `${t.fromSha256}>${t.toSha256}`;
97
+ if (t.fromSha256 === t.toSha256 || seen.has(key)) fail("invalid-base-transition");
98
+ seen.add(key);
99
+ }
100
+ }
101
+
102
+ function newRequest(e) {
103
+ return {
104
+ requestId: e.requestId, scope: e.scope, scopeSha256: e.scopeSha256, requestSha256: digest(e), status: "pending",
105
+ artifact: e.artifact, revisions: new Set([e.artifact.revision]), shas: new Set([e.artifact.sha256]),
106
+ corrections: 0, retries: 0, base: e.baseBinding.initialSha256, transitions: e.baseBinding.transitions,
107
+ divergedBase: null, ops: []
108
+ };
109
+ }
110
+
111
+ // Shared by reserve events and prospective coverage. Returns null or [state, reason].
112
+ function admission(r, s, now) {
113
+ if (r.status === "pending") return ["approval-needed", "decision-pending"];
114
+ if (r.status !== "approved") return ["blocked", r.status];
115
+ if (!within(s.items, r.scope.paths, itemKey) || !within(s.checks, r.scope.checks) || !within(s.effects, r.scope.effects)) return ["approval-needed", "outside-scope"];
116
+ if (r.divergedBase !== null) return ["blocked", "unexpected-base-change"];
117
+ if (s.base !== r.base) return ["blocked", "base-diverged"];
118
+ if (s.revision !== r.artifact.revision || (s.sha !== null && s.sha !== r.artifact.sha256)) return ["blocked", "artifact-mismatch"];
119
+ if (r.ops.some(o => o.state === "indeterminate")) return ["reconciliation-required", "reconciliation-required"];
120
+ if (r.ops.some(o => OPEN.includes(o.state))) return ["blocked", "operation-in-progress"];
121
+ if (now < Date.parse(r.scope.validFrom)) return ["blocked", "not-yet-valid"];
122
+ if (now >= Date.parse(r.scope.expiresAt)) return ["approval-needed", "expired"];
123
+ if (live(r).length >= r.scope.limits.maxOperations) return ["approval-needed", "budget-exhausted"];
124
+ const key = workKey(s.items, s.checks, s.effects, r.artifact.sha256);
125
+ const twins = live(r).filter(o => o.key === key);
126
+ if (twins.some(o => o.state === "succeeded")) return ["blocked", "operation-already-finished"];
127
+ if (s.retryOf === null) return twins.length ? ["blocked", "undeclared-retry"] : null;
128
+ const origin = r.ops.find(o => o.operationId === s.retryOf);
129
+ if (!origin || origin.state !== "failed" || origin.key !== key) return ["blocked", "invalid-retry"];
130
+ if (r.retries >= r.scope.limits.maxRetries) return ["approval-needed", "retry-not-allowed"];
131
+ return null;
132
+ }
133
+
134
+ // Per-file queries inside an already reserved operation: read-only, they never consume a use.
135
+ function inFlight(r, q, now) {
136
+ if (r.status !== "approved") return ["blocked", r.status];
137
+ const o = r.ops.find(x => x.operationId === q.operationId);
138
+ if (!o) return ["blocked", "unknown-operation"];
139
+ if (o.state === "indeterminate") return ["reconciliation-required", "reconciliation-required"];
140
+ if (o.state !== "reserved" && o.state !== "started") return ["blocked", "operation-finished"];
141
+ if (now >= Date.parse(r.scope.expiresAt)) return ["blocked", "expired-in-flight"];
142
+ if (!within(q.items, o.items, itemKey) || !within(q.checks, o.checks) || !within(q.effects, o.effects)) return ["blocked", "outside-operation"];
143
+ if (q.observedBaseSha256 !== o.expectedBase) return ["blocked", "base-diverged"];
144
+ if (q.artifact.revision !== o.artifactRevision || q.artifact.sha256 !== o.artifactSha256) return ["blocked", "artifact-mismatch"];
145
+ return null;
146
+ }
147
+
148
+ // An unexpected base is recorded, not hidden: the approval stays, new coverage is blocked.
149
+ function settle(r, o, outcome, resulting) {
150
+ if (outcome === "succeeded" && resulting === null) fail("missing-result-base");
151
+ o.state = outcome;
152
+ if (resulting === null || resulting === o.expectedBase) return;
153
+ if (r.transitions.some(t => t.fromSha256 === o.expectedBase && t.toSha256 === resulting)) r.base = resulting;
154
+ else r.divergedBase = resulting;
155
+ }
156
+
157
+ function operationEvent(r, e, at, claim) {
158
+ const o = r.ops.find(x => x.operationId === e.operationId);
159
+ if (!o) block("unknown-operation");
160
+ if (e.type === "start") {
161
+ if (o.state !== "reserved") block("invalid-operation-transition");
162
+ if (r.status !== "approved") block(r.status);
163
+ if (at >= Date.parse(r.scope.expiresAt)) block("expired");
164
+ o.state = "started"; o.sawStart = true; o.lastEventId = e.eventId;
165
+ } else if (e.type === "interrupt") {
166
+ if (o.state !== "reserved" && o.state !== "started") block("invalid-operation-transition");
167
+ o.state = "indeterminate"; o.lastEventId = e.eventId;
168
+ } else if (e.type === "result") {
169
+ if (o.state !== "started") block("invalid-operation-transition");
170
+ settle(r, o, e.outcome, e.resultingBaseSha256);
171
+ } else {
172
+ // Reconciliation is declared data. Missing start/result or a timeout has no evidence shape
173
+ // here, so it can only leave the operation indeterminate; it never releases a use.
174
+ const ev = e.evidence;
175
+ if (!OPEN.includes(o.state)) block("invalid-operation-transition");
176
+ if (ev.reservationEventId !== o.reserveEventId || ev.priorEventId !== o.lastEventId || ev.previousState !== o.state) block("reconcile-evidence-mismatch");
177
+ claim(ev.decisionRef);
178
+ if (e.resolution === "not-started-confirmed") {
179
+ if (ev.observation !== "non-start-confirmed" || o.sawStart) block("reconcile-contradiction");
180
+ if (ev.inspectedBaseSha256 !== o.expectedBase) block("non-start-base-mismatch");
181
+ if (e.resultingBaseSha256 !== null) fail("unexpected-result-base");
182
+ o.state = "released-declared";
183
+ } else {
184
+ if (ev.observation !== "termination-observed") block("reconcile-contradiction");
185
+ settle(r, o, e.resolution === "finished-succeeded" ? "succeeded" : "failed", e.resultingBaseSha256);
186
+ }
187
+ }
188
+ }
189
+
190
+ function reduceHistory(history, checkpoint) {
191
+ const { events } = history;
192
+ if (events.length !== checkpoint.revision || digest(history) !== checkpoint.historySha256) block("checkpoint-divergent");
193
+ const seen = new Map(); const responses = new Set(); const operations = new Set(); const requests = new Map();
194
+ let clock = -Infinity; let duplicates = 0;
195
+ const claim = ref => { if (responses.has(ref)) block("response-ref-reused"); responses.add(ref); };
196
+ for (const e of events) {
197
+ if (!validTime(e.at)) fail("invalid-event-time");
198
+ const previous = seen.get(e.eventId);
199
+ if (previous) {
200
+ if (!same(previous, e)) block("event-id-conflict");
201
+ duplicates++; continue;
202
+ }
203
+ seen.set(e.eventId, e);
204
+ const at = Date.parse(e.at);
205
+ if (at < clock) block("clock-regression");
206
+ clock = at;
207
+ if (e.type === "request") {
208
+ if (requests.has(e.requestId)) block("request-id-conflict");
209
+ if (![...requests.values()].every(pristine)) block("accounting-context-required");
210
+ requestFacts(e, history); requests.set(e.requestId, newRequest(e));
211
+ continue;
212
+ }
213
+ const r = requests.get(e.requestId);
214
+ if (!r) block("unknown-request");
215
+ switch (e.type) {
216
+ case "decision":
217
+ claim(e.responseRef);
218
+ if (r.status !== "pending") block("decision-conflict");
219
+ if (e.requestSha256 !== r.requestSha256) block("decision-request-mismatch");
220
+ r.status = e.decision === "approve" ? "approved" : "denied";
221
+ break;
222
+ case "revoke":
223
+ claim(e.responseRef);
224
+ if (r.status !== "pending" && r.status !== "approved") block("terminal-conflict");
225
+ r.status = "revoked";
226
+ break;
227
+ case "close":
228
+ if (r.status !== "pending" && r.status !== "approved") block("terminal-conflict");
229
+ r.status = "closed";
230
+ break;
231
+ case "correction":
232
+ if (r.status !== "approved") block("correction-not-allowed");
233
+ if (e.scopeSha256 !== r.scopeSha256) block("scope-change-requires-new-request");
234
+ if (r.corrections >= r.scope.limits.maxCorrections) block("correction-limit");
235
+ if (e.previousRevision !== r.artifact.revision) block("correction-chain-conflict");
236
+ if (r.revisions.has(e.artifact.revision)) block("revision-reused");
237
+ if (r.shas.has(e.artifact.sha256)) block("artifact-reused");
238
+ if (r.ops.some(o => OPEN.includes(o.state))) block("operation-in-progress");
239
+ r.artifact = e.artifact; r.revisions.add(e.artifact.revision); r.shas.add(e.artifact.sha256); r.corrections++;
240
+ break;
241
+ case "reserve": {
242
+ pathFacts(e.items); effectFacts(e.items, e.checks, e.effects);
243
+ if (operations.has(e.operationId)) block("operation-id-conflict");
244
+ const refusal = admission(r, {
245
+ items: e.items, checks: e.checks, effects: e.effects, base: e.expectedBaseSha256,
246
+ revision: e.artifactRevision, sha: null, retryOf: e.retryOf
247
+ }, at);
248
+ if (refusal) block(refusal[1]);
249
+ operations.add(e.operationId);
250
+ if (e.retryOf !== null) r.retries++;
251
+ r.ops.push({
252
+ operationId: e.operationId, state: "reserved", reserveEventId: e.eventId, lastEventId: e.eventId,
253
+ items: e.items, checks: e.checks, effects: e.effects, key: workKey(e.items, e.checks, e.effects, r.artifact.sha256),
254
+ expectedBase: e.expectedBaseSha256, artifactRevision: r.artifact.revision, artifactSha256: r.artifact.sha256,
255
+ retryOf: e.retryOf, sawStart: false
256
+ });
257
+ break;
258
+ }
259
+ default:
260
+ operationEvent(r, e, at, claim);
261
+ }
262
+ }
263
+ return { requests, clock, duplicates };
264
+ }
265
+
266
+ function summarize(reduced, history) {
267
+ const { requests, clock, duplicates } = reduced;
268
+ return {
269
+ revision: history.events.length, historySha256: digest(history), duplicatesIgnored: duplicates,
270
+ lastEventAt: Number.isFinite(clock) ? new Date(clock).toISOString().replace(".000Z", "Z") : null,
271
+ requests: [...requests.values()].map(r => ({
272
+ requestId: r.requestId, status: r.status, scopeSha256: r.scopeSha256, requestSha256: r.requestSha256,
273
+ artifact: { ...r.artifact }, baseSha256: r.base, divergedBaseSha256: r.divergedBase,
274
+ corrections: r.corrections, retries: r.retries, usedOperations: live(r).length, remaining: remaining(r),
275
+ operations: r.ops.map(o => ({ operationId: o.operationId, state: o.state, reserveEventId: o.reserveEventId, retryOf: o.retryOf }))
276
+ }))
277
+ };
278
+ }
279
+
280
+ /** Strict text/bytes entry point: bounded size, valid UTF-8, no duplicate or unsafe keys. */
281
+ export function parseApprovalInput(value) {
282
+ return copyInertJson(parseEventJson(decode(copyBytes(value, LIMITS.maxBytes))));
283
+ }
284
+
285
+ /**
286
+ * Pure calculators over explicit inputs. No IO, clock, processes, store or runtime.
287
+ * Every report keeps authorityVerified/executionAuthorized/persisted/nativeExecuted false.
288
+ */
289
+ export function createTaskApprovals(schema) {
290
+ const root = copyInertJson(schema);
291
+ if (root.$id !== APPROVALS_ID) throw Error("Unsupported approvals schema");
292
+ const ajv = new Ajv2020({ strict: true, allErrors: false });
293
+ ajv.addSchema(root);
294
+ const check = Object.fromEntries(["replayInput", "proposeInput", "coverInput", "report"]
295
+ .map(name => [name, ajv.compile({ $ref: `${APPROVALS_ID}#/$defs/${name}` })]));
296
+
297
+ function run(operation, input, body) {
298
+ const r = {
299
+ schemaVersion: "1.0.0", engineVersion: "1.0.0", operation, state: "invalid", reasons: [],
300
+ authorityVerified: false, executionAuthorized: false, persisted: false, nativeExecuted: false,
301
+ requestId: null, revision: null, historySha256: null, view: null, remaining: null, proposal: null
302
+ };
303
+ try {
304
+ const d = copyInertJson(input);
305
+ if (!check[`${operation}Input`](d)) fail("invalid-approval-input");
306
+ body(d, r);
307
+ } catch (error) {
308
+ if (!(error instanceof Refusal || error instanceof ParseFailure)) throw error;
309
+ r.state = error instanceof Refusal ? error.state : "invalid"; r.reasons = [error.code];
310
+ r.view = null; r.remaining = null; r.proposal = null;
311
+ }
312
+ if (!check.report(r)) throw Error("Approval report invariant failed");
313
+ return freeze(r);
314
+ }
315
+
316
+ return {
317
+ replay: input => run("replay", input, (d, r) => {
318
+ const reduced = reduceHistory(d.history, d.checkpoint);
319
+ r.state = "reduced"; r.reasons = ["history-replayed"];
320
+ r.revision = d.history.events.length; r.historySha256 = d.checkpoint.historySha256;
321
+ r.view = summarize(reduced, d.history);
322
+ }),
323
+
324
+ propose: input => run("propose", input, (d, r) => {
325
+ reduceHistory(d.history, d.checkpoint);
326
+ r.revision = d.history.events.length; r.historySha256 = d.checkpoint.historySha256; r.requestId = d.event.requestId;
327
+ const known = d.history.events.find(e => e.eventId === d.event.eventId);
328
+ if (known) {
329
+ if (!same(known, d.event)) block("event-id-conflict");
330
+ r.state = "noop"; r.reasons = ["event-already-recorded"];
331
+ return;
332
+ }
333
+ if (d.history.events.length >= LIMITS.maxEvents) block("event-limit");
334
+ const history = { ...d.history, events: [...d.history.events, d.event] };
335
+ const next = { revision: history.events.length, historySha256: digest(history) };
336
+ reduceHistory(history, next); // the reducer is the single source of validity
337
+ r.state = "proposed"; r.reasons = ["event-proposed"];
338
+ r.proposal = { event: d.event, nextRevision: next.revision, nextHistorySha256: next.historySha256 };
339
+ }),
340
+
341
+ cover: input => run("cover", input, (d, r) => {
342
+ const reduced = reduceHistory(d.history, d.checkpoint);
343
+ const q = d.query;
344
+ r.revision = d.history.events.length; r.historySha256 = d.checkpoint.historySha256; r.requestId = q.requestId;
345
+ if (!validTime(d.now)) fail("invalid-now");
346
+ const now = Date.parse(d.now);
347
+ if (now < reduced.clock) block("clock-regression");
348
+ pathFacts(q.items); effectFacts(q.items, q.checks, q.effects);
349
+ const request = reduced.requests.get(q.requestId);
350
+ let verdict;
351
+ if (!request) verdict = ["approval-needed", "request-missing"];
352
+ else {
353
+ r.remaining = remaining(request);
354
+ if (!same(q.recipient, request.scope.recipient)) verdict = ["approval-needed", "recipient-not-covered"];
355
+ else if (q.operationId !== null) verdict = inFlight(request, q, now);
356
+ else {
357
+ verdict = admission(request, {
358
+ items: q.items, checks: q.checks, effects: q.effects, base: q.observedBaseSha256,
359
+ revision: q.artifact.revision, sha: q.artifact.sha256, retryOf: q.retryOf
360
+ }, now);
361
+ }
362
+ }
363
+ r.state = verdict ? verdict[0] : "declared-covered";
364
+ r.reasons = [verdict ? verdict[1] : "declared-data-match"];
365
+ })
366
+ };
367
+ }
@@ -0,0 +1,79 @@
1
+ import fs from "node:fs/promises";
2
+ import { fileURLToPath } from "node:url";
3
+ import { createTaskPreparer, TASK_LIMITS } from "./task-prepare.js";
4
+ import { readTaskInputs, parseTaskDocument, TaskInputError } from "./task-prepare-files.js";
5
+ import { runVerifyCli } from "./task-verify-cli.js";
6
+ import { runExternalVerifierCli } from "./task-external-verifier.js";
7
+
8
+ const HELP = `agent-task — borradores manuales y verificación local
9
+
10
+ Uso local:
11
+ node bin/agent-task.js prepare --task <archivo> --request <archivo> --catalog <archivo> --policy <archivo> [--json | --show-brief]
12
+ node bin/agent-task.js verify --contract <json> --expect <sha256> --source <raíz> --handoff <raíz> --phase <before|after> [--json]
13
+ node bin/agent-task.js external-verifier --help
14
+ node bin/agent-task.js external-verifier preview --task <json> --request <json> --catalog <json> --policy <json> --source <raíz> --handoff <raíz-0700> --delivery <ruta>
15
+ node bin/agent-task.js --help
16
+
17
+ Sin flags de salida: resumen sin cuerpo del encargo ni rutas privadas.
18
+ --json: ese mismo resumen estructurado.
19
+ --show-brief: muestra el borrador privado completo en el terminal; no lo guarda ni envía.
20
+ prepare solo interpreta documentos locales; no usa IA ni consulta cuentas.
21
+ Preparar no autoriza, verifica la base ni cambia el modelo del cliente.
22
+ No comprueba actualidad frente al reloj; acceso/disponibilidad son datos declarados.
23
+ El usuario revisa el borrador y elige manualmente el modelo antes de entregarlo.
24
+ Exit: 0 borrador/ayuda; 1 faltan datos/bloqueo; 2 entrada/lectura/salida inválida.
25
+ verify compara huellas de archivos listados; «verify --help» detalla estados y salida. matched no aprueba nada.
26
+ Modo sin ejecución de IA por omisión: external-verifier preview no llama al modelo y run exige confirmación aparte.
27
+ `;
28
+ const NAMES = ["task", "request", "catalog", "policy"];
29
+ const schemaPaths = ["agent-task-prepare", "agent-model-selection", "agent-model-preference"].map(n => fileURLToPath(new URL(`../schemas/${n}.schema.json`, import.meta.url)));
30
+ function options(argv) {
31
+ if (!Array.isArray(argv) || argv.some(v => typeof v !== "string")) throw Error();
32
+ if (!argv.length || argv.length === 1 && ["--help", "-h"].includes(argv[0]) || argv.length === 2 && argv[0] === "prepare" && ["--help", "-h"].includes(argv[1])) return { help: true };
33
+ if (argv[0] !== "prepare") throw Error();
34
+ const values = {}, flags = new Set();
35
+ for (let i = 1; i < argv.length; i++) {
36
+ const a = argv[i];
37
+ if (["--json", "--show-brief"].includes(a)) { if (flags.has(a)) throw Error(); flags.add(a); continue; }
38
+ const key = a.startsWith("--") ? a.slice(2) : "";
39
+ if (!NAMES.includes(key) || Object.hasOwn(values, key) || !argv[i + 1] || argv[i + 1].startsWith("-")) throw Error();
40
+ values[key] = argv[++i];
41
+ }
42
+ if (Object.keys(values).length !== 4 || flags.size > 1) throw Error();
43
+ return { values, json: flags.has("--json"), show: flags.has("--show-brief") };
44
+ }
45
+ function outputSummary(s, json) {
46
+ if (json) return JSON.stringify(s, null, 2) + "\n";
47
+ return `agent-task prepare: ${s.state}\n` + (s.identity?.purpose === "external-verifier" ? "Propósito: verificador externo (solo lectura declarada).\n" : "") + (s.recommended ?
48
+ `Modelo solicitado: ${s.recommended.requestedModel}; esfuerzo: ${s.recommended.effort ?? "null (sin ajuste explícito)"}\n` : "Sin recomendación utilizable.\n") +
49
+ `Motivos: ${s.reasons.join(", ")}\n` + (s.missing.length ? `Datos pendientes: ${s.missing.join(", ")}\n` : "") +
50
+ "No ejecutado, enviado ni escrito. Permiso, base y modelo real no verificados.\n" +
51
+ "Disponibilidad declarada; actualidad frente al reloj no verificada.\n";
52
+ }
53
+ /** IO callbacks/dependencies are trusted hosts, not fields in input JSON. */
54
+ export async function runTaskCli(argv, io, dependencies = {}) {
55
+ if (Array.isArray(argv) && argv[0] === "verify") return runVerifyCli(argv.slice(1), io, dependencies);
56
+ if (Array.isArray(argv) && argv[0] === "external-verifier") return runExternalVerifierCli(argv.slice(1), io, dependencies);
57
+ let opts;
58
+ const fail = async code => { try { await io.err(`agent-task: ${code}\n`); } catch {} return 2; };
59
+ try { opts = options(argv); } catch { return fail("task-invalid-option"); }
60
+ if (opts.help) {
61
+ try { await io.out(HELP); return 0; } catch { return fail("task-output-failed"); }
62
+ }
63
+ let core, report;
64
+ try {
65
+ const readSchema = dependencies.readPackagedSchema ?? (p => fs.readFile(p));
66
+ const schemas = []; for (const p of schemaPaths) schemas.push(parseTaskDocument(await readSchema(p)));
67
+ core = createTaskPreparer(...schemas);
68
+ const { data, byteHashes } = await readTaskInputs(opts.values, dependencies.cwd ?? process.cwd(), { io: dependencies.fileIo });
69
+ report = core.prepareTask(data); report.audit.sourceByteHashes = byteHashes;
70
+ } catch (e) { return fail(e instanceof TaskInputError ? e.code : "task-preparation-failed"); }
71
+ try {
72
+ const summary = core.summarize(report);
73
+ const output = opts.show && report.state === "prepared-draft" ? report.brief : outputSummary(summary, opts.json);
74
+ const cap = opts.show && report.state === "prepared-draft" ? TASK_LIMITS.briefBytes : TASK_LIMITS.summaryBytes;
75
+ if (Buffer.byteLength(output) > cap) throw Error();
76
+ await io.out(output);
77
+ return report.state === "prepared-draft" ? 0 : report.state === "invalid" ? 2 : 1;
78
+ } catch { return fail("task-output-failed"); }
79
+ }