@intentius/chant 0.124.13 → 0.124.14
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/bin/chant +11 -0
- package/dist/agents/checks.js +326 -0
- package/dist/agents/discover.js +885 -0
- package/dist/agents/importer.js +17 -0
- package/dist/agents/index.js +12 -0
- package/dist/agents/types.js +19 -0
- package/dist/apply.js +151 -0
- package/dist/attrref.js +70 -0
- package/dist/audit/catalog.js +350 -0
- package/dist/audit/core.js +252 -0
- package/dist/audit/discover.js +633 -0
- package/dist/audit/fetch.js +666 -0
- package/dist/audit/lineage.js +91 -0
- package/dist/audit/nginx.js +366 -0
- package/dist/audit/prior-art.js +132 -0
- package/dist/audit/proof.js +321 -0
- package/dist/audit/report-html.js +194 -0
- package/dist/audit/report-model.js +198 -0
- package/dist/audit/report.js +102 -0
- package/dist/audit/rules-doc.js +144 -0
- package/dist/audit/secrets.js +405 -0
- package/dist/audit/terraform-state.js +140 -0
- package/dist/audit/wrangler.js +262 -0
- package/dist/behaviour-delta.js +401 -0
- package/dist/behaviour-engine.js +357 -0
- package/dist/behaviour-graph.js +83 -0
- package/dist/behaviour-http.js +188 -0
- package/dist/behaviour-kinds.js +172 -0
- package/dist/behaviour-overlay.js +50 -0
- package/dist/behaviour-predict.js +188 -0
- package/dist/behaviour-request.js +194 -0
- package/dist/behaviour.js +1325 -0
- package/dist/build-params.js +108 -0
- package/dist/build.js +668 -0
- package/dist/builder.js +44 -0
- package/dist/cdk/advise.js +30 -0
- package/dist/cdk/assembly.js +122 -0
- package/dist/cdk/graph.js +444 -0
- package/dist/cdk/tier-map.js +64 -0
- package/dist/cdk/types.js +24 -0
- package/dist/change-set.js +312 -0
- package/dist/child-project.js +21 -0
- package/dist/claimed-fields.js +135 -0
- package/dist/cli/build-options.js +70 -0
- package/dist/cli/build-params-cli.js +139 -0
- package/dist/cli/command-group.js +123 -0
- package/dist/cli/commands/audit-agents.js +326 -0
- package/dist/cli/commands/audit.js +571 -0
- package/dist/cli/commands/build.js +920 -0
- package/dist/cli/commands/carve-apply.js +153 -0
- package/dist/cli/commands/carve-bridge.js +201 -0
- package/dist/cli/commands/carve-emit.js +332 -0
- package/dist/cli/commands/carve-status.js +119 -0
- package/dist/cli/commands/carve.js +204 -0
- package/dist/cli/commands/check-lexicon-docs.js +79 -0
- package/dist/cli/commands/check-lexicon-examples.js +177 -0
- package/dist/cli/commands/check-lexicon-intrinsics.js +291 -0
- package/dist/cli/commands/check-lexicon-mcp.js +82 -0
- package/dist/cli/commands/check-lexicon-plugin.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-plugin.js +104 -0
- package/dist/cli/commands/check-lexicon.js +766 -0
- package/dist/cli/commands/describe.js +85 -0
- package/dist/cli/commands/diff.js +175 -0
- package/dist/cli/commands/doctor.js +350 -0
- package/dist/cli/commands/import-agents.js +155 -0
- package/dist/cli/commands/import.js +670 -0
- package/dist/cli/commands/init-lexicon/templates/codegen.js +194 -0
- package/dist/cli/commands/init-lexicon/templates/docs.js +100 -0
- package/dist/cli/commands/init-lexicon/templates/examples.js +29 -0
- package/dist/cli/commands/init-lexicon/templates/lint.js +34 -0
- package/dist/cli/commands/init-lexicon/templates/lsp.js +37 -0
- package/dist/cli/commands/init-lexicon/templates/plugin.js +108 -0
- package/dist/cli/commands/init-lexicon/templates/project.js +240 -0
- package/dist/cli/commands/init-lexicon/templates/spec.js +56 -0
- package/dist/cli/commands/init-lexicon/templates/tests.js +66 -0
- package/dist/cli/commands/init-lexicon.js +172 -0
- package/dist/cli/commands/init.js +381 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.js +145 -0
- package/dist/cli/commands/lexicon-surface-diff.js +145 -0
- package/dist/cli/commands/licenses.js +125 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +948 -0
- package/dist/cli/commands/list.js +63 -0
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +423 -0
- package/dist/cli/commands/onboard.js +403 -0
- package/dist/cli/commands/pinned-upgrade.js +191 -0
- package/dist/cli/commands/update.js +194 -0
- package/dist/cli/commands/vendor.js +217 -0
- package/dist/cli/conflict-check.js +104 -0
- package/dist/cli/debug.js +8 -0
- package/dist/cli/format.js +104 -0
- package/dist/cli/handlers/build.js +267 -0
- package/dist/cli/handlers/carve-apply.js +30 -0
- package/dist/cli/handlers/carve-bridge.js +28 -0
- package/dist/cli/handlers/carve-emit.js +50 -0
- package/dist/cli/handlers/carve-status.js +26 -0
- package/dist/cli/handlers/carve.js +40 -0
- package/dist/cli/handlers/change-set.js +46 -0
- package/dist/cli/handlers/components.js +730 -0
- package/dist/cli/handlers/dev.js +113 -0
- package/dist/cli/handlers/emulator.js +233 -0
- package/dist/cli/handlers/explain.js +54 -0
- package/dist/cli/handlers/fan-out.js +422 -0
- package/dist/cli/handlers/gate-resume.js +275 -0
- package/dist/cli/handlers/generate.js +84 -0
- package/dist/cli/handlers/graph.js +969 -0
- package/dist/cli/handlers/init.js +102 -0
- package/dist/cli/handlers/lifecycle.js +1727 -0
- package/dist/cli/handlers/lint.js +62 -0
- package/dist/cli/handlers/migrate.js +48 -0
- package/dist/cli/handlers/misc.js +391 -0
- package/dist/cli/handlers/operator.js +1162 -0
- package/dist/cli/handlers/override-approve.js +102 -0
- package/dist/cli/handlers/pr.js +503 -0
- package/dist/cli/handlers/promote.js +342 -0
- package/dist/cli/handlers/run-generate.js +206 -0
- package/dist/cli/handlers/run-wave.js +66 -0
- package/dist/cli/handlers/run.js +1191 -0
- package/dist/cli/handlers/scenario.js +325 -0
- package/dist/cli/handlers/search.js +924 -0
- package/dist/cli/handlers/serve.js +32 -0
- package/dist/cli/handlers/vendor.js +154 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/is-entry-point.js +23 -0
- package/dist/cli/lsp/capabilities.js +28 -0
- package/dist/cli/lsp/diagnostics.js +34 -0
- package/dist/cli/lsp/server.js +329 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +2540 -0
- package/dist/cli/mcp/lifecycle-tools.js +80 -0
- package/dist/cli/mcp/op-tools.js +306 -0
- package/dist/cli/mcp/resource-handlers.js +258 -0
- package/dist/cli/mcp/resources/context.js +85 -0
- package/dist/cli/mcp/server.js +353 -0
- package/dist/cli/mcp/tools/build.js +111 -0
- package/dist/cli/mcp/tools/composites.js +95 -0
- package/dist/cli/mcp/tools/explain.js +166 -0
- package/dist/cli/mcp/tools/import.js +49 -0
- package/dist/cli/mcp/tools/lint.js +41 -0
- package/dist/cli/mcp/tools/scaffold.js +111 -0
- package/dist/cli/mcp/tools/search.js +112 -0
- package/dist/cli/mcp/types.js +1 -0
- package/dist/cli/mcp/workspace-plugins.js +91 -0
- package/dist/cli/mcp/workspace-tools.d.ts +1 -1
- package/dist/cli/mcp/workspace-tools.js +564 -0
- package/dist/cli/mcp-config.js +70 -0
- package/dist/cli/plugins.js +313 -0
- package/dist/cli/registry.js +23 -0
- package/dist/cli/reporters/stylish.js +329 -0
- package/dist/cli/version.js +15 -0
- package/dist/cli/watch.js +79 -0
- package/dist/codegen/bound-property-types.js +82 -0
- package/dist/codegen/coverage.js +119 -0
- package/dist/codegen/docs-file-markers.js +60 -0
- package/dist/codegen/docs-pages.js +115 -0
- package/dist/codegen/docs-rule-scanning.js +164 -0
- package/dist/codegen/docs-rules.js +76 -0
- package/dist/codegen/docs-sections.js +117 -0
- package/dist/codegen/docs-sidebar.js +65 -0
- package/dist/codegen/docs-types.js +4 -0
- package/dist/codegen/docs.js +356 -0
- package/dist/codegen/fetch.js +340 -0
- package/dist/codegen/generate-post-synth-barrel.js +63 -0
- package/dist/codegen/generate-registry.js +71 -0
- package/dist/codegen/generate-runtime-index.js +56 -0
- package/dist/codegen/generate-typescript.js +119 -0
- package/dist/codegen/generate.js +115 -0
- package/dist/codegen/json-patch.js +141 -0
- package/dist/codegen/json-schema-to-ts.js +344 -0
- package/dist/codegen/json-schema.js +246 -0
- package/dist/codegen/lexicon-regen.js +412 -0
- package/dist/codegen/naming.js +217 -0
- package/dist/codegen/okf-lexicon.js +245 -0
- package/dist/codegen/package.js +150 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.js +494 -0
- package/dist/codegen/registry.js +60 -0
- package/dist/codegen/rehype-base-url.mjs +68 -0
- package/dist/codegen/rolling-upgrade.js +217 -0
- package/dist/codegen/surface-snapshot.js +537 -0
- package/dist/codegen/testdata/postgres-tags.json +242 -0
- package/dist/codegen/topo-sort.js +36 -0
- package/dist/codegen/typecheck.js +115 -0
- package/dist/codegen/validate.js +200 -0
- package/dist/codegen/version-bump.js +35 -0
- package/dist/components/auto-release.js +143 -0
- package/dist/components/builders.js +47 -0
- package/dist/components/capability-plugin-loader.js +175 -0
- package/dist/components/capability-plugin-schema.js +46 -0
- package/dist/components/capability-plugin.js +99 -0
- package/dist/components/capability.js +60 -0
- package/dist/components/changed-files.js +72 -0
- package/dist/components/cli-support.js +427 -0
- package/dist/components/component.js +120 -0
- package/dist/components/component.schema.json +271 -0
- package/dist/components/config-defaults.js +130 -0
- package/dist/components/deploy-units.js +60 -0
- package/dist/components/discover.d.ts.map +1 -1
- package/dist/components/discover.js +189 -0
- package/dist/components/driver-output.js +86 -0
- package/dist/components/driver.js +728 -0
- package/dist/components/fan-out-output.js +165 -0
- package/dist/components/fan-out-record.js +94 -0
- package/dist/components/fan-out-run.js +373 -0
- package/dist/components/fan-out-support.js +60 -0
- package/dist/components/fan-out.js +273 -0
- package/dist/components/gate-plan.js +41 -0
- package/dist/components/gated-wave-pipeline.js +46 -0
- package/dist/components/index.js +24 -0
- package/dist/components/layers.js +28 -0
- package/dist/components/manifest-persistence.js +108 -0
- package/dist/components/pilots/alb-ecs.pilot.js +59 -0
- package/dist/components/pilots/dynamodb.pilot.js +51 -0
- package/dist/components/pilots/jar-emr.pilot.js +65 -0
- package/dist/components/pilots/lambda.pilot.js +52 -0
- package/dist/components/pilots/neo4j-fanout.pilot.js +68 -0
- package/dist/components/pilots/project.js +12 -0
- package/dist/components/pr-pipeline.js +134 -0
- package/dist/components/pr-run.js +363 -0
- package/dist/components/presets/ecs-fargate.js +72 -0
- package/dist/components/presets/index.js +28 -0
- package/dist/components/presets/lambda.js +34 -0
- package/dist/components/presets/single-host-compose.js +41 -0
- package/dist/components/promote.js +549 -0
- package/dist/components/registry.js +34 -0
- package/dist/components/run-progress.js +33 -0
- package/dist/components/sandbox/driver.d.ts.map +1 -1
- package/dist/components/sandbox/driver.js +93 -0
- package/dist/components/sandbox/run.js +115 -0
- package/dist/components/starter-plugin.js +104 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.js +68 -0
- package/dist/components/verbs/__tests__/mock-process-runner.js +45 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.js +56 -0
- package/dist/components/verbs/bom-writer.js +287 -0
- package/dist/components/verbs/build-archive.js +188 -0
- package/dist/components/verbs/build.js +142 -0
- package/dist/components/verbs/cloud-executor.js +110 -0
- package/dist/components/verbs/component-bom.js +125 -0
- package/dist/components/verbs/ensure-secret.js +50 -0
- package/dist/components/verbs/index.js +61 -0
- package/dist/components/verbs/license-policy.js +75 -0
- package/dist/components/verbs/lockfile-sbom-generator.js +191 -0
- package/dist/components/verbs/process-runner.js +78 -0
- package/dist/components/verbs/r2-sync.js +93 -0
- package/dist/components/verbs/reproducibility.js +62 -0
- package/dist/components/verbs/run-agent.js +577 -0
- package/dist/components/verbs/sbom-generator.js +119 -0
- package/dist/components/verbs/sbom.js +97 -0
- package/dist/components/verbs/shell.js +32 -0
- package/dist/components/verbs/sign.js +221 -0
- package/dist/components/verbs/stub.js +28 -0
- package/dist/components/verbs/tool-sbom-generator.js +154 -0
- package/dist/components/verbs/verify.js +112 -0
- package/dist/components/verbs/vex.js +131 -0
- package/dist/components/verbs/vuln-gate.js +152 -0
- package/dist/components/verbs/vuln-scan.js +288 -0
- package/dist/components/verbs/wait-verify.js +106 -0
- package/dist/components/verbs/wrangler.js +179 -0
- package/dist/components/wave-plan.js +102 -0
- package/dist/composite.js +305 -0
- package/dist/config-import.d.ts.map +1 -1
- package/dist/config-import.js +22 -0
- package/dist/config-sandbox.js +122 -0
- package/dist/config-static.js +206 -0
- package/dist/config.js +605 -0
- package/dist/content-digest.js +23 -0
- package/dist/declarable.js +114 -0
- package/dist/deep-observation.js +437 -0
- package/dist/detectLexicon.js +54 -0
- package/dist/discovery/cache.js +70 -0
- package/dist/discovery/collect.js +208 -0
- package/dist/discovery/cycles.js +95 -0
- package/dist/discovery/entity-wire-codec.js +391 -0
- package/dist/discovery/entity-wire.js +42 -0
- package/dist/discovery/files.js +121 -0
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-import.js +4178 -0
- package/dist/discovery/fold-rank.js +292 -0
- package/dist/discovery/graph.js +115 -0
- package/dist/discovery/import.d.ts.map +1 -1
- package/dist/discovery/import.js +65 -0
- package/dist/discovery/index.js +333 -0
- package/dist/discovery/param-deps.js +487 -0
- package/dist/discovery/resolve.js +39 -0
- package/dist/discovery/sandbox/bundle.js +214 -0
- package/dist/discovery/sandbox/child-errors.js +26 -0
- package/dist/discovery/sandbox/config-run.js +100 -0
- package/dist/discovery/sandbox/config-wire.js +183 -0
- package/dist/discovery/sandbox/driver.d.ts.map +1 -1
- package/dist/discovery/sandbox/driver.js +333 -0
- package/dist/discovery/sandbox/fork.js +229 -0
- package/dist/discovery/sandbox/policy-run.js +142 -0
- package/dist/discovery/sandbox/policy-wire.js +152 -0
- package/dist/discovery/sandbox/run.js +77 -0
- package/dist/discovery/specifier-resolve.js +320 -0
- package/dist/discovery/walk.js +284 -0
- package/dist/effect-receipt.js +340 -0
- package/dist/env.js +55 -0
- package/dist/errors.js +62 -0
- package/dist/fold/fold.js +1434 -0
- package/dist/fold/foldable-helpers.js +229 -0
- package/dist/fold/subset.js +696 -0
- package/dist/fold-provenance.js +414 -0
- package/dist/gate-decision.js +260 -0
- package/dist/gate-resume-run.js +154 -0
- package/dist/gated-waves.js +165 -0
- package/dist/governance.js +43 -0
- package/dist/graph-declared.js +45 -0
- package/dist/graph-detail.js +207 -0
- package/dist/graph-dot.js +54 -0
- package/dist/graph-effective.js +107 -0
- package/dist/graph-ir.js +623 -0
- package/dist/graph-layout.js +184 -0
- package/dist/graph-lens.js +105 -0
- package/dist/graph-mermaid.js +83 -0
- package/dist/graph-ops.js +39 -0
- package/dist/graph-refs.js +156 -0
- package/dist/held-elsewhere.js +87 -0
- package/dist/identity.js +251 -0
- package/dist/import/base-parser.js +34 -0
- package/dist/import/embedded.js +255 -0
- package/dist/import/generator.js +1 -0
- package/dist/import/ir-utils.js +85 -0
- package/dist/import/parser-options.js +45 -0
- package/dist/import/parser.js +1 -0
- package/dist/index.js +118 -0
- package/dist/intrinsic-interpolation.js +73 -0
- package/dist/intrinsic.js +31 -0
- package/dist/join-key.js +35 -0
- package/dist/kubectl-context.js +150 -0
- package/dist/lexicon-config.js +58 -0
- package/dist/lexicon-integrity.js +47 -0
- package/dist/lexicon-manifest.js +70 -0
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lexicon-module.js +241 -0
- package/dist/lexicon-output.js +218 -0
- package/dist/lexicon-plugin-helpers.js +104 -0
- package/dist/lexicon-schema.js +136 -0
- package/dist/lexicon.js +130 -0
- package/dist/lifecycle/affected.js +224 -0
- package/dist/lifecycle/assert-live.js +110 -0
- package/dist/lifecycle/build-ledger-store.js +160 -0
- package/dist/lifecycle/build-ledger.js +155 -0
- package/dist/lifecycle/change-set.js +356 -0
- package/dist/lifecycle/converge-ledger.js +161 -0
- package/dist/lifecycle/deep-diff.js +233 -0
- package/dist/lifecycle/deep-observe.js +147 -0
- package/dist/lifecycle/digest.js +143 -0
- package/dist/lifecycle/disruption.js +135 -0
- package/dist/lifecycle/gate-applied.js +113 -0
- package/dist/lifecycle/gate-audit.js +341 -0
- package/dist/lifecycle/gate-ledger-select.js +89 -0
- package/dist/lifecycle/gate-ledger.js +193 -0
- package/dist/lifecycle/gate-origin.js +117 -0
- package/dist/lifecycle/gate-pending.js +58 -0
- package/dist/lifecycle/git.js +1182 -0
- package/dist/lifecycle/identity.js +58 -0
- package/dist/lifecycle/index.js +26 -0
- package/dist/lifecycle/lease.js +283 -0
- package/dist/lifecycle/ledger-port.js +1 -0
- package/dist/lifecycle/legacy-digest.js +91 -0
- package/dist/lifecycle/live-diff.js +274 -0
- package/dist/lifecycle/local-note.js +15 -0
- package/dist/lifecycle/member-ledger.js +122 -0
- package/dist/lifecycle/observation-baseline.js +155 -0
- package/dist/lifecycle/observe.js +375 -0
- package/dist/lifecycle/oras-referrer-lookup.js +82 -0
- package/dist/lifecycle/override-ledger.js +54 -0
- package/dist/lifecycle/plan-digest.js +110 -0
- package/dist/lifecycle/plan-ledger.js +129 -0
- package/dist/lifecycle/receipt-plan.js +192 -0
- package/dist/lifecycle/release-ledger.js +155 -0
- package/dist/lifecycle/release-read.js +64 -0
- package/dist/lifecycle/replay.js +193 -0
- package/dist/lifecycle/rollback.js +102 -0
- package/dist/lifecycle/run-ledger.js +183 -0
- package/dist/lifecycle/scenario-eval.js +204 -0
- package/dist/lifecycle/scenario.js +214 -0
- package/dist/lifecycle/snapshot.js +239 -0
- package/dist/lifecycle/status.js +447 -0
- package/dist/lifecycle/symptoms.js +117 -0
- package/dist/lifecycle/teardown.js +255 -0
- package/dist/lifecycle/types.js +1 -0
- package/dist/lifecycle/unobserved-gate.js +33 -0
- package/dist/lifecycle/wave-plans.js +68 -0
- package/dist/lifecycle/work-item-id.js +36 -0
- package/dist/lifecycle/work-lease.js +393 -0
- package/dist/lint/component-checks.js +87 -0
- package/dist/lint/config.js +483 -0
- package/dist/lint/declarative.js +122 -0
- package/dist/lint/discover.d.ts.map +1 -1
- package/dist/lint/discover.js +138 -0
- package/dist/lint/engine.js +246 -0
- package/dist/lint/knowledge-checks.js +64 -0
- package/dist/lint/named-checks.js +22 -0
- package/dist/lint/output-checks.js +87 -0
- package/dist/lint/output-docs.js +163 -0
- package/dist/lint/parser.js +33 -0
- package/dist/lint/pipeline-change-gate.js +70 -0
- package/dist/lint/policy-import.d.ts +1 -1
- package/dist/lint/policy-import.d.ts.map +1 -1
- package/dist/lint/policy-import.js +62 -0
- package/dist/lint/policy-sandbox.js +86 -0
- package/dist/lint/policy.js +122 -0
- package/dist/lint/post-synth.js +87 -0
- package/dist/lint/presets/relaxed.json +26 -0
- package/dist/lint/presets/strict.json +24 -24
- package/dist/lint/receipt-checks.js +83 -0
- package/dist/lint/rule-loader.d.ts.map +1 -1
- package/dist/lint/rule-loader.js +89 -0
- package/dist/lint/rule-registry.js +86 -0
- package/dist/lint/rule.js +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.js +7 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.js +9 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.js +25 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.js +21 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.js +24 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.js +17 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.js +18 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.js +20 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.js +16 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.js +8 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.js +12 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.js +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.js +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.js +16 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.js +69 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.js +84 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.js +103 -0
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.js +70 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.js +109 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.js +49 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.js +64 -0
- package/dist/lint/rules/comp/index.js +33 -0
- package/dist/lint/rules/comp/support.js +129 -0
- package/dist/lint/rules/composite-scope.js +51 -0
- package/dist/lint/rules/cor017-composite-name-match.js +93 -0
- package/dist/lint/rules/cor018-composite-prefer-lexicon-type.js +136 -0
- package/dist/lint/rules/cor021-env-literal-name.js +100 -0
- package/dist/lint/rules/cor022-receipt-leaf.js +118 -0
- package/dist/lint/rules/cor024-receipt-secret-pointer.js +199 -0
- package/dist/lint/rules/declarable-naming-convention.js +62 -0
- package/dist/lint/rules/evl001-non-literal-expression.js +66 -0
- package/dist/lint/rules/evl002-control-flow-resource.js +69 -0
- package/dist/lint/rules/evl003-dynamic-property-access.js +44 -0
- package/dist/lint/rules/evl004-spread-non-const.js +94 -0
- package/dist/lint/rules/evl005-resource-block-body.js +41 -0
- package/dist/lint/rules/evl007-invalid-siblings.js +105 -0
- package/dist/lint/rules/evl009-composite-no-constant.js +158 -0
- package/dist/lint/rules/evl010-composite-no-transform.js +59 -0
- package/dist/lint/rules/evl011-symbolic-in-template.js +106 -0
- package/dist/lint/rules/export-required.js +115 -0
- package/dist/lint/rules/file-declarable-limit.js +88 -0
- package/dist/lint/rules/flat-declarations.js +62 -0
- package/dist/lint/rules/index.js +90 -0
- package/dist/lint/rules/no-cyclic-declarable-ref.js +138 -0
- package/dist/lint/rules/no-redundant-type-import.js +76 -0
- package/dist/lint/rules/no-redundant-value-cast.js +41 -0
- package/dist/lint/rules/no-string-ref.js +59 -0
- package/dist/lint/rules/no-unused-declarable-import.js +75 -0
- package/dist/lint/rules/no-unused-declarable.js +142 -0
- package/dist/lint/rules/op/index.js +28 -0
- package/dist/lint/rules/op/ops012-activity-contract.js +54 -0
- package/dist/lint/rules/op/ops013-step-output-ref.js +88 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.js +114 -0
- package/dist/lint/rules/op/ops015-gate-approval.js +45 -0
- package/dist/lint/rules/op/support.js +11 -0
- package/dist/lint/rules/op/sys010-key-over-plain-http.js +100 -0
- package/dist/lint/rules/property-kind.js +56 -0
- package/dist/lint/rules/single-concern-file.js +71 -0
- package/dist/lint/rules/sys001-no-literal-key.js +60 -0
- package/dist/lint/selectors.js +168 -0
- package/dist/lint/suppressions.js +129 -0
- package/dist/lint/typescript.js +17 -0
- package/dist/live-endpoint.js +113 -0
- package/dist/live-read-session.js +76 -0
- package/dist/lsp/lexicon-providers.js +163 -0
- package/dist/lsp/types.js +5 -0
- package/dist/managed-fields.js +293 -0
- package/dist/mcp/types.js +4 -0
- package/dist/notify-verify.js +0 -1
- package/dist/notify.js +0 -1
- package/dist/notify.schema.json +72 -0
- package/dist/observation.js +266 -0
- package/dist/okf-read.js +134 -0
- package/dist/okf.js +275 -0
- package/dist/op/__fixtures__/decide-stub-backend.js +125 -0
- package/dist/op/activities/activity-contracts.js +313 -0
- package/dist/op/activities/apply.js +582 -0
- package/dist/op/activities/build.js +18 -0
- package/dist/op/activities/change-coverage.js +40 -0
- package/dist/op/activities/change-set.js +64 -0
- package/dist/op/activities/converge.js +492 -0
- package/dist/op/activities/decide.js +211 -0
- package/dist/op/activities/env-teardown.js +110 -0
- package/dist/op/activities/factory.js +591 -0
- package/dist/op/activities/forge-pull-request.js +82 -0
- package/dist/op/activities/gh-host.js +78 -0
- package/dist/op/activities/guard-validate.js +165 -0
- package/dist/op/activities/http-check.js +40 -0
- package/dist/op/activities/index.js +59 -0
- package/dist/op/activities/lexicon-upgrade.js +629 -0
- package/dist/op/activities/lifecycle.js +109 -0
- package/dist/op/activities/pipeline-audit.js +147 -0
- package/dist/op/activities/policy.js +26 -0
- package/dist/op/activities/predict-behaviour.js +341 -0
- package/dist/op/activities/propose-upgrade.js +165 -0
- package/dist/op/activities/reconcile.js +997 -0
- package/dist/op/activities/shell.js +118 -0
- package/dist/op/activities/source-release.js +97 -0
- package/dist/op/activities/source-rollback.js +165 -0
- package/dist/op/activities/teardown.js +17 -0
- package/dist/op/activities/util.js +6 -0
- package/dist/op/activities/wait.js +51 -0
- package/dist/op/activities/work-evidence.js +35 -0
- package/dist/op/activities/workflow-audit.js +133 -0
- package/dist/op/activity-contract-registry.js +106 -0
- package/dist/op/activity-contract.js +232 -0
- package/dist/op/activity-failure.js +31 -0
- package/dist/op/activity-profiles.js +129 -0
- package/dist/op/activity-registry.js +105 -0
- package/dist/op/activity-runtime.js +28 -0
- package/dist/op/builders.js +801 -0
- package/dist/op/change-signal.js +118 -0
- package/dist/op/composites/apply-op.js +151 -0
- package/dist/op/composites/behaviour-op.js +65 -0
- package/dist/op/composites/converge-op.js +141 -0
- package/dist/op/composites/index.js +19 -0
- package/dist/op/composites/lexicon-upgrade-op.js +107 -0
- package/dist/op/composites/pipeline-audit-op.js +50 -0
- package/dist/op/composites/reconcile-op.js +84 -0
- package/dist/op/composites/watch-op.js +69 -0
- package/dist/op/composites/workflow-audit-op.js +57 -0
- package/dist/op/converge-rule.js +205 -0
- package/dist/op/cron.js +146 -0
- package/dist/op/decide-backend.js +181 -0
- package/dist/op/decide-config.js +68 -0
- package/dist/op/decide-read-inputs.js +141 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/discover.js +213 -0
- package/dist/op/duration.js +21 -0
- package/dist/op/emulator-freshness.js +80 -0
- package/dist/op/emulator-lifecycle.js +269 -0
- package/dist/op/factory.js +83 -0
- package/dist/op/gate-approval.js +172 -0
- package/dist/op/gate-name.js +86 -0
- package/dist/op/gate-plan-context.js +167 -0
- package/dist/op/gate-point-run.js +67 -0
- package/dist/op/gate-point.js +111 -0
- package/dist/op/gate-resume-plan.js +155 -0
- package/dist/op/gate-resume.js +31 -0
- package/dist/op/gate-review.js +290 -0
- package/dist/op/gate-run-locator.js +85 -0
- package/dist/op/gate-summary.js +100 -0
- package/dist/op/gate-wait.js +56 -0
- package/dist/op/gate.js +449 -0
- package/dist/op/generate-pipeline.js +124 -0
- package/dist/op/index.js +51 -0
- package/dist/op/lifecycle-receipt-store.js +45 -0
- package/dist/op/local-executor.js +1164 -0
- package/dist/op/local-output.js +140 -0
- package/dist/op/op-ir.js +317 -0
- package/dist/op/op-verb-class.js +131 -0
- package/dist/op/op-waves-notify.js +136 -0
- package/dist/op/op-waves-run.js +1657 -0
- package/dist/op/op-waves.js +409 -0
- package/dist/op/operator.js +743 -0
- package/dist/op/receipt-store.js +94 -0
- package/dist/op/resource.js +23 -0
- package/dist/op/run-context.js +28 -0
- package/dist/op/run-live.js +256 -0
- package/dist/op/runtime.js +21 -0
- package/dist/op/runtimes/local.js +195 -0
- package/dist/op/source-archive.js +131 -0
- package/dist/op/step-output-ref.js +397 -0
- package/dist/op/steward-beside.js +169 -0
- package/dist/op/steward-points.js +138 -0
- package/dist/op/steward-turn.js +59 -0
- package/dist/op/steward.js +317 -0
- package/dist/op/types.js +25 -0
- package/dist/op/work-lease-decl.js +81 -0
- package/dist/op/work-lease-run.js +393 -0
- package/dist/override-gate.js +284 -0
- package/dist/owner-chain.js +74 -0
- package/dist/ownership.js +92 -0
- package/dist/params.js +61 -0
- package/dist/plan-summary.js +711 -0
- package/dist/point-decision.js +211 -0
- package/dist/pr-forge.js +810 -0
- package/dist/pr-loop.js +203 -0
- package/dist/project-codegen.js +191 -0
- package/dist/project-root.js +74 -0
- package/dist/project-validation.js +50 -0
- package/dist/provenance.js +157 -0
- package/dist/pseudo-parameter.js +40 -0
- package/dist/reconcile.js +450 -0
- package/dist/resource-attributes.js +33 -0
- package/dist/runtime-adapter.js +77 -0
- package/dist/runtime.js +66 -0
- package/dist/secret-materialization.js +153 -0
- package/dist/secret-provenance.js +250 -0
- package/dist/serializer-walker.js +112 -0
- package/dist/serializer.js +1 -0
- package/dist/sort.js +45 -0
- package/dist/stack-output.js +115 -0
- package/dist/telemetry-attribution.js +149 -0
- package/dist/terraform/__fixtures__/build-graph.js +63 -0
- package/dist/terraform/adopt-state.js +40 -0
- package/dist/terraform/aws-resources.js +384 -0
- package/dist/terraform/bridge.js +204 -0
- package/dist/terraform/carve-provider.js +155 -0
- package/dist/terraform/carve.js +138 -0
- package/dist/terraform/data-source-shape.js +57 -0
- package/dist/terraform/emit-source.js +36 -0
- package/dist/terraform/excise.js +123 -0
- package/dist/terraform/graduate.js +128 -0
- package/dist/terraform/graph.js +435 -0
- package/dist/terraform/hcl2json.js +60 -0
- package/dist/terraform/manifest.js +149 -0
- package/dist/terraform/parse.js +81 -0
- package/dist/terraform/providers/aws.js +146 -0
- package/dist/terraform/providers/gcp.js +294 -0
- package/dist/terraform/providers/index.js +17 -0
- package/dist/terraform/providers/kubernetes.js +253 -0
- package/dist/terraform/score.js +151 -0
- package/dist/terraform/state.js +67 -0
- package/dist/terraform/tier-map.js +74 -0
- package/dist/terraform/types.js +13 -0
- package/dist/terraform/unified-diff.js +132 -0
- package/dist/testing.js +295 -0
- package/dist/toml-emit.js +153 -0
- package/dist/toml-parse.js +355 -0
- package/dist/toml-utils.js +60 -0
- package/dist/toml.js +428 -0
- package/dist/ts-loader.d.ts +46 -0
- package/dist/ts-loader.d.ts.map +1 -0
- package/dist/ts-loader.js +103 -0
- package/dist/types.js +1 -0
- package/dist/utils.js +61 -0
- package/dist/validation.js +20 -0
- package/dist/vendor/js-yaml-load.js +1662 -0
- package/dist/workspace/__fixtures__/contract-repo.js +103 -0
- package/dist/workspace/__fixtures__/decide-workspace.js +112 -0
- package/dist/workspace/__fixtures__/sessions.js +91 -0
- package/dist/workspace/__fixtures__/two-member-workspace.js +34 -0
- package/dist/workspace/agent-cli.js +99 -0
- package/dist/workspace/agent.schema.json +390 -0
- package/dist/workspace/answers-ledger.js +89 -0
- package/dist/workspace/box-cli.js +142 -0
- package/dist/workspace/box-factory-write.js +196 -0
- package/dist/workspace/box-factory-write.schema.json +342 -0
- package/dist/workspace/box-factory.js +88 -0
- package/dist/workspace/box-intent.js +126 -0
- package/dist/workspace/box-isolation.js +169 -0
- package/dist/workspace/box-listing-write.schema.json +204 -0
- package/dist/workspace/box-listing.js +298 -0
- package/dist/workspace/box-publish.js +352 -0
- package/dist/workspace/box-publish.schema.json +498 -0
- package/dist/workspace/box-services.js +39 -0
- package/dist/workspace/broker-protocol.js +359 -0
- package/dist/workspace/broker-protocol.schema.json +228 -0
- package/dist/workspace/change-set.schema.json +460 -0
- package/dist/workspace/changes-cli.js +56 -0
- package/dist/workspace/changes.js +446 -0
- package/dist/workspace/changes.schema.json +642 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.js +198 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.js +155 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.js +214 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.js +180 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.js +99 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.js +847 -0
- package/dist/workspace/chant-migrations.js +113 -0
- package/dist/workspace/check.schema.json +433 -0
- package/dist/workspace/checks/box-isolation.js +62 -0
- package/dist/workspace/checks/boxes.js +491 -0
- package/dist/workspace/checks/diagrams.js +104 -0
- package/dist/workspace/checks/generated.js +419 -0
- package/dist/workspace/checks/ledgers.js +212 -0
- package/dist/workspace/checks/links.js +191 -0
- package/dist/workspace/checks/live.js +100 -0
- package/dist/workspace/checks/pipelines.js +188 -0
- package/dist/workspace/checks/records.js +169 -0
- package/dist/workspace/checks.js +426 -0
- package/dist/workspace/ci-green-cli.js +125 -0
- package/dist/workspace/ci-green-forge.js +83 -0
- package/dist/workspace/ci-green-workflow.js +199 -0
- package/dist/workspace/ci-green.js +325 -0
- package/dist/workspace/ci-last-green.schema.json +158 -0
- package/dist/workspace/compose-graph.js +235 -0
- package/dist/workspace/compose-reports.js +146 -0
- package/dist/workspace/composites.js +264 -0
- package/dist/workspace/composites.schema.json +617 -0
- package/dist/workspace/conformance/__fixture__/app/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/app/src/server.mjs +29 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.kind.mjs +54 -0
- package/dist/workspace/conformance/__fixture__/decisions/decision.schema.json +512 -0
- package/dist/workspace/conformance/__fixture__/decisions/fix-001-how-the-app-is-deployed.md +40 -0
- package/dist/workspace/conformance/__fixture__/delivery/chant.config.ts +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/lexicon/index.ts +26 -0
- package/dist/workspace/conformance/__fixture__/delivery/package.json +7 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.component.ts +14 -0
- package/dist/workspace/conformance/__fixture__/delivery/src/app.ts +4 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.js +205 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/dist/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/dist/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/dist/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/dist/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/dist/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
- package/dist/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/dist/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
- package/dist/workspace/conformance/broker.js +736 -0
- package/dist/workspace/conformance/index.js +673 -0
- package/dist/workspace/conformance/vitest.js +108 -0
- package/dist/workspace/conformance/writer.js +1080 -0
- package/dist/workspace/decide.js +879 -0
- package/dist/workspace/decision-points.schema.json +135 -135
- package/dist/workspace/declaration-write-cli.js +74 -0
- package/dist/workspace/declaration-write.js +238 -0
- package/dist/workspace/declaration.js +938 -0
- package/dist/workspace/declaration.schema.json +1413 -1413
- package/dist/workspace/declared-kinds.js +106 -0
- package/dist/workspace/environments.js +164 -0
- package/dist/workspace/evidence.schema.json +279 -0
- package/dist/workspace/export-cli.js +185 -0
- package/dist/workspace/export.js +499 -0
- package/dist/workspace/factory-rules.js +175 -0
- package/dist/workspace/generated-files.js +92 -0
- package/dist/workspace/glob.js +45 -0
- package/dist/workspace/graph-cache.js +352 -0
- package/dist/workspace/graph-cli.js +348 -0
- package/dist/workspace/graph.schema.json +1338 -0
- package/dist/workspace/identity-gate-rule.js +75 -0
- package/dist/workspace/identity.js +126 -0
- package/dist/workspace/import.js +283 -0
- package/dist/workspace/init.js +620 -0
- package/dist/workspace/intent-cli.js +263 -0
- package/dist/workspace/intent-joins.js +201 -0
- package/dist/workspace/intent-record.js +352 -0
- package/dist/workspace/intent-record.schema.json +864 -0
- package/dist/workspace/intent.js +1582 -0
- package/dist/workspace/intent.schema.json +2420 -0
- package/dist/workspace/json-edit.js +221 -0
- package/dist/workspace/jsonc.js +235 -0
- package/dist/workspace/kind-readers.js +103 -0
- package/dist/workspace/kinds.js +587 -0
- package/dist/workspace/lexicon-symbols.js +112 -0
- package/dist/workspace/lineage-adopt-cli.js +102 -0
- package/dist/workspace/lineage-adopt.js +360 -0
- package/dist/workspace/lineage-check.js +282 -0
- package/dist/workspace/lineage-cli.js +121 -0
- package/dist/workspace/lineage-hash-index.js +284 -0
- package/dist/workspace/lineage-init.js +507 -0
- package/dist/workspace/lineage-lock.js +387 -0
- package/dist/workspace/lineage-merge.js +45 -0
- package/dist/workspace/lineage-migrations.d.ts.map +1 -1
- package/dist/workspace/lineage-migrations.js +329 -0
- package/dist/workspace/lineage-provenance.js +36 -0
- package/dist/workspace/lineage-update.js +138 -0
- package/dist/workspace/lineage-upgrade-cli.js +131 -0
- package/dist/workspace/lineage-upgrade.js +889 -0
- package/dist/workspace/lineage-vendor.js +171 -0
- package/dist/workspace/lineage-version.js +128 -0
- package/dist/workspace/lineage-versions.js +275 -0
- package/dist/workspace/links.js +330 -0
- package/dist/workspace/ls-generated.js +95 -0
- package/dist/workspace/ls.js +277 -0
- package/dist/workspace/ls.schema.json +333 -0
- package/dist/workspace/member-commands.js +508 -0
- package/dist/workspace/member-handles.js +216 -0
- package/dist/workspace/member-pipeline.js +258 -0
- package/dist/workspace/member-run.js +117 -0
- package/dist/workspace/member-write.schema.json +193 -0
- package/dist/workspace/nested-graph.js +156 -0
- package/dist/workspace/nesting.js +38 -0
- package/dist/workspace/patch.js +301 -0
- package/dist/workspace/patch.schema.json +321 -0
- package/dist/workspace/pin-cli.js +55 -0
- package/dist/workspace/pin-integrity.js +100 -0
- package/dist/workspace/plan-summary.schema.json +155 -0
- package/dist/workspace/point-answer.schema.json +129 -129
- package/dist/workspace/points-cli.js +291 -0
- package/dist/workspace/points-write.schema.json +660 -0
- package/dist/workspace/points.js +521 -0
- package/dist/workspace/points.schema.json +916 -0
- package/dist/workspace/pr-report.schema.json +108 -0
- package/dist/workspace/principal-classes.js +245 -0
- package/dist/workspace/reason-codes.js +326 -0
- package/dist/workspace/record-assets.js +151 -0
- package/dist/workspace/record-decided.js +105 -0
- package/dist/workspace/record-sessions.js +96 -0
- package/dist/workspace/record-source.js +114 -0
- package/dist/workspace/records-amend.schema.json +284 -0
- package/dist/workspace/records-checkout.js +76 -0
- package/dist/workspace/records-cli.js +707 -0
- package/dist/workspace/records-close.js +116 -0
- package/dist/workspace/records-close.schema.json +278 -0
- package/dist/workspace/records-new.schema.json +202 -0
- package/dist/workspace/records-review.schema.json +367 -0
- package/dist/workspace/records-since.js +317 -0
- package/dist/workspace/records-since.schema.json +218 -0
- package/dist/workspace/records-write.js +1229 -0
- package/dist/workspace/records.js +1345 -0
- package/dist/workspace/records.schema.json +604 -0
- package/dist/workspace/reference-kinds/app/package.json +10 -0
- package/dist/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/dist/workspace/returns.js +303 -0
- package/dist/workspace/root-refusal.js +75 -0
- package/dist/workspace/run-statement.schema.json +622 -0
- package/dist/workspace/runs-cli.js +584 -0
- package/dist/workspace/runs-write.schema.json +994 -0
- package/dist/workspace/runs.js +708 -0
- package/dist/workspace/runs.schema.json +1257 -0
- package/dist/workspace/runtimes.js +76 -0
- package/dist/workspace/session-kinds.js +83 -0
- package/dist/workspace/signers.schema.json +206 -0
- package/dist/workspace/source-block.js +125 -0
- package/dist/workspace/squash.js +177 -0
- package/dist/workspace/status-gates.js +162 -0
- package/dist/workspace/status-stewards.js +330 -0
- package/dist/workspace/status.js +514 -0
- package/dist/workspace/status.schema.json +998 -0
- package/dist/workspace/steward-index.js +191 -0
- package/dist/workspace/symbols.js +188 -0
- package/dist/workspace/template-manifest.js +227 -0
- package/dist/workspace/template-pins.js +115 -0
- package/dist/workspace/trailer-joins.js +65 -0
- package/dist/workspace/trailers.js +111 -0
- package/dist/workspace/tree.js +136 -0
- package/dist/workspace/trust/attestor.js +63 -0
- package/dist/workspace/trust/dsse.js +108 -0
- package/dist/workspace/trust/evidence-cli.js +175 -0
- package/dist/workspace/trust/evidence.js +161 -0
- package/dist/workspace/trust/gate-seal.js +226 -0
- package/dist/workspace/trust/policy.js +190 -0
- package/dist/workspace/trust/provenance.js +180 -0
- package/dist/workspace/trust/rotation.js +298 -0
- package/dist/workspace/trust/run-commits.js +101 -0
- package/dist/workspace/trust/run-statement.js +182 -0
- package/dist/workspace/trust/seal.js +272 -0
- package/dist/workspace/trust/signers-cli.js +152 -0
- package/dist/workspace/trust/ssh-commit.js +178 -0
- package/dist/workspace/trust/test-repo.js +118 -0
- package/dist/workspace/trust/trust-files.js +193 -0
- package/dist/workspace/trust/verify-cli.js +63 -0
- package/dist/workspace/trust/verify.js +192 -0
- package/dist/workspace/which-chant.js +141 -0
- package/dist/workspace/wip-cli.js +95 -0
- package/dist/workspace/wip-write.schema.json +504 -0
- package/dist/workspace/wip.js +631 -0
- package/dist/workspace/wip.schema.json +334 -0
- package/dist/workspace/work-cli.js +448 -0
- package/dist/workspace/work-evidence.js +122 -0
- package/dist/workspace/work-evidence.schema.json +222 -0
- package/dist/workspace/work-history.schema.json +421 -0
- package/dist/workspace/work-lease.schema.json +246 -0
- package/dist/workspace/work-size.js +77 -0
- package/dist/workspace/work.js +283 -0
- package/dist/workspace/workspace-kinds.schema.json +259 -259
- package/dist/workspace/workspace-principals.schema.json +53 -53
- package/dist/workspace/write-lock-cli.js +105 -0
- package/dist/workspace/write-lock.js +424 -0
- package/dist/workspace/write-lock.schema.json +172 -0
- package/dist/workspace/write-scope.js +484 -0
- package/dist/yaml.js +459 -0
- package/package.json +2 -2
- package/src/cli/commands/check-lexicon-plugin.ts +2 -0
- package/src/cli/commands/lint.ts +3 -0
- package/src/cli/commands/migrate.ts +2 -0
- package/src/cli/compiled-cli.e2e.test.ts +165 -0
- package/src/cli/main.ts +121 -27
- package/src/cli/mcp/workspace-tools.ts +1 -1
- package/src/codegen/pinned-upgrade.ts +2 -0
- package/src/components/discover.ts +2 -0
- package/src/components/sandbox/driver.ts +3 -1
- package/src/config-import.ts +3 -0
- package/src/discovery/fold-import.ts +23 -14
- package/src/discovery/import.ts +2 -0
- package/src/discovery/sandbox/driver.ts +3 -1
- package/src/lexicon-module.ts +3 -0
- package/src/lint/config.ts +1 -1
- package/src/lint/discover.ts +28 -8
- package/src/lint/policy-import.ts +4 -1
- package/src/lint/rule-loader.ts +2 -0
- package/src/op/discover.ts +3 -0
- package/src/ts-loader.test.ts +23 -0
- package/src/ts-loader.ts +122 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit.ts +1 -1
- package/src/workspace/declaration.ts +1 -1
- package/src/workspace/kinds.ts +1 -1
- package/src/workspace/lineage-migrations.ts +2 -0
- package/src/workspace/points.ts +1 -1
- package/src/workspace/principal-classes.ts +1 -1
|
@@ -0,0 +1,920 @@
|
|
|
1
|
+
import { build } from "../../build.js";
|
|
2
|
+
import { loadChantConfigUpward, resolveOwnershipMarker, resolveOwnershipEnv, ownershipEnvDisagreement, isOwnershipParamRef, resolveKnowledgeDir, } from "../../config.js";
|
|
3
|
+
import { resolveBuildModes, resolveProjectBuildOptions } from "../build-options.js";
|
|
4
|
+
import { resolveTelemetryAttribution } from "../../telemetry-attribution.js";
|
|
5
|
+
import { loadOkfBundle } from "../../okf-read.js";
|
|
6
|
+
import { unknownEnvError } from "../../env.js";
|
|
7
|
+
import { resolveCliBuildParams } from "../build-params-cli.js";
|
|
8
|
+
import { runPostSynthChecks } from "../../lint/post-synth.js";
|
|
9
|
+
import { loadActivityContracts } from "../../op/activity-contract-registry.js";
|
|
10
|
+
import { isOpEntity } from "../../op/resource.js";
|
|
11
|
+
import { serializeOpIR } from "../../op/op-ir.js";
|
|
12
|
+
import { opUsesDeprecatedGateKey, DEPRECATED_GATE_KEY_WARNING } from "../../op/gate-name.js";
|
|
13
|
+
import { coreReceiptChecks } from "../../lint/receipt-checks.js";
|
|
14
|
+
import { coreOutputChecks } from "../../lint/output-checks.js";
|
|
15
|
+
import { coreKnowledgeChecks } from "../../lint/knowledge-checks.js";
|
|
16
|
+
import { applyConfiguredSeverity, applyConfiguredPreset, resolvePresetIds } from "../../lint/config.js";
|
|
17
|
+
import { applyInlineSuppressions } from "../../lint/suppressions.js";
|
|
18
|
+
import { coreOpChecks } from "../../lint/rules/op/index.js";
|
|
19
|
+
import { loadPolicyChecks } from "../../lint/policy.js";
|
|
20
|
+
import { armSandboxPolicyExecution, runProjectPolicies } from "../../lint/policy-sandbox.js";
|
|
21
|
+
import { sortedJsonReplacer } from "../../utils.js";
|
|
22
|
+
import { rankFoldBlockers, toCollapsedFormat } from "../../discovery/fold-rank.js";
|
|
23
|
+
import { formatError, formatWarning, formatSuccess, formatBold, formatInfo } from "../format.js";
|
|
24
|
+
import { writeFileSync, mkdirSync } from "fs";
|
|
25
|
+
import { resolve, dirname, join, relative } from "path";
|
|
26
|
+
import { watchDirectory, formatTimestamp, formatChangedFiles } from "../watch.js";
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the output format for `chant build`.
|
|
29
|
+
*
|
|
30
|
+
* When `--format` is not given, infer it from the `-o` file extension
|
|
31
|
+
* (`.yaml`/`.yml` → yaml, `.json` → json); fall back to json when there is no
|
|
32
|
+
* extension to infer from. An explicit `--format` always wins, but a mismatch
|
|
33
|
+
* with the output extension is surfaced as a warning.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveBuildFormat(explicit, output) {
|
|
36
|
+
const inferred = output
|
|
37
|
+
? /\.ya?ml$/i.test(output)
|
|
38
|
+
? "yaml"
|
|
39
|
+
: /\.json$/i.test(output)
|
|
40
|
+
? "json"
|
|
41
|
+
: undefined
|
|
42
|
+
: undefined;
|
|
43
|
+
if (explicit === "json" || explicit === "yaml") {
|
|
44
|
+
if (inferred && inferred !== explicit) {
|
|
45
|
+
return {
|
|
46
|
+
format: explicit,
|
|
47
|
+
warning: `Output file "${output}" looks like ${inferred} but --format ${explicit} was given; writing ${explicit}.`,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return { format: explicit };
|
|
51
|
+
}
|
|
52
|
+
return { format: inferred ?? "json" };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Run each lexicon plugin's own post-synth checks over a build result, each
|
|
56
|
+
* plugin seeing only its own lexicon's output. Shared by `chant build` and
|
|
57
|
+
* `chant lint` (#3750), so the two run the same checks over the same scoping;
|
|
58
|
+
* each caller then applies `lint.presets`, `lint.rules` and inline
|
|
59
|
+
* suppressions its own way. A plugin with no checks yields no entry.
|
|
60
|
+
*/
|
|
61
|
+
export function runLexiconPostSynthChecks(plugins, result, env, opts) {
|
|
62
|
+
const batches = [];
|
|
63
|
+
for (const plugin of plugins) {
|
|
64
|
+
if (!plugin.postSynthChecks)
|
|
65
|
+
continue;
|
|
66
|
+
const checks = plugin.postSynthChecks();
|
|
67
|
+
if (checks.length === 0)
|
|
68
|
+
continue;
|
|
69
|
+
// Scope outputs to this plugin's lexicon so cross-lexicon outputs don't
|
|
70
|
+
// interfere. Outputs are keyed by the serializer's lexicon name (the
|
|
71
|
+
// build partition key), which differs from plugin.name for a dialect like
|
|
72
|
+
// forgejo (plugin "forgejo", serializer "github").
|
|
73
|
+
const outputKey = plugin.serializer.name;
|
|
74
|
+
const scopedOutputs = new Map();
|
|
75
|
+
const pluginOutput = result.outputs.get(outputKey);
|
|
76
|
+
if (pluginOutput !== undefined) {
|
|
77
|
+
scopedOutputs.set(outputKey, pluginOutput);
|
|
78
|
+
}
|
|
79
|
+
const scopedResult = { ...result, outputs: scopedOutputs };
|
|
80
|
+
batches.push({ plugin, diagnostics: runPostSynthChecks(checks, scopedResult, env, opts) });
|
|
81
|
+
}
|
|
82
|
+
return batches;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Execute the build command
|
|
86
|
+
*/
|
|
87
|
+
export async function buildCommand(options) {
|
|
88
|
+
const errors = [];
|
|
89
|
+
const warnings = [];
|
|
90
|
+
// Resolve the path
|
|
91
|
+
const infraPath = resolve(options.path);
|
|
92
|
+
// Resolve opt-in ownership marking from project config. chant #1117 — walks
|
|
93
|
+
// up from the infra dir to the project root (`loadChantConfigUpward`), not
|
|
94
|
+
// just the infra dir's immediate parent: a project whose stacks live two or
|
|
95
|
+
// more levels below `chant.config.ts` (a `src/<stack>` layout) otherwise
|
|
96
|
+
// never finds the root config at all, and every declared
|
|
97
|
+
// `buildParams`/`ownership`/`lint.policies` setting silently falls back to
|
|
98
|
+
// its default.
|
|
99
|
+
const loaded = await loadChantConfigUpward(infraPath);
|
|
100
|
+
const config = loaded.config;
|
|
101
|
+
// The ownership marker is resolved further down, after build parameters —
|
|
102
|
+
// `ownership.env` may reference one (#1396).
|
|
103
|
+
// Project-authored organizational policy checks (lint.policies), run over the
|
|
104
|
+
// resolved resources during build. Resolve paths relative to the config dir.
|
|
105
|
+
const configDir = loaded.configPath ? dirname(loaded.configPath) : infraPath;
|
|
106
|
+
const policies = config.lint?.policies ?? [];
|
|
107
|
+
// #1022/#1134 (fold) and #1045 Phase 2 (sandbox) — an explicit CLI flag
|
|
108
|
+
// (--fold/--no-fold, --sandbox) wins over `chant.config.ts`'s
|
|
109
|
+
// `build.fold`/`build.sandbox`, which wins over the defaults (fold on,
|
|
110
|
+
// sandbox off). Resolved here rather than with the rest of the build
|
|
111
|
+
// options below because arming sandboxed policy execution has to happen
|
|
112
|
+
// before any policy module could be loaded — see #2002 in ../build-options.ts.
|
|
113
|
+
const modes = resolveBuildModes(config, { fold: options.fold, sandbox: options.sandbox });
|
|
114
|
+
const { fold, sandbox } = modes;
|
|
115
|
+
// #1131 — arm sandboxed policy execution from the RESOLVED value, before any
|
|
116
|
+
// policy module could be loaded. Resolved, not `options.sandbox`, because
|
|
117
|
+
// policies have none of the config's bootstrap limit: they are loaded long
|
|
118
|
+
// after `build.sandbox` is known, so a config-only opt-in sandboxes them just
|
|
119
|
+
// as the CLI flag does. Arming (rather than threading a flag to each caller)
|
|
120
|
+
// makes `loadPolicyChecks` refuse process-wide — a call site that forgot to
|
|
121
|
+
// ask gets a loud error instead of quietly running project code here.
|
|
122
|
+
if (sandbox)
|
|
123
|
+
armSandboxPolicyExecution();
|
|
124
|
+
// Unsandboxed, the policy pack is still loaded HERE, before the build — a
|
|
125
|
+
// policy path that doesn't resolve has always failed the command up front,
|
|
126
|
+
// including when the build itself then fails, and #1131 does not change that.
|
|
127
|
+
// Sandboxed, there is nothing to load in this process at all.
|
|
128
|
+
const preloadedPolicyChecks = !sandbox && policies.length > 0 ? await loadPolicyChecks([...policies], configDir) : undefined;
|
|
129
|
+
// #1113 — the bootstrap limit, surfaced rather than left implicit. Reading
|
|
130
|
+
// `build.sandbox` out of `chant.config.ts` requires evaluating that file, so
|
|
131
|
+
// a config-only opt-in cannot have covered its own evaluation; only the CLI
|
|
132
|
+
// flag, known before any config is touched, arms `../config-sandbox.ts`.
|
|
133
|
+
// Say so instead of letting two different boundaries share one word.
|
|
134
|
+
if (sandbox && !options.sandbox && loaded.configPath?.endsWith(".ts")) {
|
|
135
|
+
warnings.push(formatWarning({
|
|
136
|
+
message: `build.sandbox is enabled by ${loaded.configPath}, but that file was itself evaluated in this process — reading the setting requires running the config. Pass --sandbox on the command line to evaluate chant.config.ts inside the boundary too.`,
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
// #1064 (factored into ../build-params-cli.ts's resolveCliBuildParams by
|
|
140
|
+
// #1108, so the component deploy driver runs the identical sequence) —
|
|
141
|
+
// resolve declared build-time parameters (chant.config.ts's buildParams)
|
|
142
|
+
// against this invocation's --param/--params-file/declared env mapping,
|
|
143
|
+
// BEFORE calling build() — a resolution failure (an unknown name, a
|
|
144
|
+
// missing required value, a type/enum mismatch) is reported as a chant
|
|
145
|
+
// build error naming the parameter, never a thrown error from inside user
|
|
146
|
+
// source (which is what a hand-rolled `tierFromEnv()`-style validator in a
|
|
147
|
+
// project's own `params.ts` does before migrating to this mechanism). Also
|
|
148
|
+
// logs a one-line count on success, or every resolved value (`[param] name =
|
|
149
|
+
// value (source)`) under --verbose (#1424).
|
|
150
|
+
const paramsResolution = resolveCliBuildParams(config.buildParams, {
|
|
151
|
+
cli: options.params,
|
|
152
|
+
paramsFile: options.paramsFile,
|
|
153
|
+
verbose: options.verbose,
|
|
154
|
+
});
|
|
155
|
+
if (!paramsResolution.success) {
|
|
156
|
+
errors.push(...paramsResolution.errors);
|
|
157
|
+
return { success: false, resourceCount: 0, fileCount: 0, errors, warnings };
|
|
158
|
+
}
|
|
159
|
+
// chant #1117 — a project that declares buildParams but resolves NONE of
|
|
160
|
+
// them for this build is the exact shape that let a silent misresolution run
|
|
161
|
+
// for two releases: the discovered config wasn't the one the project author
|
|
162
|
+
// expected (a stale --path, a workspace boundary that stopped the walk
|
|
163
|
+
// short), or every declared parameter's `env:` var went unset, and either
|
|
164
|
+
// way every `params.<name>` read silently falls back to `undefined` — with
|
|
165
|
+
// no error (an all-`required: false` declaration resolves successfully to
|
|
166
|
+
// an empty set). Warn, naming the config path this build actually
|
|
167
|
+
// discovered, so a mismatch is visible instead of silent.
|
|
168
|
+
if (Object.keys(config.buildParams ?? {}).length > 0 &&
|
|
169
|
+
paramsResolution.provenance.length === 0) {
|
|
170
|
+
warnings.push(formatWarning({
|
|
171
|
+
message: `chant.config.ts declares buildParams${loaded.configPath ? ` (${loaded.configPath})` : ""}, but none resolved for this build — every params.<name> read will be undefined. Pass --param/--params-file, or check that this is the config you expect.`,
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
// #1396 — opt-in ownership marking, resolved AFTER build parameters so
|
|
175
|
+
// `ownership.env: { param: "env" }` takes the value `--param env=prod` (or
|
|
176
|
+
// the declared env mapping, or the default) bound to params.env — one
|
|
177
|
+
// source for the label and the marker. A reference that cannot be
|
|
178
|
+
// satisfied is a build error, not a marker silently stamped without an env.
|
|
179
|
+
let ownership;
|
|
180
|
+
// Environment for policy evaluation: explicit --env wins, else ownership.env
|
|
181
|
+
// (read even when marking itself is off, so policy can still branch on it).
|
|
182
|
+
let env;
|
|
183
|
+
try {
|
|
184
|
+
ownership = resolveOwnershipMarker(config, paramsResolution.provenance);
|
|
185
|
+
env = options.env ?? resolveOwnershipEnv(config, paramsResolution.provenance);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
errors.push(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
189
|
+
return { success: false, resourceCount: 0, fileCount: 0, errors, warnings };
|
|
190
|
+
}
|
|
191
|
+
// A literal `ownership.env` next to an `env` build parameter that resolved
|
|
192
|
+
// to something else is the silent divergence #1396 reports — say so.
|
|
193
|
+
const disagreement = ownershipEnvDisagreement(config, paramsResolution.provenance);
|
|
194
|
+
if (disagreement)
|
|
195
|
+
warnings.push(formatWarning({ message: disagreement }));
|
|
196
|
+
// #1221 — dynamic-env legality. `--env` is validated against the declared
|
|
197
|
+
// `environments` in cli/main.ts; a param-bound `ownership.env` supplied via
|
|
198
|
+
// `--param env=<value>` reached here unchecked, so `--param env=pord`
|
|
199
|
+
// stamped a marker for an environment the project never declared. Same
|
|
200
|
+
// check, same site of truth: literal entries match by equality, entries
|
|
201
|
+
// containing `*` (e.g. `"pr-*"`) match as glob patterns, so an unbounded
|
|
202
|
+
// family like per-PR environments is declarable without listing each name.
|
|
203
|
+
if (isOwnershipParamRef(config.ownership?.env)) {
|
|
204
|
+
const dynamicEnvErr = unknownEnvError(env, config.environments);
|
|
205
|
+
if (dynamicEnvErr) {
|
|
206
|
+
errors.push(formatError({
|
|
207
|
+
message: dynamicEnvErr,
|
|
208
|
+
hint: 'Declare it in chant.config `environments` (a "pr-*" pattern entry covers a dynamic family), or pass a declared value.',
|
|
209
|
+
}));
|
|
210
|
+
return { success: false, resourceCount: 0, fileCount: 0, errors, warnings };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Run the build. #2002 — every option comes from the shared assembler
|
|
214
|
+
// (../build-options.ts), which `evaluateProjectPolicies` calls too, so the
|
|
215
|
+
// `policyGate` step decides on the same project this command builds.
|
|
216
|
+
const telemetry = await resolveTelemetryAttribution(configDir, config, env);
|
|
217
|
+
const runBuild = (serializers) => build(infraPath, serializers, undefined, resolveProjectBuildOptions({
|
|
218
|
+
config,
|
|
219
|
+
configDir,
|
|
220
|
+
plugins: options.plugins,
|
|
221
|
+
modes,
|
|
222
|
+
ownership,
|
|
223
|
+
buildParams: paramsResolution.provenance,
|
|
224
|
+
telemetry,
|
|
225
|
+
}));
|
|
226
|
+
let result;
|
|
227
|
+
if (options.sharedBuild) {
|
|
228
|
+
const shared = options.sharedBuild;
|
|
229
|
+
shared.result ?? (shared.result = runBuild(shared.serializers));
|
|
230
|
+
const full = await shared.result;
|
|
231
|
+
const own = new Set(options.serializers.map((x) => x.name));
|
|
232
|
+
result = { ...full, outputs: new Map([...full.outputs].filter(([name]) => own.has(name))) };
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
result = await runBuild(options.serializers);
|
|
236
|
+
}
|
|
237
|
+
// #1022 — report per-file fold vs run so it's visible what still runs.
|
|
238
|
+
// #1424 — one line by default; the per-file lines and their reasons are
|
|
239
|
+
// --verbose. A file that ran is the expected outcome for source that
|
|
240
|
+
// computes values in functions, and a dozen "is not foldable" notes read
|
|
241
|
+
// like errors to someone meeting the project for the first time.
|
|
242
|
+
if (fold && result.foldDecisions.length > 0) {
|
|
243
|
+
if (options.verbose) {
|
|
244
|
+
for (const decision of result.foldDecisions) {
|
|
245
|
+
const rel = relative(infraPath, decision.file) || decision.file;
|
|
246
|
+
const detail = decision.mode === "fold"
|
|
247
|
+
? `${decision.resourceCount ?? 0} resource(s), no module execution`
|
|
248
|
+
: (decision.reason ?? "fell back to run");
|
|
249
|
+
console.error(formatInfo(`[fold:${decision.mode}] ${rel} — ${detail}`));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
console.error(formatInfo(summarizeFoldDecisions(result.foldDecisions)));
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// chant #1083 — rank fold blockers by dominator retained-count over the
|
|
257
|
+
// forward import-failure graph, and report the reverse-taint bucket
|
|
258
|
+
// (#1044) separately. Opt-in (`--fold-rank`) and independent of
|
|
259
|
+
// `--verbose`: the per-file listing above says WHAT ran; this says WHICH
|
|
260
|
+
// of those files is worth fixing first.
|
|
261
|
+
if (fold && (options.foldRank || options.foldRankCollapsedFile) && result.foldDecisions.length > 0) {
|
|
262
|
+
const ranking = await rankFoldBlockers(result.foldDecisions);
|
|
263
|
+
console.error(formatInfo(formatFoldRanking(ranking, infraPath)));
|
|
264
|
+
if (options.foldRankCollapsedFile) {
|
|
265
|
+
const collapsedPath = resolve(options.foldRankCollapsedFile);
|
|
266
|
+
mkdirSync(dirname(collapsedPath), { recursive: true });
|
|
267
|
+
const lines = toCollapsedFormat(ranking, { relativeTo: infraPath });
|
|
268
|
+
writeFileSync(collapsedPath, lines.length > 0 ? `${lines.join("\n")}\n` : "");
|
|
269
|
+
console.error(formatInfo(`[fold-rank] collapsed-format export: ${collapsedPath} (${lines.length} line(s))`));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Format errors — grouped by message, because one refusal can surface once
|
|
273
|
+
// per resource file. A project whose params module throws (a guard like
|
|
274
|
+
// "this seam cannot back that tier") throws in EVERY file that imports it,
|
|
275
|
+
// and fourteen copies of one sentence bury the sentence
|
|
276
|
+
// (INTENTIUS/fountain-ops#62). The first file to hit it is named, the rest
|
|
277
|
+
// become a count; errors with genuinely different messages keep their own
|
|
278
|
+
// lines, and a message that appears once is printed exactly as before.
|
|
279
|
+
const byMessage = new Map();
|
|
280
|
+
for (const error of result.errors) {
|
|
281
|
+
const key = `${error.name ?? ""}:${error.message}`;
|
|
282
|
+
const seen = byMessage.get(key);
|
|
283
|
+
if (seen)
|
|
284
|
+
seen.files += 1;
|
|
285
|
+
else
|
|
286
|
+
byMessage.set(key, { first: error, files: 1 });
|
|
287
|
+
}
|
|
288
|
+
for (const { first: error, files } of byMessage.values()) {
|
|
289
|
+
const formatted = formatError({
|
|
290
|
+
file: "file" in error ? error.file : undefined,
|
|
291
|
+
line: "line" in error ? error.line : undefined,
|
|
292
|
+
column: "column" in error ? error.column : undefined,
|
|
293
|
+
message: files > 1 ? `${error.message} (and the same from ${files - 1} more files)` : error.message,
|
|
294
|
+
name: error.name,
|
|
295
|
+
});
|
|
296
|
+
errors.push(formatted);
|
|
297
|
+
}
|
|
298
|
+
// Format warnings
|
|
299
|
+
for (const warning of result.warnings) {
|
|
300
|
+
warnings.push(formatWarning({ message: warning }));
|
|
301
|
+
}
|
|
302
|
+
// Run post-synth checks from plugins — each plugin only sees its own lexicon's output
|
|
303
|
+
//
|
|
304
|
+
// chant #1138 — every diagnostic collected below (a lexicon-shipped check's
|
|
305
|
+
// AND a project's `lint.policies`') is resolved against `lint.rules` before
|
|
306
|
+
// it becomes an error/warning line, through the exact same
|
|
307
|
+
// `applyConfiguredSeverity` (../../lint/post-synth.ts) that keys off
|
|
308
|
+
// `diag.checkId` the way `lintCommand` keys an AST/COMP* diagnostic off its
|
|
309
|
+
// rule id — so `lint.rules: { WAW019: "off" }` suppresses a post-synth
|
|
310
|
+
// finding just as it suppresses a pre-synth one. A finding it suppresses is
|
|
311
|
+
// counted, not dropped silently — see `suppressedPostSynthCount` below.
|
|
312
|
+
//
|
|
313
|
+
// chant #2111: every batch also goes through `applyInlineSuppressions`
|
|
314
|
+
// right after, so a `# chant-ignore` comment on an entity (terraform's HCL
|
|
315
|
+
// blocks today; any lexicon that attaches `suppressions` to its own
|
|
316
|
+
// entities tomorrow) suppresses identically regardless of which phase
|
|
317
|
+
// produced the diagnostic. Same counted-not-dropped contract, in its own
|
|
318
|
+
// `inlineSuppressedCount`, plus `suppressionMeta` for directives that are
|
|
319
|
+
// themselves worth a finding (expired, misplaced, denied by `ignorable: false`).
|
|
320
|
+
let suppressedPostSynthCount = 0;
|
|
321
|
+
let inlineSuppressedCount = 0;
|
|
322
|
+
const suppressionMeta = [];
|
|
323
|
+
// A rule a `lint.presets` preset excludes (chant #2113) is a distinct
|
|
324
|
+
// reason a finding doesn't reach the errors/warnings lists. The preset
|
|
325
|
+
// decided the rule shouldn't run at all under this project's configured
|
|
326
|
+
// tier, not that `lint.rules` downgraded it to "off", so it gets its own
|
|
327
|
+
// counter and its own summary line rather than folding into the one above.
|
|
328
|
+
let suppressedPresetCount = 0;
|
|
329
|
+
/**
|
|
330
|
+
* Apply every suppression/filtering surface to one batch, in order:
|
|
331
|
+
* `lint.presets` (chant #2113, which check ids are enabled at all; a
|
|
332
|
+
* no-op when `presetIds` is undefined, the case for every call site below
|
|
333
|
+
* except the per-plugin loop, which is the only one with a lexicon a
|
|
334
|
+
* preset could apply to), then `lint.rules` severity overrides (chant
|
|
335
|
+
* #1138), then inline `# chant-ignore` comments (chant #2111).
|
|
336
|
+
*/
|
|
337
|
+
const resolvePostSynth = (diags, entities, presetIds) => {
|
|
338
|
+
const { diagnostics: afterPreset, suppressed: presetSuppressed } = applyConfiguredPreset(diags, presetIds, config.lint?.rules);
|
|
339
|
+
suppressedPresetCount += presetSuppressed.length;
|
|
340
|
+
const { diagnostics: afterConfig, suppressed: configSuppressed } = applyConfiguredSeverity(afterPreset, config.lint?.rules);
|
|
341
|
+
suppressedPostSynthCount += configSuppressed.length;
|
|
342
|
+
const { diagnostics: active, suppressed: inlineSuppressed, meta } = applyInlineSuppressions(afterConfig, entities, config.lint?.rules);
|
|
343
|
+
inlineSuppressedCount += inlineSuppressed.length;
|
|
344
|
+
suppressionMeta.push(...meta);
|
|
345
|
+
return active;
|
|
346
|
+
};
|
|
347
|
+
// Core-owned post-synth checks over effect receipts (#1833). Receipts are
|
|
348
|
+
// recognized by marker, lexicon-independently, so this set runs over the
|
|
349
|
+
// FULL build result — unscoped, and regardless of which plugins loaded.
|
|
350
|
+
// Same severity-resolution funnel as every other post-synth finding.
|
|
351
|
+
if (result.errors.length === 0) {
|
|
352
|
+
const receiptDiags = runPostSynthChecks(coreReceiptChecks(), result, env);
|
|
353
|
+
for (const diag of resolvePostSynth(receiptDiags, result.entities)) {
|
|
354
|
+
const prefix = diag.entity ? `[${diag.entity}] ` : "";
|
|
355
|
+
const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
|
|
356
|
+
if (diag.severity === "error") {
|
|
357
|
+
errors.push(formatError({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
warnings.push(formatWarning({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// Core-owned post-synth check over serialized output text (#1526). The
|
|
365
|
+
// "[object Object]" marker means a reference got stringified instead of
|
|
366
|
+
// resolved; it can appear in any lexicon's emitted text, so this runs over
|
|
367
|
+
// the FULL build result the same way the receipt checks above do.
|
|
368
|
+
if (result.errors.length === 0) {
|
|
369
|
+
const outputDiags = runPostSynthChecks(coreOutputChecks(), result, env);
|
|
370
|
+
for (const diag of resolvePostSynth(outputDiags, result.entities)) {
|
|
371
|
+
const prefix = diag.entity ? `[${diag.entity}] ` : "";
|
|
372
|
+
const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
|
|
373
|
+
if (diag.severity === "error") {
|
|
374
|
+
errors.push(formatError({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
warnings.push(formatWarning({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
// Core-owned post-synth check over the project's OKF knowledge bundle
|
|
382
|
+
// (#1865, design #1059): a concept's `binds` naming no discovered entity is
|
|
383
|
+
// a stale binding, surfaced as a COR026 warning. `resolveKnowledgeDir` +
|
|
384
|
+
// `loadOkfBundle` never fail — a missing/absent `knowledge/` directory
|
|
385
|
+
// loads an empty bundle, so this is a no-op for a project that has none.
|
|
386
|
+
if (result.errors.length === 0) {
|
|
387
|
+
const bundle = await loadOkfBundle(resolveKnowledgeDir(config, configDir));
|
|
388
|
+
const knowledgeDiags = runPostSynthChecks(coreKnowledgeChecks(bundle), result, env);
|
|
389
|
+
for (const diag of resolvePostSynth(knowledgeDiags, result.entities)) {
|
|
390
|
+
const prefix = diag.entity ? `[${diag.entity}] ` : "";
|
|
391
|
+
const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
|
|
392
|
+
if (diag.severity === "error") {
|
|
393
|
+
errors.push(formatError({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
warnings.push(formatWarning({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Activity contracts across every loaded lexicon (chant #2101): core's own
|
|
401
|
+
// plus each lexicon's, by the same `@intentius/chant-lexicon-<name>/op/...`
|
|
402
|
+
// convention `loadActivities` resolves implementations with. OPS012/OPS013
|
|
403
|
+
// and a plugin's own checks merge this over their own tables, so a step
|
|
404
|
+
// calling a lexicon's activity is validated against that lexicon's contract
|
|
405
|
+
// instead of failing for the absence of one. Resolved once, for both check
|
|
406
|
+
// passes below.
|
|
407
|
+
const activityContracts = result.errors.length === 0 ? await loadActivityContracts(options.plugins ?? []) : undefined;
|
|
408
|
+
// Core-owned post-synth checks over the Op model (#2122, epic #2114
|
|
409
|
+
// sub-issue 6) — OPS012/OPS013/OPS014, ported from a hosting lexicon's
|
|
410
|
+
// own TMP012/TMP013/TMP014, and SYS010 over the decide steps and the
|
|
411
|
+
// backends in `decide.backends` (#2828). An Op is recognized by entity type
|
|
412
|
+
// (`OpResource`), not by which lexicon declared it, so this runs over the
|
|
413
|
+
// FULL build result regardless of which plugins loaded — same as the
|
|
414
|
+
// receipt/output/knowledge checks above.
|
|
415
|
+
if (result.errors.length === 0) {
|
|
416
|
+
const opDiags = runPostSynthChecks(coreOpChecks({ decideBackends: config.decide?.backends }), result, env, { activityContracts });
|
|
417
|
+
const { diagnostics: activeDiags, suppressed } = applyConfiguredSeverity(opDiags, config.lint?.rules);
|
|
418
|
+
suppressedPostSynthCount += suppressed.length;
|
|
419
|
+
for (const diag of activeDiags) {
|
|
420
|
+
const prefix = diag.entity ? `[${diag.entity}] ` : "";
|
|
421
|
+
const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
|
|
422
|
+
if (diag.severity === "error") {
|
|
423
|
+
errors.push(formatError({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
warnings.push(formatWarning({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (result.errors.length === 0 && options.plugins) {
|
|
431
|
+
for (const { plugin, diagnostics: postDiags } of runLexiconPostSynthChecks(options.plugins, result, env, { activityContracts, telemetry, projectDir: configDir, projectConfig: config })) {
|
|
432
|
+
// `lint.presets` (chant #2113) filters WHICH check ids are reported at
|
|
433
|
+
// all, before `lint.rules`/inline suppression act on the reported
|
|
434
|
+
// ones. It's a no-op for a lexicon that ships no `lintPresets()` (the
|
|
435
|
+
// common case today), since `resolvePresetIds` returns `undefined`
|
|
436
|
+
// for one. This is the only `resolvePostSynth` call site with a
|
|
437
|
+
// lexicon a preset could apply to; every other call below passes no
|
|
438
|
+
// `presetIds` at all.
|
|
439
|
+
const presetIds = resolvePresetIds(plugin.lintPresets?.(), config.lint?.presets?.[plugin.name] ?? "recommended");
|
|
440
|
+
for (const diag of resolvePostSynth(postDiags, result.entities, presetIds)) {
|
|
441
|
+
const prefix = diag.entity ? `[${diag.entity}] ` : "";
|
|
442
|
+
const lexiconSuffix = diag.lexicon ? ` (${diag.lexicon})` : "";
|
|
443
|
+
if (diag.severity === "error") {
|
|
444
|
+
errors.push(formatError({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
warnings.push(formatWarning({ message: `${prefix}${diag.message}${lexiconSuffix}` }));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
// Project-authored organizational policy — cross-cutting, so it sees every
|
|
452
|
+
// lexicon's output at once (not scoped per-plugin), with the current env.
|
|
453
|
+
//
|
|
454
|
+
// #1131 — under `--sandbox` this is where the LAST piece of project-
|
|
455
|
+
// authored code the CLI used to execute in its own process moves behind
|
|
456
|
+
// the boundary: `runProjectPolicies` hands the merged, serialized build
|
|
457
|
+
// result to a post-merge sandboxed child, which imports the policy modules
|
|
458
|
+
// and runs their checks there, and only plain `PostSynthDiagnostic`s come
|
|
459
|
+
// back. Unsandboxed, it is the same in-process load-and-run as before.
|
|
460
|
+
//
|
|
461
|
+
// #1138 — `applyConfiguredSeverity` runs HERE, in the parent, after the
|
|
462
|
+
// sandboxed child (when armed) has already returned — never inside it.
|
|
463
|
+
// The child only knows the policy paths and the encoded build result, not
|
|
464
|
+
// this project's resolved `lint.rules`, and by design nothing about the
|
|
465
|
+
// suppression surface needs to cross that boundary: both the plain and
|
|
466
|
+
// the `--sandbox` path funnel through this identical call with the
|
|
467
|
+
// identical `config.lint?.rules`, so a sandboxed and an unsandboxed build
|
|
468
|
+
// of the same project apply the same config to the same diagnostics.
|
|
469
|
+
if (policies.length > 0) {
|
|
470
|
+
const policyDiags = await runProjectPolicies({
|
|
471
|
+
policies,
|
|
472
|
+
configDir,
|
|
473
|
+
buildResult: result,
|
|
474
|
+
env,
|
|
475
|
+
preloaded: preloadedPolicyChecks,
|
|
476
|
+
});
|
|
477
|
+
for (const diag of resolvePostSynth(policyDiags, result.entities)) {
|
|
478
|
+
const prefix = diag.entity ? `[${diag.entity}] ` : "";
|
|
479
|
+
const where = diag.lexicon ? ` (${diag.lexicon})` : "";
|
|
480
|
+
const msg = `[policy:${diag.checkId}] ${prefix}${diag.message}${where}`;
|
|
481
|
+
if (diag.severity === "error")
|
|
482
|
+
errors.push(formatError({ message: msg }));
|
|
483
|
+
else
|
|
484
|
+
warnings.push(formatWarning({ message: msg }));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
if (suppressedPostSynthCount > 0) {
|
|
488
|
+
warnings.push(formatWarning({
|
|
489
|
+
message: `${suppressedPostSynthCount} post-synth finding(s) suppressed via lint.rules (severity "off")`,
|
|
490
|
+
}));
|
|
491
|
+
}
|
|
492
|
+
if (suppressedPresetCount > 0) {
|
|
493
|
+
warnings.push(formatWarning({
|
|
494
|
+
message: `${suppressedPresetCount} post-synth finding(s) not reported: excluded by the active lint.presets preset`,
|
|
495
|
+
}));
|
|
496
|
+
}
|
|
497
|
+
if (inlineSuppressedCount > 0) {
|
|
498
|
+
warnings.push(formatWarning({
|
|
499
|
+
message: `${inlineSuppressedCount} post-synth finding(s) suppressed via inline chant-ignore comments`,
|
|
500
|
+
}));
|
|
501
|
+
}
|
|
502
|
+
// Directives that are themselves worth a finding (expired, misplaced, or
|
|
503
|
+
// naming a rule id configured `ignorable: false`) are reported once
|
|
504
|
+
// each, never silently (chant #2111).
|
|
505
|
+
for (const m of suppressionMeta) {
|
|
506
|
+
warnings.push(formatWarning({ message: `[${m.checkId}] ${m.file}:${m.line} ${m.message}` }));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
// Empty-output guard: source files were discovered but no lexicon produced
|
|
510
|
+
// any output. Almost always indicates broken imports resolving to undefined
|
|
511
|
+
// (e.g. missing root re-exports from a lexicon) or modules that exported no
|
|
512
|
+
// Declarables. Without this guard, chant writes "{}" and exits 0.
|
|
513
|
+
//
|
|
514
|
+
// An Op declaration is the honest exception (#2118): it belongs to no
|
|
515
|
+
// lexicon partition and its build output is the `op.json` written below,
|
|
516
|
+
// not a resource manifest, so an Ops-only project legitimately produces no
|
|
517
|
+
// serializer output and must not be reported as a broken import.
|
|
518
|
+
const declaredOps = [...result.entities.values()].filter(isOpEntity);
|
|
519
|
+
// The gate step's name key was renamed from `signalName` to `gate` in #2202.
|
|
520
|
+
// The old key is still read; a build that finds an Op still using it says so
|
|
521
|
+
// once, naming every Op involved, rather than once per gate step.
|
|
522
|
+
const opsOnOldGateKey = declaredOps
|
|
523
|
+
.map((entity) => entity.props)
|
|
524
|
+
.filter((config) => Boolean(config?.name) && opUsesDeprecatedGateKey(config))
|
|
525
|
+
.map((config) => config.name);
|
|
526
|
+
if (opsOnOldGateKey.length > 0) {
|
|
527
|
+
warnings.push(formatWarning({ message: `${DEPRECATED_GATE_KEY_WARNING} Ops: ${opsOnOldGateKey.join(", ")}.` }));
|
|
528
|
+
}
|
|
529
|
+
if (result.sourceFileCount > 0 &&
|
|
530
|
+
result.outputs.size === 0 &&
|
|
531
|
+
declaredOps.length === 0 &&
|
|
532
|
+
result.errors.length === 0 &&
|
|
533
|
+
errors.length === 0) {
|
|
534
|
+
errors.push(formatError({
|
|
535
|
+
message: `Discovered ${result.sourceFileCount} source file(s) but produced no output. Likely causes: imports resolving to undefined (missing exports from a lexicon root), or no Declarables/Composites exported. Check that imported names exist in the target package.`,
|
|
536
|
+
}));
|
|
537
|
+
}
|
|
538
|
+
// Handle output
|
|
539
|
+
if (result.errors.length === 0 && errors.length === 0) {
|
|
540
|
+
// Extract primary content and collect additional files from SerializerResult.
|
|
541
|
+
// Each entry remembers which lexicon produced it, so a same-basename
|
|
542
|
+
// collision between two sources (below) can name both.
|
|
543
|
+
const additionalFiles = new Map();
|
|
544
|
+
// Basenames (from some SerializerResult.files) that must reach disk
|
|
545
|
+
// BYTE-FOR-BYTE — e.g. committed ciphertext
|
|
546
|
+
// (`declareSecret({ provenance: "committed-encrypted", file })`). The
|
|
547
|
+
// additional-file writer below round-trips anything JSON.parse accepts,
|
|
548
|
+
// key-sorting it and possibly re-emitting it as YAML, which would break
|
|
549
|
+
// e.g. the `sops` MAC on committed ciphertext. A serializer opts a file
|
|
550
|
+
// out of that round trip structurally, via `SerializerResult.verbatimFiles`
|
|
551
|
+
// (chant#1937) — "the parse happens to fail" is not a safety guarantee.
|
|
552
|
+
const verbatimFiles = new Set();
|
|
553
|
+
// Basenames that hold a secret (`SerializerResult.secretFiles`): a build
|
|
554
|
+
// with no --output refuses rather than echo them (chant#3738). Verbatim
|
|
555
|
+
// alone does not mean secret, so this is its own set.
|
|
556
|
+
const secretFiles = new Set();
|
|
557
|
+
// A same basename emitted by two sources with different content would
|
|
558
|
+
// otherwise silently overwrite (last-writer-wins, since `additionalFiles`
|
|
559
|
+
// is keyed by basename alone). Identical content from two sources is
|
|
560
|
+
// fine — dedup — but differing content is refused, naming both sources,
|
|
561
|
+
// the same way the committed-encrypted resolution stage refuses a
|
|
562
|
+
// basename collision among its own declarations.
|
|
563
|
+
function addAdditionalFile(filename, content, source) {
|
|
564
|
+
const existing = additionalFiles.get(filename);
|
|
565
|
+
if (existing === undefined) {
|
|
566
|
+
additionalFiles.set(filename, { content, source });
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (existing.content === content)
|
|
570
|
+
return;
|
|
571
|
+
errors.push(formatError({
|
|
572
|
+
message: `Additional file "${filename}" collides: "${existing.source}" and "${source}" ` +
|
|
573
|
+
`both emit it with different content — additional files share one flat ` +
|
|
574
|
+
`namespace, so two sources whose filenames match would otherwise silently ` +
|
|
575
|
+
`overwrite each other.`,
|
|
576
|
+
}));
|
|
577
|
+
}
|
|
578
|
+
function getPrimaryContent(raw, source) {
|
|
579
|
+
if (typeof raw === "string")
|
|
580
|
+
return raw;
|
|
581
|
+
if (raw.files) {
|
|
582
|
+
for (const [filename, content] of Object.entries(raw.files)) {
|
|
583
|
+
addAdditionalFile(filename, content, source);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
if (raw.verbatimFiles) {
|
|
587
|
+
for (const filename of raw.verbatimFiles) {
|
|
588
|
+
verbatimFiles.add(filename);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (raw.secretFiles) {
|
|
592
|
+
for (const filename of raw.secretFiles) {
|
|
593
|
+
secretFiles.add(filename);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return raw.primary;
|
|
597
|
+
}
|
|
598
|
+
// Try to parse content as JSON; return raw string if not JSON.
|
|
599
|
+
function tryParseJson(content) {
|
|
600
|
+
try {
|
|
601
|
+
return { json: JSON.parse(content) };
|
|
602
|
+
}
|
|
603
|
+
catch {
|
|
604
|
+
return { raw: content };
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
// Single lexicon: output the template directly
|
|
608
|
+
// Multiple lexicons: wrap in lexicon keys
|
|
609
|
+
let output = "{}";
|
|
610
|
+
if (result.outputs.size === 1) {
|
|
611
|
+
const [lexiconName, raw] = [...result.outputs.entries()][0];
|
|
612
|
+
const content = getPrimaryContent(raw, lexiconName);
|
|
613
|
+
const parsed = tryParseJson(content);
|
|
614
|
+
if ("json" in parsed) {
|
|
615
|
+
output = JSON.stringify(parsed.json, sortedJsonReplacer, 2);
|
|
616
|
+
if (options.format === "yaml") {
|
|
617
|
+
output = jsonToYaml(JSON.parse(output));
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
output = parsed.raw;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
// Multiple lexicons: JSON outputs get combined under lexicon keys,
|
|
626
|
+
// non-JSON outputs (e.g. YAML) are appended after a separator.
|
|
627
|
+
const combined = {};
|
|
628
|
+
const nonJsonSections = [];
|
|
629
|
+
const sortedLexiconNames = [...result.outputs.keys()].sort();
|
|
630
|
+
for (const lexiconName of sortedLexiconNames) {
|
|
631
|
+
const content = getPrimaryContent(result.outputs.get(lexiconName), lexiconName);
|
|
632
|
+
const parsed = tryParseJson(content);
|
|
633
|
+
if ("json" in parsed) {
|
|
634
|
+
combined[lexiconName] = parsed.json;
|
|
635
|
+
}
|
|
636
|
+
else {
|
|
637
|
+
nonJsonSections.push(`# --- ${lexiconName} ---\n${parsed.raw}`);
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
const parts = [];
|
|
641
|
+
if (Object.keys(combined).length > 0) {
|
|
642
|
+
let jsonOutput = JSON.stringify(combined, sortedJsonReplacer, 2);
|
|
643
|
+
if (options.format === "yaml") {
|
|
644
|
+
jsonOutput = jsonToYaml(JSON.parse(jsonOutput));
|
|
645
|
+
}
|
|
646
|
+
parts.push(jsonOutput);
|
|
647
|
+
}
|
|
648
|
+
parts.push(...nonJsonSections);
|
|
649
|
+
if (parts.length > 0) {
|
|
650
|
+
output = parts.join("\n\n");
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
// Anything a serializer emits under `ops/` always goes to
|
|
654
|
+
// `<project>/dist/ops/` — the fixed place an Op's build output is read
|
|
655
|
+
// from, alongside the `op.json` core writes below — independent of
|
|
656
|
+
// `--output`, which routes the primary resource manifest. Without this, a
|
|
657
|
+
// bare `chant build` only printed them to stderr and `--output foo.yaml`
|
|
658
|
+
// scattered them next to `foo.yaml`.
|
|
659
|
+
const projectDist = resolve(options.path ?? ".", "dist");
|
|
660
|
+
let opsWritten = 0;
|
|
661
|
+
for (const [filename, entry] of [...additionalFiles]) {
|
|
662
|
+
if (!filename.startsWith("ops/"))
|
|
663
|
+
continue;
|
|
664
|
+
additionalFiles.delete(filename);
|
|
665
|
+
try {
|
|
666
|
+
const targetPath = join(projectDist, filename);
|
|
667
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
668
|
+
writeFileSync(targetPath, entry.content);
|
|
669
|
+
opsWritten += 1;
|
|
670
|
+
}
|
|
671
|
+
catch (err) {
|
|
672
|
+
errors.push(formatError({
|
|
673
|
+
message: `Failed to write Op output file ${filename}: ${err instanceof Error ? err.message : String(err)}`,
|
|
674
|
+
}));
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
if (opsWritten > 0) {
|
|
678
|
+
console.error(formatInfo(`Wrote ${opsWritten} Op output file(s) under ${join(options.path ?? ".", "dist", "ops")}/`));
|
|
679
|
+
}
|
|
680
|
+
// `dist/ops/<name>/op.json` — the Op IR (#1289), written here by core
|
|
681
|
+
// rather than emitted by a lexicon serializer (#2118). An Op declaration
|
|
682
|
+
// is core's own entity now (`Chant::Op`, lexicon `chant`) and is held out
|
|
683
|
+
// of `partitionByLexicon` entirely, so this is the one place its build
|
|
684
|
+
// output is produced: a deterministic, engine-neutral restatement of the
|
|
685
|
+
// step graph that anything can read without importing chant.
|
|
686
|
+
let irWritten = 0;
|
|
687
|
+
for (const entity of declaredOps) {
|
|
688
|
+
const config = entity.props;
|
|
689
|
+
if (!config?.name)
|
|
690
|
+
continue;
|
|
691
|
+
try {
|
|
692
|
+
const targetPath = join(projectDist, "ops", config.name, "op.json");
|
|
693
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
694
|
+
writeFileSync(targetPath, serializeOpIR(config));
|
|
695
|
+
irWritten += 1;
|
|
696
|
+
}
|
|
697
|
+
catch (err) {
|
|
698
|
+
errors.push(formatError({
|
|
699
|
+
message: `Failed to write op.json for Op "${config.name}": ${err instanceof Error ? err.message : String(err)}`,
|
|
700
|
+
}));
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (irWritten > 0) {
|
|
704
|
+
console.error(formatInfo(`Wrote ${irWritten} op.json file(s) under ${join(options.path ?? ".", "dist", "ops")}/`));
|
|
705
|
+
}
|
|
706
|
+
if (options.output) {
|
|
707
|
+
// Write to file — ensure parent directories exist for both the primary
|
|
708
|
+
// output path and any nested additional-file paths (e.g. ops/<name>/...).
|
|
709
|
+
try {
|
|
710
|
+
const outputPath = resolve(options.output);
|
|
711
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
712
|
+
writeFileSync(outputPath, output);
|
|
713
|
+
// Write additional files (e.g. nested stack templates) alongside the primary output
|
|
714
|
+
if (additionalFiles.size > 0) {
|
|
715
|
+
const outputDir = dirname(outputPath);
|
|
716
|
+
for (const [filename, entry] of additionalFiles) {
|
|
717
|
+
let fileContent = entry.content;
|
|
718
|
+
// Format additional files consistently — except the ones declared
|
|
719
|
+
// verbatim, which are copied exactly as they were committed.
|
|
720
|
+
if (!verbatimFiles.has(filename)) {
|
|
721
|
+
try {
|
|
722
|
+
const fileParsed = JSON.parse(entry.content);
|
|
723
|
+
fileContent = JSON.stringify(fileParsed, sortedJsonReplacer, 2);
|
|
724
|
+
if (options.format === "yaml") {
|
|
725
|
+
fileContent = jsonToYaml(JSON.parse(fileContent));
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
catch {
|
|
729
|
+
// If not JSON, write as-is
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
const targetPath = join(outputDir, filename);
|
|
733
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
734
|
+
writeFileSync(targetPath, fileContent);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
catch (err) {
|
|
739
|
+
errors.push(formatError({
|
|
740
|
+
message: `Failed to write output file: ${err instanceof Error ? err.message : String(err)}`,
|
|
741
|
+
}));
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
else if (secretFiles.size > 0) {
|
|
745
|
+
// A build carrying committed ciphertext and no --output has nowhere to
|
|
746
|
+
// put the sidecar. Echoing it to a terminal is not useful and dropping
|
|
747
|
+
// it silently is worse: the primary output would reference a Secret
|
|
748
|
+
// whose file never got written, and the miss would surface as a pod
|
|
749
|
+
// failing to start, far from its cause. Refuse, naming the flag.
|
|
750
|
+
const names = [...secretFiles].sort().join(", ");
|
|
751
|
+
errors.push(formatError({
|
|
752
|
+
message: `This build emits committed-encrypted secret file(s) (${names}) as sidecars, ` +
|
|
753
|
+
`which need a directory to be written into. Re-run with --output <path> ` +
|
|
754
|
+
`(the sidecars land beside it).`,
|
|
755
|
+
}));
|
|
756
|
+
}
|
|
757
|
+
else {
|
|
758
|
+
// Print to stdout
|
|
759
|
+
console.log(output);
|
|
760
|
+
// Log additional files to stderr if any
|
|
761
|
+
for (const [filename, entry] of additionalFiles) {
|
|
762
|
+
console.error(`\n--- ${filename} ---`);
|
|
763
|
+
console.error(entry.content);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
const resourceCount = result.entities.size;
|
|
768
|
+
const fileCount = result.sourceFileCount;
|
|
769
|
+
// A build root (a lexicon's own source files, a rendered overlay) can declare everything without one .ts file.
|
|
770
|
+
if (fileCount === 0 && resourceCount === 0 && errors.length === 0) {
|
|
771
|
+
console.error(formatInfo("No source files found — create .ts files in the target directory"));
|
|
772
|
+
}
|
|
773
|
+
if (options.verbose && errors.length === 0) {
|
|
774
|
+
console.error(formatSuccess(`Built ${formatBold(String(resourceCount))} resources successfully`));
|
|
775
|
+
}
|
|
776
|
+
return {
|
|
777
|
+
success: errors.length === 0,
|
|
778
|
+
resourceCount,
|
|
779
|
+
fileCount,
|
|
780
|
+
errors,
|
|
781
|
+
warnings,
|
|
782
|
+
buildParams: paramsResolution.provenance,
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* `fold: 8 files folded, 13 ran (--verbose for reasons)` — the non-verbose
|
|
787
|
+
* report of a fold build's per-file decisions (#1424). The "(--verbose for
|
|
788
|
+
* reasons)" hint appears only when something ran, since that is the only case
|
|
789
|
+
* with a reason to read.
|
|
790
|
+
*/
|
|
791
|
+
export function summarizeFoldDecisions(decisions) {
|
|
792
|
+
const folded = decisions.filter((d) => d.mode === "fold").length;
|
|
793
|
+
const ran = decisions.length - folded;
|
|
794
|
+
const files = (n) => `${n} file${n === 1 ? "" : "s"}`;
|
|
795
|
+
const hint = ran > 0 ? " (--verbose for reasons)" : "";
|
|
796
|
+
return `fold: ${files(folded)} folded, ${ran} ran${hint}`;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* `chant build --fold --fold-rank`'s text report (chant #1083): blockers
|
|
800
|
+
* ranked by dominator retained-count, highest first, then the reverse-taint
|
|
801
|
+
* bucket (#1044) called out separately since the tree can't express that
|
|
802
|
+
* edge (see `../../discovery/fold-rank.ts`'s module doc).
|
|
803
|
+
*/
|
|
804
|
+
export function formatFoldRanking(ranking, infraPath) {
|
|
805
|
+
const rel = (file) => relative(infraPath, file) || file;
|
|
806
|
+
const lines = [];
|
|
807
|
+
if (ranking.blockers.length === 0) {
|
|
808
|
+
lines.push("fold-rank: no run-mode files to rank");
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
lines.push(`fold-rank: ${ranking.blockers.length} blocker(s), ${ranking.totalBlocked} file(s) blocked`);
|
|
812
|
+
for (const b of ranking.blockers) {
|
|
813
|
+
const via = b.topLevel ? "" : ` (behind ${rel(b.dominatedBy)})`;
|
|
814
|
+
const reason = b.reason ? ` — ${b.reason}` : "";
|
|
815
|
+
lines.push(` retained ${b.retained}: ${rel(b.file)}${via}${reason}`);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
if (ranking.reverseTainted.length > 0) {
|
|
819
|
+
lines.push(`fold-rank: ${ranking.reverseTainted.length} file(s) held back only by the reverse rule (#1044) — would fold in isolation, blocked by a run-mode importer, not modeled in the tree above:`);
|
|
820
|
+
for (const t of ranking.reverseTainted) {
|
|
821
|
+
lines.push(` ${rel(t.file)}`);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
return lines.join("\n");
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Simple JSON to YAML converter
|
|
828
|
+
*/
|
|
829
|
+
function jsonToYaml(obj, indent = 0) {
|
|
830
|
+
const spaces = " ".repeat(indent);
|
|
831
|
+
if (obj === null)
|
|
832
|
+
return "null";
|
|
833
|
+
if (obj === undefined)
|
|
834
|
+
return "~";
|
|
835
|
+
if (typeof obj === "boolean")
|
|
836
|
+
return obj ? "true" : "false";
|
|
837
|
+
if (typeof obj === "number")
|
|
838
|
+
return String(obj);
|
|
839
|
+
if (typeof obj === "string") {
|
|
840
|
+
// Quote strings that need it
|
|
841
|
+
if (obj.includes("\n") || obj.includes(":") || obj.includes("#")) {
|
|
842
|
+
return `"${obj.replace(/"/g, '\\"')}"`;
|
|
843
|
+
}
|
|
844
|
+
return obj;
|
|
845
|
+
}
|
|
846
|
+
if (Array.isArray(obj)) {
|
|
847
|
+
if (obj.length === 0)
|
|
848
|
+
return "[]";
|
|
849
|
+
return obj
|
|
850
|
+
.map((item) => `${spaces}- ${jsonToYaml(item, indent + 1).trimStart()}`)
|
|
851
|
+
.join("\n");
|
|
852
|
+
}
|
|
853
|
+
if (typeof obj === "object") {
|
|
854
|
+
const entries = Object.entries(obj).sort(([a], [b]) => a.localeCompare(b));
|
|
855
|
+
if (entries.length === 0)
|
|
856
|
+
return "{}";
|
|
857
|
+
return entries
|
|
858
|
+
.map(([key, value]) => {
|
|
859
|
+
const yamlValue = jsonToYaml(value, indent + 1);
|
|
860
|
+
// A non-empty container (object OR array) renders as a block: the key on
|
|
861
|
+
// its own line, the value indented beneath it. Arrays were previously
|
|
862
|
+
// excluded here, which inlined `Tags: - Key: t` as invalid YAML.
|
|
863
|
+
const isContainer = typeof value === "object" && value !== null;
|
|
864
|
+
const isEmpty = isContainer && (Array.isArray(value) ? value.length === 0 : Object.keys(value).length === 0);
|
|
865
|
+
if (isContainer && !isEmpty) {
|
|
866
|
+
return `${spaces}${key}:\n${yamlValue}`;
|
|
867
|
+
}
|
|
868
|
+
return `${spaces}${key}: ${yamlValue.trimStart()}`;
|
|
869
|
+
})
|
|
870
|
+
.join("\n");
|
|
871
|
+
}
|
|
872
|
+
return String(obj);
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Print errors to stderr
|
|
876
|
+
*/
|
|
877
|
+
export function printErrors(errors) {
|
|
878
|
+
for (const error of errors) {
|
|
879
|
+
console.error(error);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Print warnings to stderr
|
|
884
|
+
*/
|
|
885
|
+
export function printWarnings(warnings) {
|
|
886
|
+
for (const warning of warnings) {
|
|
887
|
+
console.error(warning);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* Run build in watch mode. Runs an initial build, then watches for changes
|
|
892
|
+
* and triggers rebuilds. Returns a cleanup function.
|
|
893
|
+
*/
|
|
894
|
+
export function buildCommandWatch(options, onRebuild) {
|
|
895
|
+
const infraPath = resolve(options.path);
|
|
896
|
+
console.error(formatInfo(`[${formatTimestamp()}] Watching for changes...`));
|
|
897
|
+
// Run initial build
|
|
898
|
+
buildCommand(options).then((result) => {
|
|
899
|
+
printWarnings(result.warnings);
|
|
900
|
+
printErrors(result.errors);
|
|
901
|
+
onRebuild?.(result);
|
|
902
|
+
console.error(formatInfo(`[${formatTimestamp()}] Waiting for changes...`));
|
|
903
|
+
});
|
|
904
|
+
// Watch for changes and trigger rebuilds
|
|
905
|
+
const cleanup = watchDirectory(infraPath, async (changedFiles) => {
|
|
906
|
+
console.error("");
|
|
907
|
+
console.error(formatInfo(`[${formatTimestamp()}] Changes detected: ${formatChangedFiles(changedFiles, infraPath)}`));
|
|
908
|
+
try {
|
|
909
|
+
const result = await buildCommand(options);
|
|
910
|
+
printWarnings(result.warnings);
|
|
911
|
+
printErrors(result.errors);
|
|
912
|
+
onRebuild?.(result);
|
|
913
|
+
}
|
|
914
|
+
catch (err) {
|
|
915
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
916
|
+
}
|
|
917
|
+
console.error(formatInfo(`[${formatTimestamp()}] Waiting for changes...`));
|
|
918
|
+
});
|
|
919
|
+
return cleanup;
|
|
920
|
+
}
|