@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,146 @@
|
|
|
1
|
+
export type RouteManifestShardKind = 'api' | 'backend'
|
|
2
|
+
|
|
3
|
+
export type RouteManifestShardEntry = {
|
|
4
|
+
path: string
|
|
5
|
+
declaration: string
|
|
6
|
+
imports?: string[]
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type RouteManifestShardOutput = {
|
|
10
|
+
fileName: string
|
|
11
|
+
content: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type IndexedRouteManifestShardEntry = RouteManifestShardEntry & {
|
|
15
|
+
order: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DYNAMIC_SHARD_KEY = '__dynamic'
|
|
19
|
+
const ROOT_SHARD_KEY = '__root'
|
|
20
|
+
|
|
21
|
+
function normalizeRoutePath(kind: RouteManifestShardKind, pathname: string): string[] {
|
|
22
|
+
const segments = pathname.split('?')[0].split('/').filter(Boolean)
|
|
23
|
+
if (kind === 'backend' && segments[0]?.toLowerCase() === 'backend') {
|
|
24
|
+
segments.shift()
|
|
25
|
+
}
|
|
26
|
+
return segments
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getRouteManifestShardKey(kind: RouteManifestShardKind, pathname: string): string {
|
|
30
|
+
const firstSegment = normalizeRoutePath(kind, pathname)[0]
|
|
31
|
+
if (!firstSegment) return ROOT_SHARD_KEY
|
|
32
|
+
if (
|
|
33
|
+
firstSegment.startsWith('[')
|
|
34
|
+
|| firstSegment.startsWith(':')
|
|
35
|
+
|| firstSegment === '*'
|
|
36
|
+
) {
|
|
37
|
+
return DYNAMIC_SHARD_KEY
|
|
38
|
+
}
|
|
39
|
+
return firstSegment.toLowerCase()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function renderArray(entries: RouteManifestShardEntry[]): string {
|
|
43
|
+
if (entries.length === 0) return '[]'
|
|
44
|
+
return `[\n${entries.map((entry) => ` ${entry.declaration}`).join(',\n')}\n]`
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function uniqueImports(entries: RouteManifestShardEntry[]): string[] {
|
|
48
|
+
return Array.from(new Set(entries.flatMap((entry) => entry.imports ?? [])))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function shardStem(kind: RouteManifestShardKind, index: number, key: string): string {
|
|
52
|
+
const safeKey = key.replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
53
|
+
return `${kind}-route-shard.${String(index).padStart(3, '0')}.${safeKey}.generated`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function renderShardFile(kind: RouteManifestShardKind, entries: IndexedRouteManifestShardEntry[]): string {
|
|
57
|
+
const typeName = kind === 'api' ? 'ApiRouteManifestEntry' : 'BackendRouteManifestEntry'
|
|
58
|
+
const helperImport = kind === 'backend' ? 'resolvePageRouteMetadata, ' : ''
|
|
59
|
+
const imports = uniqueImports(entries)
|
|
60
|
+
return `// AUTO-GENERATED by mercato generate registry (request-scoped route shard)\nimport { ${helperImport}type ${typeName} } from '@open-mercato/shared/modules/registry'\n${imports.length ? `${imports.join('\n')}\n` : ''}\nexport const routes: ${typeName}[] = ${renderArray(entries)}\nexport const routeOrders = [${entries.map((entry) => entry.order).join(', ')}]\n\nexport default routes\n`
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function renderLoaderFile(
|
|
64
|
+
kind: RouteManifestShardKind,
|
|
65
|
+
shards: Array<{ key: string; stem: string; orders: number[] }>,
|
|
66
|
+
): string {
|
|
67
|
+
const isApi = kind === 'api'
|
|
68
|
+
const typeName = kind === 'api' ? 'ApiRouteManifestEntry' : 'BackendRouteManifestEntry'
|
|
69
|
+
const functionName = kind === 'api' ? 'loadApiRouteManifestShard' : 'loadBackendRouteManifestShard'
|
|
70
|
+
const ordinalFunctionName = isApi ? 'loadApiRouteManifestByOrdinal' : 'loadBackendRouteManifestByOrdinal'
|
|
71
|
+
const facadeExportName = isApi ? 'apiRouteFacades' : 'backendRouteFacades'
|
|
72
|
+
const metadataExportName = isApi ? 'apiRouteMetadata' : 'backendRouteMetadata'
|
|
73
|
+
const metadataFileName = isApi ? 'api-route-metadata.generated' : 'backend-route-metadata.generated'
|
|
74
|
+
const shardCases = shards
|
|
75
|
+
.map(({ key, stem }) => ` case ${JSON.stringify(key)}:\n return import('./${stem}').then((entry) => ({ routes: entry.routes, routeOrders: entry.routeOrders }))`)
|
|
76
|
+
.join('\n')
|
|
77
|
+
const hasDynamicShard = shards.some(({ key }) => key === DYNAMIC_SHARD_KEY)
|
|
78
|
+
const routeShardKeys: string[] = []
|
|
79
|
+
for (const shard of shards) {
|
|
80
|
+
for (const order of shard.orders) routeShardKeys[order] = shard.key
|
|
81
|
+
}
|
|
82
|
+
const prefixNormalization = kind === 'backend'
|
|
83
|
+
? ` if (segments[0]?.toLowerCase() === 'backend') segments.shift()\n`
|
|
84
|
+
: ''
|
|
85
|
+
const loadDynamic = hasDynamicShard
|
|
86
|
+
? ` const dynamicShard = await loadShard(${JSON.stringify(DYNAMIC_SHARD_KEY)})\n`
|
|
87
|
+
: ` const dynamicShard: LoadedRouteShard = EMPTY_SHARD\n`
|
|
88
|
+
|
|
89
|
+
return `// AUTO-GENERATED by mercato generate registry (request-scoped route loader)\nimport type { ${typeName} } from '@open-mercato/shared/modules/registry'\nimport { ${metadataExportName} } from './${metadataFileName}'\n\ntype LoadedRouteShard = { routes: ${typeName}[]; routeOrders: number[] }\nconst EMPTY_SHARD: LoadedRouteShard = { routes: [], routeOrders: [] }\nconst ROUTE_SHARD_KEYS = ${JSON.stringify(routeShardKeys)}\n\nfunction resolveShardKey(pathname: string): string {\n const segments = pathname.split('?')[0].split('/').filter(Boolean)\n${prefixNormalization} return segments[0]?.toLowerCase() ?? ${JSON.stringify(ROOT_SHARD_KEY)}\n}\n\nasync function loadShard(key: string): Promise<LoadedRouteShard> {\n switch (key) {\n${shardCases ? `${shardCases}\n` : ''} default:\n return EMPTY_SHARD\n }\n}\n\nexport async function ${ordinalFunctionName}(ordinal: number): Promise<${typeName}> {\n const shardKey = ROUTE_SHARD_KEYS[ordinal]\n if (shardKey === undefined) throw new Error('Unknown generated route manifest ordinal: ' + ordinal)\n const shard = await loadShard(shardKey)\n const index = shard.routeOrders.indexOf(ordinal)\n if (index < 0 || !shard.routes[index]) throw new Error('Generated route manifest ordinal is missing from its shard: ' + ordinal)\n return shard.routes[index]\n}\n\nexport const ${facadeExportName}: ${typeName}[] = ${metadataExportName}.map((metadata, ordinal) => ({\n ...metadata,\n load: async () => {\n const route = await ${ordinalFunctionName}(ordinal)\n return route.load()\n },\n}))\n\nexport async function ${functionName}(pathname: string): Promise<${typeName}[]> {\n const exactShard = await loadShard(resolveShardKey(pathname))\n${loadDynamic} return [\n ...exactShard.routes.map((route, index) => ({ route, order: exactShard.routeOrders[index] })),\n ...dynamicShard.routes.map((route, index) => ({ route, order: dynamicShard.routeOrders[index] })),\n ].sort((a, b) => a.order - b.order).map(({ route }) => route)\n}\n`
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function renderRouteManifestShardOutputs(
|
|
93
|
+
kind: RouteManifestShardKind,
|
|
94
|
+
entries: RouteManifestShardEntry[],
|
|
95
|
+
): RouteManifestShardOutput[] {
|
|
96
|
+
const grouped = new Map<string, IndexedRouteManifestShardEntry[]>()
|
|
97
|
+
for (const [order, entry] of entries.entries()) {
|
|
98
|
+
const key = getRouteManifestShardKey(kind, entry.path)
|
|
99
|
+
const existing = grouped.get(key)
|
|
100
|
+
const indexedEntry = { ...entry, order }
|
|
101
|
+
if (existing) existing.push(indexedEntry)
|
|
102
|
+
else grouped.set(key, [indexedEntry])
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const sortedGroups = Array.from(grouped.entries()).sort(([a], [b]) => a.localeCompare(b))
|
|
106
|
+
const shards = sortedGroups.map(([key, shardEntries], index) => {
|
|
107
|
+
const stem = shardStem(kind, index, key)
|
|
108
|
+
return {
|
|
109
|
+
key,
|
|
110
|
+
stem,
|
|
111
|
+
orders: shardEntries.map((entry) => entry.order),
|
|
112
|
+
output: {
|
|
113
|
+
fileName: `${stem}.ts`,
|
|
114
|
+
content: renderShardFile(kind, shardEntries),
|
|
115
|
+
},
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
const loaderFileName = kind === 'api'
|
|
119
|
+
? 'api-route-shards.generated.ts'
|
|
120
|
+
: 'backend-route-shards.generated.ts'
|
|
121
|
+
|
|
122
|
+
return [
|
|
123
|
+
...shards.map(({ output }) => output),
|
|
124
|
+
{
|
|
125
|
+
fileName: loaderFileName,
|
|
126
|
+
content: renderLoaderFile(kind, shards),
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function renderRouteMetadataOutput(
|
|
132
|
+
kind: RouteManifestShardKind,
|
|
133
|
+
entries: RouteManifestShardEntry[],
|
|
134
|
+
): RouteManifestShardOutput {
|
|
135
|
+
const isApi = kind === 'api'
|
|
136
|
+
const manifestType = isApi ? 'ApiRouteManifestEntry' : 'BackendRouteManifestEntry'
|
|
137
|
+
const metadataType = isApi ? 'ApiRouteMetadataEntry' : 'BackendRouteMetadataEntry'
|
|
138
|
+
const exportName = isApi ? 'apiRouteMetadata' : 'backendRouteMetadata'
|
|
139
|
+
const fileName = isApi ? 'api-route-metadata.generated.ts' : 'backend-route-metadata.generated.ts'
|
|
140
|
+
const helperImport = isApi ? '' : 'resolvePageRouteMetadata, '
|
|
141
|
+
const imports = uniqueImports(entries)
|
|
142
|
+
const content = `// AUTO-GENERATED by mercato generate registry (route metadata without component loaders)\nimport { ${helperImport}type ${manifestType} } from '@open-mercato/shared/modules/registry'\n${imports.length ? `${imports.join('\n')}\n` : ''}\nexport type ${metadataType} = Omit<${manifestType}, 'load'>\n\nexport const ${exportName}: ${metadataType}[] = ${renderArray(entries)}\n\nexport default ${exportName}\n`
|
|
143
|
+
return { fileName, content }
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export const routeManifestShardFilePattern = /^(?:api|backend)-route-shard\..+\.generated\.(?:ts|checksum)$/
|
|
@@ -24,6 +24,8 @@ export type GenerateWatcherChangeSignal = {
|
|
|
24
24
|
currentVersion(): number
|
|
25
25
|
/** Refresh filesystem subscriptions after module configuration changes. */
|
|
26
26
|
refresh(): Promise<void> | void
|
|
27
|
+
/** Whether configured roots are missing and should be retried on idle polls. */
|
|
28
|
+
hasSkippedTargets?(): boolean
|
|
27
29
|
/** When true, preserve the legacy full-checksum-on-every-poll behavior. */
|
|
28
30
|
usesPollingFallback(): boolean
|
|
29
31
|
/** Close filesystem subscriptions. Idempotent. */
|
|
@@ -130,16 +132,23 @@ export function startInProcessGenerateWatcher(
|
|
|
130
132
|
if (stopping) return
|
|
131
133
|
try {
|
|
132
134
|
const changeVersion = changeSignal?.currentVersion() ?? 0
|
|
133
|
-
|
|
135
|
+
const eventGatedIdle = Boolean(
|
|
134
136
|
changeSignal
|
|
135
137
|
&& !changeSignal.usesPollingFallback()
|
|
136
138
|
&& changeVersion === observedChangeVersion
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
+
)
|
|
140
|
+
let refreshedSkippedTargets = false
|
|
141
|
+
if (eventGatedIdle) {
|
|
142
|
+
if (!changeSignal?.hasSkippedTargets?.()) return
|
|
143
|
+
await changeSignal.refresh()
|
|
144
|
+
refreshedSkippedTargets = true
|
|
145
|
+
if (changeSignal.hasSkippedTargets?.()) return
|
|
139
146
|
}
|
|
140
147
|
const nextChecksum = await computeStructureChecksum()
|
|
141
148
|
observedChangeVersion = changeVersion
|
|
142
|
-
|
|
149
|
+
if (!refreshedSkippedTargets) {
|
|
150
|
+
await changeSignal?.refresh()
|
|
151
|
+
}
|
|
143
152
|
if (nextChecksum !== previousChecksum) {
|
|
144
153
|
previousChecksum = nextChecksum
|
|
145
154
|
await runOnce('structure change')
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Bootstrap-free `.env` loader for the CLI binary. `bin.ts` must load the app's
|
|
6
|
+
* `.env` BEFORE `initTelemetry()` so `TELEMETRY_*` set only in `.env` resolves a
|
|
7
|
+
* real backend for worker/scheduler processes — `run()`'s `ensureEnvLoaded()`
|
|
8
|
+
* happens after telemetry init, which is too late. Deliberately read-only (no
|
|
9
|
+
* `.env.example` copy — that UX stays in `ensureEnvLoaded`) and pulls in only the
|
|
10
|
+
* resolver + dotenv, so nothing here loads `pg` and the OTEL instrumentation
|
|
11
|
+
* load-order guarantee is preserved.
|
|
12
|
+
*/
|
|
13
|
+
export async function loadAppEnv(options: { cwd?: string } = {}): Promise<void> {
|
|
14
|
+
try {
|
|
15
|
+
const { createResolver } = await import('./resolver.js')
|
|
16
|
+
const appDir = createResolver(options.cwd).getAppDir()
|
|
17
|
+
const envPath = path.join(appDir, '.env')
|
|
18
|
+
if (fs.existsSync(envPath)) {
|
|
19
|
+
const dotenv = await import('dotenv')
|
|
20
|
+
dotenv.config({ path: envPath, quiet: true })
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
// Resolver can fail outside an app dir — fall through to plain cwd loading.
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const dotenv = await import('dotenv')
|
|
28
|
+
dotenv.config({ quiet: true })
|
|
29
|
+
} catch {}
|
|
30
|
+
}
|
|
@@ -32,6 +32,11 @@ import {
|
|
|
32
32
|
import type { ModuleWorker } from '@open-mercato/shared/modules/registry'
|
|
33
33
|
import type { LazyWorkerSpawnMode } from './auto-spawn-workers'
|
|
34
34
|
|
|
35
|
+
export type SupervisorWorkerDescriptor = Pick<
|
|
36
|
+
ModuleWorker,
|
|
37
|
+
'id' | 'moduleId' | 'queue' | 'concurrency'
|
|
38
|
+
>
|
|
39
|
+
|
|
35
40
|
export type LazySupervisorSpawnFn = (
|
|
36
41
|
command: string,
|
|
37
42
|
args: readonly string[],
|
|
@@ -47,7 +52,7 @@ export type LazyWorkerSupervisorOptions = {
|
|
|
47
52
|
mercatoBin: string
|
|
48
53
|
appDir: string
|
|
49
54
|
runtimeEnv: NodeJS.ProcessEnv
|
|
50
|
-
workers:
|
|
55
|
+
workers: readonly SupervisorWorkerDescriptor[]
|
|
51
56
|
pollMs: number
|
|
52
57
|
restartOnUnexpectedExit: boolean
|
|
53
58
|
spawnMode?: LazyWorkerSpawnMode
|
|
@@ -89,7 +94,7 @@ type QueueGroup = {
|
|
|
89
94
|
workerCount: number
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
function groupWorkersByQueue(workers:
|
|
97
|
+
function groupWorkersByQueue(workers: readonly SupervisorWorkerDescriptor[]): QueueGroup[] {
|
|
93
98
|
const groups = new Map<string, QueueGroup>()
|
|
94
99
|
for (const worker of workers) {
|
|
95
100
|
const existing = groups.get(worker.queue)
|
package/src/lib/resolver.ts
CHANGED
|
@@ -25,10 +25,12 @@ export type CliEnvironment = {
|
|
|
25
25
|
export type ModuleEntry = {
|
|
26
26
|
id: string
|
|
27
27
|
from?: '@open-mercato/core' | '@app' | string
|
|
28
|
+
devSupervisorRequiresFullBootstrap?: boolean
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
export type PackageInfo = {
|
|
31
32
|
name: string
|
|
33
|
+
version?: string | null
|
|
32
34
|
path: string
|
|
33
35
|
modulesPath: string
|
|
34
36
|
}
|
|
@@ -88,18 +90,45 @@ function pkgRootFor(rootDir: string, from?: string, isMonorepo = true): string {
|
|
|
88
90
|
function parseModuleEntryFromObjectLiteral(node: ts.ObjectLiteralExpression): ModuleEntry | null {
|
|
89
91
|
let id: string | null = null
|
|
90
92
|
let from: string | null = null
|
|
93
|
+
let devSupervisorRequiresFullBootstrap = false
|
|
91
94
|
for (const property of node.properties) {
|
|
92
|
-
if (!ts.isPropertyAssignment(property)
|
|
93
|
-
const key = property.name.
|
|
95
|
+
if (!ts.isPropertyAssignment(property)) continue
|
|
96
|
+
const key = ts.isIdentifier(property.name) || ts.isStringLiteralLike(property.name)
|
|
97
|
+
? property.name.text
|
|
98
|
+
: null
|
|
94
99
|
if (key === 'id' && ts.isStringLiteralLike(property.initializer)) {
|
|
95
100
|
id = property.initializer.text
|
|
96
101
|
}
|
|
97
102
|
if (key === 'from' && ts.isStringLiteralLike(property.initializer)) {
|
|
98
103
|
from = property.initializer.text
|
|
99
104
|
}
|
|
105
|
+
if (key === 'overrides') {
|
|
106
|
+
if (!ts.isObjectLiteralExpression(property.initializer)) {
|
|
107
|
+
devSupervisorRequiresFullBootstrap = true
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
for (const overrideProperty of property.initializer.properties) {
|
|
111
|
+
if (ts.isSpreadAssignment(overrideProperty)) {
|
|
112
|
+
devSupervisorRequiresFullBootstrap = true
|
|
113
|
+
break
|
|
114
|
+
}
|
|
115
|
+
if (!ts.isPropertyAssignment(overrideProperty)) continue
|
|
116
|
+
const overrideKey = ts.isIdentifier(overrideProperty.name) || ts.isStringLiteralLike(overrideProperty.name)
|
|
117
|
+
? overrideProperty.name.text
|
|
118
|
+
: null
|
|
119
|
+
if (overrideKey === 'workers' || overrideKey === 'cli') {
|
|
120
|
+
devSupervisorRequiresFullBootstrap = true
|
|
121
|
+
break
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
100
125
|
}
|
|
101
126
|
if (!id) return null
|
|
102
|
-
return {
|
|
127
|
+
return {
|
|
128
|
+
id,
|
|
129
|
+
from: from ?? '@open-mercato/core',
|
|
130
|
+
...(devSupervisorRequiresFullBootstrap ? { devSupervisorRequiresFullBootstrap: true } : {}),
|
|
131
|
+
}
|
|
103
132
|
}
|
|
104
133
|
|
|
105
134
|
function parseProcessEnvAccess(
|
|
@@ -356,6 +385,7 @@ function discoverPackagesInMonorepo(rootDir: string): PackageInfo[] {
|
|
|
356
385
|
if (fs.existsSync(modulesPath)) {
|
|
357
386
|
packages.push({
|
|
358
387
|
name: pkgJson.name || `@open-mercato/${entry.name}`,
|
|
388
|
+
version: typeof pkgJson.version === 'string' ? pkgJson.version : null,
|
|
359
389
|
path: pkgPath,
|
|
360
390
|
modulesPath,
|
|
361
391
|
})
|
|
@@ -391,6 +421,7 @@ function discoverPackagesInNodeModules(rootDir: string): PackageInfo[] {
|
|
|
391
421
|
if (fs.existsSync(modulesPath)) {
|
|
392
422
|
packages.push({
|
|
393
423
|
name: pkgJson.name || `@open-mercato/${entry.name}`,
|
|
424
|
+
version: typeof pkgJson.version === 'string' ? pkgJson.version : null,
|
|
394
425
|
path: pkgPath,
|
|
395
426
|
modulesPath,
|
|
396
427
|
})
|