@jaimevalasek/aioson 1.4.0 → 1.6.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 (301) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/LICENSE +661 -21
  3. package/README.md +9 -1
  4. package/docs/design-previews/aurora-command-ui-website.html +884 -0
  5. package/docs/design-previews/aurora-command-ui.html +682 -0
  6. package/docs/design-previews/bold-editorial-ui-website.html +658 -0
  7. package/docs/design-previews/bold-editorial-ui.html +717 -0
  8. package/docs/design-previews/clean-saas-ui-website.html +1202 -0
  9. package/docs/design-previews/clean-saas-ui.html +549 -0
  10. package/docs/design-previews/cognitive-core-ui-website.html +1009 -0
  11. package/docs/design-previews/cognitive-core-ui.html +463 -0
  12. package/docs/design-previews/glassmorphism-ui-website.html +572 -0
  13. package/docs/design-previews/glassmorphism-ui.html +886 -0
  14. package/docs/design-previews/index.html +699 -0
  15. package/docs/design-previews/interface-design-website.html +1187 -0
  16. package/docs/design-previews/interface-design.html +513 -0
  17. package/docs/design-previews/neo-brutalist-ui-website.html +621 -0
  18. package/docs/design-previews/neo-brutalist-ui.html +797 -0
  19. package/docs/design-previews/premium-command-center-ui-website.html +1217 -0
  20. package/docs/design-previews/premium-command-center-ui.html +552 -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/en/squad-dashboard.md +372 -0
  25. package/docs/openclaw-bridge.md +308 -0
  26. package/docs/pt/README.md +7 -0
  27. package/docs/pt/agent-sharding.md +132 -0
  28. package/docs/pt/agentes.md +131 -11
  29. package/docs/pt/busca-de-contexto.md +129 -0
  30. package/docs/pt/cache-de-contexto.md +156 -0
  31. package/docs/pt/cenarios.md +46 -2
  32. package/docs/pt/comandos-cli.md +88 -1
  33. package/docs/pt/design-hybrid-forge.md +107 -0
  34. package/docs/pt/inicio-rapido.md +72 -5
  35. package/docs/pt/inteligencia-adaptativa.md +324 -0
  36. package/docs/pt/monitor-de-contexto.md +104 -0
  37. package/docs/pt/recuperacao-de-sessao.md +125 -0
  38. package/docs/pt/sandbox.md +125 -0
  39. package/docs/pt/skills.md +98 -6
  40. package/docs/pt/squad-dashboard.md +373 -0
  41. package/docs/testing/genome-2.0-matrix.md +5 -5
  42. package/docs/testing/genome-2.0-rollout.md +9 -9
  43. package/package.json +2 -2
  44. package/src/agent-loader.js +280 -0
  45. package/src/backup-local.js +74 -0
  46. package/src/cli.js +192 -0
  47. package/src/commands/agent-loader.js +85 -0
  48. package/src/commands/backup-local-cmd.js +25 -0
  49. package/src/commands/context-cache.js +90 -0
  50. package/src/commands/context-monitor.js +92 -0
  51. package/src/commands/context-search.js +66 -0
  52. package/src/commands/design-hybrid-options.js +385 -0
  53. package/src/commands/health.js +214 -0
  54. package/src/commands/init.js +54 -13
  55. package/src/commands/install.js +52 -13
  56. package/src/commands/learning-evolve.js +355 -0
  57. package/src/commands/live.js +34 -0
  58. package/src/commands/recovery.js +43 -0
  59. package/src/commands/runtime.js +242 -0
  60. package/src/commands/sandbox.js +37 -0
  61. package/src/commands/setup-context.js +29 -4
  62. package/src/commands/setup.js +178 -0
  63. package/src/commands/skill.js +79 -32
  64. package/src/commands/squad-daemon.js +209 -0
  65. package/src/commands/squad-dashboard.js +39 -0
  66. package/src/commands/squad-deploy.js +64 -0
  67. package/src/commands/squad-doctor.js +52 -0
  68. package/src/commands/squad-mcp.js +270 -0
  69. package/src/commands/squad-processes.js +56 -0
  70. package/src/commands/squad-recovery.js +42 -0
  71. package/src/commands/squad-roi.js +291 -0
  72. package/src/commands/squad-score.js +250 -0
  73. package/src/commands/squad-status.js +37 -1
  74. package/src/commands/squad-validate.js +62 -1
  75. package/src/commands/squad-webhook.js +160 -0
  76. package/src/commands/squad-worker.js +191 -0
  77. package/src/commands/squad-worktrees.js +75 -0
  78. package/src/commands/tool-registry-cmd.js +232 -0
  79. package/src/commands/update.js +7 -0
  80. package/src/commands/web-map.js +70 -0
  81. package/src/commands/web-scrape.js +71 -0
  82. package/src/constants.js +17 -0
  83. package/src/context-cache.js +159 -0
  84. package/src/context-search.js +326 -0
  85. package/src/context-writer.js +45 -1
  86. package/src/design-variation-catalog.js +503 -0
  87. package/src/i18n/messages/en.js +159 -3
  88. package/src/i18n/messages/es.js +147 -2
  89. package/src/i18n/messages/fr.js +147 -2
  90. package/src/i18n/messages/pt-BR.js +158 -3
  91. package/src/install-animation.js +260 -0
  92. package/src/install-profile.js +143 -0
  93. package/src/install-wizard.js +474 -0
  94. package/src/installer.js +38 -10
  95. package/src/lib/webhook-server.js +328 -0
  96. package/src/mcp-connectors/registry.js +602 -0
  97. package/src/parser.js +7 -1
  98. package/src/recovery-context-session.js +154 -0
  99. package/src/runtime-store.js +355 -2
  100. package/src/sandbox.js +177 -0
  101. package/src/squad/external-session.js +180 -0
  102. package/src/squad/inter-squad.js +74 -0
  103. package/src/squad/recovery-context.js +201 -0
  104. package/src/squad/worktree-manager.js +114 -0
  105. package/src/squad-daemon.js +490 -0
  106. package/src/squad-dashboard/api.js +223 -0
  107. package/src/squad-dashboard/attachment-handler.js +93 -0
  108. package/src/squad-dashboard/context-monitor.js +157 -0
  109. package/src/squad-dashboard/execution-logs.js +115 -0
  110. package/src/squad-dashboard/hunk-review.js +209 -0
  111. package/src/squad-dashboard/metrics.js +133 -0
  112. package/src/squad-dashboard/process-monitor.js +125 -0
  113. package/src/squad-dashboard/renderer.js +858 -0
  114. package/src/squad-dashboard/server.js +232 -0
  115. package/src/squad-dashboard/styles.js +525 -0
  116. package/src/squad-dashboard/token-tracker.js +99 -0
  117. package/src/tool-executor.js +94 -0
  118. package/src/updater.js +11 -3
  119. package/src/web.js +284 -0
  120. package/src/worker-runner.js +339 -0
  121. package/template/.aioson/agents/analyst.md +62 -3
  122. package/template/.aioson/agents/architect.md +42 -0
  123. package/template/.aioson/agents/design-hybrid-forge.md +127 -0
  124. package/template/.aioson/agents/dev.md +223 -11
  125. package/template/.aioson/agents/deyvin.md +65 -0
  126. package/template/.aioson/agents/neo.md +152 -0
  127. package/template/.aioson/agents/orache.md +17 -0
  128. package/template/.aioson/agents/orchestrator.md +26 -0
  129. package/template/.aioson/agents/pm.md +58 -0
  130. package/template/.aioson/agents/product.md +88 -12
  131. package/template/.aioson/agents/qa.md +80 -0
  132. package/template/.aioson/agents/setup.md +128 -22
  133. package/template/.aioson/agents/sheldon.md +704 -0
  134. package/template/.aioson/agents/squad.md +191 -0
  135. package/template/.aioson/agents/tester.md +410 -0
  136. package/template/.aioson/agents/ux-ui.md +12 -0
  137. package/template/.aioson/config.md +21 -0
  138. package/template/.aioson/context/forensics/.gitkeep +0 -0
  139. package/template/.aioson/context/seeds/seed-example.md +27 -0
  140. package/template/.aioson/context/user-profile.md +42 -0
  141. package/template/.aioson/locales/en/agents/analyst.md +8 -0
  142. package/template/.aioson/locales/en/agents/architect.md +8 -0
  143. package/template/.aioson/locales/en/agents/dev.md +66 -7
  144. package/template/.aioson/locales/en/agents/deyvin.md +8 -0
  145. package/template/.aioson/locales/en/agents/neo.md +8 -0
  146. package/template/.aioson/locales/en/agents/orchestrator.md +26 -0
  147. package/template/.aioson/locales/en/agents/qa.md +49 -0
  148. package/template/.aioson/locales/en/agents/setup.md +35 -2
  149. package/template/.aioson/locales/en/agents/sheldon.md +340 -0
  150. package/template/.aioson/locales/en/agents/ux-ui.md +8 -0
  151. package/template/.aioson/locales/es/agents/analyst.md +8 -0
  152. package/template/.aioson/locales/es/agents/architect.md +8 -0
  153. package/template/.aioson/locales/es/agents/dev.md +66 -7
  154. package/template/.aioson/locales/es/agents/deyvin.md +8 -0
  155. package/template/.aioson/locales/es/agents/neo.md +48 -0
  156. package/template/.aioson/locales/es/agents/orchestrator.md +26 -0
  157. package/template/.aioson/locales/es/agents/qa.md +26 -0
  158. package/template/.aioson/locales/es/agents/setup.md +35 -2
  159. package/template/.aioson/locales/es/agents/sheldon.md +192 -0
  160. package/template/.aioson/locales/es/agents/squad.md +63 -0
  161. package/template/.aioson/locales/es/agents/ux-ui.md +8 -0
  162. package/template/.aioson/locales/fr/agents/analyst.md +8 -0
  163. package/template/.aioson/locales/fr/agents/architect.md +8 -0
  164. package/template/.aioson/locales/fr/agents/dev.md +66 -7
  165. package/template/.aioson/locales/fr/agents/deyvin.md +8 -0
  166. package/template/.aioson/locales/fr/agents/neo.md +48 -0
  167. package/template/.aioson/locales/fr/agents/orchestrator.md +26 -0
  168. package/template/.aioson/locales/fr/agents/qa.md +26 -0
  169. package/template/.aioson/locales/fr/agents/setup.md +35 -2
  170. package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
  171. package/template/.aioson/locales/fr/agents/squad.md +63 -0
  172. package/template/.aioson/locales/fr/agents/ux-ui.md +8 -0
  173. package/template/.aioson/locales/pt-BR/agents/analyst.md +19 -0
  174. package/template/.aioson/locales/pt-BR/agents/architect.md +19 -0
  175. package/template/.aioson/locales/pt-BR/agents/dev.md +75 -12
  176. package/template/.aioson/locales/pt-BR/agents/deyvin.md +8 -0
  177. package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
  178. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +26 -0
  179. package/template/.aioson/locales/pt-BR/agents/product.md +8 -3
  180. package/template/.aioson/locales/pt-BR/agents/qa.md +60 -0
  181. package/template/.aioson/locales/pt-BR/agents/setup.md +35 -2
  182. package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
  183. package/template/.aioson/locales/pt-BR/agents/squad.md +105 -0
  184. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +8 -0
  185. package/template/.aioson/schemas/squad-blueprint.schema.json +21 -0
  186. package/template/.aioson/schemas/squad-manifest.schema.json +178 -1
  187. package/template/.aioson/skills/design/aurora-command-ui/SKILL.md +243 -0
  188. package/template/.aioson/skills/design/aurora-command-ui/references/art-direction.md +293 -0
  189. package/template/.aioson/skills/design/aurora-command-ui/references/components.md +827 -0
  190. package/template/.aioson/skills/design/aurora-command-ui/references/dashboards.md +250 -0
  191. package/template/.aioson/skills/design/aurora-command-ui/references/design-tokens.md +585 -0
  192. package/template/.aioson/skills/design/aurora-command-ui/references/motion.md +365 -0
  193. package/template/.aioson/skills/design/aurora-command-ui/references/patterns.md +482 -0
  194. package/template/.aioson/skills/design/aurora-command-ui/references/websites.md +387 -0
  195. package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
  196. package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
  197. package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
  198. package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
  199. package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
  200. package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
  201. package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
  202. package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
  203. package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
  204. package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
  205. package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
  206. package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
  207. package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
  208. package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
  209. package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
  210. package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
  211. package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +55 -9
  212. package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
  213. package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +1 -1
  214. package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +100 -0
  215. package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +43 -9
  216. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +40 -0
  217. package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +1 -1
  218. package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +99 -12
  219. package/template/.aioson/skills/design/glassmorphism-ui/SKILL.md +222 -0
  220. package/template/.aioson/skills/design/glassmorphism-ui/references/art-direction.md +159 -0
  221. package/template/.aioson/skills/design/glassmorphism-ui/references/components.md +498 -0
  222. package/template/.aioson/skills/design/glassmorphism-ui/references/dashboards.md +236 -0
  223. package/template/.aioson/skills/design/glassmorphism-ui/references/design-tokens.md +274 -0
  224. package/template/.aioson/skills/design/glassmorphism-ui/references/motion.md +355 -0
  225. package/template/.aioson/skills/design/glassmorphism-ui/references/patterns.md +198 -0
  226. package/template/.aioson/skills/design/glassmorphism-ui/references/websites.md +307 -0
  227. package/template/.aioson/skills/design/neo-brutalist-ui/SKILL.md +213 -0
  228. package/template/.aioson/skills/design/neo-brutalist-ui/references/art-direction.md +228 -0
  229. package/template/.aioson/skills/design/neo-brutalist-ui/references/components.md +855 -0
  230. package/template/.aioson/skills/design/neo-brutalist-ui/references/dashboards.md +334 -0
  231. package/template/.aioson/skills/design/neo-brutalist-ui/references/design-tokens.md +342 -0
  232. package/template/.aioson/skills/design/neo-brutalist-ui/references/motion.md +286 -0
  233. package/template/.aioson/skills/design/neo-brutalist-ui/references/patterns.md +458 -0
  234. package/template/.aioson/skills/design/neo-brutalist-ui/references/websites.md +723 -0
  235. package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
  236. package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
  237. package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
  238. package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
  239. package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
  240. package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
  241. package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
  242. package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
  243. package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
  244. package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
  245. package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
  246. package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
  247. package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
  248. package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
  249. package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
  250. package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
  251. package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
  252. package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
  253. package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
  254. package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
  255. package/template/.aioson/skills/process/aioson-spec-driven/SKILL.md +45 -0
  256. package/template/.aioson/skills/process/aioson-spec-driven/references/approval-gates.md +109 -0
  257. package/template/.aioson/skills/process/aioson-spec-driven/references/artifact-map.md +44 -0
  258. package/template/.aioson/skills/process/aioson-spec-driven/references/classification-map.md +37 -0
  259. package/template/.aioson/skills/process/aioson-spec-driven/references/hardening-lane.md +49 -0
  260. package/template/.aioson/skills/process/aioson-spec-driven/references/maintenance-and-state.md +66 -0
  261. package/template/.aioson/skills/process/aioson-spec-driven/references/ui-language.md +75 -0
  262. package/template/.aioson/skills/process/design-hybrid-forge/SKILL.md +144 -0
  263. package/template/.aioson/skills/process/design-hybrid-forge/references/crossover-protocol.md +221 -0
  264. package/template/.aioson/skills/process/design-hybrid-forge/references/naming-registry.md +88 -0
  265. package/template/.aioson/skills/process/design-hybrid-forge/references/output-contract.md +291 -0
  266. package/template/.aioson/skills/process/design-hybrid-forge/references/pair-compatibility.md +117 -0
  267. package/template/.aioson/skills/process/design-hybrid-forge/references/quality-gates.md +188 -0
  268. package/template/.aioson/skills/process/design-hybrid-forge/references/variation-library.md +125 -0
  269. package/template/.aioson/skills/squad/formats/catalog.json +15 -0
  270. package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
  271. package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
  272. package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
  273. package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
  274. package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
  275. package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
  276. package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
  277. package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
  278. package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
  279. package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
  280. package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
  281. package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
  282. package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
  283. package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
  284. package/template/.aioson/skills/squad/references/checklist-templates.md +122 -0
  285. package/template/.aioson/skills/squad/references/executor-archetypes.md +123 -0
  286. package/template/.aioson/skills/squad/references/workflow-templates.md +169 -0
  287. package/template/.aioson/skills/static/debugging-protocol.md +42 -0
  288. package/template/.aioson/skills/static/git-worktrees.md +36 -0
  289. package/template/.aioson/tasks/implementation-plan.md +19 -0
  290. package/template/.aioson/tasks/squad-design.md +28 -0
  291. package/template/.aioson/tasks/squad-profile.md +48 -0
  292. package/template/.aioson/tasks/squad-review.md +61 -0
  293. package/template/.aioson/tasks/squad-task-decompose.md +66 -0
  294. package/template/.claude/commands/aioson/agent/neo.md +5 -0
  295. package/template/.claude/commands/aioson/agent/tester.md +5 -0
  296. package/template/.gemini/GEMINI.md +1 -0
  297. package/template/.gemini/commands/aios-neo.toml +4 -0
  298. package/template/.gemini/commands/aios-tester.toml +6 -0
  299. package/template/AGENTS.md +26 -1
  300. package/template/CLAUDE.md +6 -2
  301. package/template/OPENCODE.md +2 -0
