@jaimevalasek/aioson 1.3.0 → 1.5.1

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 (330) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/LICENSE +661 -21
  3. package/README.md +22 -3
  4. package/docs/en/squad-dashboard.md +372 -0
  5. package/docs/openclaw-bridge.md +308 -0
  6. package/docs/pt/README.md +62 -2
  7. package/docs/pt/advisor-spec.md +5 -5
  8. package/docs/pt/agentes-customizados.md +670 -0
  9. package/docs/pt/agentes.md +235 -23
  10. package/docs/pt/automacao-squads.md +407 -0
  11. package/docs/pt/cenarios.md +49 -5
  12. package/docs/pt/clientes-ai.md +62 -0
  13. package/docs/pt/comandos-cli.md +226 -17
  14. package/docs/pt/deyvin.md +115 -0
  15. package/docs/pt/genome-3.0-spec.md +11 -11
  16. package/docs/pt/inicio-rapido.md +63 -2
  17. package/docs/pt/memoria-contexto.md +255 -0
  18. package/docs/pt/output-strategy-delivery.md +655 -0
  19. package/docs/pt/profiler-system.md +17 -17
  20. package/docs/pt/runtime-observability.md +5 -1
  21. package/docs/pt/skills.md +175 -0
  22. package/docs/pt/squad-dashboard.md +373 -0
  23. package/docs/pt/{squad-genoma.md → squad-genome.md} +81 -75
  24. package/docs/testing/genome-2.0-matrix.md +5 -5
  25. package/docs/testing/genome-2.0-rollout.md +10 -10
  26. package/package.json +4 -4
  27. package/src/agents.js +21 -5
  28. package/src/backup-local.js +74 -0
  29. package/src/backup-provider.js +303 -0
  30. package/src/cli.js +276 -2
  31. package/src/commands/agents.js +22 -4
  32. package/src/commands/backup-local-cmd.js +25 -0
  33. package/src/commands/backup.js +533 -0
  34. package/src/commands/cloud.js +17 -17
  35. package/src/commands/context-pack.js +45 -0
  36. package/src/commands/implementation-plan.js +340 -0
  37. package/src/commands/learning.js +134 -0
  38. package/src/commands/live.js +1583 -0
  39. package/src/commands/runtime.js +1075 -2
  40. package/src/commands/scan-project.js +288 -24
  41. package/src/commands/setup-context.js +30 -2
  42. package/src/commands/skill.js +558 -0
  43. package/src/commands/squad-agent-create.js +788 -0
  44. package/src/commands/squad-daemon.js +209 -0
  45. package/src/commands/squad-dashboard.js +39 -0
  46. package/src/commands/squad-deploy.js +64 -0
  47. package/src/commands/squad-doctor.js +103 -1
  48. package/src/commands/squad-investigate.js +261 -0
  49. package/src/commands/squad-learning.js +209 -0
  50. package/src/commands/squad-mcp.js +270 -0
  51. package/src/commands/squad-pipeline.js +247 -1
  52. package/src/commands/squad-plan.js +329 -0
  53. package/src/commands/squad-processes.js +56 -0
  54. package/src/commands/squad-recovery.js +42 -0
  55. package/src/commands/squad-roi.js +291 -0
  56. package/src/commands/squad-score.js +250 -0
  57. package/src/commands/squad-status.js +38 -2
  58. package/src/commands/squad-validate.js +118 -1
  59. package/src/commands/squad-webhook.js +160 -0
  60. package/src/commands/squad-worker.js +191 -0
  61. package/src/commands/squad-worktrees.js +75 -0
  62. package/src/commands/test-agents.js +6 -1
  63. package/src/commands/web-map.js +70 -0
  64. package/src/commands/web-scrape.js +71 -0
  65. package/src/commands/workflow-next.js +8 -1
  66. package/src/commands/workflow-status.js +250 -0
  67. package/src/constants.js +88 -16
  68. package/src/context-memory.js +837 -0
  69. package/src/context-writer.js +47 -1
  70. package/src/delivery-runner.js +319 -0
  71. package/src/genome-files.js +1 -1
  72. package/src/genome-format.js +1 -1
  73. package/src/i18n/messages/en.js +333 -8
  74. package/src/i18n/messages/es.js +240 -6
  75. package/src/i18n/messages/fr.js +239 -5
  76. package/src/i18n/messages/pt-BR.js +330 -12
  77. package/src/installer.js +30 -2
  78. package/src/lib/genomes/compat.js +1 -1
  79. package/src/lib/webhook-server.js +328 -0
  80. package/src/mcp-connectors/registry.js +602 -0
  81. package/src/runtime-store.js +1037 -42
  82. package/src/session-handoff.js +77 -0
  83. package/src/squad/external-session.js +180 -0
  84. package/src/squad/inter-squad.js +74 -0
  85. package/src/squad/recovery-context.js +201 -0
  86. package/src/squad/worktree-manager.js +114 -0
  87. package/src/squad-daemon.js +490 -0
  88. package/src/squad-dashboard/api.js +223 -0
  89. package/src/squad-dashboard/attachment-handler.js +93 -0
  90. package/src/squad-dashboard/context-monitor.js +157 -0
  91. package/src/squad-dashboard/execution-logs.js +115 -0
  92. package/src/squad-dashboard/hunk-review.js +209 -0
  93. package/src/squad-dashboard/metrics.js +133 -0
  94. package/src/squad-dashboard/process-monitor.js +125 -0
  95. package/src/squad-dashboard/renderer.js +858 -0
  96. package/src/squad-dashboard/server.js +232 -0
  97. package/src/squad-dashboard/styles.js +525 -0
  98. package/src/squad-dashboard/token-tracker.js +99 -0
  99. package/src/web.js +284 -0
  100. package/src/worker-runner.js +339 -0
  101. package/template/.aioson/agents/analyst.md +40 -9
  102. package/template/.aioson/agents/architect.md +24 -5
  103. package/template/.aioson/agents/dev.md +254 -25
  104. package/template/.aioson/agents/deyvin.md +174 -0
  105. package/template/.aioson/agents/discovery-design-doc.md +25 -1
  106. package/template/.aioson/agents/{genoma.md → genome.md} +20 -20
  107. package/template/.aioson/agents/neo.md +152 -0
  108. package/template/.aioson/agents/orache.md +388 -0
  109. package/template/.aioson/agents/orchestrator.md +63 -2
  110. package/template/.aioson/agents/pair.md +5 -0
  111. package/template/.aioson/agents/pm.md +17 -5
  112. package/template/.aioson/agents/product.md +113 -29
  113. package/template/.aioson/agents/profiler-enricher.md +1 -1
  114. package/template/.aioson/agents/profiler-forge.md +9 -9
  115. package/template/.aioson/agents/profiler-researcher.md +1 -1
  116. package/template/.aioson/agents/qa.md +18 -5
  117. package/template/.aioson/agents/setup.md +138 -18
  118. package/template/.aioson/agents/sheldon.md +603 -0
  119. package/template/.aioson/agents/squad.md +866 -28
  120. package/template/.aioson/agents/tester.md +254 -0
  121. package/template/.aioson/agents/ux-ui.md +289 -34
  122. package/template/.aioson/config.md +181 -0
  123. package/template/.aioson/context/spec.md.template +17 -0
  124. package/template/.aioson/genomes/.gitkeep +0 -0
  125. package/template/.aioson/installed-skills/.gitkeep +0 -0
  126. package/template/.aioson/locales/en/agents/analyst.md +34 -4
  127. package/template/.aioson/locales/en/agents/architect.md +18 -0
  128. package/template/.aioson/locales/en/agents/dev.md +155 -11
  129. package/template/.aioson/locales/en/agents/deyvin.md +137 -0
  130. package/template/.aioson/locales/en/agents/{genoma.md → genome.md} +14 -14
  131. package/template/.aioson/locales/en/agents/neo.md +8 -0
  132. package/template/.aioson/locales/en/agents/orchestrator.md +62 -2
  133. package/template/.aioson/locales/en/agents/pair.md +5 -0
  134. package/template/.aioson/locales/en/agents/pm.md +7 -0
  135. package/template/.aioson/locales/en/agents/product.md +35 -17
  136. package/template/.aioson/locales/en/agents/qa.md +56 -0
  137. package/template/.aioson/locales/en/agents/setup.md +53 -6
  138. package/template/.aioson/locales/en/agents/sheldon.md +340 -0
  139. package/template/.aioson/locales/en/agents/squad.md +203 -15
  140. package/template/.aioson/locales/en/agents/ux-ui.md +383 -35
  141. package/template/.aioson/locales/es/agents/analyst.md +24 -4
  142. package/template/.aioson/locales/es/agents/architect.md +18 -0
  143. package/template/.aioson/locales/es/agents/dev.md +136 -9
  144. package/template/.aioson/locales/es/agents/deyvin.md +97 -0
  145. package/template/.aioson/locales/es/agents/{genoma.md → genome.md} +13 -13
  146. package/template/.aioson/locales/es/agents/neo.md +48 -0
  147. package/template/.aioson/locales/es/agents/orache.md +103 -0
  148. package/template/.aioson/locales/es/agents/orchestrator.md +62 -2
  149. package/template/.aioson/locales/es/agents/pair.md +5 -0
  150. package/template/.aioson/locales/es/agents/pm.md +7 -0
  151. package/template/.aioson/locales/es/agents/product.md +13 -3
  152. package/template/.aioson/locales/es/agents/qa.md +33 -0
  153. package/template/.aioson/locales/es/agents/setup.md +30 -6
  154. package/template/.aioson/locales/es/agents/sheldon.md +192 -0
  155. package/template/.aioson/locales/es/agents/squad.md +284 -15
  156. package/template/.aioson/locales/es/agents/ux-ui.md +34 -25
  157. package/template/.aioson/locales/fr/agents/analyst.md +24 -4
  158. package/template/.aioson/locales/fr/agents/architect.md +18 -0
  159. package/template/.aioson/locales/fr/agents/dev.md +136 -9
  160. package/template/.aioson/locales/fr/agents/deyvin.md +97 -0
  161. package/template/.aioson/locales/fr/agents/{genoma.md → genome.md} +7 -7
  162. package/template/.aioson/locales/fr/agents/neo.md +48 -0
  163. package/template/.aioson/locales/fr/agents/orache.md +104 -0
  164. package/template/.aioson/locales/fr/agents/orchestrator.md +62 -2
  165. package/template/.aioson/locales/fr/agents/pair.md +5 -0
  166. package/template/.aioson/locales/fr/agents/pm.md +7 -0
  167. package/template/.aioson/locales/fr/agents/product.md +13 -3
  168. package/template/.aioson/locales/fr/agents/qa.md +33 -0
  169. package/template/.aioson/locales/fr/agents/setup.md +30 -6
  170. package/template/.aioson/locales/fr/agents/sheldon.md +192 -0
  171. package/template/.aioson/locales/fr/agents/squad.md +279 -10
  172. package/template/.aioson/locales/fr/agents/ux-ui.md +34 -25
  173. package/template/.aioson/locales/pt-BR/agents/analyst.md +45 -4
  174. package/template/.aioson/locales/pt-BR/agents/architect.md +29 -0
  175. package/template/.aioson/locales/pt-BR/agents/dev.md +167 -15
  176. package/template/.aioson/locales/pt-BR/agents/deyvin.md +137 -0
  177. package/template/.aioson/locales/pt-BR/agents/{genoma.md → genome.md} +49 -49
  178. package/template/.aioson/locales/pt-BR/agents/neo.md +147 -0
  179. package/template/.aioson/locales/pt-BR/agents/orache.md +137 -0
  180. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +62 -2
  181. package/template/.aioson/locales/pt-BR/agents/pair.md +5 -0
  182. package/template/.aioson/locales/pt-BR/agents/pm.md +7 -0
  183. package/template/.aioson/locales/pt-BR/agents/product.md +43 -20
  184. package/template/.aioson/locales/pt-BR/agents/qa.md +67 -0
  185. package/template/.aioson/locales/pt-BR/agents/setup.md +53 -6
  186. package/template/.aioson/locales/pt-BR/agents/sheldon.md +192 -0
  187. package/template/.aioson/locales/pt-BR/agents/squad.md +591 -47
  188. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +369 -22
  189. package/template/.aioson/my-agents/.gitkeep +0 -0
  190. package/template/.aioson/rules/.gitkeep +0 -0
  191. package/template/.aioson/rules/squad/.gitkeep +0 -0
  192. package/template/.aioson/rules/squad/README.md +50 -0
  193. package/template/.aioson/schemas/genome-meta.schema.json +1 -1
  194. package/template/.aioson/schemas/genome.schema.json +1 -1
  195. package/template/.aioson/schemas/squad-blueprint.schema.json +32 -0
  196. package/template/.aioson/schemas/squad-manifest.schema.json +434 -1
  197. package/template/.aioson/skills/design/bold-editorial-ui/SKILL.md +205 -0
  198. package/template/.aioson/skills/design/bold-editorial-ui/references/art-direction.md +338 -0
  199. package/template/.aioson/skills/design/bold-editorial-ui/references/components.md +977 -0
  200. package/template/.aioson/skills/design/bold-editorial-ui/references/dashboards.md +218 -0
  201. package/template/.aioson/skills/design/bold-editorial-ui/references/design-tokens.md +326 -0
  202. package/template/.aioson/skills/design/bold-editorial-ui/references/motion.md +461 -0
  203. package/template/.aioson/skills/design/bold-editorial-ui/references/patterns.md +293 -0
  204. package/template/.aioson/skills/design/bold-editorial-ui/references/websites.md +352 -0
  205. package/template/.aioson/skills/design/clean-saas-ui/SKILL.md +210 -0
  206. package/template/.aioson/skills/design/clean-saas-ui/references/art-direction.md +319 -0
  207. package/template/.aioson/skills/design/clean-saas-ui/references/components.md +365 -0
  208. package/template/.aioson/skills/design/clean-saas-ui/references/dashboards.md +196 -0
  209. package/template/.aioson/skills/design/clean-saas-ui/references/design-tokens.md +244 -0
  210. package/template/.aioson/skills/design/clean-saas-ui/references/motion.md +235 -0
  211. package/template/.aioson/skills/design/clean-saas-ui/references/patterns.md +215 -0
  212. package/template/.aioson/skills/design/clean-saas-ui/references/websites.md +295 -0
  213. package/template/.aioson/skills/design/cognitive-core-ui/SKILL.md +203 -0
  214. package/template/.aioson/skills/design/cognitive-core-ui/references/art-direction.md +339 -0
  215. package/template/.aioson/skills/design/cognitive-core-ui/references/components.md +407 -0
  216. package/template/.aioson/skills/design/cognitive-core-ui/references/dashboards.md +272 -0
  217. package/template/.aioson/skills/design/cognitive-core-ui/references/design-tokens.md +524 -0
  218. package/template/.aioson/skills/design/cognitive-core-ui/references/motion.md +277 -0
  219. package/template/.aioson/skills/design/cognitive-core-ui/references/patterns.md +289 -0
  220. package/template/.aioson/skills/design/cognitive-core-ui/references/websites.md +437 -0
  221. package/template/.aioson/skills/design/interface-design/SKILL.md +47 -0
  222. package/template/.aioson/skills/design/interface-design/references/components-and-states.md +105 -0
  223. package/template/.aioson/skills/design/interface-design/references/design-directions.md +101 -0
  224. package/template/.aioson/skills/design/interface-design/references/handoff-and-quality.md +71 -0
  225. package/template/.aioson/skills/design/interface-design/references/intent-and-domain.md +74 -0
  226. package/template/.aioson/skills/design/interface-design/references/tokens-and-depth.md +173 -0
  227. package/template/.aioson/skills/design/premium-command-center-ui/SKILL.md +62 -0
  228. package/template/.aioson/skills/design/premium-command-center-ui/references/operations.md +74 -0
  229. package/template/.aioson/skills/design/premium-command-center-ui/references/patterns.md +116 -0
  230. package/template/.aioson/skills/design/premium-command-center-ui/references/validation.md +47 -0
  231. package/template/.aioson/skills/design/premium-command-center-ui/references/visual-system.md +215 -0
  232. package/template/.aioson/skills/design/warm-craft-ui/SKILL.md +209 -0
  233. package/template/.aioson/skills/design/warm-craft-ui/references/art-direction.md +324 -0
  234. package/template/.aioson/skills/design/warm-craft-ui/references/components.md +508 -0
  235. package/template/.aioson/skills/design/warm-craft-ui/references/dashboards.md +223 -0
  236. package/template/.aioson/skills/design/warm-craft-ui/references/design-tokens.md +374 -0
  237. package/template/.aioson/skills/design/warm-craft-ui/references/motion.md +356 -0
  238. package/template/.aioson/skills/design/warm-craft-ui/references/patterns.md +288 -0
  239. package/template/.aioson/skills/design/warm-craft-ui/references/websites.md +289 -0
  240. package/template/.aioson/skills/design-system/SKILL.md +92 -0
  241. package/template/.aioson/skills/design-system/cognitive-core-ui.skill +0 -0
  242. package/template/.aioson/skills/design-system/components/SKILL.md +274 -0
  243. package/template/.aioson/skills/design-system/components/SKILL.md:Zone.Identifier +0 -0
  244. package/template/.aioson/skills/design-system/dashboards/SKILL.md +184 -0
  245. package/template/.aioson/skills/design-system/dashboards/SKILL.md:Zone.Identifier +0 -0
  246. package/template/.aioson/skills/design-system/foundations/SKILL.md +250 -0
  247. package/template/.aioson/skills/design-system/foundations/SKILL.md:Zone.Identifier +0 -0
  248. package/template/.aioson/skills/design-system/motion/SKILL.md +197 -0
  249. package/template/.aioson/skills/design-system/motion/SKILL.md:Zone.Identifier +0 -0
  250. package/template/.aioson/skills/design-system/patterns/SKILL.md +231 -0
  251. package/template/.aioson/skills/design-system/patterns/SKILL.md:Zone.Identifier +0 -0
  252. package/template/.aioson/skills/premium-visual-design/SKILL.md +83 -0
  253. package/template/.aioson/skills/premium-visual-design/components/agent-badge.md +92 -0
  254. package/template/.aioson/skills/premium-visual-design/components/dependency-node.md +102 -0
  255. package/template/.aioson/skills/premium-visual-design/components/mention-autocomplete.md +136 -0
  256. package/template/.aioson/skills/premium-visual-design/components/notification-center.md +136 -0
  257. package/template/.aioson/skills/premium-visual-design/components/review-action-bar.md +188 -0
  258. package/template/.aioson/skills/premium-visual-design/components/team-switcher.md +131 -0
  259. package/template/.aioson/skills/premium-visual-design/patterns/agent-message-thread.md +198 -0
  260. package/template/.aioson/skills/premium-visual-design/patterns/notification-panel.md +275 -0
  261. package/template/.aioson/skills/premium-visual-design/patterns/review-workflow-ui.md +234 -0
  262. package/template/.aioson/skills/premium-visual-design/patterns/task-dependency-graph.md +147 -0
  263. package/template/.aioson/skills/premium-visual-design/tokens/status-extended.md +142 -0
  264. package/template/.aioson/skills/squad/SKILL.md +58 -0
  265. package/template/.aioson/skills/squad/domains/.gitkeep +0 -0
  266. package/template/.aioson/skills/squad/formats/.gitkeep +0 -0
  267. package/template/.aioson/skills/squad/formats/catalog.json +15 -0
  268. package/template/.aioson/skills/squad/formats/content/blog-post.md +47 -0
  269. package/template/.aioson/skills/squad/formats/content/newsletter.md +47 -0
  270. package/template/.aioson/skills/squad/formats/creative/podcast-script.md +43 -0
  271. package/template/.aioson/skills/squad/formats/creative/video-script.md +41 -0
  272. package/template/.aioson/skills/squad/formats/social/instagram-feed.md +42 -0
  273. package/template/.aioson/skills/squad/formats/social/linkedin-post.md +42 -0
  274. package/template/.aioson/skills/squad/formats/social/tiktok.md +39 -0
  275. package/template/.aioson/skills/squad/formats/social/twitter-thread.md +39 -0
  276. package/template/.aioson/skills/squad/formats/social/youtube-long.md +47 -0
  277. package/template/.aioson/skills/squad/formats/social/youtube-shorts.md +39 -0
  278. package/template/.aioson/skills/squad/patterns/.gitkeep +0 -0
  279. package/template/.aioson/skills/squad/patterns/multi-platform-pattern.md +108 -0
  280. package/template/.aioson/skills/squad/patterns/persona-based-pattern.md +98 -0
  281. package/template/.aioson/skills/squad/patterns/pipeline-pattern.md +106 -0
  282. package/template/.aioson/skills/squad/patterns/review-loop-pattern.md +81 -0
  283. package/template/.aioson/skills/squad/references/.gitkeep +0 -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 +307 -0
  290. package/template/.aioson/tasks/squad-create.md +1 -1
  291. package/template/.aioson/tasks/squad-design.md +28 -0
  292. package/template/.aioson/tasks/squad-execution-plan.md +279 -0
  293. package/template/.aioson/tasks/squad-export.md +1 -1
  294. package/template/.aioson/tasks/squad-investigate.md +44 -0
  295. package/template/.aioson/tasks/squad-learning-review.md +44 -0
  296. package/template/.aioson/tasks/squad-output-config.md +177 -0
  297. package/template/.aioson/tasks/squad-profile.md +48 -0
  298. package/template/.aioson/tasks/squad-review.md +61 -0
  299. package/template/.aioson/tasks/squad-task-decompose.md +66 -0
  300. package/template/.aioson/tasks/squad-validate.md +1 -1
  301. package/template/.claude/commands/aioson/agent/deyvin.md +5 -0
  302. package/template/.claude/commands/aioson/agent/discovery-design-doc.md +5 -0
  303. package/template/.claude/commands/aioson/agent/genome.md +5 -0
  304. package/template/.claude/commands/aioson/agent/neo.md +5 -0
  305. package/template/.claude/commands/aioson/agent/product.md +5 -0
  306. package/template/.claude/commands/aioson/agent/profiler-enricher.md +5 -0
  307. package/template/.claude/commands/aioson/agent/profiler-forge.md +5 -0
  308. package/template/.claude/commands/aioson/agent/profiler-researcher.md +5 -0
  309. package/template/.claude/commands/aioson/agent/squad.md +5 -0
  310. package/template/.claude/commands/aioson/agent/tester.md +5 -0
  311. package/template/.gemini/GEMINI.md +3 -0
  312. package/template/.gemini/commands/aios-deyvin.toml +6 -0
  313. package/template/.gemini/commands/aios-neo.toml +4 -0
  314. package/template/.gemini/commands/aios-pair.toml +6 -0
  315. package/template/.gemini/commands/aios-tester.toml +6 -0
  316. package/template/AGENTS.md +37 -6
  317. package/template/CLAUDE.md +34 -4
  318. package/template/OPENCODE.md +8 -2
  319. package/template/squad-searches/.gitkeep +0 -0
  320. package/template/.aioson/skills/static/interface-design.md +0 -372
  321. package/template/.aioson/skills/static/premium-command-center-ui.md +0 -190
  322. /package/template/.aioson/{genomas → docs}/.gitkeep +0 -0
  323. /package/template/.claude/commands/aioson/{analyst.md → agent/analyst.md} +0 -0
  324. /package/template/.claude/commands/aioson/{architect.md → agent/architect.md} +0 -0
  325. /package/template/.claude/commands/aioson/{dev.md → agent/dev.md} +0 -0
  326. /package/template/.claude/commands/aioson/{orchestrator.md → agent/orchestrator.md} +0 -0
  327. /package/template/.claude/commands/aioson/{pm.md → agent/pm.md} +0 -0
  328. /package/template/.claude/commands/aioson/{qa.md → agent/qa.md} +0 -0
  329. /package/template/.claude/commands/aioson/{setup.md → agent/setup.md} +0 -0
  330. /package/template/.claude/commands/aioson/{ux-ui.md → agent/ux-ui.md} +0 -0
