@open-mercato/cli 0.6.7 → 0.6.8-canary.320.1.bf889f49e4

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 (335) hide show
  1. package/.turbo/turbo-build.log +77 -4
  2. package/AGENTS.md +6 -1
  3. package/build.mjs +68 -11
  4. package/dist/agentic/claude-code/hooks/entity-migration-check.ts +32 -88
  5. package/dist/agentic/codex/enforcement-rules.md +2 -16
  6. package/dist/agentic/cursor/hooks/entity-migration-check.mjs +19 -50
  7. package/dist/agentic/cursor/rules/entity-guard.mdc +9 -21
  8. package/dist/agentic/cursor/rules/generated-guard.mdc +3 -5
  9. package/dist/agentic/cursor/rules/open-mercato.mdc +3 -29
  10. package/dist/agentic/guides/ai-workflows.md +76 -0
  11. package/dist/agentic/guides/architecture.md +107 -0
  12. package/dist/agentic/guides/backend-ui.md +86 -0
  13. package/dist/agentic/guides/contracts.md +92 -0
  14. package/dist/agentic/guides/extensions.md +121 -0
  15. package/dist/agentic/guides/framework-extension-points.md +36 -0
  16. package/dist/agentic/guides/integrations.md +81 -0
  17. package/dist/agentic/guides/module-facts.json +116757 -3951
  18. package/dist/agentic/guides/module-system.md +12 -127
  19. package/dist/agentic/guides/modules/ai_assistant.md +227 -28
  20. package/dist/agentic/guides/modules/api_docs.md +58 -2
  21. package/dist/agentic/guides/modules/api_keys.md +92 -7
  22. package/dist/agentic/guides/modules/attachments.md +119 -14
  23. package/dist/agentic/guides/modules/audit_logs.md +131 -10
  24. package/dist/agentic/guides/modules/auth.md +276 -33
  25. package/dist/agentic/guides/modules/business_rules.md +149 -14
  26. package/dist/agentic/guides/modules/catalog.md +482 -43
  27. package/dist/agentic/guides/modules/channel_gmail.md +82 -3
  28. package/dist/agentic/guides/modules/channel_imap.md +82 -3
  29. package/dist/agentic/guides/modules/checkout.md +305 -27
  30. package/dist/agentic/guides/modules/communication_channels.md +315 -33
  31. package/dist/agentic/guides/modules/configs.md +104 -8
  32. package/dist/agentic/guides/modules/content.md +57 -2
  33. package/dist/agentic/guides/modules/currencies.md +152 -17
  34. package/dist/agentic/guides/modules/customer_accounts.md +387 -45
  35. package/dist/agentic/guides/modules/customers.md +746 -85
  36. package/dist/agentic/guides/modules/dashboards.md +155 -10
  37. package/dist/agentic/guides/modules/data_sync.md +149 -16
  38. package/dist/agentic/guides/modules/design_system.md +102 -0
  39. package/dist/agentic/guides/modules/dictionaries.md +107 -12
  40. package/dist/agentic/guides/modules/directory.md +148 -15
  41. package/dist/agentic/guides/modules/entities.md +145 -13
  42. package/dist/agentic/guides/modules/events.md +59 -2
  43. package/dist/agentic/guides/modules/feature_toggles.md +119 -9
  44. package/dist/agentic/guides/modules/gateway_stripe.md +92 -4
  45. package/dist/agentic/guides/modules/generators.md +45 -2
  46. package/dist/agentic/guides/modules/inbox_ops.md +207 -27
  47. package/dist/agentic/guides/modules/integrations.md +149 -16
  48. package/dist/agentic/guides/modules/messages.md +223 -24
  49. package/dist/agentic/guides/modules/notifications.md +96 -8
  50. package/dist/agentic/guides/modules/onboarding.md +77 -6
  51. package/dist/agentic/guides/modules/payment_gateways.md +168 -21
  52. package/dist/agentic/guides/modules/perspectives.md +77 -7
  53. package/dist/agentic/guides/modules/planner.md +136 -18
  54. package/dist/agentic/guides/modules/portal.md +93 -2
  55. package/dist/agentic/guides/modules/progress.md +104 -14
  56. package/dist/agentic/guides/modules/query_index.md +154 -15
  57. package/dist/agentic/guides/modules/record_locks.md +206 -21
  58. package/dist/agentic/guides/modules/resources.md +197 -30
  59. package/dist/agentic/guides/modules/sales.md +687 -84
  60. package/dist/agentic/guides/modules/scheduler.md +133 -14
  61. package/dist/agentic/guides/modules/search.md +170 -6
  62. package/dist/agentic/guides/modules/security.md +294 -35
  63. package/dist/agentic/guides/modules/shipping_carriers.md +134 -18
  64. package/dist/agentic/guides/modules/sso.md +151 -26
  65. package/dist/agentic/guides/modules/staff.md +372 -57
  66. package/dist/agentic/guides/modules/storage_s3.md +95 -5
  67. package/dist/agentic/guides/modules/sync_akeneo.md +85 -3
  68. package/dist/agentic/guides/modules/sync_excel.md +75 -6
  69. package/dist/agentic/guides/modules/system_status_overlays.md +60 -2
  70. package/dist/agentic/guides/modules/translations.md +104 -10
  71. package/dist/agentic/guides/modules/webhooks.md +203 -24
  72. package/dist/agentic/guides/modules/wms.md +469 -47
  73. package/dist/agentic/guides/modules/workflows.md +302 -43
  74. package/dist/agentic/guides/reference-module-facts.json +6942 -0
  75. package/dist/agentic/guides/reference-modules/example.md +462 -0
  76. package/dist/agentic/guides/spec-delivery.md +56 -0
  77. package/dist/agentic/guides/testing-debugging.md +80 -0
  78. package/dist/agentic/guides/upstream/AGENTS.md +300 -0
  79. package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +334 -0
  80. package/dist/agentic/guides/upstream/manifest.json +8 -0
  81. package/dist/agentic/shared/AGENTS.md.template +120 -311
  82. package/dist/agentic/shared/ai/agentic.config.json +2 -0
  83. package/dist/agentic/shared/ai/harness/README.md +50 -0
  84. package/dist/agentic/shared/ai/harness/RELEASE.md +59 -0
  85. package/dist/agentic/shared/ai/harness/cases.json +20596 -0
  86. package/dist/agentic/shared/ai/harness/cases.schema.json +196 -0
  87. package/dist/agentic/shared/ai/harness/design-system-inventory.json +6326 -0
  88. package/dist/agentic/shared/ai/harness/fixtures/index.json +51 -0
  89. package/dist/agentic/shared/ai/harness/fixtures/seeds.json +166 -0
  90. package/dist/agentic/shared/ai/harness/generated-code-review-policy.md +21 -0
  91. package/dist/agentic/shared/ai/harness/generated-code-review-response.schema.json +96 -0
  92. package/dist/agentic/shared/ai/harness/generated-code-review-result.schema.json +172 -0
  93. package/dist/agentic/shared/ai/harness/knowledge-change.schema.json +228 -0
  94. package/dist/agentic/shared/ai/harness/release-matrix.json +163 -0
  95. package/dist/agentic/shared/ai/harness/release-result.schema.json +219 -0
  96. package/dist/agentic/shared/ai/harness/result.schema.json +136 -0
  97. package/dist/agentic/shared/ai/harness/routing-response.schema.json +22 -0
  98. package/dist/agentic/shared/ai/harness/source-link-inventory.json +1706 -0
  99. package/dist/agentic/shared/ai/harness/target-validation-result.schema.json +73 -0
  100. package/dist/agentic/shared/ai/harness/validators.json +82 -0
  101. package/dist/agentic/shared/ai/harness/writable-ast-oracles.mjs +2121 -0
  102. package/dist/agentic/shared/ai/harness/writable-behavior-oracles.mjs +1096 -0
  103. package/dist/agentic/shared/ai/harness/writable-spec-oracles.mjs +602 -0
  104. package/dist/agentic/shared/ai/lessons/_template.md +16 -0
  105. package/dist/agentic/shared/ai/lessons.md +26 -3
  106. package/dist/agentic/shared/ai/review-checklist.md +36 -0
  107. package/dist/agentic/shared/ai/skills/om-auto-implement-spec/SKILL.md +21 -0
  108. package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +4 -0
  109. package/dist/agentic/shared/ai/skills/om-auto-upgrade-0.6.6-to-0.6.7/SKILL.md +98 -0
  110. package/dist/agentic/shared/ai/skills/om-backend-ui-design/SKILL.md +21 -241
  111. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/crud-surfaces.md +31 -0
  112. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/frontend-and-design-system.md +53 -0
  113. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/page-and-navigation.md +15 -0
  114. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/quality-states.md +11 -0
  115. package/dist/agentic/shared/ai/skills/om-build-workflow/SKILL.md +30 -0
  116. package/dist/agentic/shared/ai/skills/om-build-workflow/references/activity-contracts.md +12 -0
  117. package/dist/agentic/shared/ai/skills/om-build-workflow/references/durability-and-progress.md +13 -0
  118. package/dist/agentic/shared/ai/skills/om-build-workflow/references/workflow-design.md +14 -0
  119. package/dist/agentic/shared/ai/skills/om-create-ai-agent/SKILL.md +28 -0
  120. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/attachments-and-overrides.md +12 -0
  121. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/module-agents-and-tools.md +22 -0
  122. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/orchestrator-agents.md +12 -0
  123. package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/surface-selector.md +19 -0
  124. package/dist/agentic/shared/ai/skills/om-data-model-design/SKILL.md +17 -601
  125. package/dist/agentic/shared/ai/skills/om-data-model-design/references/integrity-and-concurrency.md +21 -0
  126. package/dist/agentic/shared/ai/skills/om-data-model-design/references/migration-workflow.md +15 -0
  127. package/dist/agentic/shared/ai/skills/om-data-model-design/references/schema-design.md +16 -0
  128. package/dist/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +10 -0
  129. package/dist/agentic/shared/ai/skills/om-eject-and-customize/SKILL.md +15 -310
  130. package/dist/agentic/shared/ai/skills/om-eject-and-customize/references/decision-and-procedure.md +19 -0
  131. package/dist/agentic/shared/ai/skills/om-evolve-harness/SKILL.md +31 -0
  132. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-template.md +100 -0
  133. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-workflow.md +16 -0
  134. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/knowledge-change.md +133 -0
  135. package/dist/agentic/shared/ai/skills/om-evolve-harness/references/owner-selection.md +17 -0
  136. package/dist/agentic/shared/ai/skills/om-framework-context/SKILL.md +25 -0
  137. package/dist/agentic/shared/ai/skills/om-framework-context/references/resolver-procedure.md +11 -0
  138. package/dist/agentic/shared/ai/skills/om-framework-context/references/skew-and-escalation.md +13 -0
  139. package/dist/agentic/shared/ai/skills/om-help/SKILL.md +15 -97
  140. package/dist/agentic/shared/ai/skills/om-help/references/delivery-workflows.md +18 -0
  141. package/dist/agentic/shared/ai/skills/om-help/references/task-families.md +20 -0
  142. package/dist/agentic/shared/ai/skills/om-implement-spec/SKILL.md +33 -152
  143. package/dist/agentic/shared/ai/skills/om-implement-spec/references/phases-and-gates.md +33 -0
  144. package/dist/agentic/shared/ai/skills/om-implement-spec/references/planning-and-progress.md +40 -0
  145. package/dist/agentic/shared/ai/skills/om-implement-spec/references/report-templates.md +27 -0
  146. package/dist/agentic/shared/ai/skills/om-implement-spec/references/spec-resolution.md +24 -0
  147. package/dist/agentic/shared/ai/skills/om-integration-builder/SKILL.md +25 -708
  148. package/dist/agentic/shared/ai/skills/om-integration-builder/references/package-and-activation.md +16 -0
  149. package/dist/agentic/shared/ai/skills/om-integration-builder/references/provider-families.md +25 -0
  150. package/dist/agentic/shared/ai/skills/om-integration-builder/references/security-and-reliability.md +15 -0
  151. package/dist/agentic/shared/ai/skills/om-integration-builder/references/sync-and-files.md +12 -0
  152. package/dist/agentic/shared/ai/skills/om-judge-agent-session/SKILL.md +34 -0
  153. package/dist/agentic/shared/ai/skills/om-judge-agent-session/agents/openai.yaml +4 -0
  154. package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/agentic-setup.md +11 -0
  155. package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/input-normalization.md +31 -0
  156. package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/judge-workflow.md +39 -0
  157. package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/report-template.md +43 -0
  158. package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/rules.md +11 -0
  159. package/dist/agentic/shared/ai/skills/om-module-scaffold/SKILL.md +20 -820
  160. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/api-and-domain.md +32 -0
  161. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/business-one-shot-blueprints.md +172 -0
  162. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/data-and-migrations.md +14 -0
  163. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/discovery-surface-catalog.md +83 -0
  164. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/module-surfaces.md +40 -0
  165. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/planning.md +11 -0
  166. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/runtime-cache-and-queues.md +22 -0
  167. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/verification.md +13 -0
  168. package/dist/agentic/shared/ai/skills/om-share-this-session/SKILL.md +41 -0
  169. package/dist/agentic/shared/ai/skills/om-share-this-session/references/agentic-setup.md +19 -0
  170. package/dist/agentic/shared/ai/skills/om-share-this-session/references/bundle-preparation.md +44 -0
  171. package/dist/agentic/shared/ai/skills/om-share-this-session/references/consent-and-review.md +39 -0
  172. package/dist/agentic/shared/ai/skills/om-share-this-session/references/publication.md +20 -0
  173. package/dist/agentic/shared/ai/skills/om-share-this-session/references/report-templates.md +57 -0
  174. package/dist/agentic/shared/ai/skills/om-share-this-session/references/rules.md +11 -0
  175. package/dist/agentic/shared/ai/skills/om-share-this-session/scripts/prepare-share-bundle.mjs +486 -0
  176. package/dist/agentic/shared/ai/skills/om-system-extension/SKILL.md +20 -843
  177. package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-branches.md +42 -0
  178. package/dist/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +27 -0
  179. package/dist/agentic/shared/ai/skills/om-system-extension/references/read-write-roundtrip.md +13 -0
  180. package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +43 -0
  181. package/dist/agentic/shared/ai/skills/om-system-extension/references/verification.md +11 -0
  182. package/dist/agentic/shared/ai/skills/om-trim-unused-modules/SKILL.md +15 -63
  183. package/dist/agentic/shared/ai/skills/om-trim-unused-modules/references/dependency-and-redirect.md +15 -0
  184. package/dist/agentic/shared/ai/skills/om-troubleshooter/SKILL.md +17 -467
  185. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnosis-map.md +29 -0
  186. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/regression-oracles.md +14 -0
  187. package/dist/agentic/shared/ai/skills/tiers.json +143 -21
  188. package/dist/agentic/shared/ai/skills/tiers.schema.json +52 -40
  189. package/dist/agentic/shared/ai/specs/2026-08-06-reference-module-activation.md +248 -0
  190. package/dist/agentic/shared/ai/specs/README.md +4 -3
  191. package/dist/agentic/shared/ai/specs/SPEC-000-template.md +226 -10
  192. package/dist/agentic/shared/ai/trackers/github.md +108 -4
  193. package/dist/agentic/shared/scripts/agent-harness-tool-server.mjs +224 -0
  194. package/dist/agentic/shared/scripts/check-lessons.mjs +178 -0
  195. package/dist/agentic/shared/scripts/evaluate-agent-harness.mjs +3812 -0
  196. package/dist/agentic/shared/scripts/execution-sandbox.mjs +329 -0
  197. package/dist/agentic/shared/scripts/framework-context.mjs +888 -0
  198. package/dist/agentic/shared/scripts/install-skills.mjs +1029 -0
  199. package/dist/agentic/shared/scripts/install-skills.sh +4 -694
  200. package/dist/agentic/shared/scripts/prepare-agent-harness-fixture.mjs +222 -0
  201. package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +1774 -0
  202. package/dist/agentic/shared/scripts/validate-knowledge-change.mjs +1172 -0
  203. package/dist/bin.js +32 -34
  204. package/dist/bin.js.map +2 -2
  205. package/dist/lib/__integration__/TC-INT-008.spec.js +88 -8
  206. package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
  207. package/dist/lib/agentic-init.js +13 -3
  208. package/dist/lib/agentic-init.js.map +2 -2
  209. package/dist/lib/agentic-setup.js +434 -186
  210. package/dist/lib/agentic-setup.js.map +2 -2
  211. package/dist/lib/cli-bootstrap-mode.js +32 -0
  212. package/dist/lib/cli-bootstrap-mode.js.map +7 -0
  213. package/dist/lib/dev-supervisor-manifest.js +105 -0
  214. package/dist/lib/dev-supervisor-manifest.js.map +7 -0
  215. package/dist/lib/generate-watch-events.js +15 -0
  216. package/dist/lib/generate-watch-events.js.map +2 -2
  217. package/dist/lib/generators/entity-ids.js +11 -24
  218. package/dist/lib/generators/entity-ids.js.map +2 -2
  219. package/dist/lib/generators/extensions/injection-widgets.js +20 -0
  220. package/dist/lib/generators/extensions/injection-widgets.js.map +2 -2
  221. package/dist/lib/generators/module-di.js +10 -23
  222. package/dist/lib/generators/module-di.js.map +2 -2
  223. package/dist/lib/generators/module-entities.js +10 -23
  224. package/dist/lib/generators/module-entities.js.map +2 -2
  225. package/dist/lib/generators/module-extension-facts.js +1882 -0
  226. package/dist/lib/generators/module-extension-facts.js.map +7 -0
  227. package/dist/lib/generators/module-fact-sources.js +70 -0
  228. package/dist/lib/generators/module-fact-sources.js.map +7 -0
  229. package/dist/lib/generators/module-facts-discovery.js +64 -7
  230. package/dist/lib/generators/module-facts-discovery.js.map +2 -2
  231. package/dist/lib/generators/module-facts.js +1913 -52
  232. package/dist/lib/generators/module-facts.js.map +3 -3
  233. package/dist/lib/generators/module-override-targets.js +712 -0
  234. package/dist/lib/generators/module-override-targets.js.map +7 -0
  235. package/dist/lib/generators/module-registry.js +405 -36
  236. package/dist/lib/generators/module-registry.js.map +2 -2
  237. package/dist/lib/generators/route-manifest-shards.js +170 -0
  238. package/dist/lib/generators/route-manifest-shards.js.map +7 -0
  239. package/dist/lib/in-process-generate-watcher.js +12 -3
  240. package/dist/lib/in-process-generate-watcher.js.map +2 -2
  241. package/dist/lib/load-env.js +24 -0
  242. package/dist/lib/load-env.js.map +7 -0
  243. package/dist/lib/queue-worker-supervisor.js.map +2 -2
  244. package/dist/lib/resolver.js +28 -3
  245. package/dist/lib/resolver.js.map +2 -2
  246. package/dist/lib/telemetry-init.js +358 -0
  247. package/dist/lib/telemetry-init.js.map +7 -0
  248. package/dist/lib/testing/integration.js +5 -2
  249. package/dist/lib/testing/integration.js.map +2 -2
  250. package/dist/lib/utils.js +15 -8
  251. package/dist/lib/utils.js.map +2 -2
  252. package/dist/mercato.js +35 -9
  253. package/dist/mercato.js.map +2 -2
  254. package/package.json +13 -11
  255. package/src/__tests__/mercato.test.ts +144 -0
  256. package/src/bin.ts +60 -42
  257. package/src/lib/__integration__/TC-INT-008.spec.ts +107 -9
  258. package/src/lib/__tests__/agentic-init.test.ts +41 -5
  259. package/src/lib/__tests__/agentic-setup.ownership.test.ts +386 -0
  260. package/src/lib/__tests__/cli-bootstrap-mode.test.ts +22 -0
  261. package/src/lib/__tests__/content-stable-writes.test.ts +74 -0
  262. package/src/lib/__tests__/dev-supervisor-manifest.test.ts +131 -0
  263. package/src/lib/__tests__/generate-watch-events.test.ts +76 -0
  264. package/src/lib/__tests__/in-process-generate-watcher.test.ts +52 -1
  265. package/src/lib/__tests__/injection-widget-id-validation.test.ts +184 -0
  266. package/src/lib/__tests__/load-env.test.ts +65 -0
  267. package/src/lib/__tests__/queue-worker-supervisor.test.ts +33 -0
  268. package/src/lib/__tests__/resolver.enterprise.test.ts +50 -0
  269. package/src/lib/__tests__/telemetry-init.test.ts +298 -0
  270. package/src/lib/agentic-init.ts +15 -3
  271. package/src/lib/agentic-setup.ts +573 -222
  272. package/src/lib/cli-bootstrap-mode.ts +31 -0
  273. package/src/lib/dev-supervisor-manifest.ts +142 -0
  274. package/src/lib/generate-watch-events.ts +14 -0
  275. package/src/lib/generators/__tests__/activation-adapter-coverage.test.ts +92 -0
  276. package/src/lib/generators/__tests__/entity-ids.test.ts +32 -0
  277. package/src/lib/generators/__tests__/helpers/override-target-diagnostic-fixtures.ts +150 -0
  278. package/src/lib/generators/__tests__/module-extension-activations.test.ts +762 -0
  279. package/src/lib/generators/__tests__/module-extension-facts.test.ts +603 -0
  280. package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +139 -2
  281. package/src/lib/generators/__tests__/module-facts.computed-di-token.test.ts +88 -0
  282. package/src/lib/generators/__tests__/module-facts.customers.fixture.test.ts +1 -0
  283. package/src/lib/generators/__tests__/module-facts.discovery.test.ts +54 -10
  284. package/src/lib/generators/__tests__/module-facts.example-fact-coverage.test.ts +414 -0
  285. package/src/lib/generators/__tests__/module-facts.extension-hosts.test.ts +108 -0
  286. package/src/lib/generators/__tests__/module-facts.local-reference.test.ts +393 -0
  287. package/src/lib/generators/__tests__/module-facts.owned-contracts.test.ts +561 -0
  288. package/src/lib/generators/__tests__/module-facts.search-entity-id.test.ts +151 -0
  289. package/src/lib/generators/__tests__/module-facts.source-links.test.ts +160 -0
  290. package/src/lib/generators/__tests__/module-override-targets.diagnostic-wiring.test.ts +92 -0
  291. package/src/lib/generators/__tests__/module-override-targets.roundtrip.test.ts +149 -0
  292. package/src/lib/generators/__tests__/module-override-targets.test.ts +328 -0
  293. package/src/lib/generators/__tests__/module-override-targets.unknown-mode.test.ts +117 -0
  294. package/src/lib/generators/__tests__/module-subset.test.ts +266 -0
  295. package/src/lib/generators/__tests__/output-snapshots.test.ts +3 -3
  296. package/src/lib/generators/__tests__/route-manifest-shards.test.ts +62 -0
  297. package/src/lib/generators/entity-ids.ts +10 -26
  298. package/src/lib/generators/extensions/injection-widgets.ts +51 -0
  299. package/src/lib/generators/module-di.ts +9 -25
  300. package/src/lib/generators/module-entities.ts +9 -25
  301. package/src/lib/generators/module-extension-facts.ts +2472 -0
  302. package/src/lib/generators/module-fact-sources.ts +108 -0
  303. package/src/lib/generators/module-facts-discovery.ts +104 -7
  304. package/src/lib/generators/module-facts.ts +2747 -138
  305. package/src/lib/generators/module-override-targets.ts +907 -0
  306. package/src/lib/generators/module-registry.ts +448 -35
  307. package/src/lib/generators/route-manifest-shards.ts +146 -0
  308. package/src/lib/in-process-generate-watcher.ts +13 -4
  309. package/src/lib/load-env.ts +30 -0
  310. package/src/lib/queue-worker-supervisor.ts +7 -2
  311. package/src/lib/resolver.ts +34 -3
  312. package/src/lib/telemetry-init.ts +461 -0
  313. package/src/lib/testing/__tests__/integration.test.ts +4 -0
  314. package/src/lib/testing/integration.ts +5 -2
  315. package/src/lib/utils.ts +24 -16
  316. package/src/mercato.ts +46 -9
  317. package/dist/agentic/guides/cache.md +0 -45
  318. package/dist/agentic/guides/core.md +0 -453
  319. package/dist/agentic/guides/events.md +0 -117
  320. package/dist/agentic/guides/queue.md +0 -53
  321. package/dist/agentic/guides/search.md +0 -115
  322. package/dist/agentic/guides/shared.md +0 -108
  323. package/dist/agentic/guides/ui.md +0 -347
  324. package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +0 -27
  325. package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +0 -27
  326. package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/ui-components.md +0 -260
  327. package/dist/agentic/shared/ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md +0 -146
  328. package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +0 -84
  329. package/dist/agentic/shared/ai/skills/om-help/references/workflow-sequences.md +0 -193
  330. package/dist/agentic/shared/ai/skills/om-integration-builder/STANDALONE.md +0 -34
  331. package/dist/agentic/shared/ai/skills/om-integration-builder/references/adapter-contracts.md +0 -762
  332. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/naming-conventions.md +0 -50
  333. package/dist/agentic/shared/ai/skills/om-module-scaffold/references/navigation-patterns.md +0 -97
  334. package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-contracts.md +0 -271
  335. package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnostic-commands.md +0 -101
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/cli",
3
- "version": "0.6.7",
3
+ "version": "0.6.8-canary.320.1.bf889f49e4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -56,12 +56,13 @@
56
56
  "node": "24.x"