@@ -16,6 +16,47 @@ function resolveTargetDir(args) {
16
16
  return path.resolve(process.cwd(), args[0] || '.');
17
17
  }
18
18
 
19
+ async function copyRecursive(src, dest) {
20
+ const stat = await fs.stat(src);
21
+ if (stat.isDirectory()) {
22
+ await ensureDir(dest);
23
+ const entries = await fs.readdir(src);
24
+ for (const entry of entries) {
25
+ await copyRecursive(path.join(src, entry), path.join(dest, entry));
26
+ }
27
+ return;
28
+ }
29
+
30
+ await ensureDir(path.dirname(dest));
31
+ await fs.copyFile(src, dest);
32
+ }
33
+
34
+ async function replaceDirectory(srcDir, destDir) {
35
+ await fs.rm(destDir, { recursive: true, force: true });
36
+ await copyRecursive(srcDir, destDir);
37
+ }
38
+
39
+ async function readJsonIfExists(filePath) {
40
+ if (!(await exists(filePath))) return null;
41
+ try {
42
+ return JSON.parse(await fs.readFile(filePath, 'utf8'));
43
+ } catch {
44
+ return null;
45
+ }
46
+ }
47
+
48
+ async function writeSkillMeta(destDir, patch) {
49
+ const metaPath = path.join(destDir, '.skill-meta.json');
50
+ const existing = await readJsonIfExists(metaPath) || {};
51
+ const merged = {
52
+ ...existing,
53
+ ...patch
54
+ };
55
+
56
+ await fs.writeFile(metaPath, JSON.stringify(merged, null, 2), 'utf8');
57
+ return merged;
58
+ }
59
+
19
60
  /**
20
61
  * Parse YAML frontmatter from a SKILL.md file.
21
62
  */