@@ -15,7 +15,14 @@ const path = require('node:path');
15
15
  const fs = require('node:fs/promises');
16
16
  const https = require('node:https');
17
17
  const http = require('node:http');
18
- const { ensureDir, exists } = require('../utils');
18
+ const { ensureDir, exists, copyFileWithDir, nowStamp, toRelativeSafe } = require('../utils');
19
+ const { ensureGitignoreEntry, ensureProjectGitignorePolicy } = require('../installer');
20
+ const {
21
+ MEMORY_INDEX_FILE,
22
+ SPEC_CURRENT_FILE,
23
+ SPEC_HISTORY_FILE,
24
+ writeDerivedContextMemory
25
+ } = require('../context-memory');
19
26
 
20
27
  // ── Constants ────────────────────────────────────────────────────────────────
21
28
 
@@ -29,10 +36,11 @@ const CONTEXT_FILE = '.aioson/context/project.context.md';
29
36
  const SPEC_FILE = '.aioson/context/spec.md';
30
37
  const DELIMITER = '<<<SKELETON>>>';
31
38
  const SUMMARY_MODES = new Set(['titles', 'summaries', 'raw']);
39
+ const CONTEXT_MODES = new Set(['merge', 'rewrite']);
32
40
  const FORGE_SCAN_ROOTS = [
33
41
  '.aioson/context',
34
42
  '.aioson/squads',
35
- '.aioson/genomas',
43
+ '.aioson/genomes',
36
44
  '.aioson/mcp'
37
45
  ];
