@jaimevalasek/aioson 1.5.1 → 1.7.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 (341) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +729 -226
  3. package/docs/design-previews/aurora-command-ui-website.html +884 -0
  4. package/docs/design-previews/aurora-command-ui.html +682 -0
  5. package/docs/design-previews/bold-editorial-ui-website.html +658 -0
  6. package/docs/design-previews/bold-editorial-ui.html +717 -0
  7. package/docs/design-previews/clean-saas-ui-website.html +1202 -0
  8. package/docs/design-previews/clean-saas-ui.html +549 -0
  9. package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
  10. package/docs/design-previews/cognitive-core-ui.html +463 -0
  11. package/docs/design-previews/glassmorphism-ui-website.html +572 -0
  12. package/docs/design-previews/glassmorphism-ui.html +886 -0
  13. package/docs/design-previews/index.html +699 -0
  14. package/docs/design-previews/interface-design-website.html +1187 -0
  15. package/docs/design-previews/interface-design.html +513 -0
  16. package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
  17. package/docs/design-previews/neo-brutalist-ui.html +797 -0
  18. package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
  19. package/docs/design-previews/premium-command-center-ui.html +552 -0
  20. package/docs/design-previews/pt.squarespace.com-homepage.html +889 -0
  21. package/docs/design-previews/warm-craft-ui-website.html +684 -0
  22. package/docs/design-previews/warm-craft-ui.html +739 -0
  23. package/docs/en/cli-reference.md +20 -9
  24. package/docs/integrations/sdlc-genius-boundary.md +76 -0
  25. package/docs/integrations/sdlc-genius-eval-matrix.md +75 -0
  26. package/docs/integrations/sdlc-genius-install-checklist.md +93 -0
  27. package/docs/integrations/sdlc-genius-review-samples.md +86 -0
  28. package/docs/pt/README.md +10 -0
  29. package/docs/pt/agent-sharding.md +132 -0
  30. package/docs/pt/agentes.md +9 -2
  31. package/docs/pt/busca-de-contexto.md +129 -0
  32. package/docs/pt/cache-de-contexto.md +156 -0
  33. package/docs/pt/comandos-cli.md +915 -1
  34. package/docs/pt/design-hybrid-forge.md +356 -0
  35. package/docs/pt/devlog-pipeline.md +270 -0
  36. package/docs/pt/fluxo-artefatos.md +178 -0
  37. package/docs/pt/hooks-session-guard.md +454 -0
  38. package/docs/pt/inicio-rapido.md +54 -3
  39. package/docs/pt/inteligencia-adaptativa.md +324 -0
  40. package/docs/pt/monitor-de-contexto.md +158 -0
  41. package/docs/pt/recuperacao-de-sessao.md +125 -0
  42. package/docs/pt/sandbox.md +125 -0
  43. package/docs/pt/sdd-automation-scripts.md +557 -0
  44. package/docs/pt/site-forge.md +309 -0
  45. package/docs/pt/skills.md +98 -6
  46. package/docs/pt/spec-learnings-pipeline.md +265 -0
  47. package/package.json +1 -1
  48. package/src/a2a/client.js +165 -0
  49. package/src/a2a/server.js +223 -0
  50. package/src/agent-loader.js +280 -0
  51. package/src/cli.js +329 -1
  52. package/src/commands/agent-audit.js +397 -0
  53. package/src/commands/agent-export-skill.js +229 -0
  54. package/src/commands/agent-loader.js +85 -0
  55. package/src/commands/artifact-validate.js +189 -0
  56. package/src/commands/brief-gen.js +405 -0
  57. package/src/commands/brief-validate.js +65 -0
  58. package/src/commands/classify.js +256 -0
  59. package/src/commands/context-cache.js +90 -0
  60. package/src/commands/context-compact.js +49 -0
  61. package/src/commands/context-health.js +175 -0
  62. package/src/commands/context-monitor.js +163 -0
  63. package/src/commands/context-search.js +66 -0
  64. package/src/commands/context-trim.js +177 -0
  65. package/src/commands/design-hybrid-options.js +385 -0
  66. package/src/commands/detect-test-runner.js +55 -0
  67. package/src/commands/devlog-export-brains.js +27 -0
  68. package/src/commands/devlog-process.js +292 -0
  69. package/src/commands/devlog-watch.js +131 -0
  70. package/src/commands/feature-close.js +165 -0
  71. package/src/commands/gate-check.js +228 -0
  72. package/src/commands/health.js +214 -0
  73. package/src/commands/hooks-emit.js +253 -0
  74. package/src/commands/hooks-install.js +347 -0
  75. package/src/commands/init.js +54 -13
  76. package/src/commands/install.js +52 -13
  77. package/src/commands/learning-auto-promote.js +195 -0
  78. package/src/commands/learning-evolve.js +364 -0
  79. package/src/commands/learning-export.js +103 -0
  80. package/src/commands/learning-rollback.js +164 -0
  81. package/src/commands/live.js +59 -1
  82. package/src/commands/pattern-detect.js +33 -0
  83. package/src/commands/preflight-context.js +30 -0
  84. package/src/commands/preflight.js +208 -0
  85. package/src/commands/pulse-update.js +130 -0
  86. package/src/commands/recovery.js +43 -0
  87. package/src/commands/runner-daemon.js +274 -0
  88. package/src/commands/runner-plan.js +70 -0
  89. package/src/commands/runner-queue-from-plan.js +166 -0
  90. package/src/commands/runner-queue.js +189 -0
  91. package/src/commands/runner-run.js +129 -0
  92. package/src/commands/runtime.js +47 -1
  93. package/src/commands/sandbox.js +37 -0
  94. package/src/commands/self-implement-loop.js +256 -0
  95. package/src/commands/session-guard.js +218 -0
  96. package/src/commands/setup-context.js +22 -2
  97. package/src/commands/setup.js +178 -0
  98. package/src/commands/sizing.js +165 -0
  99. package/src/commands/skill.js +144 -32
  100. package/src/commands/spec-checkpoint.js +177 -0
  101. package/src/commands/spec-status.js +79 -0
  102. package/src/commands/spec-sync.js +190 -0
  103. package/src/commands/spec-tasks.js +288 -0
  104. package/src/commands/squad-autorun.js +1220 -0
  105. package/src/commands/squad-bus.js +217 -0
  106. package/src/commands/squad-card.js +149 -0
  107. package/src/commands/squad-daemon.js +134 -0
  108. package/src/commands/squad-dependency-graph.js +164 -0
  109. package/src/commands/squad-review.js +106 -0
  110. package/src/commands/squad-scaffold.js +55 -0
  111. package/src/commands/squad-tool-register.js +157 -0
  112. package/src/commands/state-save.js +122 -0
  113. package/src/commands/tool-registry-cmd.js +232 -0
  114. package/src/commands/update.js +9 -0
  115. package/src/commands/verify-gate.js +572 -0
  116. package/src/commands/workflow-execute.js +241 -0
  117. package/src/constants.js +18 -0
  118. package/src/context-cache.js +159 -0
  119. package/src/context-search.js +326 -0
  120. package/src/design-variation-catalog.js +503 -0
  121. package/src/i18n/messages/en.js +32 -2
  122. package/src/i18n/messages/es.js +30 -2
  123. package/src/i18n/messages/fr.js +30 -2
  124. package/src/i18n/messages/pt-BR.js +32 -2
  125. package/src/install-animation.js +260 -0
  126. package/src/install-profile.js +143 -0
  127. package/src/install-wizard.js +475 -0
  128. package/src/installer.js +44 -10
  129. package/src/lib/health-check.js +158 -0
  130. package/src/lib/hook-protocol.js +76 -0
  131. package/src/mcp/apps/squad-dashboard/app.js +163 -0
  132. package/src/mcp/apps/squad-dashboard/index.html +261 -0
  133. package/src/mcp/apps/squad-dashboard/mcp-manifest.json +23 -0
  134. package/src/mcp/resources/squad-state.js +130 -0
  135. package/src/parser.js +7 -1
  136. package/src/preflight-engine.js +443 -0
  137. package/src/recovery-context-session.js +154 -0
  138. package/src/runner/cascade.js +97 -0
  139. package/src/runner/cli-launcher.js +109 -0
  140. package/src/runner/plan-importer.js +63 -0
  141. package/src/runner/queue-store.js +159 -0
  142. package/src/runtime-store.js +158 -4
  143. package/src/sandbox.js +177 -0
  144. package/src/squad/agent-teams-adapter.js +264 -0
  145. package/src/squad/brief-validator.js +350 -0
  146. package/src/squad/bus-bridge.js +140 -0
  147. package/src/squad/context-compactor.js +265 -0
  148. package/src/squad/cross-ai-synthesizer.js +250 -0
  149. package/src/squad/hooks-generator.js +196 -0
  150. package/src/squad/inter-squad-events.js +175 -0
  151. package/src/squad/intra-bus.js +345 -0
  152. package/src/squad/learning-extractor.js +213 -0
  153. package/src/squad/pattern-detector.js +365 -0
  154. package/src/squad/preflight-context.js +296 -0
  155. package/src/squad/recovery-context.js +242 -71
  156. package/src/squad/reflection.js +365 -0
  157. package/src/squad/squad-scaffold.js +177 -0
  158. package/src/squad/state-manager.js +310 -0
  159. package/src/squad/task-decomposer.js +652 -0
  160. package/src/squad/verify-gate.js +303 -0
  161. package/src/tool-executor.js +94 -0
  162. package/src/updater.js +10 -3
  163. package/src/worker-runner.js +186 -1
  164. package/template/.aioson/agents/analyst.md +119 -3
  165. package/template/.aioson/agents/architect.md +98 -0
  166. package/template/.aioson/agents/design-hybrid-forge.md +141 -0
  167. package/template/.aioson/agents/dev.md +335 -14
  168. package/template/.aioson/agents/deyvin.md +117 -2
  169. package/template/.aioson/agents/discovery-design-doc.md +44 -0
  170. package/template/.aioson/agents/genome.md +14 -0
  171. package/template/.aioson/agents/neo.md +78 -1
  172. package/template/.aioson/agents/orache.md +50 -4
  173. package/template/.aioson/agents/orchestrator.md +197 -1
  174. package/template/.aioson/agents/pm.md +93 -0
  175. package/template/.aioson/agents/product.md +77 -4
  176. package/template/.aioson/agents/profiler-enricher.md +14 -0
  177. package/template/.aioson/agents/profiler-forge.md +14 -0
  178. package/template/.aioson/agents/profiler-researcher.md +14 -0
  179. package/template/.aioson/agents/qa.md +249 -19
  180. package/template/.aioson/agents/setup.md +144 -12
  181. package/template/.aioson/agents/sheldon.md +237 -11
  182. package/template/.aioson/agents/site-forge.md +1753 -0
  183. package/template/.aioson/agents/squad.md +162 -0
  184. package/template/.aioson/agents/tester.md +209 -0
  185. package/template/.aioson/agents/ux-ui.md +34 -1
  186. package/template/.aioson/brains/README.md +128 -0
  187. package/template/.aioson/brains/_index.json +16 -0
  188. package/template/.aioson/brains/scripts/query.js +103 -0
  189. package/template/.aioson/brains/site-forge/visual-patterns.brain.json +205 -0
  190. package/template/.aioson/config.md +158 -13
  191. package/template/.aioson/constitution.md +33 -0
  192. package/template/.aioson/context/forensics/.gitkeep +0 -0
  193. package/template/.aioson/context/project-pulse.md +34 -0
  194. package/template/.aioson/context/seeds/seed-example.md +27 -0
  195. package/template/.aioson/context/user-profile.md +42 -0
  196. package/template/.aioson/docs/LAYERS.md +79 -0
  197. package/template/.aioson/docs/README.md +76 -0
  198. package/template/.aioson/docs/example-external-api-context.md +72 -0
  199. package/template/.aioson/locales/en/agents/architect.md +17 -0
  200. package/template/.aioson/locales/en/agents/dev.md +79 -13
  201. package/template/.aioson/locales/en/agents/orache.md +6 -0
  202. package/template/.aioson/locales/en/agents/orchestrator.md +24 -0
  203. package/template/.aioson/locales/en/agents/product.md +50 -0
  204. package/template/.aioson/locales/en/agents/setup.md +33 -1
  205. package/template/.aioson/locales/en/agents/sheldon.md +115 -0
  206. package/template/.aioson/locales/en/agents/squad.md +14 -0
  207. package/template/.aioson/locales/en/agents/tester.md +6 -0
  208. package/template/.aioson/locales/es/agents/analyst.md +2 -0
  209. package/template/.aioson/locales/es/agents/architect.md +19 -0
  210. package/template/.aioson/locales/es/agents/dev.md +64 -4
  211. package/template/.aioson/locales/es/agents/deyvin.md +2 -0
  212. package/template/.aioson/locales/es/agents/discovery-design-doc.md +2 -0
  213. package/template/.aioson/locales/es/agents/genome.md +2 -0
  214. package/template/.aioson/locales/es/agents/neo.md +2 -0
  215. package/template/.aioson/locales/es/agents/orache.md +2 -0
  216. package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
  217. package/template/.aioson/locales/es/agents/pair.md +2 -0
  218. package/template/.aioson/locales/es/agents/pm.md +2 -0
  219. package/template/.aioson/locales/es/agents/product.md +52 -0
  220. package/template/.aioson/locales/es/agents/profiler-enricher.md +2 -0
  221. package/template/.aioson/locales/es/agents/profiler-forge.md +2 -0
  222. package/template/.aioson/locales/es/agents/profiler-researcher.md +2 -0
  223. package/template/.aioson/locales/es/agents/qa.md +2 -0
  224. package/template/.aioson/locales/es/agents/setup.md +35 -1
  225. package/template/.aioson/locales/es/agents/sheldon.md +117 -0
  226. package/template/.aioson/locales/es/agents/squad.md +16 -0
  227. package/template/.aioson/locales/es/agents/tester.md +9 -0
  228. package/template/.aioson/locales/es/agents/ux-ui.md +2 -0
  229. package/template/.aioson/locales/fr/agents/analyst.md +2 -0
  230. package/template/.aioson/locales/fr/agents/architect.md +19 -0
  231. package/template/.aioson/locales/fr/agents/dev.md +64 -4
  232. package/template/.aioson/locales/fr/agents/deyvin.md +2 -0
  233. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +2 -0
  234. package/template/.aioson/locales/fr/agents/genome.md +2 -0
  235. package/template/.aioson/locales/fr/agents/neo.md +2 -0
  236. package/template/.aioson/locales/fr/agents/orache.md +2 -0
  237. package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
  238. package/template/.aioson/locales/fr/agents/pair.md +2 -0
  239. package/template/.aioson/locales/fr/agents/pm.md +2 -0
  240. package/template/.aioson/locales/fr/agents/product.md +52 -0
  241. package/template/.aioson/locales/fr/agents/profiler-enricher.md +2 -0
  242. package/template/.aioson/locales/fr/agents/profiler-forge.md +2 -0
  243. package/template/.aioson/locales/fr/agents/profiler-researcher.md +2 -0
  244. package/template/.aioson/locales/fr/agents/qa.md +2 -0
  245. package/template/.aioson/locales/fr/agents/setup.md +35 -1
  246. package/template/.aioson/locales/fr/agents/sheldon.md +117 -0
  247. package/template/.aioson/locales/fr/agents/squad.md +16 -0
  248. package/template/.aioson/locales/fr/agents/tester.md +9 -0
  249. package/template/.aioson/locales/fr/agents/ux-ui.md +2 -0
  250. package/template/.aioson/locales/pt-BR/agents/analyst.md +64 -3
  251. package/template/.aioson/locales/pt-BR/agents/architect.md +42 -0
  252. package/template/.aioson/locales/pt-BR/agents/dev.md +147 -14
  253. package/template/.aioson/locales/pt-BR/agents/deyvin.md +47 -0
  254. package/template/.aioson/locales/pt-BR/agents/neo.md +62 -1
  255. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +158 -2
  256. package/template/.aioson/locales/pt-BR/agents/pm.md +95 -1
  257. package/template/.aioson/locales/pt-BR/agents/product.md +145 -18
  258. package/template/.aioson/locales/pt-BR/agents/qa.md +16 -0
  259. package/template/.aioson/locales/pt-BR/agents/setup.md +134 -19
  260. package/template/.aioson/locales/pt-BR/agents/sheldon.md +132 -1
  261. package/template/.aioson/locales/pt-BR/agents/squad.md +14 -0
  262. package/template/.aioson/locales/pt-BR/agents/tester.md +449 -0
  263. package/template/.aioson/rules/README.md +69 -0
  264. package/template/.aioson/rules/data-format-convention.md +136 -0
  265. package/template/.aioson/rules/example-monetary-values.md +30 -0
  266. package/template/.aioson/schemas/squad-manifest.schema.json +124 -3
  267. package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +243 -0
  268. package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
  269. package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
  270. package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
  271. package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
  272. package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
  273. package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
  274. package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
  275. package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
  276. package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
  277. package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
  278. package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
  279. package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
  280. package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
  281. package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
  282. package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
  283. package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
  284. package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
  285. package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
  286. package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
  287. package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
  288. package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
  289. package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
  290. package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -0
  291. package/template/.aioson/skills/design/pt.squarespace.com/.skill-meta.json +31 -0
  292. package/template/.aioson/skills/design/pt.squarespace.com/SKILL.md +66 -0
  293. package/template/.aioson/skills/design/pt.squarespace.com/references/components.md +368 -0
  294. package/template/.aioson/skills/design/pt.squarespace.com/references/design-tokens.md +150 -0
  295. package/template/.aioson/skills/design/pt.squarespace.com/references/motion.md +270 -0
  296. package/template/.aioson/skills/design/pt.squarespace.com/references/patterns.md +189 -0
  297. package/template/.aioson/skills/design/pt.squarespace.com/references/websites.md +165 -0
  298. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +46 -0
  299. package/template/.aioson/skills/process/aioson-spec-driven/references/analyst.md +30 -0
  300. package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
  301. package/template/.aioson/skills/process/aioson-spec-driven/references/architect.md +23 -0
  302. package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
  303. package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -0
  304. package/template/.aioson/skills/process/aioson-spec-driven/references/dev.md +47 -0
  305. package/template/.aioson/skills/process/aioson-spec-driven/references/deyvin.md +27 -0
  306. package/template/.aioson/skills/process/aioson-spec-driven/references/hardening-lane.md +49 -0
  307. package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +101 -0
  308. package/template/.aioson/skills/process/aioson-spec-driven/references/product.md +25 -0
  309. package/template/.aioson/skills/process/aioson-spec-driven/references/qa.md +30 -0
  310. package/template/.aioson/skills/process/aioson-spec-driven/references/sheldon.md +25 -0
  311. package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +75 -0
  312. package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +147 -0
  313. package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
  314. package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
  315. package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +306 -0
  316. package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +149 -0
  317. package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +208 -0
  318. package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -0
  319. package/template/.aioson/skills/process/simplify/SKILL.md +173 -0
  320. package/template/.aioson/skills/static/context-budget-guide.md +46 -0
  321. package/template/.aioson/skills/static/harness-sensors.md +74 -0
  322. package/template/.aioson/skills/static/multi-agent-patterns.md +43 -0
  323. package/template/.aioson/skills/static/react-motion-patterns.md +22 -0
  324. package/template/.aioson/skills/static/static-html-patterns/checklists.md +43 -0
  325. package/template/.aioson/skills/static/static-html-patterns/css-tokens.md +609 -0
  326. package/template/.aioson/skills/static/static-html-patterns/motion.md +193 -0
  327. package/template/.aioson/skills/static/static-html-patterns/premium.md +711 -0
  328. package/template/.aioson/skills/static/static-html-patterns/structure.md +209 -0
  329. package/template/.aioson/skills/static/static-html-patterns/utilities.md +190 -0
  330. package/template/.aioson/skills/static/static-html-patterns.md +58 -1913
  331. package/template/.aioson/skills/static/threejs-patterns.md +929 -0
  332. package/template/.aioson/skills/static/web-research-cache.md +112 -0
  333. package/template/.aioson/tasks/implementation-plan.md +21 -1
  334. package/template/.claude/commands/aioson/agent/design-hybrid-forge.md +5 -0
  335. package/template/.claude/commands/aioson/agent/orache.md +5 -0
  336. package/template/.claude/commands/aioson/agent/sheldon.md +5 -0
  337. package/template/.claude/commands/aioson/agent/site-forge.md +5 -0
  338. package/template/AGENTS.md +75 -1
  339. package/template/CLAUDE.md +31 -0
  340. package/template/OPENCODE.md +4 -0
  341. package/template/researchs/.gitkeep +0 -0