@@ -44,17 +85,7 @@ async function distributeToTool(targetDir, slug, skillDir) {
44
85
  for (const toolPath of TOOL_TARGETS) {
45
86
  const toolSkillDir = path.join(targetDir, toolPath, slug);
46
87
  try {
47
- await ensureDir(toolSkillDir);
48
- // Copy all files from the installed skill dir
49
- const entries = await fs.readdir(skillDir);
50
- for (const entry of entries) {
51
- const src = path.join(skillDir, entry);
52
- const dest = path.join(toolSkillDir, entry);
53
- const stat = await fs.stat(src);
54
- if (stat.isFile()) {
55
- await fs.copyFile(src, dest);
56
- }
57
- }
88
+ await replaceDirectory(skillDir, toolSkillDir);
58
89
  results.push({ tool: toolPath, ok: true });
59
90
  } catch (err) {
60
91
  results.push({ tool: toolPath, ok: false, error: err.message });
@@ -187,12 +218,13 @@ async function installFromNpm(targetDir, slug, options, logger) {
187
218
 
188
219
  // Copy to .aioson/installed-skills/{slug}/
189
220
  const destDir = path.join(targetDir, INSTALLED_SKILLS_DIR, slug);
190
- await ensureDir(destDir);
191
-
192
- const entries = await fs.readdir(sourceDir);
193
- for (const entry of entries) {
194
- await fs.copyFile(path.join(sourceDir, entry), path.join(destDir, entry));
195
- }
221
+ await replaceDirectory(sourceDir, destDir);
222
+ await writeSkillMeta(destDir, {
223
+ source: 'npm',
224
+ sourcePackage: '@tech-leads-club/agent-skills',
225
+ sourcePath: path.relative(targetDir, sourceDir),
226
+ installedAt: new Date().toISOString()
227
+ });
196
228
 
197
229
  resolve({ ok: true, sourceDir, destDir });
198
230
  });
@@ -248,15 +280,16 @@ async function installFromCloud(targetDir, slug, options, logger) {
248
280
  ].join('\n');
249
281
 
250
282
  const destDir = path.join(targetDir, INSTALLED_SKILLS_DIR, slug);
283
+ await fs.rm(destDir, { recursive: true, force: true });
251
284
  await ensureDir(destDir);
252
285
  await fs.writeFile(path.join(destDir, 'SKILL.md'), fm, 'utf8');
253
286
 
254
287
  // Write meta
255
- await fs.writeFile(path.join(destDir, '.skill-meta.json'), JSON.stringify({
288
+ await writeSkillMeta(destDir, {
256
289
  source: 'cloud',
257
290
  cloudSlug: snapshot.skill.slug,
258
291
  installedAt: new Date().toISOString()
259
- }, null, 2), 'utf8');
292
+ });
260
293
 
261
294
  return { ok: true, destDir };
262
295
  }
@@ -271,30 +304,32 @@ async function installFromLocal(targetDir, slug, filePath, logger) {
271
304
  }
272
305
 
273
306
  const destDir = path.join(targetDir, INSTALLED_SKILLS_DIR, slug);
274
- await ensureDir(destDir);
275
-
276
307
  const stat = await fs.stat(absPath);
308
+ const samePath = path.resolve(absPath) === path.resolve(destDir);
309
+
310
+ if (!samePath) {
311
+ await fs.rm(destDir, { recursive: true, force: true });
312
+ await ensureDir(destDir);
313
+ } else if (!stat.isDirectory()) {
314
+ return { ok: false, error: 'Local self-install only supports skill directories' };
315
+ }
316
+
277
317
  if (stat.isDirectory()) {
278
- // Copy entire directory
279
- const entries = await fs.readdir(absPath);
280
- for (const entry of entries) {
281
- const src = path.join(absPath, entry);
282
- const srcStat = await fs.stat(src);
283
- if (srcStat.isFile()) {
284
- await fs.copyFile(src, path.join(destDir, entry));
285
- }
318
+ if (!samePath) {
319
+ await replaceDirectory(absPath, destDir);
286
320
  }
287
321
  } else {
288
322
  // Single file — copy as SKILL.md
323
+ await ensureDir(destDir);
289
324
  await fs.copyFile(absPath, path.join(destDir, 'SKILL.md'));
290
325
  }
291
326
 
292
327
  // Write meta
293
- await fs.writeFile(path.join(destDir, '.skill-meta.json'), JSON.stringify({
328
+ await writeSkillMeta(destDir, {
294
329
  source: 'local',
295
330
  sourcePath: filePath,
296
331
  installedAt: new Date().toISOString()
297
- }, null, 2), 'utf8');
332
+ });
298
333
 
299
334
  return { ok: true, destDir };
300
335
  }
@@ -429,17 +464,27 @@ async function runSkillList({ args, options = {}, logger, t }) {
429
464
  const fm = parseSkillFrontmatter(raw);
430
465
 
431
466
  let source = 'unknown';
467
+ let meta = null;
432
468
  try {
433
469
  const metaRaw = await fs.readFile(path.join(skillsDir, slug, '.skill-meta.json'), 'utf8');
434
- const meta = JSON.parse(metaRaw);
470
+ meta = JSON.parse(metaRaw);
435
471
  source = meta.source || 'unknown';
436
472
  } catch { /* no meta */ }
437
473
 
474
+ const author = meta?.author?.name || meta?.author_name || null;
475
+ const model =
476
+ meta?.generator?.model ||
477
+ meta?.generation?.model ||
478
+ meta?.generated_by_model ||
479
+ null;
480
+
438
481
  installed.push({
439
482
  slug,
440
483
  name: fm.name || slug,
441
484
  description: fm.description || '',
442
485
  source,
486
+ author,
487
+ model,
443
488
  path: path.relative(targetDir, path.join(skillsDir, slug))
444
489
  });
445
490
  }
@@ -472,6 +517,8 @@ async function runSkillList({ args, options = {}, logger, t }) {
472
517
  if (s.description) {
473
518
  logger.log(` ${s.description.slice(0, 100)}`);
474
519
  }
520
+ if (s.author) logger.log(` author: ${s.author}`);
521
+ if (s.model) logger.log(` model: ${s.model}`);
475
522
  logger.log(` ${s.path}/SKILL.md`);
476
523
  logger.log('');
477
524
  }
@@ -0,0 +1,209 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const { SquadDaemon } = require('../squad-daemon');
6
+ const { openRuntimeDb } = require('../runtime-store');
7
+
8
+ async function handleStart(projectDir, squadSlug, options, { logger, t }) {
9
+ if (!squadSlug) {
10
+ logger.error(t('squad_daemon.squad_required'));
11
+ return { ok: false };
12
+ }
13
+
14
+ let squadConfig = {};
15
+ try {
16
+ const squadJsonPath = path.join(projectDir, '.aioson', 'squads', squadSlug, 'squad.json');
17
+ squadConfig = JSON.parse(await fs.readFile(squadJsonPath, 'utf8'));
18
+ } catch { /* squad.json is optional */ }
19
+
20
+ const daemon = new SquadDaemon(projectDir, squadSlug, {
21
+ port: options.port ? Number(options.port) : 0,
22
+ poll: options.poll ? Number(options.poll) : 10000,
23
+ config: squadConfig
24
+ });
25
+
26
+ try {
27
+ const info = await daemon.start();
28
+ logger.log(t('squad_daemon.started', {
29
+ squad: squadSlug,
30
+ port: info.port,
31
+ workers: info.workers,
32
+ cron: info.cronJobs
33
+ }));
34
+ logger.log(t('squad_daemon.webhook_hint', { port: info.port }));
35
+ logger.log(t('squad_daemon.stop_hint'));
36
+
37
+ // Keep alive until signal
38
+ await new Promise((resolve) => {
39
+ process.on('SIGINT', resolve);
40
+ process.on('SIGTERM', resolve);
41
+ });
42
+
43
+ logger.log(t('squad_daemon.stopping'));
44
+ await daemon.stop();
45
+ return { ok: true, ...info };
46
+ } catch (err) {
47
+ logger.error(t('squad_daemon.start_failed', { error: err.message }));
48
+ return { ok: false, error: err.message };
49
+ }
50
+ }
51
+
52
+ async function handleStatus(projectDir, squadSlug, { logger, t }) {
53
+ if (!squadSlug) {
54
+ // List all daemons
55
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
56
+ if (!handle) {
57
+ logger.error(t('squad_daemon.no_runtime'));
58
+ return { ok: false };
59
+ }
60
+ const { db } = handle;
61
+ try {
62
+ const daemons = db.prepare('SELECT * FROM squad_daemons ORDER BY squad_slug').all();
63
+ if (daemons.length === 0) {
64
+ logger.log(t('squad_daemon.no_daemons'));
65
+ return { ok: true, daemons: [] };
66
+ }
67
+ logger.log(`Daemons (${daemons.length}):`);
68
+ for (const d of daemons) {
69
+ const icon = d.status === 'running' ? '[*]' : '[ ]';
70
+ logger.log(` ${icon} ${d.squad_slug} (${d.status}) port:${d.port || '-'} pid:${d.pid || '-'} heartbeat:${d.last_heartbeat || '-'}`);
71
+ }
72
+ return { ok: true, daemons };
73
+ } finally {
74
+ db.close();
75
+ }
76
+ }
77
+
78
+ // Specific squad daemon status
79
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
80
+ if (!handle) {
81
+ logger.error(t('squad_daemon.no_runtime'));
82
+ return { ok: false };
83
+ }
84
+ const { db } = handle;
85
+ try {
86
+ const record = db.prepare('SELECT * FROM squad_daemons WHERE squad_slug = ?').get(squadSlug);
87
+ if (!record) {
88
+ logger.log(t('squad_daemon.not_found', { squad: squadSlug }));
89
+ return { ok: true, daemon: null };
90
+ }
91
+ logger.log(`Daemon: ${record.squad_slug}`);
92
+ logger.log(` Status: ${record.status}`);
93
+ logger.log(` PID: ${record.pid || '-'}`);
94
+ logger.log(` Port: ${record.port || '-'}`);
95
+ logger.log(` Started: ${record.started_at || '-'}`);
96
+ logger.log(` Heartbeat: ${record.last_heartbeat || '-'}`);
97
+ if (record.error_message) logger.log(` Error: ${record.error_message}`);
98
+ if (record.config_json) {
99
+ try {
100
+ const config = JSON.parse(record.config_json);
101
+ if (config.cronJobs && config.cronJobs.length > 0) {
102
+ logger.log(` Cron Jobs:`);
103
+ for (const job of config.cronJobs) {
104
+ logger.log(` - ${job.worker} (${job.cron})`);
105
+ }
106
+ }
107
+ } catch { /* ignore */ }
108
+ }
109
+ return { ok: true, daemon: record };
110
+ } finally {
111
+ db.close();
112
+ }
113
+ }
114
+
115
+ async function handleStop(projectDir, squadSlug, { logger, t }) {
116
+ if (!squadSlug) {
117
+ logger.error(t('squad_daemon.squad_required'));
118
+ return { ok: false };
119
+ }
120
+
121
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
122
+ if (!handle) {
123
+ logger.error(t('squad_daemon.no_runtime'));
124
+ return { ok: false };
125
+ }
126
+ const { db } = handle;
127
+ try {
128
+ const record = db.prepare('SELECT * FROM squad_daemons WHERE squad_slug = ?').get(squadSlug);
129
+ if (!record || record.status !== 'running') {
130
+ logger.log(t('squad_daemon.not_running', { squad: squadSlug }));
131
+ return { ok: true };
132
+ }
133
+
134
+ // Try to kill the process
135
+ if (record.pid) {
136
+ try {
137
+ process.kill(record.pid, 'SIGTERM');
138
+ logger.log(t('squad_daemon.signal_sent', { squad: squadSlug, pid: record.pid }));
139
+ } catch {
140
+ logger.log(t('squad_daemon.process_gone', { squad: squadSlug }));
141
+ }
142
+ }
143
+
144
+ // Update record
145
+ db.prepare(
146
+ "UPDATE squad_daemons SET status = 'stopped' WHERE squad_slug = ?"
147
+ ).run(squadSlug);
148
+
149
+ return { ok: true };
150
+ } finally {
151
+ db.close();
152
+ }
153
+ }
154
+
155
+ async function handleLogs(projectDir, squadSlug, { logger, t }) {
156
+ if (!squadSlug) {
157
+ logger.error(t('squad_daemon.squad_required'));
158
+ return { ok: false };
159
+ }
160
+
161
+ // Show recent worker runs as daemon logs
162
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
163
+ if (!handle) {
164
+ logger.error(t('squad_daemon.no_runtime'));
165
+ return { ok: false };
166
+ }
167
+ const { db } = handle;
168
+ try {
169
+ const runs = db.prepare(
170
+ 'SELECT * FROM worker_runs WHERE squad_slug = ? ORDER BY created_at DESC LIMIT 30'
171
+ ).all(squadSlug);
172
+ if (runs.length === 0) {
173
+ logger.log(t('squad_daemon.no_logs'));
174
+ return { ok: true, runs: [] };
175
+ }
176
+ logger.log(`Recent daemon activity for "${squadSlug}" (${runs.length}):`);
177
+ for (const r of runs) {
178
+ const icon = r.status === 'completed' ? '[ok]' : r.status === 'failed' ? '[!!]' : '[..]';
179
+ const ms = r.duration_ms ? `${r.duration_ms}ms` : '-';
180
+ logger.log(` ${icon} ${r.created_at} ${r.worker_slug} (${r.trigger_type}) ${ms}`);
181
+ if (r.error_message) logger.log(` ${r.error_message}`);
182
+ }
183
+ return { ok: true, runs };
184
+ } finally {
185
+ db.close();
186
+ }
187
+ }
188
+
189
+ async function runSquadDaemon({ args, options, logger, t }) {
190
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
191
+ const sub = options.sub || 'status';
192
+ const squadSlug = options.squad;
193
+
194
+ switch (sub) {
195
+ case 'start':
196
+ return handleStart(targetDir, squadSlug, options, { logger, t });
197
+ case 'status':
198
+ return handleStatus(targetDir, squadSlug, { logger, t });
199
+ case 'stop':
200
+ return handleStop(targetDir, squadSlug, { logger, t });
201
+ case 'logs':
202
+ return handleLogs(targetDir, squadSlug, { logger, t });
203
+ default:
204
+ logger.error(t('squad_daemon.unknown_sub', { sub }));
205
+ return { ok: false };
206
+ }
207
+ }
208
+
209
+ module.exports = { runSquadDaemon };
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { createDashboardServer } = require('../squad-dashboard/server');
5
+
6
+ async function runSquadDashboard({ args, options, logger, t }) {
7
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
8
+ const port = Number(options.port) || 4180;
9
+ const filterSquad = options.squad || null;
10
+
11
+ const dashboard = createDashboardServer(targetDir, { port, squad: filterSquad });
12
+
13
+ try {
14
+ const info = await dashboard.start();
15
+ logger.log(t('squad_dashboard.started', { url: info.url, port: info.port }));
16
+ if (filterSquad) {
17
+ logger.log(t('squad_dashboard.filtered', { squad: filterSquad }));
18
+ }
19
+ logger.log(t('squad_dashboard.stop_hint'));
20
+
21
+ // Keep the process alive until SIGINT/SIGTERM
22
+ await new Promise((resolve) => {
23
+ process.on('SIGINT', resolve);
24
+ process.on('SIGTERM', resolve);
25
+ });
26
+
27
+ logger.log(t('squad_dashboard.stopping'));
28
+ await dashboard.stop();
29
+ return { ok: true, port: info.port, url: info.url };
30
+ } catch (err) {
31
+ if (err.code === 'EADDRINUSE') {
32
+ logger.error(t('squad_dashboard.port_in_use', { port }));
33
+ return { ok: false, error: `Port ${port} already in use` };
34
+ }
35
+ throw err;
36
+ }
37
+ }
38
+
39
+ module.exports = { runSquadDashboard };
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+
6
+ async function runSquadDeploy({ args, options, logger }) {
7
+ const squadSlug = args[0] || options.squad;
8
+ const projectDir = path.resolve(args[1] || options.path || '.');
9
+ const provider = options.provider || 'cloudpanel';
10
+
11
+ if (!squadSlug) {
12
+ logger.log('Uso: aioson squad:deploy <squad> [dir] --provider=cloudpanel');
13
+ return { ok: false };
14
+ }
15
+
16
+ const squadJsonPath = path.join(projectDir, '.aioson', 'squads', squadSlug, 'squad.json');
17
+ let squadConfig;
18
+ try {
19
+ squadConfig = JSON.parse(await fs.readFile(squadJsonPath, 'utf8'));
20
+ } catch {
21
+ logger.log(`Squad "${squadSlug}" não encontrado em ${squadJsonPath}`);
22
+ return { ok: false, error: 'squad_not_found' };
23
+ }
24
+
25
+ const port = squadConfig.port || 3001;
26
+ const deployDir = path.join(projectDir, '.aioson', 'squads', squadSlug, 'deploy');
27
+ await fs.mkdir(deployDir, { recursive: true });
28
+
29
+ const nginxConf = generateNginxConf(squadSlug, port, provider);
30
+ const outPath = path.join(deployDir, 'nginx.conf');
31
+ await fs.writeFile(outPath, nginxConf);
32
+
33
+ logger.log(`✓ Configuração nginx gerada: ${outPath}`);
34
+ logger.log('');
35
+ logger.log('Instruções CloudPanel:');
36
+ logger.log(' 1. Acesse CloudPanel → Websites → [seu site] → Nginx');
37
+ logger.log(' 2. Cole o conteúdo do arquivo nginx.conf em "Custom Nginx Directives"');
38
+ logger.log(' 3. Salve e aguarde o reload automático do nginx');
39
+ logger.log(` 4. Certifique-se que o daemon está rodando: aioson squad:daemon ${squadSlug} start`);
40
+
41
+ return { ok: true, path: outPath };
42
+ }
43
+
44
+ function generateNginxConf(slug, port, provider) {
45
+ return [
46
+ `# Squad: ${slug} — gerado por aioson squad:deploy`,
47
+ `# Provider: ${provider}`,
48
+ `# Cole em: CloudPanel → Website → Nginx → Custom Nginx Directives`,
49
+ `#`,
50
+ `# Pré-requisito: aioson squad:daemon ${slug} start`,
51
+ ``,
52
+ `location /${slug}/webhook/ {`,
53
+ ` proxy_pass http://127.0.0.1:${port}/webhook/;`,
54
+ ` proxy_http_version 1.1;`,
55
+ ` proxy_set_header Host $host;`,
56
+ ` proxy_set_header X-Real-IP $remote_addr;`,
57
+ ` proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;`,
58
+ ` proxy_read_timeout 30s;`,
59
+ ` proxy_connect_timeout 5s;`,
60
+ `}`,
61
+ ].join('\n');
62
+ }
63
+
64
+ module.exports = { runSquadDeploy, generateNginxConf };
@@ -5,6 +5,7 @@ const path = require('node:path');
5
5
  const { openRuntimeDb } = require('../runtime-store');
6
6
  const { exists } = require('../utils');
7
7
  const { runSquadValidate } = require('./squad-validate');
8
+ const { scoreCompletude, scoreProfundidade, scoreQualidadeEstrutural, scorePotencial, gradeFromScore } = require('./squad-score');
8
9
 
9
10
  function normalizeRel(value) {
10
11
  return String(value || '')
@@ -259,6 +260,36 @@ async function runSquadDoctor({ args, options = {}, logger, t }) {
259
260
  ));
260
261
  }
