@hybridlabor-api/aos 4.6.6 → 4.7.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 (503) hide show
  1. package/.agents/agents.md +9 -3
  2. package/.agents/nodes.json +7 -2
  3. package/.agents/state.schema.json +26 -1
  4. package/.agents/vendor-manifest.json +56 -0
  5. package/.agents/workflows/startcycle-graph.md +2 -2
  6. package/.claude/agents/architect.md +7 -2
  7. package/.claude/agents/security-reviewer.md +1 -1
  8. package/.claude/agents/techlead.md +2 -0
  9. package/.claude/hooks/memb-inject.mjs +257 -135
  10. package/.claude/hooks/trail-relay.mjs +18 -0
  11. package/.claude/settings.json +70 -0
  12. package/.claude/workflows/startcycle-dispatch.mjs +203 -17
  13. package/.opencode/agents/architect.md +7 -2
  14. package/.opencode/agents/techlead.md +2 -0
  15. package/.opencode/plugins/bdb-aos.js +75 -0
  16. package/THIRD_PARTY_NOTICES.md +57 -1
  17. package/bin/aos-doctor.mjs +366 -0
  18. package/bin/aos-store.mjs +167 -0
  19. package/bin/aos-uninstall.mjs +55 -1
  20. package/docs/AUDIT_BRIEF_ECC_STORE.md +122 -0
  21. package/docs/PLAN_AOS_STORE_PHASE1.md +190 -0
  22. package/docs/handover/agenttrail-for-ao.md +58 -0
  23. package/docs/handover/deja-for-ao.md +51 -0
  24. package/installer.js +182 -38
  25. package/lib/aos-archify-contract.mjs +277 -0
  26. package/lib/ecc-store-index.json +1 -0
  27. package/mcp_config.json +8 -0
  28. package/mcps/mcsc/README.md +24 -0
  29. package/mcps/mcsc/package-lock.json +1234 -0
  30. package/mcps/mcsc/package.json +14 -0
  31. package/mcps/mcsc/packages/core/bin/mcsc.js +162 -0
  32. package/mcps/mcsc/packages/core/rulebook.default.yaml +49 -0
  33. package/mcps/mcsc/packages/core/schema/rulebook.schema.json +56 -0
  34. package/mcps/mcsc/packages/core/src/adapters/agy.js +107 -0
  35. package/mcps/mcsc/packages/core/src/adapters/codex.js +179 -0
  36. package/mcps/mcsc/packages/core/src/adapters/native.js +14 -0
  37. package/mcps/mcsc/packages/core/src/adapters/opencode.js +183 -0
  38. package/mcps/mcsc/packages/core/src/adapters/types.js +21 -0
  39. package/mcps/mcsc/packages/core/src/capabilities/buildOfferTable.js +34 -0
  40. package/mcps/mcsc/packages/core/src/capabilities/registry.js +99 -0
  41. package/mcps/mcsc/packages/core/src/capabilities/types.js +24 -0
  42. package/mcps/mcsc/packages/core/src/detect/cache.js +47 -0
  43. package/mcps/mcsc/packages/core/src/detect/inventory.js +73 -0
  44. package/mcps/mcsc/packages/core/src/detect/probes.js +158 -0
  45. package/mcps/mcsc/packages/core/src/detect/types.js +26 -0
  46. package/mcps/mcsc/packages/core/src/rulebook/load.js +53 -0
  47. package/mcps/mcsc/packages/core/src/rulebook/resolve.js +227 -0
  48. package/mcps/mcsc/packages/core/src/rulebook/rulebook.types.js +89 -0
  49. package/mcps/mcsc/packages/core/src/trail.js +17 -0
  50. package/mcps/mcsc/packages/mcp/server.js +302 -0
  51. package/mcps/mcsc/server.js +2 -0
  52. package/package.json +8 -2
  53. package/scripts/build-ecc-store-index.mjs +147 -0
  54. package/skills/basic/bdbmediastorm/SKILL.md +1 -1
  55. package/skills/basic/godmode-ui-ux/SKILL.md +2 -2
  56. package/skills/basic/godmode-ui-ux/references/anti-slop-rules.md +44 -40
  57. package/skills/basic/godmode-ui-ux/references/taste-archetypes.md +49 -0
  58. package/skills/basic/startcycle/SKILL.md +7 -0
  59. package/skills/basic/startcycle-graph/SKILL.md +25 -0
  60. package/skills/basic/startcycle-graph-user/SKILL.md +3 -0
  61. package/skills/basic/teamwork-preview/SKILL.md +2 -0
  62. package/skills/bdbrainstorm/SKILL.md +1 -0
  63. package/skills/global_config/agenttrail/LICENSE +21 -0
  64. package/skills/global_config/agenttrail/SKILL.md +48 -0
  65. package/skills/global_config/agenttrail/bin/agenttrail.mjs +1113 -0
  66. package/skills/global_config/agenttrail/public/index.html +662 -0
  67. package/skills/global_config/aos-project-init/SKILL.md +25 -5
  68. package/skills/global_config/aos-setup/SKILL.md +34 -1
  69. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +115 -1
  70. package/skills/global_config/archify/LICENSE +22 -0
  71. package/skills/global_config/archify/SKILL.md +140 -0
  72. package/skills/global_config/archify/THIRD_PARTY_NOTICES.md +69 -0
  73. package/skills/global_config/archify/assets/JetBrainsMono-OFL.txt +93 -0
  74. package/skills/global_config/archify/assets/template.html +14937 -0
  75. package/skills/global_config/archify/bin/archify.mjs +2139 -0
  76. package/skills/global_config/archify/bin/open-artifact.mjs +86 -0
  77. package/skills/global_config/archify/bin/preview.mjs +653 -0
  78. package/skills/global_config/archify/bin/visual-check.mjs +829 -0
  79. package/skills/global_config/archify/brand-marks/README.md +31 -0
  80. package/skills/global_config/archify/brand-marks/catalog.json +131 -0
  81. package/skills/global_config/archify/delta/architecture-delta.mjs +1232 -0
  82. package/skills/global_config/archify/examples/agent-run.lifecycle.json +60 -0
  83. package/skills/global_config/archify/examples/agent-tool-call.workflow.json +94 -0
  84. package/skills/global_config/archify/examples/async-job-roundtrip.sequence.json +61 -0
  85. package/skills/global_config/archify/examples/brand-aware-delivery.architecture.json +47 -0
  86. package/skills/global_config/archify/examples/cache-miss-request.sequence.json +82 -0
  87. package/skills/global_config/archify/examples/checkout-platform.base.architecture.json +31 -0
  88. package/skills/global_config/archify/examples/checkout-platform.head.architecture.json +31 -0
  89. package/skills/global_config/archify/examples/dataflow-product-analytics.html +15048 -0
  90. package/skills/global_config/archify/examples/deployment-release.lifecycle.json +49 -0
  91. package/skills/global_config/archify/examples/event-stream.dataflow.json +57 -0
  92. package/skills/global_config/archify/examples/incident-response.workflow.json +64 -0
  93. package/skills/global_config/archify/examples/lifecycle-agent-run.html +14983 -0
  94. package/skills/global_config/archify/examples/product-analytics.dataflow.json +76 -0
  95. package/skills/global_config/archify/examples/production-deployment.architecture.json +71 -0
  96. package/skills/global_config/archify/examples/release-delivery.workflow.json +62 -0
  97. package/skills/global_config/archify/examples/sequence-cache-miss-request.html +15063 -0
  98. package/skills/global_config/archify/examples/web-app-rendered.html +15012 -0
  99. package/skills/global_config/archify/examples/web-app.architecture.json +46 -0
  100. package/skills/global_config/archify/examples/workflow-agent-tool-call-rendered.html +15054 -0
  101. package/skills/global_config/archify/migrations/workflow-v2.mjs +279 -0
  102. package/skills/global_config/archify/package.json +39 -0
  103. package/skills/global_config/archify/recipes/scenarios.mjs +391 -0
  104. package/skills/global_config/archify/references/authoring-contract.md +247 -0
  105. package/skills/global_config/archify/references/brand-marks.md +65 -0
  106. package/skills/global_config/archify/references/delivery-contract.md +138 -0
  107. package/skills/global_config/archify/references/viewer-runtime.md +45 -0
  108. package/skills/global_config/archify/renderers/architecture/grid.mjs +62 -0
  109. package/skills/global_config/archify/renderers/architecture/render-architecture.mjs +1078 -0
  110. package/skills/global_config/archify/renderers/dataflow/README.md +104 -0
  111. package/skills/global_config/archify/renderers/dataflow/render-dataflow.mjs +483 -0
  112. package/skills/global_config/archify/renderers/lifecycle/README.md +115 -0
  113. package/skills/global_config/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
  114. package/skills/global_config/archify/renderers/sequence/README.md +114 -0
  115. package/skills/global_config/archify/renderers/sequence/render-sequence.mjs +464 -0
  116. package/skills/global_config/archify/renderers/shared/brand-marks.mjs +563 -0
  117. package/skills/global_config/archify/renderers/shared/cli.mjs +218 -0
  118. package/skills/global_config/archify/renderers/shared/desktop-readability.mjs +26 -0
  119. package/skills/global_config/archify/renderers/shared/diagnostics.mjs +160 -0
  120. package/skills/global_config/archify/renderers/shared/engineering-profiles.mjs +157 -0
  121. package/skills/global_config/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
  122. package/skills/global_config/archify/renderers/shared/generated-validators.mjs +13 -0
  123. package/skills/global_config/archify/renderers/shared/geometry.mjs +1423 -0
  124. package/skills/global_config/archify/renderers/shared/i18n.mjs +595 -0
  125. package/skills/global_config/archify/renderers/shared/layout-report.mjs +40 -0
  126. package/skills/global_config/archify/renderers/shared/legend.mjs +217 -0
  127. package/skills/global_config/archify/renderers/shared/output-path.mjs +340 -0
  128. package/skills/global_config/archify/renderers/shared/repository-evidence.mjs +239 -0
  129. package/skills/global_config/archify/renderers/shared/repository-location.mjs +58 -0
  130. package/skills/global_config/archify/renderers/shared/text-fit.mjs +49 -0
  131. package/skills/global_config/archify/renderers/shared/utils.mjs +232 -0
  132. package/skills/global_config/archify/renderers/shared/validator.mjs +86 -0
  133. package/skills/global_config/archify/renderers/workflow/README.md +223 -0
  134. package/skills/global_config/archify/renderers/workflow/render-workflow.mjs +35 -0
  135. package/skills/global_config/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
  136. package/skills/global_config/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
  137. package/skills/global_config/archify/schemas/README.md +211 -0
  138. package/skills/global_config/archify/schemas/architecture.schema.json +178 -0
  139. package/skills/global_config/archify/schemas/common.schema.json +115 -0
  140. package/skills/global_config/archify/schemas/dataflow.schema.json +243 -0
  141. package/skills/global_config/archify/schemas/lifecycle.schema.json +266 -0
  142. package/skills/global_config/archify/schemas/sequence.schema.json +223 -0
  143. package/skills/global_config/archify/schemas/workflow.schema.json +428 -0
  144. package/skills/global_config/archify/scripts/check-render-output.mjs +916 -0
  145. package/skills/global_config/archify/scripts/generate-brand-marks.mjs +141 -0
  146. package/skills/global_config/archify/scripts/generate-validators.mjs +66 -0
  147. package/skills/global_config/archify/scripts/render-examples.mjs +26 -0
  148. package/skills/global_config/archify/skill-release.json +10 -0
  149. package/skills/global_config/ask-tim/SKILL.md +10 -0
  150. package/skills/global_config/bdb-security-audit/SKILL.md +109 -0
  151. package/skills/global_config/bdb-security-audit/references/audit-checklists.md +172 -0
  152. package/skills/global_config/bdb-security-audit/references/skylos-guide.md +139 -0
  153. package/skills/global_config/bdb-security-audit/references/xalgorix-bridge.md +110 -0
  154. package/skills/global_config/bdbdesignpro/SKILL.md +4 -4
  155. package/skills/global_config/bdbdesignpro/references/bdb-motion-tokens.md +52 -31
  156. package/skills/global_config/bdbresilience/SKILL.md +10 -0
  157. package/skills/global_config/brag/SKILL.md +179 -0
  158. package/skills/global_config/brag/assets/music/README.md +20 -0
  159. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-1-by-ende-dot-app.music-cues.json +3846 -0
  160. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-1-by-ende-dot-app.music-cues.md +35 -0
  161. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-10-by-ende-dot-app.music-cues.json +1826 -0
  162. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-10-by-ende-dot-app.music-cues.md +35 -0
  163. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-11-by-ende-dot-app.music-cues.json +2266 -0
  164. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-11-by-ende-dot-app.music-cues.md +35 -0
  165. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-12-by-ende-dot-app.music-cues.json +2806 -0
  166. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-12-by-ende-dot-app.music-cues.md +35 -0
  167. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-9-by-ende-dot-app.music-cues.json +2796 -0
  168. package/skills/global_config/brag/assets/music/cues/happy-beats-business-moves-vol-9-by-ende-dot-app.music-cues.md +35 -0
  169. package/skills/global_config/brag/assets/music/happy-beats-business-moves-vol-1-by-ende-dot-app.mp3 +0 -0
  170. package/skills/global_config/brag/assets/music/happy-beats-business-moves-vol-10-by-ende-dot-app.mp3 +0 -0
  171. package/skills/global_config/brag/assets/music/happy-beats-business-moves-vol-11-by-ende-dot-app.mp3 +0 -0
  172. package/skills/global_config/brag/assets/music/happy-beats-business-moves-vol-12-by-ende-dot-app.mp3 +0 -0
  173. package/skills/global_config/brag/assets/music/happy-beats-business-moves-vol-9-by-ende-dot-app.mp3 +0 -0
  174. package/skills/global_config/brag/assets/sfx/casino/card-fan-1.ogg +0 -0
  175. package/skills/global_config/brag/assets/sfx/casino/card-fan-2.ogg +0 -0
  176. package/skills/global_config/brag/assets/sfx/casino/card-place-1.ogg +0 -0
  177. package/skills/global_config/brag/assets/sfx/casino/card-place-2.ogg +0 -0
  178. package/skills/global_config/brag/assets/sfx/casino/card-place-3.ogg +0 -0
  179. package/skills/global_config/brag/assets/sfx/casino/card-place-4.ogg +0 -0
  180. package/skills/global_config/brag/assets/sfx/casino/card-shove-1.ogg +0 -0
  181. package/skills/global_config/brag/assets/sfx/casino/card-shove-2.ogg +0 -0
  182. package/skills/global_config/brag/assets/sfx/casino/card-shove-3.ogg +0 -0
  183. package/skills/global_config/brag/assets/sfx/casino/card-shove-4.ogg +0 -0
  184. package/skills/global_config/brag/assets/sfx/casino/card-shuffle.ogg +0 -0
  185. package/skills/global_config/brag/assets/sfx/casino/card-slide-1.ogg +0 -0
  186. package/skills/global_config/brag/assets/sfx/casino/card-slide-2.ogg +0 -0
  187. package/skills/global_config/brag/assets/sfx/casino/card-slide-3.ogg +0 -0
  188. package/skills/global_config/brag/assets/sfx/casino/card-slide-4.ogg +0 -0
  189. package/skills/global_config/brag/assets/sfx/casino/card-slide-5.ogg +0 -0
  190. package/skills/global_config/brag/assets/sfx/casino/card-slide-6.ogg +0 -0
  191. package/skills/global_config/brag/assets/sfx/casino/card-slide-7.ogg +0 -0
  192. package/skills/global_config/brag/assets/sfx/casino/card-slide-8.ogg +0 -0
  193. package/skills/global_config/brag/assets/sfx/casino/cards-pack-open-1.ogg +0 -0
  194. package/skills/global_config/brag/assets/sfx/casino/cards-pack-open-2.ogg +0 -0
  195. package/skills/global_config/brag/assets/sfx/casino/chip-lay-1.ogg +0 -0
  196. package/skills/global_config/brag/assets/sfx/casino/chip-lay-2.ogg +0 -0
  197. package/skills/global_config/brag/assets/sfx/casino/chip-lay-3.ogg +0 -0
  198. package/skills/global_config/brag/assets/sfx/casino/chips-collide-1.ogg +0 -0
  199. package/skills/global_config/brag/assets/sfx/casino/chips-collide-2.ogg +0 -0
  200. package/skills/global_config/brag/assets/sfx/casino/chips-collide-3.ogg +0 -0
  201. package/skills/global_config/brag/assets/sfx/casino/chips-collide-4.ogg +0 -0
  202. package/skills/global_config/brag/assets/sfx/casino/chips-handle-1.ogg +0 -0
  203. package/skills/global_config/brag/assets/sfx/casino/chips-handle-2.ogg +0 -0
  204. package/skills/global_config/brag/assets/sfx/casino/chips-handle-3.ogg +0 -0
  205. package/skills/global_config/brag/assets/sfx/casino/chips-handle-4.ogg +0 -0
  206. package/skills/global_config/brag/assets/sfx/casino/chips-handle-6.ogg +0 -0
  207. package/skills/global_config/brag/assets/sfx/casino/chips-stack-1.ogg +0 -0
  208. package/skills/global_config/brag/assets/sfx/casino/chips-stack-2.ogg +0 -0
  209. package/skills/global_config/brag/assets/sfx/casino/chips-stack-3.ogg +0 -0
  210. package/skills/global_config/brag/assets/sfx/casino/chips-stack-4.ogg +0 -0
  211. package/skills/global_config/brag/assets/sfx/casino/chips-stack-5.ogg +0 -0
  212. package/skills/global_config/brag/assets/sfx/casino/chips-stack-6.ogg +0 -0
  213. package/skills/global_config/brag/assets/sfx/casino/dice-grab-1.ogg +0 -0
  214. package/skills/global_config/brag/assets/sfx/casino/dice-grab-2.ogg +0 -0
  215. package/skills/global_config/brag/assets/sfx/casino/dice-shake-1.ogg +0 -0
  216. package/skills/global_config/brag/assets/sfx/casino/dice-shake-2.ogg +0 -0
  217. package/skills/global_config/brag/assets/sfx/casino/dice-shake-3.ogg +0 -0
  218. package/skills/global_config/brag/assets/sfx/casino/dice-throw-1.ogg +0 -0
  219. package/skills/global_config/brag/assets/sfx/casino/dice-throw-2.ogg +0 -0
  220. package/skills/global_config/brag/assets/sfx/casino/dice-throw-3.ogg +0 -0
  221. package/skills/global_config/brag/assets/sfx/casino/die-throw-1.ogg +0 -0
  222. package/skills/global_config/brag/assets/sfx/casino/die-throw-2.ogg +0 -0
  223. package/skills/global_config/brag/assets/sfx/casino/die-throw-3.ogg +0 -0
  224. package/skills/global_config/brag/assets/sfx/casino/die-throw-4.ogg +0 -0
  225. package/skills/global_config/brag/assets/sfx/impact/footstep_carpet_000.ogg +0 -0
  226. package/skills/global_config/brag/assets/sfx/impact/footstep_carpet_003.ogg +0 -0
  227. package/skills/global_config/brag/assets/sfx/impact/footstep_carpet_004.ogg +0 -0
  228. package/skills/global_config/brag/assets/sfx/impact/footstep_concrete_000.ogg +0 -0
  229. package/skills/global_config/brag/assets/sfx/impact/footstep_concrete_001.ogg +0 -0
  230. package/skills/global_config/brag/assets/sfx/impact/footstep_concrete_002.ogg +0 -0
  231. package/skills/global_config/brag/assets/sfx/impact/footstep_concrete_003.ogg +0 -0
  232. package/skills/global_config/brag/assets/sfx/impact/footstep_concrete_004.ogg +0 -0
  233. package/skills/global_config/brag/assets/sfx/impact/footstep_grass_000.ogg +0 -0
  234. package/skills/global_config/brag/assets/sfx/impact/footstep_grass_001.ogg +0 -0
  235. package/skills/global_config/brag/assets/sfx/impact/footstep_grass_002.ogg +0 -0
  236. package/skills/global_config/brag/assets/sfx/impact/footstep_grass_003.ogg +0 -0
  237. package/skills/global_config/brag/assets/sfx/impact/footstep_grass_004.ogg +0 -0
  238. package/skills/global_config/brag/assets/sfx/impact/footstep_snow_000.ogg +0 -0
  239. package/skills/global_config/brag/assets/sfx/impact/footstep_snow_001.ogg +0 -0
  240. package/skills/global_config/brag/assets/sfx/impact/footstep_snow_002.ogg +0 -0
  241. package/skills/global_config/brag/assets/sfx/impact/footstep_snow_003.ogg +0 -0
  242. package/skills/global_config/brag/assets/sfx/impact/footstep_snow_004.ogg +0 -0
  243. package/skills/global_config/brag/assets/sfx/impact/footstep_wood_000.ogg +0 -0
  244. package/skills/global_config/brag/assets/sfx/impact/footstep_wood_001.ogg +0 -0
  245. package/skills/global_config/brag/assets/sfx/impact/footstep_wood_002.ogg +0 -0
  246. package/skills/global_config/brag/assets/sfx/impact/footstep_wood_003.ogg +0 -0
  247. package/skills/global_config/brag/assets/sfx/impact/footstep_wood_004.ogg +0 -0
  248. package/skills/global_config/brag/assets/sfx/impact/impactBell_heavy_000.ogg +0 -0
  249. package/skills/global_config/brag/assets/sfx/impact/impactBell_heavy_003.ogg +0 -0
  250. package/skills/global_config/brag/assets/sfx/impact/impactBell_heavy_004.ogg +0 -0
  251. package/skills/global_config/brag/assets/sfx/impact/impactGeneric_light_000.ogg +0 -0
  252. package/skills/global_config/brag/assets/sfx/impact/impactGeneric_light_001.ogg +0 -0
  253. package/skills/global_config/brag/assets/sfx/impact/impactGeneric_light_002.ogg +0 -0
  254. package/skills/global_config/brag/assets/sfx/impact/impactGeneric_light_003.ogg +0 -0
  255. package/skills/global_config/brag/assets/sfx/impact/impactGeneric_light_004.ogg +0 -0
  256. package/skills/global_config/brag/assets/sfx/impact/impactGlass_heavy_002.ogg +0 -0
  257. package/skills/global_config/brag/assets/sfx/impact/impactGlass_light_001.ogg +0 -0
  258. package/skills/global_config/brag/assets/sfx/impact/impactGlass_light_002.ogg +0 -0
  259. package/skills/global_config/brag/assets/sfx/impact/impactGlass_light_003.ogg +0 -0
  260. package/skills/global_config/brag/assets/sfx/impact/impactGlass_medium_000.ogg +0 -0
  261. package/skills/global_config/brag/assets/sfx/impact/impactGlass_medium_002.ogg +0 -0
  262. package/skills/global_config/brag/assets/sfx/impact/impactGlass_medium_004.ogg +0 -0
  263. package/skills/global_config/brag/assets/sfx/impact/impactMetal_heavy_000.ogg +0 -0
  264. package/skills/global_config/brag/assets/sfx/impact/impactMetal_heavy_002.ogg +0 -0
  265. package/skills/global_config/brag/assets/sfx/impact/impactMetal_heavy_004.ogg +0 -0
  266. package/skills/global_config/brag/assets/sfx/impact/impactMetal_light_002.ogg +0 -0
  267. package/skills/global_config/brag/assets/sfx/impact/impactMetal_light_003.ogg +0 -0
  268. package/skills/global_config/brag/assets/sfx/impact/impactMetal_medium_000.ogg +0 -0
  269. package/skills/global_config/brag/assets/sfx/impact/impactMetal_medium_001.ogg +0 -0
  270. package/skills/global_config/brag/assets/sfx/impact/impactMetal_medium_002.ogg +0 -0
  271. package/skills/global_config/brag/assets/sfx/impact/impactMetal_medium_003.ogg +0 -0
  272. package/skills/global_config/brag/assets/sfx/impact/impactMetal_medium_004.ogg +0 -0
  273. package/skills/global_config/brag/assets/sfx/impact/impactMining_001.ogg +0 -0
  274. package/skills/global_config/brag/assets/sfx/impact/impactPlank_medium_000.ogg +0 -0
  275. package/skills/global_config/brag/assets/sfx/impact/impactPlank_medium_001.ogg +0 -0
  276. package/skills/global_config/brag/assets/sfx/impact/impactPlank_medium_002.ogg +0 -0
  277. package/skills/global_config/brag/assets/sfx/impact/impactPlank_medium_003.ogg +0 -0
  278. package/skills/global_config/brag/assets/sfx/impact/impactPlank_medium_004.ogg +0 -0
  279. package/skills/global_config/brag/assets/sfx/impact/impactPlate_heavy_000.ogg +0 -0
  280. package/skills/global_config/brag/assets/sfx/impact/impactPlate_heavy_001.ogg +0 -0
  281. package/skills/global_config/brag/assets/sfx/impact/impactPlate_heavy_002.ogg +0 -0
  282. package/skills/global_config/brag/assets/sfx/impact/impactPlate_heavy_003.ogg +0 -0
  283. package/skills/global_config/brag/assets/sfx/impact/impactPlate_heavy_004.ogg +0 -0
  284. package/skills/global_config/brag/assets/sfx/impact/impactPlate_light_000.ogg +0 -0
  285. package/skills/global_config/brag/assets/sfx/impact/impactPlate_light_001.ogg +0 -0
  286. package/skills/global_config/brag/assets/sfx/impact/impactPlate_light_002.ogg +0 -0
  287. package/skills/global_config/brag/assets/sfx/impact/impactPlate_light_003.ogg +0 -0
  288. package/skills/global_config/brag/assets/sfx/impact/impactPlate_light_004.ogg +0 -0
  289. package/skills/global_config/brag/assets/sfx/impact/impactPlate_medium_000.ogg +0 -0
  290. package/skills/global_config/brag/assets/sfx/impact/impactPlate_medium_001.ogg +0 -0
  291. package/skills/global_config/brag/assets/sfx/impact/impactPlate_medium_002.ogg +0 -0
  292. package/skills/global_config/brag/assets/sfx/impact/impactPlate_medium_003.ogg +0 -0
  293. package/skills/global_config/brag/assets/sfx/impact/impactPlate_medium_004.ogg +0 -0
  294. package/skills/global_config/brag/assets/sfx/impact/impactPunch_heavy_000.ogg +0 -0
  295. package/skills/global_config/brag/assets/sfx/impact/impactPunch_heavy_001.ogg +0 -0
  296. package/skills/global_config/brag/assets/sfx/impact/impactPunch_heavy_002.ogg +0 -0
  297. package/skills/global_config/brag/assets/sfx/impact/impactPunch_heavy_003.ogg +0 -0
  298. package/skills/global_config/brag/assets/sfx/impact/impactPunch_heavy_004.ogg +0 -0
  299. package/skills/global_config/brag/assets/sfx/impact/impactPunch_medium_000.ogg +0 -0
  300. package/skills/global_config/brag/assets/sfx/impact/impactPunch_medium_001.ogg +0 -0
  301. package/skills/global_config/brag/assets/sfx/impact/impactPunch_medium_002.ogg +0 -0
  302. package/skills/global_config/brag/assets/sfx/impact/impactPunch_medium_003.ogg +0 -0
  303. package/skills/global_config/brag/assets/sfx/impact/impactPunch_medium_004.ogg +0 -0
  304. package/skills/global_config/brag/assets/sfx/impact/impactSoft_heavy_000.ogg +0 -0
  305. package/skills/global_config/brag/assets/sfx/impact/impactSoft_heavy_001.ogg +0 -0
  306. package/skills/global_config/brag/assets/sfx/impact/impactSoft_heavy_002.ogg +0 -0
  307. package/skills/global_config/brag/assets/sfx/impact/impactSoft_heavy_003.ogg +0 -0
  308. package/skills/global_config/brag/assets/sfx/impact/impactSoft_heavy_004.ogg +0 -0
  309. package/skills/global_config/brag/assets/sfx/impact/impactSoft_medium_000.ogg +0 -0
  310. package/skills/global_config/brag/assets/sfx/impact/impactSoft_medium_001.ogg +0 -0
  311. package/skills/global_config/brag/assets/sfx/impact/impactSoft_medium_002.ogg +0 -0
  312. package/skills/global_config/brag/assets/sfx/impact/impactSoft_medium_003.ogg +0 -0
  313. package/skills/global_config/brag/assets/sfx/impact/impactSoft_medium_004.ogg +0 -0
  314. package/skills/global_config/brag/assets/sfx/impact/impactTin_medium_000.ogg +0 -0
  315. package/skills/global_config/brag/assets/sfx/impact/impactTin_medium_001.ogg +0 -0
  316. package/skills/global_config/brag/assets/sfx/impact/impactTin_medium_002.ogg +0 -0
  317. package/skills/global_config/brag/assets/sfx/impact/impactTin_medium_003.ogg +0 -0
  318. package/skills/global_config/brag/assets/sfx/impact/impactTin_medium_004.ogg +0 -0
  319. package/skills/global_config/brag/assets/sfx/impact/impactWood_heavy_000.ogg +0 -0
  320. package/skills/global_config/brag/assets/sfx/impact/impactWood_heavy_001.ogg +0 -0
  321. package/skills/global_config/brag/assets/sfx/impact/impactWood_heavy_002.ogg +0 -0
  322. package/skills/global_config/brag/assets/sfx/impact/impactWood_heavy_003.ogg +0 -0
  323. package/skills/global_config/brag/assets/sfx/impact/impactWood_heavy_004.ogg +0 -0
  324. package/skills/global_config/brag/assets/sfx/impact/impactWood_light_000.ogg +0 -0
  325. package/skills/global_config/brag/assets/sfx/impact/impactWood_light_001.ogg +0 -0
  326. package/skills/global_config/brag/assets/sfx/impact/impactWood_light_002.ogg +0 -0
  327. package/skills/global_config/brag/assets/sfx/impact/impactWood_light_003.ogg +0 -0
  328. package/skills/global_config/brag/assets/sfx/impact/impactWood_light_004.ogg +0 -0
  329. package/skills/global_config/brag/assets/sfx/impact/impactWood_medium_000.ogg +0 -0
  330. package/skills/global_config/brag/assets/sfx/impact/impactWood_medium_001.ogg +0 -0
  331. package/skills/global_config/brag/assets/sfx/impact/impactWood_medium_002.ogg +0 -0
  332. package/skills/global_config/brag/assets/sfx/impact/impactWood_medium_003.ogg +0 -0
  333. package/skills/global_config/brag/assets/sfx/impact/impactWood_medium_004.ogg +0 -0
  334. package/skills/global_config/brag/assets/sfx/interface/bong_001.ogg +0 -0
  335. package/skills/global_config/brag/assets/sfx/interface/click_001.ogg +0 -0
  336. package/skills/global_config/brag/assets/sfx/interface/click_002.ogg +0 -0
  337. package/skills/global_config/brag/assets/sfx/interface/click_003.ogg +0 -0
  338. package/skills/global_config/brag/assets/sfx/interface/click_004.ogg +0 -0
  339. package/skills/global_config/brag/assets/sfx/interface/click_005.ogg +0 -0
  340. package/skills/global_config/brag/assets/sfx/interface/drop_001.ogg +0 -0
  341. package/skills/global_config/brag/assets/sfx/interface/drop_002.ogg +0 -0
  342. package/skills/global_config/brag/assets/sfx/interface/drop_003.ogg +0 -0
  343. package/skills/global_config/brag/assets/sfx/interface/error_005.ogg +0 -0
  344. package/skills/global_config/brag/assets/sfx/interface/error_006.ogg +0 -0
  345. package/skills/global_config/brag/assets/sfx/interface/glitch_002.ogg +0 -0
  346. package/skills/global_config/brag/assets/sfx/interface/glitch_004.ogg +0 -0
  347. package/skills/global_config/brag/assets/sfx/interface/select_008.ogg +0 -0
  348. package/skills/global_config/brag/assets/sfx/interface/switch_001.ogg +0 -0
  349. package/skills/global_config/brag/assets/sfx/interface/switch_002.ogg +0 -0
  350. package/skills/global_config/brag/assets/sfx/interface/switch_004.ogg +0 -0
  351. package/skills/global_config/brag/assets/sfx/interface/switch_005.ogg +0 -0
  352. package/skills/global_config/brag/assets/sfx/interface/switch_006.ogg +0 -0
  353. package/skills/global_config/brag/assets/sfx/interface/switch_007.ogg +0 -0
  354. package/skills/global_config/brag/assets/sfx/keyboard/keypress-001.wav +0 -0
  355. package/skills/global_config/brag/assets/sfx/keyboard/keypress-002.wav +0 -0
  356. package/skills/global_config/brag/assets/sfx/keyboard/keypress-003.wav +0 -0
  357. package/skills/global_config/brag/assets/sfx/keyboard/keypress-004.wav +0 -0
  358. package/skills/global_config/brag/assets/sfx/keyboard/keypress-005.wav +0 -0
  359. package/skills/global_config/brag/assets/sfx/keyboard/keypress-006.wav +0 -0
  360. package/skills/global_config/brag/assets/sfx/keyboard/keypress-007.wav +0 -0
  361. package/skills/global_config/brag/assets/sfx/keyboard/keypress-008.wav +0 -0
  362. package/skills/global_config/brag/assets/sfx/keyboard/keypress-009.wav +0 -0
  363. package/skills/global_config/brag/assets/sfx/keyboard/keypress-010.wav +0 -0
  364. package/skills/global_config/brag/assets/sfx/keyboard/keypress-011.wav +0 -0
  365. package/skills/global_config/brag/assets/sfx/keyboard/keypress-012.wav +0 -0
  366. package/skills/global_config/brag/assets/sfx/keyboard/keypress-013.wav +0 -0
  367. package/skills/global_config/brag/assets/sfx/keyboard/keypress-014.wav +0 -0
  368. package/skills/global_config/brag/assets/sfx/keyboard/keypress-015.wav +0 -0
  369. package/skills/global_config/brag/assets/sfx/keyboard/keypress-016.wav +0 -0
  370. package/skills/global_config/brag/assets/sfx/keyboard/keypress-017.wav +0 -0
  371. package/skills/global_config/brag/assets/sfx/keyboard/keypress-018.wav +0 -0
  372. package/skills/global_config/brag/assets/sfx/keyboard/keypress-019.wav +0 -0
  373. package/skills/global_config/brag/assets/sfx/keyboard/keypress-020.wav +0 -0
  374. package/skills/global_config/brag/assets/sfx/keyboard/keypress-021.wav +0 -0
  375. package/skills/global_config/brag/assets/sfx/keyboard/keypress-022.wav +0 -0
  376. package/skills/global_config/brag/assets/sfx/keyboard/keypress-023.wav +0 -0
  377. package/skills/global_config/brag/assets/sfx/keyboard/keypress-024.wav +0 -0
  378. package/skills/global_config/brag/assets/sfx/keyboard/keypress-025.wav +0 -0
  379. package/skills/global_config/brag/assets/sfx/keyboard/keypress-026.wav +0 -0
  380. package/skills/global_config/brag/assets/sfx/keyboard/keypress-027.wav +0 -0
  381. package/skills/global_config/brag/assets/sfx/keyboard/keypress-028.wav +0 -0
  382. package/skills/global_config/brag/assets/sfx/keyboard/keypress-029.wav +0 -0
  383. package/skills/global_config/brag/assets/sfx/keyboard/keypress-030.wav +0 -0
  384. package/skills/global_config/brag/assets/sfx/keyboard/keypress-031.wav +0 -0
  385. package/skills/global_config/brag/assets/sfx/keyboard/keypress-032.wav +0 -0
  386. package/skills/global_config/brag/assets/sfx/sfx-analysis.json +15584 -0
  387. package/skills/global_config/brag/assets/sfx/sfx-analysis.md +75 -0
  388. package/skills/global_config/brag/assets/sfx/ui/click1.ogg +0 -0
  389. package/skills/global_config/brag/assets/sfx/ui/click2.ogg +0 -0
  390. package/skills/global_config/brag/assets/sfx/ui/click3.ogg +0 -0
  391. package/skills/global_config/brag/assets/sfx/ui/click4.ogg +0 -0
  392. package/skills/global_config/brag/assets/sfx/ui/click5.ogg +0 -0
  393. package/skills/global_config/brag/assets/sfx/ui/mouseclick1.ogg +0 -0
  394. package/skills/global_config/brag/assets/sfx/ui/rollover1.ogg +0 -0
  395. package/skills/global_config/brag/assets/sfx/ui/rollover2.ogg +0 -0
  396. package/skills/global_config/brag/assets/sfx/ui/rollover4.ogg +0 -0
  397. package/skills/global_config/brag/assets/sfx/ui/rollover5.ogg +0 -0
  398. package/skills/global_config/brag/assets/sfx/ui/switch1.ogg +0 -0
  399. package/skills/global_config/brag/assets/sfx/ui/switch10.ogg +0 -0
  400. package/skills/global_config/brag/assets/sfx/ui/switch11.ogg +0 -0
  401. package/skills/global_config/brag/assets/sfx/ui/switch12.ogg +0 -0
  402. package/skills/global_config/brag/assets/sfx/ui/switch13.ogg +0 -0
  403. package/skills/global_config/brag/assets/sfx/ui/switch14.ogg +0 -0
  404. package/skills/global_config/brag/assets/sfx/ui/switch15.ogg +0 -0
  405. package/skills/global_config/brag/assets/sfx/ui/switch16.ogg +0 -0
  406. package/skills/global_config/brag/assets/sfx/ui/switch17.ogg +0 -0
  407. package/skills/global_config/brag/assets/sfx/ui/switch18.ogg +0 -0
  408. package/skills/global_config/brag/assets/sfx/ui/switch19.ogg +0 -0
  409. package/skills/global_config/brag/assets/sfx/ui/switch2.ogg +0 -0
  410. package/skills/global_config/brag/assets/sfx/ui/switch20.ogg +0 -0
  411. package/skills/global_config/brag/assets/sfx/ui/switch21.ogg +0 -0
  412. package/skills/global_config/brag/assets/sfx/ui/switch22.ogg +0 -0
  413. package/skills/global_config/brag/assets/sfx/ui/switch23.ogg +0 -0
  414. package/skills/global_config/brag/assets/sfx/ui/switch24.ogg +0 -0
  415. package/skills/global_config/brag/assets/sfx/ui/switch25.ogg +0 -0
  416. package/skills/global_config/brag/assets/sfx/ui/switch26.ogg +0 -0
  417. package/skills/global_config/brag/assets/sfx/ui/switch27.ogg +0 -0
  418. package/skills/global_config/brag/assets/sfx/ui/switch28.ogg +0 -0
  419. package/skills/global_config/brag/assets/sfx/ui/switch29.ogg +0 -0
  420. package/skills/global_config/brag/assets/sfx/ui/switch3.ogg +0 -0
  421. package/skills/global_config/brag/assets/sfx/ui/switch30.ogg +0 -0
  422. package/skills/global_config/brag/assets/sfx/ui/switch31.ogg +0 -0
  423. package/skills/global_config/brag/assets/sfx/ui/switch32.ogg +0 -0
  424. package/skills/global_config/brag/assets/sfx/ui/switch33.ogg +0 -0
  425. package/skills/global_config/brag/assets/sfx/ui/switch34.ogg +0 -0
  426. package/skills/global_config/brag/assets/sfx/ui/switch35.ogg +0 -0
  427. package/skills/global_config/brag/assets/sfx/ui/switch36.ogg +0 -0
  428. package/skills/global_config/brag/assets/sfx/ui/switch37.ogg +0 -0
  429. package/skills/global_config/brag/assets/sfx/ui/switch38.ogg +0 -0
  430. package/skills/global_config/brag/assets/sfx/ui/switch4.ogg +0 -0
  431. package/skills/global_config/brag/assets/sfx/ui/switch5.ogg +0 -0
  432. package/skills/global_config/brag/assets/sfx/ui/switch6.ogg +0 -0
  433. package/skills/global_config/brag/assets/sfx/ui/switch7.ogg +0 -0
  434. package/skills/global_config/brag/assets/sfx/ui/switch8.ogg +0 -0
  435. package/skills/global_config/brag/assets/sfx/ui/switch9.ogg +0 -0
  436. package/skills/global_config/brag/references/audio.md +307 -0
  437. package/skills/global_config/brag/references/step-1-inspect.md +133 -0
  438. package/skills/global_config/brag/references/step-2-plan.md +234 -0
  439. package/skills/global_config/brag/references/step-3-compose.md +210 -0
  440. package/skills/global_config/brag/references/step-4-deliver.md +168 -0
  441. package/skills/global_config/brag/references/tones.md +231 -0
  442. package/skills/global_config/brag/scripts/analyze_music_cues.py +309 -0
  443. package/skills/global_config/brag/scripts/pyproject.toml +14 -0
  444. package/skills/global_config/brag/scripts/uv.lock +819 -0
  445. package/skills/global_config/deja-memory/SKILL.md +42 -0
  446. package/skills/global_config/editable-design/LICENSE +202 -0
  447. package/skills/global_config/editable-design/README.md +34 -0
  448. package/skills/global_config/editable-design/SKILL.md +630 -0
  449. package/skills/global_config/editable-design/THIRD_PARTY_NOTICES.md +10 -0
  450. package/skills/global_config/editable-design/agents/openai.yaml +4 -0
  451. package/skills/global_config/editable-design/assets/editor/layer-editor.css +262 -0
  452. package/skills/global_config/editable-design/assets/editor/layer-editor.js +1929 -0
  453. package/skills/global_config/editable-design/assets/poster-starter/README.md +92 -0
  454. package/skills/global_config/editable-design/assets/poster-starter/assets/.gitkeep +0 -0
  455. package/skills/global_config/editable-design/assets/poster-starter/index.html +91 -0
  456. package/skills/global_config/editable-design/assets/poster-starter/poster.json +6 -0
  457. package/skills/global_config/editable-design/assets/poster-starter/reference/.gitkeep +1 -0
  458. package/skills/global_config/editable-design/assets/replay/icons/assets.png +0 -0
  459. package/skills/global_config/editable-design/assets/replay/icons/html.png +0 -0
  460. package/skills/global_config/editable-design/assets/replay/icons/input.png +0 -0
  461. package/skills/global_config/editable-design/assets/replay/icons/layers.png +0 -0
  462. package/skills/global_config/editable-design/assets/replay/icons/plan.png +0 -0
  463. package/skills/global_config/editable-design/assets/replay/icons/reference.png +0 -0
  464. package/skills/global_config/editable-design/assets/replay/icons/review.png +0 -0
  465. package/skills/global_config/editable-design/assets/replay/index.html +59 -0
  466. package/skills/global_config/editable-design/assets/replay/replay-motion.js +410 -0
  467. package/skills/global_config/editable-design/assets/replay/replay.css +380 -0
  468. package/skills/global_config/editable-design/assets/replay/replay.js +374 -0
  469. package/skills/global_config/editable-design/font-kit/package-lock.json +115 -0
  470. package/skills/global_config/editable-design/font-kit/package.json +19 -0
  471. package/skills/global_config/editable-design/pack.sh +20 -0
  472. package/skills/global_config/editable-design/references/asset-architecture.md +72 -0
  473. package/skills/global_config/editable-design/references/editor-pitfalls.md +70 -0
  474. package/skills/global_config/editable-design/references/editor-runtime.md +131 -0
  475. package/skills/global_config/editable-design/references/font-system.md +89 -0
  476. package/skills/global_config/editable-design/references/imagery.md +145 -0
  477. package/skills/global_config/editable-design/references/layout-typography.md +116 -0
  478. package/skills/global_config/editable-design/references/replay-contract.md +169 -0
  479. package/skills/global_config/editable-design/scripts/_browser.mjs +247 -0
  480. package/skills/global_config/editable-design/scripts/bake.mjs +87 -0
  481. package/skills/global_config/editable-design/scripts/build-replay.mjs +316 -0
  482. package/skills/global_config/editable-design/scripts/check-contract.mjs +293 -0
  483. package/skills/global_config/editable-design/scripts/check-fonts.sh +252 -0
  484. package/skills/global_config/editable-design/scripts/check-poster.sh +70 -0
  485. package/skills/global_config/editable-design/scripts/doctor.sh +78 -0
  486. package/skills/global_config/editable-design/scripts/explode.mjs +115 -0
  487. package/skills/global_config/editable-design/scripts/font-kit.mjs +187 -0
  488. package/skills/global_config/editable-design/scripts/import-asset.sh +23 -0
  489. package/skills/global_config/editable-design/scripts/init-poster.sh +64 -0
  490. package/skills/global_config/editable-design/scripts/install-font-kit.sh +13 -0
  491. package/skills/global_config/editable-design/scripts/package-lock.json +334 -0
  492. package/skills/global_config/editable-design/scripts/package.json +14 -0
  493. package/skills/global_config/editable-design/scripts/remove-chroma-key.py +201 -0
  494. package/skills/global_config/editable-design/scripts/render-poster.sh +202 -0
  495. package/skills/global_config/editable-design/scripts/trace.sh +159 -0
  496. package/skills/global_config/editable-design/scripts/verify-replay.mjs +97 -0
  497. package/skills/global_config/editable-design/scripts/verify.mjs +782 -0
  498. package/skills/global_config/editable-design/scripts/wire-editor.mjs +104 -0
  499. package/skills/global_config/editable-design/tests/fixtures/small-explode/index.html +86 -0
  500. package/skills/global_config/mcsc/SKILL.md +60 -0
  501. package/skills/global_config/plan-canvas/SKILL.md +8 -0
  502. package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/server.js +31 -6
  503. package/skills/global_config/plan-canvas/scripts/plan-canvas.js +4 -2