@@ -0,0 +1,397 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson agent:audit — Token and size audit for AIOSON agent files
5
+ *
6
+ * Scans .aioson/agents/*.md (and optionally locale variants) and reports:
7
+ * - Size in chars and estimated tokens per file
8
+ * - Size per section (## headings)
9
+ * - Files and sections over budget thresholds
10
+ * - Sections that are candidates to move to .aioson/docs/ (on-demand loading)
11
+ * - Estimated token savings per session if candidates are moved
12
+ *
13
+ * Budget thresholds (from config.md guidelines):
14
+ * Auto-loaded files (CLAUDE.md, AGENTS.md): 3,500 chars recommended / 4,000 hard
15
+ * Agent files (read manually):
16
+ * focused agents (analyst, qa, tester): 8,000 chars
17
+ * generalist agents (dev, architect): 15,000 chars
18
+ * orchestrator agents (orchestrator, squad): 12,000 chars
19
+ *
20
+ * Usage:
21
+ * aioson agent:audit .
22
+ * aioson agent:audit . --verbose Show per-section breakdown
23
+ * aioson agent:audit . --locales Include locale variant files
24
+ * aioson agent:audit . --fix Write savings report to .aioson/docs/agent-audit.md
25
+ * aioson agent:audit . --json
26
+ */
27
+
28
+ const fs = require('node:fs/promises');
29
+ const path = require('node:path');
30
+
31
+ // ─── Thresholds ───────────────────────────────────────────────────────────────
32
+
33
+ const CHARS_PER_TOKEN = 4;
34
+
35
+ // Agent type classification by slug keywords
36
+ const AGENT_TYPES = [
37
+ { type: 'auto-loaded', slugs: ['CLAUDE', 'AGENTS'], target: 3500, hard: 4000 },
38
+ { type: 'orchestrator', slugs: ['orchestrator', 'squad'], target: 12000, hard: 20000 },
39
+ { type: 'generalist', slugs: ['dev', 'architect', 'deyvin', 'sheldon', 'setup', 'product', 'ux-ui', 'site-forge'], target: 15000, hard: 40000 },
40
+ { type: 'focused', slugs: [], target: 8000, hard: 16000 } // default
41
+ ];
42
+
43
+ // Sections considered "on-demand candidates" — rarely needed at session start
44
+ const ON_DEMAND_KEYWORDS = [
45
+ 'conventions', 'folder structure', 'stack', 'laravel', 'next.js', 'node',
46
+ 'web3', 'dapp', 'brownfield', 'debugging', 'git worktree', 'worktree',
47
+ 'motion', 'animation', 'output contract', 'output targets', 'format',
48
+ 'devlog', 'observabilidade', 'observability', 'exemplos', 'examples',
49
+ 'reference', 'template', 'esquema'
50
+ ];
51
+
52
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
53
+
54
+ function estimateTokens(chars) {
55
+ return Math.ceil(chars / CHARS_PER_TOKEN);
56
+ }
57
+
58
+ function formatKb(chars) {
59
+ return `${(chars / 1024).toFixed(1)}KB`;
60
+ }
61
+
62
+ function formatTokens(chars) {
63
+ return `~${estimateTokens(chars).toLocaleString()} tok`;
64
+ }
65
+
66
+ function classifyAgent(slug) {
67
+ for (const def of AGENT_TYPES) {
68
+ if (def.slugs.some((s) => slug.toLowerCase().includes(s.toLowerCase()))) {
69
+ return def;
70
+ }
71
+ }
72
+ return AGENT_TYPES[AGENT_TYPES.length - 1]; // focused (default)
73
+ }
74
+
75
+ function isOnDemandCandidate(sectionTitle) {
76
+ const lower = sectionTitle.toLowerCase();
77
+ return ON_DEMAND_KEYWORDS.some((kw) => lower.includes(kw));
78
+ }
79
+
80
+ // ─── Section parser ───────────────────────────────────────────────────────────
81
+
82
+ function parseSections(content) {
83
+ const sections = [];
84
+ const lines = content.split(/\r?\n/);
85
+ const headingRe = /^(#{1,4})\s+(.+)/;
86
+
87
+ let currentSection = null;
88
+ let currentLines = [];
89
+
90
+ function flush() {
91
+ if (currentSection !== null) {
92
+ const body = currentLines.join('\n');
93
+ sections.push({
94
+ title: currentSection.title,
95
+ level: currentSection.level,
96
+ chars: body.length,
97
+ tokens: estimateTokens(body.length),
98
+ onDemandCandidate: isOnDemandCandidate(currentSection.title)
99
+ });
100
+ }
101
+ }
102
+
103
+ for (const line of lines) {
104
+ const match = line.match(headingRe);
105
+ if (match) {
106
+ flush();
107
+ currentSection = { level: match[1].length, title: match[2].trim() };
108
+ currentLines = [line];
109
+ } else {
110
+ currentLines.push(line);
111
+ }
112
+ }
113
+ flush();
114
+
115
+ return sections;
116
+ }
117
+
118
+ // ─── File scanner ─────────────────────────────────────────────────────────────
119
+
120
+ async function scanAgentFile(filePath, relativePath) {
121
+ let content;
122
+ try {
123
+ content = await fs.readFile(filePath, 'utf8');
124
+ } catch {
125
+ return null;
126
+ }
127
+
128
+ const slug = path.basename(filePath, '.md');
129
+ const typeDef = classifyAgent(slug);
130
+ const chars = content.length;
131
+ const sections = parseSections(content);
132
+
133
+ const onDemandSections = sections.filter((s) => s.onDemandCandidate);
134
+ const onDemandChars = onDemandSections.reduce((sum, s) => sum + s.chars, 0);
135
+
136
+ const status =
137
+ chars > typeDef.hard
138
+ ? 'over_hard'
139
+ : chars > typeDef.target
140
+ ? 'over_target'
141
+ : 'ok';
142
+
143
+ return {
144
+ file: relativePath,
145
+ slug,
146
+ agent_type: typeDef.type,
147
+ chars,
148
+ tokens: estimateTokens(chars),
149
+ target_chars: typeDef.target,
150
+ hard_chars: typeDef.hard,
151
+ status,
152
+ sections,
153
+ on_demand_candidates: onDemandSections,
154
+ savings_if_moved: onDemandChars,
155
+ savings_tokens: estimateTokens(onDemandChars)
156
+ };
157
+ }
158
+
159
+ async function scanDir(dirPath, projectDir, results) {
160
+ let entries;
161
+ try {
162
+ entries = await fs.readdir(dirPath, { withFileTypes: true });
163
+ } catch {
164
+ return;
165
+ }
166
+
167
+ for (const entry of entries) {
168
+ if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
169
+ const filePath = path.join(dirPath, entry.name);
170
+ const rel = path.relative(projectDir, filePath).split(path.sep).join('/');
171
+ const result = await scanAgentFile(filePath, rel);
172
+ if (result) results.push(result);
173
+ }
174
+ }
175
+
176
+ // ─── Report writer ────────────────────────────────────────────────────────────
177
+
178
+ function buildMarkdownReport(files, projectDir) {
179
+ const overHard = files.filter((f) => f.status === 'over_hard');
180
+ const overTarget = files.filter((f) => f.status === 'over_target');
181
+ const totalTokens = files.reduce((s, f) => s + f.tokens, 0);
182
+ const totalSavings = files.reduce((s, f) => s + f.savings_tokens, 0);
183
+
184
+ const lines = [
185
+ '# Agent Audit Report',
186
+ `Generated: ${new Date().toISOString()}`,
187
+ '',
188
+ '## Summary',
189
+ `Total agent files scanned : ${files.length}`,
190
+ `Total estimated tokens : ~${totalTokens.toLocaleString()}`,
191
+ `Over hard limit : ${overHard.length}`,
192
+ `Over target : ${overTarget.length}`,
193
+ `Potential savings (on-demand split): ~${totalSavings.toLocaleString()} tokens/session`,
194
+ ''
195
+ ];
196
+
197
+ if (overHard.length > 0) {
198
+ lines.push('## Over hard limit (split recommended)');
199
+ for (const f of overHard) {
200
+ lines.push(`- **${f.file}** — ${formatKb(f.chars)} (${formatTokens(f.chars)}) — type: ${f.agent_type}, hard: ${formatKb(f.hard_chars)}`);
201
+ }
202
+ lines.push('');
203
+ }
204
+
205
+ if (overTarget.length > 0) {
206
+ lines.push('## Over target (consider splitting)');
207
+ for (const f of overTarget) {
208
+ lines.push(`- ${f.file} — ${formatKb(f.chars)} (${formatTokens(f.chars)}) — target: ${formatKb(f.target_chars)}`);
209
+ }
210
+ lines.push('');
211
+ }
212
+
213
+ lines.push('## On-demand candidates (sections to move to .aioson/docs/)');
214
+ lines.push('These sections are loaded every session but are rarely needed at start.');
215
+ lines.push('Moving them to `.aioson/docs/` files saves tokens without losing capability.');
216
+ lines.push('');
217
+
218
+ for (const f of files) {
219
+ if (f.on_demand_candidates.length === 0) continue;
220
+ lines.push(`### ${f.file}`);
221
+ lines.push(`Current size: ${formatKb(f.chars)} — savings if moved: ~${f.savings_tokens.toLocaleString()} tokens`);
222
+ for (const s of f.on_demand_candidates) {
223
+ lines.push(`- \`## ${s.title}\` (${formatKb(s.chars)})`);
224
+ }
225
+ lines.push('');
226
+ }
227
+
228
+ lines.push('## All files');
229
+ lines.push('| File | Type | Size | Tokens | Target | Status |');
230
+ lines.push('|------|------|------|--------|--------|--------|');
231
+ for (const f of [...files].sort((a, b) => b.chars - a.chars)) {
232
+ const statusLabel = { ok: '✓', over_target: '⚠', over_hard: '✗' }[f.status];
233
+ lines.push(`| ${f.file} | ${f.agent_type} | ${formatKb(f.chars)} | ${formatTokens(f.chars)} | ${formatKb(f.target_chars)} | ${statusLabel} |`);
234
+ }
235
+
236
+ return lines.join('\n');
237
+ }
238
+
239
+ // ─── Main command ─────────────────────────────────────────────────────────────
240
+
241
+ async function runAgentAudit({ args, options = {}, logger }) {
242
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
243
+ const verbose = Boolean(options.verbose || options.v);
244
+ const includeLocales = Boolean(options.locales);
245
+ const writeFix = Boolean(options.fix);
246
+
247
+ const agentsDir = path.join(targetDir, 'template', '.aioson', 'agents');
248
+ const rootAgentsDir = path.join(targetDir, '.aioson', 'agents');
249
+
250
+ const files = [];
251
+
252
+ // Scan template agents (this project)
253
+ if (await dirExists(agentsDir)) {
254
+ await scanDir(agentsDir, targetDir, files);
255
+ }
256
+ // Scan project agents (when used inside a project)
257
+ if (await dirExists(rootAgentsDir)) {
258
+ await scanDir(rootAgentsDir, targetDir, files);
259
+ }
260
+ // Scan auto-loaded files
261
+ for (const name of ['CLAUDE.md', 'AGENTS.md']) {
262
+ for (const base of [path.join(targetDir, 'template'), targetDir]) {
263
+ const fp = path.join(base, name);
264
+ const rel = path.relative(targetDir, fp).split(path.sep).join('/');
265
+ const r = await scanAgentFile(fp, rel);
266
+ if (r) files.push(r);
267
+ }
268
+ }
269
+
270
+ // Optionally include locales
271
+ if (includeLocales) {
272
+ const localesBase = path.join(targetDir, 'template', '.aioson', 'locales');
273
+ try {
274
+ const langs = await fs.readdir(localesBase, { withFileTypes: true });
275
+ for (const lang of langs) {
276
+ if (!lang.isDirectory()) continue;
277
+ await scanDir(
278
+ path.join(localesBase, lang.name, 'agents'),
279
+ targetDir,
280
+ files
281
+ );
282
+ }
283
+ } catch { /* locales dir optional */ }
284
+ }
285
+
286
+ if (files.length === 0) {
287
+ if (!options.json) logger.log('No agent files found. Run from the aioson project root or a project with .aioson/agents/.');
288
+ return { ok: false, reason: 'no_files' };
289
+ }
290
+
291
+ // Sort by size descending
292
+ files.sort((a, b) => b.chars - a.chars);
293
+
294
+ if (options.json) return { ok: true, files };
295
+
296
+ // ── Console report ─────────────────────────────────────────────────────────
297
+ const overHard = files.filter((f) => f.status === 'over_hard');
298
+ const overTarget = files.filter((f) => f.status === 'over_target');
299
+ const totalTokens = files.reduce((s, f) => s + f.tokens, 0);
300
+ const totalSavings = files.reduce((s, f) => s + f.savings_tokens, 0);
301
+
302
+ logger.log('Agent Audit');
303
+ logger.log('─'.repeat(70));
304
+ logger.log(`Files scanned : ${files.length}`);
305
+ logger.log(`Total tokens : ~${totalTokens.toLocaleString()} per session`);
306
+ logger.log(`Over hard limit: ${overHard.length} Over target: ${overTarget.length}`);
307
+ logger.log(`Potential save : ~${totalSavings.toLocaleString()} tokens/session (on-demand split)`);
308
+ logger.log('');
309
+
310
+ // File table
311
+ const COL = { file: 45, type: 14, size: 9, tokens: 12, status: 8 };
312
+ logger.log(
313
+ 'File'.padEnd(COL.file) +
314
+ 'Type'.padEnd(COL.type) +
315
+ 'Size'.padEnd(COL.size) +
316
+ 'Tokens'.padEnd(COL.tokens) +
317
+ 'Status'
318
+ );
319
+ logger.log('─'.repeat(70));
320
+
321
+ for (const f of files) {
322
+ const statusLabel = { ok: '✓ ok', over_target: '⚠ target', over_hard: '✗ hard' }[f.status];
323
+ logger.log(
324
+ f.file.slice(0, COL.file - 1).padEnd(COL.file) +
325
+ f.agent_type.padEnd(COL.type) +
326
+ formatKb(f.chars).padEnd(COL.size) +
327
+ formatTokens(f.chars).padEnd(COL.tokens) +
328
+ statusLabel
329
+ );
330
+
331
+ if (verbose && f.sections.length > 0) {
332
+ const topSections = [...f.sections].sort((a, b) => b.chars - a.chars).slice(0, 5);
333
+ for (const s of topSections) {
334
+ const flag = s.onDemandCandidate ? ' [on-demand candidate]' : '';
335
+ logger.log(` ${'§ ' + s.title.slice(0, 40)} ${formatKb(s.chars)}${flag}`);
336
+ }
337
+ }
338
+ }
339
+
340
+ logger.log('');
341
+
342
+ // On-demand candidates summary
343
+ const withCandidates = files.filter((f) => f.on_demand_candidates.length > 0);
344
+ if (withCandidates.length > 0) {
345
+ logger.log('On-demand candidates (move to .aioson/docs/ to save tokens):');
346
+ for (const f of withCandidates) {
347
+ logger.log(` ${f.file.slice(0, 42)} save ~${f.savings_tokens.toLocaleString()} tok (${f.on_demand_candidates.length} section${f.on_demand_candidates.length > 1 ? 's' : ''})`);
348
+ if (verbose) {
349
+ for (const s of f.on_demand_candidates) {
350
+ logger.log(` § ${s.title.slice(0, 50)} ${formatKb(s.chars)}`);
351
+ }
352
+ }
353
+ }
354
+ logger.log('');
355
+ }
356
+
357
+ if (overHard.length > 0) {
358
+ logger.log('✗ Files over hard limit (will be truncated in auto-loaded contexts):');
359
+ for (const f of overHard) {
360
+ logger.log(` ${f.file} — ${formatKb(f.chars)} (target: ${formatKb(f.target_chars)}, hard: ${formatKb(f.hard_chars)})`);
361
+ }
362
+ logger.log('');
363
+ }
364
+
365
+ // Write fix report
366
+ if (writeFix) {
367
+ const reportPath = path.join(targetDir, '.aioson', 'docs', 'agent-audit.md');
368
+ const reportDir = path.dirname(reportPath);
369
+ await fs.mkdir(reportDir, { recursive: true });
370
+ await fs.writeFile(reportPath, buildMarkdownReport(files, targetDir), 'utf8');
371
+ logger.log(`✓ Full report saved: .aioson/docs/agent-audit.md`);
372
+ logger.log(' Review the "On-demand candidates" section to decide which sections to move.');
373
+ } else {
374
+ logger.log('Tip: Run with --fix to save a full markdown report with split recommendations.');
375
+ logger.log(' Run with --verbose to see per-section breakdown.');
376
+ }
377
+
378
+ return {
379
+ ok: true,
380
+ files: files.length,
381
+ over_hard: overHard.length,
382
+ over_target: overTarget.length,
383
+ total_tokens: totalTokens,
384
+ potential_savings_tokens: totalSavings
385
+ };
386
+ }
387
+
388
+ async function dirExists(dirPath) {
389
+ try {
390
+ const s = await fs.stat(dirPath);
391
+ return s.isDirectory();
392
+ } catch {
393
+ return false;
394
+ }
395
+ }
396
+
397
+ module.exports = { runAgentAudit };
@@ -0,0 +1,229 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * aioson agent:export-skill — Export AIOSON agent as portable Agent Skills Standard
5
+ *
6
+ * Converts an AIOSON agent (.aioson/agents/<name>.md) into the Agent Skills Standard
7
+ * format (SKILL.md + resources), making it usable in Cursor, Copilot, Gemini CLI,
8
+ * Codex, JetBrains, and 32+ other tools.
9
+ *
10
+ * Usage:
11
+ * aioson agent:export-skill . --agent=dev
12
+ * aioson agent:export-skill . --agent=dev --output=.claude/skills/aioson-dev/
13
+ * aioson agent:export-skill . --agent=qa --json
14
+ */
15
+
16
+ const fs = require('node:fs/promises');
17
+ const path = require('node:path');
18
+
19
+ const AGENTS_DIR = path.join('.aioson', 'agents');
20
+
21
+ // ─── Frontmatter extraction ─────────────────────────────────────────────────
22
+
23
+ /**
24
+ * Extract YAML-like frontmatter from a markdown file.
25
+ */
26
+ function extractFrontmatter(content) {
27
+ const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
28
+ if (!match) return { meta: {}, body: content };
29
+
30
+ const meta = {};
31
+ for (const line of match[1].split('\n')) {
32
+ const kv = line.match(/^(\w[\w_-]*):\s*(.+)$/);
33
+ if (kv) meta[kv[1]] = kv[2].trim().replace(/^["']|["']$/g, '');
34
+ }
35
+
36
+ return { meta, body: match[2] };
37
+ }
38
+
39
+ /**
40
+ * Extract template sections from agent body (```template blocks or ## Template sections).
41
+ */
42
+ function extractTemplates(body) {
43
+ const templates = [];
44
+ const templatePattern = /```template(?:\s+(\S+))?\n([\s\S]*?)```/g;
45
+ let match;
46
+
47
+ while ((match = templatePattern.exec(body)) !== null) {
48
+ templates.push({
49
+ name: match[1] || `template-${templates.length + 1}`,
50
+ content: match[2].trim()
51
+ });
52
+ }
53
+
54
+ return templates;
55
+ }
56
+
57
+ /**
58
+ * Extract tool references from agent body.
59
+ */
60
+ function extractTools(body) {
61
+ const tools = new Set();
62
+ const toolPattern = /\b(Read|Write|Edit|Bash|Glob|Grep|Agent|WebFetch|WebSearch|NotebookEdit)\b/g;
63
+ let match;
64
+
65
+ while ((match = toolPattern.exec(body)) !== null) {
66
+ tools.add(match[1]);
67
+ }
68
+
69
+ return [...tools];
70
+ }
71
+
72
+ /**
73
+ * Infer activation patterns from agent content.
74
+ */
75
+ function inferActivation(agentName, body) {
76
+ const activation = [];
77
+
78
+ // Always activate for .aioson files
79
+ activation.push({ path: '.aioson/**' });
80
+
81
+ // Keyword-based activation from agent name/role
82
+ const keywords = {
83
+ dev: ['implement', 'code', 'build', 'feature'],
84
+ qa: ['test', 'quality', 'verify', 'bug'],
85
+ architect: ['architecture', 'structure', 'design'],
86
+ analyst: ['analyze', 'discover', 'map'],
87
+ 'ux-ui': ['design', 'interface', 'component'],
88
+ product: ['product', 'prd', 'requirement'],
89
+ pm: ['sprint', 'backlog', 'story']
90
+ };
91
+
92
+ const agentKeywords = keywords[agentName] || [agentName];
93
+ for (const kw of agentKeywords) {
94
+ activation.push({ keyword: kw });
95
+ }
96
+
97
+ return activation;
98
+ }
99
+
100
+ // ─── SKILL.md generator ──────────────────────────────────────────────────────
101
+
102
+ /**
103
+ * Generate Agent Skills Standard SKILL.md from AIOSON agent.
104
+ */
105
+ function generateSkillMd(agentName, agentContent, options = {}) {
106
+ const { meta, body } = extractFrontmatter(agentContent);
107
+ const tools = extractTools(body);
108
+ const activation = inferActivation(agentName, body);
109
+
110
+ // Build skills-standard frontmatter
111
+ const frontmatter = {
112
+ name: meta.name || `AIOSON ${capitalize(agentName)} Agent`,
113
+ description: meta.description || `${capitalize(agentName)} agent from AIOSON framework`,
114
+ version: options.version || '1.0.0',
115
+ tools: tools.length > 0 ? tools : ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep'],
116
+ context: 'fork',
117
+ activation
118
+ };
119
+
120
+ const fmLines = [
121
+ '---',
122
+ `name: ${frontmatter.name}`,
123
+ `description: ${frontmatter.description}`,
124
+ `version: ${frontmatter.version}`,
125
+ `tools: [${frontmatter.tools.join(', ')}]`,
126
+ `context: ${frontmatter.context}`,
127
+ 'activation:',
128
+ ...frontmatter.activation.map((a) => {
129
+ if (a.path) return ` - path: "${a.path}"`;
130
+ if (a.keyword) return ` - keyword: "${a.keyword}"`;
131
+ return '';
132
+ }).filter(Boolean),
133
+ '---',
134
+ ''
135
+ ];
136
+
137
+ // Clean body: remove AIOSON-specific sections that don't apply portably
138
+ let cleanBody = body;
139
+ // Remove runtime boundary sections
140
+ cleanBody = cleanBody.replace(/## AIOSON Runtime boundary[\s\S]*?(?=\n## |$)/g, '');
141
+ // Remove observability sections
142
+ cleanBody = cleanBody.replace(/## Observability[\s\S]*?(?=\n## |$)/g, '');
143
+
144
+ return fmLines.join('\n') + cleanBody.trim() + '\n';
145
+ }
146
+
147
+ function capitalize(str) {
148
+ return str.charAt(0).toUpperCase() + str.slice(1);
149
+ }
150
+
151
+ // ─── Public API ──────────────────────────────────────────────────────────────
152
+
153
+ /**
154
+ * Export an AIOSON agent as an Agent Skills Standard skill.
155
+ *
156
+ * @param {object} params — { args, options, logger }
157
+ */
158
+ async function runAgentExportSkill({ args, options = {}, logger }) {
159
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
160
+ const agentName = String(options.agent || options.a || '').trim();
161
+ const outputDir = options.output
162
+ ? path.resolve(targetDir, options.output)
163
+ : path.join(targetDir, '.claude', 'skills', `aioson-${agentName}`);
164
+
165
+ if (!agentName) {
166
+ logger.error('Error: --agent is required');
167
+ return { ok: false, error: 'missing_agent' };
168
+ }
169
+
170
+ // Read agent file
171
+ const agentPath = path.join(targetDir, AGENTS_DIR, `${agentName}.md`);
172
+ let agentContent;
173
+ try {
174
+ agentContent = await fs.readFile(agentPath, 'utf8');
175
+ } catch {
176
+ logger.error(`Agent not found: ${agentPath}`);
177
+ return { ok: false, error: 'agent_not_found' };
178
+ }
179
+
180
+ // Generate SKILL.md
181
+ const skillContent = generateSkillMd(agentName, agentContent, {
182
+ version: options.version || '1.0.0'
183
+ });
184
+
185
+ // Extract templates
186
+ const templates = extractTemplates(agentContent);
187
+
188
+ // Write output
189
+ await fs.mkdir(outputDir, { recursive: true });
190
+ await fs.writeFile(path.join(outputDir, 'SKILL.md'), skillContent, 'utf8');
191
+
192
+ const written = ['SKILL.md'];
193
+
194
+ // Write templates
195
+ if (templates.length > 0) {
196
+ const templatesDir = path.join(outputDir, 'templates');
197
+ await fs.mkdir(templatesDir, { recursive: true });
198
+ for (const t of templates) {
199
+ const ext = t.content.includes('{') ? '.json' : '.md';
200
+ await fs.writeFile(path.join(templatesDir, `${t.name}${ext}`), t.content, 'utf8');
201
+ written.push(`templates/${t.name}${ext}`);
202
+ }
203
+ }
204
+
205
+ // Write scripts directory (empty, for custom scripts)
206
+ const scriptsDir = path.join(outputDir, 'scripts');
207
+ await fs.mkdir(scriptsDir, { recursive: true });
208
+
209
+ if (options.json) {
210
+ return {
211
+ ok: true,
212
+ agent: agentName,
213
+ outputDir: path.relative(targetDir, outputDir),
214
+ files: written
215
+ };
216
+ }
217
+
218
+ logger.log(`Exported @${agentName} as Agent Skills Standard:`);
219
+ logger.log(` Output: ${path.relative(targetDir, outputDir)}/`);
220
+ for (const f of written) {
221
+ logger.log(` ✓ ${f}`);
222
+ }
223
+ logger.log('');
224
+ logger.log('This skill is now portable to Cursor, Copilot, Gemini CLI, and 32+ tools.');
225
+
226
+ return { ok: true, agent: agentName, outputDir: path.relative(targetDir, outputDir), files: written };
227
+ }
228
+
229
+ module.exports = { runAgentExportSkill, generateSkillMd };