@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.
- package/.turbo/turbo-build.log +77 -4
- package/AGENTS.md +6 -1
- package/build.mjs +68 -11
- package/dist/agentic/claude-code/hooks/entity-migration-check.ts +32 -88
- package/dist/agentic/codex/enforcement-rules.md +2 -16
- package/dist/agentic/cursor/hooks/entity-migration-check.mjs +19 -50
- package/dist/agentic/cursor/rules/entity-guard.mdc +9 -21
- package/dist/agentic/cursor/rules/generated-guard.mdc +3 -5
- package/dist/agentic/cursor/rules/open-mercato.mdc +3 -29
- package/dist/agentic/guides/ai-workflows.md +76 -0
- package/dist/agentic/guides/architecture.md +107 -0
- package/dist/agentic/guides/backend-ui.md +86 -0
- package/dist/agentic/guides/contracts.md +92 -0
- package/dist/agentic/guides/extensions.md +121 -0
- package/dist/agentic/guides/framework-extension-points.md +36 -0
- package/dist/agentic/guides/integrations.md +81 -0
- package/dist/agentic/guides/module-facts.json +116757 -3951
- package/dist/agentic/guides/module-system.md +12 -127
- package/dist/agentic/guides/modules/ai_assistant.md +227 -28
- package/dist/agentic/guides/modules/api_docs.md +58 -2
- package/dist/agentic/guides/modules/api_keys.md +92 -7
- package/dist/agentic/guides/modules/attachments.md +119 -14
- package/dist/agentic/guides/modules/audit_logs.md +131 -10
- package/dist/agentic/guides/modules/auth.md +276 -33
- package/dist/agentic/guides/modules/business_rules.md +149 -14
- package/dist/agentic/guides/modules/catalog.md +482 -43
- package/dist/agentic/guides/modules/channel_gmail.md +82 -3
- package/dist/agentic/guides/modules/channel_imap.md +82 -3
- package/dist/agentic/guides/modules/checkout.md +305 -27
- package/dist/agentic/guides/modules/communication_channels.md +315 -33
- package/dist/agentic/guides/modules/configs.md +104 -8
- package/dist/agentic/guides/modules/content.md +57 -2
- package/dist/agentic/guides/modules/currencies.md +152 -17
- package/dist/agentic/guides/modules/customer_accounts.md +387 -45
- package/dist/agentic/guides/modules/customers.md +746 -85
- package/dist/agentic/guides/modules/dashboards.md +155 -10
- package/dist/agentic/guides/modules/data_sync.md +149 -16
- package/dist/agentic/guides/modules/design_system.md +102 -0
- package/dist/agentic/guides/modules/dictionaries.md +107 -12
- package/dist/agentic/guides/modules/directory.md +148 -15
- package/dist/agentic/guides/modules/entities.md +145 -13
- package/dist/agentic/guides/modules/events.md +59 -2
- package/dist/agentic/guides/modules/feature_toggles.md +119 -9
- package/dist/agentic/guides/modules/gateway_stripe.md +92 -4
- package/dist/agentic/guides/modules/generators.md +45 -2
- package/dist/agentic/guides/modules/inbox_ops.md +207 -27
- package/dist/agentic/guides/modules/integrations.md +149 -16
- package/dist/agentic/guides/modules/messages.md +223 -24
- package/dist/agentic/guides/modules/notifications.md +96 -8
- package/dist/agentic/guides/modules/onboarding.md +77 -6
- package/dist/agentic/guides/modules/payment_gateways.md +168 -21
- package/dist/agentic/guides/modules/perspectives.md +77 -7
- package/dist/agentic/guides/modules/planner.md +136 -18
- package/dist/agentic/guides/modules/portal.md +93 -2
- package/dist/agentic/guides/modules/progress.md +104 -14
- package/dist/agentic/guides/modules/query_index.md +154 -15
- package/dist/agentic/guides/modules/record_locks.md +206 -21
- package/dist/agentic/guides/modules/resources.md +197 -30
- package/dist/agentic/guides/modules/sales.md +687 -84
- package/dist/agentic/guides/modules/scheduler.md +133 -14
- package/dist/agentic/guides/modules/search.md +170 -6
- package/dist/agentic/guides/modules/security.md +294 -35
- package/dist/agentic/guides/modules/shipping_carriers.md +134 -18
- package/dist/agentic/guides/modules/sso.md +151 -26
- package/dist/agentic/guides/modules/staff.md +372 -57
- package/dist/agentic/guides/modules/storage_s3.md +95 -5
- package/dist/agentic/guides/modules/sync_akeneo.md +85 -3
- package/dist/agentic/guides/modules/sync_excel.md +75 -6
- package/dist/agentic/guides/modules/system_status_overlays.md +60 -2
- package/dist/agentic/guides/modules/translations.md +104 -10
- package/dist/agentic/guides/modules/webhooks.md +203 -24
- package/dist/agentic/guides/modules/wms.md +469 -47
- package/dist/agentic/guides/modules/workflows.md +302 -43
- package/dist/agentic/guides/reference-module-facts.json +6942 -0
- package/dist/agentic/guides/reference-modules/example.md +462 -0
- package/dist/agentic/guides/spec-delivery.md +56 -0
- package/dist/agentic/guides/testing-debugging.md +80 -0
- package/dist/agentic/guides/upstream/AGENTS.md +300 -0
- package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +334 -0
- package/dist/agentic/guides/upstream/manifest.json +8 -0
- package/dist/agentic/shared/AGENTS.md.template +120 -311
- package/dist/agentic/shared/ai/agentic.config.json +2 -0
- package/dist/agentic/shared/ai/harness/README.md +50 -0
- package/dist/agentic/shared/ai/harness/RELEASE.md +59 -0
- package/dist/agentic/shared/ai/harness/cases.json +20596 -0
- package/dist/agentic/shared/ai/harness/cases.schema.json +196 -0
- package/dist/agentic/shared/ai/harness/design-system-inventory.json +6326 -0
- package/dist/agentic/shared/ai/harness/fixtures/index.json +51 -0
- package/dist/agentic/shared/ai/harness/fixtures/seeds.json +166 -0
- package/dist/agentic/shared/ai/harness/generated-code-review-policy.md +21 -0
- package/dist/agentic/shared/ai/harness/generated-code-review-response.schema.json +96 -0
- package/dist/agentic/shared/ai/harness/generated-code-review-result.schema.json +172 -0
- package/dist/agentic/shared/ai/harness/knowledge-change.schema.json +228 -0
- package/dist/agentic/shared/ai/harness/release-matrix.json +163 -0
- package/dist/agentic/shared/ai/harness/release-result.schema.json +219 -0
- package/dist/agentic/shared/ai/harness/result.schema.json +136 -0
- package/dist/agentic/shared/ai/harness/routing-response.schema.json +22 -0
- package/dist/agentic/shared/ai/harness/source-link-inventory.json +1706 -0
- package/dist/agentic/shared/ai/harness/target-validation-result.schema.json +73 -0
- package/dist/agentic/shared/ai/harness/validators.json +82 -0
- package/dist/agentic/shared/ai/harness/writable-ast-oracles.mjs +2121 -0
- package/dist/agentic/shared/ai/harness/writable-behavior-oracles.mjs +1096 -0
- package/dist/agentic/shared/ai/harness/writable-spec-oracles.mjs +602 -0
- package/dist/agentic/shared/ai/lessons/_template.md +16 -0
- package/dist/agentic/shared/ai/lessons.md +26 -3
- package/dist/agentic/shared/ai/review-checklist.md +36 -0
- package/dist/agentic/shared/ai/skills/om-auto-implement-spec/SKILL.md +21 -0
- package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +4 -0
- package/dist/agentic/shared/ai/skills/om-auto-upgrade-0.6.6-to-0.6.7/SKILL.md +98 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/SKILL.md +21 -241
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/crud-surfaces.md +31 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/frontend-and-design-system.md +53 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/page-and-navigation.md +15 -0
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/quality-states.md +11 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/SKILL.md +30 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/activity-contracts.md +12 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/durability-and-progress.md +13 -0
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/workflow-design.md +14 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/SKILL.md +28 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/attachments-and-overrides.md +12 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/module-agents-and-tools.md +22 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/orchestrator-agents.md +12 -0
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/surface-selector.md +19 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/SKILL.md +17 -601
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/integrity-and-concurrency.md +21 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/migration-workflow.md +15 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/schema-design.md +16 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +10 -0
- package/dist/agentic/shared/ai/skills/om-eject-and-customize/SKILL.md +15 -310
- package/dist/agentic/shared/ai/skills/om-eject-and-customize/references/decision-and-procedure.md +19 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/SKILL.md +31 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-template.md +100 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-workflow.md +16 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/knowledge-change.md +133 -0
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/owner-selection.md +17 -0
- package/dist/agentic/shared/ai/skills/om-framework-context/SKILL.md +25 -0
- package/dist/agentic/shared/ai/skills/om-framework-context/references/resolver-procedure.md +11 -0
- package/dist/agentic/shared/ai/skills/om-framework-context/references/skew-and-escalation.md +13 -0
- package/dist/agentic/shared/ai/skills/om-help/SKILL.md +15 -97
- package/dist/agentic/shared/ai/skills/om-help/references/delivery-workflows.md +18 -0
- package/dist/agentic/shared/ai/skills/om-help/references/task-families.md +20 -0
- package/dist/agentic/shared/ai/skills/om-implement-spec/SKILL.md +33 -152
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/phases-and-gates.md +33 -0
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/planning-and-progress.md +40 -0
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/report-templates.md +27 -0
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/spec-resolution.md +24 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/SKILL.md +25 -708
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/package-and-activation.md +16 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/provider-families.md +25 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/security-and-reliability.md +15 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/sync-and-files.md +12 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/SKILL.md +34 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/agents/openai.yaml +4 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/agentic-setup.md +11 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/input-normalization.md +31 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/judge-workflow.md +39 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/report-template.md +43 -0
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/rules.md +11 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/SKILL.md +20 -820
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/api-and-domain.md +32 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/business-one-shot-blueprints.md +172 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/data-and-migrations.md +14 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/discovery-surface-catalog.md +83 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/module-surfaces.md +40 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/planning.md +11 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/runtime-cache-and-queues.md +22 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/verification.md +13 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/SKILL.md +41 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/agentic-setup.md +19 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/bundle-preparation.md +44 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/consent-and-review.md +39 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/publication.md +20 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/report-templates.md +57 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/rules.md +11 -0
- package/dist/agentic/shared/ai/skills/om-share-this-session/scripts/prepare-share-bundle.mjs +486 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/SKILL.md +20 -843
- package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-branches.md +42 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +27 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/read-write-roundtrip.md +13 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +43 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/references/verification.md +11 -0
- package/dist/agentic/shared/ai/skills/om-trim-unused-modules/SKILL.md +15 -63
- package/dist/agentic/shared/ai/skills/om-trim-unused-modules/references/dependency-and-redirect.md +15 -0
- package/dist/agentic/shared/ai/skills/om-troubleshooter/SKILL.md +17 -467
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnosis-map.md +29 -0
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/regression-oracles.md +14 -0
- package/dist/agentic/shared/ai/skills/tiers.json +143 -21
- package/dist/agentic/shared/ai/skills/tiers.schema.json +52 -40
- package/dist/agentic/shared/ai/specs/2026-08-06-reference-module-activation.md +248 -0
- package/dist/agentic/shared/ai/specs/README.md +4 -3
- package/dist/agentic/shared/ai/specs/SPEC-000-template.md +226 -10
- package/dist/agentic/shared/ai/trackers/github.md +108 -4
- package/dist/agentic/shared/scripts/agent-harness-tool-server.mjs +224 -0
- package/dist/agentic/shared/scripts/check-lessons.mjs +178 -0
- package/dist/agentic/shared/scripts/evaluate-agent-harness.mjs +3812 -0
- package/dist/agentic/shared/scripts/execution-sandbox.mjs +329 -0
- package/dist/agentic/shared/scripts/framework-context.mjs +888 -0
- package/dist/agentic/shared/scripts/install-skills.mjs +1029 -0
- package/dist/agentic/shared/scripts/install-skills.sh +4 -694
- package/dist/agentic/shared/scripts/prepare-agent-harness-fixture.mjs +222 -0
- package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +1774 -0
- package/dist/agentic/shared/scripts/validate-knowledge-change.mjs +1172 -0
- package/dist/bin.js +32 -34
- package/dist/bin.js.map +2 -2
- package/dist/lib/__integration__/TC-INT-008.spec.js +88 -8
- package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
- package/dist/lib/agentic-init.js +13 -3
- package/dist/lib/agentic-init.js.map +2 -2
- package/dist/lib/agentic-setup.js +434 -186
- package/dist/lib/agentic-setup.js.map +2 -2
- package/dist/lib/cli-bootstrap-mode.js +32 -0
- package/dist/lib/cli-bootstrap-mode.js.map +7 -0
- package/dist/lib/dev-supervisor-manifest.js +105 -0
- package/dist/lib/dev-supervisor-manifest.js.map +7 -0
- package/dist/lib/generate-watch-events.js +15 -0
- package/dist/lib/generate-watch-events.js.map +2 -2
- package/dist/lib/generators/entity-ids.js +11 -24
- package/dist/lib/generators/entity-ids.js.map +2 -2
- package/dist/lib/generators/extensions/injection-widgets.js +20 -0
- package/dist/lib/generators/extensions/injection-widgets.js.map +2 -2
- package/dist/lib/generators/module-di.js +10 -23
- package/dist/lib/generators/module-di.js.map +2 -2
- package/dist/lib/generators/module-entities.js +10 -23
- package/dist/lib/generators/module-entities.js.map +2 -2
- package/dist/lib/generators/module-extension-facts.js +1882 -0
- package/dist/lib/generators/module-extension-facts.js.map +7 -0
- package/dist/lib/generators/module-fact-sources.js +70 -0
- package/dist/lib/generators/module-fact-sources.js.map +7 -0
- package/dist/lib/generators/module-facts-discovery.js +64 -7
- package/dist/lib/generators/module-facts-discovery.js.map +2 -2
- package/dist/lib/generators/module-facts.js +1913 -52
- package/dist/lib/generators/module-facts.js.map +3 -3
- package/dist/lib/generators/module-override-targets.js +712 -0
- package/dist/lib/generators/module-override-targets.js.map +7 -0
- package/dist/lib/generators/module-registry.js +405 -36
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/generators/route-manifest-shards.js +170 -0
- package/dist/lib/generators/route-manifest-shards.js.map +7 -0
- package/dist/lib/in-process-generate-watcher.js +12 -3
- package/dist/lib/in-process-generate-watcher.js.map +2 -2
- package/dist/lib/load-env.js +24 -0
- package/dist/lib/load-env.js.map +7 -0
- package/dist/lib/queue-worker-supervisor.js.map +2 -2
- package/dist/lib/resolver.js +28 -3
- package/dist/lib/resolver.js.map +2 -2
- package/dist/lib/telemetry-init.js +358 -0
- package/dist/lib/telemetry-init.js.map +7 -0
- package/dist/lib/testing/integration.js +5 -2
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/lib/utils.js +15 -8
- package/dist/lib/utils.js.map +2 -2
- package/dist/mercato.js +35 -9
- package/dist/mercato.js.map +2 -2
- package/package.json +13 -11
- package/src/__tests__/mercato.test.ts +144 -0
- package/src/bin.ts +60 -42
- package/src/lib/__integration__/TC-INT-008.spec.ts +107 -9
- package/src/lib/__tests__/agentic-init.test.ts +41 -5
- package/src/lib/__tests__/agentic-setup.ownership.test.ts +386 -0
- package/src/lib/__tests__/cli-bootstrap-mode.test.ts +22 -0
- package/src/lib/__tests__/content-stable-writes.test.ts +74 -0
- package/src/lib/__tests__/dev-supervisor-manifest.test.ts +131 -0
- package/src/lib/__tests__/generate-watch-events.test.ts +76 -0
- package/src/lib/__tests__/in-process-generate-watcher.test.ts +52 -1
- package/src/lib/__tests__/injection-widget-id-validation.test.ts +184 -0
- package/src/lib/__tests__/load-env.test.ts +65 -0
- package/src/lib/__tests__/queue-worker-supervisor.test.ts +33 -0
- package/src/lib/__tests__/resolver.enterprise.test.ts +50 -0
- package/src/lib/__tests__/telemetry-init.test.ts +298 -0
- package/src/lib/agentic-init.ts +15 -3
- package/src/lib/agentic-setup.ts +573 -222
- package/src/lib/cli-bootstrap-mode.ts +31 -0
- package/src/lib/dev-supervisor-manifest.ts +142 -0
- package/src/lib/generate-watch-events.ts +14 -0
- package/src/lib/generators/__tests__/activation-adapter-coverage.test.ts +92 -0
- package/src/lib/generators/__tests__/entity-ids.test.ts +32 -0
- package/src/lib/generators/__tests__/helpers/override-target-diagnostic-fixtures.ts +150 -0
- package/src/lib/generators/__tests__/module-extension-activations.test.ts +762 -0
- package/src/lib/generators/__tests__/module-extension-facts.test.ts +603 -0
- package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +139 -2
- package/src/lib/generators/__tests__/module-facts.computed-di-token.test.ts +88 -0
- package/src/lib/generators/__tests__/module-facts.customers.fixture.test.ts +1 -0
- package/src/lib/generators/__tests__/module-facts.discovery.test.ts +54 -10
- package/src/lib/generators/__tests__/module-facts.example-fact-coverage.test.ts +414 -0
- package/src/lib/generators/__tests__/module-facts.extension-hosts.test.ts +108 -0
- package/src/lib/generators/__tests__/module-facts.local-reference.test.ts +393 -0
- package/src/lib/generators/__tests__/module-facts.owned-contracts.test.ts +561 -0
- package/src/lib/generators/__tests__/module-facts.search-entity-id.test.ts +151 -0
- package/src/lib/generators/__tests__/module-facts.source-links.test.ts +160 -0
- package/src/lib/generators/__tests__/module-override-targets.diagnostic-wiring.test.ts +92 -0
- package/src/lib/generators/__tests__/module-override-targets.roundtrip.test.ts +149 -0
- package/src/lib/generators/__tests__/module-override-targets.test.ts +328 -0
- package/src/lib/generators/__tests__/module-override-targets.unknown-mode.test.ts +117 -0
- package/src/lib/generators/__tests__/module-subset.test.ts +266 -0
- package/src/lib/generators/__tests__/output-snapshots.test.ts +3 -3
- package/src/lib/generators/__tests__/route-manifest-shards.test.ts +62 -0
- package/src/lib/generators/entity-ids.ts +10 -26
- package/src/lib/generators/extensions/injection-widgets.ts +51 -0
- package/src/lib/generators/module-di.ts +9 -25
- package/src/lib/generators/module-entities.ts +9 -25
- package/src/lib/generators/module-extension-facts.ts +2472 -0
- package/src/lib/generators/module-fact-sources.ts +108 -0
- package/src/lib/generators/module-facts-discovery.ts +104 -7
- package/src/lib/generators/module-facts.ts +2747 -138
- package/src/lib/generators/module-override-targets.ts +907 -0
- package/src/lib/generators/module-registry.ts +448 -35
- package/src/lib/generators/route-manifest-shards.ts +146 -0
- package/src/lib/in-process-generate-watcher.ts +13 -4
- package/src/lib/load-env.ts +30 -0
- package/src/lib/queue-worker-supervisor.ts +7 -2
- package/src/lib/resolver.ts +34 -3
- package/src/lib/telemetry-init.ts +461 -0
- package/src/lib/testing/__tests__/integration.test.ts +4 -0
- package/src/lib/testing/integration.ts +5 -2
- package/src/lib/utils.ts +24 -16
- package/src/mercato.ts +46 -9
- package/dist/agentic/guides/cache.md +0 -45
- package/dist/agentic/guides/core.md +0 -453
- package/dist/agentic/guides/events.md +0 -117
- package/dist/agentic/guides/queue.md +0 -53
- package/dist/agentic/guides/search.md +0 -115
- package/dist/agentic/guides/shared.md +0 -108
- package/dist/agentic/guides/ui.md +0 -347
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +0 -27
- package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +0 -27
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/ui-components.md +0 -260
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md +0 -146
- package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +0 -84
- package/dist/agentic/shared/ai/skills/om-help/references/workflow-sequences.md +0 -193
- package/dist/agentic/shared/ai/skills/om-integration-builder/STANDALONE.md +0 -34
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/adapter-contracts.md +0 -762
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/naming-conventions.md +0 -50
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/navigation-patterns.md +0 -97
- package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-contracts.md +0 -271
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnostic-commands.md +0 -101
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type CliBootstrapMode = 'none' | 'dev-supervisor' | 'full'
|
|
2
|
+
|
|
3
|
+
const BOOTSTRAP_FREE_COMMANDS = new Set([
|
|
4
|
+
'generate',
|
|
5
|
+
'module',
|
|
6
|
+
'deploy',
|
|
7
|
+
'db',
|
|
8
|
+
'init',
|
|
9
|
+
'agentic:init',
|
|
10
|
+
'telemetry',
|
|
11
|
+
'eject',
|
|
12
|
+
'test',
|
|
13
|
+
'test:integration',
|
|
14
|
+
'test:integration:coverage',
|
|
15
|
+
'test:integration:spec-coverage',
|
|
16
|
+
'test:ephemeral',
|
|
17
|
+
'test:integration:interactive',
|
|
18
|
+
'umes:list',
|
|
19
|
+
'umes:inspect',
|
|
20
|
+
'umes:check',
|
|
21
|
+
'help',
|
|
22
|
+
'--help',
|
|
23
|
+
'-h',
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
export function resolveCliBootstrapMode(argv: readonly string[]): CliBootstrapMode {
|
|
27
|
+
const [, , first, second] = argv
|
|
28
|
+
if (!first || BOOTSTRAP_FREE_COMMANDS.has(first)) return 'none'
|
|
29
|
+
if (first === 'server' && second === 'dev') return 'dev-supervisor'
|
|
30
|
+
return 'full'
|
|
31
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import type { ModuleWorker } from '@open-mercato/shared/modules/registry'
|
|
4
|
+
|
|
5
|
+
export const DEV_SUPERVISOR_MANIFEST_FILE = 'dev-supervisor.generated.json'
|
|
6
|
+
export const DEV_SUPERVISOR_MANIFEST_VERSION = 1
|
|
7
|
+
|
|
8
|
+
export type DevSupervisorWorkerDescriptor = Pick<
|
|
9
|
+
ModuleWorker,
|
|
10
|
+
'id' | 'moduleId' | 'queue' | 'concurrency'
|
|
11
|
+
>
|
|
12
|
+
|
|
13
|
+
export type DevSupervisorSchedulerStartStatus =
|
|
14
|
+
| 'ok'
|
|
15
|
+
| 'missing-module'
|
|
16
|
+
| 'missing-cli'
|
|
17
|
+
| 'missing-command'
|
|
18
|
+
|
|
19
|
+
export type DevSupervisorManifest = {
|
|
20
|
+
version: typeof DEV_SUPERVISOR_MANIFEST_VERSION
|
|
21
|
+
workers: DevSupervisorWorkerDescriptor[]
|
|
22
|
+
schedulerStartStatus: DevSupervisorSchedulerStartStatus
|
|
23
|
+
requiresFullBootstrap: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let registeredManifest: DevSupervisorManifest | null = null
|
|
27
|
+
|
|
28
|
+
function manifestError(filePath: string, detail: string): Error {
|
|
29
|
+
return new Error(
|
|
30
|
+
`Invalid generated dev supervisor manifest at ${filePath}: ${detail}. ` +
|
|
31
|
+
'Run `yarn generate` and retry.',
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function isNonEmptyString(value: unknown): value is string {
|
|
36
|
+
return typeof value === 'string' && value.trim().length > 0
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseWorkerDescriptor(
|
|
40
|
+
value: unknown,
|
|
41
|
+
index: number,
|
|
42
|
+
filePath: string,
|
|
43
|
+
): DevSupervisorWorkerDescriptor {
|
|
44
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
45
|
+
throw manifestError(filePath, `workers[${index}] must be an object`)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const worker = value as Record<string, unknown>
|
|
49
|
+
if (!isNonEmptyString(worker.id)) {
|
|
50
|
+
throw manifestError(filePath, `workers[${index}].id must be a non-empty string`)
|
|
51
|
+
}
|
|
52
|
+
if (!isNonEmptyString(worker.queue)) {
|
|
53
|
+
throw manifestError(filePath, `workers[${index}].queue must be a non-empty string`)
|
|
54
|
+
}
|
|
55
|
+
if (typeof worker.concurrency !== 'number' || !Number.isFinite(worker.concurrency)) {
|
|
56
|
+
throw manifestError(filePath, `workers[${index}].concurrency must be a finite number`)
|
|
57
|
+
}
|
|
58
|
+
if (worker.moduleId !== undefined && !isNonEmptyString(worker.moduleId)) {
|
|
59
|
+
throw manifestError(filePath, `workers[${index}].moduleId must be a non-empty string when present`)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
id: worker.id,
|
|
64
|
+
...(worker.moduleId === undefined ? {} : { moduleId: worker.moduleId }),
|
|
65
|
+
queue: worker.queue,
|
|
66
|
+
concurrency: worker.concurrency,
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function parseManifest(value: unknown, filePath: string): DevSupervisorManifest {
|
|
71
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
72
|
+
throw manifestError(filePath, 'root value must be an object')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const manifest = value as Record<string, unknown>
|
|
76
|
+
if (manifest.version !== DEV_SUPERVISOR_MANIFEST_VERSION) {
|
|
77
|
+
throw manifestError(
|
|
78
|
+
filePath,
|
|
79
|
+
`unsupported version ${String(manifest.version)} (expected ${DEV_SUPERVISOR_MANIFEST_VERSION})`,
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
if (!Array.isArray(manifest.workers)) {
|
|
83
|
+
throw manifestError(filePath, 'workers must be an array')
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const schedulerStartStatus = manifest.schedulerStartStatus
|
|
87
|
+
if (
|
|
88
|
+
schedulerStartStatus !== 'ok' &&
|
|
89
|
+
schedulerStartStatus !== 'missing-module' &&
|
|
90
|
+
schedulerStartStatus !== 'missing-cli' &&
|
|
91
|
+
schedulerStartStatus !== 'missing-command'
|
|
92
|
+
) {
|
|
93
|
+
throw manifestError(filePath, 'schedulerStartStatus is invalid')
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
version: DEV_SUPERVISOR_MANIFEST_VERSION,
|
|
98
|
+
workers: manifest.workers.map((worker, index) => parseWorkerDescriptor(worker, index, filePath)),
|
|
99
|
+
schedulerStartStatus,
|
|
100
|
+
// Version-1 manifests produced before this safety marker existed cannot
|
|
101
|
+
// prove that worker/CLI overrides were accounted for. Preserve the old
|
|
102
|
+
// full-bootstrap behavior until `yarn generate` writes an explicit false.
|
|
103
|
+
requiresFullBootstrap: manifest.requiresFullBootstrap !== false,
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function canUseLightweightDevSupervisor(manifest: DevSupervisorManifest): boolean {
|
|
108
|
+
return manifest.requiresFullBootstrap === false
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function loadDevSupervisorManifest(appDir: string): DevSupervisorManifest {
|
|
112
|
+
const filePath = path.join(appDir, '.mercato', 'generated', DEV_SUPERVISOR_MANIFEST_FILE)
|
|
113
|
+
let source: string
|
|
114
|
+
try {
|
|
115
|
+
source = fs.readFileSync(filePath, 'utf8')
|
|
116
|
+
} catch (error) {
|
|
117
|
+
const detail = error instanceof Error ? error.message : String(error)
|
|
118
|
+
throw manifestError(filePath, `file could not be read (${detail})`)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let parsed: unknown
|
|
122
|
+
try {
|
|
123
|
+
parsed = JSON.parse(source)
|
|
124
|
+
} catch (error) {
|
|
125
|
+
const detail = error instanceof Error ? error.message : String(error)
|
|
126
|
+
throw manifestError(filePath, `JSON could not be parsed (${detail})`)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return parseManifest(parsed, filePath)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function registerDevSupervisorManifest(manifest: DevSupervisorManifest): void {
|
|
133
|
+
registeredManifest = manifest
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function getRegisteredDevSupervisorManifest(): DevSupervisorManifest | null {
|
|
137
|
+
return registeredManifest
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function resetDevSupervisorManifestForTests(): void {
|
|
141
|
+
registeredManifest = null
|
|
142
|
+
}
|
|
@@ -21,6 +21,8 @@ type WatchDirectory = (
|
|
|
21
21
|
export type GenerateWatchChangeSignalOptions = {
|
|
22
22
|
getWatchTargets: () => Promise<GenerateWatchTarget[]> | GenerateWatchTarget[]
|
|
23
23
|
watchDirectory?: WatchDirectory
|
|
24
|
+
directoryExists?: (directory: string) => boolean
|
|
25
|
+
onSkippedDirectory?: (directory: string) => void
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
function targetKey(target: GenerateWatchTarget): string {
|
|
@@ -49,7 +51,9 @@ export function createGenerateWatchChangeSignal(
|
|
|
49
51
|
options: GenerateWatchChangeSignalOptions,
|
|
50
52
|
): GenerateWatcherChangeSignal {
|
|
51
53
|
const watchDirectory = options.watchDirectory ?? defaultWatchDirectory
|
|
54
|
+
const directoryExists = options.directoryExists ?? fs.existsSync
|
|
52
55
|
const watchers = new Map<string, WatchHandle>()
|
|
56
|
+
let skippedDirectories = new Set<string>()
|
|
53
57
|
let version = 0
|
|
54
58
|
let pollingFallback = false
|
|
55
59
|
let closed = false
|
|
@@ -70,6 +74,7 @@ export function createGenerateWatchChangeSignal(
|
|
|
70
74
|
|
|
71
75
|
return {
|
|
72
76
|
currentVersion: () => version,
|
|
77
|
+
hasSkippedTargets: () => skippedDirectories.size > 0,
|
|
73
78
|
usesPollingFallback: () => pollingFallback,
|
|
74
79
|
refresh: async () => {
|
|
75
80
|
if (closed || pollingFallback) return
|
|
@@ -83,13 +88,22 @@ export function createGenerateWatchChangeSignal(
|
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
const normalizedTargets = new Map<string, GenerateWatchTarget>()
|
|
91
|
+
const nextSkippedDirectories = new Set<string>()
|
|
86
92
|
for (const target of targets) {
|
|
87
93
|
const normalized: GenerateWatchTarget = {
|
|
88
94
|
...target,
|
|
89
95
|
directory: path.resolve(target.directory),
|
|
90
96
|
}
|
|
97
|
+
if (!directoryExists(normalized.directory)) {
|
|
98
|
+
nextSkippedDirectories.add(normalized.directory)
|
|
99
|
+
if (!skippedDirectories.has(normalized.directory)) {
|
|
100
|
+
try { options.onSkippedDirectory?.(normalized.directory) } catch {}
|
|
101
|
+
}
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
91
104
|
normalizedTargets.set(targetKey(normalized), normalized)
|
|
92
105
|
}
|
|
106
|
+
skippedDirectories = nextSkippedDirectories
|
|
93
107
|
|
|
94
108
|
for (const [key, watcher] of watchers) {
|
|
95
109
|
if (normalizedTargets.has(key)) continue
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ACTIVATION_ADAPTERS,
|
|
3
|
+
ALL_ACTIVATION_KINDS,
|
|
4
|
+
ALL_CONTRIBUTION_KINDS,
|
|
5
|
+
CONTRIBUTION_ACTIVATION_CLASSIFICATION,
|
|
6
|
+
} from '../module-extension-facts'
|
|
7
|
+
import type {
|
|
8
|
+
ModuleExtensionActivationKind,
|
|
9
|
+
ModuleExtensionContributionKind,
|
|
10
|
+
} from '@open-mercato/shared/modules/widgets/extension-points'
|
|
11
|
+
|
|
12
|
+
// Explicit expected inventories. Adding a UMES activation kind or contribution
|
|
13
|
+
// kind to the shared union forces the typed Record in module-extension-facts.ts
|
|
14
|
+
// to gain a key (compile-time gate) AND requires updating these lists (this
|
|
15
|
+
// coverage gate), so an unclassified kind cannot ship silently.
|
|
16
|
+
const EXPECTED_ACTIVATION_KINDS: ModuleExtensionActivationKind[] = [
|
|
17
|
+
'crud-response-enricher',
|
|
18
|
+
'query-enricher',
|
|
19
|
+
'mutation-guard',
|
|
20
|
+
'api-interceptor-bridge',
|
|
21
|
+
'command-interceptor-bridge',
|
|
22
|
+
'widget-injection-consumer',
|
|
23
|
+
'component-extension-consumer',
|
|
24
|
+
'dashboard-host-consumer',
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const EXPECTED_CONTRIBUTION_KINDS: ModuleExtensionContributionKind[] = [
|
|
28
|
+
'widget',
|
|
29
|
+
'data-table',
|
|
30
|
+
'crud-form',
|
|
31
|
+
'component-override',
|
|
32
|
+
'response-enricher',
|
|
33
|
+
'api-interceptor',
|
|
34
|
+
'command-interceptor',
|
|
35
|
+
'mutation-guard',
|
|
36
|
+
'entity-extension',
|
|
37
|
+
'subscriber',
|
|
38
|
+
'browser-reaction',
|
|
39
|
+
'specialized-registry',
|
|
40
|
+
'module-override',
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
// Route/entity-bound contribution kinds MUST bind through an activation adapter —
|
|
44
|
+
// never be silently classified as capability-only.
|
|
45
|
+
const ROUTE_OR_ENTITY_BOUND_KINDS: ModuleExtensionContributionKind[] = [
|
|
46
|
+
'response-enricher',
|
|
47
|
+
'mutation-guard',
|
|
48
|
+
'api-interceptor',
|
|
49
|
+
'command-interceptor',
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
describe('activation adapter coverage', () => {
|
|
53
|
+
it('registers exactly the expected closed set of activation adapters', () => {
|
|
54
|
+
expect([...ALL_ACTIVATION_KINDS].sort()).toEqual([...EXPECTED_ACTIVATION_KINDS].sort())
|
|
55
|
+
expect(Object.keys(ACTIVATION_ADAPTERS).sort()).toEqual([...EXPECTED_ACTIVATION_KINDS].sort())
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it('classifies exactly the expected closed set of contribution kinds', () => {
|
|
59
|
+
expect([...ALL_CONTRIBUTION_KINDS].sort()).toEqual([...EXPECTED_CONTRIBUTION_KINDS].sort())
|
|
60
|
+
expect(Object.keys(CONTRIBUTION_ACTIVATION_CLASSIFICATION).sort()).toEqual([...EXPECTED_CONTRIBUTION_KINDS].sort())
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('maps every contribution kind to a real adapter whose contributionKinds accept it, or to a tested capability-only classification', () => {
|
|
64
|
+
for (const kind of ALL_CONTRIBUTION_KINDS) {
|
|
65
|
+
const classification = CONTRIBUTION_ACTIVATION_CLASSIFICATION[kind]
|
|
66
|
+
if (classification === 'capability-only') {
|
|
67
|
+
expect(ROUTE_OR_ENTITY_BOUND_KINDS).not.toContain(kind)
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
expect(classification.length).toBeGreaterThan(0)
|
|
71
|
+
for (const activationKind of classification) {
|
|
72
|
+
const adapter = ACTIVATION_ADAPTERS[activationKind]
|
|
73
|
+
expect(adapter).toBeDefined()
|
|
74
|
+
expect(adapter.contributionKinds).toContain(kind)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('requires every route/entity-bound contribution kind to have an activation adapter (never capability-only)', () => {
|
|
80
|
+
for (const kind of ROUTE_OR_ENTITY_BOUND_KINDS) {
|
|
81
|
+
const classification = CONTRIBUTION_ACTIVATION_CLASSIFICATION[kind]
|
|
82
|
+
expect(classification).not.toBe('capability-only')
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('keeps a call-site-object adapter for every kind that distinguishes bound from capability-only by opt-in', () => {
|
|
87
|
+
const callSiteKinds = ALL_ACTIVATION_KINDS.filter((kind) => ACTIVATION_ADAPTERS[kind].mode === 'call-site-object')
|
|
88
|
+
// Enricher (response + query) and mutation-guard opt-ins are the only surfaces
|
|
89
|
+
// whose activation presence is NOT implied by mere host existence.
|
|
90
|
+
expect(callSiteKinds.sort()).toEqual(['crud-response-enricher', 'mutation-guard', 'query-enricher'])
|
|
91
|
+
})
|
|
92
|
+
})
|
|
@@ -201,6 +201,38 @@ describe('generateEntityIds', () => {
|
|
|
201
201
|
expect(registry).not.toContain("import * as sales_order from './entities/sales_order/index'")
|
|
202
202
|
})
|
|
203
203
|
|
|
204
|
+
it('preserves every generated entity output mtime when the output bytes are unchanged', async () => {
|
|
205
|
+
const moduleEntry: ModuleEntry = { id: 'orders', from: '@open-mercato/core' }
|
|
206
|
+
const entitiesFile = path.join(tmpDir, 'packages', 'core', 'src', 'modules', 'orders', 'data', 'entities.ts')
|
|
207
|
+
fs.mkdirSync(path.dirname(entitiesFile), { recursive: true })
|
|
208
|
+
fs.writeFileSync(entitiesFile, 'export class SalesOrder { id!: string; totalGross!: number }\n')
|
|
209
|
+
|
|
210
|
+
const resolver = createMockResolver(tmpDir, [moduleEntry])
|
|
211
|
+
const firstResult = await generateEntityIds({ resolver, quiet: true })
|
|
212
|
+
const outputDir = resolver.getOutputDir()
|
|
213
|
+
const generatedFiles = [
|
|
214
|
+
path.join(outputDir, 'entities.ids.generated.ts'),
|
|
215
|
+
path.join(outputDir, 'entity-fields-registry.ts'),
|
|
216
|
+
path.join(outputDir, 'entities', 'sales_order', 'index.ts'),
|
|
217
|
+
]
|
|
218
|
+
const oldTime = new Date(Date.now() - 60_000)
|
|
219
|
+
for (const filePath of generatedFiles) {
|
|
220
|
+
fs.utimesSync(filePath, oldTime, oldTime)
|
|
221
|
+
}
|
|
222
|
+
const mtimesBefore = new Map(
|
|
223
|
+
generatedFiles.map((filePath) => [filePath, fs.statSync(filePath).mtimeMs]),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
const secondResult = await generateEntityIds({ resolver, quiet: true })
|
|
227
|
+
|
|
228
|
+
expect(firstResult.filesWritten).toEqual(expect.arrayContaining(generatedFiles))
|
|
229
|
+
expect(secondResult.filesWritten).toEqual([])
|
|
230
|
+
expect(secondResult.filesUnchanged).toEqual(expect.arrayContaining(generatedFiles))
|
|
231
|
+
for (const filePath of generatedFiles) {
|
|
232
|
+
expect(fs.statSync(filePath).mtimeMs).toBe(mtimesBefore.get(filePath))
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
|
|
204
236
|
it('reuses package generated entity metadata in standalone mode', async () => {
|
|
205
237
|
const moduleEntry: ModuleEntry = { id: 'directory', from: '@open-mercato/core' }
|
|
206
238
|
const packageRoot = path.join(tmpDir, 'node_modules', '@open-mercato', 'core')
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { ModuleFactsJsonEntry } from '../../module-facts'
|
|
2
|
+
import { getFrameworkOverrideHostOperations } from '../../module-extension-facts'
|
|
3
|
+
import {
|
|
4
|
+
collectModuleOverrideTargets,
|
|
5
|
+
type ModuleOverrideTargetDiagnostic,
|
|
6
|
+
type ModuleOverrideTargetDiagnosticCode,
|
|
7
|
+
type ModuleOverrideTargetsResult,
|
|
8
|
+
} from '../../module-override-targets'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Real producers for every override-target diagnostic the projector can emit.
|
|
12
|
+
*
|
|
13
|
+
* The `factCoverage` ledger classifies four diagnostic codes as `negative-fixture`,
|
|
14
|
+
* which is a claim that a fixture really drives that code out of
|
|
15
|
+
* {@link collectModuleOverrideTargets}. These fixtures ARE that claim's evidence, and
|
|
16
|
+
* the coverage test asserts the produced set matches the ledger rows exactly — so a
|
|
17
|
+
* row can never name a fixture that does not exist, and a code no fixture reaches
|
|
18
|
+
* cannot be published as `negative-fixture`.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export const FIXTURE_MODULE_ID = 'fixture'
|
|
22
|
+
export const FIXTURE_SOURCE_ROOT = `node_modules/@open-mercato/core/src/modules/${FIXTURE_MODULE_ID}`
|
|
23
|
+
|
|
24
|
+
export function fixtureFacts(overrides: Partial<ModuleFactsJsonEntry> = {}): ModuleFactsJsonEntry {
|
|
25
|
+
return {
|
|
26
|
+
title: 'Fixture',
|
|
27
|
+
description: null,
|
|
28
|
+
coreVersion: null,
|
|
29
|
+
sourcePackage: '@open-mercato/core',
|
|
30
|
+
sourceVersion: null,
|
|
31
|
+
sourceRoot: FIXTURE_SOURCE_ROOT,
|
|
32
|
+
entities: [],
|
|
33
|
+
events: [],
|
|
34
|
+
aclFeatures: [],
|
|
35
|
+
apiRoutes: [],
|
|
36
|
+
diTokens: [],
|
|
37
|
+
searchEntities: [],
|
|
38
|
+
hostTokens: { entityIds: [], tableIds: [] },
|
|
39
|
+
notifications: [],
|
|
40
|
+
cli: ['fixture:seed'],
|
|
41
|
+
backendPages: [],
|
|
42
|
+
frontendPages: [],
|
|
43
|
+
cliCommands: [{ command: 'fixture:seed', sourcePath: `${FIXTURE_SOURCE_ROOT}/cli.ts` }],
|
|
44
|
+
aiTools: [],
|
|
45
|
+
aiAgents: [],
|
|
46
|
+
...overrides,
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function fixtureWorkerFacts(): ModuleFactsJsonEntry {
|
|
51
|
+
return fixtureFacts({
|
|
52
|
+
ownedContracts: {
|
|
53
|
+
worker: [
|
|
54
|
+
{
|
|
55
|
+
kind: 'worker',
|
|
56
|
+
id: 'fixture.worker',
|
|
57
|
+
source: { sourcePath: `${FIXTURE_SOURCE_ROOT}/workers/fixture.ts`, line: 1 },
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The framework catalog's real declared operations, which the projector reads at
|
|
66
|
+
* import time. Tests derive their stub catalogs from this so a stub differs from
|
|
67
|
+
* production in exactly the one host under test.
|
|
68
|
+
*/
|
|
69
|
+
export function realCatalogOperations(): Record<string, string> {
|
|
70
|
+
return getFrameworkOverrideHostOperations()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function catalogWithout(dottedHost: string): Record<string, string> {
|
|
74
|
+
const operations = realCatalogOperations()
|
|
75
|
+
delete operations[dottedHost]
|
|
76
|
+
return operations
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function catalogWith(dottedHost: string, operation: string): Record<string, string> {
|
|
80
|
+
return { ...realCatalogOperations(), [dottedHost]: operation }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Re-imports the projector against a stubbed framework catalog, so the two "no
|
|
85
|
+
* modes" causes reach the real `pushTarget` wiring instead of only the pure
|
|
86
|
+
* resolver. Every catalog host ships a valid operation today, so a stub is the only
|
|
87
|
+
* way to drive the unknown-domain/unknown-mode branches through production code.
|
|
88
|
+
*/
|
|
89
|
+
export function collectWithCatalogOperations(
|
|
90
|
+
hostOperations: Record<string, string>,
|
|
91
|
+
facts: ModuleFactsJsonEntry,
|
|
92
|
+
): ModuleOverrideTargetsResult {
|
|
93
|
+
let result: ModuleOverrideTargetsResult | undefined
|
|
94
|
+
jest.isolateModules(() => {
|
|
95
|
+
jest.doMock('../../module-extension-facts', () => ({
|
|
96
|
+
...jest.requireActual('../../module-extension-facts'),
|
|
97
|
+
getFrameworkOverrideHostOperations: () => hostOperations,
|
|
98
|
+
}))
|
|
99
|
+
const projector = require('../../module-override-targets') as typeof import('../../module-override-targets')
|
|
100
|
+
result = projector.collectModuleOverrideTargets(facts)
|
|
101
|
+
})
|
|
102
|
+
jest.dontMock('../../module-extension-facts')
|
|
103
|
+
if (!result) throw new Error('[internal] isolated override-target collection produced no result')
|
|
104
|
+
return result
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export type OverrideTargetDiagnosticFixture = {
|
|
108
|
+
code: ModuleOverrideTargetDiagnosticCode
|
|
109
|
+
description: string
|
|
110
|
+
run: () => ModuleOverrideTargetDiagnostic[]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const OVERRIDE_TARGET_DIAGNOSTIC_FIXTURES: OverrideTargetDiagnosticFixture[] = [
|
|
114
|
+
{
|
|
115
|
+
code: 'missing-source',
|
|
116
|
+
description: 'a cli command whose provenance cannot be proven',
|
|
117
|
+
run: () =>
|
|
118
|
+
collectModuleOverrideTargets(fixtureFacts({ cliCommands: [{ command: 'fixture:seed', sourcePath: null }] }))
|
|
119
|
+
.overrideTargetDiagnostics,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
code: 'unsupported-dynamic-key',
|
|
123
|
+
description: 'an api route whose method the runtime cannot address',
|
|
124
|
+
run: () =>
|
|
125
|
+
collectModuleOverrideTargets(
|
|
126
|
+
fixtureFacts({
|
|
127
|
+
apiRoutes: [
|
|
128
|
+
{
|
|
129
|
+
path: '/fixture/items',
|
|
130
|
+
methods: ['FETCH'],
|
|
131
|
+
auth: {},
|
|
132
|
+
sourcePath: `${FIXTURE_SOURCE_ROOT}/api/items/route.ts`,
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
}),
|
|
136
|
+
).overrideTargetDiagnostics,
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
code: 'unknown-framework-domain',
|
|
140
|
+
description: 'the framework catalog does not describe the cli host at all',
|
|
141
|
+
run: () => collectWithCatalogOperations(catalogWithout('cli'), fixtureFacts()).overrideTargetDiagnostics,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
code: 'unknown-framework-mode',
|
|
145
|
+
description: 'the framework catalog describes the workers host with an operation that is not a public mode',
|
|
146
|
+
run: () =>
|
|
147
|
+
collectWithCatalogOperations(catalogWith('workers', 'merge-deep'), fixtureWorkerFacts())
|
|
148
|
+
.overrideTargetDiagnostics,
|
|
149
|
+
},
|
|
150
|
+
]
|