261
262
 
263
+ // Webhook production checks (from squad.json, optional file)
264
+ const squadJsonPath = path.join(paths.packageDir, 'squad.json');
265
+ let squadConfig = null;
266
+ try {
267
+ const raw = await fs.readFile(squadJsonPath, 'utf8');
268
+ squadConfig = JSON.parse(raw);
269
+ } catch { /* squad.json is optional */ }
270
+
271
+ if (squadConfig && squadConfig.webhook?.validate_signature) {
272
+ const envKey = squadConfig.webhook.signature_env || 'WEBHOOK_SECRET';
273
+ const defined = Boolean(process.env[envKey]);
274
+ checks.push(makeCheck(
275
+ `webhook_env_${envKey}`,
276
+ defined,
277
+ defined ? 'info' : 'error',
278
+ defined
279
+ ? `Env ${envKey} definida (HMAC validation enabled)`
280
+ : `Env ${envKey} não definida — webhook HMAC validation está ativo mas a variável está ausente`
281
+ ));
282
+ }
283
+
284
+ if (squadConfig && squadConfig.webhook?.public) {
285
+ checks.push(makeCheck(
286
+ 'webhook_public_deploy',
287
+ null,
288
+ 'warn',
289
+ 'Config nginx: execute aioson squad:deploy para gerar nginx.conf'
290
+ ));
291
+ }
292
+
262
293
  const runtimeHandle = await openRuntimeDb(targetDir, { mustExist: true });