57
57
  },
58
58
  "dependencies": {
59
- "@mikro-orm/core": "^7.1.5",
60
- "@mikro-orm/decorators": "^7.1.5",
61
- "@mikro-orm/migrations": "^7.1.5",
62
- "@mikro-orm/postgresql": "^7.1.5",
63
- "@open-mercato/queue": "0.6.7",
64
- "@open-mercato/shared": "0.6.7",
59
+ "@mikro-orm/core": "^7.1.8",
60
+ "@mikro-orm/decorators": "^7.1.8",
61
+ "@mikro-orm/migrations": "^7.1.8",
62
+ "@mikro-orm/postgresql": "^7.1.8",
63
+ "@open-mercato/queue": "0.6.8-canary.320.1.bf889f49e4",
64
+ "@open-mercato/shared": "0.6.8-canary.320.1.bf889f49e4",
65
+ "@open-mercato/telemetry": "0.6.8-canary.320.1.bf889f49e4",
65
66
  "cross-spawn": "^7.0.6",
66
67
  "pg": "8.22.0",
67
68
  "semver": "^7.8.5",
@@ -72,13 +73,13 @@
72
73
  "typescript-js": "npm:typescript@6.0.3"
73
74
  },
74
75
  "peerDependencies": {
75
- "@open-mercato/shared": "0.6.7"
76
+ "@open-mercato/shared": "0.6.8-canary.320.1.bf889f49e4"
76
77
  },
