@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
@@ -0,0 +1,191 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const {
5
+ loadWorkerConfig,
6
+ listWorkers,
7
+ runWorker,
8
+ scaffoldWorker
9
+ } = require('../worker-runner');
10
+ const {
11
+ openRuntimeDb,
12
+ insertWorkerRun,
13
+ listWorkerRuns
14
+ } = require('../runtime-store');
15
+
16
+ async function handleList(projectDir, squadSlug, { logger, t }) {
17
+ if (!squadSlug) {
18
+ logger.error(t('squad_worker.squad_required'));
19
+ return { ok: false };
20
+ }
21
+ const workers = await listWorkers(projectDir, squadSlug);
22
+ if (workers.length === 0) {
23
+ logger.log(t('squad_worker.no_workers'));
24
+ return { ok: true, workers: [] };
25
+ }
26
+ logger.log(`Workers for squad "${squadSlug}" (${workers.length}):`);
27
+ for (const w of workers) {
28
+ logger.log(` ${w.slug} [${w.type || 'manual'}] - ${w.name || w.slug}`);
29
+ }
30
+ return { ok: true, workers };
31
+ }
32
+
33
+ async function handleRun(projectDir, squadSlug, workerSlug, inputStr, { logger, t }) {
34
+ if (!squadSlug || !workerSlug) {
35
+ logger.error(t('squad_worker.run_usage'));
36
+ return { ok: false };
37
+ }
38
+
39
+ let inputPayload = {};
40
+ if (inputStr) {
41
+ try {
42
+ inputPayload = JSON.parse(inputStr);
43
+ } catch {
44
+ logger.error(t('squad_worker.invalid_input'));
45
+ return { ok: false, error: 'Invalid JSON input' };
46
+ }
47
+ }
48
+
49
+ logger.log(`Running worker "${workerSlug}" on squad "${squadSlug}"...`);
50
+ const result = await runWorker(projectDir, squadSlug, workerSlug, inputPayload, { triggerType: 'manual' });
51
+
52
+ // Log to runtime store
53
+ const handle = await openRuntimeDb(projectDir, { mustExist: false });
54
+ if (handle) {
55
+ const { db } = handle;
56
+ try {
57
+ insertWorkerRun(db, {
58
+ squadSlug,
59
+ workerSlug,
60
+ triggerType: 'manual',
61
+ inputJson: JSON.stringify(inputPayload),
62
+ outputJson: result.ok ? JSON.stringify(result.output) : null,
63
+ status: result.ok ? 'completed' : 'failed',
64
+ errorMessage: result.ok ? null : result.error,
65
+ durationMs: result.durationMs || 0,
66
+ attempt: result.attempt || 1
67
+ });
68
+ } finally {
69
+ db.close();
70
+ }
71
+ }
72
+
73
+ if (result.ok) {
74
+ logger.log(t('squad_worker.run_success', { worker: workerSlug }));
75
+ logger.log(JSON.stringify(result.output, null, 2));
76
+ } else {
77
+ logger.error(t('squad_worker.run_failed', { worker: workerSlug, error: result.error }));
78
+ }
79
+ return result;
80
+ }
81
+
82
+ async function handleTest(projectDir, squadSlug, workerSlug, { logger, t }) {
83
+ if (!squadSlug || !workerSlug) {
84
+ logger.error(t('squad_worker.test_usage'));
85
+ return { ok: false };
86
+ }
87
+
88
+ const config = await loadWorkerConfig(projectDir, squadSlug, workerSlug);
89
+ if (!config) {
90
+ logger.error(t('squad_worker.not_found', { worker: workerSlug }));
91
+ return { ok: false };
92
+ }
93
+
94
+ // Build mock input from schema
95
+ const mockInput = {};
96
+ for (const [key, spec] of Object.entries(config.inputs || {})) {
97
+ if (spec.type === 'string') mockInput[key] = `test-${key}`;
98
+ else if (spec.type === 'number') mockInput[key] = 0;
99
+ else mockInput[key] = `test-${key}`;
100
+ }
101
+
102
+ logger.log(`Testing worker "${workerSlug}" with mock input:`);
103
+ logger.log(JSON.stringify(mockInput, null, 2));
104
+
105
+ const result = await runWorker(projectDir, squadSlug, workerSlug, mockInput, {
106
+ triggerType: 'manual',
107
+ noRetry: true
108
+ });
109
+
110
+ if (result.ok) {
111
+ logger.log(t('squad_worker.test_passed', { worker: workerSlug }));
112
+ logger.log(JSON.stringify(result.output, null, 2));
113
+ } else {
114
+ logger.error(t('squad_worker.test_failed', { worker: workerSlug, error: result.error }));
115
+ }
116
+ return result;
117
+ }
118
+
119
+ async function handleLogs(projectDir, squadSlug, { logger, t }) {
120
+ if (!squadSlug) {
121
+ logger.error(t('squad_worker.squad_required'));
122
+ return { ok: false };
123
+ }
124
+
125
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
126
+ if (!handle) {
127
+ logger.error(t('squad_worker.no_runtime'));
128
+ return { ok: false };
129
+ }
130
+ const { db } = handle;
131
+ try {
132
+ const runs = listWorkerRuns(db, squadSlug);
133
+ if (runs.length === 0) {
134
+ logger.log(t('squad_worker.no_logs'));
135
+ return { ok: true, runs: [] };
136
+ }
137
+ logger.log(`Worker runs for squad "${squadSlug}" (${runs.length}):`);
138
+ for (const run of runs) {
139
+ const icon = run.status === 'completed' ? '[ok]' : run.status === 'failed' ? '[!!]' : '[..]';
140
+ const duration = run.duration_ms ? `${run.duration_ms}ms` : '-';
141
+ logger.log(` ${icon} ${run.worker_slug} (${run.trigger_type}) ${duration} - ${run.created_at}`);
142
+ if (run.error_message) logger.log(` Error: ${run.error_message}`);
143
+ }
144
+ return { ok: true, runs };
145
+ } finally {
146
+ db.close();
147
+ }
148
+ }
149
+
150
+ async function handleScaffold(projectDir, squadSlug, workerSlug, options, { logger, t }) {
151
+ if (!squadSlug || !workerSlug) {
152
+ logger.error(t('squad_worker.scaffold_usage'));
153
+ return { ok: false };
154
+ }
155
+
156
+ const result = await scaffoldWorker(projectDir, squadSlug, workerSlug, {
157
+ name: options.name || workerSlug,
158
+ triggerType: options.trigger || 'manual',
159
+ inputs: options.inputs ? options.inputs.split(',') : [],
160
+ outputs: options.outputs ? options.outputs.split(',') : [],
161
+ env: options.env ? options.env.split(',') : []
162
+ });
163
+
164
+ logger.log(t('squad_worker.scaffold_created', { worker: workerSlug, path: result.workerDir }));
165
+ return { ok: true, ...result };
166
+ }
167
+
168
+ async function runSquadWorker({ args, options, logger, t }) {
169
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
170
+ const sub = options.sub || 'list';
171
+ const squadSlug = options.squad;
172
+ const workerSlug = options.worker;
173
+
174
+ switch (sub) {
175
+ case 'list':
176
+ return handleList(targetDir, squadSlug, { logger, t });
177
+ case 'run':
178
+ return handleRun(targetDir, squadSlug, workerSlug, options.input, { logger, t });
179
+ case 'test':
180
+ return handleTest(targetDir, squadSlug, workerSlug, { logger, t });
181
+ case 'logs':
182
+ return handleLogs(targetDir, squadSlug, { logger, t });
183
+ case 'scaffold':
184
+ return handleScaffold(targetDir, squadSlug, workerSlug, options, { logger, t });
185
+ default:
186
+ logger.error(t('squad_worker.unknown_sub', { sub }));
187
+ return { ok: false };
188
+ }
189
+ }
190
+
191
+ module.exports = { runSquadWorker };
@@ -0,0 +1,75 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { createWorktree, mergeWorktree, cleanupWorktree, listWorktrees } = require('../squad/worktree-manager');
5
+
6
+ async function runSquadWorktrees({ args, options, logger }) {
7
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
8
+ const squadSlug = options.squad || args[1];
9
+
10
+ if (!squadSlug) {
11
+ logger.error('Squad slug required. Use --squad <slug>');
12
+ return { ok: false };
13
+ }
14
+
15
+ // --cleanup [agent]
16
+ if (options.cleanup !== undefined) {
17
+ const agentSlug = typeof options.cleanup === 'string' ? options.cleanup : null;
18
+ if (agentSlug) {
19
+ const result = cleanupWorktree(projectDir, squadSlug, agentSlug, true);
20
+ logger.log(result.ok ? `Worktree for "${agentSlug}" removed.` : `Failed to remove worktree for "${agentSlug}".`);
21
+ return result;
22
+ }
23
+ // cleanup all for squad
24
+ const worktrees = listWorktrees(projectDir, squadSlug);
25
+ if (worktrees.length === 0) {
26
+ logger.log(`No worktrees found for squad "${squadSlug}".`);
27
+ return { ok: true };
28
+ }
29
+ for (const wt of worktrees) {
30
+ const result = cleanupWorktree(projectDir, squadSlug, wt.agentSlug, false);
31
+ logger.log(result.ok ? ` Removed: ${wt.agentSlug}` : ` Failed: ${wt.agentSlug}`);
32
+ }
33
+ return { ok: true };
34
+ }
35
+
36
+ // List
37
+ const worktrees = listWorktrees(projectDir, squadSlug);
38
+ if (worktrees.length === 0) {
39
+ logger.log(`No worktrees found for squad "${squadSlug}".`);
40
+ return { ok: true, worktrees: [] };
41
+ }
42
+
43
+ logger.log(`Worktrees for "${squadSlug}" (${worktrees.length}):`);
44
+ for (const wt of worktrees) {
45
+ logger.log(` ${wt.agentSlug} branch:${wt.branch} path:${wt.path}`);
46
+ }
47
+ return { ok: true, worktrees };
48
+ }
49
+
50
+ async function runSquadMerge({ args, options, logger }) {
51
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
52
+ const squadSlug = options.squad || args[1];
53
+ const agentSlug = options.agent || args[2];
54
+
55
+ if (!squadSlug || !agentSlug) {
56
+ logger.error('Usage: aioson squad:merge <project> --squad <squad> --agent <agent>');
57
+ return { ok: false };
58
+ }
59
+
60
+ const autoMerge = options['no-auto'] !== true;
61
+ const result = mergeWorktree(projectDir, squadSlug, agentSlug, autoMerge);
62
+
63
+ if (result.ok) {
64
+ logger.log(`Merged branch ${result.branch} successfully.`);
65
+ } else if (result.reason === 'merge_conflict') {
66
+ logger.error(`Merge conflict on ${result.branch}. Resolve manually.`);
67
+ if (result.detail) logger.error(result.detail);
68
+ } else if (result.reason === 'auto_merge_disabled') {
69
+ logger.log(`Auto-merge disabled. Branch ready: ${result.branch}`);
70
+ }
71
+
72
+ return result;
73
+ }
74
+
75
+ module.exports = { runSquadWorktrees, runSquadMerge };
@@ -0,0 +1,232 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const {
5
+ openRuntimeDb,
6
+ registerDynamicTool,
7
+ unregisterDynamicTool,
8
+ getDynamicTool,
9
+ listDynamicTools
10
+ } = require('../runtime-store');
11
+ const { executeTool } = require('../tool-executor');
12
+
13
+ const TOOL_NAME_RE = /^[a-z][a-z0-9_]*$/;
14
+
15
+ async function runToolRegistry({ args = [], options = {}, logger = console, t = (k) => k } = {}) {
16
+ const projectDir = path.resolve(process.cwd(), args[0] || '.');
17
+ const sub = options.sub || 'list';
18
+
19
+ if (sub === 'register') return handleRegister(projectDir, options, logger);
20
+ if (sub === 'list') return handleList(projectDir, options, logger);
21
+ if (sub === 'call') return handleCall(projectDir, options, logger);
22
+ if (sub === 'unregister') return handleUnregister(projectDir, options, logger);
23
+ if (sub === 'show') return handleShow(projectDir, options, logger);
24
+
25
+ logger.error(`Subcomando desconhecido: ${sub}. Disponíveis: register, list, call, unregister, show`);
26
+ return { ok: false, error: 'unknown_sub' };
27
+ }
28
+
29
+ async function handleRegister(projectDir, options, logger) {
30
+ const name = String(options.name || '').trim();
31
+ const description = String(options.description || options.desc || '').trim();
32
+ const handlerType = String(options.type || 'shell').trim();
33
+ const handlerCode = options.cmd ? String(options.cmd) : null;
34
+ const handlerPath = options.path ? String(options.path) : null;
35
+ const squadSlug = options.squad ? String(options.squad) : null;
36
+ const registeredBy = options.by ? String(options.by) : null;
37
+
38
+ if (!name) {
39
+ logger.error('--name é obrigatório');
40
+ return { ok: false, error: 'name_required' };
41
+ }
42
+ if (!TOOL_NAME_RE.test(name) || name.length > 64) {
43
+ logger.error(`Nome inválido: "${name}". Use apenas letras minúsculas, números e _ (máx 64 chars, começando com letra)`);
44
+ return { ok: false, error: 'invalid_name' };
45
+ }
46
+ if (!description) {
47
+ logger.error('--description é obrigatório');
48
+ return { ok: false, error: 'description_required' };
49
+ }
50
+ if (!['shell', 'script'].includes(handlerType)) {
51
+ logger.error('--type deve ser "shell" ou "script"');
52
+ return { ok: false, error: 'invalid_type' };
53
+ }
54
+ if (handlerType === 'shell' && !handlerCode) {
55
+ logger.error('--cmd é obrigatório para tools do tipo shell');
56
+ return { ok: false, error: 'cmd_required' };
57
+ }
58
+ if (handlerType === 'script' && !handlerPath) {
59
+ logger.error('--path é obrigatório para tools do tipo script');
60
+ return { ok: false, error: 'path_required' };
61
+ }
62
+
63
+ const handle = await openRuntimeDb(projectDir);
64
+ if (!handle) {
65
+ logger.error('Runtime store não encontrado. Execute aioson runtime:init primeiro.');
66
+ return { ok: false, error: 'no_runtime' };
67
+ }
68
+ const { db } = handle;
69
+
70
+ try {
71
+ registerDynamicTool(db, {
72
+ name,
73
+ description,
74
+ handlerType,
75
+ handlerCode,
76
+ handlerPath,
77
+ squadSlug,
78
+ registeredBy
79
+ });
80
+ logger.log(`Tool registrada: ${name} (${handlerType})`);
81
+ return { ok: true, name, handlerType };
82
+ } finally {
83
+ db.close();
84
+ }
85
+ }
86
+
87
+ async function handleList(projectDir, options, logger) {
88
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
89
+ if (!handle) {
90
+ logger.log('Nenhum runtime store encontrado.');
91
+ return { ok: true, tools: [] };
92
+ }
93
+ const { db } = handle;
94
+
95
+ try {
96
+ const tools = listDynamicTools(db, options.squad || null);
97
+ if (tools.length === 0) {
98
+ logger.log('Nenhuma tool registrada neste projeto.');
99
+ return { ok: true, tools: [] };
100
+ }
101
+
102
+ logger.log(`Tools registradas (${tools.length}):`);
103
+ logger.log('');
104
+ for (const tool of tools) {
105
+ const scope = tool.squad_slug ? ` [squad:${tool.squad_slug}]` : '';
106
+ logger.log(` ${tool.name}${scope}`);
107
+ logger.log(` ${tool.description}`);
108
+ logger.log(` tipo: ${tool.handler_type} | registrada: ${tool.registered_at.slice(0, 10)}`);
109
+ logger.log('');
110
+ }
111
+ return { ok: true, tools };
112
+ } finally {
113
+ db.close();
114
+ }
115
+ }
116
+
117
+ async function handleCall(projectDir, options, logger) {
118
+ const name = String(options.name || '').trim();
119
+ if (!name) {
120
+ logger.error('--name é obrigatório');
121
+ return { ok: false, error: 'name_required' };
122
+ }
123
+
124
+ let input = {};
125
+ if (options.input) {
126
+ try {
127
+ input = JSON.parse(String(options.input));
128
+ } catch {
129
+ logger.error('--input deve ser JSON válido');
130
+ return { ok: false, error: 'invalid_input' };
131
+ }
132
+ }
133
+
134
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
135
+ if (!handle) {
136
+ logger.error('Runtime store não encontrado.');
137
+ return { ok: false, error: 'no_runtime' };
138
+ }
139
+ const { db } = handle;
140
+
141
+ let tool;
142
+ try {
143
+ tool = getDynamicTool(db, name);
144
+ } finally {
145
+ db.close();
146
+ }
147
+
148
+ if (!tool) {
149
+ logger.error(`Tool não encontrada: ${name}`);
150
+ return { ok: false, error: 'tool_not_found' };
151
+ }
152
+
153
+ const timeoutMs = options.timeout ? Number(options.timeout) * 1000 : undefined;
154
+ const result = executeTool(tool, input, { projectDir, timeoutMs });
155
+
156
+ if (result.stdout) logger.log(result.stdout);
157
+ if (result.stderr) logger.error(result.stderr);
158
+
159
+ if (!result.ok) {
160
+ logger.error(`Tool falhou (exit ${result.exitCode})${result.error ? `: ${result.error}` : ''}`);
161
+ return { ok: false, exitCode: result.exitCode, error: result.error };
162
+ }
163
+
164
+ return { ok: true, exitCode: result.exitCode, stdout: result.stdout };
165
+ }
166
+
167
+ async function handleUnregister(projectDir, options, logger) {
168
+ const name = String(options.name || '').trim();
169
+ if (!name) {
170
+ logger.error('--name é obrigatório');
171
+ return { ok: false, error: 'name_required' };
172
+ }
173
+
174
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
175
+ if (!handle) {
176
+ logger.error('Runtime store não encontrado.');
177
+ return { ok: false, error: 'no_runtime' };
178
+ }
179
+ const { db } = handle;
180
+
181
+ try {
182
+ const tool = getDynamicTool(db, name);
183
+ if (!tool) {
184
+ logger.error(`Tool não encontrada: ${name}`);
185
+ return { ok: false, error: 'tool_not_found' };
186
+ }
187
+
188
+ unregisterDynamicTool(db, name);
189
+ logger.log(`Tool removida: ${name}`);
190
+ return { ok: true, name };
191
+ } finally {
192
+ db.close();
193
+ }
194
+ }
195
+
196
+ async function handleShow(projectDir, options, logger) {
197
+ const name = String(options.name || '').trim();
198
+ if (!name) {
199
+ logger.error('--name é obrigatório');
200
+ return { ok: false, error: 'name_required' };
201
+ }
202
+
203
+ const handle = await openRuntimeDb(projectDir, { mustExist: true });
204
+ if (!handle) {
205
+ logger.error('Runtime store não encontrado.');
206
+ return { ok: false, error: 'no_runtime' };
207
+ }
208
+ const { db } = handle;
209
+
210
+ try {
211
+ const tool = getDynamicTool(db, name);
212
+ if (!tool) {
213
+ logger.error(`Tool não encontrada: ${name}`);
214
+ return { ok: false, error: 'tool_not_found' };
215
+ }
216
+
217
+ logger.log(`Tool: ${tool.name}`);
218
+ logger.log(`Descrição: ${tool.description}`);
219
+ logger.log(`Tipo: ${tool.handler_type}`);
220
+ if (tool.handler_code) logger.log(`Comando: ${tool.handler_code}`);
221
+ if (tool.handler_path) logger.log(`Script: ${tool.handler_path}`);
222
+ if (tool.squad_slug) logger.log(`Squad: ${tool.squad_slug}`);
223
+ if (tool.registered_by) logger.log(`Registrada por: ${tool.registered_by}`);
224
+ logger.log(`Registrada em: ${tool.registered_at}`);
225
+
226
+ return { ok: true, tool };
227
+ } finally {
228
+ db.close();
229
+ }
230
+ }
231
+
232
+ module.exports = { runToolRegistry };
@@ -28,6 +28,9 @@ async function runUpdate({ args, options, logger, t }) {
28
28
  requestedLanguage ||
29
29
  (context.parsed && context.data && context.data.conversation_language
30
30
  ? context.data.conversation_language
31
+ : null) ||
32
+ (result.savedProfile && result.savedProfile.locale
33
+ ? result.savedProfile.locale
31
34
  : 'en');
32
35
  localeSync = await applyAgentLocale(targetDir, language, { dryRun });
33
36
  }