263
294
  if (!runtimeHandle) {
264
295
  checks.push(makeCheck('runtime_store', false, 'warn', t('squad_doctor.check_runtime_missing')));
@@ -347,6 +378,27 @@ async function runSquadDoctor({ args, options = {}, logger, t }) {
347
378
  checks.push(makeCheck('formal_validation', true, 'info', 'Manifest formally valid'));
348
379
  }
349
380
 
381
+ // Quality score
382
+ try {
383
+ const d1 = scoreCompletude(manifest);
384
+ const d2 = scoreProfundidade(manifest);
385
+ const d3 = scoreQualidadeEstrutural(manifest);
386
+ const d4 = scorePotencial(manifest);
387
+ const total = d1.score + d2.score + d3.score + d4.score;
388
+ const maxTotal = d1.max + d2.max + d3.max + d4.max;
389
+ const grade = gradeFromScore(total);
390
+ const isLow = total < 50;
391
+ checks.push(
392
+ makeCheck(
393
+ 'quality_score',
394
+ !isLow,
395
+ 'info',
396
+ `Quality score: ${total}/${maxTotal} — ${grade}`,
397
+ { qualityScore: { total, max: maxTotal, grade } }
398
+ )
399
+ );
400
+ } catch { /* scoring not critical */ }
401
+
350
402
  const summary = {
351
403
  failed: checks.filter((check) => check.severity === 'error' && !check.ok).length,
352
404
  warned: checks.filter((check) => check.severity === 'warn' && !check.ok).length,