38
46
  const FORGE_SECTION_ROOTS = [
@@ -47,9 +55,9 @@ const FORGE_SECTION_ROOTS = [
47
55
  empty: '_No squads detected yet_'
48
56
  },
49
57
  {
50
- root: '.aioson/genomas',
51
- title: 'Genomas',
52
- empty: '_No genomas detected yet_'
58
+ root: '.aioson/genomes',
59
+ title: 'Genomes',
60
+ empty: '_No genomes detected yet_'
53
61
  },
54
62
  {
55
63
  root: '.aioson/mcp',
@@ -62,6 +70,7 @@ const FORGE_SKIP_GENERATED_FILES = new Set([
62
70
  '.aioson/context/spec.md.template',
63
71
  '.aioson/install.json'
64
72
  ]);
73
+ const BACKUPS_GITIGNORE_ENTRY = '.aioson/backups/';
65
74
 
66
75
  const SKIP_DIRS = new Set([
67
76
  '.git', 'node_modules', 'vendor', '.next', 'dist', 'build',
@@ -133,6 +142,30 @@ async function readFileSafe(filePath, maxChars) {
133
142
  }
134
143
  }
135
144
 
145
+ async function backupProjectFiles(targetDir, relPaths) {
146
+ const uniqueRelPaths = [...new Set(relPaths.filter(Boolean))];
147
+ if (uniqueRelPaths.length === 0) {
148
+ return { backupRoot: null, backedUp: [] };
149
+ }
150
+
151
+ const backupRoot = path.join(targetDir, '.aioson/backups', nowStamp());
152
+ const backedUp = [];
153
+
154
+ for (const relPath of uniqueRelPaths) {
155
+ const source = path.join(targetDir, relPath);
156
+ if (!(await exists(source))) continue;
157
+ const dest = path.join(backupRoot, relPath);
158
+ await copyFileWithDir(source, dest);
159
+ backedUp.push(toRelativeSafe(targetDir, dest));
160
+ }
161
+
162
+ if (backedUp.length === 0) {
163
+ return { backupRoot: null, backedUp: [] };
164
+ }
165
+
166
+ return { backupRoot, backedUp };
167
+ }
168
+
136
169
  async function loadGitignorePatterns(root) {
137
170
  const patterns = new Set();
138
171
  try {
@@ -291,11 +324,36 @@ function httpPost(url, headers, body) {
291
324
 
292
325
  async function callOpenAICompatible(baseUrl, apiKey, model, prompt) {
293
326
  const url = `${baseUrl.replace(/\/$/, '')}/chat/completions`;
294
- const text = await httpPost(
295
- url,
296
- { Authorization: `Bearer ${apiKey}` },
297
- { model, messages: [{ role: 'user', content: prompt }], max_tokens: 4096, temperature: 0.2 }
298
- );
327
+ const baseBody = {
328
+ model,
329
+ messages: [{ role: 'user', content: prompt }],
330
+ temperature: 0.2
331
+ };
332
+
333
+ let text;
334
+ try {
335
+ text = await httpPost(
336
+ url,
337
+ { Authorization: `Bearer ${apiKey}` },
338
+ { ...baseBody, max_tokens: 4096 }
339
+ );
340
+ } catch (error) {
341
+ const message = String(error && error.message || '');
342
+ const requiresMaxCompletionTokens =
343
+ message.includes("Unsupported parameter: 'max_tokens'") &&
344
+ message.includes('max_completion_tokens');
345
+
346
+ if (!requiresMaxCompletionTokens) {
347
+ throw error;
348
+ }
349
+
350
+ text = await httpPost(
351
+ url,
352
+ { Authorization: `Bearer ${apiKey}` },
353
+ { ...baseBody, max_completion_tokens: 4096 }
354
+ );
355
+ }
356
+
299
357
  const data = JSON.parse(text);
300
358
  return data.choices[0].message.content;
301
359
  }
@@ -336,6 +394,11 @@ function resolveSummaryMode(value) {
336
394
  return SUMMARY_MODES.has(normalized) ? normalized : 'summaries';
337
395
  }
338
396
 
397
+ function resolveContextMode(value) {
398
+ const normalized = String(value || '').trim().toLowerCase();
399
+ return CONTEXT_MODES.has(normalized) ? normalized : 'merge';
400
+ }
401
+
339
402
  function formatBytesCompact(sizeBytes) {
340
403
  const bytes = Number(sizeBytes || 0);
341
404
  const kb = bytes / 1024;
@@ -631,7 +694,7 @@ function buildForgeArtifactsMarkdown({ entries, generatedAt, managedForgePaths }
631
694
  '',
632
695
  '## Scope',
633
696
  '- Shows generated or project-specific artifacts inside `.aioson/`.',
634
- '- Groups what matters for client analysis, especially context pages, squads, genomas and local MCP artifacts.',
697
+ '- Groups what matters for client analysis, especially context pages, squads, genomes and local MCP artifacts.',
635
698
  '- Hides framework-managed defaults such as agents, locales, schemas, static skills and task docs.'
636
699
  ];
637
700
 
@@ -664,7 +727,11 @@ function buildScanIndexMarkdown({
664
727
  foldersPath,
665
728
  folderScans = [],
666
729
  forgePath,
667
- forgeArtifactCount = 0
730
+ forgeArtifactCount = 0,
731
+ memoryIndexPath = null,
732
+ specCurrentPath = null,
733
+ specHistoryPath = null,
734
+ moduleDocs = []
668
735
  }) {
669
736
  const lines = [
670
737
  '# Scan Index',
@@ -679,6 +746,18 @@ function buildScanIndexMarkdown({
679
746
  `| ${scan.relativePath} | Full folder and file map for requested folder \`${scan.folder}/\` |`
680
747
  ),
681
748
  `| ${FORGE_FILE} | Generated or project-specific artifacts inside .aioson/ |`,
749
+ ...(memoryIndexPath
750
+ ? [`| ${MEMORY_INDEX_FILE} | Read-this-first index of context docs and when to load them |`]
751
+ : []),
752
+ ...(specCurrentPath
753
+ ? [`| ${SPEC_CURRENT_FILE} | Current development snapshot derived from spec.md |`]
754
+ : []),
755
+ ...(specHistoryPath
756
+ ? [`| ${SPEC_HISTORY_FILE} | Historical implementation and decision view derived from spec.md |`]
757
+ : []),
758
+ ...moduleDocs.map((doc) =>
759
+ `| ${doc.relativePath} | Focused module memory for requested folder \`${doc.folder}/\` |`
760
+ ),
682
761
  '',
683
762
  `- Folder map: \`${foldersPath}\``,
684
763
  ...(
@@ -688,6 +767,10 @@ function buildScanIndexMarkdown({
688
767
  ),
689
768
  `- AIOSON generated map: \`${forgePath}\``,
690
769
  `- AIOSON generated entries: ${forgeArtifactCount}`,
770
+ ...(memoryIndexPath ? [`- Memory index: \`${memoryIndexPath}\``] : []),
771
+ ...(specCurrentPath ? [`- Spec current view: \`${specCurrentPath}\``] : []),
772
+ ...(specHistoryPath ? [`- Spec history view: \`${specHistoryPath}\``] : []),
773
+ ...moduleDocs.map((doc) => `- Module memory \`${doc.folder}/\`: \`${doc.absolutePath}\``),
691
774
  '',
692
775
  '## Top-level footprint',
693
776
  '| Path | Files | Approx size |',
@@ -726,6 +809,8 @@ function buildPrompt({
726
809
  keyContents,
727
810
  projectContext,
728
811
  specContent,
812
+ existingDiscoveryContent,
813
+ existingSkeletonContent,
729
814
  summaryMode
730
815
  }) {
731
816
  const now = new Date().toISOString().replace(/\.\d+Z$/, 'Z');
@@ -752,11 +837,25 @@ function buildPrompt({
752
837
  parts.push(`## Development Memory (spec.md)\n\`\`\`\n${specContent}\n\`\`\`\n`);
753
838
  }
754
839
 
840
+ if (existingDiscoveryContent) {
841
+ parts.push(`## Existing Discovery Memory (update in place)\n\`\`\`md\n${existingDiscoveryContent}\n\`\`\`\n`);
842
+ }
843
+
844
+ if (existingSkeletonContent) {
845
+ parts.push(`## Existing Skeleton Memory (update in place)\n\`\`\`md\n${existingSkeletonContent}\n\`\`\`\n`);
846
+ }
847
+
755
848
  parts.push(`
756
849
  ## Task
757
850
  Generate TWO documents. Separate them with exactly this delimiter on its own line:
758
851
  <<<SKELETON>>>
759
852
 
853
+ If existing discovery or skeleton documents were provided above, treat them as the current memory baseline and UPDATE them in place.
854
+ - Preserve stable system knowledge, conventions, and still-valid human notes.
855
+ - Remove or correct only what is clearly contradicted by the current scan, project.context.md, or spec.md.
856
+ - Do not throw away useful prior context just because the current scan sample is smaller.
857
+ - Keep the required output sections exactly as specified below.
858
+
760
859
  ### Document 1: \`.aioson/context/discovery.md\`
761
860
  Generate with exactly these sections:
762
861
 
@@ -844,8 +943,10 @@ function listTopLevelDirectories(entries) {
844
943
  // ── Main ─────────────────────────────────────────────────────────────────────
845
944
 
846
945
  async function runScanProject({ args, options = {}, logger, t }) {
847
- const targetDir = path.resolve(process.cwd(), args[0] || '.');
946
+ const targetArg = args[0] || '.';
947
+ const targetDir = path.resolve(process.cwd(), targetArg);
848
948
  const summaryMode = resolveSummaryMode(options['summary-mode']);
949
+ const contextMode = resolveContextMode(options['context-mode']);
849
950
  const requestedFolders = resolveRequestedFolders(options.folder);
850
951
  const llmRequested = Boolean(options['with-llm']);
851
952
  const llmModelOverride = String(options['llm-model'] || options.model || '').trim();
@@ -854,6 +955,13 @@ async function runScanProject({ args, options = {}, logger, t }) {
854
955
 
855
956
  if (requestedFolders.length === 0) {
856
957
  logger.error(t('scan_project.folder_required'));
958
+ logger.error(t('scan_project.folder_required_examples_title'));
959
+ logger.error(t('scan_project.folder_required_example_local'));
960
+ logger.error(t('scan_project.folder_required_example_multi'));
961
+ logger.error(t('scan_project.folder_required_example_llm'));
962
+ logger.error(t('scan_project.folder_required_example_cli'));
963
+ logger.error(t('scan_project.folder_required_example_prompt'));
964
+ logger.error(t('scan_project.folder_required_example_next'));
857
965
  process.exitCode = 1;
858
966
  return { ok: false, error: 'folder_required' };
859
967
  }
@@ -862,6 +970,14 @@ async function runScanProject({ args, options = {}, logger, t }) {
862
970
  let providerCfg = null;
863
971
  let model = null;
864
972
 
973
+ if (!options['dry-run']) {
974
+ const gitignoreRulesAdded = await ensureProjectGitignorePolicy(targetDir);
975
+ if (gitignoreRulesAdded > 0) {
976
+ logger.log(t('scan_project.gitignore_policy_written', { path: path.join(targetDir, '.gitignore') }));
977
+ logger.log(t('scan_project.gitignore_tracked_note'));
978
+ }
979
+ }
980
+
865
981
  if (!llmRequested) {
866
982
  logger.log(t('scan_project.local_only'));
867
983
  } else if (!options['dry-run']) {
@@ -900,10 +1016,18 @@ async function runScanProject({ args, options = {}, logger, t }) {
900
1016
  // Read context files
901
1017
  const projectContext = await readFileSafe(path.join(targetDir, CONTEXT_FILE));
902
1018
  const specContent = await readFileSafe(path.join(targetDir, SPEC_FILE));
1019
+ const existingDiscoveryPath = path.join(targetDir, OUTPUT_FILE);
1020
+ const existingSkeletonPath = path.join(targetDir, SKELETON_FILE);
1021
+ const existingDiscoveryContent = contextMode === 'merge' ? await readFileSafe(existingDiscoveryPath) : null;
1022
+ const existingSkeletonContent = contextMode === 'merge' ? await readFileSafe(existingSkeletonPath) : null;
903
1023
 
904
1024
  if (projectContext) logger.log(t('scan_project.context_found'));
905
1025
  else logger.log(t('scan_project.context_missing'));
906
1026
  if (specContent) logger.log(t('scan_project.spec_found'));
1027
+ if (llmRequested && existingDiscoveryContent) logger.log(t('scan_project.existing_discovery_found', { path: existingDiscoveryPath }));
1028
+ if (llmRequested && existingSkeletonContent) logger.log(t('scan_project.existing_skeleton_found', { path: existingSkeletonPath }));
1029
+ if (llmRequested && (existingDiscoveryContent || existingSkeletonContent)) logger.log(t('scan_project.context_update_mode'));
1030
+ if (llmRequested) logger.log(t('scan_project.context_mode', { mode: contextMode }));
907
1031
 
908
1032
  // Walk project
909
1033
  logger.log(t('scan_project.walking'));
@@ -953,34 +1077,37 @@ async function runScanProject({ args, options = {}, logger, t }) {
953
1077
  };
954
1078
  });
955
1079
 
1080
+ const scanIndexPath = path.join(targetDir, INDEX_FILE);
1081
+ const scanFoldersPath = path.join(targetDir, FOLDERS_FILE);
1082
+ const scanForgePath = path.join(targetDir, FORGE_FILE);
956
1083
  const scanIndexMarkdown = buildScanIndexMarkdown({
957
1084
  keyFiles,
958
1085
  topLevelStats,
959
1086
  generatedAt,
960
1087
  includeSummaries: summaryMode !== 'titles',
961
- foldersPath: path.join(targetDir, FOLDERS_FILE),
1088
+ foldersPath: scanFoldersPath,
962
1089
  folderScans,
963
- forgePath: path.join(targetDir, FORGE_FILE),
1090
+ forgePath: scanForgePath,
964
1091
  forgeArtifactCount: forgeArtifacts.artifactCount
965
1092
  });
966
-
967
- const scanIndexPath = path.join(targetDir, INDEX_FILE);
968
- const scanFoldersPath = path.join(targetDir, FOLDERS_FILE);
969
- const scanForgePath = path.join(targetDir, FORGE_FILE);
1093
+ let derivedArtifacts = {
1094
+ memoryIndexPath: null,
1095
+ specCurrentPath: null,
1096
+ specHistoryPath: null,
1097
+ moduleDocs: []
1098
+ };
970
1099
  if (!options['dry-run']) {
971
1100
  await ensureDir(path.dirname(scanIndexPath));
972
- await fs.writeFile(scanIndexPath, scanIndexMarkdown, 'utf8');
973
1101
  await fs.writeFile(scanFoldersPath, folderMapMarkdown, 'utf8');
974
1102
  for (const scan of folderScans) {
975
1103
  await fs.writeFile(scan.absolutePath, scan.markdown, 'utf8');
976
1104
  }
1105
+ await fs.writeFile(scanIndexPath, scanIndexMarkdown, 'utf8');
977
1106
  await fs.writeFile(scanForgePath, forgeArtifacts.markdown, 'utf8');
978
- logger.log(t('scan_project.index_written', { path: scanIndexPath, mode: summaryMode }));
979
1107
  logger.log(t('scan_project.folders_written', { path: scanFoldersPath }));
980
1108
  for (const scan of folderScans) {
981
1109
  logger.log(t('scan_project.folder_written', { folder: `${scan.folder}/`, path: scan.absolutePath }));
982
1110
  }
983
- logger.log(t('scan_project.forge_written', { path: scanForgePath }));
984
1111
  }
985
1112
 
986
1113
  if (options['dry-run']) {
@@ -993,6 +1120,7 @@ async function runScanProject({ args, options = {}, logger, t }) {
993
1120
  model,
994
1121
  llmRequested,
995
1122
  summaryMode,
1123
+ contextMode,
996
1124
  requestedFolders,
997
1125
  scanIndexPath,
998
1126
  scanFoldersPath,
@@ -1005,7 +1133,61 @@ async function runScanProject({ args, options = {}, logger, t }) {
1005
1133
  }
1006
1134
 
1007
1135
  if (!llmRequested) {
1136
+ derivedArtifacts = await writeDerivedContextMemory({
1137
+ targetDir,
1138
+ generatedAt,
1139
+ folderScans
1140
+ });
1141
+
1142
+ const refreshedWalk = await walkProject(targetDir);
1143
+ const refreshedForgeArtifacts = buildForgeArtifactsMarkdown({
1144
+ entries: refreshedWalk.entries,
1145
+ generatedAt,
1146
+ managedForgePaths
1147
+ });
1148
+ const refreshedScanIndexMarkdown = buildScanIndexMarkdown({
1149
+ keyFiles: refreshedWalk.keyFiles,
1150
+ topLevelStats: refreshedWalk.topLevelStats,
1151
+ generatedAt,
1152
+ includeSummaries: summaryMode !== 'titles',
1153
+ foldersPath: path.join(targetDir, FOLDERS_FILE),
1154
+ folderScans,
1155
+ forgePath: path.join(targetDir, FORGE_FILE),
1156
+ forgeArtifactCount: refreshedForgeArtifacts.artifactCount,
1157
+ memoryIndexPath: derivedArtifacts.memoryIndexPath,
1158
+ specCurrentPath: derivedArtifacts.specCurrentPath,
1159
+ specHistoryPath: derivedArtifacts.specHistoryPath,
1160
+ moduleDocs: derivedArtifacts.moduleDocs
1161
+ });
1162
+
1163
+ await fs.writeFile(scanIndexPath, refreshedScanIndexMarkdown, 'utf8');
1164
+ await fs.writeFile(scanForgePath, refreshedForgeArtifacts.markdown, 'utf8');
1165
+ logger.log(t('scan_project.index_written', { path: scanIndexPath, mode: summaryMode }));
1166
+ logger.log(t('scan_project.forge_written', { path: scanForgePath }));
1167
+ if (derivedArtifacts.memoryIndexPath) logger.log(t('scan_project.memory_index_written', { path: derivedArtifacts.memoryIndexPath }));
1168
+ if (derivedArtifacts.specCurrentPath) logger.log(t('scan_project.spec_current_written', { path: derivedArtifacts.specCurrentPath }));
1169
+ if (derivedArtifacts.specHistoryPath) logger.log(t('scan_project.spec_history_written', { path: derivedArtifacts.specHistoryPath }));
1170
+ for (const doc of derivedArtifacts.moduleDocs) {
1171
+ logger.log(t('scan_project.module_memory_written', { folder: `${doc.folder}/`, path: doc.absolutePath }));
1172
+ }
1173
+
1008
1174
  logger.log(t('scan_project.local_done', { path: scanIndexPath }));
1175
+ logger.log(t('scan_project.local_missing'));
1176
+ logger.log(t('scan_project.architecture_note'));
1177
+ logger.log(t('scan_project.local_paths_title'));
1178
+ logger.log(t('scan_project.local_path_api'));
1179
+ logger.log(t('scan_project.local_next_steps', {
1180
+ target: targetArg,
1181
+ folders: requestedFolders.join(',')
1182
+ }));
1183
+ logger.log(t('scan_project.local_path_cli'));
1184
+ logger.log(t('scan_project.local_cli_step_analyst'));
1185
+ logger.log(t('scan_project.local_cli_step_prompt_codex'));
1186
+ logger.log(t('scan_project.local_cli_step_prompt_claude'));
1187
+ logger.log(t('scan_project.local_cli_step_model_hint'));
1188
+ logger.log(t('scan_project.local_workflow_title'));
1189
+ logger.log(t('scan_project.local_step_architect'));
1190
+ logger.log(t('scan_project.local_step_dev'));
1009
1191
  return {
1010
1192
  ok: true,
1011
1193
  targetDir,
@@ -1013,11 +1195,16 @@ async function runScanProject({ args, options = {}, logger, t }) {
1013
1195
  model: null,
1014
1196
  llmRequested: false,
1015
1197
  summaryMode,
1198
+ contextMode,
1016
1199
  requestedFolders,
1017
1200
  scanIndexPath,
1018
1201
  scanFoldersPath,
1019
1202
  scanFolderPaths: folderScans.map((scan) => scan.absolutePath),
1020
1203
  scanForgePath,
1204
+ memoryIndexPath: derivedArtifacts.memoryIndexPath,
1205
+ specCurrentPath: derivedArtifacts.specCurrentPath,
1206
+ specHistoryPath: derivedArtifacts.specHistoryPath,
1207
+ moduleDocPaths: derivedArtifacts.moduleDocs.map((doc) => doc.absolutePath),
1021
1208
  discoveryPath: null,
1022
1209
  skeletonPath: null
1023
1210
  };
@@ -1032,6 +1219,8 @@ async function runScanProject({ args, options = {}, logger, t }) {
1032
1219
  keyContents,
1033
1220
  projectContext,
1034
1221
  specContent,
1222
+ existingDiscoveryContent,
1223
+ existingSkeletonContent,
1035
1224
  summaryMode
1036
1225
  });
1037
1226
  logger.log(t('scan_project.calling_llm', { provider: providerName, model }));
@@ -1050,8 +1239,8 @@ async function runScanProject({ args, options = {}, logger, t }) {
1050
1239
  }
1051
1240
 
1052
1241
  // Parse and write both documents
1053
- const outputPath = path.join(targetDir, OUTPUT_FILE);
1054
- const skeletonPath = path.join(targetDir, SKELETON_FILE);
1242
+ const outputPath = existingDiscoveryPath;
1243
+ const skeletonPath = existingSkeletonPath;
1055
1244
 
1056
1245
  await ensureDir(path.dirname(outputPath));
1057
1246
 
@@ -1065,6 +1254,37 @@ async function runScanProject({ args, options = {}, logger, t }) {
1065
1254
  skeletonContent = null;
1066
1255
  }
1067
1256
 
1257
+ if (!discoveryContent) {
1258
+ logger.error(t('scan_project.invalid_llm_output_discovery_empty'));
1259
+ process.exitCode = 1;
1260
+ return { ok: false, error: 'empty_discovery' };
1261
+ }
1262
+
1263
+ if (result.includes(DELIMITER) && !skeletonContent) {
1264
+ logger.error(t('scan_project.invalid_llm_output_skeleton_empty'));
1265
+ process.exitCode = 1;
1266
+ return { ok: false, error: 'empty_skeleton' };
1267
+ }
1268
+
1269
+ const contextFilesToBackup = [];
1270
+ if (await exists(existingDiscoveryPath)) contextFilesToBackup.push(OUTPUT_FILE);
1271
+ if (skeletonContent && await exists(existingSkeletonPath)) contextFilesToBackup.push(SKELETON_FILE);
1272
+
1273
+ if (contextFilesToBackup.length > 0) {
1274
+ const gitignoreChanged = await ensureGitignoreEntry(targetDir, BACKUPS_GITIGNORE_ENTRY);
1275
+ if (gitignoreChanged) {
1276
+ logger.log(t('scan_project.gitignore_backups_written', { path: path.join(targetDir, '.gitignore') }));
1277
+ }
1278
+
1279
+ const backupResult = await backupProjectFiles(targetDir, contextFilesToBackup);
1280
+ if (backupResult.backedUp.length > 0) {
1281
+ logger.log(t('scan_project.backups_written', {
1282
+ count: backupResult.backedUp.length,
1283
+ path: backupResult.backupRoot
1284
+ }));
1285
+ }
1286
+ }
1287
+
1068
1288
  await fs.writeFile(outputPath, discoveryContent, 'utf8');
1069
1289
  logger.log(t('scan_project.discovery_written', { path: outputPath, chars: discoveryContent.length }));
1070
1290
 
@@ -1075,8 +1295,46 @@ async function runScanProject({ args, options = {}, logger, t }) {
1075
1295
  logger.log(t('scan_project.skeleton_missing'));
1076
1296
  }
1077
1297
 
1298
+ derivedArtifacts = await writeDerivedContextMemory({
1299
+ targetDir,
1300
+ generatedAt,
1301
+ folderScans
1302
+ });
1303
+ const refreshedWalk = await walkProject(targetDir);
1304
+ const refreshedForgeArtifacts = buildForgeArtifactsMarkdown({
1305
+ entries: refreshedWalk.entries,
1306
+ generatedAt,
1307
+ managedForgePaths
1308
+ });
1309
+ const refreshedScanIndexMarkdown = buildScanIndexMarkdown({
1310
+ keyFiles: refreshedWalk.keyFiles,
1311
+ topLevelStats: refreshedWalk.topLevelStats,
1312
+ generatedAt,
1313
+ includeSummaries: summaryMode !== 'titles',
1314
+ foldersPath: path.join(targetDir, FOLDERS_FILE),
1315
+ folderScans,
1316
+ forgePath: path.join(targetDir, FORGE_FILE),
1317
+ forgeArtifactCount: refreshedForgeArtifacts.artifactCount,
1318
+ memoryIndexPath: derivedArtifacts.memoryIndexPath,
1319
+ specCurrentPath: derivedArtifacts.specCurrentPath,
1320
+ specHistoryPath: derivedArtifacts.specHistoryPath,
1321
+ moduleDocs: derivedArtifacts.moduleDocs
1322
+ });
1323
+ await fs.writeFile(scanIndexPath, refreshedScanIndexMarkdown, 'utf8');
1324
+ await fs.writeFile(scanForgePath, refreshedForgeArtifacts.markdown, 'utf8');
1325
+ logger.log(t('scan_project.index_written', { path: scanIndexPath, mode: summaryMode }));
1326
+ logger.log(t('scan_project.forge_written', { path: scanForgePath }));
1327
+ if (derivedArtifacts.memoryIndexPath) logger.log(t('scan_project.memory_index_written', { path: derivedArtifacts.memoryIndexPath }));
1328
+ if (derivedArtifacts.specCurrentPath) logger.log(t('scan_project.spec_current_written', { path: derivedArtifacts.specCurrentPath }));
1329
+ if (derivedArtifacts.specHistoryPath) logger.log(t('scan_project.spec_history_written', { path: derivedArtifacts.specHistoryPath }));
1330
+ for (const doc of derivedArtifacts.moduleDocs) {
1331
+ logger.log(t('scan_project.module_memory_written', { folder: `${doc.folder}/`, path: doc.absolutePath }));
1332
+ }
1333
+
1334
+ logger.log(t('scan_project.architecture_note'));
1078
1335
  logger.log(t('scan_project.next_steps'));
1079
1336
  logger.log(t('scan_project.step_analyst'));
1337
+ logger.log(t('scan_project.step_architect'));
1080
1338
  logger.log(t('scan_project.step_dev'));
1081
1339
 
1082
1340
  const output = {
@@ -1086,11 +1344,16 @@ async function runScanProject({ args, options = {}, logger, t }) {
1086
1344
  model,
1087
1345
  llmRequested: true,
1088
1346
  summaryMode,
1347
+ contextMode,
1089
1348
  requestedFolders,
1090
1349
  scanIndexPath,
1091
1350
  scanFoldersPath,
1092
1351
  scanFolderPaths: folderScans.map((scan) => scan.absolutePath),
1093
1352
  scanForgePath,
1353
+ memoryIndexPath: derivedArtifacts.memoryIndexPath,
1354
+ specCurrentPath: derivedArtifacts.specCurrentPath,
1355
+ specHistoryPath: derivedArtifacts.specHistoryPath,
1356
+ moduleDocPaths: derivedArtifacts.moduleDocs.map((doc) => doc.absolutePath),
1094
1357
  discoveryPath: outputPath,
1095
1358
  skeletonPath: skeletonContent ? skeletonPath : null
1096
1359
  };
@@ -1101,6 +1364,7 @@ async function runScanProject({ args, options = {}, logger, t }) {
1101
1364
  module.exports = {
1102
1365
  runScanProject,
1103
1366
  resolveSummaryMode,
1367
+ resolveContextMode,
1104
1368
  resolveRequestedFolders,
1105
1369
  buildScanIndexMarkdown,
1106
1370
  buildPrompt
@@ -8,9 +8,11 @@ const {
8
8
  calculateClassification,
9
9
  normalizeBoolean,
10
10
  renderProjectContext,
11
- writeProjectContext
11
+ writeProjectContext,
12
+ renderSquadApiSection
12
13
  } = require('../context-writer');
13
14
  const { applyAgentLocale } = require('../locales');
15
+ const { openRuntimeDb, logAgentEvent } = require('../runtime-store');
14
16
  const {
15
17
  BACKEND_CHOICES,
16
18
  FRONTEND_CHOICES,
@@ -206,6 +208,8 @@ function applyExplicitOverrides(data, options, detectedInstalled) {
206
208
  }
207
209
  const langValue = options.language ?? options.lang;
208
210
  if (langValue !== undefined) output.conversationLanguage = String(langValue);
211
+ if (hasOption(options, 'design-skill')) output.designSkill = String(options['design-skill']);
212
+ if (hasOption(options, 'test-runner')) output.testRunner = String(options['test-runner']);
209
213
  if (hasOption(options, 'web3-enabled')) {
210
214
  output.web3Enabled = normalizeBoolean(options['web3-enabled'], output.web3Enabled);
211
215
  }
@@ -466,6 +470,8 @@ async function runSetupContext({ args, options, logger, t }) {
466
470
  framework: detectedFramework,
467
471
  frameworkInstalled: detectedInstalled,
468
472
  conversationLanguage: 'en',
473
+ designSkill: '',
474
+ testRunner: '',
469
475
  web3Enabled: inferredWeb3Enabled,
470
476
  web3Networks: inferredWeb3Enabled ? inferWeb3Network(detectedFramework) : '',
471
477
  contractFramework: inferredWeb3Enabled ? detectedFramework : '',
@@ -613,7 +619,9 @@ async function runSetupContext({ args, options, logger, t }) {
613
619
  }
614
620
 
615
621
  const content = renderProjectContext(data);
616
- const filePath = await writeProjectContext(targetDir, content);
622
+ const squadApiSection = await renderSquadApiSection(targetDir);
623
+ const fullContent = squadApiSection ? content + '\n' + squadApiSection + '\n' : content;
624
+ const filePath = await writeProjectContext(targetDir, fullContent);
617
625
  const localeApplyResult = await applyAgentLocale(targetDir, data.conversationLanguage, {
618
626
  dryRun: false
619
627
  });
@@ -632,6 +640,26 @@ async function runSetupContext({ args, options, logger, t }) {
632
640
  })
633
641
  );
634
642
 
643
+ try {
644
+ const handle = await openRuntimeDb(targetDir);
645
+ const { db, runtimeDir } = handle;
646
+ try {
647
+ await logAgentEvent(db, runtimeDir, {
648
+ agentName: '@setup',
649
+ message: `Project context created: ${data.projectName} (${data.classification} / ${data.framework})`,
650
+ type: 'completed',
651
+ taskTitle: `@setup — ${data.projectName}`,
652
+ finish: true,
653
+ status: 'completed',
654
+ summary: `Setup: ${data.projectType} · ${data.framework} · ${data.classification}`
655
+ });
656
+ } finally {
657
+ db.close();
658
+ }
659
+ } catch {
660
+ // Runtime DB may not exist yet on first setup — not a fatal error
661
+ }
662
+
635
663
  return {
636
664
  ok: true,
637
665
  targetDir,