@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,222 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import fs from 'node:fs'
|
|
4
|
-
import path from 'node:path'
|
|
5
|
-
import process from 'node:process'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
|
-
|
|
8
|
-
const controllerRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
|
9
|
-
|
|
10
|
-
function isWithin(parent, child) {
|
|
11
|
-
const relative = path.relative(parent, child)
|
|
12
|
-
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function usage() {
|
|
16
|
-
return `Prepare one declared writable agent-harness fixture in a separate disposable app.
|
|
17
|
-
|
|
18
|
-
Usage:
|
|
19
|
-
node scripts/prepare-agent-harness-fixture.mjs --case OMH-NNN --target /absolute/app --acknowledge-writes
|
|
20
|
-
|
|
21
|
-
The target must be a fresh standalone scaffold. Existing fixture files are never overwritten.`
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function parseArgs(argv) {
|
|
25
|
-
const options = { caseId: undefined, target: undefined, acknowledgeWrites: false }
|
|
26
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
27
|
-
const arg = argv[index]
|
|
28
|
-
const value = () => {
|
|
29
|
-
const next = argv[index + 1]
|
|
30
|
-
if (!next || next.startsWith('--')) throw new Error(`${arg} requires a value`)
|
|
31
|
-
index += 1
|
|
32
|
-
return next
|
|
33
|
-
}
|
|
34
|
-
if (arg === '--help' || arg === '-h') return { help: true }
|
|
35
|
-
if (arg === '--case') options.caseId = value()
|
|
36
|
-
else if (arg === '--target') options.target = value()
|
|
37
|
-
else if (arg === '--acknowledge-writes') options.acknowledgeWrites = true
|
|
38
|
-
else throw new Error(`unknown argument: ${arg}`)
|
|
39
|
-
}
|
|
40
|
-
return options
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function readJson(relative) {
|
|
44
|
-
return JSON.parse(fs.readFileSync(path.join(controllerRoot, relative), 'utf8'))
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function isSafeRelative(value) {
|
|
48
|
-
if (typeof value !== 'string' || !value || path.isAbsolute(value) || value.includes('\0')) return false
|
|
49
|
-
const normalized = path.posix.normalize(value.replaceAll('\\', '/'))
|
|
50
|
-
return normalized !== '..' && !normalized.startsWith('../')
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function lstatIfPresent(candidate) {
|
|
54
|
-
try {
|
|
55
|
-
return fs.lstatSync(candidate)
|
|
56
|
-
} catch (error) {
|
|
57
|
-
if (error?.code === 'ENOENT') return null
|
|
58
|
-
throw error
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function assertDirectory(root, candidate, label) {
|
|
63
|
-
const lexical = path.resolve(candidate)
|
|
64
|
-
if (!isWithin(root, lexical)) throw new Error(`${label} escapes the target app`)
|
|
65
|
-
const stat = lstatIfPresent(lexical)
|
|
66
|
-
if (!stat) return false
|
|
67
|
-
if (stat.isSymbolicLink()) throw new Error(`${label} must not be a symbolic link`)
|
|
68
|
-
if (!stat.isDirectory()) throw new Error(`${label} must be a directory`)
|
|
69
|
-
const real = fs.realpathSync(lexical)
|
|
70
|
-
if (!isWithin(root, real)) throw new Error(`${label} resolves outside the target app`)
|
|
71
|
-
return true
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function ensureDirectoryChain(root, relativeDirectory, create) {
|
|
75
|
-
if (!isSafeRelative(relativeDirectory) && relativeDirectory !== '.') {
|
|
76
|
-
throw new Error(`unsafe fixture parent path: ${relativeDirectory}`)
|
|
77
|
-
}
|
|
78
|
-
assertDirectory(root, root, 'target root')
|
|
79
|
-
if (relativeDirectory === '.') return
|
|
80
|
-
|
|
81
|
-
let cursor = root
|
|
82
|
-
for (const component of relativeDirectory.replaceAll('\\', '/').split('/').filter(Boolean)) {
|
|
83
|
-
cursor = path.join(cursor, component)
|
|
84
|
-
if (assertDirectory(root, cursor, `fixture parent ${path.relative(root, cursor)}`)) continue
|
|
85
|
-
if (!create) throw new Error(`fixture parent is missing: ${path.relative(root, cursor)}`)
|
|
86
|
-
try {
|
|
87
|
-
fs.mkdirSync(cursor, { mode: 0o755 })
|
|
88
|
-
} catch (error) {
|
|
89
|
-
if (error?.code !== 'EEXIST') throw error
|
|
90
|
-
}
|
|
91
|
-
if (!assertDirectory(root, cursor, `fixture parent ${path.relative(root, cursor)}`)) {
|
|
92
|
-
throw new Error(`failed to create fixture parent: ${path.relative(root, cursor)}`)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function assertSafeDestination(root, relativeFile) {
|
|
98
|
-
const destination = path.resolve(root, relativeFile)
|
|
99
|
-
if (!isWithin(root, destination)) throw new Error(`fixture destination escapes the target app: ${relativeFile}`)
|
|
100
|
-
assertDirectory(root, root, 'target root')
|
|
101
|
-
|
|
102
|
-
let cursor = root
|
|
103
|
-
for (const component of path.dirname(relativeFile).replaceAll('\\', '/').split('/').filter((entry) => entry && entry !== '.')) {
|
|
104
|
-
cursor = path.join(cursor, component)
|
|
105
|
-
const stat = lstatIfPresent(cursor)
|
|
106
|
-
if (!stat) return
|
|
107
|
-
assertDirectory(root, cursor, `fixture parent ${path.relative(root, cursor)}`)
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function assertRegularFile(root, relativeFile, label) {
|
|
112
|
-
ensureDirectoryChain(root, path.dirname(relativeFile), false)
|
|
113
|
-
const candidate = path.join(root, relativeFile)
|
|
114
|
-
const stat = lstatIfPresent(candidate)
|
|
115
|
-
if (!stat || stat.isSymbolicLink() || !stat.isFile()) throw new Error(`${label} must be a regular file`)
|
|
116
|
-
const real = fs.realpathSync(candidate)
|
|
117
|
-
if (!isWithin(root, real)) throw new Error(`${label} resolves outside the target app`)
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function createFile(root, relativeFile, content, mode) {
|
|
121
|
-
ensureDirectoryChain(root, path.dirname(relativeFile), true)
|
|
122
|
-
const destination = path.join(root, relativeFile)
|
|
123
|
-
if (!isWithin(root, path.resolve(destination))) throw new Error(`fixture destination escapes the target app: ${relativeFile}`)
|
|
124
|
-
const flags = fs.constants.O_CREAT
|
|
125
|
-
| fs.constants.O_EXCL
|
|
126
|
-
| fs.constants.O_WRONLY
|
|
127
|
-
| (fs.constants.O_NOFOLLOW ?? 0)
|
|
128
|
-
let descriptor
|
|
129
|
-
try {
|
|
130
|
-
descriptor = fs.openSync(destination, flags, mode)
|
|
131
|
-
fs.writeFileSync(descriptor, content)
|
|
132
|
-
} catch (error) {
|
|
133
|
-
if (error?.code === 'EEXIST' || error?.code === 'ELOOP') {
|
|
134
|
-
throw new Error(`fixture would overwrite existing files: ${relativeFile}`)
|
|
135
|
-
}
|
|
136
|
-
throw error
|
|
137
|
-
} finally {
|
|
138
|
-
if (descriptor !== undefined) fs.closeSync(descriptor)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const stat = fs.lstatSync(destination)
|
|
142
|
-
if (stat.isSymbolicLink() || !stat.isFile()) throw new Error(`fixture destination is not a regular file: ${relativeFile}`)
|
|
143
|
-
const real = fs.realpathSync(destination)
|
|
144
|
-
if (!isWithin(root, real)) throw new Error(`fixture destination resolves outside the target app: ${relativeFile}`)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function assertFreshStandaloneTarget(target) {
|
|
148
|
-
if (isWithin(controllerRoot, target) || target === path.parse(target).root) throw new Error('--target must be outside the controller app')
|
|
149
|
-
for (const required of ['package.json', 'src/modules.ts', '.ai/harness/cases.json']) {
|
|
150
|
-
try {
|
|
151
|
-
assertRegularFile(target, required, `standalone marker ${required}`)
|
|
152
|
-
} catch {
|
|
153
|
-
throw new Error(`target is not a generated standalone app: missing or unsafe ${required}`)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
if (lstatIfPresent(path.join(target, '.ai', 'harness', 'DISPOSABLE'))) throw new Error('target is already prepared; use a fresh scaffold')
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function main() {
|
|
160
|
-
const options = parseArgs(process.argv.slice(2))
|
|
161
|
-
if (options.help) {
|
|
162
|
-
console.log(usage())
|
|
163
|
-
return 0
|
|
164
|
-
}
|
|
165
|
-
if (!options.caseId || !options.target || !options.acknowledgeWrites) {
|
|
166
|
-
throw new Error('--case, --target, and --acknowledge-writes are required')
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (!path.isAbsolute(options.target)) throw new Error('--target must be absolute')
|
|
170
|
-
const lexicalTarget = path.resolve(options.target)
|
|
171
|
-
const targetStat = fs.lstatSync(lexicalTarget)
|
|
172
|
-
if (targetStat.isSymbolicLink() || !targetStat.isDirectory()) throw new Error('--target must be a regular directory, not a symbolic link')
|
|
173
|
-
const target = fs.realpathSync(lexicalTarget)
|
|
174
|
-
assertFreshStandaloneTarget(target)
|
|
175
|
-
const cases = readJson('.ai/harness/cases.json')
|
|
176
|
-
const fixtures = readJson('.ai/harness/fixtures/index.json')
|
|
177
|
-
const seeds = readJson('.ai/harness/fixtures/seeds.json')
|
|
178
|
-
const caseRecord = cases.find((entry) => entry.id === options.caseId)
|
|
179
|
-
if (!caseRecord || !['implementation', 'regression'].includes(caseRecord.evaluationKind)) {
|
|
180
|
-
throw new Error(`${options.caseId} is not a writable harness case`)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const declarations = caseRecord.fixture?.setup ?? []
|
|
184
|
-
if (declarations.length !== 1 || !declarations[0].startsWith('fixture:')) throw new Error(`${options.caseId} has an invalid fixture declaration`)
|
|
185
|
-
const fixtureId = declarations[0].slice('fixture:'.length)
|
|
186
|
-
const fixture = fixtures.fixtures?.[fixtureId]
|
|
187
|
-
const files = seeds.fixtures?.[fixtureId]
|
|
188
|
-
if (!fixture || !files) throw new Error(`fixture seed is unavailable: ${fixtureId}`)
|
|
189
|
-
const paths = Object.keys(files)
|
|
190
|
-
if (paths.some((entry) => !isSafeRelative(entry))) throw new Error(`fixture contains an unsafe path: ${fixtureId}`)
|
|
191
|
-
if (JSON.stringify([...paths].sort()) !== JSON.stringify([...fixture.seededArtifacts].sort())) {
|
|
192
|
-
throw new Error(`fixture seed paths do not match the declared artifacts: ${fixtureId}`)
|
|
193
|
-
}
|
|
194
|
-
if (paths.some((entry) => !caseRecord.allowedWrites.some((allowed) => allowed === entry || (allowed.endsWith('/**') && entry.startsWith(allowed.slice(0, -2)))))) {
|
|
195
|
-
throw new Error(`fixture seed escapes the case write allowlist: ${fixtureId}`)
|
|
196
|
-
}
|
|
197
|
-
for (const relative of [...paths, '.ai/harness/DISPOSABLE']) assertSafeDestination(target, relative)
|
|
198
|
-
const existing = paths.filter((entry) => lstatIfPresent(path.join(target, entry)))
|
|
199
|
-
if (existing.length) throw new Error(`fixture would overwrite existing files: ${existing.join(', ')}`)
|
|
200
|
-
|
|
201
|
-
for (const [relative, content] of Object.entries(files)) {
|
|
202
|
-
createFile(target, relative, content.endsWith('\n') ? content : `${content}\n`, 0o644)
|
|
203
|
-
}
|
|
204
|
-
createFile(
|
|
205
|
-
target,
|
|
206
|
-
'.ai/harness/DISPOSABLE',
|
|
207
|
-
`${JSON.stringify({ schemaVersion: 1, caseId: options.caseId, fixtureId }, null, 2)}\n`,
|
|
208
|
-
0o600,
|
|
209
|
-
)
|
|
210
|
-
console.log(`Prepared ${options.caseId} (${fixtureId}) in ${target}`)
|
|
211
|
-
console.log('Before validation, run `yarn generate` in the target and link its node_modules to the controller dependency tree.')
|
|
212
|
-
console.log(`Run: yarn harness:validate --runner <codex|claude> --case ${options.caseId} --writable-root ${target} --acknowledge-writes`)
|
|
213
|
-
return 0
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
try {
|
|
217
|
-
process.exitCode = main()
|
|
218
|
-
} catch (error) {
|
|
219
|
-
console.error(error instanceof Error ? error.message : String(error))
|
|
220
|
-
console.error(usage())
|
|
221
|
-
process.exitCode = 2
|
|
222
|
-
}
|