@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,280 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const os = require('node:os');
6
+ const { IndexManager } = require('./context-search');
7
+
8
+ const SHARD_SEARCH_DIR = path.join(os.homedir(), '.aioson', 'shards');
9
+ const MAX_SHARD_TOKENS = 2000;
10
+ const DEFAULT_SHARDS = 3;
11
+
12
+ function estimateTokens(str) {
13
+ return Math.ceil(str.length / 4);
14
+ }
15
+
16
+ /**
17
+ * Split a markdown document into semantic shards by H2/H3 headings.
18
+ * Each shard = heading + its content until the next heading.
19
+ *
20
+ * @param {string} content — raw markdown
21
+ * @param {string} agentId — used to label shards
22
+ * @returns {Array<{id, heading, level, content, tokens}>}
23
+ */
24
+ function shardMarkdown(content, agentId) {
25
+ const lines = content.split('\n');
26
+ const shards = [];
27
+ let currentHeading = '(preamble)';
28
+ let currentLevel = 1;
29
+ let currentLines = [];
30
+ let shardIndex = 0;
31
+
32
+ function flushShard() {
33
+ const text = currentLines.join('\n').trim();
34
+ if (!text) return;
35
+ const tokens = estimateTokens(text);
36
+ shards.push({
37
+ id: `${agentId}:shard:${shardIndex}`,
38
+ heading: currentHeading,
39
+ level: currentLevel,
40
+ content: text,
41
+ tokens
42
+ });
43
+ shardIndex++;
44
+ }
45
+
46
+ for (const line of lines) {
47
+ const h2 = line.match(/^##\s+(.+)/);
48
+ const h3 = line.match(/^###\s+(.+)/);
49
+
50
+ if (h2 || h3) {
51
+ flushShard();
52
+ currentHeading = (h2 || h3)[1].trim();
53
+ currentLevel = h2 ? 2 : 3;
54
+ currentLines = [line];
55
+ } else {
56
+ currentLines.push(line);
57
+ }
58
+ }
59
+
60
+ flushShard();
61
+ return shards;
62
+ }
63
+
64
+ /**
65
+ * Agent shard loader — indexes agent instruction files as shards
66
+ * and loads only the relevant ones based on a goal query.
67
+ */
68
+ class AgentLoader {
69
+ constructor(opts = {}) {
70
+ this._searchDir = opts.searchDir || SHARD_SEARCH_DIR;
71
+ this._idx = null;
72
+ this._shardMap = new Map(); // id → shard content
73
+ }
74
+
75
+ async open() {
76
+ this._idx = new IndexManager(this._searchDir);
77
+ await this._idx.open();
78
+ return this;
79
+ }
80
+
81
+ close() {
82
+ if (this._idx) {
83
+ this._idx.close();
84
+ this._idx = null;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Index a single agent instruction file as shards.
90
+ * @param {string} filePath — absolute path to agent .md file
91
+ * @param {string} agentId
92
+ * @param {object} opts — { force? }
93
+ */
94
+ async indexAgentFile(filePath, agentId, opts = {}) {
95
+ const content = await fs.readFile(filePath, 'utf8');
96
+ const shards = shardMarkdown(content, agentId);
97
+
98
+ // Write individual shard files to a temp dir for FTS5 indexing
99
+ const shardDir = path.join(this._searchDir, 'agent-shards', agentId);
100
+ await fs.mkdir(shardDir, { recursive: true });
101
+
102
+ for (const shard of shards) {
103
+ const shardFile = path.join(shardDir, `${shard.id.replace(/:/g, '_')}.md`);
104
+ const shardContent = `# ${shard.heading}\n\n${shard.content}`;
105
+ await fs.writeFile(shardFile, shardContent, 'utf8');
106
+ // Keep content in memory for fast retrieval
107
+ this._shardMap.set(shard.id, shard);
108
+ }
109
+
110
+ // Index the shard dir
111
+ await this._idx.indexDirectory(shardDir, { force: opts.force !== false });
112
+
113
+ return { agentId, shards: shards.length };
114
+ }
115
+
116
+ /**
117
+ * Index an entire agents directory.
118
+ * @param {string} agentsDir — directory containing agent .md files
119
+ * @param {object} opts — { force? }
120
+ * @returns {{ agents: number, totalShards: number }}
121
+ */
122
+ async indexAgentsDir(agentsDir, opts = {}) {
123
+ let entries;
124
+ try {
125
+ entries = await fs.readdir(agentsDir, { withFileTypes: true });
126
+ } catch {
127
+ return { agents: 0, totalShards: 0 };
128
+ }
129
+
130
+ let agents = 0;
131
+ let totalShards = 0;
132
+
133
+ for (const entry of entries) {
134
+ if (!entry.isFile()) continue;
135
+ if (!entry.name.endsWith('.md')) continue;
136
+
137
+ const agentId = entry.name.replace(/\.md$/, '');
138
+ const filePath = path.join(agentsDir, entry.name);
139
+
140
+ try {
141
+ const result = await this.indexAgentFile(filePath, agentId, opts);
142
+ agents++;
143
+ totalShards += result.shards;
144
+ } catch {
145
+ // best-effort: skip unreadable files
146
+ }
147
+ }
148
+
149
+ return { agents, totalShards };
150
+ }
151
+
152
+ /**
153
+ * Load the most relevant shards for an agent given a goal query.
154
+ *
155
+ * Strategy:
156
+ * 1. Search FTS5 index for the goal query, filtered to agent shards
157
+ * 2. Always include H1/H2 "Role" and "preamble" shards
158
+ * 3. Fill remaining budget with ranked results
159
+ *
160
+ * @param {string} agentId
161
+ * @param {string} goal
162
+ * @param {object} opts — { maxShards?, maxTokens? }
163
+ * @returns {{ shards: Array, tokens: number, agentId: string }}
164
+ */
165
+ async loadRelevantShards(agentId, goal, opts = {}) {
166
+ const maxShards = opts.maxShards || DEFAULT_SHARDS;
167
+ const maxTokens = opts.maxTokens || MAX_SHARD_TOKENS;
168
+
169
+ // If shards aren't in memory (e.g., loaded from a previous session), load from disk
170
+ if (this._shardMap.size === 0) {
171
+ await this._loadShardsFromDisk(agentId);
172
+ }
173
+
174
+ const agentShards = [...this._shardMap.values()].filter(s => s.id.startsWith(`${agentId}:`));
175
+
176
+ if (agentShards.length === 0) {
177
+ return { shards: [], tokens: 0, agentId };
178
+ }
179
+
180
+ // Always include preamble/role shards
181
+ const priority = agentShards.filter(s =>
182
+ s.heading === '(preamble)' ||
183
+ /^role$/i.test(s.heading) ||
184
+ /^your role$/i.test(s.heading)
185
+ );
186
+
187
+ let selected = [...priority];
188
+ let usedTokens = selected.reduce((sum, s) => sum + s.tokens, 0);
189
+
190
+ // Search for relevant shards
191
+ if (goal && goal.trim()) {
192
+ const searchResults = this._idx.search(`${agentId} ${goal}`, { limit: maxShards + 2 });
193
+
194
+ for (const result of searchResults) {
195
+ if (selected.length >= maxShards) break;
196
+
197
+ // Match result back to shard via heading
198
+ const matchedShard = agentShards.find(s =>
199
+ result.relPath.includes(s.id.replace(/:/g, '_')) ||
200
+ s.heading.toLowerCase().includes(result.title.toLowerCase())
201
+ );
202
+
203
+ if (!matchedShard) continue;
204
+ if (selected.some(s => s.id === matchedShard.id)) continue;
205
+
206
+ if (usedTokens + matchedShard.tokens <= maxTokens) {
207
+ selected.push(matchedShard);
208
+ usedTokens += matchedShard.tokens;
209
+ }
210
+ }
211
+ }
212
+
213
+ // Fill with remaining shards if budget allows
214
+ if (selected.length < maxShards) {
215
+ for (const shard of agentShards) {
216
+ if (selected.length >= maxShards) break;
217
+ if (selected.some(s => s.id === shard.id)) continue;
218
+ if (usedTokens + shard.tokens <= maxTokens) {
219
+ selected.push(shard);
220
+ usedTokens += shard.tokens;
221
+ }
222
+ }
223
+ }
224
+
225
+ return {
226
+ agentId,
227
+ shards: selected,
228
+ tokens: usedTokens,
229
+ totalShards: agentShards.length
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Load shards from disk (for cross-session use).
235
+ * @private
236
+ */
237
+ async _loadShardsFromDisk(agentId) {
238
+ const shardDir = path.join(this._searchDir, 'agent-shards', agentId);
239
+ let files;
240
+ try {
241
+ files = await fs.readdir(shardDir);
242
+ } catch {
243
+ return;
244
+ }
245
+
246
+ for (const file of files) {
247
+ if (!file.endsWith('.md')) continue;
248
+ const filePath = path.join(shardDir, file);
249
+ try {
250
+ const content = await fs.readFile(filePath, 'utf8');
251
+ // Reconstruct shard id from filename
252
+ const id = file.replace(/\.md$/, '').replace(/_/g, ':');
253
+ const headingMatch = content.match(/^#\s+(.+)$/m);
254
+ const heading = headingMatch ? headingMatch[1] : '(unknown)';
255
+ const tokens = estimateTokens(content);
256
+ this._shardMap.set(id, { id, heading, level: 2, content, tokens });
257
+ } catch {
258
+ // skip
259
+ }
260
+ }
261
+ }
262
+
263
+ /**
264
+ * Build a merged context string from selected shards.
265
+ * @param {Array} shards
266
+ * @returns {string}
267
+ */
268
+ static buildContext(shards) {
269
+ return shards.map(s => s.content).join('\n\n---\n\n');
270
+ }
271
+
272
+ /**
273
+ * Return index statistics for all agent shards.
274
+ */
275
+ stats() {
276
+ return this._idx.stats();
277
+ }
278
+ }
279
+
280
+ module.exports = { AgentLoader, shardMarkdown };
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const os = require('node:os');
6
+ const { ensureDir, nowStamp } = require('./utils');
7
+
8
+ const DOC_CREATING_AGENTS = new Set([
9
+ 'product', 'analyst', 'architect', 'ux-ui', 'sheldon'
10
+ ]);
11
+
12
+ function isDocCreatingAgent(agentName) {
13
+ const normalized = agentName.toLowerCase().replace(/^@/, '');
14
+ return DOC_CREATING_AGENTS.has(normalized);
15
+ }
16
+
17
+ async function collectMdFiles(dir) {
18
+ const results = [];
19
+ let entries;
20
+ try {
21
+ entries = await fs.readdir(dir, { withFileTypes: true });
22
+ } catch {
23
+ return results;
24
+ }
25
+ for (const entry of entries) {
26
+ const full = path.join(dir, entry.name);
27
+ if (entry.isDirectory()) {
28
+ results.push(...(await collectMdFiles(full)));
29
+ } else if (entry.isFile() && entry.name.endsWith('.md')) {
30
+ results.push(full);
31
+ }
32
+ }
33
+ return results;
34
+ }
35
+
36
+ /**
37
+ * Backs up all .md files from .aioson/context/ and .aioson/plans/ to
38
+ * ~/.aioson/backups/{project-name}/{timestamp}/
39
+ *
40
+ * @param {string} targetDir - Project root directory
41
+ * @returns {{ ok: boolean, count: number, backupPath: string|null }}
42
+ */
43
+ async function backupAiosonDocs(targetDir) {
44
+ const contextDir = path.join(targetDir, '.aioson', 'context');
45
+ const plansDir = path.join(targetDir, '.aioson', 'plans');
46
+
47
+ const files = [
48
+ ...(await collectMdFiles(contextDir)),
49
+ ...(await collectMdFiles(plansDir))
50
+ ];
51
+
52
+ if (files.length === 0) return { ok: true, count: 0, backupPath: null };
53
+
54
+ const projectName = path.basename(path.resolve(targetDir));
55
+ // nowStamp() returns ISO with colons replaced: 2026-01-01T00-00-00.000Z
56
+ // Take just the date+time part: YYYY-MM-DDTHH-MM-SS
57
+ const stamp = nowStamp().slice(0, 19);
58
+ const backupRoot = path.join(os.homedir(), '.aioson', 'backups', projectName, stamp);
59
+
60
+ await ensureDir(backupRoot);
61
+
62
+ const aiosonRoot = path.join(targetDir, '.aioson');
63
+
64
+ for (const file of files) {
65
+ const rel = path.relative(aiosonRoot, file); // e.g. "context/prd.md"
66
+ const dest = path.join(backupRoot, rel);
67
+ await ensureDir(path.dirname(dest));
68
+ await fs.copyFile(file, dest);
69
+ }
70
+
71
+ return { ok: true, count: files.length, backupPath: backupRoot };
72
+ }
73
+
74
+ module.exports = { backupAiosonDocs, isDocCreatingAgent };