77
78
  "devDependencies": {
78
- "@open-mercato/shared": "0.6.7",
79
+ "@open-mercato/shared": "0.6.8-canary.320.1.bf889f49e4",
79
80
  "@types/jest": "^30.0.0",
80
81
  "jest": "^30.4.2",
81
- "ts-jest": "^29.4.11"
82
+ "ts-jest": "^29.4.12"
82
83
  },
83
84
  "publishConfig": {
84
85
  "access": "public"
@@ -87,5 +88,6 @@
87
88
  "type": "git",
88
89
  "url": "https://github.com/open-mercato/open-mercato",
89
90
  "directory": "packages/cli"
90
- }
91
+ },
92
+ "stableVersion": "0.6.7"
91
93
  }
@@ -716,6 +716,7 @@ describe('generate post-step structural invalidation', () => {
716
716
  consoleErrorSpy.mockRestore()
717
717
  consoleLogSpy.mockRestore()
718
718
  })
719
+
719
720
  })
720
721
 
721
722
  describe('server dev managed process exits', () => {
@@ -1263,6 +1264,86 @@ describe('server dev managed process exits', () => {
1263
1264
  consoleLogSpy.mockRestore()
1264
1265
  })
1265
1266
 
1267
+ it('uses lightweight manifest workers instead of handler-bearing CLI modules', async () => {
1268
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
1269
+ const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
1270
+ process.env.OM_AUTO_SPAWN_WORKERS_LAZY = 'true'
1271
+ process.env.OM_AUTO_SPAWN_WORKERS_LAZY_MODE = 'shared'
1272
+
1273
+ jest.doMock('node:fs', () => {
1274
+ const actual = jest.requireActual('node:fs')
1275
+ return {
1276
+ ...actual,
1277
+ existsSync: jest.fn((candidate: string) =>
1278
+ pathIncludes(candidate, 'next/dist/bin/next') || pathIncludes(candidate, '@open-mercato/cli/bin/mercato'),
1279
+ ),
1280
+ unlinkSync: jest.fn(),
1281
+ }
1282
+ })
1283
+ jest.doMock('../lib/generators', () => ({
1284
+ generateModulePackageSources: jest.fn().mockResolvedValue(undefined),
1285
+ }))
1286
+ jest.doMock('../lib/resolver', () => ({
1287
+ resolveEnvironment: () => ({
1288
+ appDir: '/tmp/test-app',
1289
+ rootDir: '/tmp/test-root',
1290
+ }),
1291
+ createResolver: () => ({}),
1292
+ }))
1293
+
1294
+ const supervisorClose = jest.fn().mockResolvedValue(undefined)
1295
+ const startLazyWorkerSupervisor = jest.fn(() => ({
1296
+ startedQueues: new Set<string>(),
1297
+ getActiveChild: () => undefined,
1298
+ close: supervisorClose,
1299
+ done: Promise.resolve(),
1300
+ }))
1301
+ jest.doMock('../lib/queue-worker-supervisor', () => ({
1302
+ startLazyWorkerSupervisor,
1303
+ }))
1304
+ jest.doMock('child_process', () =>
1305
+ buildMockChildProcessModule((args) =>
1306
+ pathIncludes(args[0] ?? '', 'next/dist/bin/next') ? { code: null, signal: 'SIGTERM' } : undefined,
1307
+ ),
1308
+ )
1309
+
1310
+ const manifestRegistry = await import('../lib/dev-supervisor-manifest')
1311
+ manifestRegistry.registerDevSupervisorManifest({
1312
+ version: 1,
1313
+ workers: [
1314
+ {
1315
+ id: 'manifest:worker',
1316
+ moduleId: 'manifest',
1317
+ queue: 'manifest-events',
1318
+ concurrency: 1,
1319
+ },
1320
+ ],
1321
+ schedulerStartStatus: 'missing-module',
1322
+ requiresFullBootstrap: false,
1323
+ })
1324
+ const mercato = await import('../mercato')
1325
+ mercato.registerCliModules([eventsWorkerFixture as Module])
1326
+
1327
+ const exitCode = await mercato.run(['node', 'mercato', 'server', 'dev'])
1328
+
1329
+ expect(exitCode).toBe(0)
1330
+ expect(startLazyWorkerSupervisor).toHaveBeenCalledTimes(1)
1331
+ const workers = startLazyWorkerSupervisor.mock.calls[0][0].workers
1332
+ expect(workers).toEqual([
1333
+ {
1334
+ id: 'manifest:worker',
1335
+ moduleId: 'manifest',
1336
+ queue: 'manifest-events',
1337
+ concurrency: 1,
1338
+ },
1339
+ ])
1340
+ expect(workers[0]).not.toHaveProperty('handler')
1341
+ expect(supervisorClose).toHaveBeenCalled()
1342
+
1343
+ consoleErrorSpy.mockRestore()
1344
+ consoleLogSpy.mockRestore()
1345
+ })
1346
+
1266
1347
  it('starts the lazy scheduler supervisor instead of the scheduler process when OM_AUTO_SPAWN_SCHEDULER_LAZY=true', async () => {
1267
1348
  const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
1268
1349
  const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
@@ -1328,6 +1409,69 @@ describe('server dev managed process exits', () => {
1328
1409
  consoleErrorSpy.mockRestore()
1329
1410
  consoleLogSpy.mockRestore()
1330
1411
  })
1412
+
1413
+ it('uses the lightweight manifest scheduler status without loading scheduler CLI modules', async () => {
1414
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
1415
+ const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
1416
+ process.env.AUTO_SPAWN_SCHEDULER = 'true'
1417
+ process.env.AUTO_SPAWN_WORKERS = 'false'
1418
+ process.env.OM_AUTO_SPAWN_SCHEDULER_LAZY = 'true'
1419
+
1420
+ jest.doMock('node:fs', () => {
1421
+ const actual = jest.requireActual('node:fs')
1422
+ return {
1423
+ ...actual,
1424
+ existsSync: jest.fn((candidate: string) =>
1425
+ pathIncludes(candidate, 'next/dist/bin/next') || pathIncludes(candidate, '@open-mercato/cli/bin/mercato'),
1426
+ ),
1427
+ unlinkSync: jest.fn(),
1428
+ }
1429
+ })
1430
+ jest.doMock('../lib/generators', () => ({
1431
+ generateModulePackageSources: jest.fn().mockResolvedValue(undefined),
1432
+ }))
1433
+ jest.doMock('../lib/resolver', () => ({
1434
+ resolveEnvironment: () => ({
1435
+ appDir: '/tmp/test-app',
1436
+ rootDir: '/tmp/test-root',
1437
+ }),
1438
+ createResolver: () => ({}),
1439
+ }))
1440
+
1441
+ const schedulerClose = jest.fn().mockResolvedValue(undefined)
1442
+ const startLazySchedulerSupervisor = jest.fn(() => ({
1443
+ started: false,
1444
+ getActiveChild: () => undefined,
1445
+ close: schedulerClose,
1446
+ done: Promise.resolve(),
1447
+ }))
1448
+ jest.doMock('../lib/scheduler-supervisor', () => ({
1449
+ startLazySchedulerSupervisor,
1450
+ }))
1451
+ jest.doMock('child_process', () =>
1452
+ buildMockChildProcessModule((args) =>
1453
+ pathIncludes(args[0] ?? '', 'next/dist/bin/next') ? { code: null, signal: 'SIGTERM' } : undefined,
1454
+ ),
1455
+ )
1456
+
1457
+ const manifestRegistry = await import('../lib/dev-supervisor-manifest')
1458
+ manifestRegistry.registerDevSupervisorManifest({
1459
+ version: 1,
1460
+ workers: [],
1461
+ schedulerStartStatus: 'ok',
1462
+ requiresFullBootstrap: false,
1463
+ })
1464
+ const mercato = await import('../mercato')
1465
+
1466
+ const exitCode = await mercato.run(['node', 'mercato', 'server', 'dev'])
1467
+
1468
+ expect(exitCode).toBe(0)
1469
+ expect(startLazySchedulerSupervisor).toHaveBeenCalledTimes(1)
1470
+ expect(schedulerClose).toHaveBeenCalled()
1471
+
1472
+ consoleErrorSpy.mockRestore()
1473
+ consoleLogSpy.mockRestore()
1474
+ })
1331
1475
  })
1332
1476
 
1333
1477
  describe('server start managed process exits', () => {
package/src/bin.ts CHANGED
@@ -4,34 +4,13 @@
4
4
  * Called from within a Next.js app directory as: yarn mercato <command>
5
5
  * Uses dynamic app resolution to find generated files at .mercato/generated/
6
6
  */
7
- import { run } from './mercato.js'
8
-
9
- // Commands that can run without bootstrap (without generated files)
10
- // - generate: creates the generated files
11
- // - db: uses resolver directly to find modules and migrations
12
- // - init: runs yarn commands to set up the app
13
- // - help: just shows help text
14
- const BOOTSTRAP_FREE_COMMANDS = [
15
- 'generate',
16
- 'module',
17
- 'deploy',
18
- 'db',
19
- 'init',
20
- 'agentic:init',
21
- 'eject',
22
- 'test',
23
- 'test:integration',
24
- 'test:integration:coverage',
25
- 'test:integration:spec-coverage',
26
- 'test:ephemeral',
27
- 'test:integration:interactive',
28
- 'umes:list',
29
- 'umes:inspect',
30
- 'umes:check',
31
- 'help',
32
- '--help',
33
- '-h',
34
- ]
7
+ import {
8
+ getTelemetryRuntime,
9
+ isTelemetryBackendEnabled,
10
+ } from '@open-mercato/shared/lib/telemetry/runtime'
11
+ import { resolveCliBootstrapMode, type CliBootstrapMode } from './lib/cli-bootstrap-mode.js'
12
+ // `run` is imported dynamically inside `main()` so telemetry can initialize
13
+ // before the mercato entry (and its Postgres driver) loads — see main().
35
14
 
36
15
  function assertNode24Runtime(): void {
37
16
  const detectedNodeVersion = process.versions.node
@@ -48,20 +27,30 @@ function assertNode24Runtime(): void {
48
27
  )
49
28
  }
50
29
 
51
- function needsBootstrap(argv: string[]): boolean {
52
- const [, , first] = argv
53
- if (!first) return false // help screen
54
- return !BOOTSTRAP_FREE_COMMANDS.includes(first)
55
- }
56
-
57
- async function tryBootstrap(): Promise<boolean> {
30
+ async function tryBootstrap(mode: Exclude<CliBootstrapMode, 'none'>): Promise<boolean> {
58
31
  try {
59
- const { bootstrapFromAppRoot } = await import('@open-mercato/shared/lib/bootstrap/dynamicLoader')
60
- const { registerCliModules } = await import('./mercato.js')
61
32
  // Use the CLI resolver to find the app directory (handles monorepo detection)
62
33
  const { createResolver } = await import('./lib/resolver.js')
63
34
  const resolver = createResolver()
64
35
  const appDir = resolver.getAppDir()
36
+
37
+ if (mode === 'dev-supervisor') {
38
+ const {
39
+ canUseLightweightDevSupervisor,
40
+ loadDevSupervisorManifest,
41
+ registerDevSupervisorManifest,
42
+ } = await import(
43
+ './lib/dev-supervisor-manifest.js'
44
+ )
45
+ const manifest = loadDevSupervisorManifest(appDir)
46
+ if (canUseLightweightDevSupervisor(manifest)) {
47
+ registerDevSupervisorManifest(manifest)
48
+ return true
49
+ }
50
+ }
51
+
52
+ const { bootstrapFromAppRoot } = await import('@open-mercato/shared/lib/bootstrap/dynamicLoader')
53
+ const { registerCliModules } = await import('./mercato.js')
65
54
  const data = await bootstrapFromAppRoot(appDir)
66
55
  // Register CLI modules directly to avoid module resolution issues
67
56
  registerCliModules(data.modules)
@@ -70,8 +59,11 @@ async function tryBootstrap(): Promise<boolean> {
70
59
  const message = err instanceof Error ? err.message : String(err)
71
60
  // Check if the error is about missing generated files
72
61
  if (
73
- message.includes('Cannot find module') &&
74
- (message.includes('/generated/') || message.includes('.generated') || message.includes('.mercato'))
62
+ message.includes('dev-supervisor.generated.json') ||
63
+ (
64
+ message.includes('Cannot find module') &&
65
+ (message.includes('/generated/') || message.includes('.generated') || message.includes('.mercato'))
66
+ )
75
67
  ) {
76
68
  return false
77
69
  }
@@ -82,10 +74,30 @@ async function tryBootstrap(): Promise<boolean> {
82
74
 
83
75
  async function main(): Promise<void> {
84
76
  assertNode24Runtime()
85
- const requiresBootstrap = needsBootstrap(process.argv)
77
+ const bootstrapMode = resolveCliBootstrapMode(process.argv)
78
+
79
+ if (bootstrapMode !== 'none') {
80
+ // Load the app's `.env` BEFORE initTelemetry(): `run()` only dotenv-loads it
81
+ // later (ensureEnvLoaded), which is too late — TELEMETRY_BACKEND set only in
82
+ // `.env` would silently resolve to `noop` for worker/scheduler processes.
83
+ // The loader touches only the resolver + dotenv (no `pg`), preserving the
84
+ // instrumentation load-order guarantee below.
85
+ const { loadAppEnv } = await import('./lib/load-env.js')
86
+ await loadAppEnv()
87
+
88
+ // Initialize telemetry BEFORE bootstrapping the app graph. Bootstrap and the
89
+ // per-command handlers load MikroORM's Postgres driver → `pg`, and the
90
+ // OpenTelemetry pg/undici auto-instrumentation only records spans for a
91
+ // driver required AFTER the SDK has started. Registering here — ahead of any
92
+ // app module — is what lets long-running worker/scheduler processes emit DB
93
+ // spans (not just the bullmq-otel add/process envelope). The package itself
94
+ // is not imported unless an explicit supported backend is selected.
95
+ if (isTelemetryBackendEnabled()) {
96
+ const { initTelemetry } = await import('@open-mercato/telemetry')
97
+ await initTelemetry()
98
+ }
86
99
 
87
- if (requiresBootstrap) {
88
- const bootstrapSucceeded = await tryBootstrap()
100
+ const bootstrapSucceeded = await tryBootstrap(bootstrapMode)
89
101
  if (!bootstrapSucceeded) {
90
102
  console.error('╔═══════════════════════════════════════════════════════════════════╗')
91
103
  console.error('║ Generated files not found! ║')
@@ -100,7 +112,13 @@ async function main(): Promise<void> {
100
112
  }
101
113
  }
102
114
 
115
+ // Dynamic import (not a top-level static import) so the mercato entry — and the
116
+ // Postgres driver it pulls in — loads only after initTelemetry() above.
117
+ const { run } = await import('./mercato.js')
103
118
  const code = await run(process.argv)
119
+ // Flush spans/logs for commands that return (workers block forever and flush via
120
+ // their own shutdown handler instead).
121
+ await getTelemetryRuntime()?.shutdown()
104
122
  process.exit(code ?? 0)
105
123
  }
106
124
 
@@ -14,6 +14,8 @@ const cliIntegrationRunnerPath = path.join(cliDir, 'src', 'lib', 'testing', 'int
14
14
  const standaloneTemplatePackageJsonPath = path.join(repoRoot, 'packages', 'create-app', 'template', 'package.json.template')
15
15
  const agenticRoot = path.join(repoRoot, 'packages', 'create-app', 'agentic')
16
16
  const packagesRoot = path.join(repoRoot, 'packages')
17
+ const coreVersion = JSON.parse(fs.readFileSync(path.join(packagesRoot, 'core', 'package.json'), 'utf8')).version as string
18
+ const UNROUTED_PACKAGE_GUIDES = new Set(['cache', 'core', 'events', 'queue', 'search', 'shared', 'ui'])
17
19
 
18
20
  // Modules the standalone fixture enables in src/modules.ts. Both are on the
19
21
  // fact-sheet allowlist, so agentic:init must ship exactly their fact-sheets
@@ -24,7 +26,7 @@ function normalizePath(value: string): string {
24
26
  return value.split(path.sep).join('/')
25
27
  }
26
28
 
27
- function runCommand(command: string, args: string[], cwd: string): string {
29
+ function runCommand(command: string, args: string[], cwd: string, env: NodeJS.ProcessEnv = {}): string {
28
30
  return execFileSync(command, args, {
29
31
  cwd,
30
32
  encoding: 'utf8',
@@ -36,6 +38,7 @@ function runCommand(command: string, args: string[], cwd: string): string {
36
38
  // whose external step (`npx skills add`) needs the network. Local tier
37
39
  // symlinks are still installed.
38
40
  OM_SKIP_EXTERNAL_SKILLS: '1',
41
+ ...env,
39
42
  },
40
43
  })
41
44
  }
@@ -61,16 +64,48 @@ function createStandaloneFixture(rootDir: string): string {
61
64
  {
62
65
  name: 'sample-store',
63
66
  private: true,
67
+ dependencies: { '@open-mercato/core': coreVersion },
64
68
  },
65
69
  null,
66
70
  2,
67
71
  ),
68
72
  )
69
- const moduleEntries = FIXTURE_ENABLED_MODULES.map((moduleId) => ` { id: '${moduleId}' },`).join('\n')
73
+ const moduleEntries = FIXTURE_ENABLED_MODULES
74
+ .map((moduleId) => ` { id: '${moduleId}', from: '@open-mercato/core' },`)
75
+ .join('\n')
70
76
  writeFile(path.join(appDir, 'src', 'modules.ts'), `export const enabledModules = [\n${moduleEntries}\n]\n`)
71
77
  return appDir
72
78
  }
73
79
 
80
+ function installFakeFrameworkPackage(appDir: string): string {
81
+ const packageRoot = path.join(appDir, 'node_modules', '@open-mercato', 'core')
82
+ writeFile(path.join(packageRoot, 'package.json'), JSON.stringify({
83
+ name: '@open-mercato/core',
84
+ version: coreVersion,
85
+ type: 'module',
86
+ exports: { '.': './dist/index.js' },
87
+ }))
88
+ writeFile(path.join(packageRoot, 'dist', 'index.js'), 'export {}\n')
89
+ writeFile(path.join(packageRoot, 'AGENTS.md'), '# Installed core instructions\n')
90
+ for (const moduleId of FIXTURE_ENABLED_MODULES) {
91
+ writeFile(path.join(packageRoot, 'src', 'modules', moduleId, 'AGENTS.md'), `# Installed ${moduleId} instructions\n`)
92
+ writeFile(
93
+ path.join(packageRoot, 'src', 'modules', moduleId, 'data', 'entities.ts'),
94
+ `export class ${moduleId === 'customers' ? 'Person' : 'Sale'} {}\n`,
95
+ )
96
+ }
97
+ return packageRoot
98
+ }
99
+
100
+ function snapshotTextFiles(rootDir: string): Record<string, string> {
101
+ return Object.fromEntries(
102
+ listRelativeFiles(rootDir).map((relativePath) => [
103
+ relativePath,
104
+ fs.readFileSync(path.join(rootDir, relativePath), 'utf8'),
105
+ ]),
106
+ )
107
+ }
108
+
74
109
  function listRelativeFiles(rootDir: string): string[] {
75
110
  if (!fs.existsSync(rootDir)) {
76
111
  return []
@@ -194,7 +229,7 @@ function expectedGuideOutputNames(): string[] {
194
229
 
195
230
  for (const packageName of fs.readdirSync(packagesRoot)) {
196
231
  const packageGuide = path.join(packagesRoot, packageName, 'agentic', 'standalone-guide.md')
197
- if (fs.existsSync(packageGuide)) {
232
+ if (fs.existsSync(packageGuide) && !UNROUTED_PACKAGE_GUIDES.has(packageName)) {
198
233
  collected.add(`${packageName}.md`)
199
234
  }
200
235
 
@@ -214,8 +249,14 @@ function expectedGuideOutputNames(): string[] {
214
249
  // Generated fact-sheet artifacts (spec 2026-06-27-ts-morph-module-fact-sheets):
215
250
  // the module-facts.json sidecar is copied as-is and fact-sheets are filtered to the
216
251
  // fixture's enabled modules. The legacy core.<module>.md redirect stubs are no longer
217
- // emitted (#3754).
252
+ // emitted (#3754). framework-extension-points.md is likewise generated into
253
+ // dist/agentic/guides by both build.mjs pipelines (#4810) rather than checked in
254
+ // alongside the static conceptual guides, so it needs an explicit entry here.
218
255
  collected.add('module-facts.json')
256
+ collected.add('framework-extension-points.md')
257
+ collected.add('upstream/AGENTS.md')
258
+ collected.add('upstream/BACKWARD_COMPATIBILITY.md')
259
+ collected.add('upstream/manifest.json')
219
260
  for (const moduleId of FIXTURE_ENABLED_MODULES) {
220
261
  collected.add(normalizePath(path.join('modules', `${moduleId}.md`)))
221
262
  }
@@ -262,14 +303,17 @@ test.describe('TC-INT-008: CLI agentic init mirrors standalone scaffolding asset
262
303
 
263
304
  const agentsSource = fs.readFileSync(path.join(appDir, 'AGENTS.md'), 'utf8')
264
305
  expect(agentsSource).toContain('<!-- CODEX_ENFORCEMENT_RULES_START -->')
265
- expect(agentsSource).toContain('.ai/guides/core.md')
306
+ expect(agentsSource).toContain('.ai/guides/upstream/BACKWARD_COMPATIBILITY.md')
266
307
 
267
- // The Module-Specific Guides marker block lists exactly the enabled modules'
268
- // fact-sheets (enabled ∩ allowlist), not the full bundled set.
308
+ // The Module-Specific Guides marker block is a compact enabled-module ID
309
+ // index (enabled ∩ bundled) plus one progressively loaded path pattern.
269
310
  for (const moduleId of FIXTURE_ENABLED_MODULES) {
270
- expect(agentsSource).toContain(`.ai/guides/modules/${moduleId}.md`)
311
+ expect(agentsSource).toContain(`\`${moduleId}\``)
271
312
  }
272
- expect(agentsSource).not.toContain('.ai/guides/modules/auth.md')
313
+ expect(agentsSource).toContain('`.ai/guides/modules/<id>.md`')
314
+ expect(agentsSource.match(/\.ai\/guides\/modules\//g)).toHaveLength(1)
315
+ expect(agentsSource).not.toContain('`auth`')
316
+ expect(agentsSource).not.toContain('Core CRM capabilities')
273
317
 
274
318
  const specsReadmeSource = fs.readFileSync(path.join(appDir, '.ai', 'specs', 'README.md'), 'utf8')
275
319
  expect(specsReadmeSource).toContain('sample-store')
@@ -308,4 +352,58 @@ test.describe('TC-INT-008: CLI agentic init mirrors standalone scaffolding asset
308
352
  fs.rmSync(tempRoot, { recursive: true, force: true })
309
353
  }
310
354
  })
355
+
356
+ test('emits a runnable exact-version framework context escape hatch for an installed package', () => {
357
+ const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'mercato-cli-framework-context-'))
358
+
359
+ try {
360
+ const appDir = createStandaloneFixture(tempRoot)
361
+ const packageRoot = installFakeFrameworkPackage(appDir)
362
+ const resolvedPackageRoot = fs.realpathSync(packageRoot)
363
+ const packageBefore = snapshotTextFiles(packageRoot)
364
+
365
+ runMercato(['agentic:init', '--tool=codex'], appDir)
366
+ const generatedScript = path.join(appDir, 'scripts', 'framework-context.mjs')
367
+ expect(fs.existsSync(generatedScript)).toBe(true)
368
+
369
+ const output = runCommand(
370
+ process.execPath,
371
+ [generatedScript, '--module', 'customers', '--query', 'Person', '--json'],
372
+ appDir,
373
+ // The generated standalone helper must not depend on a globally
374
+ // installed ripgrep binary; process.execPath is already absolute.
375
+ { PATH: '', Path: '' },
376
+ )
377
+ const context = JSON.parse(output) as {
378
+ module: string
379
+ package: { name: string; version: string; root: string }
380
+ sourceKind: string
381
+ sourceRoot: string
382
+ materializedSource: string
383
+ instructions: Array<{ kind: string; path: string | null; materializedPath?: string }>
384
+ boundedSearch: { status: string; matches: number; maxMatches: number; result: string }
385
+ warnings: string[]
386
+ }
387
+
388
+ expect(context.module).toBe('customers')
389
+ expect(context.package).toEqual({ name: '@open-mercato/core', version: coreVersion, root: resolvedPackageRoot })
390
+ expect(context.sourceKind).toBe('source')
391
+ expect(normalizePath(context.sourceRoot)).toBe(normalizePath(path.join(resolvedPackageRoot, 'src', 'modules', 'customers')))
392
+ expect(context.instructions.filter((entry) => entry.path).map((entry) => entry.kind)).toEqual([
393
+ 'standalone-root',
394
+ 'upstream-bc',
395
+ 'package',
396
+ 'module-1',
397
+ 'upstream-root',
398
+ ])
399
+ expect(context.instructions.filter((entry) => entry.path).every((entry) => entry.materializedPath)).toBe(true)
400
+ expect(context.boundedSearch).toMatchObject({ status: 'matched', matches: 1, maxMatches: 200 })
401
+ expect(fs.existsSync(path.join(appDir, context.materializedSource))).toBe(true)
402
+ expect(fs.existsSync(path.join(appDir, context.boundedSearch.result))).toBe(true)
403
+ expect(context.warnings.some((warning) => warning.includes('Generated facts for customers are stale'))).toBe(false)
404
+ expect(snapshotTextFiles(packageRoot)).toEqual(packageBefore)
405
+ } finally {
406
+ fs.rmSync(tempRoot, { recursive: true, force: true })
407
+ }
408
+ })
311
409
  })
@@ -17,7 +17,11 @@ const loadRunAgenticInit = async ({
17
17
  }: {
18
18
  existingPaths: Set<string>
19
19
  questionAnswer?: string
20
- runAgenticSetupImplementation?: (targetDir: string, ask: (question: string) => Promise<string>, options?: { tool?: string; force?: boolean }) => Promise<void>
20
+ runAgenticSetupImplementation?: (
21
+ targetDir: string,
22
+ ask: (question: string) => Promise<string>,
23
+ options?: { tool?: string; force?: boolean; updateHarness?: boolean },
24
+ ) => Promise<void>
21
25
  }): Promise<AgenticInitTestContext> => {
22
26
  jest.resetModules()
23
27
 
@@ -136,6 +140,22 @@ describe('runAgenticInit', () => {
136
140
  expect(testContext.runAgenticSetup).not.toHaveBeenCalled()
137
141
  })
138
142
 
143
+ it('rejects force and ownership-aware update together before setup', async () => {
144
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
145
+ const testContext = await loadRunAgenticInit({
146
+ existingPaths: new Set<string>([appModulesPath]),
147
+ })
148
+
149
+ const exitCode = await testContext.runAgenticInit(['--force', '--update-harness'])
150
+
151
+ expect(exitCode).toBe(1)
152
+ expect(consoleErrorSpy).toHaveBeenCalledWith(
153
+ '❌ --force and --update-harness are mutually exclusive',
154
+ )
155
+ expect(testContext.createInterface).not.toHaveBeenCalled()
156
+ expect(testContext.runAgenticSetup).not.toHaveBeenCalled()
157
+ })
158
+
139
159
  it('warns and exits early when relevant agentic files already exist without force', async () => {
140
160
  const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation()
141
161
  const testContext = await loadRunAgenticInit({
@@ -150,7 +170,7 @@ describe('runAgenticInit', () => {
150
170
  expect(consoleLogSpy.mock.calls.flat()).toEqual(expect.arrayContaining([
151
171
  '⚠️ Agentic files already exist:',
152
172
  ' • .codex/mcp.json.example',
153
- 'Run with --force to regenerate from current templates.',
173
+ 'Run with --update-harness to preserve local edits, or --force to replace generated files.',
154
174
  ]))
155
175
  })
156
176
 
@@ -160,7 +180,7 @@ describe('runAgenticInit', () => {
160
180
  questionAnswer: ' cursor ',
161
181
  runAgenticSetupImplementation: async (currentTargetDir, ask, options) => {
162
182
  expect(currentTargetDir).toBe(targetDir)
163
- expect(options).toEqual({ tool: undefined, force: undefined })
183
+ expect(options).toEqual({ tool: undefined, force: undefined, updateHarness: undefined })
164
184
  await expect(ask('Select a tool')).resolves.toBe('cursor')
165
185
  },
166
186
  })
@@ -188,7 +208,7 @@ describe('runAgenticInit', () => {
188
208
  expect(testContext.runAgenticSetup).toHaveBeenCalledWith(
189
209
  targetDir,
190
210
  expect.any(Function),
191
- { tool: 'codex', force: undefined },
211
+ { tool: 'codex', force: undefined, updateHarness: undefined },
192
212
  )
193
213
  expect(consoleLogSpy.mock.calls.flat()).not.toContain('⚠️ Agentic files already exist:')
194
214
  expect(testContext.closeInterface).toHaveBeenCalledTimes(1)
@@ -205,7 +225,23 @@ describe('runAgenticInit', () => {
205
225
  expect(testContext.runAgenticSetup).toHaveBeenCalledWith(
206
226
  targetDir,
207
227
  expect.any(Function),
208
- { tool: 'codex', force: true },
228
+ { tool: 'codex', force: true, updateHarness: undefined },
229
+ )
230
+ expect(testContext.closeInterface).toHaveBeenCalledTimes(1)
231
+ })
232
+
233
+ it('bypasses overwrite warnings and requests an ownership-aware update', async () => {
234
+ const testContext = await loadRunAgenticInit({
235
+ existingPaths: new Set<string>([appModulesPath, codexConfigPath]),
236
+ })
237
+
238
+ const exitCode = await testContext.runAgenticInit(['--tool=codex', '--update-harness'])
239
+
240
+ expect(exitCode).toBe(0)
241
+ expect(testContext.runAgenticSetup).toHaveBeenCalledWith(
242
+ targetDir,
243
+ expect.any(Function),
244
+ { tool: 'codex', force: undefined, updateHarness: true },
209
245
  )
210
246
  expect(testContext.closeInterface).toHaveBeenCalledTimes(1)
211
247
  })