@open-mercato/cli 0.6.7-develop.6862.1.c11a64ce0a → 0.6.7
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 +4 -4
- package/build.mjs +7 -24
- package/dist/agentic/claude-code/hooks/entity-migration-check.ts +88 -32
- package/dist/agentic/codex/enforcement-rules.md +16 -2
- package/dist/agentic/cursor/hooks/entity-migration-check.mjs +50 -19
- package/dist/agentic/cursor/rules/entity-guard.mdc +21 -9
- package/dist/agentic/cursor/rules/generated-guard.mdc +5 -3
- package/dist/agentic/cursor/rules/open-mercato.mdc +29 -3
- package/dist/agentic/guides/cache.md +45 -0
- package/dist/agentic/guides/core.md +453 -0
- package/dist/agentic/guides/events.md +117 -0
- package/dist/agentic/guides/module-facts.json +3833 -115419
- package/dist/agentic/guides/module-system.md +127 -12
- package/dist/agentic/guides/modules/ai_assistant.md +28 -227
- package/dist/agentic/guides/modules/api_docs.md +2 -58
- package/dist/agentic/guides/modules/api_keys.md +7 -92
- package/dist/agentic/guides/modules/attachments.md +14 -119
- package/dist/agentic/guides/modules/audit_logs.md +10 -131
- package/dist/agentic/guides/modules/auth.md +33 -276
- package/dist/agentic/guides/modules/business_rules.md +14 -149
- package/dist/agentic/guides/modules/catalog.md +43 -475
- package/dist/agentic/guides/modules/channel_gmail.md +3 -82
- package/dist/agentic/guides/modules/channel_imap.md +3 -82
- package/dist/agentic/guides/modules/checkout.md +27 -299
- package/dist/agentic/guides/modules/communication_channels.md +33 -315
- package/dist/agentic/guides/modules/configs.md +8 -104
- package/dist/agentic/guides/modules/content.md +2 -57
- package/dist/agentic/guides/modules/currencies.md +17 -152
- package/dist/agentic/guides/modules/customer_accounts.md +45 -387
- package/dist/agentic/guides/modules/customers.md +85 -746
- package/dist/agentic/guides/modules/dashboards.md +10 -155
- package/dist/agentic/guides/modules/data_sync.md +16 -149
- package/dist/agentic/guides/modules/dictionaries.md +12 -107
- package/dist/agentic/guides/modules/directory.md +15 -148
- package/dist/agentic/guides/modules/entities.md +13 -145
- package/dist/agentic/guides/modules/events.md +2 -59
- package/dist/agentic/guides/modules/feature_toggles.md +9 -119
- package/dist/agentic/guides/modules/gateway_stripe.md +4 -92
- package/dist/agentic/guides/modules/generators.md +2 -45
- package/dist/agentic/guides/modules/inbox_ops.md +27 -207
- package/dist/agentic/guides/modules/integrations.md +16 -146
- package/dist/agentic/guides/modules/messages.md +24 -223
- package/dist/agentic/guides/modules/notifications.md +8 -96
- package/dist/agentic/guides/modules/onboarding.md +6 -77
- package/dist/agentic/guides/modules/payment_gateways.md +21 -164
- package/dist/agentic/guides/modules/perspectives.md +7 -77
- package/dist/agentic/guides/modules/planner.md +18 -136
- package/dist/agentic/guides/modules/portal.md +2 -93
- package/dist/agentic/guides/modules/progress.md +14 -104
- package/dist/agentic/guides/modules/query_index.md +15 -154
- package/dist/agentic/guides/modules/record_locks.md +21 -206
- package/dist/agentic/guides/modules/resources.md +30 -197
- package/dist/agentic/guides/modules/sales.md +84 -678
- package/dist/agentic/guides/modules/scheduler.md +14 -133
- package/dist/agentic/guides/modules/search.md +6 -170
- package/dist/agentic/guides/modules/security.md +35 -294
- package/dist/agentic/guides/modules/shipping_carriers.md +18 -134
- package/dist/agentic/guides/modules/sso.md +26 -151
- package/dist/agentic/guides/modules/staff.md +57 -369
- package/dist/agentic/guides/modules/storage_s3.md +5 -95
- package/dist/agentic/guides/modules/sync_akeneo.md +3 -85
- package/dist/agentic/guides/modules/sync_excel.md +6 -75
- package/dist/agentic/guides/modules/system_status_overlays.md +2 -60
- package/dist/agentic/guides/modules/translations.md +10 -104
- package/dist/agentic/guides/modules/webhooks.md +24 -203
- package/dist/agentic/guides/modules/wms.md +46 -441
- package/dist/agentic/guides/modules/workflows.md +43 -302
- package/dist/agentic/guides/queue.md +53 -0
- package/dist/agentic/guides/search.md +115 -0
- package/dist/agentic/guides/shared.md +108 -0
- package/dist/agentic/guides/ui.md +347 -0
- package/dist/agentic/shared/AGENTS.md.template +311 -124
- package/dist/agentic/shared/ai/agentic.config.json +0 -2
- package/dist/agentic/shared/ai/lessons.md +3 -26
- package/dist/agentic/shared/ai/skills/om-auto-continue-pr-loop/SKILL.md +27 -0
- package/dist/agentic/shared/ai/skills/om-auto-create-pr-loop/SKILL.md +27 -0
- package/dist/agentic/shared/ai/skills/om-auto-review-pr/SKILL.md +0 -4
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/SKILL.md +241 -20
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/ui-components.md +260 -0
- package/dist/agentic/shared/ai/skills/om-data-model-design/SKILL.md +601 -16
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md +146 -0
- package/dist/agentic/shared/ai/skills/om-eject-and-customize/SKILL.md +310 -14
- package/dist/agentic/shared/ai/skills/om-help/SKILL.md +97 -15
- package/dist/agentic/shared/ai/skills/om-help/references/skills-catalog.md +84 -0
- package/dist/agentic/shared/ai/skills/om-help/references/workflow-sequences.md +193 -0
- package/dist/agentic/shared/ai/skills/om-implement-spec/SKILL.md +152 -33
- package/dist/agentic/shared/ai/skills/om-integration-builder/SKILL.md +708 -24
- package/dist/agentic/shared/ai/skills/om-integration-builder/STANDALONE.md +34 -0
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/adapter-contracts.md +762 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/SKILL.md +820 -20
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/naming-conventions.md +50 -0
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/navigation-patterns.md +97 -0
- package/dist/agentic/shared/ai/skills/om-system-extension/SKILL.md +843 -19
- package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-contracts.md +271 -0
- package/dist/agentic/shared/ai/skills/om-trim-unused-modules/SKILL.md +63 -15
- package/dist/agentic/shared/ai/skills/om-troubleshooter/SKILL.md +467 -16
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnostic-commands.md +101 -0
- package/dist/agentic/shared/ai/skills/tiers.json +21 -143
- package/dist/agentic/shared/ai/skills/tiers.schema.json +40 -52
- package/dist/agentic/shared/ai/specs/README.md +3 -4
- package/dist/agentic/shared/ai/specs/SPEC-000-template.md +10 -226
- package/dist/agentic/shared/ai/trackers/github.md +4 -108
- package/dist/agentic/shared/scripts/install-skills.sh +694 -4
- package/dist/bin.js +1 -13
- package/dist/bin.js.map +2 -2
- package/dist/lib/__integration__/TC-INT-008.spec.js +8 -88
- package/dist/lib/__integration__/TC-INT-008.spec.js.map +2 -2
- package/dist/lib/agentic-init.js +3 -13
- package/dist/lib/agentic-init.js.map +2 -2
- package/dist/lib/agentic-setup.js +186 -418
- package/dist/lib/agentic-setup.js.map +2 -2
- package/dist/lib/generators/extensions/injection-widgets.js +0 -20
- package/dist/lib/generators/extensions/injection-widgets.js.map +2 -2
- package/dist/lib/generators/module-facts-discovery.js +7 -41
- package/dist/lib/generators/module-facts-discovery.js.map +2 -2
- package/dist/lib/generators/module-facts.js +45 -1387
- package/dist/lib/generators/module-facts.js.map +3 -3
- package/dist/lib/generators/module-registry.js +5 -11
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/resolver.js +0 -2
- package/dist/lib/resolver.js.map +2 -2
- package/dist/lib/testing/integration.js +0 -5
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/mercato.js +1 -23
- package/dist/mercato.js.map +2 -2
- package/package.json +11 -13
- package/src/bin.ts +1 -33
- package/src/lib/__integration__/TC-INT-008.spec.ts +9 -107
- package/src/lib/__tests__/agentic-init.test.ts +5 -41
- package/src/lib/agentic-init.ts +3 -15
- package/src/lib/agentic-setup.ts +224 -530
- package/src/lib/generators/__tests__/module-facts.bc-guard.test.ts +2 -88
- package/src/lib/generators/__tests__/module-facts.customers.fixture.test.ts +0 -1
- package/src/lib/generators/__tests__/module-facts.discovery.test.ts +10 -54
- package/src/lib/generators/__tests__/module-subset.test.ts +0 -18
- package/src/lib/generators/extensions/injection-widgets.ts +0 -51
- package/src/lib/generators/module-facts-discovery.ts +7 -58
- package/src/lib/generators/module-facts.ts +46 -1851
- package/src/lib/generators/module-registry.ts +6 -16
- package/src/lib/resolver.ts +0 -3
- package/src/lib/testing/__tests__/integration.test.ts +0 -4
- package/src/lib/testing/integration.ts +0 -5
- package/src/mercato.ts +1 -26
- package/dist/agentic/guides/ai-workflows.md +0 -76
- package/dist/agentic/guides/architecture.md +0 -107
- package/dist/agentic/guides/backend-ui.md +0 -80
- package/dist/agentic/guides/contracts.md +0 -92
- package/dist/agentic/guides/extensions.md +0 -121
- package/dist/agentic/guides/framework-extension-points.md +0 -36
- package/dist/agentic/guides/integrations.md +0 -81
- package/dist/agentic/guides/modules/design_system.md +0 -102
- package/dist/agentic/guides/spec-delivery.md +0 -22
- package/dist/agentic/guides/testing-debugging.md +0 -80
- package/dist/agentic/guides/upstream/AGENTS.md +0 -298
- package/dist/agentic/guides/upstream/BACKWARD_COMPATIBILITY.md +0 -316
- package/dist/agentic/guides/upstream/manifest.json +0 -8
- package/dist/agentic/shared/ai/harness/README.md +0 -50
- package/dist/agentic/shared/ai/harness/RELEASE.md +0 -57
- package/dist/agentic/shared/ai/harness/cases.json +0 -13680
- package/dist/agentic/shared/ai/harness/cases.schema.json +0 -133
- package/dist/agentic/shared/ai/harness/fixtures/index.json +0 -49
- package/dist/agentic/shared/ai/harness/fixtures/seeds.json +0 -162
- package/dist/agentic/shared/ai/harness/generated-code-review-policy.md +0 -21
- package/dist/agentic/shared/ai/harness/generated-code-review-response.schema.json +0 -96
- package/dist/agentic/shared/ai/harness/generated-code-review-result.schema.json +0 -172
- package/dist/agentic/shared/ai/harness/release-matrix.json +0 -158
- package/dist/agentic/shared/ai/harness/release-result.schema.json +0 -219
- package/dist/agentic/shared/ai/harness/result.schema.json +0 -76
- package/dist/agentic/shared/ai/harness/routing-response.schema.json +0 -12
- package/dist/agentic/shared/ai/harness/target-validation-result.schema.json +0 -73
- package/dist/agentic/shared/ai/harness/validators.json +0 -78
- package/dist/agentic/shared/ai/harness/writable-ast-oracles.mjs +0 -2121
- package/dist/agentic/shared/ai/harness/writable-behavior-oracles.mjs +0 -1096
- package/dist/agentic/shared/ai/lessons/_template.md +0 -16
- package/dist/agentic/shared/ai/review-checklist.md +0 -36
- package/dist/agentic/shared/ai/skills/om-auto-implement-spec/SKILL.md +0 -21
- package/dist/agentic/shared/ai/skills/om-auto-upgrade-0.6.6-to-0.6.7/SKILL.md +0 -98
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/crud-surfaces.md +0 -16
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/frontend-and-design-system.md +0 -53
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/page-and-navigation.md +0 -13
- package/dist/agentic/shared/ai/skills/om-backend-ui-design/references/quality-states.md +0 -11
- package/dist/agentic/shared/ai/skills/om-build-workflow/SKILL.md +0 -30
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/activity-contracts.md +0 -12
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/durability-and-progress.md +0 -13
- package/dist/agentic/shared/ai/skills/om-build-workflow/references/workflow-design.md +0 -14
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/SKILL.md +0 -28
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/attachments-and-overrides.md +0 -12
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/module-agents-and-tools.md +0 -22
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/orchestrator-agents.md +0 -12
- package/dist/agentic/shared/ai/skills/om-create-ai-agent/references/surface-selector.md +0 -19
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/integrity-and-concurrency.md +0 -19
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/migration-workflow.md +0 -13
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/schema-design.md +0 -14
- package/dist/agentic/shared/ai/skills/om-data-model-design/references/sensitive-data.md +0 -10
- package/dist/agentic/shared/ai/skills/om-eject-and-customize/references/decision-and-procedure.md +0 -17
- package/dist/agentic/shared/ai/skills/om-evolve-harness/SKILL.md +0 -29
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-template.md +0 -100
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/case-workflow.md +0 -16
- package/dist/agentic/shared/ai/skills/om-evolve-harness/references/owner-selection.md +0 -17
- package/dist/agentic/shared/ai/skills/om-framework-context/SKILL.md +0 -25
- package/dist/agentic/shared/ai/skills/om-framework-context/references/resolver-procedure.md +0 -11
- package/dist/agentic/shared/ai/skills/om-framework-context/references/skew-and-escalation.md +0 -13
- package/dist/agentic/shared/ai/skills/om-help/references/delivery-workflows.md +0 -18
- package/dist/agentic/shared/ai/skills/om-help/references/task-families.md +0 -20
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/phases-and-gates.md +0 -33
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/planning-and-progress.md +0 -40
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/report-templates.md +0 -27
- package/dist/agentic/shared/ai/skills/om-implement-spec/references/spec-resolution.md +0 -24
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/package-and-activation.md +0 -16
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/provider-families.md +0 -14
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/security-and-reliability.md +0 -15
- package/dist/agentic/shared/ai/skills/om-integration-builder/references/sync-and-files.md +0 -12
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/SKILL.md +0 -34
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/agents/openai.yaml +0 -4
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/agentic-setup.md +0 -11
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/input-normalization.md +0 -31
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/judge-workflow.md +0 -39
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/report-template.md +0 -43
- package/dist/agentic/shared/ai/skills/om-judge-agent-session/references/rules.md +0 -11
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/api-and-domain.md +0 -19
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/business-one-shot-blueprints.md +0 -172
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/data-and-migrations.md +0 -12
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/discovery-surface-catalog.md +0 -83
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/module-surfaces.md +0 -21
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/planning.md +0 -11
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/runtime-cache-and-queues.md +0 -22
- package/dist/agentic/shared/ai/skills/om-module-scaffold/references/verification.md +0 -13
- package/dist/agentic/shared/ai/skills/om-share-this-session/SKILL.md +0 -41
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/agentic-setup.md +0 -19
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/bundle-preparation.md +0 -44
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/consent-and-review.md +0 -39
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/publication.md +0 -20
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/report-templates.md +0 -57
- package/dist/agentic/shared/ai/skills/om-share-this-session/references/rules.md +0 -11
- package/dist/agentic/shared/ai/skills/om-share-this-session/scripts/prepare-share-bundle.mjs +0 -486
- package/dist/agentic/shared/ai/skills/om-system-extension/references/extension-branches.md +0 -18
- package/dist/agentic/shared/ai/skills/om-system-extension/references/mechanism-selector.md +0 -27
- package/dist/agentic/shared/ai/skills/om-system-extension/references/read-write-roundtrip.md +0 -13
- package/dist/agentic/shared/ai/skills/om-system-extension/references/unified-overrides.md +0 -41
- package/dist/agentic/shared/ai/skills/om-system-extension/references/verification.md +0 -11
- package/dist/agentic/shared/ai/skills/om-trim-unused-modules/references/dependency-and-redirect.md +0 -15
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/diagnosis-map.md +0 -16
- package/dist/agentic/shared/ai/skills/om-troubleshooter/references/regression-oracles.md +0 -14
- package/dist/agentic/shared/scripts/agent-harness-tool-server.mjs +0 -187
- package/dist/agentic/shared/scripts/check-lessons.mjs +0 -178
- package/dist/agentic/shared/scripts/evaluate-agent-harness.mjs +0 -2958
- package/dist/agentic/shared/scripts/execution-sandbox.mjs +0 -329
- package/dist/agentic/shared/scripts/framework-context.mjs +0 -888
- package/dist/agentic/shared/scripts/install-skills.mjs +0 -1029
- package/dist/agentic/shared/scripts/prepare-agent-harness-fixture.mjs +0 -222
- package/dist/agentic/shared/scripts/run-agent-harness-release.mjs +0 -1774
- package/dist/lib/generators/module-extension-facts.js +0 -1840
- package/dist/lib/generators/module-extension-facts.js.map +0 -7
- package/dist/lib/generators/module-fact-sources.js +0 -70
- package/dist/lib/generators/module-fact-sources.js.map +0 -7
- package/dist/lib/generators/module-override-targets.js +0 -688
- package/dist/lib/generators/module-override-targets.js.map +0 -7
- package/dist/lib/load-env.js +0 -24
- package/dist/lib/load-env.js.map +0 -7
- package/dist/lib/telemetry-init.js +0 -358
- package/dist/lib/telemetry-init.js.map +0 -7
- package/src/lib/__tests__/agentic-setup.ownership.test.ts +0 -386
- package/src/lib/__tests__/injection-widget-id-validation.test.ts +0 -184
- package/src/lib/__tests__/load-env.test.ts +0 -65
- package/src/lib/__tests__/telemetry-init.test.ts +0 -298
- package/src/lib/generators/__tests__/activation-adapter-coverage.test.ts +0 -92
- package/src/lib/generators/__tests__/module-extension-activations.test.ts +0 -762
- package/src/lib/generators/__tests__/module-extension-facts.test.ts +0 -404
- package/src/lib/generators/__tests__/module-facts.extension-hosts.test.ts +0 -108
- package/src/lib/generators/__tests__/module-facts.owned-contracts.test.ts +0 -561
- package/src/lib/generators/__tests__/module-facts.source-links.test.ts +0 -119
- package/src/lib/generators/__tests__/module-override-targets.roundtrip.test.ts +0 -149
- package/src/lib/generators/__tests__/module-override-targets.test.ts +0 -304
- package/src/lib/generators/module-extension-facts.ts +0 -2365
- package/src/lib/generators/module-fact-sources.ts +0 -108
- package/src/lib/generators/module-override-targets.ts +0 -863
- package/src/lib/load-env.ts +0 -30
- package/src/lib/telemetry-init.ts +0 -461
|
@@ -1,27 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
chmodSync,
|
|
3
|
-
copyFileSync,
|
|
4
|
-
existsSync,
|
|
5
|
-
lstatSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
mkdtempSync,
|
|
8
|
-
readFileSync,
|
|
9
|
-
readdirSync,
|
|
10
|
-
realpathSync,
|
|
11
|
-
renameSync,
|
|
12
|
-
rmSync,
|
|
13
|
-
statSync,
|
|
14
|
-
writeFileSync
|
|
15
|
-
} from "node:fs";
|
|
16
|
-
import { createHash } from "node:crypto";
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, symlinkSync, lstatSync, unlinkSync, readdirSync } from "node:fs";
|
|
17
2
|
import { spawnSync } from "node:child_process";
|
|
18
|
-
import {
|
|
19
|
-
import { join, dirname, basename, relative, resolve, sep } from "node:path";
|
|
3
|
+
import { join, dirname, basename } from "node:path";
|
|
20
4
|
import { fileURLToPath } from "node:url";
|
|
21
5
|
import { Project, SyntaxKind } from "ts-morph";
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const AGENTIC_DIR = existsSync(bundledAgenticDir) ? bundledAgenticDir : join(moduleDir, "..", "..", "..", "create-app", "agentic");
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const AGENTIC_DIR = join(__dirname, "..", "agentic");
|
|
25
8
|
const GUIDES_DIR = join(AGENTIC_DIR, "guides");
|
|
26
9
|
function resolvePlaceholders(content, config) {
|
|
27
10
|
return content.replace(/\{\{PROJECT_NAME\}\}/g, config.projectName);
|
|
@@ -42,13 +25,13 @@ function copyFile(srcDir, srcRelative, destPath) {
|
|
|
42
25
|
copyFileSync(srcPath, destPath);
|
|
43
26
|
}
|
|
44
27
|
function readEnabledModuleIds(modulesPath) {
|
|
45
|
-
if (!existsSync(modulesPath)) return
|
|
28
|
+
if (!existsSync(modulesPath)) return [];
|
|
46
29
|
try {
|
|
47
30
|
const project = new Project({ useInMemoryFileSystem: true });
|
|
48
31
|
const sourceFile = project.createSourceFile("modules.ts", readFileSync(modulesPath, "utf-8"));
|
|
49
32
|
const declaration = sourceFile.getVariableDeclaration("enabledModules");
|
|
50
33
|
const arrayLiteral = declaration?.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);
|
|
51
|
-
if (!arrayLiteral) return
|
|
34
|
+
if (!arrayLiteral) return [];
|
|
52
35
|
const ids = [];
|
|
53
36
|
for (const element of arrayLiteral.getElements()) {
|
|
54
37
|
const objectLiteral = element.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
@@ -57,31 +40,44 @@ function readEnabledModuleIds(modulesPath) {
|
|
|
57
40
|
const idValue = idProperty?.getInitializerIfKind(SyntaxKind.StringLiteral)?.getLiteralValue();
|
|
58
41
|
if (idValue) ids.push(idValue);
|
|
59
42
|
}
|
|
60
|
-
return
|
|
43
|
+
return ids;
|
|
61
44
|
} catch {
|
|
62
|
-
return
|
|
45
|
+
return [];
|
|
63
46
|
}
|
|
64
47
|
}
|
|
65
48
|
function selectModuleFactSheets(targetDir, modulesSubdir) {
|
|
66
49
|
const available = existsSync(modulesSubdir) ? readdirSync(modulesSubdir).filter((file) => file.endsWith(".md")).map((file) => file.replace(/\.md$/, "")) : [];
|
|
67
50
|
if (available.length === 0) return [];
|
|
68
|
-
const
|
|
69
|
-
if (!parsed.parsed) return available;
|
|
70
|
-
const enabled = new Set(parsed.ids);
|
|
51
|
+
const enabled = new Set(readEnabledModuleIds(join(targetDir, "src", "modules.ts")));
|
|
71
52
|
const selected = available.filter((moduleId) => enabled.has(moduleId));
|
|
72
|
-
return selected;
|
|
53
|
+
return selected.length > 0 ? selected : available;
|
|
73
54
|
}
|
|
74
55
|
const MODULE_GUIDES_START = "<!-- om:module-guides:start -->";
|
|
75
56
|
const MODULE_GUIDES_END = "<!-- om:module-guides:end -->";
|
|
76
|
-
function
|
|
57
|
+
function readModuleGuideLabels(guidesDir) {
|
|
58
|
+
const factsPath = join(guidesDir, "module-facts.json");
|
|
59
|
+
if (!existsSync(factsPath)) return {};
|
|
60
|
+
try {
|
|
61
|
+
const parsed = JSON.parse(readFileSync(factsPath, "utf-8"));
|
|
62
|
+
const labels = {};
|
|
63
|
+
for (const [moduleId, entry] of Object.entries(parsed)) {
|
|
64
|
+
const label = entry && typeof entry.description === "string" && entry.description || entry && typeof entry.title === "string" && entry.title || "";
|
|
65
|
+
if (label) labels[moduleId] = label;
|
|
66
|
+
}
|
|
67
|
+
return labels;
|
|
68
|
+
} catch {
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function renderModuleGuidesBlock(selected, labels) {
|
|
77
73
|
if (selected.length === 0) return "_No module fact-sheets are bundled for this app._";
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
].join("\n");
|
|
74
|
+
const rows = selected.map((moduleId) => {
|
|
75
|
+
const label = labels[moduleId] ?? `Use the ${moduleId} module`;
|
|
76
|
+
return `| ${label} | \`.ai/guides/modules/${moduleId}.md\` |`;
|
|
77
|
+
});
|
|
78
|
+
return ["| Task | Load |", "|---|---|", ...rows].join("\n");
|
|
83
79
|
}
|
|
84
|
-
function injectModuleGuides(agentsMdPath, selected) {
|
|
80
|
+
function injectModuleGuides(agentsMdPath, selected, labels = {}) {
|
|
85
81
|
if (!existsSync(agentsMdPath)) return;
|
|
86
82
|
const content = readFileSync(agentsMdPath, "utf-8");
|
|
87
83
|
const startIndex = content.indexOf(MODULE_GUIDES_START);
|
|
@@ -95,333 +91,154 @@ function injectModuleGuides(agentsMdPath, selected) {
|
|
|
95
91
|
const before = content.slice(0, startIndex + MODULE_GUIDES_START.length);
|
|
96
92
|
const after = content.slice(endIndex);
|
|
97
93
|
const next = `${before}
|
|
98
|
-
${renderModuleGuidesBlock(selected)}
|
|
94
|
+
${renderModuleGuidesBlock(selected, labels)}
|
|
99
95
|
${after}`;
|
|
100
96
|
if (next !== content) writeFileSync(agentsMdPath, next);
|
|
101
97
|
}
|
|
102
|
-
|
|
103
|
-
function isTextAsset(path) {
|
|
104
|
-
const dot = path.lastIndexOf(".");
|
|
105
|
-
return dot === -1 || TEXT_EXTENSIONS.has(path.slice(dot));
|
|
106
|
-
}
|
|
107
|
-
function listFiles(root) {
|
|
108
|
-
if (!existsSync(root)) return [];
|
|
109
|
-
const files = [];
|
|
110
|
-
for (const entry of readdirSync(root, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
111
|
-
const absolute = join(root, entry.name);
|
|
112
|
-
if (entry.isDirectory()) files.push(...listFiles(absolute));
|
|
113
|
-
else if (entry.isFile()) files.push(absolute);
|
|
114
|
-
}
|
|
115
|
-
return files;
|
|
116
|
-
}
|
|
117
|
-
function copyTree(sourceRoot, destinationRoot, config) {
|
|
118
|
-
for (const sourcePath of listFiles(sourceRoot)) {
|
|
119
|
-
const destinationPath = join(destinationRoot, relative(sourceRoot, sourcePath));
|
|
120
|
-
ensureDir(destinationPath);
|
|
121
|
-
if (isTextAsset(sourcePath)) {
|
|
122
|
-
writeFileSync(destinationPath, resolvePlaceholders(readFileSync(sourcePath, "utf8"), config));
|
|
123
|
-
} else {
|
|
124
|
-
copyFileSync(sourcePath, destinationPath);
|
|
125
|
-
}
|
|
126
|
-
if (process.platform !== "win32") chmodSync(destinationPath, statSync(sourcePath).mode & 511);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
function hashFile(path) {
|
|
130
|
-
return createHash("sha256").update(readFileSync(path)).digest("hex");
|
|
131
|
-
}
|
|
132
|
-
function canonicalHarnessRoot(root) {
|
|
133
|
-
const resolved = resolve(root);
|
|
134
|
-
if (!existsSync(resolved)) {
|
|
135
|
-
throw new Error(`Harness root must be an existing directory: ${resolved}`);
|
|
136
|
-
}
|
|
137
|
-
const canonical = realpathSync(resolved);
|
|
138
|
-
const entry = lstatSync(canonical, { throwIfNoEntry: false });
|
|
139
|
-
if (!entry || !entry.isDirectory()) {
|
|
140
|
-
throw new Error(`Harness root must be an existing directory: ${resolved}`);
|
|
141
|
-
}
|
|
142
|
-
return canonical;
|
|
143
|
-
}
|
|
144
|
-
function assertManagedPath(root, path, options = {}) {
|
|
145
|
-
const absolutePath = resolve(path);
|
|
146
|
-
const normalizedRelative = relative(root, absolutePath);
|
|
147
|
-
if (normalizedRelative === ".." || normalizedRelative.startsWith(`..${sep}`)) {
|
|
148
|
-
throw new Error(`Harness-managed path escapes its root: ${absolutePath}`);
|
|
149
|
-
}
|
|
150
|
-
if (normalizedRelative === "") return;
|
|
151
|
-
const components = normalizedRelative.split(sep).filter(Boolean);
|
|
152
|
-
let current = root;
|
|
153
|
-
for (let index = 0; index < components.length; index += 1) {
|
|
154
|
-
current = join(current, components[index]);
|
|
155
|
-
const entry = lstatSync(current, { throwIfNoEntry: false });
|
|
156
|
-
if (!entry) return;
|
|
157
|
-
if (entry.isSymbolicLink()) {
|
|
158
|
-
throw new Error(`Harness-managed path contains a symbolic-link component: ${current}`);
|
|
159
|
-
}
|
|
160
|
-
const isLeaf = index === components.length - 1;
|
|
161
|
-
if (!isLeaf && !entry.isDirectory()) {
|
|
162
|
-
throw new Error(`Harness-managed path component is not a directory: ${current}`);
|
|
163
|
-
}
|
|
164
|
-
if (isLeaf && options.leaf === "file" && !entry.isFile()) {
|
|
165
|
-
throw new Error(`Harness-managed file is not a regular file: ${current}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
function ensureManagedParent(root, filePath) {
|
|
170
|
-
const parent = dirname(filePath);
|
|
171
|
-
const normalizedRelative = relative(root, parent);
|
|
172
|
-
if (normalizedRelative === ".." || normalizedRelative.startsWith(`..${sep}`)) {
|
|
173
|
-
throw new Error(`Harness-managed path escapes its root: ${filePath}`);
|
|
174
|
-
}
|
|
175
|
-
let current = root;
|
|
176
|
-
for (const component of normalizedRelative.split(sep).filter(Boolean)) {
|
|
177
|
-
assertManagedPath(root, current);
|
|
178
|
-
current = join(current, component);
|
|
179
|
-
const entry = lstatSync(current, { throwIfNoEntry: false });
|
|
180
|
-
if (!entry) mkdirSync(current);
|
|
181
|
-
const created = lstatSync(current, { throwIfNoEntry: false });
|
|
182
|
-
if (!created || created.isSymbolicLink() || !created.isDirectory()) {
|
|
183
|
-
throw new Error(`Harness-managed path component is not a real directory: ${current}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
function harnessGeneratorId() {
|
|
188
|
-
try {
|
|
189
|
-
const upstream = JSON.parse(readFileSync(join(GUIDES_DIR, "upstream", "manifest.json"), "utf8"));
|
|
190
|
-
const generator = typeof upstream.generator === "string" ? upstream.generator : "";
|
|
191
|
-
const version = generator.slice(generator.lastIndexOf("@") + 1);
|
|
192
|
-
if (version && version !== generator) return `open-mercato-agentic@${version}`;
|
|
193
|
-
} catch {
|
|
194
|
-
}
|
|
195
|
-
return "open-mercato-agentic@unknown";
|
|
196
|
-
}
|
|
197
|
-
function externalSkillNames(targetDir) {
|
|
198
|
-
try {
|
|
199
|
-
const tiers = JSON.parse(readFileSync(join(targetDir, ".ai", "skills", "tiers.json"), "utf8"));
|
|
200
|
-
return new Set(Array.isArray(tiers.external?.skills) ? tiers.external.skills.filter((name) => typeof name === "string") : []);
|
|
201
|
-
} catch {
|
|
202
|
-
return /* @__PURE__ */ new Set();
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
function atomicCopyFile(sourcePath, destinationPath, managedRoot) {
|
|
206
|
-
if (managedRoot) {
|
|
207
|
-
assertManagedPath(managedRoot, destinationPath, { leaf: "file" });
|
|
208
|
-
ensureManagedParent(managedRoot, destinationPath);
|
|
209
|
-
} else {
|
|
210
|
-
ensureDir(destinationPath);
|
|
211
|
-
}
|
|
212
|
-
const temporaryPath = `${destinationPath}.tmp-${process.pid}-${Date.now()}`;
|
|
213
|
-
try {
|
|
214
|
-
if (managedRoot) assertManagedPath(managedRoot, temporaryPath, { leaf: "file" });
|
|
215
|
-
copyFileSync(sourcePath, temporaryPath);
|
|
216
|
-
if (process.platform !== "win32") chmodSync(temporaryPath, statSync(sourcePath).mode & 511);
|
|
217
|
-
if (managedRoot) {
|
|
218
|
-
assertManagedPath(managedRoot, dirname(destinationPath));
|
|
219
|
-
assertManagedPath(managedRoot, destinationPath, { leaf: "file" });
|
|
220
|
-
assertManagedPath(managedRoot, temporaryPath, { leaf: "file" });
|
|
221
|
-
}
|
|
222
|
-
renameSync(temporaryPath, destinationPath);
|
|
223
|
-
} finally {
|
|
224
|
-
if (!managedRoot || !lstatSync(temporaryPath, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
225
|
-
rmSync(temporaryPath, { force: true });
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
function atomicWriteFile(destinationPath, content, managedRoot) {
|
|
230
|
-
if (managedRoot) {
|
|
231
|
-
assertManagedPath(managedRoot, destinationPath, { leaf: "file" });
|
|
232
|
-
ensureManagedParent(managedRoot, destinationPath);
|
|
233
|
-
} else {
|
|
234
|
-
ensureDir(destinationPath);
|
|
235
|
-
}
|
|
236
|
-
const temporaryPath = `${destinationPath}.tmp-${process.pid}-${Date.now()}`;
|
|
237
|
-
try {
|
|
238
|
-
if (managedRoot) assertManagedPath(managedRoot, temporaryPath, { leaf: "file" });
|
|
239
|
-
writeFileSync(temporaryPath, content);
|
|
240
|
-
if (managedRoot) {
|
|
241
|
-
assertManagedPath(managedRoot, dirname(destinationPath));
|
|
242
|
-
assertManagedPath(managedRoot, destinationPath, { leaf: "file" });
|
|
243
|
-
assertManagedPath(managedRoot, temporaryPath, { leaf: "file" });
|
|
244
|
-
}
|
|
245
|
-
renameSync(temporaryPath, destinationPath);
|
|
246
|
-
} finally {
|
|
247
|
-
if (!managedRoot || !lstatSync(temporaryPath, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
248
|
-
rmSync(temporaryPath, { force: true });
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
function resolveManifestPath(root, relativePath) {
|
|
253
|
-
if (!relativePath || relativePath.includes("\0")) return null;
|
|
254
|
-
const absolutePath = resolve(root, relativePath);
|
|
255
|
-
const normalizedRelative = relative(root, absolutePath);
|
|
256
|
-
if (normalizedRelative === "" || normalizedRelative === ".." || normalizedRelative.startsWith(`..${sep}`)) {
|
|
257
|
-
return null;
|
|
258
|
-
}
|
|
259
|
-
return absolutePath;
|
|
260
|
-
}
|
|
261
|
-
function normalizeManifestRelativePath(path) {
|
|
262
|
-
return path.replace(/\\/g, "/");
|
|
263
|
-
}
|
|
264
|
-
function readHarnessManifest(manifestPath) {
|
|
265
|
-
if (!existsSync(manifestPath)) return null;
|
|
266
|
-
try {
|
|
267
|
-
const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
|
|
268
|
-
if (typeof parsed.version !== "number" || typeof parsed.generator !== "string" || !Array.isArray(parsed.files)) {
|
|
269
|
-
return null;
|
|
270
|
-
}
|
|
271
|
-
const files = [];
|
|
272
|
-
for (const entry of parsed.files) {
|
|
273
|
-
if (!entry || typeof entry.path !== "string" || typeof entry.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(entry.sha256) || typeof entry.source !== "string" || typeof entry.userEditable !== "boolean") {
|
|
274
|
-
return null;
|
|
275
|
-
}
|
|
276
|
-
files.push({ ...entry, path: normalizeManifestRelativePath(entry.path) });
|
|
277
|
-
}
|
|
278
|
-
return { version: parsed.version, generator: parsed.generator, files };
|
|
279
|
-
} catch {
|
|
280
|
-
return null;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
function targetPathsForTree(sourceRoot, destinationRoot) {
|
|
284
|
-
return listFiles(sourceRoot).map((sourcePath) => join(destinationRoot, relative(sourceRoot, sourcePath)));
|
|
285
|
-
}
|
|
286
|
-
function finalizeHarnessManifest(config, selectedTools) {
|
|
98
|
+
function generateShared(config) {
|
|
287
99
|
const { targetDir } = config;
|
|
288
100
|
const srcDir = join(AGENTIC_DIR, "shared");
|
|
289
101
|
const selectedModules = selectModuleFactSheets(targetDir, join(GUIDES_DIR, "modules"));
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
paths.add(join(targetDir, ".claude", "hooks", "entity-migration-check.ts"));
|
|
306
|
-
paths.add(join(targetDir, ".mcp.json.example"));
|
|
307
|
-
}
|
|
308
|
-
if (selectedTools.includes("codex")) paths.add(join(targetDir, ".codex", "mcp.json.example"));
|
|
309
|
-
if (selectedTools.includes("cursor")) {
|
|
310
|
-
for (const file of listFiles(join(AGENTIC_DIR, "cursor"))) {
|
|
311
|
-
const rel = relative(join(AGENTIC_DIR, "cursor"), file);
|
|
312
|
-
paths.add(join(targetDir, ".cursor", rel));
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
const manifestPath = join(targetDir, ".ai", "harness", "manifest.json");
|
|
316
|
-
const externalSkills = externalSkillNames(targetDir);
|
|
317
|
-
paths.delete(manifestPath);
|
|
318
|
-
const files = [...paths].filter((path) => existsSync(path)).sort((left, right) => left.localeCompare(right)).map((path) => {
|
|
319
|
-
const relativePath = normalizeManifestRelativePath(relative(targetDir, path));
|
|
320
|
-
const skillName = relativePath.match(/^\.ai\/skills\/([^/]+)\//)?.[1];
|
|
321
|
-
return {
|
|
322
|
-
path: relativePath,
|
|
323
|
-
sha256: hashFile(path),
|
|
324
|
-
source: skillName ? externalSkills.has(skillName) ? "external-override" : "local-skill" : "generated",
|
|
325
|
-
userEditable: relativePath === "AGENTS.md" || relativePath === ".ai/agentic.config.json" || relativePath === ".ai/lessons.md" || relativePath.startsWith(".ai/lessons/")
|
|
326
|
-
};
|
|
327
|
-
});
|
|
328
|
-
atomicWriteFile(
|
|
329
|
-
manifestPath,
|
|
330
|
-
`${JSON.stringify({ version: 1, generator: harnessGeneratorId(), files }, null, 2)}
|
|
331
|
-
`
|
|
102
|
+
const moduleGuideLabels = readModuleGuideLabels(GUIDES_DIR);
|
|
103
|
+
writeTemplate(srcDir, "AGENTS.md.template", join(targetDir, "AGENTS.md"), config);
|
|
104
|
+
injectModuleGuides(join(targetDir, "AGENTS.md"), selectedModules, moduleGuideLabels);
|
|
105
|
+
writeTemplate(srcDir, "ai/specs/README.md", join(targetDir, ".ai", "specs", "README.md"), config);
|
|
106
|
+
copyFile(srcDir, "ai/specs/SPEC-000-template.md", join(targetDir, ".ai", "specs", "SPEC-000-template.md"));
|
|
107
|
+
copyFile(srcDir, "ai/lessons.md", join(targetDir, ".ai", "lessons.md"));
|
|
108
|
+
copyFile(srcDir, "ai/skills/tiers.json", join(targetDir, ".ai", "skills", "tiers.json"));
|
|
109
|
+
copyFile(srcDir, "ai/skills/tiers.schema.json", join(targetDir, ".ai", "skills", "tiers.schema.json"));
|
|
110
|
+
copyFile(srcDir, "ai/agentic.config.json", join(targetDir, ".ai", "agentic.config.json"));
|
|
111
|
+
copyFile(srcDir, "ai/trackers/github.md", join(targetDir, ".ai", "trackers", "github.md"));
|
|
112
|
+
copyFile(srcDir, "scripts/install-skills.sh", join(targetDir, "scripts", "install-skills.sh"));
|
|
113
|
+
copyFile(
|
|
114
|
+
srcDir,
|
|
115
|
+
"ai/skills/om-backend-ui-design/SKILL.md",
|
|
116
|
+
join(targetDir, ".ai", "skills", "om-backend-ui-design", "SKILL.md")
|
|
332
117
|
);
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
function applyHarnessUpdate(targetDir, stagingDir, options = {}) {
|
|
347
|
-
const targetRoot = canonicalHarnessRoot(targetDir);
|
|
348
|
-
const stagingRoot = canonicalHarnessRoot(stagingDir);
|
|
349
|
-
const targetManifestPath = join(targetRoot, ".ai", "harness", "manifest.json");
|
|
350
|
-
const stagingManifestPath = join(stagingRoot, ".ai", "harness", "manifest.json");
|
|
351
|
-
assertManagedPath(targetRoot, targetManifestPath, { leaf: "file" });
|
|
352
|
-
assertManagedPath(stagingRoot, stagingManifestPath, { leaf: "file" });
|
|
353
|
-
const candidateManifest = readHarnessManifest(stagingManifestPath);
|
|
354
|
-
if (!candidateManifest) {
|
|
355
|
-
throw new Error("Generated harness candidate has a missing or invalid ownership manifest.");
|
|
118
|
+
copyFile(
|
|
119
|
+
srcDir,
|
|
120
|
+
"ai/skills/om-backend-ui-design/references/ui-components.md",
|
|
121
|
+
join(targetDir, ".ai", "skills", "om-backend-ui-design", "references", "ui-components.md")
|
|
122
|
+
);
|
|
123
|
+
copyFile(srcDir, "ai/skills/om-integration-builder/SKILL.md", join(targetDir, ".ai", "skills", "om-integration-builder", "SKILL.md"));
|
|
124
|
+
if (existsSync(join(srcDir, "ai", "skills", "om-integration-builder", "STANDALONE.md"))) {
|
|
125
|
+
copyFile(
|
|
126
|
+
srcDir,
|
|
127
|
+
"ai/skills/om-integration-builder/STANDALONE.md",
|
|
128
|
+
join(targetDir, ".ai", "skills", "om-integration-builder", "STANDALONE.md")
|
|
129
|
+
);
|
|
356
130
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
candidates.push({ entry, sourcePath, destinationPath });
|
|
131
|
+
copyFile(
|
|
132
|
+
srcDir,
|
|
133
|
+
"ai/skills/om-integration-builder/references/adapter-contracts.md",
|
|
134
|
+
join(targetDir, ".ai", "skills", "om-integration-builder", "references", "adapter-contracts.md")
|
|
135
|
+
);
|
|
136
|
+
if (existsSync(join(srcDir, "ai", "skills", "om-integration-builder", "STANDALONE.md"))) {
|
|
137
|
+
copyFile(
|
|
138
|
+
srcDir,
|
|
139
|
+
"ai/skills/om-integration-builder/STANDALONE.md",
|
|
140
|
+
join(targetDir, ".ai", "skills", "om-integration-builder", "STANDALONE.md")
|
|
141
|
+
);
|
|
370
142
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
143
|
+
copyFile(
|
|
144
|
+
srcDir,
|
|
145
|
+
"ai/skills/om-system-extension/SKILL.md",
|
|
146
|
+
join(targetDir, ".ai", "skills", "om-system-extension", "SKILL.md")
|
|
147
|
+
);
|
|
148
|
+
copyFile(
|
|
149
|
+
srcDir,
|
|
150
|
+
"ai/skills/om-system-extension/references/extension-contracts.md",
|
|
151
|
+
join(targetDir, ".ai", "skills", "om-system-extension", "references", "extension-contracts.md")
|
|
152
|
+
);
|
|
153
|
+
copyFile(
|
|
154
|
+
srcDir,
|
|
155
|
+
"ai/skills/om-module-scaffold/SKILL.md",
|
|
156
|
+
join(targetDir, ".ai", "skills", "om-module-scaffold", "SKILL.md")
|
|
157
|
+
);
|
|
158
|
+
copyFile(
|
|
159
|
+
srcDir,
|
|
160
|
+
"ai/skills/om-module-scaffold/references/naming-conventions.md",
|
|
161
|
+
join(targetDir, ".ai", "skills", "om-module-scaffold", "references", "naming-conventions.md")
|
|
162
|
+
);
|
|
163
|
+
copyFile(
|
|
164
|
+
srcDir,
|
|
165
|
+
"ai/skills/om-module-scaffold/references/navigation-patterns.md",
|
|
166
|
+
join(targetDir, ".ai", "skills", "om-module-scaffold", "references", "navigation-patterns.md")
|
|
167
|
+
);
|
|
168
|
+
copyFile(
|
|
169
|
+
srcDir,
|
|
170
|
+
"ai/skills/om-troubleshooter/SKILL.md",
|
|
171
|
+
join(targetDir, ".ai", "skills", "om-troubleshooter", "SKILL.md")
|
|
172
|
+
);
|
|
173
|
+
copyFile(
|
|
174
|
+
srcDir,
|
|
175
|
+
"ai/skills/om-troubleshooter/references/diagnostic-commands.md",
|
|
176
|
+
join(targetDir, ".ai", "skills", "om-troubleshooter", "references", "diagnostic-commands.md")
|
|
177
|
+
);
|
|
178
|
+
copyFile(
|
|
179
|
+
srcDir,
|
|
180
|
+
"ai/skills/om-eject-and-customize/SKILL.md",
|
|
181
|
+
join(targetDir, ".ai", "skills", "om-eject-and-customize", "SKILL.md")
|
|
182
|
+
);
|
|
183
|
+
copyFile(
|
|
184
|
+
srcDir,
|
|
185
|
+
"ai/skills/om-data-model-design/SKILL.md",
|
|
186
|
+
join(targetDir, ".ai", "skills", "om-data-model-design", "SKILL.md")
|
|
187
|
+
);
|
|
188
|
+
copyFile(
|
|
189
|
+
srcDir,
|
|
190
|
+
"ai/skills/om-data-model-design/references/mikro-orm-cheatsheet.md",
|
|
191
|
+
join(targetDir, ".ai", "skills", "om-data-model-design", "references", "mikro-orm-cheatsheet.md")
|
|
192
|
+
);
|
|
193
|
+
copyFile(
|
|
194
|
+
srcDir,
|
|
195
|
+
"ai/skills/om-implement-spec/SKILL.md",
|
|
196
|
+
join(targetDir, ".ai", "skills", "om-implement-spec", "SKILL.md")
|
|
197
|
+
);
|
|
198
|
+
copyFile(
|
|
199
|
+
srcDir,
|
|
200
|
+
"ai/skills/om-help/SKILL.md",
|
|
201
|
+
join(targetDir, ".ai", "skills", "om-help", "SKILL.md")
|
|
202
|
+
);
|
|
203
|
+
copyFile(
|
|
204
|
+
srcDir,
|
|
205
|
+
"ai/skills/om-help/references/skills-catalog.md",
|
|
206
|
+
join(targetDir, ".ai", "skills", "om-help", "references", "skills-catalog.md")
|
|
207
|
+
);
|
|
208
|
+
copyFile(
|
|
209
|
+
srcDir,
|
|
210
|
+
"ai/skills/om-help/references/workflow-sequences.md",
|
|
211
|
+
join(targetDir, ".ai", "skills", "om-help", "references", "workflow-sequences.md")
|
|
212
|
+
);
|
|
213
|
+
copyFile(
|
|
214
|
+
srcDir,
|
|
215
|
+
"ai/skills/om-auto-upgrade-0.4.10-to-0.5.0/SKILL.md",
|
|
216
|
+
join(targetDir, ".ai", "skills", "om-auto-upgrade-0.4.10-to-0.5.0", "SKILL.md")
|
|
217
|
+
);
|
|
218
|
+
for (const autoSkill of [
|
|
219
|
+
"om-auto-create-pr",
|
|
220
|
+
"om-auto-continue-pr",
|
|
221
|
+
"om-auto-create-pr-loop",
|
|
222
|
+
"om-auto-continue-pr-loop",
|
|
223
|
+
"om-auto-review-pr",
|
|
224
|
+
"om-auto-fix-issue",
|
|
225
|
+
"om-prepare-test-env"
|
|
226
|
+
]) {
|
|
227
|
+
if (!existsSync(join(srcDir, "ai", "skills", autoSkill, "SKILL.md"))) {
|
|
385
228
|
continue;
|
|
386
229
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
if (candidatePaths.has(previousEntry.path)) continue;
|
|
393
|
-
const destinationPath = resolveManifestPath(targetRoot, previousEntry.path);
|
|
394
|
-
if (!destinationPath || !existsSync(destinationPath)) continue;
|
|
395
|
-
assertManagedPath(targetRoot, destinationPath, { leaf: "file" });
|
|
396
|
-
let unchanged = false;
|
|
397
|
-
try {
|
|
398
|
-
unchanged = hashFile(destinationPath) === previousEntry.sha256;
|
|
399
|
-
} catch {
|
|
400
|
-
}
|
|
401
|
-
if (unchanged) {
|
|
402
|
-
assertManagedPath(targetRoot, dirname(destinationPath));
|
|
403
|
-
assertManagedPath(targetRoot, destinationPath, { leaf: "file" });
|
|
404
|
-
rmSync(destinationPath, { force: true });
|
|
405
|
-
} else {
|
|
406
|
-
retainedRetiredEntries.push(previousEntry);
|
|
407
|
-
conflicts.push({ path: previousEntry.path, candidate: null });
|
|
408
|
-
}
|
|
230
|
+
copyFile(
|
|
231
|
+
srcDir,
|
|
232
|
+
`ai/skills/${autoSkill}/SKILL.md`,
|
|
233
|
+
join(targetDir, ".ai", "skills", autoSkill, "SKILL.md")
|
|
234
|
+
);
|
|
409
235
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
return conflicts;
|
|
417
|
-
}
|
|
418
|
-
function generateShared(config) {
|
|
419
|
-
const { targetDir } = config;
|
|
420
|
-
const srcDir = join(AGENTIC_DIR, "shared");
|
|
421
|
-
const selectedModules = selectModuleFactSheets(targetDir, join(GUIDES_DIR, "modules"));
|
|
422
|
-
writeTemplate(srcDir, "AGENTS.md.template", join(targetDir, "AGENTS.md"), config);
|
|
423
|
-
copyTree(join(srcDir, "ai"), join(targetDir, ".ai"), config);
|
|
424
|
-
copyTree(join(srcDir, "scripts"), join(targetDir, "scripts"), config);
|
|
236
|
+
copyFile(
|
|
237
|
+
srcDir,
|
|
238
|
+
"ai/skills/om-trim-unused-modules/SKILL.md",
|
|
239
|
+
join(targetDir, ".ai", "skills", "om-trim-unused-modules", "SKILL.md")
|
|
240
|
+
);
|
|
241
|
+
copyFile(srcDir, "ai/qa/tests/playwright.config.ts", join(targetDir, ".ai", "qa", "tests", "playwright.config.ts"));
|
|
425
242
|
if (existsSync(GUIDES_DIR)) {
|
|
426
243
|
const guidesDestDir = join(targetDir, ".ai", "guides");
|
|
427
244
|
for (const file of readdirSync(GUIDES_DIR)) {
|
|
@@ -437,7 +254,6 @@ function generateShared(config) {
|
|
|
437
254
|
ensureDir(destPath);
|
|
438
255
|
copyFileSync(moduleFactsPath, destPath);
|
|
439
256
|
}
|
|
440
|
-
copyTree(join(GUIDES_DIR, "upstream"), join(guidesDestDir, "upstream"), config);
|
|
441
257
|
const modulesSubdir = join(GUIDES_DIR, "modules");
|
|
442
258
|
for (const moduleId of selectedModules) {
|
|
443
259
|
const destPath = join(guidesDestDir, "modules", `${moduleId}.md`);
|
|
@@ -445,7 +261,6 @@ function generateShared(config) {
|
|
|
445
261
|
copyFileSync(join(modulesSubdir, `${moduleId}.md`), destPath);
|
|
446
262
|
}
|
|
447
263
|
}
|
|
448
|
-
injectModuleGuides(join(targetDir, "AGENTS.md"), selectedModules);
|
|
449
264
|
}
|
|
450
265
|
function generateClaudeCode(config) {
|
|
451
266
|
const { targetDir } = config;
|
|
@@ -454,6 +269,7 @@ function generateClaudeCode(config) {
|
|
|
454
269
|
copyFile(srcDir, "settings.json", join(targetDir, ".claude", "settings.json"));
|
|
455
270
|
copyFile(srcDir, "hooks/entity-migration-check.ts", join(targetDir, ".claude", "hooks", "entity-migration-check.ts"));
|
|
456
271
|
copyFile(srcDir, "mcp.json.example", join(targetDir, ".mcp.json.example"));
|
|
272
|
+
ensureSkillsLink(join(targetDir, ".claude", "skills"), join("..", ".ai", "skills"));
|
|
457
273
|
}
|
|
458
274
|
function generateCodex(config) {
|
|
459
275
|
const { targetDir } = config;
|
|
@@ -492,6 +308,16 @@ function generateCursor(config) {
|
|
|
492
308
|
copyFile(srcDir, "hooks/entity-migration-check.mjs", join(targetDir, ".cursor", "hooks", "entity-migration-check.mjs"));
|
|
493
309
|
copyFile(srcDir, "mcp.json.example", join(targetDir, ".cursor", "mcp.json.example"));
|
|
494
310
|
}
|
|
311
|
+
function ensureSkillsLink(linkPath, target) {
|
|
312
|
+
ensureDir(linkPath);
|
|
313
|
+
if (existsSync(linkPath) && !lstatSync(linkPath).isSymbolicLink()) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (lstatSync(linkPath, { throwIfNoEntry: false })?.isSymbolicLink()) {
|
|
317
|
+
unlinkSync(linkPath);
|
|
318
|
+
}
|
|
319
|
+
symlinkSync(target, linkPath);
|
|
320
|
+
}
|
|
495
321
|
const TOOLS = [
|
|
496
322
|
{ key: "1", label: "Claude Code (Anthropic)", id: "claude-code" },
|
|
497
323
|
{ key: "2", label: "Codex (OpenAI)", id: "codex" },
|
|
@@ -500,30 +326,6 @@ const TOOLS = [
|
|
|
500
326
|
{ key: "5", label: "Skip \u2014 set up manually later", id: "skip" }
|
|
501
327
|
];
|
|
502
328
|
const SELECTABLE = TOOLS.filter((t) => t.id !== "multiple" && t.id !== "skip");
|
|
503
|
-
function persistedAgentSelection(targetDir) {
|
|
504
|
-
const selectableIds = SELECTABLE.map((tool) => tool.id);
|
|
505
|
-
const tiersPath = join(targetDir, ".ai", "skills", "tiers.json");
|
|
506
|
-
try {
|
|
507
|
-
const tiers = JSON.parse(readFileSync(tiersPath, "utf8"));
|
|
508
|
-
if (Array.isArray(tiers.agents?.ignore) && tiers.agents.ignore.every((id) => typeof id === "string")) {
|
|
509
|
-
const ignored = new Set(tiers.agents.ignore);
|
|
510
|
-
return selectableIds.filter((id) => !ignored.has(id));
|
|
511
|
-
}
|
|
512
|
-
} catch {
|
|
513
|
-
}
|
|
514
|
-
const manifest = readHarnessManifest(join(targetDir, ".ai", "harness", "manifest.json"));
|
|
515
|
-
const owned = new Set(manifest?.files.map((entry) => entry.path) ?? []);
|
|
516
|
-
const selected = SELECTABLE.filter((tool) => {
|
|
517
|
-
if (tool.id === "claude-code") {
|
|
518
|
-
return owned.has("CLAUDE.md") || owned.has(".claude/settings.json") || existsSync(join(targetDir, "CLAUDE.md")) || existsSync(join(targetDir, ".claude", "settings.json"));
|
|
519
|
-
}
|
|
520
|
-
if (tool.id === "codex") {
|
|
521
|
-
return owned.has(".codex/mcp.json.example") || existsSync(join(targetDir, ".codex", "mcp.json.example"));
|
|
522
|
-
}
|
|
523
|
-
return owned.has(".cursor/hooks.json") || existsSync(join(targetDir, ".cursor", "hooks.json"));
|
|
524
|
-
}).map((tool) => tool.id);
|
|
525
|
-
return selected.length > 0 ? selected : null;
|
|
526
|
-
}
|
|
527
329
|
async function promptSelection(ask) {
|
|
528
330
|
console.log("");
|
|
529
331
|
console.log("\u{1F916} Agentic workflow setup");
|
|
@@ -560,8 +362,6 @@ async function runAgenticSetup(targetDir, ask, options) {
|
|
|
560
362
|
let selectedIds;
|
|
561
363
|
if (options?.tool) {
|
|
562
364
|
selectedIds = options.tool.split(",").map((t) => t.trim());
|
|
563
|
-
} else if (options?.updateHarness) {
|
|
564
|
-
selectedIds = persistedAgentSelection(targetDir) ?? await promptSelection(ask);
|
|
565
365
|
} else {
|
|
566
366
|
selectedIds = await promptSelection(ask);
|
|
567
367
|
}
|
|
@@ -575,33 +375,11 @@ async function runAgenticSetup(targetDir, ask, options) {
|
|
|
575
375
|
projectName: basename(targetDir),
|
|
576
376
|
targetDir
|
|
577
377
|
};
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
ensureDir(modulesCandidatePath);
|
|
584
|
-
copyFileSync(modulesSourcePath, modulesCandidatePath);
|
|
585
|
-
}
|
|
586
|
-
const stagingConfig = {
|
|
587
|
-
projectName: config.projectName,
|
|
588
|
-
targetDir: stagingDir
|
|
589
|
-
};
|
|
590
|
-
generateHarness(stagingConfig, selectedIds);
|
|
591
|
-
const conflicts = applyHarnessUpdate(targetDir, stagingDir, {
|
|
592
|
-
force: options?.force
|
|
593
|
-
});
|
|
594
|
-
if (conflicts.length > 0) {
|
|
595
|
-
console.warn("");
|
|
596
|
-
console.warn(" \u26A0 Preserved locally modified harness files:");
|
|
597
|
-
for (const conflict of conflicts) {
|
|
598
|
-
const detail = conflict.candidate ? `candidate: ${conflict.candidate}` : "retired asset kept because it has local changes";
|
|
599
|
-
console.warn(` \u2022 ${conflict.path} (${detail})`);
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
} finally {
|
|
603
|
-
rmSync(stagingDir, { recursive: true, force: true });
|
|
604
|
-
}
|
|
378
|
+
generateShared(config);
|
|
379
|
+
if (selectedIds.includes("claude-code")) generateClaudeCode(config);
|
|
380
|
+
if (selectedIds.includes("codex")) generateCodex(config);
|
|
381
|
+
if (selectedIds.includes("cursor")) generateCursor(config);
|
|
382
|
+
persistAgentSelection(targetDir, selectedIds);
|
|
605
383
|
installSkills(targetDir);
|
|
606
384
|
console.log("");
|
|
607
385
|
console.log(" Agentic setup complete:");
|
|
@@ -621,14 +399,6 @@ async function runAgenticSetup(targetDir, ask, options) {
|
|
|
621
399
|
console.log(" refresh the external open-mercato/skills subset.");
|
|
622
400
|
console.log("");
|
|
623
401
|
}
|
|
624
|
-
function generateHarness(config, selectedIds) {
|
|
625
|
-
generateShared(config);
|
|
626
|
-
if (selectedIds.includes("claude-code")) generateClaudeCode(config);
|
|
627
|
-
if (selectedIds.includes("codex")) generateCodex(config);
|
|
628
|
-
if (selectedIds.includes("cursor")) generateCursor(config);
|
|
629
|
-
persistAgentSelection(config.targetDir, selectedIds);
|
|
630
|
-
finalizeHarnessManifest(config, selectedIds);
|
|
631
|
-
}
|
|
632
402
|
function persistAgentSelection(targetDir, selectedIds) {
|
|
633
403
|
const manifestPath = join(targetDir, ".ai", "skills", "tiers.json");
|
|
634
404
|
if (!existsSync(manifestPath)) return;
|
|
@@ -643,18 +413,16 @@ function persistAgentSelection(targetDir, selectedIds) {
|
|
|
643
413
|
`);
|
|
644
414
|
}
|
|
645
415
|
function installSkills(targetDir) {
|
|
646
|
-
const installScript = join(targetDir, "scripts", "install-skills.
|
|
416
|
+
const installScript = join(targetDir, "scripts", "install-skills.sh");
|
|
647
417
|
if (!existsSync(installScript)) return;
|
|
648
418
|
console.log("");
|
|
649
419
|
console.log(" Installing agent skills (local tiers + external open-mercato/skills subset)...");
|
|
650
|
-
const result = spawnSync(
|
|
420
|
+
const result = spawnSync("sh", [installScript], { cwd: targetDir, stdio: "inherit" });
|
|
651
421
|
if (result.error || result.status !== 0) {
|
|
652
422
|
console.log(" \u26A0 Skill installation did not complete; run `yarn install-skills` inside the app when online.");
|
|
653
423
|
}
|
|
654
424
|
}
|
|
655
425
|
export {
|
|
656
|
-
applyHarnessUpdate,
|
|
657
|
-
renderModuleGuidesBlock,
|
|
658
426
|
runAgenticSetup
|
|
659
427
|
};
|
|
660
428
|
//# sourceMappingURL=agentic-setup.js.map
|