@@ -35,6 +38,10 @@ async function runUpdate({ args, options, logger, t }) {
35
38
  logger.log(t('update.done_at', { targetDir }));
36
39
  logger.log(t('update.files_updated', { count: result.copied.length }));
37
40
  logger.log(t('update.backups_created', { count: result.backedUp.length }));
41
+ if (!dryRun) {
42
+ logger.log('');
43
+ logger.log(t('update.reconfigure_hint'));
44
+ }
38
45
  if (localeSync) {
39
46
  if (dryRun) {
40
47
  logger.log(t('locale_apply.dry_run_applied', { locale: localeSync.locale }));
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { mapWebsite } = require('../web');
5
+
6
+ function normalizeBoolean(value, fallback = false) {
7
+ if (typeof value === 'boolean') return value;
8
+ if (value === undefined || value === null) return fallback;
9
+ const text = String(value).trim().toLowerCase();
10
+ if (['1', 'true', 'yes', 'y', 'on'].includes(text)) return true;
11
+ if (['0', 'false', 'no', 'n', 'off'].includes(text)) return false;
12
+ return fallback;
13
+ }
14
+
15
+ function parseInteger(value, fallback) {
16
+ const parsed = Number.parseInt(String(value ?? ''), 10);
17
+ return Number.isFinite(parsed) ? parsed : fallback;
18
+ }
19
+
20
+ async function runWebMap({ args, options = {}, logger, t }) {
21
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
22
+ const url = String(options.url || '').trim();
23
+ if (!url) {
24
+ logger.error(t('web_map.url_missing'));
25
+ process.exitCode = 1;
26
+ return { ok: false, error: 'url_missing' };
27
+ }
28
+
29
+ const maxDepth = Math.max(0, parseInteger(options.depth, 2));
30
+ const maxPages = Math.max(1, parseInteger(options['max-pages'], 25));
31
+ const sameOriginOnly = !normalizeBoolean(options['include-external'], false);
32
+
33
+ try {
34
+ logger.log(t('web_map.starting', { url }));
35
+ const result = await mapWebsite(url, { maxDepth, maxPages, sameOriginOnly });
36
+ const output = {
37
+ ok: true,
38
+ targetDir,
39
+ url: result.startUrl,
40
+ maxDepth,
41
+ maxPages,
42
+ sameOriginOnly,
43
+ pageCount: result.pageCount,
44
+ urls: result.urls,
45
+ pages: result.pages
46
+ };
47
+
48
+ if (options.json) return output;
49
+
50
+ logger.log(t('web_map.pages_found', { count: result.pageCount }));
51
+ for (const page of result.pages) {
52
+ logger.log(t('web_map.page_line', {
53
+ url: page.url,
54
+ depth: page.depth,
55
+ status: page.statusCode,
56
+ links: page.linkCount
57
+ }));
58
+ }
59
+ logger.log(t('web_map.done'));
60
+ return output;
61
+ } catch (error) {
62
+ logger.error(t('web_map.failed', { error: error.message }));
63
+ process.exitCode = 1;
64
+ return { ok: false, error: 'map_failed', detail: error.message };
65
+ }
66
+ }
67
+
68
+ module.exports = {
69
+ runWebMap
70
+ };
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { scrapePage } = require('../web');
5
+
6
+ const SUPPORTED_FORMATS = new Set(['markdown', 'text', 'html', 'links']);
7
+
8
+ async function runWebScrape({ args, options = {}, logger, t }) {
9
+ const targetDir = path.resolve(process.cwd(), args[0] || '.');
10
+ const url = String(options.url || '').trim();
11
+ const format = String(options.format || 'markdown').trim().toLowerCase();
12
+
13
+ if (!url) {
14
+ logger.error(t('web_scrape.url_missing'));
15
+ process.exitCode = 1;
16
+ return { ok: false, error: 'url_missing' };
17
+ }
18
+ if (!SUPPORTED_FORMATS.has(format)) {
19
+ logger.error(t('web_scrape.invalid_format', { format }));
20
+ process.exitCode = 1;
21
+ return { ok: false, error: 'invalid_format' };
22
+ }
23
+
24
+ try {
25
+ logger.log(t('web_scrape.fetching', { url }));
26
+ const page = await scrapePage(url, { sameOriginOnly: false });
27
+ const selected = format === 'markdown'
28
+ ? page.markdown
29
+ : format === 'text'
30
+ ? page.text
31
+ : format === 'html'
32
+ ? page.html
33
+ : page.links;
34
+
35
+ const output = {
36
+ ok: true,
37
+ targetDir,
38
+ url: page.url,
39
+ statusCode: page.statusCode,
40
+ contentType: page.contentType,
41
+ title: page.title,
42
+ description: page.description,
43
+ canonical: page.canonical,
44
+ format,
45
+ content: selected,
46
+ links: page.links,
47
+ truncated: page.truncated
48
+ };
49
+
50
+ if (options.json) return output;
51
+
52
+ logger.log(t('web_scrape.title_line', { title: page.title || '-' }));
53
+ logger.log(t('web_scrape.status_line', { status: page.statusCode, type: page.contentType || '-' }));
54
+ logger.log(t('web_scrape.done', { format }));
55
+ if (Array.isArray(selected)) {
56
+ for (const link of selected) logger.log(link);
57
+ } else {
58
+ logger.log(String(selected || ''));
59
+ }
60
+ return output;
61
+ } catch (error) {
62
+ logger.error(t('web_scrape.failed', { error: error.message }));
63
+ process.exitCode = 1;
64
+ return { ok: false, error: 'scrape_failed', detail: error.message };
65
+ }
66
+ }
67
+
68
+ module.exports = {
69
+ runWebScrape,
70
+ SUPPORTED_FORMATS
71
+ };
package/src/constants.js CHANGED
@@ -33,6 +33,7 @@ const MANAGED_FILES = [
33
33
  '.aioson/agents/squad.md',
34
34
  '.aioson/agents/orache.md',
35
35
  '.aioson/agents/genome.md',
36
+ '.aioson/agents/design-hybrid-forge.md',
36
37
  '.aioson/agents/profiler-researcher.md',
37
38
  '.aioson/agents/profiler-enricher.md',
38
39
  '.aioson/agents/profiler-forge.md',
@@ -304,6 +305,14 @@ const AGENT_DEFINITIONS = [
304
305
  dependsOn: ['.aioson/context/discovery.md'],
305
306
  output: 'QA report'
306
307
  },
308
+ {
309
+ id: 'tester',
310
+ displayName: 'Tester',
311
+ command: '@tester',
312
+ path: '.aioson/agents/tester.md',
313
+ dependsOn: ['.aioson/context/project.context.md'],
314
+ output: '.aioson/context/test-inventory.md + .aioson/context/test-plan.md'
315
+ },
307
316
  {
308
317
  id: 'orchestrator',
309
318
  displayName: 'Orchestrator',
@@ -341,6 +350,14 @@ const AGENT_DEFINITIONS = [
341
350
  dependsOn: [],
342
351
  output: '.aioson/genomes/[slug].md + .aioson/genomes/[slug].meta.json + optional binding in .aioson/squads/{slug}/squad.md or .aioson/squads/{slug}/squad.manifest.json'
343
352
  },
353
+ {
354
+ id: 'design-hybrid-forge',
355
+ displayName: 'Design Hybrid Forge',
356
+ command: '@design-hybrid-forge',
357
+ path: '.aioson/agents/design-hybrid-forge.md',
358
+ dependsOn: ['.aioson/context/project.context.md'],
359
+ output: '.aioson/installed-skills/{hybrid-slug}/SKILL.md + .aioson/installed-skills/{hybrid-slug}/references/ + .aioson/installed-skills/{hybrid-slug}/previews/ + .aioson/installed-skills/{hybrid-slug}/.skill-meta.json'
360
+ },
344
361
  {
345
362
  id: 'profiler-researcher',
346
363
  displayName: 'Profiler Researcher',