@intentius/chant 0.79.0 → 0.81.0
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/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +30 -0
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts +5 -0
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +13 -0
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/terraform-state.d.ts +13 -0
- package/dist/audit/terraform-state.d.ts.map +1 -1
- package/dist/cli/command-group.d.ts +6 -0
- package/dist/cli/command-group.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +44 -3
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +8 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/import-agents.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/update.d.ts +6 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/vendor.d.ts +5 -0
- package/dist/cli/commands/vendor.d.ts.map +1 -1
- package/dist/cli/conflict-check.d.ts +6 -0
- package/dist/cli/conflict-check.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/init.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +7 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/promote.d.ts +20 -0
- package/dist/cli/handlers/promote.d.ts.map +1 -0
- package/dist/cli/handlers/run-generate.d.ts +39 -0
- package/dist/cli/handlers/run-generate.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts +4 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/vendor.d.ts +8 -3
- package/dist/cli/handlers/vendor.d.ts.map +1 -1
- package/dist/cli/main.d.ts +12 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/plugins.d.ts +14 -0
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +46 -1
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts +10 -0
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +3 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/driver.d.ts +16 -2
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/gate-plan.d.ts +40 -0
- package/dist/components/gate-plan.d.ts.map +1 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts +7 -1
- package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -1
- package/dist/components/presets/ecs-fargate.d.ts +10 -4
- package/dist/components/presets/ecs-fargate.d.ts.map +1 -1
- package/dist/components/promote.d.ts +264 -0
- package/dist/components/promote.d.ts.map +1 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/run.d.ts.map +1 -1
- package/dist/components/verbs/build-archive.d.ts +22 -11
- package/dist/components/verbs/build-archive.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/config-static.d.ts +59 -0
- package/dist/config-static.d.ts.map +1 -0
- package/dist/config.d.ts +104 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/content-digest.d.ts +17 -0
- package/dist/content-digest.d.ts.map +1 -0
- package/dist/discovery/files.d.ts +48 -4
- package/dist/discovery/files.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +32 -1
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.d.ts +20 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/fork.d.ts +20 -0
- package/dist/discovery/sandbox/fork.d.ts.map +1 -1
- package/dist/discovery/walk.d.ts +119 -0
- package/dist/discovery/walk.d.ts.map +1 -0
- package/dist/graph-ir.d.ts +17 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/join-key.d.ts +31 -0
- package/dist/join-key.d.ts.map +1 -0
- package/dist/lexicon-module.d.ts +110 -0
- package/dist/lexicon-module.d.ts.map +1 -0
- package/dist/lexicon.d.ts +82 -1
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/build-ledger-store.d.ts.map +1 -1
- package/dist/lifecycle/digest.d.ts +5 -1
- package/dist/lifecycle/digest.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +20 -5
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +64 -0
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/lease.d.ts +8 -1
- package/dist/lifecycle/lease.d.ts.map +1 -1
- package/dist/lifecycle/legacy-digest.d.ts +59 -0
- package/dist/lifecycle/legacy-digest.d.ts.map +1 -0
- package/dist/lifecycle/member-ledger.d.ts +67 -0
- package/dist/lifecycle/member-ledger.d.ts.map +1 -0
- package/dist/lifecycle/plan-digest.d.ts +4 -3
- package/dist/lifecycle/plan-digest.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts +42 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts +90 -5
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +2 -3
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +32 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/index.d.ts +2 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/propose-upgrade.d.ts +75 -0
- package/dist/op/activities/propose-upgrade.d.ts.map +1 -0
- package/dist/op/activity-contract-registry.d.ts.map +1 -1
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-name.d.ts +7 -0
- package/dist/op/gate-name.d.ts.map +1 -1
- package/dist/op/gate-summary.d.ts +16 -0
- package/dist/op/gate-summary.d.ts.map +1 -1
- package/dist/op/gate.d.ts +16 -2
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/generate-pipeline.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/project-root.d.ts +26 -0
- package/dist/project-root.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts +37 -0
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts +11 -0
- package/dist/workspace/__fixtures__/two-member-workspace.d.ts.map +1 -0
- package/dist/workspace/checks/generated.d.ts +156 -0
- package/dist/workspace/checks/generated.d.ts.map +1 -0
- package/dist/workspace/checks/ledgers.d.ts +78 -0
- package/dist/workspace/checks/ledgers.d.ts.map +1 -0
- package/dist/workspace/checks/links.d.ts +25 -0
- package/dist/workspace/checks/links.d.ts.map +1 -0
- package/dist/workspace/checks/pipelines.d.ts +76 -0
- package/dist/workspace/checks/pipelines.d.ts.map +1 -0
- package/dist/workspace/checks.d.ts +161 -0
- package/dist/workspace/checks.d.ts.map +1 -0
- package/dist/workspace/compose-graph.d.ts +115 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -0
- package/dist/workspace/compose-reports.d.ts +68 -0
- package/dist/workspace/compose-reports.d.ts.map +1 -0
- package/dist/workspace/declaration.d.ts +220 -0
- package/dist/workspace/declaration.d.ts.map +1 -0
- package/dist/workspace/declaration.schema.json +434 -0
- package/dist/workspace/generated-files.d.ts +65 -0
- package/dist/workspace/generated-files.d.ts.map +1 -0
- package/dist/workspace/glob.d.ts +13 -0
- package/dist/workspace/glob.d.ts.map +1 -0
- package/dist/workspace/graph-cli.d.ts +75 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +96 -0
- package/dist/workspace/init.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +38 -0
- package/dist/workspace/jsonc.d.ts.map +1 -0
- package/dist/workspace/kinds.d.ts +192 -0
- package/dist/workspace/kinds.d.ts.map +1 -0
- package/dist/workspace/lineage-check.d.ts +84 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -0
- package/dist/workspace/lineage-cli.d.ts +31 -0
- package/dist/workspace/lineage-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-init.d.ts +101 -0
- package/dist/workspace/lineage-init.d.ts.map +1 -0
- package/dist/workspace/lineage-lock.d.ts +258 -0
- package/dist/workspace/lineage-lock.d.ts.map +1 -0
- package/dist/workspace/lineage-merge.d.ts +14 -0
- package/dist/workspace/lineage-merge.d.ts.map +1 -0
- package/dist/workspace/lineage-migrations.d.ts +178 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -0
- package/dist/workspace/lineage-update.d.ts +59 -0
- package/dist/workspace/lineage-update.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts +40 -0
- package/dist/workspace/lineage-upgrade-cli.d.ts.map +1 -0
- package/dist/workspace/lineage-upgrade.d.ts +146 -0
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -0
- package/dist/workspace/lineage-vendor.d.ts +63 -0
- package/dist/workspace/lineage-vendor.d.ts.map +1 -0
- package/dist/workspace/lineage-version.d.ts +32 -0
- package/dist/workspace/lineage-version.d.ts.map +1 -0
- package/dist/workspace/links.d.ts +150 -0
- package/dist/workspace/links.d.ts.map +1 -0
- package/dist/workspace/ls.d.ts +99 -0
- package/dist/workspace/ls.d.ts.map +1 -0
- package/dist/workspace/member-commands.d.ts +139 -0
- package/dist/workspace/member-commands.d.ts.map +1 -0
- package/dist/workspace/member-handles.d.ts +54 -0
- package/dist/workspace/member-handles.d.ts.map +1 -0
- package/dist/workspace/member-pipeline.d.ts +143 -0
- package/dist/workspace/member-pipeline.d.ts.map +1 -0
- package/dist/workspace/member-run.d.ts +67 -0
- package/dist/workspace/member-run.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +65 -0
- package/dist/workspace/reason-codes.d.ts.map +1 -0
- package/dist/workspace/record-source.d.ts +22 -0
- package/dist/workspace/record-source.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +81 -0
- package/dist/workspace/records-cli.d.ts.map +1 -0
- package/dist/workspace/records.d.ts +118 -0
- package/dist/workspace/records.d.ts.map +1 -0
- package/dist/workspace/root-refusal.d.ts +53 -0
- package/dist/workspace/root-refusal.d.ts.map +1 -0
- package/dist/workspace/status.d.ts +150 -0
- package/dist/workspace/status.d.ts.map +1 -0
- package/dist/workspace/template-manifest.d.ts +90 -0
- package/dist/workspace/template-manifest.d.ts.map +1 -0
- package/dist/workspace/tree.d.ts +36 -0
- package/dist/workspace/tree.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts +67 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -0
- package/dist/workspace/trust/policy.d.ts +111 -0
- package/dist/workspace/trust/policy.d.ts.map +1 -0
- package/dist/workspace/trust/provenance.d.ts +67 -0
- package/dist/workspace/trust/provenance.d.ts.map +1 -0
- package/dist/workspace/trust/ssh-commit.d.ts +43 -0
- package/dist/workspace/trust/ssh-commit.d.ts.map +1 -0
- package/dist/workspace/trust/test-repo.d.ts +42 -0
- package/dist/workspace/trust/test-repo.d.ts.map +1 -0
- package/dist/workspace/trust/verify-cli.d.ts +9 -0
- package/dist/workspace/trust/verify-cli.d.ts.map +1 -0
- package/dist/workspace/trust/verify.d.ts +66 -0
- package/dist/workspace/trust/verify.d.ts.map +1 -0
- package/dist/workspace/which-chant.d.ts +58 -0
- package/dist/workspace/which-chant.d.ts.map +1 -0
- package/dist/workspace/workspace-kinds.schema.json +133 -0
- package/package.json +4 -3
- package/src/audit/core.ts +13 -2
- package/src/audit/discover.ts +102 -36
- package/src/audit/report-html.ts +3 -1
- package/src/audit/report-model.ts +14 -1
- package/src/audit/terraform-state.test.ts +81 -1
- package/src/audit/terraform-state.ts +25 -0
- package/src/cli/command-group.ts +7 -0
- package/src/cli/commands/audit-truncation.test.ts +167 -0
- package/src/cli/commands/audit.ts +132 -29
- package/src/cli/commands/check-lexicon-examples.ts +2 -1
- package/src/cli/commands/check-lexicon.ts +24 -0
- package/src/cli/commands/doctor.test.ts +30 -0
- package/src/cli/commands/doctor.ts +21 -0
- package/src/cli/commands/import-agents.ts +15 -4
- package/src/cli/commands/init.ts +76 -25
- package/src/cli/commands/lint.test.ts +52 -1
- package/src/cli/commands/lint.ts +41 -71
- package/src/cli/commands/onboard.ts +15 -0
- package/src/cli/commands/update.ts +18 -5
- package/src/cli/commands/vendor.ts +11 -6
- package/src/cli/conflict-check.test.ts +18 -1
- package/src/cli/conflict-check.ts +13 -0
- package/src/cli/discovery-skip.test.ts +168 -0
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +38 -0
- package/src/cli/handlers/build-member.test.ts +127 -0
- package/src/cli/handlers/build.test.ts +11 -0
- package/src/cli/handlers/build.ts +35 -1
- package/src/cli/handlers/components.test.ts +127 -0
- package/src/cli/handlers/components.ts +70 -8
- package/src/cli/handlers/dev.ts +6 -1
- package/src/cli/handlers/fan-out.ts +9 -2
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +4 -2
- package/src/cli/handlers/init.ts +54 -1
- package/src/cli/handlers/lifecycle.ts +2 -1
- package/src/cli/handlers/misc.ts +16 -0
- package/src/cli/handlers/operator.test.ts +68 -0
- package/src/cli/handlers/operator.ts +39 -10
- package/src/cli/handlers/promote.test.ts +377 -0
- package/src/cli/handlers/promote.ts +391 -0
- package/src/cli/handlers/run-generate-member.test.ts +83 -0
- package/src/cli/handlers/run-generate.test.ts +158 -0
- package/src/cli/handlers/run-generate.ts +168 -0
- package/src/cli/handlers/run.test.ts +47 -0
- package/src/cli/handlers/run.ts +41 -6
- package/src/cli/handlers/vendor.ts +147 -43
- package/src/cli/main.test.ts +137 -1
- package/src/cli/main.ts +290 -24
- package/src/cli/mcp/op-tools.ts +2 -1
- package/src/cli/path-lexicon-messages.test.ts +152 -0
- package/src/cli/plugins.ts +43 -5
- package/src/cli/registry.ts +46 -1
- package/src/cli/static-config-read.test.ts +208 -0
- package/src/codegen/fetch.test.ts +63 -1
- package/src/codegen/fetch.ts +30 -1
- package/src/components/__fixtures__/alb-ecs-service.json +0 -8
- package/src/components/capability-plugin-loader.ts +3 -1
- package/src/components/cli-support.ts +9 -3
- package/src/components/discover.test.ts +27 -57
- package/src/components/discover.ts +20 -51
- package/src/components/driver.test.ts +90 -12
- package/src/components/driver.ts +43 -5
- package/src/components/fan-out-support.ts +2 -1
- package/src/components/gate-plan.ts +53 -0
- package/src/components/pilots/README.md +1 -1
- package/src/components/pilots/alb-ecs.pilot.ts +7 -7
- package/src/components/presets/ecs-fargate.ts +10 -5
- package/src/components/promote.test.ts +645 -0
- package/src/components/promote.ts +641 -0
- package/src/components/sandbox/driver.ts +8 -8
- package/src/components/sandbox/run.ts +4 -1
- package/src/components/verbs/build-archive.ts +27 -21
- package/src/components/verbs/run-agent.ts +3 -5
- package/src/config-static.test.ts +136 -0
- package/src/config-static.ts +232 -0
- package/src/config.test.ts +40 -0
- package/src/config.ts +161 -11
- package/src/content-digest.test.ts +120 -0
- package/src/content-digest.ts +21 -0
- package/src/discovery/files.test.ts +127 -1
- package/src/discovery/files.ts +91 -59
- package/src/discovery/fold-import.ts +127 -9
- package/src/discovery/index.ts +1 -0
- package/src/discovery/sandbox/driver.ts +73 -35
- package/src/discovery/sandbox/fork-diagnostic.test.ts +136 -13
- package/src/discovery/sandbox/fork.ts +83 -43
- package/src/discovery/sandbox/path-lexicon-multifile.test.ts +285 -0
- package/src/discovery/sandbox/path-lexicon-parity.test.ts +162 -0
- package/src/discovery/walk.test.ts +263 -0
- package/src/discovery/walk.ts +334 -0
- package/src/effect-receipt.ts +2 -2
- package/src/graph-ir.ts +18 -1
- package/src/join-key.test.ts +25 -0
- package/src/join-key.ts +39 -0
- package/src/lexicon-module.test.ts +203 -0
- package/src/lexicon-module.ts +215 -0
- package/src/lexicon.ts +105 -1
- package/src/lifecycle/build-ledger-store.ts +13 -2
- package/src/lifecycle/digest.ts +9 -5
- package/src/lifecycle/gate-ledger.test.ts +20 -0
- package/src/lifecycle/gate-ledger.ts +28 -6
- package/src/lifecycle/git.test.ts +13 -1
- package/src/lifecycle/git.ts +221 -176
- package/src/lifecycle/lease.ts +25 -10
- package/src/lifecycle/legacy-digest.test.ts +206 -0
- package/src/lifecycle/legacy-digest.ts +103 -0
- package/src/lifecycle/member-ledger.test.ts +319 -0
- package/src/lifecycle/member-ledger.ts +145 -0
- package/src/lifecycle/plan-digest.ts +7 -7
- package/src/lifecycle/release-ledger.test.ts +20 -0
- package/src/lifecycle/release-ledger.ts +53 -3
- package/src/lifecycle/status.test.ts +151 -1
- package/src/lifecycle/status.ts +228 -7
- package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +2 -3
- package/src/op/activities/activity-contracts.ts +37 -0
- package/src/op/activities/index.ts +10 -0
- package/src/op/activities/propose-upgrade.ts +206 -0
- package/src/op/activity-contract-registry.ts +18 -4
- package/src/op/activity-registry.ts +26 -0
- package/src/op/discover.test.ts +14 -4
- package/src/op/discover.ts +19 -23
- package/src/op/gate-approval.ts +3 -1
- package/src/op/gate-name.ts +8 -0
- package/src/op/gate-summary.test.ts +14 -0
- package/src/op/gate-summary.ts +25 -2
- package/src/op/gate.ts +36 -7
- package/src/op/generate-pipeline.test.ts +14 -5
- package/src/op/generate-pipeline.ts +2 -1
- package/src/op/runtimes/local.ts +2 -1
- package/src/project-root.test.ts +66 -1
- package/src/project-root.ts +48 -0
- package/src/workspace/__fixtures__/contract-repo.ts +100 -0
- package/src/workspace/__fixtures__/two-member-workspace.ts +35 -0
- package/src/workspace/behold-kinds.test.ts +162 -0
- package/src/workspace/check-contract.test.ts +127 -0
- package/src/workspace/check.schema.json +347 -0
- package/src/workspace/checks/generated.test.ts +287 -0
- package/src/workspace/checks/generated.ts +475 -0
- package/src/workspace/checks/ledgers.test.ts +139 -0
- package/src/workspace/checks/ledgers.ts +246 -0
- package/src/workspace/checks/links.ts +183 -0
- package/src/workspace/checks/pipelines.test.ts +133 -0
- package/src/workspace/checks/pipelines.ts +225 -0
- package/src/workspace/checks-repo.test.ts +71 -0
- package/src/workspace/checks.test.ts +450 -0
- package/src/workspace/checks.ts +461 -0
- package/src/workspace/compose-graph.test.ts +146 -0
- package/src/workspace/compose-graph.ts +228 -0
- package/src/workspace/compose-reports.test.ts +109 -0
- package/src/workspace/compose-reports.ts +186 -0
- package/src/workspace/declaration.schema.json +434 -0
- package/src/workspace/declaration.test.ts +347 -0
- package/src/workspace/declaration.ts +623 -0
- package/src/workspace/generated-files.test.ts +114 -0
- package/src/workspace/generated-files.ts +94 -0
- package/src/workspace/glob.ts +49 -0
- package/src/workspace/graph-cli.ts +220 -0
- package/src/workspace/graph-contract.test.ts +204 -0
- package/src/workspace/graph.schema.json +662 -0
- package/src/workspace/init.test.ts +223 -0
- package/src/workspace/init.ts +585 -0
- package/src/workspace/jsonc.test.ts +65 -0
- package/src/workspace/jsonc.ts +231 -0
- package/src/workspace/kinds.test.ts +288 -0
- package/src/workspace/kinds.ts +506 -0
- package/src/workspace/lineage-check.ts +264 -0
- package/src/workspace/lineage-cli.ts +114 -0
- package/src/workspace/lineage-init.test.ts +231 -0
- package/src/workspace/lineage-init.ts +365 -0
- package/src/workspace/lineage-lock.test.ts +224 -0
- package/src/workspace/lineage-lock.ts +357 -0
- package/src/workspace/lineage-merge.ts +44 -0
- package/src/workspace/lineage-migrations.test.ts +178 -0
- package/src/workspace/lineage-migrations.ts +343 -0
- package/src/workspace/lineage-update.ts +160 -0
- package/src/workspace/lineage-upgrade-cli.ts +151 -0
- package/src/workspace/lineage-upgrade.test.ts +474 -0
- package/src/workspace/lineage-upgrade.ts +624 -0
- package/src/workspace/lineage-vendor.test.ts +126 -0
- package/src/workspace/lineage-vendor.ts +215 -0
- package/src/workspace/lineage-version.ts +127 -0
- package/src/workspace/links.test.ts +344 -0
- package/src/workspace/links.ts +331 -0
- package/src/workspace/ls-contract.test.ts +200 -0
- package/src/workspace/ls.schema.json +190 -0
- package/src/workspace/ls.ts +254 -0
- package/src/workspace/member-commands.e2e.test.ts +244 -0
- package/src/workspace/member-commands.test.ts +217 -0
- package/src/workspace/member-commands.ts +540 -0
- package/src/workspace/member-handles.test.ts +76 -0
- package/src/workspace/member-handles.ts +228 -0
- package/src/workspace/member-pipeline.test.ts +135 -0
- package/src/workspace/member-pipeline.ts +317 -0
- package/src/workspace/member-run.ts +146 -0
- package/src/workspace/read-contract.test.ts +129 -0
- package/src/workspace/reason-codes.test.ts +113 -0
- package/src/workspace/reason-codes.ts +81 -0
- package/src/workspace/record-source.ts +117 -0
- package/src/workspace/records-cli.ts +198 -0
- package/src/workspace/records-contract.test.ts +93 -0
- package/src/workspace/records.schema.json +150 -0
- package/src/workspace/records.test.ts +243 -0
- package/src/workspace/records.ts +384 -0
- package/src/workspace/root-refusal.ts +97 -0
- package/src/workspace/status-contract.test.ts +308 -0
- package/src/workspace/status.schema.json +210 -0
- package/src/workspace/status.ts +412 -0
- package/src/workspace/template-manifest.test.ts +79 -0
- package/src/workspace/template-manifest.ts +221 -0
- package/src/workspace/tree.ts +132 -0
- package/src/workspace/trust/attestor.ts +93 -0
- package/src/workspace/trust/policy.ts +306 -0
- package/src/workspace/trust/provenance.ts +181 -0
- package/src/workspace/trust/ssh-commit.ts +138 -0
- package/src/workspace/trust/test-repo.ts +138 -0
- package/src/workspace/trust/trust.test.ts +397 -0
- package/src/workspace/trust/verify-cli.ts +56 -0
- package/src/workspace/trust/verify.ts +194 -0
- package/src/workspace/which-chant.test.ts +117 -0
- package/src/workspace/which-chant.ts +151 -0
- package/src/workspace/workspace-kinds.schema.json +133 -0
package/src/discovery/files.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { open } from "node:fs/promises";
|
|
2
|
+
import { relative, sep, isAbsolute } from "node:path";
|
|
3
|
+
// @ts-ignore — picomatch has no types declaration
|
|
4
|
+
import picomatch from "picomatch";
|
|
5
|
+
import { resolveDiscoveryGlobs, type DiscoveryGlobs } from "../config";
|
|
6
|
+
import { readHead, walkDiscovery, workspaceMemberDirs } from "./walk";
|
|
4
7
|
|
|
5
8
|
/**
|
|
6
9
|
* Marker chant writes at the top of files it generates (a hosting lexicon's
|
|
@@ -12,13 +15,38 @@ import { join, relative } from "node:path";
|
|
|
12
15
|
*/
|
|
13
16
|
export const GENERATED_MARKER = "Generated by chant — do not edit directly";
|
|
14
17
|
|
|
15
|
-
/**
|
|
16
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Comment a hand-written file carries to keep discovery out of it (#2519): a
|
|
20
|
+
* runnable script with top-level side effects, say, that lives next to the
|
|
21
|
+
* project's declarations. It must be a comment of its own (`// chant-discovery-skip`
|
|
22
|
+
* or inside a block comment) within the first {@link SKIP_MARKER_HEAD_BYTES}
|
|
23
|
+
* bytes of the file. See {@link hasSkipMarker}.
|
|
24
|
+
*/
|
|
25
|
+
export const SKIP_MARKER = "chant-discovery-skip";
|
|
26
|
+
|
|
27
|
+
/** How much of a file's head {@link hasSkipMarker} reads: room for a shebang and a license header. */
|
|
28
|
+
const SKIP_MARKER_HEAD_BYTES = 1024;
|
|
29
|
+
|
|
30
|
+
/** {@link SKIP_MARKER} opening a `//`, `/*` or ` * ` comment line, as a whole word. */
|
|
31
|
+
const SKIP_MARKER_PATTERN = /^[ \t]*(?:\/\/|\/\*+|\*)[ \t]*chant-discovery-skip(?![\w-])/m;
|
|
32
|
+
|
|
33
|
+
/** True when `head`, the start of a file, carries the {@link SKIP_MARKER} comment. */
|
|
34
|
+
export function hasSkipMarker(head: string): boolean {
|
|
35
|
+
return SKIP_MARKER_PATTERN.test(head.slice(0, SKIP_MARKER_HEAD_BYTES));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Whether a file's head carries the {@link GENERATED_MARKER} or the
|
|
40
|
+
* {@link SKIP_MARKER}. Reads only the head. The generated marker is looked for
|
|
41
|
+
* in the first 256 bytes, as it always was.
|
|
42
|
+
*/
|
|
43
|
+
export async function hasDiscoveryMarker(file: string): Promise<boolean> {
|
|
17
44
|
let fh;
|
|
18
45
|
try {
|
|
19
46
|
fh = await open(file, "r");
|
|
20
|
-
const { buffer, bytesRead } = await fh.read({ buffer: Buffer.alloc(
|
|
21
|
-
|
|
47
|
+
const { buffer, bytesRead } = await fh.read({ buffer: Buffer.alloc(SKIP_MARKER_HEAD_BYTES), position: 0 });
|
|
48
|
+
if (buffer.toString("utf8", 0, Math.min(bytesRead, 256)).includes(GENERATED_MARKER)) return true;
|
|
49
|
+
return hasSkipMarker(buffer.toString("utf8", 0, bytesRead));
|
|
22
50
|
} catch {
|
|
23
51
|
return false;
|
|
24
52
|
} finally {
|
|
@@ -26,61 +54,65 @@ async function isGeneratedFile(file: string): Promise<boolean> {
|
|
|
26
54
|
}
|
|
27
55
|
}
|
|
28
56
|
|
|
57
|
+
/** Whether a file's head carries the {@link GENERATED_MARKER} or the {@link SKIP_MARKER}. The synchronous form of {@link hasDiscoveryMarker}. */
|
|
58
|
+
export function hasDiscoveryMarkerSync(file: string): boolean {
|
|
59
|
+
const head = readHead(file, SKIP_MARKER_HEAD_BYTES);
|
|
60
|
+
return head.slice(0, 256).includes(GENERATED_MARKER) || hasSkipMarker(head);
|
|
61
|
+
}
|
|
62
|
+
|
|
29
63
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
64
|
+
* Compile a project's `exclude`/`include` globs (#2519) into a predicate that
|
|
65
|
+
* is true for a file discovery must skip, or `undefined` when there is nothing
|
|
66
|
+
* to skip.
|
|
67
|
+
*
|
|
68
|
+
* Each pattern is matched, with picomatch and dot files included, against the
|
|
69
|
+
* file's path relative to `globs.root` (forward slashes) and against the path
|
|
70
|
+
* of every directory above it, so a pattern naming a directory covers
|
|
71
|
+
* everything under it. A file is skipped when some `exclude` pattern matches
|
|
72
|
+
* and no `include` pattern does: `include` always wins. Files outside
|
|
73
|
+
* `globs.root` are never skipped. The discovery walk (`./walk.ts`) applies the
|
|
74
|
+
* same rule, and also lets `include` re-admit what its default rules skip.
|
|
33
75
|
*/
|
|
34
|
-
export
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
for (const entry of entries) {
|
|
49
|
-
const fullPath = join(dir, entry.name);
|
|
76
|
+
export function compileDiscoveryFilter(globs: DiscoveryGlobs | undefined): ((file: string) => boolean) | undefined {
|
|
77
|
+
if (!globs || globs.exclude.length === 0) return undefined;
|
|
78
|
+
const excluded = picomatch(globs.exclude, { dot: true });
|
|
79
|
+
const included = globs.include.length > 0 ? picomatch(globs.include, { dot: true }) : () => false;
|
|
80
|
+
return (file: string): boolean => {
|
|
81
|
+
const rel = relative(globs.root, file);
|
|
82
|
+
if (rel === "" || rel === ".." || rel.startsWith(`..${sep}`) || isAbsolute(rel)) return false;
|
|
83
|
+
const parts = rel.split(sep);
|
|
84
|
+
const candidates = parts.map((_, i) => parts.slice(0, i + 1).join("/"));
|
|
85
|
+
return candidates.some((c) => excluded(c)) && !candidates.some((c) => included(c));
|
|
86
|
+
};
|
|
87
|
+
}
|
|
50
88
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
89
|
+
/** Options for {@link findInfraFiles}. */
|
|
90
|
+
export interface FindInfraFilesOptions {
|
|
91
|
+
/**
|
|
92
|
+
* The project's discovery globs. Omitted, they are read from the project
|
|
93
|
+
* config `path` belongs to ({@link resolveDiscoveryGlobs}); `null` applies none.
|
|
94
|
+
*/
|
|
95
|
+
globs?: DiscoveryGlobs | null;
|
|
96
|
+
}
|
|
55
97
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// a child project.
|
|
61
|
-
const configPath = join(fullPath, "chant.config.ts");
|
|
62
|
-
if (existsSync(configPath)) {
|
|
63
|
-
if (sourceRoot === null) {
|
|
64
|
-
sourceRoot = fullPath;
|
|
65
|
-
} else {
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
await scanDirectory(fullPath);
|
|
70
|
-
} else if (entry.isFile()) {
|
|
71
|
-
// Include only .ts files, exclude test files and chant-generated files
|
|
72
|
-
if (
|
|
73
|
-
entry.name.endsWith(".ts") &&
|
|
74
|
-
!entry.name.endsWith(".test.ts") &&
|
|
75
|
-
!entry.name.endsWith(".spec.ts") &&
|
|
76
|
-
!(await isGeneratedFile(fullPath))
|
|
77
|
-
) {
|
|
78
|
-
files.push(fullPath);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
98
|
+
/** A TypeScript source file by name: `.ts`, not a test or spec. */
|
|
99
|
+
export function isSourceFileName(name: string): boolean {
|
|
100
|
+
return name.endsWith(".ts") && !name.endsWith(".test.ts") && !name.endsWith(".spec.ts");
|
|
101
|
+
}
|
|
83
102
|
|
|
84
|
-
|
|
85
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Find every TypeScript infrastructure file under `path`, through the one
|
|
105
|
+
* discovery walk (`./walk.ts`, #2527): test and spec files, chant-generated
|
|
106
|
+
* files, skip-marked files and whatever the walk's rules and the project's
|
|
107
|
+
* globs skip are left out.
|
|
108
|
+
*/
|
|
109
|
+
export async function findInfraFiles(path: string, options?: FindInfraFilesOptions): Promise<string[]> {
|
|
110
|
+
const globs = options?.globs === null ? undefined : (options?.globs ?? (await resolveDiscoveryGlobs(path)));
|
|
111
|
+
return walkDiscovery({
|
|
112
|
+
walker: "source",
|
|
113
|
+
root: path,
|
|
114
|
+
globs,
|
|
115
|
+
excludeDirs: await workspaceMemberDirs(path),
|
|
116
|
+
accept: (name, full) => isSourceFileName(name) && !hasDiscoveryMarkerSync(full),
|
|
117
|
+
});
|
|
86
118
|
}
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
type FoldedCompositeStepCall,
|
|
28
28
|
} from "../fold/fold";
|
|
29
29
|
import { isChantOwnedSpecifier, isFoldableHelperName } from "../fold/foldable-helpers";
|
|
30
|
+
import { lexiconModulePath, lexiconModuleRoot } from "../lexicon-module";
|
|
30
31
|
import {
|
|
31
32
|
briefNodeText,
|
|
32
33
|
callExpressionMessage,
|
|
@@ -247,6 +248,32 @@ export interface FoldSession {
|
|
|
247
248
|
* established one.
|
|
248
249
|
*/
|
|
249
250
|
readonly lexiconPackages: ReadonlySet<string>;
|
|
251
|
+
/**
|
|
252
|
+
* chant#2577 — the absolute module paths of this build's lexicons that
|
|
253
|
+
* `chant.config.ts` declares by path (#2520), each resolved to the file an
|
|
254
|
+
* import of it reaches. Such a lexicon has no package specifier, so a
|
|
255
|
+
* project imports it by a relative or absolute path. A binding whose path
|
|
256
|
+
* resolves to one of these is treated exactly like a binding of a
|
|
257
|
+
* {@link lexiconPackages} entry: its data exports resolve as values, and
|
|
258
|
+
* under `--sandbox` it is on {@link isTrustedExecutableBinding}'s allowlist,
|
|
259
|
+
* because `loadPlugins` has already imported and run it in this process.
|
|
260
|
+
*
|
|
261
|
+
* Only the declared module itself is in the set. The other files of a
|
|
262
|
+
* multi-file path lexicon are covered by {@link lexiconRoots}.
|
|
263
|
+
*/
|
|
264
|
+
readonly lexiconModules: ReadonlySet<string>;
|
|
265
|
+
/**
|
|
266
|
+
* chant#2590 — the directory trusted for each path-declared lexicon that has
|
|
267
|
+
* one (`../lexicon-module.ts`'s `pathLexiconRoot`: the declared `root`, or
|
|
268
|
+
* the module's own directory, inside the project and not containing its
|
|
269
|
+
* source directory). A file under one of these gets what a subpath of an
|
|
270
|
+
* active lexicon package gets: a place on the `--sandbox` trust list, and
|
|
271
|
+
* no fold as a project file. Its data exports are not read as values,
|
|
272
|
+
* which is also how a package subpath is treated. A directory that holds
|
|
273
|
+
* any of the build's own source files is dropped, so the build's source is
|
|
274
|
+
* never trusted this way.
|
|
275
|
+
*/
|
|
276
|
+
readonly lexiconRoots: readonly string[];
|
|
250
277
|
/**
|
|
251
278
|
* chant #1093 — this build asked for the #1045 sandbox
|
|
252
279
|
* (`DiscoveryOptions.sandbox`, `chant build --sandbox`), so fold must not
|
|
@@ -326,7 +353,24 @@ export function createFoldSession(
|
|
|
326
353
|
lexiconPackages: readonly string[] = [],
|
|
327
354
|
/** chant#2455 — `ι = executing`. Mutually exclusive with `sandbox`. */
|
|
328
355
|
executing = false,
|
|
356
|
+
/**
|
|
357
|
+
* chant#2590 — the build's own source files. A path lexicon's trusted
|
|
358
|
+
* directory that holds any of them is dropped (see {@link FoldSession.lexiconRoots}).
|
|
359
|
+
*/
|
|
360
|
+
sourceFiles: readonly string[] = [],
|
|
329
361
|
): FoldSession {
|
|
362
|
+
// chant#2577 — a lexicon declared by path is that module and no package, so
|
|
363
|
+
// its name contributes the module path and not `@intentius/chant-lexicon-<name>`.
|
|
364
|
+
const packages = new Set(lexiconPackages);
|
|
365
|
+
const modules = new Set<string>();
|
|
366
|
+
const roots: string[] = [];
|
|
367
|
+
for (const name of lexicons) {
|
|
368
|
+
const modulePath = lexiconModulePath(name);
|
|
369
|
+
if (modulePath === undefined) packages.add(lexiconPackageName(name));
|
|
370
|
+
else modules.add(resolveModulePath(modulePath, modulePath));
|
|
371
|
+
const root = lexiconModuleRoot(name);
|
|
372
|
+
if (root !== undefined && !sourceFiles.some((file) => isUnderDirectory(resolvePath(file), root))) roots.push(root);
|
|
373
|
+
}
|
|
330
374
|
return {
|
|
331
375
|
intrinsics,
|
|
332
376
|
cache: new Map(),
|
|
@@ -334,7 +378,9 @@ export function createFoldSession(
|
|
|
334
378
|
importCache: new Map(),
|
|
335
379
|
resolvePathCache: new Map(),
|
|
336
380
|
buildParams,
|
|
337
|
-
lexiconPackages:
|
|
381
|
+
lexiconPackages: packages,
|
|
382
|
+
lexiconModules: modules,
|
|
383
|
+
lexiconRoots: roots,
|
|
338
384
|
sandbox,
|
|
339
385
|
executing,
|
|
340
386
|
factoryModules: new Map(),
|
|
@@ -1104,6 +1150,39 @@ function activeLexiconPackage(specifier: string, lexiconPackages: ReadonlySet<st
|
|
|
1104
1150
|
return lexiconPackages.has(specifier) ? specifier : undefined;
|
|
1105
1151
|
}
|
|
1106
1152
|
|
|
1153
|
+
/**
|
|
1154
|
+
* chant#2577 — the path-declared counterpart of {@link activeLexiconPackage}:
|
|
1155
|
+
* the resolved module path when a relative or absolute `specifier` reaches
|
|
1156
|
+
* one of this build's {@link FoldSession.lexiconModules}, `undefined`
|
|
1157
|
+
* otherwise. A bare specifier is never resolved here, and a build with no
|
|
1158
|
+
* path-declared lexicon resolves nothing.
|
|
1159
|
+
*/
|
|
1160
|
+
function activeLexiconModule(
|
|
1161
|
+
specifier: string,
|
|
1162
|
+
fromFile: string,
|
|
1163
|
+
lexiconModules: ReadonlySet<string>,
|
|
1164
|
+
resolvePathCache: Map<string, string>,
|
|
1165
|
+
): string | undefined {
|
|
1166
|
+
if (lexiconModules.size === 0 || !isProjectFileSpecifier(specifier)) return undefined;
|
|
1167
|
+
let modulePath: string;
|
|
1168
|
+
try {
|
|
1169
|
+
modulePath = resolveModulePathMemoized(specifier, fromFile, resolvePathCache);
|
|
1170
|
+
} catch {
|
|
1171
|
+
return undefined;
|
|
1172
|
+
}
|
|
1173
|
+
return lexiconModules.has(modulePath) ? modulePath : undefined;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
/** chant#2590 — true when absolute `file` lies under absolute directory `dir`. */
|
|
1177
|
+
function isUnderDirectory(file: string, dir: string): boolean {
|
|
1178
|
+
return file.startsWith(dir.endsWith(sep) ? dir : dir + sep);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/** chant#2590 — true when `path` lies under one of the build's trusted path-lexicon directories. */
|
|
1182
|
+
function inPathLexiconRoot(path: string, roots: readonly string[]): boolean {
|
|
1183
|
+
return roots.some((root) => isUnderDirectory(path, root));
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1107
1186
|
/**
|
|
1108
1187
|
* chant #1995 — the package-ROOT portion of a bare subpath specifier
|
|
1109
1188
|
* (`@intentius/chant-lexicon-azure/generated/index` ->
|
|
@@ -1168,13 +1247,17 @@ async function resolveActiveLexiconExport(
|
|
|
1168
1247
|
fromFile: string,
|
|
1169
1248
|
session: FoldSession,
|
|
1170
1249
|
): Promise<{ value: unknown } | undefined> {
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1250
|
+
let modulePath: string | undefined;
|
|
1251
|
+
if (activeLexiconPackage(binding.specifier, session.lexiconPackages)) {
|
|
1252
|
+
try {
|
|
1253
|
+
modulePath = resolveModulePathMemoized(binding.specifier, fromFile, session.resolvePathCache);
|
|
1254
|
+
} catch {
|
|
1255
|
+
return undefined;
|
|
1256
|
+
}
|
|
1257
|
+
} else {
|
|
1258
|
+
// chant#2577 — a lexicon declared by path, imported by its path.
|
|
1259
|
+
modulePath = activeLexiconModule(binding.specifier, fromFile, session.lexiconModules, session.resolvePathCache);
|
|
1260
|
+
if (modulePath === undefined) return undefined;
|
|
1178
1261
|
}
|
|
1179
1262
|
|
|
1180
1263
|
let mod: Record<string, unknown>;
|
|
@@ -1278,6 +1361,10 @@ interface ResolveCtx {
|
|
|
1278
1361
|
* site that imports and executes a module.
|
|
1279
1362
|
*/
|
|
1280
1363
|
lexiconPackages: ReadonlySet<string>;
|
|
1364
|
+
/** chant#2577 — see {@link FoldSession.lexiconModules}. */
|
|
1365
|
+
lexiconModules: ReadonlySet<string>;
|
|
1366
|
+
/** chant#2590 — see {@link FoldSession.lexiconRoots}. */
|
|
1367
|
+
lexiconRoots: readonly string[];
|
|
1281
1368
|
/** chant #1093 — see {@link FoldSession.sandbox}. */
|
|
1282
1369
|
sandbox: boolean;
|
|
1283
1370
|
/** chant#2455 — see {@link FoldSession.executing}. */
|
|
@@ -2053,7 +2140,10 @@ function findCompositeDefinition(
|
|
|
2053
2140
|
// chant build the set holds only `@intentius/chant-lexicon-*`, and no
|
|
2054
2141
|
// lexicon exports a `Composite`, so nothing about a chant project moves.
|
|
2055
2142
|
const chantOwned = isChantOwnedHelperBinding(compositeBinding, { ...ctx, file: scope.file });
|
|
2056
|
-
const hostOwned =
|
|
2143
|
+
const hostOwned =
|
|
2144
|
+
activeLexiconPackage(compositeBinding.specifier, ctx.lexiconPackages) !== undefined ||
|
|
2145
|
+
activeLexiconModule(compositeBinding.specifier, scope.file, ctx.lexiconModules, ctx.resolvePathCache) !==
|
|
2146
|
+
undefined;
|
|
2057
2147
|
if (!chantOwned && !hostOwned) return undefined;
|
|
2058
2148
|
|
|
2059
2149
|
const [fnArg, nameArg] = init.arguments;
|
|
@@ -2425,6 +2515,8 @@ async function interpretCompositeFactory(
|
|
|
2425
2515
|
importCache: ctx.importCache,
|
|
2426
2516
|
resolvePathCache: ctx.resolvePathCache,
|
|
2427
2517
|
lexiconPackages: ctx.lexiconPackages,
|
|
2518
|
+
lexiconModules: ctx.lexiconModules,
|
|
2519
|
+
lexiconRoots: ctx.lexiconRoots,
|
|
2428
2520
|
sandbox: ctx.sandbox,
|
|
2429
2521
|
executing: ctx.executing,
|
|
2430
2522
|
session: ctx.session,
|
|
@@ -3048,6 +3140,12 @@ function isTrustedExecutableBinding(binding: ImportBinding, ctx: ResolveCtx): bo
|
|
|
3048
3140
|
} catch {
|
|
3049
3141
|
return false;
|
|
3050
3142
|
}
|
|
3143
|
+
// chant#2577 — arm 1 for a lexicon declared by path: the module
|
|
3144
|
+
// `loadPlugins` already imported, reached by the path the project imports it by.
|
|
3145
|
+
if (ctx.lexiconModules.has(targetPath)) return true;
|
|
3146
|
+
// chant#2590 — the subpath case of the same arm: another file of a
|
|
3147
|
+
// multi-file path lexicon, under its trusted directory.
|
|
3148
|
+
if (inPathLexiconRoot(targetPath, ctx.lexiconRoots)) return true;
|
|
3051
3149
|
const root = chantCoreRoot();
|
|
3052
3150
|
return targetPath === root || targetPath.startsWith(root + sep);
|
|
3053
3151
|
}
|
|
@@ -3607,6 +3705,20 @@ async function buildExternals(
|
|
|
3607
3705
|
} catch {
|
|
3608
3706
|
continue;
|
|
3609
3707
|
}
|
|
3708
|
+
// chant#2577 — a path-declared lexicon is a lexicon, not a project file:
|
|
3709
|
+
// resolve its data export the way the bare-specifier branch above does,
|
|
3710
|
+
// with no `liveSources` edge for the same reason.
|
|
3711
|
+
if (session.lexiconModules.has(targetPath)) {
|
|
3712
|
+
const lexiconExport = await resolveActiveLexiconExport(binding, file, session);
|
|
3713
|
+
if (lexiconExport) externals.set(localName, lexiconExport.value);
|
|
3714
|
+
continue;
|
|
3715
|
+
}
|
|
3716
|
+
// chant#2590 — another file of a multi-file path lexicon is a lexicon
|
|
3717
|
+
// subpath, not a project file: it is not folded, and like a package
|
|
3718
|
+
// subpath (see the bare-specifier branch above) its data exports are not
|
|
3719
|
+
// read as values. A constructor or composite from it resolves through the
|
|
3720
|
+
// import path, where `isTrustedExecutableBinding` admits it.
|
|
3721
|
+
if (inPathLexiconRoot(targetPath, session.lexiconRoots)) continue;
|
|
3610
3722
|
const result = await foldFileMemoized(targetPath, session);
|
|
3611
3723
|
if (!result.ok) {
|
|
3612
3724
|
failures.set(localName, locatedMessage(binding.specifierNode, result.reason));
|
|
@@ -3632,6 +3744,9 @@ async function buildExternals(
|
|
|
3632
3744
|
} catch {
|
|
3633
3745
|
continue;
|
|
3634
3746
|
}
|
|
3747
|
+
// chant#2577 — a namespace import of a lexicon is left alone, as the
|
|
3748
|
+
// bare-specifier check above leaves a package's alone.
|
|
3749
|
+
if (session.lexiconModules.has(targetPath) || inPathLexiconRoot(targetPath, session.lexiconRoots)) continue;
|
|
3635
3750
|
const result = await foldFileMemoized(targetPath, session);
|
|
3636
3751
|
if (!result.ok) {
|
|
3637
3752
|
failures.set(localName, locatedMessage(binding.specifierNode, result.reason));
|
|
@@ -3738,6 +3853,8 @@ async function tryFoldFileCore(file: string, session: FoldSession): Promise<Fold
|
|
|
3738
3853
|
importCache: session.importCache,
|
|
3739
3854
|
resolvePathCache: session.resolvePathCache,
|
|
3740
3855
|
lexiconPackages: session.lexiconPackages,
|
|
3856
|
+
lexiconModules: session.lexiconModules,
|
|
3857
|
+
lexiconRoots: session.lexiconRoots,
|
|
3741
3858
|
sandbox: session.sandbox,
|
|
3742
3859
|
executing: session.executing,
|
|
3743
3860
|
session,
|
|
@@ -4267,6 +4384,7 @@ export async function foldProject(
|
|
|
4267
4384
|
options.sandbox ?? false,
|
|
4268
4385
|
options.lexiconPackages ?? [],
|
|
4269
4386
|
options.executing ?? false,
|
|
4387
|
+
files,
|
|
4270
4388
|
);
|
|
4271
4389
|
const attempts = new Map<string, FoldFileResult>();
|
|
4272
4390
|
for (const file of files) attempts.set(file, await tryFoldFile(file, intrinsics, session));
|
package/src/discovery/index.ts
CHANGED
|
@@ -70,6 +70,49 @@ function lit(value: unknown): string {
|
|
|
70
70
|
return JSON.stringify(value);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* chant#2461 — the `send` every driver uses, as generated source lines.
|
|
75
|
+
*
|
|
76
|
+
* `process.send` is asynchronous: it queues the message on the IPC channel and
|
|
77
|
+
* returns. Node's contract is that the optional callback runs once the message
|
|
78
|
+
* has been written, or with an error if it could not be. Without the callback a
|
|
79
|
+
* failed send is not reported to the caller at all, so the driver could return
|
|
80
|
+
* from `main()` believing it had answered.
|
|
81
|
+
*
|
|
82
|
+
* So `send` returns a promise that settles only when the write has completed,
|
|
83
|
+
* and every call site awaits it before `main()` returns. A send that fails, or
|
|
84
|
+
* throws synchronously (a payload that cannot be serialized), writes the reason
|
|
85
|
+
* to stderr with a synchronous `writeSync` and exits 1. That way a result that
|
|
86
|
+
* never left the child cannot end as exit 0 with empty stderr, which is the
|
|
87
|
+
* signature that looks like success went missing.
|
|
88
|
+
*
|
|
89
|
+
* `before` is spliced in at the top of the function body (the run driver marks
|
|
90
|
+
* itself `reported` there).
|
|
91
|
+
*/
|
|
92
|
+
export function sendFunctionSource(before: readonly string[] = []): string[] {
|
|
93
|
+
return [
|
|
94
|
+
`function send(payload) {`,
|
|
95
|
+
...before.map((line) => ` ${line}`),
|
|
96
|
+
` if (typeof process.send !== "function") {`,
|
|
97
|
+
` console.log(JSON.stringify(payload));`,
|
|
98
|
+
` return Promise.resolve();`,
|
|
99
|
+
` }`,
|
|
100
|
+
` return new Promise((resolve) => {`,
|
|
101
|
+
` const lost = (err) => {`,
|
|
102
|
+
` writeSync(2, "chant: the sandboxed child could not hand its result to the parent: " +`,
|
|
103
|
+
` (err && err.message ? err.message : String(err)) + " (chant#2461)\\n");`,
|
|
104
|
+
` process.exit(1);`,
|
|
105
|
+
` };`,
|
|
106
|
+
` try {`,
|
|
107
|
+
` process.send(payload, (err) => (err ? lost(err) : resolve()));`,
|
|
108
|
+
` } catch (err) {`,
|
|
109
|
+
` lost(err);`,
|
|
110
|
+
` }`,
|
|
111
|
+
` });`,
|
|
112
|
+
`}`,
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
|
|
73
116
|
/**
|
|
74
117
|
* Generate the driver module's full TypeScript source. Written to a tmp file
|
|
75
118
|
* and bundled (see `./bundle.ts`) before being handed to a sandboxed child —
|
|
@@ -117,11 +160,7 @@ export function generateDriverSource(options: GenerateDriverOptions): string {
|
|
|
117
160
|
` "Nothing is thrown, so nothing else can name it (chant#2461).\\n");`,
|
|
118
161
|
`});`,
|
|
119
162
|
``,
|
|
120
|
-
`
|
|
121
|
-
` reported = true;`,
|
|
122
|
-
` if (typeof process.send === "function") process.send(payload);`,
|
|
123
|
-
` else console.log(JSON.stringify(payload));`,
|
|
124
|
-
`}`,
|
|
163
|
+
...sendFunctionSource([`reported = true;`]),
|
|
125
164
|
``,
|
|
126
165
|
// collectEntities (bundled, real DiscoveryError instances) already names
|
|
127
166
|
// the exact offending file on a same-directory duplicate — reuse that
|
|
@@ -156,7 +195,7 @@ export function generateDriverSource(options: GenerateDriverOptions): string {
|
|
|
156
195
|
` entities = collectEntities(modules, BUILD_ROOT);`,
|
|
157
196
|
` } catch (err) {`,
|
|
158
197
|
` errors.push(classifyChildError(errFile(err), err, "resolution").toJSON());`,
|
|
159
|
-
` send({ entitySet: { entities: [] }, errors, provenanceByName: {} });`,
|
|
198
|
+
` await send({ entitySet: { entities: [] }, errors, provenanceByName: {} });`,
|
|
160
199
|
` return;`,
|
|
161
200
|
` }`,
|
|
162
201
|
``,
|
|
@@ -178,18 +217,20 @@ export function generateDriverSource(options: GenerateDriverOptions): string {
|
|
|
178
217
|
` errors.push(classifyChildError("", err, "resolution").toJSON());`,
|
|
179
218
|
` }`,
|
|
180
219
|
``,
|
|
220
|
+
` let entitySet;`,
|
|
181
221
|
` try {`,
|
|
182
|
-
`
|
|
183
|
-
` send({ entitySet, errors, provenanceByName });`,
|
|
222
|
+
` entitySet = encodeEntitySet(entities);`,
|
|
184
223
|
` } catch (err) {`,
|
|
185
224
|
` errors.push(classifyChildError("", err, "resolution").toJSON());`,
|
|
186
|
-
` send({ entitySet: { entities: [] }, errors, provenanceByName });`,
|
|
225
|
+
` await send({ entitySet: { entities: [] }, errors, provenanceByName });`,
|
|
226
|
+
` return;`,
|
|
187
227
|
` }`,
|
|
228
|
+
` await send({ entitySet, errors, provenanceByName });`,
|
|
188
229
|
`}`,
|
|
189
230
|
``,
|
|
190
|
-
`main().catch((err)
|
|
191
|
-
` send({ entitySet: { entities: [] }, errors: [classifyChildError("", err).toJSON()], provenanceByName: {}, fatal: true })
|
|
192
|
-
`
|
|
231
|
+
`main().catch((err) =>`,
|
|
232
|
+
` send({ entitySet: { entities: [] }, errors: [classifyChildError("", err).toJSON()], provenanceByName: {}, fatal: true }),`,
|
|
233
|
+
`);`,
|
|
193
234
|
);
|
|
194
235
|
|
|
195
236
|
return lines.join("\n");
|
|
@@ -218,18 +259,16 @@ export function generateConfigDriverSource(configPath: string): string {
|
|
|
218
259
|
return [
|
|
219
260
|
`import { classifyChildError } from ${lit(CHILD_ERRORS_MODULE)};`,
|
|
220
261
|
`import { scanConfigWireSafety } from ${lit(CONFIG_WIRE_MODULE)};`,
|
|
262
|
+
`import { writeSync } from "node:fs";`,
|
|
221
263
|
``,
|
|
222
|
-
|
|
223
|
-
` if (typeof process.send === "function") process.send(payload);`,
|
|
224
|
-
` else console.log(JSON.stringify(payload));`,
|
|
225
|
-
`}`,
|
|
264
|
+
...sendFunctionSource(),
|
|
226
265
|
``,
|
|
227
266
|
`async function main() {`,
|
|
228
267
|
` let namespace;`,
|
|
229
268
|
` try {`,
|
|
230
269
|
` namespace = await import(${lit(configPath)});`,
|
|
231
270
|
` } catch (err) {`,
|
|
232
|
-
` send({ kind: "chant-config", ok: false, error: classifyChildError(${lit(configPath)}, err).toJSON() });`,
|
|
271
|
+
` await send({ kind: "chant-config", ok: false, error: classifyChildError(${lit(configPath)}, err).toJSON() });`,
|
|
233
272
|
` return;`,
|
|
234
273
|
` }`,
|
|
235
274
|
``,
|
|
@@ -240,24 +279,26 @@ export function generateConfigDriverSource(configPath: string): string {
|
|
|
240
279
|
``,
|
|
241
280
|
` const offenders = scanConfigWireSafety(selected);`,
|
|
242
281
|
` if (offenders.length > 0) {`,
|
|
243
|
-
` send({ kind: "chant-config", ok: false, offenders });`,
|
|
282
|
+
` await send({ kind: "chant-config", ok: false, offenders });`,
|
|
244
283
|
` return;`,
|
|
245
284
|
` }`,
|
|
246
285
|
``,
|
|
286
|
+
` let config;`,
|
|
247
287
|
` try {`,
|
|
248
288
|
// Round-trip here, not just at the IPC boundary: this is what proves the
|
|
249
289
|
// payload really is JSON before it leaves the child, and turns anything
|
|
250
290
|
// the scan somehow missed into a named error instead of a quiet drop.
|
|
251
|
-
`
|
|
252
|
-
` send({ kind: "chant-config", ok: true, config });`,
|
|
291
|
+
` config = JSON.parse(JSON.stringify(selected ?? {}));`,
|
|
253
292
|
` } catch (err) {`,
|
|
254
|
-
` send({ kind: "chant-config", ok: false, error: classifyChildError(${lit(configPath)}, err, "resolution").toJSON() });`,
|
|
293
|
+
` await send({ kind: "chant-config", ok: false, error: classifyChildError(${lit(configPath)}, err, "resolution").toJSON() });`,
|
|
294
|
+
` return;`,
|
|
255
295
|
` }`,
|
|
296
|
+
` await send({ kind: "chant-config", ok: true, config });`,
|
|
256
297
|
`}`,
|
|
257
298
|
``,
|
|
258
|
-
`main().catch((err)
|
|
259
|
-
` send({ kind: "chant-config", ok: false, error: classifyChildError(${lit(configPath)}, err).toJSON() })
|
|
260
|
-
`
|
|
299
|
+
`main().catch((err) =>`,
|
|
300
|
+
` send({ kind: "chant-config", ok: false, error: classifyChildError(${lit(configPath)}, err).toJSON() }),`,
|
|
301
|
+
`);`,
|
|
261
302
|
].join("\n");
|
|
262
303
|
}
|
|
263
304
|
|
|
@@ -294,18 +335,15 @@ export function generatePolicyDriverSource(policyPaths: readonly string[]): stri
|
|
|
294
335
|
`import { classifyChildError } from ${lit(CHILD_ERRORS_MODULE)};`,
|
|
295
336
|
`import { decodePolicyBuildResult, scanPolicyDiagnostics, PolicyWireError } from ${lit(POLICY_WIRE_MODULE)};`,
|
|
296
337
|
`import { runPostSynthChecks, isPostSynthCheck } from ${lit(POST_SYNTH_MODULE)};`,
|
|
338
|
+
`import { writeSync } from "node:fs";`,
|
|
297
339
|
``,
|
|
298
|
-
|
|
299
|
-
` if (typeof process.send === "function") process.send(payload);`,
|
|
300
|
-
` else console.log(JSON.stringify(payload));`,
|
|
301
|
-
`}`,
|
|
340
|
+
...sendFunctionSource(),
|
|
302
341
|
``,
|
|
303
342
|
`function fail(file, err, type) {`,
|
|
304
343
|
` if (err instanceof PolicyWireError) {`,
|
|
305
|
-
` send({ kind: "chant-policy", ok: false, offenders: err.offenders });`,
|
|
306
|
-
` return;`,
|
|
344
|
+
` return send({ kind: "chant-policy", ok: false, offenders: err.offenders });`,
|
|
307
345
|
` }`,
|
|
308
|
-
` send({ kind: "chant-policy", ok: false, error: classifyChildError(file, err, type).toJSON() });`,
|
|
346
|
+
` return send({ kind: "chant-policy", ok: false, error: classifyChildError(file, err, type).toJSON() });`,
|
|
309
347
|
`}`,
|
|
310
348
|
``,
|
|
311
349
|
// The wrapper described in the doc above: same id/description so any
|
|
@@ -329,7 +367,7 @@ export function generatePolicyDriverSource(policyPaths: readonly string[]): stri
|
|
|
329
367
|
` try {`,
|
|
330
368
|
` buildResult = decodePolicyBuildResult(request.buildResult);`,
|
|
331
369
|
` } catch (err) {`,
|
|
332
|
-
` fail("", err, "resolution");`,
|
|
370
|
+
` await fail("", err, "resolution");`,
|
|
333
371
|
` return;`,
|
|
334
372
|
` }`,
|
|
335
373
|
``,
|
|
@@ -347,7 +385,7 @@ export function generatePolicyDriverSource(policyPaths: readonly string[]): stri
|
|
|
347
385
|
` if (isPostSynthCheck(value)) checks.push(guard(value, ${lit(policyPath)}));`,
|
|
348
386
|
` }`,
|
|
349
387
|
` } catch (err) {`,
|
|
350
|
-
` fail(${lit(policyPath)}, err, "import");`,
|
|
388
|
+
` await fail(${lit(policyPath)}, err, "import");`,
|
|
351
389
|
` return;`,
|
|
352
390
|
` }`,
|
|
353
391
|
);
|
|
@@ -359,11 +397,11 @@ export function generatePolicyDriverSource(policyPaths: readonly string[]): stri
|
|
|
359
397
|
` try {`,
|
|
360
398
|
` diagnostics = runPostSynthChecks(checks, buildResult, request.env ?? undefined);`,
|
|
361
399
|
` } catch (err) {`,
|
|
362
|
-
` fail("", err, "resolution");`,
|
|
400
|
+
` await fail("", err, "resolution");`,
|
|
363
401
|
` return;`,
|
|
364
402
|
` }`,
|
|
365
403
|
``,
|
|
366
|
-
` send({ kind: "chant-policy", ok: true, diagnostics });`,
|
|
404
|
+
` await send({ kind: "chant-policy", ok: true, diagnostics });`,
|
|
367
405
|
`}`,
|
|
368
406
|
``,
|
|
369
407
|
// Registered synchronously at module top level — see the doc above on why
|