package/installer.js CHANGED
@@ -1828,6 +1828,50 @@ function moduleBasePath() {
1828
1828
  return scriptDir.includes('_npx') ? path.join(os.homedir(), '.agents') : path.dirname(srcDir);
1829
1829
  }
1830
1830
 
1831
+ // deja resolves its exclude file as $XDG_CONFIG_HOME/deja/exclude, falling
1832
+ // back to $HOME/.config on ALL platforms including Windows -- do not switch
1833
+ // this to os.UserConfigDir()/APPDATA, deja would never read that file there.
1834
+ function ensureDejaExclude(excludePath) {
1835
+ fs.mkdirSync(path.dirname(excludePath), { recursive: true });
1836
+ let existing = '';
1837
+ if (fs.existsSync(excludePath)) {
1838
+ existing = fs.readFileSync(excludePath, 'utf8');
1839
+ }
1840
+ // deja skips comment lines when matching, so a '# secret' line does not
1841
+ // count as the pattern being present. Only a line trimming to exactly
1842
+ // 'secret' counts -- never rewrite, reorder or deduplicate user lines.
1843
+ if (existing.split(/\r?\n/).some(line => line.trim() === 'secret')) return false;
1844
+ let content = existing;
1845
+ if (content.length > 0 && !content.endsWith('\n')) content += '\n';
1846
+ fs.writeFileSync(excludePath, `${content}secret\n`);
1847
+ return true;
1848
+ }
1849
+
1850
+ async function installDeja() {
1851
+ if (DRY_RUN) {
1852
+ log.step('[dry-run] would install deja-vu 0.21.1 globally and add its exclude pattern');
1853
+ return;
1854
+ }
1855
+ try {
1856
+ log.step('Installing deja-vu session memory...');
1857
+ execSync('npm install -g @vshulcz/deja-vu@0.21.1', { stdio: 'ignore' });
1858
+ } catch (e) {
1859
+ log.warn('deja-vu install failed. Install later with: npm install -g @vshulcz/deja-vu@0.21.1');
1860
+ }
1861
+ if (!hasExecutable('deja')) {
1862
+ log.warn('deja is not on PATH. Install it with: npm install -g @vshulcz/deja-vu@0.21.1');
1863
+ }
1864
+ const base = process.env.XDG_CONFIG_HOME || path.join(homeDir, '.config');
1865
+ const excludePath = path.join(base, 'deja', 'exclude');
1866
+ try {
1867
+ if (ensureDejaExclude(excludePath)) {
1868
+ log.step(`Added 'secret' to the deja exclude list at ${excludePath}`);
1869
+ }
1870
+ } catch (e) {
1871
+ log.warn(`Could not update the deja exclude list at ${excludePath}: ${e.message}. Add the line 'secret' to it by hand.`);
1872
+ }
1873
+ }
1874
+
1831
1875
  async function installMemB(interactive) {
1832
1876
  let installWebUI = true;
1833
1877
  if (interactive && !isAutoYes) {
@@ -1845,6 +1889,7 @@ async function installMemB(interactive) {
1845
1889
  log.warn('Skipping memB setup: the module could not be downloaded.');
1846
1890
  return;
1847
1891
  }
1892
+ await installDeja();
1848
1893
  if (DRY_RUN) {
1849
1894
  log.step('[dry-run] would bootstrap memB venv + pip requirements');
1850
1895
  return;
@@ -2846,6 +2891,13 @@ async function installMcpsForTarget(paths, ctx) {
2846
2891
  const skippedMcpConfigKeys = resolveUnsupportedMcpConfigKeys();
2847
2892
  try {
2848
2893
  const parsedMcpConfig = JSON.parse(mcpConfigStr);
2894
+ // npm's Windows shim is deja.cmd, which Node refuses to spawn without
2895
+ // a shell (EINVAL since the CVE-2024-27980 fix) -- wrap the command in
2896
+ // cmd /c here so every generated config, the Codex TOML block and the
2897
+ // ~/.claude.json mirror get the launchable form.
2898
+ if (process.platform === 'win32' && parsedMcpConfig.mcpServers.deja) {
2899
+ parsedMcpConfig.mcpServers.deja = { command: 'cmd', args: ['/c', 'deja', 'mcp'] };
2900
+ }
2849
2901
  const finalMcpServers = {};
2850
2902
  const availableFolders = fs.readdirSync(mcpSrcDir);
2851
2903
 
@@ -2903,7 +2955,7 @@ async function installMcpsForTarget(paths, ctx) {
2903
2955
  ? path.join(mcpCodeTarget, 'memb-mcp', '.venv', 'Scripts', 'python.exe')
2904
2956
  : path.join(mcpCodeTarget, 'memb-mcp', '.venv', 'bin', 'python');
2905
2957
  const pythonBinValue = pythonBinPath.split('\\').join('/');
2906
- const geminiKeyValue = creds.gemini || process.env.GEMINI_API_KEY || '';
2958
+ const geminiKeyValue = (creds.keyEnvName === 'GEMINI_API_KEY' ? creds.gemini : '') || process.env.GEMINI_API_KEY || '';
2907
2959
  mcpConfigStr = mcpConfigStr.replace(/__PYTHON_BIN__/g, () => JSON.stringify(pythonBinValue).slice(1, -1));
2908
2960
  mcpConfigStr = mcpConfigStr.replace(/__GEMINI_API_KEY__/g, () => JSON.stringify(geminiKeyValue).slice(1, -1));
2909
2961
  }
@@ -2939,39 +2991,12 @@ async function installMcpsForTarget(paths, ctx) {
2939
2991
  if (!mcpTemplate.ok) {
2940
2992
  log.warn(`No MCP config was written: the template could not be read. ${configName} left untouched.`);
2941
2993
  } else if (isTomlConfig) {
2942
- const snippetPath = `${paths.mcpConfigPath}.bdb-mcp-servers.toml`;
2943
- const tomlKey = (k) => (/^[A-Za-z0-9_-]+$/.test(k) ? k : JSON.stringify(k));
2944
- const tomlValue = (v) => {
2945
- if (Array.isArray(v)) return `[${v.map(tomlValue).join(', ')}]`;
2946
- if (v && typeof v === 'object') {
2947
- const pairs = Object.entries(v).map(([k, x]) => `${tomlKey(k)} = ${tomlValue(x)}`);
2948
- return `{ ${pairs.join(', ')} }`;
2949
- }
2950
- if (typeof v === 'number' || typeof v === 'boolean') return String(v);
2951
- return JSON.stringify(String(v));
2952
- };
2953
2994
  try {
2954
- const servers = JSON.parse(mcpConfigStr).mcpServers || {};
2955
- const tables = Object.entries(servers).map(([name, cfg]) => {
2956
- const rows = [`[mcp_servers.${tomlKey(name)}]`];
2957
- Object.entries(cfg || {}).forEach(([k, v]) => rows.push(`${tomlKey(k)} = ${tomlValue(v)}`));
2958
- return rows.join('\n');
2959
- });
2960
- const snippet = [
2961
- '# BDB MCP servers for Codex, generated by installer.beta.js.',
2962
- `# Append these tables to ${configName}; if you ran the installer`,
2963
- '# before, replace the [mcp_servers.*] tables of the same name',
2964
- '# instead of adding them a second time.',
2965
- '',
2966
- tables.join('\n\n'),
2967
- ''
2968
- ].join('\n');
2969
- // Snippets can embed injected API keys — keep them user-readable only.
2970
- fs.writeFileSync(snippetPath, snippet, { mode: 0o600 });
2971
- try { fs.chmodSync(snippetPath, 0o600); } catch (e) { logDebug(e, 'chmod snippetPath'); }
2972
- log.warn(`${configName} is TOML; written as snippet instead: ${snippetPath}`);
2995
+ const skipped = mergeCodexTomlMcpServers(paths.mcpConfigPath, JSON.parse(mcpConfigStr).mcpServers || {});
2996
+ log.step(`Merged BDB MCP servers into ${configName}`);
2997
+ if (skipped.length) log.step(`Kept your own entries for: ${skipped.join(', ')}`);
2973
2998
  } catch (e) {
2974
- log.warn(`Could not write the Codex TOML snippet: ${e.message}`);
2999
+ log.warn(`Could not merge MCP servers into ${configName}: ${e.message}`);
2975
3000
  }
2976
3001
  } else if (mode === 'merge' && fs.existsSync(paths.mcpConfigPath) && !existingConfigIsEmpty()) {
2977
3002
  const oldConfig = readJsonFile(paths.mcpConfigPath);
@@ -3583,7 +3608,7 @@ function installGlobalBinaries() {
3583
3608
  }
3584
3609
 
3585
3610
  const isWin = process.platform === 'win32';
3586
- const cliBins = ['aos-config', 'aos-dashboard', 'aos-uninstall'];
3611
+ const cliBins = ['aos-config', 'aos-dashboard', 'aos-uninstall', 'aos-store', 'aos-doctor'];
3587
3612
 
3588
3613
  for (const name of cliBins) {
3589
3614
  const targetMjs = path.join(globalAgentsBin, `${name}.mjs`);
@@ -3626,13 +3651,14 @@ function installGlobalBinaries() {
3626
3651
  // merged result goes to a .bdb-new.json sidecar -- the same recovery pattern
3627
3652
  // the MCP config merge in installMcpsForTarget uses.
3628
3653
  function mergeBdbSettingsHooks(settingsPath, { projectLocal = false } = {}) {
3629
- const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs'];
3654
+ const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'trail-relay.mjs'];
3630
3655
  // memb-inject reads the machine-global memB store under $HOME and is
3631
3656
  // installed once per machine, so it stays $HOME-anchored even inside a
3632
3657
  // project harness -- unlike the two gate hooks, which are per-checkout by
3633
3658
  // design. Pointing it at $CLAUDE_PROJECT_DIR would make it fail on every
3634
- // prompt in any project the harness was never installed into.
3635
- const machineGlobalHooks = ['memb-inject.mjs'];
3659
+ // prompt in any project the harness was never installed into. trail-relay
3660
+ // talks to machine-global live-map daemons, so it is anchored the same way.
3661
+ const machineGlobalHooks = ['memb-inject.mjs', 'trail-relay.mjs'];
3636
3662
  const isBdbEntry = (entry) => {
3637
3663
  const cmds = (entry && Array.isArray(entry.hooks) ? entry.hooks : [])
3638
3664
  .map((h) => (h && typeof h.command === 'string' ? h.command : ''))
@@ -3697,7 +3723,7 @@ function mergeBdbSettingsHooks(settingsPath, { projectLocal = false } = {}) {
3697
3723
  // Merge the BDB hooks into Google Antigravity's hooks.json (.agents/hooks.json or
3698
3724
  // ~/.gemini/config/hooks.json), preserving user-defined foreign hooks.
3699
3725
  function mergeAntigravityHooks(hooksPath, { projectLocal = false } = {}) {
3700
- const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'startcycle-dispatch.mjs'];
3726
+ const bdbHookScripts = ['go-gate.mjs', 'graph-gate.mjs', 'memb-inject.mjs', 'startcycle-dispatch.mjs', 'trail-relay.mjs'];
3701
3727
  const isBdbEntry = (entry) => {
3702
3728
  const cmds = (entry && Array.isArray(entry.hooks) ? entry.hooks : [entry])
3703
3729
  .map((h) => (h && typeof h.command === 'string' ? h.command : (typeof h === 'string' ? h : '')))
@@ -3715,11 +3741,17 @@ function mergeAntigravityHooks(hooksPath, { projectLocal = false } = {}) {
3715
3741
  {
3716
3742
  matcher: "run_command|Bash",
3717
3743
  hooks: [{ type: "command", command: `node "${path.join(hooksDir, 'go-gate.mjs')}"`, timeout: 10000 }]
3744
+ },
3745
+ {
3746
+ hooks: [{ type: "command", command: `node "${path.join(globalHooksDir, 'trail-relay.mjs')}" --agent agy --event PreToolUse`, timeout: 2000 }]
3718
3747
  }
3719
3748
  ],
3720
3749
  Stop: [
3721
3750
  {
3722
3751
  hooks: [{ type: "command", command: `node "${path.join(hooksDir, 'graph-gate.mjs')}"`, timeout: 10000 }]
3752
+ },
3753
+ {
3754
+ hooks: [{ type: "command", command: `node "${path.join(globalHooksDir, 'trail-relay.mjs')}" --agent agy --event Stop`, timeout: 2000 }]
3723
3755
  }
3724
3756
  ],
3725
3757
  PreInvocation: [
@@ -3776,6 +3808,46 @@ function mergeAntigravityHooks(hooksPath, { projectLocal = false } = {}) {
3776
3808
  }
3777
3809
  }
3778
3810
 
3811
+ // Writes the AOS MCP servers into Codex's config.toml between AOS:MCP markers,
3812
+ // replacing the block on re-runs. A server the user already declared outside the
3813
+ // block is skipped: a second [mcp_servers.<name>] table would make the file invalid TOML.
3814
+ function mergeCodexTomlMcpServers(configTomlPath, servers) {
3815
+ const tomlKey = (k) => (/^[A-Za-z0-9_-]+$/.test(k) ? k : JSON.stringify(k));
3816
+ const tomlValue = (v) => {
3817
+ if (Array.isArray(v)) return `[${v.map(tomlValue).join(', ')}]`;
3818
+ if (v && typeof v === 'object') {
3819
+ const pairs = Object.entries(v).map(([k, x]) => `${tomlKey(k)} = ${tomlValue(x)}`);
3820
+ return `{ ${pairs.join(', ')} }`;
3821
+ }
3822
+ if (typeof v === 'number' || typeof v === 'boolean') return String(v);
3823
+ return JSON.stringify(String(v));
3824
+ };
3825
+ let content = fs.existsSync(configTomlPath) ? fs.readFileSync(configTomlPath, 'utf8') : '';
3826
+ const blockRegex = /# AOS:MCP:START[\s\S]*?# AOS:MCP:END\n?/;
3827
+ const outside = content.replace(blockRegex, '');
3828
+ const tables = [];
3829
+ const skipped = [];
3830
+ Object.entries(servers || {}).forEach(([name, cfg]) => {
3831
+ const header = `[mcp_servers.${tomlKey(name)}]`;
3832
+ const headerRegex = new RegExp(`^${header.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*$`, 'm');
3833
+ if (headerRegex.test(outside)) { skipped.push(name); return; }
3834
+ const rows = [header];
3835
+ Object.entries(cfg || {}).forEach(([k, v]) => rows.push(`${tomlKey(k)} = ${tomlValue(v)}`));
3836
+ tables.push(rows.join('\n'));
3837
+ });
3838
+ const block = ['# AOS:MCP:START', tables.join('\n\n'), '# AOS:MCP:END'].join('\n');
3839
+ if (blockRegex.test(content)) {
3840
+ content = content.replace(blockRegex, `${block}\n`);
3841
+ } else if (content.length) {
3842
+ content = `${content.trimEnd()}\n\n${block}\n`;
3843
+ } else {
3844
+ content = `${block}\n`;
3845
+ }
3846
+ fs.writeFileSync(configTomlPath, content, { mode: 0o600 });
3847
+ try { fs.chmodSync(configTomlPath, 0o600); } catch (e) { logDebug(e, 'chmod configTomlPath'); }
3848
+ return skipped;
3849
+ }
3850
+
3779
3851
  // Merge the BDB hooks into ChatGPT Codex CLI's config.toml (~/.codex/config.toml or
3780
3852
  // .codex/config.toml), ensuring [features] hooks = true and preserving existing
3781
3853
  // non-BDB settings, comments, and MCP servers.
@@ -3806,11 +3878,29 @@ function mergeCodexTomlHooks(configTomlPath, { projectLocal = false } = {}) {
3806
3878
  `command = ${JSON.stringify(`node "${path.join(globalHooksDir, 'memb-inject.mjs')}"`)}`,
3807
3879
  'timeout = 30',
3808
3880
  '',
3881
+ '[[hooks.SessionStart]]',
3882
+ '[[hooks.SessionStart.hooks]]',
3883
+ 'type = "command"',
3884
+ `command = ${JSON.stringify(`node "${path.join(globalHooksDir, 'memb-inject.mjs')}"`)}`,
3885
+ 'timeout = 30',
3886
+ '',
3809
3887
  '[[hooks.UserPromptSubmit]]',
3810
3888
  '[[hooks.UserPromptSubmit.hooks]]',
3811
3889
  'type = "command"',
3812
3890
  `command = ${JSON.stringify(`node "${path.join(workflowsDir, 'startcycle-dispatch.mjs')}"`)}`,
3813
3891
  'timeout = 30',
3892
+ '',
3893
+ '[[hooks.PreToolUse]]',
3894
+ '[[hooks.PreToolUse.hooks]]',
3895
+ 'type = "command"',
3896
+ `command = ${JSON.stringify(`node "${path.join(globalHooksDir, 'trail-relay.mjs')}" --agent codex --event PreToolUse`)}`,
3897
+ 'timeout = 2',
3898
+ '',
3899
+ '[[hooks.Stop]]',
3900
+ '[[hooks.Stop.hooks]]',
3901
+ 'type = "command"',
3902
+ `command = ${JSON.stringify(`node "${path.join(globalHooksDir, 'trail-relay.mjs')}" --agent codex --event Stop`)}`,
3903
+ 'timeout = 2',
3814
3904
  '# AOS:HOOKS:END'
3815
3905
  ].join('\n');
3816
3906
 
@@ -3927,6 +4017,9 @@ async function promptMcpSelection(tier) {
3927
4017
  .map(d => d.name);
3928
4018
  } catch (e) { return []; }
3929
4019
 
4020
+ // memb-mcp ships via npm, not as a folder under mcps/, so readdir never lists it.
4021
+ if (!availableMcps.includes(CORE_MCP)) availableMcps.push(CORE_MCP);
4022
+
3930
4023
  if (tier === '2') {
3931
4024
  const basicMcps = ['computer-use-mcp', 'memb-mcp', 'windows-computer-use-mcp'];
3932
4025
  availableMcps = availableMcps.filter(m => basicMcps.includes(m));
@@ -4471,7 +4564,7 @@ async function universalHarnessSync(primaryMcpConfigPath, installedModules = [])
4471
4564
  // OpenCode provider APIs (e.g. OpenAI-compatible, Console) enforce tool name length limits
4472
4565
  // (e.g. max 64 chars) and context limits. Loading 20+ MCPs causes provider errors (e.g. 73-char tool names).
4473
4566
  // OpenCode uses a slim profile: only core servers (memb_mcp, zavora_computer_use) are enabled by default.
4474
- const OPENCODE_DEFAULT_SLIM = new Set(['memb_mcp', 'zavora_computer_use']);
4567
+ const OPENCODE_DEFAULT_SLIM = new Set(['memb_mcp', 'zavora_computer_use', 'deja']);
4475
4568
  const existingMcp = existing && existing.mcp ? existing.mcp : {};
4476
4569
  const hasExistingKeys = Object.keys(existingMcp).length > 0;
4477
4570
 
@@ -4595,6 +4688,14 @@ async function universalHarnessSync(primaryMcpConfigPath, installedModules = [])
4595
4688
  syncMcpConfig(path.join(homeDir, '.aider', 'mcp.json'));
4596
4689
  } else if (d.key === 'opencode') {
4597
4690
  syncOpencodeConfig(path.join(d.path, 'opencode.jsonc'));
4691
+ } else if (d.key === 'codex') {
4692
+ // Universal Sync never had a branch for Codex, so its config.toml
4693
+ // was never updated here even though the log claimed it was.
4694
+ try {
4695
+ mergeCodexTomlMcpServers(path.join(d.path, 'config.toml'), masterMcpData.mcpServers || {});
4696
+ } catch (e) {
4697
+ log.warn(`Failed to sync MCP to ${path.join(d.path, 'config.toml')}: ${e.message}`);
4698
+ }
4598
4699
  }
4599
4700
  }
4600
4701
  log.success('Universal Sync Complete!');
@@ -4708,7 +4809,38 @@ async function runQuickUpdate(installState) {
4708
4809
  }
4709
4810
 
4710
4811
 
4812
+ function buildAoAnnouncementBanner() {
4813
+ return [
4814
+ '\x1b[36m╭──────────────────────────────────────────────────────────────────────────────╮\x1b[0m',
4815
+ '\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
4816
+ '\x1b[36m│\x1b[0m \x1b[1m\x1b[35m🚀 BDB AGENT ORCHESTRATOR APP — FINALE BETA JETZT VERFÜGBAR!\x1b[0m \x1b[36m│\x1b[0m',
4817
+ '\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
4818
+ '\x1b[36m│\x1b[0m Die nächste Generation der Cross-Harness Multi-Agenten-Orchestrierung \x1b[36m│\x1b[0m',
4819
+ '\x1b[36m│\x1b[0m ist jetzt als finale Beta für alle User freigeschaltet. \x1b[36m│\x1b[0m',
4820
+ '\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
4821
+ '\x1b[36m│\x1b[0m • \x1b[1mDashboard & WebUI:\x1b[0m http://localhost:3101 \x1b[36m│\x1b[0m',
4822
+ '\x1b[36m│\x1b[0m • \x1b[1mService-Befehl:\x1b[0m ao service install (Hintergrunddienst aktivieren) \x1b[36m│\x1b[0m',
4823
+ '\x1b[36m│\x1b[0m • \x1b[1mQuick Launch:\x1b[0m ao open oder ao service status \x1b[36m│\x1b[0m',
4824
+ '\x1b[36m│\x1b[0m • \x1b[1mFeatures:\x1b[0m Session-Telemetrie, Live-AgentTrail & Multi-Workspaces\x1b[36m│\x1b[0m',
4825
+ '\x1b[36m│\x1b[0m \x1b[36m│\x1b[0m',
4826
+ '\x1b[36m╰──────────────────────────────────────────────────────────────────────────────╯\x1b[0m\n'
4827
+ ].join('\n');
4828
+ }
4829
+
4711
4830
  async function main() {
4831
+ if (process.argv[2] === 'store') {
4832
+ const storeScript = path.join(srcDir, 'bin', 'aos-store.mjs');
4833
+ const result = spawnSync(process.execPath, [storeScript, ...process.argv.slice(3)], { stdio: 'inherit' });
4834
+ process.exitCode = result.status == null ? 1 : result.status;
4835
+ return;
4836
+ }
4837
+ if (process.argv[2] === 'doctor' || process.argv[2] === 'checkup' || process.argv.includes('--doctor')) {
4838
+ const doctorScript = path.join(srcDir, 'bin', 'aos-doctor.mjs');
4839
+ const doctorArgs = process.argv.slice(process.argv[2] === 'doctor' || process.argv[2] === 'checkup' ? 3 : 2).filter(a => a !== '--doctor');
4840
+ const result = spawnSync(process.execPath, [doctorScript, ...doctorArgs], { stdio: 'inherit' });
4841
+ process.exitCode = result.status == null ? 1 : result.status;
4842
+ return;
4843
+ }
4712
4844
  const skipIntro = isAutoYes || process.argv.includes('--no-intro') || process.argv.includes('--no-animation');
4713
4845
  await renderKineticIntro({ rotations: 1, fps: 12.5, skip: skipIntro, pkgVersion: pkg.version });
4714
4846
  console.log(buildWordmarkBanner());
@@ -4726,6 +4858,7 @@ async function main() {
4726
4858
 
4727
4859
  intro(buildHeroHeader(pkg.version));
4728
4860
  console.log(buildTelemetryCard({ installState, detections, daemonStatus }));
4861
+ console.log(buildAoAnnouncementBanner());
4729
4862
 
4730
4863
  if (DRY_RUN) {
4731
4864
  // Precise on purpose: version comparison still queries the registry, and
@@ -4768,12 +4901,14 @@ async function main() {
4768
4901
  const options = installState.updateAvailable
4769
4902
  ? [
4770
4903
  { value: 'quick', label: `⚡ Quick Update (v${installState.localVersion} ➔ v${installState.currentVersion})`, hint: 'refresh skills, templates & daemons' },
4904
+ { value: 'doctor', label: '🩺 Run System Checkup / Doctor', hint: 'verify environment, placement, daemons & AO' },
4771
4905
  { value: 'project', label: '📁 Drop Local Project Harness', hint: 'copy dispatcher contract to cwd' },
4772
4906
  { value: 'reconfigure', label: '🛠️ Reconfigure System', hint: 'change targets, tier or options' },
4773
4907
  { value: 'uninstall', label: '🗑️ Uninstall AOS', hint: 'remove what this installer placed; your data stays' },
4774
4908
  { value: 'cancel', label: '❌ Exit' }
4775
4909
  ]
4776
4910
  : [
4911
+ { value: 'doctor', label: '🩺 Run System Checkup / Doctor', hint: 'verify environment, placement, daemons & AO' },
4777
4912
  { value: 'project', label: '📁 Drop Local Project Harness', hint: 'copy dispatcher contract to cwd' },
4778
4913
  { value: 'quick', label: '🔄 Verify & Refresh All Skills', hint: 're-sync and health check' },
4779
4914
  { value: 'reconfigure', label: '🛠️ Reconfigure System', hint: 'switch tier or targets' },
@@ -4791,6 +4926,12 @@ async function main() {
4791
4926
  outro('Cancelled.');
4792
4927
  return;
4793
4928
  }
4929
+ if (action === 'doctor') {
4930
+ const doctorScript = path.join(srcDir, 'bin', 'aos-doctor.mjs');
4931
+ spawnSync(process.execPath, [doctorScript], { stdio: 'inherit' });
4932
+ outro('System Checkup complete.');
4933
+ return;
4934
+ }
4794
4935
  if (action === 'project') {
4795
4936
  installProjectHarness();
4796
4937
  outro('Project harness installation complete.');
@@ -5129,9 +5270,12 @@ module.exports = {
5129
5270
  mergeAntigravityHooks,
5130
5271
  mergeCodexTomlHooks,
5131
5272
  mergeCodexHooks: mergeCodexTomlHooks,
5273
+ mergeCodexTomlMcpServers,
5132
5274
  installGlobalHooks,
5133
5275
  installProjectHarness,
5276
+ promptMcpSelection,
5134
5277
  mirrorMcpServersTo,
5278
+ ensureDejaExclude,
5135
5279
  // Manifest store (exported for verification tests)
5136
5280
  computeFileHash,
5137
5281
  getInstallManifestPath,
@@ -0,0 +1,277 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ export const ARCHITECTURE_SPEC_PATH = 'production_artifacts/00_architecture.json';
5
+ export const ARCHITECTURE_HTML_PATH = 'production_artifacts/00_architecture.html';
6
+ export const ARCHITECTURE_STATE_KEY = 'architecture';
7
+ export const ARCHITECTURE_CHECK_COUNT = 9;
8
+ export const RECEIPT_MAX_BYTES = 65536;
9
+ export const LOG_MAX_CHARS = 400;
10
+ export const ARCHIFY_REL_BIN = 'skills/global_config/archify/bin/archify.mjs';
11
+ export const ARCHIFY_TIMEOUT_MS = 120000;
12
+ export const ARCHIFY_MAX_BYTES = 65536;
13
+ export const PLAN_CANVAS_BIN = 'aos-plan-canvas';
14
+ export const PLAN_CANVAS_TIMEOUT_MS = 15000;
15
+ export const PLAN_CANVAS_MAX_BYTES = 16384;
16
+ export const AGENT_TRAIL_BIN = 'aos-trail';
17
+ export const EXECUTION_PLAN_PATH = 'production_artifacts/00_execution_plan.md';
18
+
19
+ const ALLOWED_PATHS = new Set([ARCHITECTURE_SPEC_PATH, ARCHITECTURE_HTML_PATH]);
20
+ const SHA256_RE = /^[a-fA-F0-9]{64}$/;
21
+ const LONG_HEX_RE = /[a-fA-F0-9]{64}/g;
22
+ const HOME_RE = /\/(Users|home)\/[^\s/]+/g;
23
+
24
+ export function isAllowedArchitecturePath(value) {
25
+ if (typeof value !== 'string') return false;
26
+ return ALLOWED_PATHS.has(value);
27
+ }
28
+
29
+ function boundedString(raw, maxBytes) {
30
+ if (typeof raw !== 'string') return { ok: false, value: '' };
31
+ if (Buffer.byteLength(raw, 'utf8') > maxBytes) return { ok: false, value: '' };
32
+ return { ok: true, value: raw };
33
+ }
34
+
35
+ function firstDiagnosticMessage(diagnostics) {
36
+ if (!Array.isArray(diagnostics)) return '';
37
+ for (const entry of diagnostics) {
38
+ if (entry && typeof entry.message === 'string' && entry.message) return entry.message;
39
+ if (entry && typeof entry.code === 'string' && entry.code) return entry.code;
40
+ }
41
+ return '';
42
+ }
43
+
44
+ export function parseDeliverReceipt(raw, options = {}) {
45
+ const maxBytes = Number.isInteger(options.maxBytes) ? options.maxBytes : RECEIPT_MAX_BYTES;
46
+ const bounded = boundedString(raw, maxBytes);
47
+ if (!bounded.ok) {
48
+ return { ok: false, error: 'receipt exceeds bounded size, refusing to parse' };
49
+ }
50
+ let obj = null;
51
+ try {
52
+ obj = JSON.parse(bounded.value);
53
+ } catch {
54
+ return { ok: false, error: 'receipt is not valid JSON' };
55
+ }
56
+ if (!obj || typeof obj !== 'object') {
57
+ return { ok: false, error: 'receipt is not a JSON object' };
58
+ }
59
+ if (obj.ok !== true) {
60
+ const detail = (typeof obj.error === 'string' && obj.error) || firstDiagnosticMessage(obj.diagnostics) || 'archify deliver failed';
61
+ return { ok: false, error: String(detail).slice(0, 300), stage: typeof obj.stage === 'string' ? obj.stage : 'unknown' };
62
+ }
63
+ const validation = obj.validation && typeof obj.validation === 'object' ? obj.validation : null;
64
+ const checksPassed = validation ? validation.checksPassed : undefined;
65
+ const checkCount = validation ? validation.checkCount : undefined;
66
+ const errors = validation ? validation.errors : undefined;
67
+ const artifactSha = obj.artifact && typeof obj.artifact.sha256 === 'string' ? obj.artifact.sha256 : '';
68
+ const specSha = obj.specification && typeof obj.specification.sha256 === 'string' ? obj.specification.sha256 : '';
69
+ if (checksPassed !== checkCount || checkCount !== ARCHITECTURE_CHECK_COUNT || errors !== 0) {
70
+ return { ok: false, error: `deliver receipt incomplete: ${checksPassed}/${checkCount} checks, errors ${errors}` };
71
+ }
72
+ if (!SHA256_RE.test(artifactSha) || !SHA256_RE.test(specSha)) {
73
+ return { ok: false, error: 'deliver receipt missing sha256 evidence' };
74
+ }
75
+ return {
76
+ ok: true,
77
+ checksPassed,
78
+ checkCount,
79
+ errors: 0,
80
+ warnings: typeof validation.warnings === 'number' ? validation.warnings : 0,
81
+ artifactSha256: artifactSha,
82
+ specificationSha256: specSha,
83
+ };
84
+ }
85
+
86
+ export function mergeArchitectureState(state, receipt) {
87
+ const base = state && typeof state === 'object' ? state : {};
88
+ const artifacts = base.artifacts && typeof base.artifacts === 'object' ? { ...base.artifacts } : {};
89
+ if (receipt && receipt.ok === true) {
90
+ artifacts[ARCHITECTURE_STATE_KEY] = ARCHITECTURE_HTML_PATH;
91
+ return { state: { ...base, artifacts }, escalate: null };
92
+ }
93
+ const detail = receipt && typeof receipt.error === 'string' && receipt.error ? receipt.error : 'archify deliver/validate failed';
94
+ return {
95
+ state: { ...base, artifacts },
96
+ escalate: `archify deliver/validate failed: ${String(detail).slice(0, 200)}, previous artifact preserved`,
97
+ };
98
+ }
99
+
100
+ export function buildUrlLine() {
101
+ return `url: ${ARCHITECTURE_HTML_PATH}`;
102
+ }
103
+
104
+ export function planCanvasCommands() {
105
+ return {
106
+ open: `aos-plan-canvas open ${ARCHITECTURE_HTML_PATH}`,
107
+ awaitCmd: `aos-plan-canvas await ${ARCHITECTURE_HTML_PATH}`,
108
+ };
109
+ }
110
+
111
+ export function agentTrailCommand() {
112
+ return 'aos-trail . --plan production_artifacts/00_execution_plan.md --no-open';
113
+ }
114
+
115
+ export function buildPlanCanvasOpenArgs(htmlPath) {
116
+ if (!isAllowedArchitecturePath(htmlPath)) return null;
117
+ if (htmlPath !== ARCHITECTURE_HTML_PATH) return null;
118
+ return ['open', ARCHITECTURE_HTML_PATH, '--no-open'];
119
+ }
120
+
121
+ export function buildAgentTrailArgs() {
122
+ return ['.', '--plan', EXECUTION_PLAN_PATH, '--no-open'];
123
+ }
124
+
125
+ export async function runArchitectureCanvas(options = {}) {
126
+ const cwd = options.cwd;
127
+ const htmlPath = options.htmlPath;
128
+ const exists = options.exists;
129
+ const run = options.run;
130
+ const maxBytes = Number.isInteger(options.maxBytes) ? options.maxBytes : PLAN_CANVAS_MAX_BYTES;
131
+ const timeoutMs = Number.isInteger(options.timeoutMs) ? options.timeoutMs : PLAN_CANVAS_TIMEOUT_MS;
132
+ const args = buildPlanCanvasOpenArgs(htmlPath);
133
+ if (!args || typeof cwd !== 'string' || cwd.length === 0) {
134
+ return { displayed: false, reason: 'plan-canvas rejected untrusted arguments, architecture preserved', architecturePreserved: true };
135
+ }
136
+ if (typeof exists === 'function') {
137
+ let present = false;
138
+ try {
139
+ present = exists(htmlPath);
140
+ } catch {
141
+ present = false;
142
+ }
143
+ if (!present) {
144
+ return { displayed: false, reason: 'architecture artifact missing, canvas skipped', architecturePreserved: true };
145
+ }
146
+ }
147
+ if (typeof run !== 'function') {
148
+ return { displayed: false, reason: 'plan-canvas unavailable, architecture preserved', architecturePreserved: true };
149
+ }
150
+ let res = null;
151
+ try {
152
+ res = await run(args, { cwd, timeoutMs, shell: false });
153
+ } catch (error) {
154
+ return { displayed: false, error: redactForLog(error && error.message ? error.message : 'plan-canvas open failed'), architecturePreserved: true };
155
+ }
156
+ const out = boundedOutputText(res ? res.stdout : '', maxBytes);
157
+ if (!out.ok) {
158
+ return { displayed: false, error: 'plan-canvas output exceeds bounded size', architecturePreserved: true };
159
+ }
160
+ if (!res || res.status !== 0) {
161
+ return { displayed: false, error: redactForLog((res && res.stderr) || 'plan-canvas open failed'), architecturePreserved: true };
162
+ }
163
+ return { displayed: true, architecturePreserved: true };
164
+ }
165
+
166
+ export function redactForLog(value) {
167
+ const text = String(value ?? '');
168
+ const homes = text.replace(HOME_RE, '~');
169
+ const shas = homes.replace(LONG_HEX_RE, (m) => `${m.slice(0, 12)}..`);
170
+ return shas.slice(0, LOG_MAX_CHARS);
171
+ }
172
+
173
+ function isWithin(root, candidate) {
174
+ const relativePath = path.relative(root, candidate);
175
+ return relativePath === '' || (relativePath !== '..' && !relativePath.startsWith(`..${path.sep}`) && !path.isAbsolute(relativePath));
176
+ }
177
+
178
+ export function resolveArchifyBin(cwd) {
179
+ if (typeof cwd !== 'string' || cwd.length === 0) return null;
180
+ try {
181
+ const root = fs.realpathSync(path.resolve(cwd));
182
+ if (!fs.statSync(root).isDirectory()) return null;
183
+ const binaryPath = fs.realpathSync(path.resolve(root, ARCHIFY_REL_BIN));
184
+ if (!isWithin(root, binaryPath) || !fs.statSync(binaryPath).isFile()) return null;
185
+ return binaryPath;
186
+ } catch {
187
+ return null;
188
+ }
189
+ }
190
+
191
+ export function buildValidateArgs(specPath) {
192
+ if (!isAllowedArchitecturePath(specPath)) return null;
193
+ if (specPath !== ARCHITECTURE_SPEC_PATH) return null;
194
+ return ['validate', 'architecture', specPath, '--quality', 'showcase', '--json'];
195
+ }
196
+
197
+ export function buildDeliverArgs(specPath, htmlPath) {
198
+ if (!isAllowedArchitecturePath(specPath) || !isAllowedArchitecturePath(htmlPath)) return null;
199
+ if (specPath !== ARCHITECTURE_SPEC_PATH || htmlPath !== ARCHITECTURE_HTML_PATH) return null;
200
+ return ['deliver', 'architecture', specPath, htmlPath, '--quality', 'showcase', '--json'];
201
+ }
202
+
203
+ function boundedOutputText(value, maxBytes) {
204
+ if (typeof value !== 'string') return { ok: false, text: '' };
205
+ let size = 0;
206
+ try {
207
+ size = Buffer.byteLength(value, 'utf8');
208
+ } catch {
209
+ size = value.length;
210
+ }
211
+ if (size > maxBytes) return { ok: false, text: '' };
212
+ return { ok: true, text: value };
213
+ }
214
+
215
+ function boundaryFailure(stage, detail) {
216
+ return {
217
+ ok: false,
218
+ stage,
219
+ error: redactForLog(String(detail || 'archify boundary step failed')).slice(0, LOG_MAX_CHARS),
220
+ preservePrevious: true,
221
+ };
222
+ }
223
+
224
+ export async function runArchifyBoundary(options = {}) {
225
+ const cwd = options.cwd;
226
+ const specPath = options.specPath;
227
+ const htmlPath = options.htmlPath;
228
+ const run = options.run;
229
+ const maxBytes = Number.isInteger(options.maxBytes) ? options.maxBytes : ARCHIFY_MAX_BYTES;
230
+ const timeoutMs = Number.isInteger(options.timeoutMs) ? options.timeoutMs : ARCHIFY_TIMEOUT_MS;
231
+ const validateArgs = buildValidateArgs(specPath);
232
+ const deliverArgs = buildDeliverArgs(specPath, htmlPath);
233
+ if (!validateArgs || !deliverArgs || typeof cwd !== 'string' || cwd.length === 0) {
234
+ return boundaryFailure('arguments', 'archify boundary rejected untrusted arguments');
235
+ }
236
+ if (typeof run !== 'function') {
237
+ return boundaryFailure('executor', 'archify boundary has no executor in this runtime');
238
+ }
239
+ let validateRes = null;
240
+ try {
241
+ validateRes = await run(validateArgs, { cwd, timeoutMs, shell: false, maxBuffer: maxBytes });
242
+ } catch (error) {
243
+ return boundaryFailure('validate', error && error.message ? error.message : 'archify validate executor failed');
244
+ }
245
+ const validateOut = boundedOutputText(validateRes ? validateRes.stdout : '', maxBytes);
246
+ if (!validateRes || validateRes.status !== 0 || !validateOut.ok) {
247
+ const detail = !validateOut.ok
248
+ ? 'archify validate output exceeds bounded size'
249
+ : (validateRes && validateRes.stderr) || 'archify validate failed';
250
+ return boundaryFailure('validate', detail);
251
+ }
252
+ let deliverRes = null;
253
+ try {
254
+ deliverRes = await run(deliverArgs, { cwd, timeoutMs, shell: false, maxBuffer: maxBytes });
255
+ } catch (error) {
256
+ return boundaryFailure('deliver', error && error.message ? error.message : 'archify deliver executor failed');
257
+ }
258
+ const deliverOut = boundedOutputText(deliverRes ? deliverRes.stdout : '', maxBytes);
259
+ if (!deliverRes || deliverRes.status !== 0 || !deliverOut.ok) {
260
+ const detail = !deliverOut.ok
261
+ ? 'archify deliver output exceeds bounded size'
262
+ : (deliverRes && deliverRes.stderr) || 'archify deliver failed';
263
+ return boundaryFailure('deliver', detail);
264
+ }
265
+ const receipt = parseDeliverReceipt(deliverOut.text, { maxBytes });
266
+ if (!receipt || receipt.ok !== true) {
267
+ return boundaryFailure('deliver', (receipt && receipt.error) || 'archify deliver receipt invalid');
268
+ }
269
+ return {
270
+ ok: true,
271
+ stage: 'deliver',
272
+ validate: { status: 0 },
273
+ deliver: { status: 0 },
274
+ receipt,
275
+ preservePrevious: false,
276
+ };
277
+ }