@intentius/chant 0.124.12 → 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.d.ts +36 -4
- package/dist/gate-decision.d.ts.map +1 -1
- 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.d.ts +8 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- 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.d.ts +1 -1
- package/dist/op/op-waves-run.d.ts.map +1 -1
- 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.d.ts +65 -0
- package/dist/workspace/identity-gate-rule.d.ts.map +1 -0
- package/dist/workspace/identity-gate-rule.js +75 -0
- package/dist/workspace/identity.d.ts +4 -2
- package/dist/workspace/identity.d.ts.map +1 -1
- 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.d.ts +3 -14
- package/dist/workspace/principal-classes.d.ts.map +1 -1
- 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 +36 -6
- 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/gate-decision-bundle.test.ts +3 -2
- package/src/gate-decision-identity.test.ts +176 -0
- package/src/gate-decision.ts +100 -22
- package/src/lexicon-module.ts +3 -0
- package/src/lifecycle/gate-ledger.ts +8 -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/op/op-waves-point.test.ts +1 -0
- package/src/op/op-waves-run.ts +5 -4
- package/src/op/op-waves.test.ts +14 -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/identity-gate-rule.ts +109 -0
- package/src/workspace/identity.ts +8 -18
- 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 +5 -30
package/dist/cli/main.js
ADDED
|
@@ -0,0 +1,2540 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { isEntryPoint } from "./is-entry-point.js";
|
|
4
|
+
import { formatError } from "./format.js";
|
|
5
|
+
import { resolveCommand } from "./registry.js";
|
|
6
|
+
import { loadChantConfigUpward } from "../config.js";
|
|
7
|
+
import { findProjectRoot, findWorkspaceRoot } from "../project-root.js";
|
|
8
|
+
import { isNoLexiconDetected } from "../detectLexicon.js";
|
|
9
|
+
import { CHANT_VERSION } from "./version.js";
|
|
10
|
+
import { validateLexiconConfig, formatLexiconConfigProblems } from "../lexicon-config.js";
|
|
11
|
+
import { armSandboxConfigEvaluation } from "../config-sandbox.js";
|
|
12
|
+
import { armSandboxPolicyExecution } from "../lint/policy-import.js";
|
|
13
|
+
import { ENV_VAR, unknownEnvError } from "../env.js";
|
|
14
|
+
import { initRuntime } from "../runtime-adapter.js";
|
|
15
|
+
import { installCompiledCli } from "../ts-loader.js";
|
|
16
|
+
import { splitJoinedFlags, dispatchCommandGroup, collectCommandGroups, formatCommandGroupsHelp } from "./command-group.js";
|
|
17
|
+
const handlerModules = new Map();
|
|
18
|
+
function lazyHandler(load, pick) {
|
|
19
|
+
const handler = async (ctx) => pick(await load())(ctx);
|
|
20
|
+
handlerModules.set(handler, load);
|
|
21
|
+
return handler;
|
|
22
|
+
}
|
|
23
|
+
const buildHandlers = () => import("./handlers/build.js");
|
|
24
|
+
const runBuild = lazyHandler(buildHandlers, (m) => m.runBuild);
|
|
25
|
+
const lintHandlers = () => import("./handlers/lint.js");
|
|
26
|
+
const runLint = lazyHandler(lintHandlers, (m) => m.runLint);
|
|
27
|
+
const devHandlers = () => import("./handlers/dev.js");
|
|
28
|
+
const runDevGenerate = lazyHandler(devHandlers, (m) => m.runDevGenerate);
|
|
29
|
+
const runDevPublish = lazyHandler(devHandlers, (m) => m.runDevPublish);
|
|
30
|
+
const runDevOnboard = lazyHandler(devHandlers, (m) => m.runDevOnboard);
|
|
31
|
+
const runDevCheckLexicon = lazyHandler(devHandlers, (m) => m.runDevCheckLexicon);
|
|
32
|
+
const runDevSurfaceDiff = lazyHandler(devHandlers, (m) => m.runDevSurfaceDiff);
|
|
33
|
+
const runDevPinnedUpgrade = lazyHandler(devHandlers, (m) => m.runDevPinnedUpgrade);
|
|
34
|
+
const runDevRollingUpgrade = lazyHandler(devHandlers, (m) => m.runDevRollingUpgrade);
|
|
35
|
+
const runDevUnknown = lazyHandler(devHandlers, (m) => m.runDevUnknown);
|
|
36
|
+
const serveHandlers = () => import("./handlers/serve.js");
|
|
37
|
+
const runServeLsp = lazyHandler(serveHandlers, (m) => m.runServeLsp);
|
|
38
|
+
const runServeMcp = lazyHandler(serveHandlers, (m) => m.runServeMcp);
|
|
39
|
+
const runServeUnknown = lazyHandler(serveHandlers, (m) => m.runServeUnknown);
|
|
40
|
+
const initHandlers = () => import("./handlers/init.js");
|
|
41
|
+
const runInit = lazyHandler(initHandlers, (m) => m.runInit);
|
|
42
|
+
const runInitLexicon = lazyHandler(initHandlers, (m) => m.runInitLexicon);
|
|
43
|
+
const miscHandlers = () => import("./handlers/misc.js");
|
|
44
|
+
const runList = lazyHandler(miscHandlers, (m) => m.runList);
|
|
45
|
+
const runDescribe = lazyHandler(miscHandlers, (m) => m.runDescribe);
|
|
46
|
+
const runImport = lazyHandler(miscHandlers, (m) => m.runImport);
|
|
47
|
+
const runAudit = lazyHandler(miscHandlers, (m) => m.runAudit);
|
|
48
|
+
const runUpdate = lazyHandler(miscHandlers, (m) => m.runUpdate);
|
|
49
|
+
const runDoctor = lazyHandler(miscHandlers, (m) => m.runDoctor);
|
|
50
|
+
const vendorHandlers = () => import("./handlers/vendor.js");
|
|
51
|
+
const runVendor = lazyHandler(vendorHandlers, (m) => m.runVendor);
|
|
52
|
+
const migrateHandlers = () => import("./handlers/migrate.js");
|
|
53
|
+
const runMigrate = lazyHandler(migrateHandlers, (m) => m.runMigrate);
|
|
54
|
+
const carveHandlers = () => import("./handlers/carve.js");
|
|
55
|
+
const runCarveAdvise = lazyHandler(carveHandlers, (m) => m.runCarveAdvise);
|
|
56
|
+
const runCarveUnknown = lazyHandler(carveHandlers, (m) => m.runCarveUnknown);
|
|
57
|
+
const carveEmitHandlers = () => import("./handlers/carve-emit.js");
|
|
58
|
+
const runCarveEmit = lazyHandler(carveEmitHandlers, (m) => m.runCarveEmit);
|
|
59
|
+
const carveBridgeHandlers = () => import("./handlers/carve-bridge.js");
|
|
60
|
+
const runCarveBridge = lazyHandler(carveBridgeHandlers, (m) => m.runCarveBridge);
|
|
61
|
+
const carveApplyHandlers = () => import("./handlers/carve-apply.js");
|
|
62
|
+
const runCarveApply = lazyHandler(carveApplyHandlers, (m) => m.runCarveApply);
|
|
63
|
+
const carveStatusHandlers = () => import("./handlers/carve-status.js");
|
|
64
|
+
const runCarveStatus = lazyHandler(carveStatusHandlers, (m) => m.runCarveStatus);
|
|
65
|
+
const lifecycleHandlers = () => import("./handlers/lifecycle.js");
|
|
66
|
+
const runLifecycleSnapshot = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleSnapshot);
|
|
67
|
+
const runLifecycleShow = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleShow);
|
|
68
|
+
const runLifecycleDiff = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleDiff);
|
|
69
|
+
const runLifecycleRollback = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleRollback);
|
|
70
|
+
const runLifecyclePlan = lazyHandler(lifecycleHandlers, (m) => m.runLifecyclePlan);
|
|
71
|
+
const runLifecycleAffected = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleAffected);
|
|
72
|
+
const runLifecycleLog = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleLog);
|
|
73
|
+
const runLifecycleTeardown = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleTeardown);
|
|
74
|
+
const runLifecycleWhoami = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleWhoami);
|
|
75
|
+
const runLifecycleUnknown = lazyHandler(lifecycleHandlers, (m) => m.runLifecycleUnknown);
|
|
76
|
+
const componentsHandlers = () => import("./handlers/components.js");
|
|
77
|
+
const runComponentsStatus = lazyHandler(componentsHandlers, (m) => m.runComponentsStatus);
|
|
78
|
+
const runComponentsReleaseRecord = lazyHandler(componentsHandlers, (m) => m.runComponentsReleaseRecord);
|
|
79
|
+
const runComponentsExport = lazyHandler(componentsHandlers, (m) => m.runComponentsExport);
|
|
80
|
+
const runComponentsUnknown = lazyHandler(componentsHandlers, (m) => m.runComponentsUnknown);
|
|
81
|
+
const fanOutHandlers = () => import("./handlers/fan-out.js");
|
|
82
|
+
const runComponentsFanOut = lazyHandler(fanOutHandlers, (m) => m.runComponentsFanOut);
|
|
83
|
+
const promoteHandlers = () => import("./handlers/promote.js");
|
|
84
|
+
const runComponentsPromote = lazyHandler(promoteHandlers, (m) => m.runComponentsPromote);
|
|
85
|
+
const runComponentsRollback = lazyHandler(promoteHandlers, (m) => m.runComponentsRollback);
|
|
86
|
+
const runComponentsRedeploy = lazyHandler(promoteHandlers, (m) => m.runComponentsRedeploy);
|
|
87
|
+
const scenarioHandlers = () => import("./handlers/scenario.js");
|
|
88
|
+
const runScenarioCheck = lazyHandler(scenarioHandlers, (m) => m.runScenarioCheck);
|
|
89
|
+
const runScenarioUnknown = lazyHandler(scenarioHandlers, (m) => m.runScenarioUnknown);
|
|
90
|
+
const graphHandlers = () => import("./handlers/graph.js");
|
|
91
|
+
const runGraph = lazyHandler(graphHandlers, (m) => m.runGraph);
|
|
92
|
+
const explainHandlers = () => import("./handlers/explain.js");
|
|
93
|
+
const runExplain = lazyHandler(explainHandlers, (m) => m.runExplain);
|
|
94
|
+
const searchHandlers = () => import("./handlers/search.js");
|
|
95
|
+
const runSearch = lazyHandler(searchHandlers, (m) => m.runSearch);
|
|
96
|
+
const runHandlers = () => import("./handlers/run.js");
|
|
97
|
+
const runOp = lazyHandler(runHandlers, (m) => m.runOp);
|
|
98
|
+
const runOpList = lazyHandler(runHandlers, (m) => m.runOpList);
|
|
99
|
+
const runOpStatus = lazyHandler(runHandlers, (m) => m.runOpStatus);
|
|
100
|
+
const runOpApprove = lazyHandler(runHandlers, (m) => m.runOpApprove);
|
|
101
|
+
const runOpSignalRenamed = lazyHandler(runHandlers, (m) => m.runOpSignalRenamed);
|
|
102
|
+
const runOpCancel = lazyHandler(runHandlers, (m) => m.runOpCancel);
|
|
103
|
+
const runOpLog = lazyHandler(runHandlers, (m) => m.runOpLog);
|
|
104
|
+
const runWaveHandlers = () => import("./handlers/run-wave.js");
|
|
105
|
+
const runOpWaveCommand = lazyHandler(runWaveHandlers, (m) => m.runOpWaveCommand);
|
|
106
|
+
const operatorHandlers = () => import("./handlers/operator.js");
|
|
107
|
+
const runOperator = lazyHandler(operatorHandlers, (m) => m.runOperator);
|
|
108
|
+
const runOperatorStatus = lazyHandler(operatorHandlers, (m) => m.runOperatorStatus);
|
|
109
|
+
const runOperatorLog = lazyHandler(operatorHandlers, (m) => m.runOperatorLog);
|
|
110
|
+
const runApprove = lazyHandler(operatorHandlers, (m) => m.runApprove);
|
|
111
|
+
const emulatorHandlers = () => import("./handlers/emulator.js");
|
|
112
|
+
const runEmulator = lazyHandler(emulatorHandlers, (m) => m.runEmulator);
|
|
113
|
+
/** The lexicon plugin loader, which imports the lint, fold and build machinery: loaded when a command needs plugins (#3878). */
|
|
114
|
+
const loadPlugins = async (...a) => (await import("./plugins.js")).loadPlugins(...a);
|
|
115
|
+
const resolveProjectLexicons = async (...a) => (await import("./plugins.js")).resolveProjectLexicons(...a);
|
|
116
|
+
/**
|
|
117
|
+
* Long-form flags that are pure booleans in {@link parseArgs} — their branch
|
|
118
|
+
* below sets a field to `true` and never consumes a following array element.
|
|
119
|
+
* Used only to reject a joined `--flag=value` form for these (chant #1127):
|
|
120
|
+
* a boolean has no value to assign, and silently reinterpreting the joined
|
|
121
|
+
* value as the next positional argument (path, component name, ...) would be
|
|
122
|
+
* exactly the kind of silent misparse this issue exists to close. `--report`
|
|
123
|
+
* is deliberately excluded — it's context-sensitive (bare boolean vs a SARIF
|
|
124
|
+
* path, decided by lookahead), so a joined value for it is legitimate and
|
|
125
|
+
* already handled correctly once split.
|
|
126
|
+
*/
|
|
127
|
+
const BOOLEAN_FLAGS = new Set([
|
|
128
|
+
"--help",
|
|
129
|
+
"--open",
|
|
130
|
+
"--version",
|
|
131
|
+
"--agents",
|
|
132
|
+
"--agent",
|
|
133
|
+
"--all-projects",
|
|
134
|
+
"--force",
|
|
135
|
+
"--fix",
|
|
136
|
+
"--watch",
|
|
137
|
+
"--verbose",
|
|
138
|
+
"--live",
|
|
139
|
+
"--overlay",
|
|
140
|
+
"--explain",
|
|
141
|
+
"--owned",
|
|
142
|
+
"--verbatim",
|
|
143
|
+
"--apply-rewrites",
|
|
144
|
+
"--write",
|
|
145
|
+
"--strict",
|
|
146
|
+
"--validate",
|
|
147
|
+
"--use-composites",
|
|
148
|
+
"--composites",
|
|
149
|
+
"--stacks",
|
|
150
|
+
"--components",
|
|
151
|
+
"--up",
|
|
152
|
+
"--down",
|
|
153
|
+
"--include-dependents",
|
|
154
|
+
"--local",
|
|
155
|
+
"--json",
|
|
156
|
+
"--progress-json",
|
|
157
|
+
"--update-snapshot",
|
|
158
|
+
"--update-baseline",
|
|
159
|
+
"--run-examples",
|
|
160
|
+
"--check",
|
|
161
|
+
"--bump",
|
|
162
|
+
"--no-release-record",
|
|
163
|
+
"--fold",
|
|
164
|
+
"--no-fold",
|
|
165
|
+
"--no-cache",
|
|
166
|
+
"--sandbox",
|
|
167
|
+
"--yes",
|
|
168
|
+
"--confirm-prod",
|
|
169
|
+
"--once",
|
|
170
|
+
"--expire",
|
|
171
|
+
"--check-live",
|
|
172
|
+
"--check-snapshot",
|
|
173
|
+
"--fail-on-drift",
|
|
174
|
+
"--durable-requests",
|
|
175
|
+
"--skip-mcp",
|
|
176
|
+
"--current",
|
|
177
|
+
"--uncommitted",
|
|
178
|
+
"--allow-code",
|
|
179
|
+
"--root-only",
|
|
180
|
+
"--generated",
|
|
181
|
+
"--decide",
|
|
182
|
+
"--record-plans",
|
|
183
|
+
]);
|
|
184
|
+
/**
|
|
185
|
+
* Parse command line arguments
|
|
186
|
+
*/
|
|
187
|
+
export function parseArgs(args) {
|
|
188
|
+
// Local mutable copy — chant #1127's joined-`--flag=value` splitting below
|
|
189
|
+
// rewrites the array in place (one token becomes two), so this must not
|
|
190
|
+
// mutate whatever array the caller passed in (e.g. `process.argv.slice(2)`
|
|
191
|
+
// is already a fresh copy, but callers shouldn't have to know that).
|
|
192
|
+
args = args.slice();
|
|
193
|
+
const result = {
|
|
194
|
+
command: "",
|
|
195
|
+
path: ".",
|
|
196
|
+
extraPositional: undefined,
|
|
197
|
+
extraPositional2: undefined,
|
|
198
|
+
output: undefined,
|
|
199
|
+
format: "",
|
|
200
|
+
force: undefined,
|
|
201
|
+
fix: false,
|
|
202
|
+
lexicon: undefined,
|
|
203
|
+
template: undefined,
|
|
204
|
+
watch: false,
|
|
205
|
+
verbose: false,
|
|
206
|
+
help: false,
|
|
207
|
+
param: undefined,
|
|
208
|
+
paramsFile: undefined,
|
|
209
|
+
report: undefined,
|
|
210
|
+
local: undefined,
|
|
211
|
+
profile: undefined,
|
|
212
|
+
json: undefined,
|
|
213
|
+
live: false,
|
|
214
|
+
migrateFrom: undefined,
|
|
215
|
+
migrateTo: undefined,
|
|
216
|
+
emit: undefined,
|
|
217
|
+
strict: false,
|
|
218
|
+
validate: false,
|
|
219
|
+
useComposites: false,
|
|
220
|
+
reportFile: undefined,
|
|
221
|
+
skill: undefined,
|
|
222
|
+
skipMcp: undefined,
|
|
223
|
+
src: undefined,
|
|
224
|
+
env: undefined,
|
|
225
|
+
};
|
|
226
|
+
// chant #1127 — generic joined `--flag=value` support, factored out to
|
|
227
|
+
// ./command-group.ts (chant #1078) so a lexicon's own mounted command can
|
|
228
|
+
// apply the identical splitting discipline to its own flag vocabulary.
|
|
229
|
+
// Every value-taking flag below is matched by an exact `arg === "--flag"`
|
|
230
|
+
// check and then consumes the *next* array element (`args[++i]`) as its
|
|
231
|
+
// value; a joined token like `--env=prod` never matches any of those,
|
|
232
|
+
// doesn't match the trailing positional branch either (it starts with
|
|
233
|
+
// `-`), and used to vanish with no error. Splitting the token at its FIRST
|
|
234
|
+
// `=` and re-dispatching as two array elements makes every flag below see
|
|
235
|
+
// the exact shape it already handles — including a flag like `--param`
|
|
236
|
+
// whose own value legitimately contains `=` (`--param=tier=production`
|
|
237
|
+
// splits to flag `--param`, value `tier=production`, not further split on
|
|
238
|
+
// the second `=`).
|
|
239
|
+
args = splitJoinedFlags(args, BOOLEAN_FLAGS);
|
|
240
|
+
let i = 0;
|
|
241
|
+
while (i < args.length) {
|
|
242
|
+
const arg = args[i];
|
|
243
|
+
if (arg === "--help" || arg === "-h") {
|
|
244
|
+
result.help = true;
|
|
245
|
+
}
|
|
246
|
+
else if (arg === "--version" || arg === "-V") {
|
|
247
|
+
result.version = true;
|
|
248
|
+
}
|
|
249
|
+
else if (arg === "--output" || arg === "-o") {
|
|
250
|
+
result.output = args[++i];
|
|
251
|
+
}
|
|
252
|
+
else if (arg === "--format" || arg === "-f") {
|
|
253
|
+
result.format = args[++i];
|
|
254
|
+
}
|
|
255
|
+
else if (arg === "--lexicon" || arg === "-d") {
|
|
256
|
+
result.lexicon = args[++i];
|
|
257
|
+
}
|
|
258
|
+
else if (arg === "--template" || arg === "-t") {
|
|
259
|
+
result.template = args[++i];
|
|
260
|
+
}
|
|
261
|
+
else if (arg === "--force") {
|
|
262
|
+
result.force = true;
|
|
263
|
+
}
|
|
264
|
+
else if (arg === "--fix") {
|
|
265
|
+
result.fix = true;
|
|
266
|
+
}
|
|
267
|
+
else if (arg === "--watch" || arg === "-w") {
|
|
268
|
+
result.watch = true;
|
|
269
|
+
}
|
|
270
|
+
else if (arg === "--verbose" || arg === "-v") {
|
|
271
|
+
result.verbose = true;
|
|
272
|
+
}
|
|
273
|
+
else if (arg === "--profile" || arg === "-p") {
|
|
274
|
+
result.profile = args[++i];
|
|
275
|
+
}
|
|
276
|
+
else if (arg === "--report") {
|
|
277
|
+
// --report alone is the boolean (used by `run`); --report <path> is
|
|
278
|
+
// the migrate-command file path. Look ahead for a non-flag.
|
|
279
|
+
const next = args[i + 1];
|
|
280
|
+
if (next && !next.startsWith("-")) {
|
|
281
|
+
result.reportFile = next;
|
|
282
|
+
i++;
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
result.report = true;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else if (arg === "--live") {
|
|
289
|
+
result.live = true;
|
|
290
|
+
}
|
|
291
|
+
else if (arg === "--overlay") {
|
|
292
|
+
result.overlay = true;
|
|
293
|
+
}
|
|
294
|
+
else if (arg === "--between") {
|
|
295
|
+
result.betweenA = args[++i];
|
|
296
|
+
result.betweenB = args[++i];
|
|
297
|
+
if (!result.betweenA || !result.betweenB)
|
|
298
|
+
throw new Error("--between needs two snapshot refs: --between <refA> <refB>");
|
|
299
|
+
}
|
|
300
|
+
else if (arg === "--traffic") {
|
|
301
|
+
const v = args[++i];
|
|
302
|
+
if (!v)
|
|
303
|
+
throw new Error('--traffic needs a level, passed to the engine verbatim: --traffic "100 rps, p50"');
|
|
304
|
+
result.traffic = v;
|
|
305
|
+
}
|
|
306
|
+
else if (arg === "--overlay-anchor") {
|
|
307
|
+
const v = args[++i];
|
|
308
|
+
if (v !== "source" && v !== "live")
|
|
309
|
+
throw new Error(`--overlay-anchor must be 'source' or 'live', got '${v}'`);
|
|
310
|
+
result.overlayAnchor = v;
|
|
311
|
+
}
|
|
312
|
+
else if (arg === "--from") {
|
|
313
|
+
// Shared by `migrate --from <lexicon>`, `import --from <env>`,
|
|
314
|
+
// `components promote --from <env>` and `init --from <repo>@<ref>`;
|
|
315
|
+
// the commands never run together, so one field carries all four.
|
|
316
|
+
result.migrateFrom = args[++i];
|
|
317
|
+
}
|
|
318
|
+
else if (arg === "--kustomize") {
|
|
319
|
+
// `chant import --kustomize <dir>` (#1548): render the overlay, import
|
|
320
|
+
// the output through the k8s template parser.
|
|
321
|
+
result.kustomize = args[++i];
|
|
322
|
+
}
|
|
323
|
+
else if (arg === "--parser-option") {
|
|
324
|
+
// `chant import --parser-option key[=value]` (#2994), repeatable: checked
|
|
325
|
+
// against the lexicon's parserOptions() by the import command.
|
|
326
|
+
const v = args[++i];
|
|
327
|
+
if (!v || v.startsWith("-"))
|
|
328
|
+
throw new Error("--parser-option needs key or key=value: --parser-option acceptLossyV1");
|
|
329
|
+
(result.parserOption ?? (result.parserOption = [])).push(v);
|
|
330
|
+
}
|
|
331
|
+
else if (arg === "--type") {
|
|
332
|
+
result.selectType = args[++i];
|
|
333
|
+
}
|
|
334
|
+
else if (arg === "--name") {
|
|
335
|
+
result.selectName = args[++i];
|
|
336
|
+
}
|
|
337
|
+
else if (arg === "--owned") {
|
|
338
|
+
result.owned = true;
|
|
339
|
+
}
|
|
340
|
+
else if (arg === "--namespace") {
|
|
341
|
+
// The live read's namespace default (#1629), not a kubectl `-n`: it fills
|
|
342
|
+
// in for entities that declare no namespace and leaves the ones that do
|
|
343
|
+
// alone. No `-n` short form — that spelling belongs to `chant kube`,
|
|
344
|
+
// where it means kubectl's scope selector.
|
|
345
|
+
result.namespace = args[++i];
|
|
346
|
+
if (!result.namespace || result.namespace.startsWith("-"))
|
|
347
|
+
throw new Error("--namespace needs a namespace: --namespace <ns>");
|
|
348
|
+
}
|
|
349
|
+
else if (arg === "--verbatim") {
|
|
350
|
+
result.verbatim = true;
|
|
351
|
+
}
|
|
352
|
+
else if (arg === "--state") {
|
|
353
|
+
result.statePath = args[++i];
|
|
354
|
+
}
|
|
355
|
+
else if (arg === "--select") {
|
|
356
|
+
result.selectAddress = args[++i];
|
|
357
|
+
}
|
|
358
|
+
else if (arg === "--live-name") {
|
|
359
|
+
result.liveName = args[++i];
|
|
360
|
+
}
|
|
361
|
+
else if (arg === "--apply-rewrites") {
|
|
362
|
+
result.applyRewrites = true;
|
|
363
|
+
}
|
|
364
|
+
else if (arg === "--stack") {
|
|
365
|
+
result.carveStack = args[++i];
|
|
366
|
+
}
|
|
367
|
+
else if (arg === "--write") {
|
|
368
|
+
result.write = true;
|
|
369
|
+
}
|
|
370
|
+
else if (arg === "--write-source") {
|
|
371
|
+
result.writeSource = true;
|
|
372
|
+
}
|
|
373
|
+
else if (arg === "--to") {
|
|
374
|
+
result.migrateTo = args[++i];
|
|
375
|
+
}
|
|
376
|
+
else if (arg === "--emit") {
|
|
377
|
+
result.emit = args[++i];
|
|
378
|
+
}
|
|
379
|
+
else if (arg === "--dry-run") {
|
|
380
|
+
result.dryRun = true;
|
|
381
|
+
}
|
|
382
|
+
else if (arg === "--yes") {
|
|
383
|
+
result.yes = true;
|
|
384
|
+
}
|
|
385
|
+
else if (arg === "--confirm-prod") {
|
|
386
|
+
result.confirmProd = true;
|
|
387
|
+
}
|
|
388
|
+
else if (arg === "--strict") {
|
|
389
|
+
result.strict = true;
|
|
390
|
+
}
|
|
391
|
+
else if (arg === "--validate") {
|
|
392
|
+
result.validate = true;
|
|
393
|
+
}
|
|
394
|
+
else if (arg === "--use-composites") {
|
|
395
|
+
result.useComposites = true;
|
|
396
|
+
}
|
|
397
|
+
else if (arg === "--skill") {
|
|
398
|
+
result.skill = args[++i];
|
|
399
|
+
}
|
|
400
|
+
else if (arg === "--skip-mcp") {
|
|
401
|
+
result.skipMcp = true;
|
|
402
|
+
}
|
|
403
|
+
else if (arg === "--src") {
|
|
404
|
+
result.src = args[++i];
|
|
405
|
+
}
|
|
406
|
+
else if (arg === "--env") {
|
|
407
|
+
result.env = args[++i];
|
|
408
|
+
}
|
|
409
|
+
else if (arg === "--port") {
|
|
410
|
+
const value = args[++i];
|
|
411
|
+
if (!value || value.startsWith("-"))
|
|
412
|
+
throw new Error("--port needs a port: --port <container-port>=<host-port>");
|
|
413
|
+
(result.port ?? (result.port = [])).push(value);
|
|
414
|
+
}
|
|
415
|
+
else if (arg === "--promote-to") {
|
|
416
|
+
result.promoteTo = args[++i];
|
|
417
|
+
if (!result.promoteTo || result.promoteTo.startsWith("-"))
|
|
418
|
+
throw new Error("--promote-to needs an environment: --promote-to <env>");
|
|
419
|
+
}
|
|
420
|
+
else if (arg === "--tier") {
|
|
421
|
+
result.tier = args[++i];
|
|
422
|
+
}
|
|
423
|
+
else if (arg === "--agents") {
|
|
424
|
+
result.agents = true;
|
|
425
|
+
}
|
|
426
|
+
else if (arg === "--scope") {
|
|
427
|
+
result.scope = args[++i];
|
|
428
|
+
}
|
|
429
|
+
else if (arg === "--all-projects") {
|
|
430
|
+
result.allProjects = true;
|
|
431
|
+
}
|
|
432
|
+
else if (arg === "--runtime") {
|
|
433
|
+
result.runtime = args[++i];
|
|
434
|
+
}
|
|
435
|
+
else if (arg === "--fail-on") {
|
|
436
|
+
result.failOn = args[++i];
|
|
437
|
+
}
|
|
438
|
+
else if (arg === "--max-files") {
|
|
439
|
+
// Validated by the audit handler, like `--limit` below.
|
|
440
|
+
result.maxFiles = Number(args[++i]);
|
|
441
|
+
}
|
|
442
|
+
else if (arg === "--theme") {
|
|
443
|
+
result.theme = args[++i];
|
|
444
|
+
}
|
|
445
|
+
else if (arg === "--stacks") {
|
|
446
|
+
result.stacks = true;
|
|
447
|
+
}
|
|
448
|
+
else if (arg === "--components") {
|
|
449
|
+
result.components = true;
|
|
450
|
+
}
|
|
451
|
+
else if (arg === "--generate") {
|
|
452
|
+
result.generate = args[++i];
|
|
453
|
+
}
|
|
454
|
+
else if (arg === "--spec") {
|
|
455
|
+
result.opsSpec = args[++i];
|
|
456
|
+
}
|
|
457
|
+
else if (arg === "--dump-outputs") {
|
|
458
|
+
result.dumpOutputs = args[++i];
|
|
459
|
+
}
|
|
460
|
+
else if (arg === "--digest-file") {
|
|
461
|
+
result.digestFile = args[++i];
|
|
462
|
+
}
|
|
463
|
+
else if (arg === "--seed-outputs") {
|
|
464
|
+
(result.seedOutputs ?? (result.seedOutputs = [])).push(args[++i]);
|
|
465
|
+
}
|
|
466
|
+
else if (arg === "--detail") {
|
|
467
|
+
result.detail = Number(args[++i]);
|
|
468
|
+
}
|
|
469
|
+
else if (arg === "--lens") {
|
|
470
|
+
result.lens = args[++i];
|
|
471
|
+
}
|
|
472
|
+
else if (arg === "--explain") {
|
|
473
|
+
result.explain = true;
|
|
474
|
+
}
|
|
475
|
+
else if (arg === "--show") {
|
|
476
|
+
result.show = args[++i];
|
|
477
|
+
}
|
|
478
|
+
else if (arg === "--up") {
|
|
479
|
+
result.up = true;
|
|
480
|
+
}
|
|
481
|
+
else if (arg === "--down") {
|
|
482
|
+
result.down = true;
|
|
483
|
+
}
|
|
484
|
+
else if (arg === "--node-sizes") {
|
|
485
|
+
result.nodeSizes = args[++i];
|
|
486
|
+
}
|
|
487
|
+
else if (arg === "--layout-engine") {
|
|
488
|
+
result.layoutEngine = args[++i];
|
|
489
|
+
}
|
|
490
|
+
else if (arg === "--base") {
|
|
491
|
+
result.base = args[++i];
|
|
492
|
+
}
|
|
493
|
+
else if (arg === "--head") {
|
|
494
|
+
result.head = args[++i];
|
|
495
|
+
}
|
|
496
|
+
else if (arg === "--include-dependents") {
|
|
497
|
+
result.includeDependents = true;
|
|
498
|
+
}
|
|
499
|
+
else if (arg === "--from-affected") {
|
|
500
|
+
result.fromAffected = args[++i];
|
|
501
|
+
}
|
|
502
|
+
else if (arg === "--gate") {
|
|
503
|
+
result.gate = args[++i];
|
|
504
|
+
}
|
|
505
|
+
else if (arg === "--wave-gate") {
|
|
506
|
+
result.waveGate = args[++i];
|
|
507
|
+
if (!result.waveGate || result.waveGate.startsWith("-"))
|
|
508
|
+
throw new Error("--wave-gate needs a gate name: --wave-gate <name>");
|
|
509
|
+
}
|
|
510
|
+
else if (arg === "--wave") {
|
|
511
|
+
const raw = args[++i];
|
|
512
|
+
const wave = Number(raw);
|
|
513
|
+
if (!Number.isInteger(wave) || wave < 1)
|
|
514
|
+
throw new Error(`--wave needs a wave number from 1: got "${raw ?? ""}"`);
|
|
515
|
+
result.wave = wave;
|
|
516
|
+
}
|
|
517
|
+
else if (arg === "--decide") {
|
|
518
|
+
result.decide = true;
|
|
519
|
+
}
|
|
520
|
+
else if (arg === "--record-plans") {
|
|
521
|
+
result.recordPlans = true;
|
|
522
|
+
}
|
|
523
|
+
else if (arg === "--share") {
|
|
524
|
+
const raw = args[++i];
|
|
525
|
+
const share = Number(raw);
|
|
526
|
+
if (!Number.isInteger(share) || share < 1)
|
|
527
|
+
throw new Error(`--share needs a share number from 1: got "${raw ?? ""}"`);
|
|
528
|
+
result.share = share;
|
|
529
|
+
}
|
|
530
|
+
else if (arg === "--canary") {
|
|
531
|
+
const raw = args[++i];
|
|
532
|
+
if (!raw || raw.startsWith("-"))
|
|
533
|
+
throw new Error("--canary needs a component name: --canary <name>[,<name>...]");
|
|
534
|
+
(result.canary ?? (result.canary = [])).push(...raw.split(",").map((n) => n.trim()).filter(Boolean));
|
|
535
|
+
}
|
|
536
|
+
else if (arg === "--pr") {
|
|
537
|
+
const raw = args[++i];
|
|
538
|
+
const pr = Number(raw);
|
|
539
|
+
if (!Number.isInteger(pr) || pr < 1)
|
|
540
|
+
throw new Error(`--pr needs a pull or merge request number: got "${raw ?? ""}"`);
|
|
541
|
+
result.pr = pr;
|
|
542
|
+
}
|
|
543
|
+
else if (arg === "--forge") {
|
|
544
|
+
result.forge = args[++i];
|
|
545
|
+
if (!result.forge || result.forge.startsWith("-"))
|
|
546
|
+
throw new Error("--forge needs a forge: --forge github|gitlab|forgejo");
|
|
547
|
+
}
|
|
548
|
+
else if (arg === "--require-review") {
|
|
549
|
+
result.requireReview = true;
|
|
550
|
+
}
|
|
551
|
+
else if (arg === "--pr-loop") {
|
|
552
|
+
result.prLoop = true;
|
|
553
|
+
}
|
|
554
|
+
else if (arg === "--resume") {
|
|
555
|
+
// `chant approve <op> <gate> --resume` (#3683) takes no value; the
|
|
556
|
+
// fan-out and pull-request apply take the attempt file they resume.
|
|
557
|
+
const next = args[i + 1];
|
|
558
|
+
if (next === undefined || next.startsWith("-"))
|
|
559
|
+
result.resumeRun = true;
|
|
560
|
+
else
|
|
561
|
+
result.resume = args[++i];
|
|
562
|
+
}
|
|
563
|
+
else if (arg === "--local") {
|
|
564
|
+
result.local = true;
|
|
565
|
+
}
|
|
566
|
+
else if (arg === "--json") {
|
|
567
|
+
result.json = true;
|
|
568
|
+
}
|
|
569
|
+
else if (arg === "--progress-json") {
|
|
570
|
+
result.progressJson = true;
|
|
571
|
+
}
|
|
572
|
+
else if (arg === "--gated-exit") {
|
|
573
|
+
// `chant run <op> --gated-exit <code>` (#2243) — remap only the gated
|
|
574
|
+
// outcome's exit code. Parsed as a number here and range-checked in the
|
|
575
|
+
// handler, where the refusal can name the flag alongside the run.
|
|
576
|
+
result.gatedExit = Number(args[++i]);
|
|
577
|
+
}
|
|
578
|
+
else if (arg === "--durable-requests") {
|
|
579
|
+
// `chant run approve ... --on <lexicon> --durable-requests` (#2126) —
|
|
580
|
+
// resolve the gate on the hosting runtime's own request path rather
|
|
581
|
+
// than by posting a follow-up prompt. Core only carries the flag; the
|
|
582
|
+
// runtime decides whether it has such a path.
|
|
583
|
+
result.durableRequests = true;
|
|
584
|
+
}
|
|
585
|
+
else if (arg === "--update-snapshot") {
|
|
586
|
+
result.updateSnapshot = true;
|
|
587
|
+
}
|
|
588
|
+
else if (arg === "--update-baseline") {
|
|
589
|
+
result.updateBaseline = true;
|
|
590
|
+
}
|
|
591
|
+
else if (arg === "--deep") {
|
|
592
|
+
result.deep = true;
|
|
593
|
+
}
|
|
594
|
+
else if (arg === "--at") {
|
|
595
|
+
result.at = args[++i];
|
|
596
|
+
}
|
|
597
|
+
else if (arg === "--kind") {
|
|
598
|
+
// `chant workspace records|graph|check --kind <kind file>` (#2546, #2549)
|
|
599
|
+
result.kind = args[++i];
|
|
600
|
+
if (!result.kind || result.kind.startsWith("-"))
|
|
601
|
+
throw new Error("--kind needs a kind file: --kind <path>");
|
|
602
|
+
// Repeatable for `workspace graph --intent` (#2651); the others read the last one.
|
|
603
|
+
(result.kinds ?? (result.kinds = [])).push(result.kind);
|
|
604
|
+
}
|
|
605
|
+
else if (arg === "--composites") {
|
|
606
|
+
// `chant workspace graph --composites` (#2662)
|
|
607
|
+
result.composites = true;
|
|
608
|
+
}
|
|
609
|
+
else if (arg === "--intent") {
|
|
610
|
+
// `chant workspace graph --intent <path[:start-end]|path#symbol>` (#2651), or `--intent --record <id>` with no region.
|
|
611
|
+
const value = args[i + 1];
|
|
612
|
+
if (value !== undefined && !value.startsWith("-"))
|
|
613
|
+
result.intent = args[++i];
|
|
614
|
+
else if (args.includes("--record"))
|
|
615
|
+
result.intent = "";
|
|
616
|
+
else
|
|
617
|
+
throw new Error("--intent needs a region: --intent <path[:start-end]|path#symbol>, or --intent --record <id>");
|
|
618
|
+
}
|
|
619
|
+
else if (arg === "--follow-squash") {
|
|
620
|
+
// `chant workspace graph --intent ... --follow-squash` and `chant workspace runs --follow-squash` (#3035)
|
|
621
|
+
result.followSquash = true;
|
|
622
|
+
}
|
|
623
|
+
else if (arg === "--record") {
|
|
624
|
+
// `chant workspace graph --intent --record <id>`
|
|
625
|
+
result.record = args[++i];
|
|
626
|
+
if (!result.record || result.record.startsWith("-"))
|
|
627
|
+
throw new Error("--record needs a record id: --record <id>");
|
|
628
|
+
}
|
|
629
|
+
else if (arg === "--path") {
|
|
630
|
+
// `chant workspace patch <range> --path <p>`, repeatable
|
|
631
|
+
const value = args[++i];
|
|
632
|
+
if (!value || value.startsWith("-"))
|
|
633
|
+
throw new Error("--path needs a path: --path <path>");
|
|
634
|
+
(result.paths ?? (result.paths = [])).push(value);
|
|
635
|
+
}
|
|
636
|
+
else if (arg === "--worktree") {
|
|
637
|
+
// `chant workspace patch [<commit>] --worktree`
|
|
638
|
+
result.worktree = true;
|
|
639
|
+
}
|
|
640
|
+
else if (arg === "--max-bytes") {
|
|
641
|
+
// `chant workspace patch <range> --max-bytes <n>`
|
|
642
|
+
const value = Number(args[++i]);
|
|
643
|
+
if (!Number.isInteger(value) || value < 1)
|
|
644
|
+
throw new Error("--max-bytes needs a whole number of bytes above 0");
|
|
645
|
+
result.maxBytes = value;
|
|
646
|
+
}
|
|
647
|
+
else if (arg === "--changes") {
|
|
648
|
+
// `chant workspace check --changes <base>..<head>` (#2773)
|
|
649
|
+
result.changes = args[++i];
|
|
650
|
+
if (!result.changes || result.changes.startsWith("-"))
|
|
651
|
+
throw new Error("--changes needs a range: --changes <base>..<head>");
|
|
652
|
+
}
|
|
653
|
+
else if (arg === "--severity") {
|
|
654
|
+
// `chant workspace check --changes <range> --severity off|warn|fail` (#2773)
|
|
655
|
+
result.severity = args[++i];
|
|
656
|
+
if (!result.severity || result.severity.startsWith("-"))
|
|
657
|
+
throw new Error("--severity needs off, warn or fail");
|
|
658
|
+
}
|
|
659
|
+
else if (arg === "--current") {
|
|
660
|
+
result.current = true;
|
|
661
|
+
}
|
|
662
|
+
else if (arg === "--uncommitted") {
|
|
663
|
+
// `chant workspace records --uncommitted` (#3160)
|
|
664
|
+
result.uncommitted = true;
|
|
665
|
+
}
|
|
666
|
+
else if (arg === "--set") {
|
|
667
|
+
// `chant workspace records amend <id> --set <file|->` (#2670)
|
|
668
|
+
result.set = args[++i];
|
|
669
|
+
if (!result.set || (result.set.startsWith("-") && result.set !== "-"))
|
|
670
|
+
throw new Error("--set needs a JSON file, or - for standard input: --set <file|->");
|
|
671
|
+
}
|
|
672
|
+
else if (arg === "--cover") {
|
|
673
|
+
// `chant workspace box listing set <member> --cover <image>` (#3308)
|
|
674
|
+
result.cover = args[++i];
|
|
675
|
+
if (!result.cover || result.cover.startsWith("-"))
|
|
676
|
+
throw new Error("--cover needs a PNG, JPEG or WebP file: --cover <image>");
|
|
677
|
+
}
|
|
678
|
+
else if (arg === "--cover-path") {
|
|
679
|
+
// `chant workspace box listing set <member> --cover <image> --cover-path <path>` (#3308)
|
|
680
|
+
result.coverPath = args[++i];
|
|
681
|
+
if (!result.coverPath || result.coverPath.startsWith("-"))
|
|
682
|
+
throw new Error("--cover-path needs a path from the workspace root: --cover-path <path>");
|
|
683
|
+
}
|
|
684
|
+
else if (arg === "--records") {
|
|
685
|
+
// `chant workspace box publish <member> --records` (#3165): the records kept uncommitted, not a work item.
|
|
686
|
+
result.records = true;
|
|
687
|
+
}
|
|
688
|
+
else if (arg === "--expect") {
|
|
689
|
+
// `chant workspace records amend|review|close <id> --expect <digest>` (#3173): the record's digest the caller last read.
|
|
690
|
+
result.expect = args[++i];
|
|
691
|
+
if (!result.expect || result.expect.startsWith("-"))
|
|
692
|
+
throw new Error("--expect needs the record's digest, as records --json prints it: --expect <digest>");
|
|
693
|
+
}
|
|
694
|
+
else if (arg === "--label") {
|
|
695
|
+
// `chant workspace wip save --label <text>` (#3172)
|
|
696
|
+
result.label = args[++i];
|
|
697
|
+
if (!result.label || result.label.startsWith("-"))
|
|
698
|
+
throw new Error("--label needs the snapshot's name, such as a turn id: --label <text>");
|
|
699
|
+
}
|
|
700
|
+
else if (arg === "--branch") {
|
|
701
|
+
// `chant workspace wip --branch <branch>` (#3172)
|
|
702
|
+
result.branch = args[++i];
|
|
703
|
+
if (!result.branch || result.branch.startsWith("-"))
|
|
704
|
+
throw new Error("--branch needs a branch name: --branch <branch>");
|
|
705
|
+
}
|
|
706
|
+
else if (arg === "--workflow") {
|
|
707
|
+
// `chant ci workflow --workflow <name>`, repeatable (#3573)
|
|
708
|
+
const name = args[++i];
|
|
709
|
+
if (!name || name.startsWith("-"))
|
|
710
|
+
throw new Error("--workflow needs a workflow's name: --workflow <name>");
|
|
711
|
+
result.ciWorkflows = [...(result.ciWorkflows ?? []), name];
|
|
712
|
+
}
|
|
713
|
+
else if (arg === "--chant") {
|
|
714
|
+
// `chant ci workflow --chant <command>` (#3573): what the tick step runs chant with.
|
|
715
|
+
result.ciChant = args[++i];
|
|
716
|
+
if (!result.ciChant || result.ciChant.startsWith("-"))
|
|
717
|
+
throw new Error("--chant needs the command that runs chant, such as \"npx tsx packages/core/src/cli/main.ts\": --chant <command>");
|
|
718
|
+
}
|
|
719
|
+
else if (arg === "--install") {
|
|
720
|
+
// `chant ci workflow --install <command>` (#3573): a step before the tick that installs what --chant runs.
|
|
721
|
+
result.ciInstall = args[++i];
|
|
722
|
+
if (!result.ciInstall || result.ciInstall.startsWith("-"))
|
|
723
|
+
throw new Error("--install needs the install command, such as \"npm install\": --install <command>");
|
|
724
|
+
}
|
|
725
|
+
else if (arg === "--token-secret") {
|
|
726
|
+
// `chant ci workflow --token-secret <NAME>` (#3573): the secret the tick's tag push authenticates with.
|
|
727
|
+
result.ciTokenSecret = args[++i];
|
|
728
|
+
if (!result.ciTokenSecret || result.ciTokenSecret.startsWith("-"))
|
|
729
|
+
throw new Error("--token-secret needs a repository secret's name, such as CI_GREEN_TOKEN: --token-secret <NAME>");
|
|
730
|
+
}
|
|
731
|
+
else if (arg === "--app-id-var") {
|
|
732
|
+
// `chant ci workflow --app-id-var <VAR> --app-key-secret <NAME>` (#3573): a GitHub App token pushes the tags.
|
|
733
|
+
result.ciAppIdVar = args[++i];
|
|
734
|
+
if (!result.ciAppIdVar || result.ciAppIdVar.startsWith("-"))
|
|
735
|
+
throw new Error("--app-id-var needs the Actions variable holding the App's id: --app-id-var <VAR>");
|
|
736
|
+
}
|
|
737
|
+
else if (arg === "--app-key-secret") {
|
|
738
|
+
result.ciAppKeySecret = args[++i];
|
|
739
|
+
if (!result.ciAppKeySecret || result.ciAppKeySecret.startsWith("-"))
|
|
740
|
+
throw new Error("--app-key-secret needs the secret holding the App's private key: --app-key-secret <NAME>");
|
|
741
|
+
}
|
|
742
|
+
else if (arg === "--verdict") {
|
|
743
|
+
// `chant workspace records review <id> --verdict agree|dissent|abstain` (#2670)
|
|
744
|
+
result.verdict = args[++i];
|
|
745
|
+
if (!result.verdict || result.verdict.startsWith("-"))
|
|
746
|
+
throw new Error("--verdict needs agree, dissent or abstain");
|
|
747
|
+
}
|
|
748
|
+
else if (arg === "--by") {
|
|
749
|
+
// `chant workspace records review <id> --by <principal>` (#2670): whoever the caller says.
|
|
750
|
+
result.by = args[++i];
|
|
751
|
+
if (!result.by || result.by.startsWith("-"))
|
|
752
|
+
throw new Error("--by needs the reviewer: --by <principal>");
|
|
753
|
+
// Repeatable for `workspace points answer` (#2739): each person who answered.
|
|
754
|
+
(result.bys ?? (result.bys = [])).push(result.by);
|
|
755
|
+
}
|
|
756
|
+
else if (arg === "--open") {
|
|
757
|
+
// `chant workspace points --open` (#2739): only the questions still open.
|
|
758
|
+
result.open = true;
|
|
759
|
+
}
|
|
760
|
+
else if (arg === "--inputs") {
|
|
761
|
+
// `chant workspace points ask <point> --inputs <file|-|json>` (#2739; JSON itself, #3403)
|
|
762
|
+
result.inputs = args[++i];
|
|
763
|
+
if (!result.inputs || (result.inputs.startsWith("-") && result.inputs !== "-"))
|
|
764
|
+
throw new Error("--inputs needs a JSON file, - for standard input, or the JSON itself: --inputs <file|-|json>");
|
|
765
|
+
}
|
|
766
|
+
else if (arg === "--candidates") {
|
|
767
|
+
// `chant workspace points ask <point> --candidates <file|-|json>` (#3403): an ad-hoc point's question and candidates.
|
|
768
|
+
result.candidates = args[++i];
|
|
769
|
+
if (!result.candidates || (result.candidates.startsWith("-") && result.candidates !== "-"))
|
|
770
|
+
throw new Error("--candidates needs a JSON file, - for standard input, or the JSON itself: --candidates <file|-|json>");
|
|
771
|
+
}
|
|
772
|
+
else if (arg === "--response") {
|
|
773
|
+
// `chant workspace points ask <point> --response <file>` (#2739): a POST /v1/systemone response the caller got.
|
|
774
|
+
result.response = args[++i];
|
|
775
|
+
if (!result.response || result.response.startsWith("-"))
|
|
776
|
+
throw new Error("--response needs a JSON file: --response <file>");
|
|
777
|
+
}
|
|
778
|
+
else if (arg === "--subject") {
|
|
779
|
+
// `chant workspace points ask <point> --subject <id>` (#2739): what the question is about.
|
|
780
|
+
result.subject = args[++i];
|
|
781
|
+
if (!result.subject || result.subject.startsWith("-"))
|
|
782
|
+
throw new Error("--subject needs what the question is about, such as a work item id: --subject <id>");
|
|
783
|
+
}
|
|
784
|
+
else if (arg === "--store") {
|
|
785
|
+
// `chant workspace points ask <point> --store ledger` (#3815): where a new question goes.
|
|
786
|
+
const store = args[++i];
|
|
787
|
+
if (store !== "tree" && store !== "ledger")
|
|
788
|
+
throw new Error("--store is tree (the answer kind's directory in the working tree) or ledger (chant/lifecycle): --store <tree|ledger>");
|
|
789
|
+
result.store = store;
|
|
790
|
+
}
|
|
791
|
+
else if (arg === "--answer") {
|
|
792
|
+
// `chant workspace points answer <id> --answer <value>` (#2739)
|
|
793
|
+
result.answer = args[++i];
|
|
794
|
+
if (result.answer === undefined || result.answer === "")
|
|
795
|
+
throw new Error("--answer needs one of the question's candidates: --answer <value>");
|
|
796
|
+
}
|
|
797
|
+
else if (arg === "--sign") {
|
|
798
|
+
// `chant workspace records review <id> --sign [<key file>]` (#2687): seal the verdict.
|
|
799
|
+
// `records new` and `records amend` take it too, to seal the record's author (#2688).
|
|
800
|
+
// `chant approve <op> <gate> --sign [<key file>]` seals a gate approval (#3163).
|
|
801
|
+
// With no key file, git's user.signingkey, as `git commit -S` reads it.
|
|
802
|
+
const next = args[i + 1];
|
|
803
|
+
result.sign = next !== undefined && !next.startsWith("-") ? args[++i] : true;
|
|
804
|
+
}
|
|
805
|
+
else if (arg === "--session") {
|
|
806
|
+
// `chant workspace records review <id> --session <id>` (#2670)
|
|
807
|
+
result.session = args[++i];
|
|
808
|
+
if (!result.session || result.session.startsWith("-"))
|
|
809
|
+
throw new Error("--session needs a session id: --session <id>");
|
|
810
|
+
}
|
|
811
|
+
else if (arg === "--prefix") {
|
|
812
|
+
// `chant workspace records new <kind> --prefix <prefix>` (#2670): the id prefix to allocate under.
|
|
813
|
+
result.prefix = args[++i];
|
|
814
|
+
if (!result.prefix || result.prefix.startsWith("-"))
|
|
815
|
+
throw new Error("--prefix needs an id prefix: --prefix <prefix>");
|
|
816
|
+
}
|
|
817
|
+
else if (arg === "--key" || arg === "--check-id" || arg === "--claim" || arg === "--environment" || arg === "--envelope" || arg === "--threshold") {
|
|
818
|
+
// `chant workspace evidence sign|verify` and `chant workspace signers` (#2553)
|
|
819
|
+
const value = args[++i];
|
|
820
|
+
if (value === undefined || value.startsWith("-"))
|
|
821
|
+
throw new Error(`${arg} needs a value`);
|
|
822
|
+
const field = { "--key": "key", "--check-id": "checkId", "--claim": "claim", "--environment": "environment", "--envelope": "envelope", "--threshold": "threshold" }[arg];
|
|
823
|
+
result[field] = value;
|
|
824
|
+
}
|
|
825
|
+
else if (arg === "--require") {
|
|
826
|
+
// `chant workspace records|verify --require attested` (#2547)
|
|
827
|
+
result.require = args[++i];
|
|
828
|
+
if (!result.require || result.require.startsWith("-"))
|
|
829
|
+
throw new Error("--require needs a provenance level: --require attested");
|
|
830
|
+
}
|
|
831
|
+
else if (arg === "--ambient") {
|
|
832
|
+
result.ambient = true;
|
|
833
|
+
}
|
|
834
|
+
else if (arg === "--check-live") {
|
|
835
|
+
result.checkLive = true;
|
|
836
|
+
}
|
|
837
|
+
else if (arg === "--check-snapshot") {
|
|
838
|
+
result.checkSnapshot = true;
|
|
839
|
+
}
|
|
840
|
+
else if (arg === "--fail-on-drift") {
|
|
841
|
+
result.failOnDrift = true;
|
|
842
|
+
}
|
|
843
|
+
else if (arg === "--run-examples") {
|
|
844
|
+
result.runExamples = true;
|
|
845
|
+
}
|
|
846
|
+
else if (arg === "--pinned-digest") {
|
|
847
|
+
result.pinnedDigest = args[++i];
|
|
848
|
+
}
|
|
849
|
+
else if (arg === "--check") {
|
|
850
|
+
result.check = true;
|
|
851
|
+
}
|
|
852
|
+
else if (arg === "--bump") {
|
|
853
|
+
result.bump = true;
|
|
854
|
+
}
|
|
855
|
+
else if (arg === "--component") {
|
|
856
|
+
result.component = args[++i];
|
|
857
|
+
}
|
|
858
|
+
else if (arg === "--digest") {
|
|
859
|
+
result.digest = args[++i];
|
|
860
|
+
if (result.digest !== undefined)
|
|
861
|
+
(result.digests ?? (result.digests = [])).push(result.digest);
|
|
862
|
+
}
|
|
863
|
+
else if (arg === "--release-plan") {
|
|
864
|
+
result.releasePlanFile = args[++i];
|
|
865
|
+
}
|
|
866
|
+
else if (arg === "--git-sha") {
|
|
867
|
+
result.gitSha = args[++i];
|
|
868
|
+
}
|
|
869
|
+
else if (arg === "--run-id") {
|
|
870
|
+
result.runId = args[++i];
|
|
871
|
+
}
|
|
872
|
+
else if (arg === "--actor") {
|
|
873
|
+
result.actor = args[++i];
|
|
874
|
+
}
|
|
875
|
+
else if (arg === "--approver") {
|
|
876
|
+
result.approver = args[++i];
|
|
877
|
+
}
|
|
878
|
+
else if (arg === "--relayed-by") {
|
|
879
|
+
// `chant approve <op> <gate> --relayed-by <principal>` and `workspace points answer <id> --relayed-by <principal>` (#3402):
|
|
880
|
+
// who carried the approval or answer to chant for the person it names.
|
|
881
|
+
result.relayedBy = args[++i];
|
|
882
|
+
if (!result.relayedBy || result.relayedBy.startsWith("-"))
|
|
883
|
+
throw new Error("--relayed-by needs the principal that relayed it: --relayed-by <principal>");
|
|
884
|
+
}
|
|
885
|
+
else if (arg === "--on") {
|
|
886
|
+
// `chant run ... --on <lexicon>` (#2121) — which runtime hosts the run.
|
|
887
|
+
result.on = args[++i];
|
|
888
|
+
if (!result.on || result.on.startsWith("-"))
|
|
889
|
+
throw new Error("--on needs a runtime name: --on <lexicon>");
|
|
890
|
+
}
|
|
891
|
+
else if (arg === "--compare-to") {
|
|
892
|
+
result.compareTo = args[++i];
|
|
893
|
+
}
|
|
894
|
+
else if (arg === "--no-release-record") {
|
|
895
|
+
result.noReleaseRecord = true;
|
|
896
|
+
}
|
|
897
|
+
else if (arg === "--fold") {
|
|
898
|
+
result.fold = true;
|
|
899
|
+
}
|
|
900
|
+
else if (arg === "--no-cache") {
|
|
901
|
+
// `chant workspace graph --no-cache` (#2876): read every member.
|
|
902
|
+
result.noCache = true;
|
|
903
|
+
}
|
|
904
|
+
else if (arg === "--no-fold") {
|
|
905
|
+
// chant #1134 — fold is the default build path; this is the explicit
|
|
906
|
+
// opt-out, and like --fold it beats chant.config.ts's build.fold.
|
|
907
|
+
result.fold = false;
|
|
908
|
+
}
|
|
909
|
+
else if (arg === "--sandbox") {
|
|
910
|
+
result.sandbox = true;
|
|
911
|
+
}
|
|
912
|
+
else if (arg === "--fold-rank") {
|
|
913
|
+
// chant #1083 — same context-sensitive shape as --report above:
|
|
914
|
+
// `--fold-rank` alone prints the ranked-blocker report; `--fold-rank
|
|
915
|
+
// <path>` ALSO writes the Brendan Gregg collapsed-format export there.
|
|
916
|
+
const next = args[i + 1];
|
|
917
|
+
if (next && !next.startsWith("-")) {
|
|
918
|
+
result.foldRankCollapsedFile = next;
|
|
919
|
+
i++;
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
result.foldRank = true;
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
else if (arg === "--param") {
|
|
926
|
+
// chant #1118/#1127 — `--param name=value` (space-separated) and
|
|
927
|
+
// `--param=name=value` (joined, split above at its first `=` into flag
|
|
928
|
+
// `--param` + value `name=value`) both land here and behave
|
|
929
|
+
// identically; there is no separate joined-form error anymore (the
|
|
930
|
+
// #1118 hard error this superseded only existed because the parser
|
|
931
|
+
// didn't support joined forms at all — now that it does, the joined
|
|
932
|
+
// form is just as valid as the space-separated one).
|
|
933
|
+
(result.param ?? (result.param = [])).push(args[++i]);
|
|
934
|
+
}
|
|
935
|
+
else if (arg === "--lexicon-output") {
|
|
936
|
+
// `--lexicon-output <lexicon>=<path>` (repeatable); the joined form
|
|
937
|
+
// `--lexicon-output=otel=a.yml` arrives here already split at the first `=`.
|
|
938
|
+
(result.lexiconOutput ?? (result.lexiconOutput = [])).push(args[++i]);
|
|
939
|
+
}
|
|
940
|
+
else if (arg === "--params-file") {
|
|
941
|
+
result.paramsFile = args[++i];
|
|
942
|
+
}
|
|
943
|
+
else if (arg === "--projection") {
|
|
944
|
+
result.projection = args[++i];
|
|
945
|
+
}
|
|
946
|
+
else if (arg === "--interval") {
|
|
947
|
+
result.interval = args[++i];
|
|
948
|
+
}
|
|
949
|
+
else if (arg === "--lease-ttl") {
|
|
950
|
+
result.leaseTtl = args[++i];
|
|
951
|
+
}
|
|
952
|
+
else if (arg === "--steward") {
|
|
953
|
+
// #2731 — the name is optional: a project with one steward runs it
|
|
954
|
+
// with a bare `--steward`.
|
|
955
|
+
const next = args[i + 1];
|
|
956
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
957
|
+
result.steward = next;
|
|
958
|
+
i++;
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
result.steward = "";
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
else if (arg === "--once") {
|
|
965
|
+
result.once = true;
|
|
966
|
+
}
|
|
967
|
+
else if (arg === "--work") {
|
|
968
|
+
// `chant run <op> --work <id>` (#2748)
|
|
969
|
+
const value = args[++i];
|
|
970
|
+
if (!value || value.startsWith("-"))
|
|
971
|
+
throw new Error("--work needs a work item id: --work <id>");
|
|
972
|
+
result.work = value;
|
|
973
|
+
}
|
|
974
|
+
else if (arg === "--holder" || arg === "--ttl" || arg === "--token" || arg === "--outcome") {
|
|
975
|
+
// `chant workspace work claim|renew|release <id>` (#2732)
|
|
976
|
+
const value = args[++i];
|
|
977
|
+
if (!value || value.startsWith("-"))
|
|
978
|
+
throw new Error(`${arg} needs a value: ${arg} <${arg.slice(2)}>`);
|
|
979
|
+
result[arg.slice(2)] = value;
|
|
980
|
+
}
|
|
981
|
+
else if (arg === "--signer") {
|
|
982
|
+
// `chant workspace runs statement <id> --signer <principal>` (#3192): the runner principal that will sign.
|
|
983
|
+
const value = args[++i];
|
|
984
|
+
if (!value || value.startsWith("-"))
|
|
985
|
+
throw new Error("--signer needs a principal: --signer <principal>");
|
|
986
|
+
result.signer = value;
|
|
987
|
+
}
|
|
988
|
+
else if (arg === "--unit" || arg === "--decision") {
|
|
989
|
+
// `chant workspace runs --unit <id> | --decision <id>` (#3033): the runs on one work item, or for one decision.
|
|
990
|
+
const value = args[++i];
|
|
991
|
+
if (!value || value.startsWith("-"))
|
|
992
|
+
throw new Error(`${arg} needs an id: ${arg} <id>`);
|
|
993
|
+
result[arg.slice(2)] = value;
|
|
994
|
+
}
|
|
995
|
+
else if (arg === "--note") {
|
|
996
|
+
result.note = args[++i];
|
|
997
|
+
}
|
|
998
|
+
else if (arg === "--reason") {
|
|
999
|
+
// `chant approve policy-override <subject> --reason <text>` (#3760): why the denied plan goes out anyway.
|
|
1000
|
+
result.reason = args[++i];
|
|
1001
|
+
if (result.reason === undefined || result.reason.startsWith("-"))
|
|
1002
|
+
throw new Error("--reason needs the text of the reason: --reason <text>");
|
|
1003
|
+
}
|
|
1004
|
+
else if (arg === "--rule") {
|
|
1005
|
+
// `chant approve policy-override <subject> --rule <id>` (#3760), once per rule that denied the plan.
|
|
1006
|
+
const value = args[++i];
|
|
1007
|
+
if (!value || value.startsWith("-"))
|
|
1008
|
+
throw new Error("--rule needs a rule id: --rule <id>");
|
|
1009
|
+
(result.rules ?? (result.rules = [])).push(value);
|
|
1010
|
+
}
|
|
1011
|
+
else if (arg === "--expire") {
|
|
1012
|
+
result.expire = true;
|
|
1013
|
+
}
|
|
1014
|
+
else if (arg === "--role") {
|
|
1015
|
+
// #2508 — a role the approver holds, for a gate whose quorum names
|
|
1016
|
+
// roles. Repeatable, and a comma list works too.
|
|
1017
|
+
const value = args[++i] ?? "";
|
|
1018
|
+
result.roles = [...(result.roles ?? []), ...value.split(",").map((r) => r.trim()).filter(Boolean)];
|
|
1019
|
+
}
|
|
1020
|
+
else if (arg === "--agent") {
|
|
1021
|
+
// #2508 — record the approval as an agent's rather than a person's.
|
|
1022
|
+
result.agent = true;
|
|
1023
|
+
}
|
|
1024
|
+
else if (arg === "--allow-code") {
|
|
1025
|
+
// #2550 — `chant workspace upgrade` runs a template's code migrations
|
|
1026
|
+
// only when asked to.
|
|
1027
|
+
result.allowCode = true;
|
|
1028
|
+
}
|
|
1029
|
+
else if (arg === "--source") {
|
|
1030
|
+
// #2551 — `chant workspace upgrade --source <repo>[#<member>]`.
|
|
1031
|
+
result.source = args[++i];
|
|
1032
|
+
if (!result.source || result.source.startsWith("-"))
|
|
1033
|
+
throw new Error("--source needs a template: --source <repo>[#<member>]");
|
|
1034
|
+
}
|
|
1035
|
+
else if (arg === "--tags") {
|
|
1036
|
+
// #2551 — `chant workspace adopt-lineage --tags <glob>`, also hash-index and versions.
|
|
1037
|
+
result.tags = args[++i];
|
|
1038
|
+
if (!result.tags || result.tags.startsWith("-"))
|
|
1039
|
+
throw new Error("--tags needs a tag glob: --tags 'v*'");
|
|
1040
|
+
}
|
|
1041
|
+
else if (arg === "--index") {
|
|
1042
|
+
// #2551 — `chant workspace adopt-lineage --index <file>`.
|
|
1043
|
+
result.index = args[++i];
|
|
1044
|
+
if (!result.index || result.index.startsWith("-"))
|
|
1045
|
+
throw new Error("--index needs a hash index file: --index <file>");
|
|
1046
|
+
}
|
|
1047
|
+
else if (arg === "--remove") {
|
|
1048
|
+
// #2552 — `chant workspace import --remove` removes the export member instead of writing it again.
|
|
1049
|
+
result.remove = true;
|
|
1050
|
+
}
|
|
1051
|
+
else if (arg === "--available") {
|
|
1052
|
+
// #2551 — `chant workspace versions --available` lists the template's version tags.
|
|
1053
|
+
result.available = true;
|
|
1054
|
+
}
|
|
1055
|
+
else if (arg === "--root-only") {
|
|
1056
|
+
// #2537 — `chant build` and `chant lint` at a declared workspace root
|
|
1057
|
+
// run on the root project alone instead of refusing with WSP000.
|
|
1058
|
+
result.rootOnly = true;
|
|
1059
|
+
}
|
|
1060
|
+
else if (arg === "--generated") {
|
|
1061
|
+
// #2641 — `chant workspace check --generated` runs each declared
|
|
1062
|
+
// generator and compares its output with the file in the tree.
|
|
1063
|
+
result.generated = true;
|
|
1064
|
+
}
|
|
1065
|
+
else if (arg === "--member") {
|
|
1066
|
+
// #2537 — `chant workspace build|lint|audit|graph --member <name>`.
|
|
1067
|
+
// Repeatable, and a comma list works too.
|
|
1068
|
+
const value = args[++i];
|
|
1069
|
+
if (!value || value.startsWith("-"))
|
|
1070
|
+
throw new Error("--member needs a member or group name: --member <name>");
|
|
1071
|
+
result.members = [...(result.members ?? []), ...value.split(",").map((m) => m.trim()).filter(Boolean)];
|
|
1072
|
+
}
|
|
1073
|
+
else if (arg === "--allow-same-origin") {
|
|
1074
|
+
// chant#2384 — record a resolution the same-origin rule would refuse,
|
|
1075
|
+
// deliberately. Flagged on the record, not just accepted quietly.
|
|
1076
|
+
result.allowSameOrigin = true;
|
|
1077
|
+
}
|
|
1078
|
+
else if (arg === "--plan") {
|
|
1079
|
+
result.plan = args[++i];
|
|
1080
|
+
}
|
|
1081
|
+
else if (arg === "--url") {
|
|
1082
|
+
result.url = args[++i];
|
|
1083
|
+
}
|
|
1084
|
+
else if (arg === "--op") {
|
|
1085
|
+
result.op = args[++i];
|
|
1086
|
+
}
|
|
1087
|
+
else if (arg === "--since") {
|
|
1088
|
+
result.since = args[++i];
|
|
1089
|
+
}
|
|
1090
|
+
else if (arg === "--limit") {
|
|
1091
|
+
// Parsed here, validated by the handler — `parseArgs` reports shape, not
|
|
1092
|
+
// policy, the same split every other value flag here uses.
|
|
1093
|
+
result.limit = Number(args[++i]);
|
|
1094
|
+
}
|
|
1095
|
+
else if (arg.startsWith("--")) {
|
|
1096
|
+
// chant #1127 — every recognized flag is matched above; anything left
|
|
1097
|
+
// starting with `--` is unrecognized, whether it arrived bare
|
|
1098
|
+
// (`--bogus`) or joined (`--bogus=value`, already split into
|
|
1099
|
+
// `--bogus` + `value` above). This used to fall through silently (the
|
|
1100
|
+
// "ignores unknown flags" case) — a typo'd or misremembered flag would
|
|
1101
|
+
// vanish with no diagnostic, exactly like the silent-drop this issue
|
|
1102
|
+
// closes for joined values. Point at --help rather than enumerating
|
|
1103
|
+
// every flag here: this parser's flag set is one flat list shared by
|
|
1104
|
+
// every command, not scoped per-command, so "the command's known
|
|
1105
|
+
// flags" isn't something this loop can name in isolation.
|
|
1106
|
+
throw new Error(`Unknown flag: ${arg}\nRun "chant --help" to see supported flags.`);
|
|
1107
|
+
}
|
|
1108
|
+
else if (!arg.startsWith("-")) {
|
|
1109
|
+
if (result.command)
|
|
1110
|
+
(result.positionals ?? (result.positionals = [])).push(arg);
|
|
1111
|
+
if (!result.command) {
|
|
1112
|
+
result.command = arg;
|
|
1113
|
+
}
|
|
1114
|
+
else if (result.path === ".") {
|
|
1115
|
+
result.path = arg;
|
|
1116
|
+
}
|
|
1117
|
+
else if (!result.extraPositional) {
|
|
1118
|
+
result.extraPositional = arg;
|
|
1119
|
+
}
|
|
1120
|
+
else {
|
|
1121
|
+
result.extraPositional2 = arg;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
i++;
|
|
1125
|
+
}
|
|
1126
|
+
// #2603 — `--promote-to` (#2575) adds a job to the pipeline that generate
|
|
1127
|
+
// mode synthesizes; no other command or mode reads it. Checked here, once
|
|
1128
|
+
// the whole command line is known, rather than in the build handler, so
|
|
1129
|
+
// `chant build --promote-to prod` and `chant run --promote-to prod` both
|
|
1130
|
+
// fail instead of running as if the flag were absent. A lexicon-mounted
|
|
1131
|
+
// command that takes its own `--promote-to` still gets it: `main` tries the
|
|
1132
|
+
// plugin commands before rethrowing a parse error.
|
|
1133
|
+
if (result.promoteTo && !(result.command === "build" && result.components && result.generate)) {
|
|
1134
|
+
throw new Error("--promote-to needs build --components --generate <lexicon>: it adds a promote job to the generated CI pipeline, and only generate mode emits one.");
|
|
1135
|
+
}
|
|
1136
|
+
return result;
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Print help message. `groups` — lexicon-contributed command groups
|
|
1140
|
+
* (chant #1078), best-effort loaded from the current project; composed in
|
|
1141
|
+
* below the static command list so `--help` lists every mounted verb group
|
|
1142
|
+
* alongside core's own commands.
|
|
1143
|
+
*/
|
|
1144
|
+
function printHelp(groups = []) {
|
|
1145
|
+
console.log(`
|
|
1146
|
+
chant - Declarative infrastructure specification toolkit
|
|
1147
|
+
|
|
1148
|
+
Usage:
|
|
1149
|
+
chant <command> [options] [path]
|
|
1150
|
+
|
|
1151
|
+
Commands:
|
|
1152
|
+
init Initialize a new chant project
|
|
1153
|
+
(--from <repo>@<ref>[#<member>] copies a template
|
|
1154
|
+
repository and records its lineage, and --from
|
|
1155
|
+
<dir>[#<member>] copies a template directory on
|
|
1156
|
+
disk; --param
|
|
1157
|
+
<name>=<value> sets a parameter the template's
|
|
1158
|
+
chant.template.json declares, repeatable)
|
|
1159
|
+
init lexicon <name> Scaffold a new lexicon plugin project
|
|
1160
|
+
build Build infrastructure from specification files
|
|
1161
|
+
(--components --generate github|gitlab|forgejo:
|
|
1162
|
+
generate mode (#563), which synthesizes a thin CI
|
|
1163
|
+
pipeline that triggers each discovered component's
|
|
1164
|
+
own deploy in wave order, instead of a normal
|
|
1165
|
+
lexicon build)
|
|
1166
|
+
At a declared workspace root it refuses with WSP000;
|
|
1167
|
+
--root-only builds the root project alone
|
|
1168
|
+
lint Check specifications for issues
|
|
1169
|
+
(at a declared workspace root: WSP000 unless --root-only)
|
|
1170
|
+
list List discovered entities
|
|
1171
|
+
describe Show the effective config for one component
|
|
1172
|
+
explain Summarize discovered entities (--format markdown|json|okf;
|
|
1173
|
+
okf emits an OKF v0.2 knowledge bundle — one markdown
|
|
1174
|
+
concept per entity + index.md; -o <dir> writes the
|
|
1175
|
+
bundle tree, otherwise JSON path→content on stdout)
|
|
1176
|
+
generate Generate typed code from sources chant.config declares
|
|
1177
|
+
(k8s.crds, helm.charts) into src/generated/<lexicon>/
|
|
1178
|
+
(codegen.outDir); --check exits 1 when the committed
|
|
1179
|
+
output no longer matches its sources, as build does
|
|
1180
|
+
vendor Pull pinned, checksummed patterns into your repo
|
|
1181
|
+
(pull [name] | check | migrate; migrate moves
|
|
1182
|
+
vendor.json into .chant/workspace.lock.json)
|
|
1183
|
+
import Import external template into TypeScript
|
|
1184
|
+
(--agents re-expresses this machine's agent config as
|
|
1185
|
+
chant code instead of reading a template file)
|
|
1186
|
+
audit [path|url] Audit a repo's CI YAML for security issues
|
|
1187
|
+
(--format stylish|json|sarif|markdown|html, -o <file>,
|
|
1188
|
+
--tier merge-worthy|all, --fail-on merge-worthy|warning|error|none,
|
|
1189
|
+
--template <file> / --theme <file> for the html report,
|
|
1190
|
+
--max-files <n> to walk more than 1000 files)
|
|
1191
|
+
--agents audits this machine's agent configuration —
|
|
1192
|
+
instruction files, MCP servers, skills, plugins,
|
|
1193
|
+
permissions — instead of a repository
|
|
1194
|
+
(--scope system,user,project, --runtime claude,codex,...,
|
|
1195
|
+
--all-projects)
|
|
1196
|
+
migrate <file> Translate a workflow between lexicons
|
|
1197
|
+
(default: --from github --to gitlab)
|
|
1198
|
+
carve advise Read-only peelability advisor: rank which resources
|
|
1199
|
+
--from <dir> are cheap to carve into native chant
|
|
1200
|
+
(--json, --report <path>). Emits nothing, changes nothing.
|
|
1201
|
+
--from a Terraform dir needs @cdktn/hcl2json
|
|
1202
|
+
(npm install -D @cdktn/hcl2json); --from a CDK cloud
|
|
1203
|
+
assembly (cdk.out) needs nothing and ranks constructs.
|
|
1204
|
+
carve emit Adopt a selected TF resource into chant source + report
|
|
1205
|
+
--from <tf-dir> its boundary. --state <tfstate> adopts offline
|
|
1206
|
+
--select <addr> (recommended for TF-managed resources); --env
|
|
1207
|
+
--state|--env <env> adopts via live cloud import (--live-name
|
|
1208
|
+
<logical-id> narrows a multi-resource stack).
|
|
1209
|
+
Persists a carve manifest bridge/apply compose
|
|
1210
|
+
with; scaffolds the output dir into a buildable
|
|
1211
|
+
chant project (src/ + config + package.json).
|
|
1212
|
+
carve bridge Generate the surviving-TF patch (data sources + rewired
|
|
1213
|
+
--from <tf-dir> refs) + deferred inputs + reversible runbook,
|
|
1214
|
+
[--select <addr>] plus one git-applyable .patch for the whole
|
|
1215
|
+
edit. Writes proposals for review;
|
|
1216
|
+
--apply-rewrites edits the .tf in place.
|
|
1217
|
+
--select is optional when the output dir
|
|
1218
|
+
holds one carve manifest.
|
|
1219
|
+
carve apply Apply graduation: ownership marker + finalized apply
|
|
1220
|
+
--from <tf-dir> runbook (dial-turn observe→apply). BYOL —
|
|
1221
|
+
[--select <addr>] no cloud call; --write saves the doc. --select
|
|
1222
|
+
--env <env> is optional with a carve manifest present.
|
|
1223
|
+
--write-source stamps the ownership marker
|
|
1224
|
+
into the emitted chant source.
|
|
1225
|
+
carve status Status read over a tree of carve manifests: every
|
|
1226
|
+
[--from <dir>] *.carve.json under --from (default: cwd) with
|
|
1227
|
+
(--json) its target, stage (planned/emitted/bridged/
|
|
1228
|
+
applied) and path. Read-only.
|
|
1229
|
+
|
|
1230
|
+
CI:
|
|
1231
|
+
ci last-green [--json] The newest first-parent commit of ci.green's branch
|
|
1232
|
+
with a ci/green tag and no ci/revoked tag. Reads local
|
|
1233
|
+
tags only; fetch them first.
|
|
1234
|
+
ci tick [--dry-run] [--forge github] Tag each commit within ci.green's
|
|
1235
|
+
window whose required phases all passed ci/green/<sha>,
|
|
1236
|
+
and revoke a green one that now fails ci/revoked/<sha>.
|
|
1237
|
+
Reads check runs from the forge, pushes the tags.
|
|
1238
|
+
ci workflow [--workflow <name>]... [--output <file>] Write
|
|
1239
|
+
[--chant <command>] [--install <command>]
|
|
1240
|
+
[--token-secret <NAME> | --app-id-var <VAR> --app-key-secret <NAME>]
|
|
1241
|
+
.github/workflows/chant-ci-green.yml, which runs the
|
|
1242
|
+
tick when a required workflow completes and every 15m.
|
|
1243
|
+
--chant replaces the npx @intentius/chant pin the tick
|
|
1244
|
+
runs; --install adds a step before it. --token-secret,
|
|
1245
|
+
or a GitHub App's id and key, pushes the tags with a
|
|
1246
|
+
token that may tag commits changing workflow files.
|
|
1247
|
+
|
|
1248
|
+
Change sets:
|
|
1249
|
+
change-set summary <file> The grouped plan summary of a change-set
|
|
1250
|
+
[--format text|json|markdown] document: members taking
|
|
1251
|
+
[--limit <chars>] the same change grouped, every destroy,
|
|
1252
|
+
replacement, failure and hole named.
|
|
1253
|
+
markdown fits an MR/PR note of --limit
|
|
1254
|
+
characters (default 65536). Read-only.
|
|
1255
|
+
|
|
1256
|
+
Ops:
|
|
1257
|
+
run <name> Run an Op on the resolved runtime (--on; local by default)
|
|
1258
|
+
[--work <id>] [--holder <name>]: the work item an Op
|
|
1259
|
+
with a work lease runs under, and who holds it
|
|
1260
|
+
--fail-on-drift: exit 2 when the run completes and
|
|
1261
|
+
its Drift outcome is true (WatchOp failOn: "drift")
|
|
1262
|
+
run list List all Ops with the runtime's state for each
|
|
1263
|
+
run status <name> Show the runtime's state for one Op's latest run
|
|
1264
|
+
run approve <op> <gate> Record a gate's resolution and wake the runtime
|
|
1265
|
+
run cancel <name> Cancel the active run (requires --force)
|
|
1266
|
+
run log <name> Show run history for an Op
|
|
1267
|
+
run wave --spec <file> --wave <k> Plan, gate and apply wave k of an Op
|
|
1268
|
+
waves spec (#3679): the job a generated waves
|
|
1269
|
+
pipeline runs. --decide plans and decides only;
|
|
1270
|
+
--share <i> applies one share of a decided wave.
|
|
1271
|
+
--record-plans (no --wave), in a pull request's
|
|
1272
|
+
pipeline: plan every wave at its head and record the
|
|
1273
|
+
digests a pr-review approval mode compares
|
|
1274
|
+
run resume [--op <name>] [--gate <name>] Start again each CI job that
|
|
1275
|
+
waits at a gate an approval now answers, through the
|
|
1276
|
+
forge's API (#3683); approves nothing. --gate resumes
|
|
1277
|
+
that gate's job alone (#3854). Skips an approval a
|
|
1278
|
+
wave already applied under; restarts an apply that
|
|
1279
|
+
stopped once its run is gone (#3858). --dry-run
|
|
1280
|
+
starts nothing; with --json it says per gate whether
|
|
1281
|
+
it would resume and why
|
|
1282
|
+
run --generate <provider> Write one CI pipeline file per scheduled Op for
|
|
1283
|
+
github, gitlab or forgejo (#2533), from every Op that
|
|
1284
|
+
declares a schedule or from --spec <file.json>.
|
|
1285
|
+
Files go to the forge's own directory unless
|
|
1286
|
+
--output <dir>; --format json prints them instead
|
|
1287
|
+
run --components <name|all> Run discovered Component(s) through the interpret
|
|
1288
|
+
driver on the local executor (--env <env>; #585).
|
|
1289
|
+
On success, auto-emits a release-ledger record per
|
|
1290
|
+
component that published a digest (default: on;
|
|
1291
|
+
--no-release-record to opt out; #597)
|
|
1292
|
+
--progress-json: stream one NDJSON RunProgressEvent
|
|
1293
|
+
per line to stdout while the run executes, for a
|
|
1294
|
+
consumer to render live wave/component/phase/step
|
|
1295
|
+
progress instead of tailing raw logs (additive; run
|
|
1296
|
+
semantics/exit code unchanged)
|
|
1297
|
+
operator Run scheduled ticks for discovered ConvergeOps
|
|
1298
|
+
locally (#1485): acquire/renew a per-op
|
|
1299
|
+
lease (git ref CAS), tick on --interval, record every
|
|
1300
|
+
result as a ledger fact. --env <env> scopes to one
|
|
1301
|
+
environment; --interval <dur> (default 60s) and
|
|
1302
|
+
--lease-ttl <dur> (default 5m) tune cadence; --once
|
|
1303
|
+
runs a single round and exits (cron/systemd-timer/
|
|
1304
|
+
CronJob invokers use this instead of the daemon).
|
|
1305
|
+
--steward [<name>] runs a declared steward's local
|
|
1306
|
+
form instead (#2731): its scheduled Ops on their
|
|
1307
|
+
crons, under the steward's own lease, and its
|
|
1308
|
+
beside Ops as chant run processes of their own
|
|
1309
|
+
(#2861)
|
|
1310
|
+
operator status Last tick, outcomes, and pending gates per
|
|
1311
|
+
ConvergeOp, read from the chant/lifecycle orphan
|
|
1312
|
+
branch alone — no daemon needs to be running
|
|
1313
|
+
(--env <env>, --json)
|
|
1314
|
+
operator log Converge tick history and the gate resolutions
|
|
1315
|
+
against it, merged into one timestamp-ordered
|
|
1316
|
+
timeline, from the same orphan branch (--env <env>,
|
|
1317
|
+
--op <name>, --since <iso>, --limit <n>, --json).
|
|
1318
|
+
--json also carries the count of ledger lines that
|
|
1319
|
+
were unreadable, so a short timeline is never
|
|
1320
|
+
silently short
|
|
1321
|
+
approve <op> <gate> Record a gate's out-of-band resolution fact
|
|
1322
|
+
(--actor <name>, --note <text>, --url <url>) — the
|
|
1323
|
+
durable counterpart to the pending fact a run records
|
|
1324
|
+
when it reaches the gate; see the pending-gates list
|
|
1325
|
+
in operator status. --url is the PR/MR the resolution
|
|
1326
|
+
happened at, recorded typed rather than as free text,
|
|
1327
|
+
and defaults to the PR/MR of the surrounding CI job.
|
|
1328
|
+
The next "chant run <op>" walks through the gate.
|
|
1329
|
+
--expire clears a pending fact without approving it,
|
|
1330
|
+
so the gate is re-decided from scratch next run.
|
|
1331
|
+
--sign [<key file>] seals the approval with an ssh
|
|
1332
|
+
key; a gate the workspace's identity.gates names
|
|
1333
|
+
counts only an approval sealed by a key the signers
|
|
1334
|
+
file at base lists for --actor. --relayed-by
|
|
1335
|
+
<principal> records who carried the approval to chant
|
|
1336
|
+
for --actor (a follower, a bot); --sign covers it.
|
|
1337
|
+
--resume then starts the CI job that waits at the
|
|
1338
|
+
gate again (GitHub re-run, GitLab retry, Forgejo
|
|
1339
|
+
dispatch) with CHANT_FORGE_TOKEN
|
|
1340
|
+
On op policy-override the gate is the subject a
|
|
1341
|
+
policy denied: --rule <id> names each rule that
|
|
1342
|
+
denied it and --reason <text> says why the plan goes
|
|
1343
|
+
out anyway; the next run that plans the same digest
|
|
1344
|
+
applies it once, if .chant/overriders at base lists
|
|
1345
|
+
--actor
|
|
1346
|
+
|
|
1347
|
+
graph Show Op dependency graph (--stacks for cross-stack order,
|
|
1348
|
+
--format ir|mermaid|dot|layout for the lint-gated graph IR,
|
|
1349
|
+
a Mermaid flowchart, Graphviz DOT, or node positions;
|
|
1350
|
+
layout uses dagre by default (no native dep) — pass
|
|
1351
|
+
--node-sizes <json|-|@file> for size-aware spacing,
|
|
1352
|
+
--layout-engine graphviz to use dot instead;
|
|
1353
|
+
--detail 0..3: stacks|composites|declarables|attributes;
|
|
1354
|
+
--lens lexicon:<n>|stack:<n>|blast:<node> (--up/--down))
|
|
1355
|
+
--components --format ir --projection gitlab|github|forgejo:
|
|
1356
|
+
add the CI/pipeline projection (stages/jobs/needs) to
|
|
1357
|
+
the component-graph IR, from the same generator
|
|
1358
|
+
'build --components --generate' uses (#989)
|
|
1359
|
+
--traffic "<level>": ask the project's predicting
|
|
1360
|
+
lexicon what the estate does at that traffic level, and
|
|
1361
|
+
carry each entity's prediction on the IR. On the
|
|
1362
|
+
declared graph it predicts the file; with --live it
|
|
1363
|
+
predicts the account. The level reaches the engine
|
|
1364
|
+
verbatim; without the flag nothing is asked (#2377)
|
|
1365
|
+
|
|
1366
|
+
Workspace (level 1, #2524):
|
|
1367
|
+
workspace init [dir] Propose a chant.workspace.json from the projects and
|
|
1368
|
+
packages already in the repository, print it with the
|
|
1369
|
+
directories that would leave the root project, and
|
|
1370
|
+
write it only on confirmation (--yes writes without
|
|
1371
|
+
asking; --name <name> names the workspace; --verbose
|
|
1372
|
+
lists every file leaving the root project)
|
|
1373
|
+
workspace ls [dir] List the declaration's members and example groups.
|
|
1374
|
+
A member that can't be read is listed with a reason
|
|
1375
|
+
code and still exits 0. --at <rev> reads a commit's
|
|
1376
|
+
git objects; --json prints the read-contract document
|
|
1377
|
+
workspace status <env> [dir] [--compare-to <env>] [--json]
|
|
1378
|
+
Each member's latest release in <env>, as digest and
|
|
1379
|
+
git SHA, read from its ledger on the local
|
|
1380
|
+
chant/lifecycle branch (_members/<member>/ or the flat
|
|
1381
|
+
layout). --compare-to <env> shows a second environment
|
|
1382
|
+
beside it and marks the members whose digests differ.
|
|
1383
|
+
Read only; never fetches. --json prints the
|
|
1384
|
+
read-contract document
|
|
1385
|
+
workspace records [--kind <kind file>] [--current] [--uncommitted | --at <rev>] [--base <rev>] [--require attested] [--json]
|
|
1386
|
+
Without --kind, every record kind the declaration
|
|
1387
|
+
names. Read the records a record kind locates, validated
|
|
1388
|
+
against its schema, with reason codes for invalid
|
|
1389
|
+
ones. --current leaves out superseded records; --at
|
|
1390
|
+
reads a commit's git objects. Needs no workspace file.
|
|
1391
|
+
Each record reports its provenance level, judged by
|
|
1392
|
+
the signers at --base (default: the target branch);
|
|
1393
|
+
--require attested exits 2 if any record is not
|
|
1394
|
+
attested. A pinned file that changed is a warning,
|
|
1395
|
+
asset-drift or asset-missing. In the working tree,
|
|
1396
|
+
each record says whether it is committed, modified
|
|
1397
|
+
or new against HEAD, with the branch and base;
|
|
1398
|
+
--uncommitted lists only the modified and new ones
|
|
1399
|
+
workspace records [--kind <kind file>] --since <rev|session id> [--at <rev>] [--json]
|
|
1400
|
+
What changed in the records between <rev> and --at
|
|
1401
|
+
(default: the working tree): new and removed records,
|
|
1402
|
+
state transitions, new verdicts, new supersessions
|
|
1403
|
+
and changed pins. A session id compares the commits
|
|
1404
|
+
the session opened and closed at
|
|
1405
|
+
workspace records pin <path>
|
|
1406
|
+
Print the path from the workspace root and the
|
|
1407
|
+
sha256 of a file, for a decision's evidence pin
|
|
1408
|
+
workspace records new [<kind file>] --from <file|-> [--prefix <prefix>] [--sign [<key file>]] [--dry-run]
|
|
1409
|
+
Write one new record in the kind's directory from
|
|
1410
|
+
the JSON fields given, after validating them as
|
|
1411
|
+
records would read them. Without a kind file, the one
|
|
1412
|
+
kind the declaration names. Allocates the next id when
|
|
1413
|
+
the fields hold none. --sign seals the record's author
|
|
1414
|
+
(decided_by for decisions) with an ssh key. Prints
|
|
1415
|
+
{path, id} as JSON and never commits
|
|
1416
|
+
workspace records amend <id> [--kind <kind file>] --set <file|-> [--expect <digest>] [--sign [<key file>]] [--dry-run]
|
|
1417
|
+
Set top-level fields of one record. A closed record
|
|
1418
|
+
never changes, and an approved one changes only its
|
|
1419
|
+
state (upward), pins and reviews; anything else is
|
|
1420
|
+
refused with amend-supersede-instead. Moving a
|
|
1421
|
+
record to its kind's ratified state (ratified for
|
|
1422
|
+
decisions) is refused with ratify-quorum-not-met
|
|
1423
|
+
until its quorum is met. --sign seals the author
|
|
1424
|
+
again; without it an amendment removes the author
|
|
1425
|
+
seal and says so. --expect refuses the write with
|
|
1426
|
+
record-conflict when the record's digest has moved
|
|
1427
|
+
on. Prints {path, id, changed, digest}
|
|
1428
|
+
workspace records review <id> [--kind <kind file>] --verdict agree|dissent|abstain --by <principal> [--note <text>] [--session <id>] [--expect <digest>] [--sign [<key file>]] [--dry-run]
|
|
1429
|
+
Append a review to one record, dated and bound to
|
|
1430
|
+
the digest of the record text. A dissent needs
|
|
1431
|
+
--note. --sign seals it with an ssh key (git's
|
|
1432
|
+
user.signingkey without a file); under a signers
|
|
1433
|
+
file at base only a sealed verdict counts. With
|
|
1434
|
+
--session, the session must be open, and the verdict
|
|
1435
|
+
is appended to its verdicts too. --expect refuses a
|
|
1436
|
+
verdict on a record that moved on. Prints
|
|
1437
|
+
{path, id, review, digest}
|
|
1438
|
+
workspace records close <session id> [--kind <session kind file>] [--expect <digest>] [--dry-run]
|
|
1439
|
+
Close an open review session: its state, close time,
|
|
1440
|
+
closing commit and seal, in one write. Without
|
|
1441
|
+
--kind, the one session kind the declaration names.
|
|
1442
|
+
Prints {path, id, changed, seal, closedRev}
|
|
1443
|
+
Every working-tree write holds the working tree's
|
|
1444
|
+
write lock (CHANT_WRITE_LOCK_WAIT_MS, default 15s)
|
|
1445
|
+
workspace lock [acquire --holder <name> [--ttl <duration>] | release --token <token>] [--json]
|
|
1446
|
+
Who holds the working tree's write lock; take it for
|
|
1447
|
+
a batch of writes across chant calls, each run with
|
|
1448
|
+
CHANT_WRITE_LOCK=<token>, and give it back
|
|
1449
|
+
workspace work claim|renew|release <id> --holder <name> [--kind <kind file>] [--ttl <seconds|duration>] [--token <token>] [--outcome <outcome>] [--note <text>] [--json]
|
|
1450
|
+
Take, heartbeat or give back the lease on a work item:
|
|
1451
|
+
refs/chant/lease/work/<id>, a compare-and-set ref with a
|
|
1452
|
+
fencing token and an expiry, pushed to the remote so
|
|
1453
|
+
separate clones coordinate. A claim is refused, exit 2,
|
|
1454
|
+
while anyone holds it live. Each change appends to
|
|
1455
|
+
_leases/<id>.jsonl on chant/lifecycle
|
|
1456
|
+
workspace work history <id> [--kind <kind file>] [--json]
|
|
1457
|
+
A work item's lease history: each claim with its token
|
|
1458
|
+
and holder, and how it ended, released with an outcome
|
|
1459
|
+
or never released (expired or lost). Read-only
|
|
1460
|
+
workspace work evidence <id> --holder <name> --token <token> --from <file|-> [--kind <kind file>]
|
|
1461
|
+
Attach evidence for one acceptance criterion under the
|
|
1462
|
+
lease you hold: the entry (criterion, result, title,
|
|
1463
|
+
a url or a path pinned by hash) is appended to the
|
|
1464
|
+
item's pins through records amend. Prints the
|
|
1465
|
+
work-evidence document and never commits
|
|
1466
|
+
workspace runs [--unit <id>] [--decision <id>] [--by <principal>] [--since <rev>] [--follow-squash] [--json]
|
|
1467
|
+
The agent runs in the run ledger on chant/lifecycle, each
|
|
1468
|
+
with its model, tokens, cost and the commits it made,
|
|
1469
|
+
and totals per work item, decision and principal; a run
|
|
1470
|
+
that reports no cost is listed as unpriced, never zero.
|
|
1471
|
+
Read-only, never fetches; --follow-squash joins each
|
|
1472
|
+
squash merge to its pull request's runs, fetching a
|
|
1473
|
+
missing refs/pull/<n>/head from origin
|
|
1474
|
+
workspace runs start --from <file|->
|
|
1475
|
+
Record that an agent run started: who it worked for,
|
|
1476
|
+
its harness, model, work item and lease. Prints the run
|
|
1477
|
+
and its Chant-Run trailer. chant never starts a run
|
|
1478
|
+
workspace runs end <run id> [--from <file|->]
|
|
1479
|
+
Record how a started run ended: its outcome, tokens,
|
|
1480
|
+
cost and price source, the transcript pinned by hash,
|
|
1481
|
+
and the commits it made
|
|
1482
|
+
workspace runs record --from <file|->
|
|
1483
|
+
Record a finished run, its start and end in one write
|
|
1484
|
+
workspace runs sign <run id> (--key <runner.pem> | --envelope <file|->) [--base <rev>]
|
|
1485
|
+
Store a DSSE statement over an ended run (its record's
|
|
1486
|
+
hash, work item, harness, model and commits), signed
|
|
1487
|
+
with a runner or steward key .chant/trust.json lists
|
|
1488
|
+
at base, or signed elsewhere and checked here
|
|
1489
|
+
workspace runs statement <run id> --signer <principal>
|
|
1490
|
+
Print the statement for a signer whose key is
|
|
1491
|
+
elsewhere, such as a lobby, with the payload to sign
|
|
1492
|
+
workspace runs verify [<run id>] [--require signed] [--base <rev>] [--json]
|
|
1493
|
+
Judge each run's stored statements against the runner
|
|
1494
|
+
keys at base. Reports only, unless --require signed
|
|
1495
|
+
workspace box listing set <member> [--from <file|->] [--cover <image> [--cover-path <path>]] [--by <principal>] [--dry-run]
|
|
1496
|
+
Change a box's listing (published, title, line, cover)
|
|
1497
|
+
in the declaration, in place, keeping its formatting
|
|
1498
|
+
and comments; --cover copies a PNG, JPEG or WebP into
|
|
1499
|
+
the repository. Judged by the write scope at base.
|
|
1500
|
+
Prints the box-listing-write document; never commits
|
|
1501
|
+
workspace member add <name> --from <file|-> [--by <principal>] [--dry-run]
|
|
1502
|
+
workspace member remove <name> [--by <principal>] [--dry-run]
|
|
1503
|
+
workspace host set <name> --from <file|-> [--by <principal>] [--dry-run]
|
|
1504
|
+
Add or remove a member's entry, or add or replace a
|
|
1505
|
+
host's, in the declaration, in place, keeping its
|
|
1506
|
+
formatting and comments. Refuses a declaration that
|
|
1507
|
+
doesn't read, or two boxes sharing a port. Judged by
|
|
1508
|
+
the write scope at base. Prints the member-write
|
|
1509
|
+
document; never commits
|
|
1510
|
+
workspace box factory set <member> --from <file|-> [--by <principal>] [--dry-run]
|
|
1511
|
+
Change a box's factory (builds, check, checks,
|
|
1512
|
+
builders, tiers, publish) in the declaration, in
|
|
1513
|
+
place, such as where a planted box publishes. Judged
|
|
1514
|
+
by the write scope at base. Prints the
|
|
1515
|
+
box-factory-write document; never commits
|
|
1516
|
+
workspace box publish <member> (<item> | --records) [--by <principal>] [--head <owner/name>] [--dry-run]
|
|
1517
|
+
Publish a built work item, or the records kept
|
|
1518
|
+
uncommitted, through the publisher the box block names:
|
|
1519
|
+
run with a JSON request on stdin, its answer checked
|
|
1520
|
+
and its commit held to the apply record (ws-088).
|
|
1521
|
+
Prints the box-publish document; chant itself never
|
|
1522
|
+
commits, pushes or calls a forge
|
|
1523
|
+
workspace wip [--branch <branch>] [--json]
|
|
1524
|
+
List the work-in-progress snapshots under
|
|
1525
|
+
refs/chant/wip/<branch>, newest first, and how far each
|
|
1526
|
+
ref the box's replicate policy names is from its remote.
|
|
1527
|
+
Reads locally; never fetches (#3172)
|
|
1528
|
+
workspace wip save [--label <text>] [--by <principal>]
|
|
1529
|
+
Snapshot the whole working tree, uncommitted records
|
|
1530
|
+
included, onto refs/chant/wip/<branch> without touching
|
|
1531
|
+
the index or the branch; pushes when the policy says so
|
|
1532
|
+
workspace wip restore [<snapshot>] [--by <principal>]
|
|
1533
|
+
Put the working tree back as the snapshot (the branch's
|
|
1534
|
+
latest by default) holds it, after a snapshot of how it
|
|
1535
|
+
is now; HEAD never moves
|
|
1536
|
+
workspace wip push Push the refs the box's replicate policy names to its
|
|
1537
|
+
remote, never forced, for the host's schedule
|
|
1538
|
+
workspace wip fetch On a replacement box, bring back what was replicated:
|
|
1539
|
+
create or fast-forward the local refs, then wip restore
|
|
1540
|
+
workspace points [--open] [--kind <kind file>] [--at <rev>] [--json]
|
|
1541
|
+
List the decision points the declared answer kinds'
|
|
1542
|
+
points files declare, and the questions asked of them;
|
|
1543
|
+
--open keeps the escalated and proposed ones (ws-058)
|
|
1544
|
+
workspace points ask <point> --inputs <file|-|json> [--candidates <file|-|json>] [--response <file>] [--subject <id>] [--store <tree|ledger>] [--kind <kind file>] [--dry-run]
|
|
1545
|
+
Ask a point's table, model and quorum deciders and
|
|
1546
|
+
record the answer: proposed from a model, escalated to
|
|
1547
|
+
people below its threshold. --response is a POST
|
|
1548
|
+
/v1/systemone response the caller got; chant calls no model.
|
|
1549
|
+
--candidates gives an ad-hoc point's question and
|
|
1550
|
+
candidates, { question, criteria }. --store ledger
|
|
1551
|
+
holds the question on chant/lifecycle and pushes it,
|
|
1552
|
+
for a checkout that does not outlive the run (CI)
|
|
1553
|
+
workspace points answer <id> --answer <value> --by <name>... [--note <text>] [--relayed-by <principal>] [--kind <kind file>] [--resume] [--dry-run]
|
|
1554
|
+
Record people's answer to an open question, or confirm
|
|
1555
|
+
a model's proposal, once the point's quorum is met,
|
|
1556
|
+
with their note and who relayed it. --resume then
|
|
1557
|
+
starts again the CI job waiting at the gate the
|
|
1558
|
+
question names, when the answer passes it
|
|
1559
|
+
workspace points retract <id> --by <name>... [--note <text>] [--kind <kind file>] [--dry-run]
|
|
1560
|
+
Take an answer back: the question is open for people
|
|
1561
|
+
again, and the answer stays in its retractions
|
|
1562
|
+
workspace pin <path> [--json]
|
|
1563
|
+
Print the integrity value that pins the plugin at
|
|
1564
|
+
<path>, to put in a path pin of chant.workspace.json.
|
|
1565
|
+
chant checks it before it reads the plugin
|
|
1566
|
+
workspace agent [<name>] [--json]
|
|
1567
|
+
Print an agent session from the declaration: the one
|
|
1568
|
+
member it is bound to, the record kinds and verbs its
|
|
1569
|
+
write scope allows, and the spec records --current
|
|
1570
|
+
prints. Without a name, the session CHANT_AGENT names
|
|
1571
|
+
workspace verify [--base <rev>] [--head <rev>] [--require attested | attested-runs]
|
|
1572
|
+
Check the commits in base..head against the signers
|
|
1573
|
+
and roles read from base. A change to the signers file
|
|
1574
|
+
or .chant/trust.json needs a signature by a signer
|
|
1575
|
+
trusted at base, and a new signer set needs a
|
|
1576
|
+
threshold of the old one. A commit an agent run made
|
|
1577
|
+
is attested by the run's signed statement; with
|
|
1578
|
+
attested-runs, only those commits must be
|
|
1579
|
+
workspace signers [--json] [rotate [--threshold <n>] | sign --key <file>]
|
|
1580
|
+
Show the signer history at base, or propose the next
|
|
1581
|
+
signer set and sign it with a current signer's key
|
|
1582
|
+
workspace evidence sign --kind <kind file> --key <runner.pem> --check-id <id>
|
|
1583
|
+
Sign runner evidence over the records' hashes in a
|
|
1584
|
+
DSSE envelope, with a runner key .chant/trust.json
|
|
1585
|
+
lists. For CI and services, never a person's key
|
|
1586
|
+
workspace evidence verify --envelope <file> [--at <rev>] [--json]
|
|
1587
|
+
Verify runner evidence offline, and whether the
|
|
1588
|
+
records it covers are unchanged
|
|
1589
|
+
workspace lineage [--json]
|
|
1590
|
+
Show each scope in .chant/workspace.lock.json: its
|
|
1591
|
+
template and pin, locally edited files and open
|
|
1592
|
+
manual steps. Needs no workspace file
|
|
1593
|
+
workspace lineage resolve <path>
|
|
1594
|
+
Close a manual step once the file is merged by hand
|
|
1595
|
+
workspace upgrade [<scope>] [--to <ref|dir>] [--source <repo>[#<member>]] [--allow-code] [--dry-run] [--output <file>]
|
|
1596
|
+
Bring a lineage scope to a newer template version: fetch
|
|
1597
|
+
it, migrate and merge per file in a worktree, run build,
|
|
1598
|
+
lint and workspace check there, then gate on the digest
|
|
1599
|
+
of the patch (chant approve workspace-upgrade <scope>).
|
|
1600
|
+
A second run with the approval applies the patch.
|
|
1601
|
+
--source <repo>[#<member>] moves the scope to another
|
|
1602
|
+
template through that template's bridge migration
|
|
1603
|
+
workspace adopt-lineage [<scope>] --from <repo>[@<ref>][#<member>] [--tags <glob>]
|
|
1604
|
+
[--index <file>] [--param name=value] [--dry-run] [--json]
|
|
1605
|
+
Give a scope a git lineage: match a scope with none
|
|
1606
|
+
against the template's versions and record the best
|
|
1607
|
+
one, with the adopted commit range in .chant/trust.json,
|
|
1608
|
+
or move a directory lineage onto the version that
|
|
1609
|
+
reproduces its recorded files
|
|
1610
|
+
workspace hash-index --from <repo>[#<member>] [--tags <glob>] [--output <file>]
|
|
1611
|
+
Compute the per-version file hashes adopt-lineage
|
|
1612
|
+
matches against, for a template's CI to publish
|
|
1613
|
+
workspace versions [<dir>] [--template <id>] [--available [--tags <glob>]] [--json]
|
|
1614
|
+
Report the template, chant and lexicon versions of
|
|
1615
|
+
every lineage lock under <dir>, grouped into families
|
|
1616
|
+
by template; --available also lists each git
|
|
1617
|
+
template's version tags and where each lock sits
|
|
1618
|
+
workspace export [<member>[,<member>...]] [--to <member>] [--param name=value] [--dry-run] [--json]
|
|
1619
|
+
Write members that set travel, with their lineage and
|
|
1620
|
+
records, into the export member (role export) as a
|
|
1621
|
+
workspace of their own; with no member named, every
|
|
1622
|
+
member that travels and the workspace's own records.
|
|
1623
|
+
--param gives a host-bound parameter its value there
|
|
1624
|
+
workspace import [<dir>] [--remove] [--dry-run] [--json]
|
|
1625
|
+
Bring an export back: merge per file against the
|
|
1626
|
+
export's hashes, switch host values back, record the
|
|
1627
|
+
return in .chant/returns/<id>.json with the commits the
|
|
1628
|
+
files were made in, then write the export member again
|
|
1629
|
+
or, with --remove, remove it
|
|
1630
|
+
workspace admit <return id> [--note <text>] [--dry-run] [--json]
|
|
1631
|
+
Admit the signers of a return in .chant/trust.json, so
|
|
1632
|
+
its signed work reads as attested once merged
|
|
1633
|
+
workspace check [--at <rev>] [--json] [--format stylish|json|sarif] [--generated] [--kind <kind file>] [--live --env <env>]
|
|
1634
|
+
Fail on an unreadable lineage lock or an open manual
|
|
1635
|
+
step, and, in a declared workspace, on a WSP check of
|
|
1636
|
+
the declaration, member ledgers, pipelines or
|
|
1637
|
+
generated files. --generated runs declared generators
|
|
1638
|
+
and compares their output. --kind warns on records
|
|
1639
|
+
whose pinned files changed. Needs no workspace file.
|
|
1640
|
+
--at reads a commit's git objects; --format json
|
|
1641
|
+
prints the read-contract document. --live --env
|
|
1642
|
+
resolves each declared member link against the live
|
|
1643
|
+
graph of <env> (each chant member runs chant graph
|
|
1644
|
+
--live, which reaches the account) and reports
|
|
1645
|
+
WSP141 and WSP142
|
|
1646
|
+
workspace check --changes <base>..<head> [--work <id>] [--severity off|warn|fail] [--kind <kind file>...] [--json]
|
|
1647
|
+
Map each path the diff changes to the current records
|
|
1648
|
+
whose constrains cover it: change-uncovered when none
|
|
1649
|
+
does, change-out-of-scope when a record in hand (the
|
|
1650
|
+
--work item and its decisions) lists it in
|
|
1651
|
+
out_of_scope. The declaration's changes block sets
|
|
1652
|
+
the severity (warn by default) and ignore globs. When
|
|
1653
|
+
the declaration at base has writeScope or agents, each
|
|
1654
|
+
commit that writes outside its writer's scope fails
|
|
1655
|
+
the check (write-scope-member, write-scope-kind)
|
|
1656
|
+
workspace patch <base>..<head>|<base>...<head>|<commit> [--path <p>...] [--max-bytes <n>] [--json]
|
|
1657
|
+
workspace patch [<commit>] --worktree [--path <p>...] [--max-bytes <n>] [--json]
|
|
1658
|
+
The hunks of a diff, file by file: a range, a work
|
|
1659
|
+
branch, or one commit against its first parent. Each
|
|
1660
|
+
file's hunk text stops at --max-bytes (64 KiB) and
|
|
1661
|
+
says it was truncated
|
|
1662
|
+
workspace build [dir] [--member <name>] [-o <dir>] [--dry-run]
|
|
1663
|
+
Build every chant member and example project, each with
|
|
1664
|
+
its own chant, one process per toolchain. -o <dir>
|
|
1665
|
+
writes <dir>/<member>.json; --member narrows the run;
|
|
1666
|
+
--dry-run prints which chant runs which project
|
|
1667
|
+
workspace lint [dir] [--format stylish|json|sarif] [--member <name>]
|
|
1668
|
+
Lint every chant member and example project with its
|
|
1669
|
+
own chant; sarif writes one run per member
|
|
1670
|
+
workspace audit [dir] [--json] [--member <name>]
|
|
1671
|
+
Audit each chant member with its own .chant-audit.json;
|
|
1672
|
+
every finding carries a member field
|
|
1673
|
+
workspace graph [dir] [--at <rev>] [--member <name>] [--kind <kind file>] [-o <file>]
|
|
1674
|
+
Compose each chant member's chant graph into one IR,
|
|
1675
|
+
with <member>/<id> ids and groups.byMember: the
|
|
1676
|
+
read-contract document. --at <rev> runs each member's
|
|
1677
|
+
source as it was at that commit; --kind adds the
|
|
1678
|
+
records' asset and constrains links. A member whose
|
|
1679
|
+
source and toolchain are unchanged is served from
|
|
1680
|
+
the cache in $CHANT_CACHE_DIR or ~/.cache/chant;
|
|
1681
|
+
--no-cache reads every member
|
|
1682
|
+
workspace graph --composites [--at <rev>] [--member <name>] [-o <file>]
|
|
1683
|
+
Each composite instance the members declare, with the
|
|
1684
|
+
components whose contract can deploy it; an instance
|
|
1685
|
+
with none lists an empty set
|
|
1686
|
+
workspace graph --intent <path[:start-end]|path#symbol> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]
|
|
1687
|
+
The intent graph over one region: the commits that
|
|
1688
|
+
touched it, the decisions whose constrains cover it,
|
|
1689
|
+
the artifacts they pin, and findings with closed codes.
|
|
1690
|
+
Without --kind, every record kind the declaration names.
|
|
1691
|
+
--follow-squash follows a squash merge to its pull
|
|
1692
|
+
request's commits, fetching a missing ref from origin
|
|
1693
|
+
workspace graph --intent --record <id> [--at <rev>] [--kind <kind file>...] [--follow-squash] [--json]
|
|
1694
|
+
One decision's intent walk over every path: and member:
|
|
1695
|
+
entry it constrains: the commits in its window, each
|
|
1696
|
+
own, worked, within-other or unexplained, with counts
|
|
1697
|
+
|
|
1698
|
+
Lifecycle (alias: lc):
|
|
1699
|
+
lifecycle snapshot <env> Query API, save metadata to orphan branch
|
|
1700
|
+
--deep: also record each resource's property tree,
|
|
1701
|
+
not just its identity — what a fold over topology
|
|
1702
|
+
needs (costs more provider calls; #1267)
|
|
1703
|
+
lifecycle show <env> Show latest lifecycle snapshot
|
|
1704
|
+
lifecycle diff <env> Compare current build against last snapshot
|
|
1705
|
+
--live: query cloud now and detect drift
|
|
1706
|
+
(lexicons with a deep reader also report
|
|
1707
|
+
property-level drift; --update-baseline records
|
|
1708
|
+
what it reports as accepted so it stops alerting)
|
|
1709
|
+
lifecycle plan <env> Typed change set (create/update/delete/adopt) vs live
|
|
1710
|
+
--deep: also report properties declared
|
|
1711
|
+
heldElsewhere(). Never changes what the plan
|
|
1712
|
+
proposes; costs a provider call pair per readable
|
|
1713
|
+
resource, so the read's cost becomes a function of
|
|
1714
|
+
estate size rather than stack count (#2405)
|
|
1715
|
+
lifecycle affected Stacks a change affects (--base <ref> [--include-dependents])
|
|
1716
|
+
--json: emit the ChangeSet as JSON
|
|
1717
|
+
lifecycle whoami <env> Who chant would act as in each configured lexicon,
|
|
1718
|
+
and what that principal is scoped to — read-only,
|
|
1719
|
+
before anything acts (--json, --strict)
|
|
1720
|
+
lifecycle teardown <env> Plan what deleting the environment would remove —
|
|
1721
|
+
marker-scoped (this project's stack + env); --yes
|
|
1722
|
+
executes the plan (production-like names also need
|
|
1723
|
+
--confirm-prod, or an interactive confirmation)
|
|
1724
|
+
lifecycle log [env] History of lifecycle snapshots
|
|
1725
|
+
|
|
1726
|
+
Plan scenarios (#1292):
|
|
1727
|
+
scenario check Evaluate every declared Scenario's expect clause
|
|
1728
|
+
offline, against its given fixture (no cloud, no
|
|
1729
|
+
credentials); --json: emit verdicts as JSON.
|
|
1730
|
+
Nonzero exit on any failing scenario.
|
|
1731
|
+
|
|
1732
|
+
Component release ledger + status:
|
|
1733
|
+
components status [env] What's built vs what's deployed where, joined by
|
|
1734
|
+
digest (--live: reconcile against live+ownership;
|
|
1735
|
+
--json: stable machine-readable contract;
|
|
1736
|
+
--compare-to <env>: cross-check the same
|
|
1737
|
+
component's recorded digest against another env)
|
|
1738
|
+
components fan-out Run a change out across the components downstream
|
|
1739
|
+
of it, in an order derived from the source
|
|
1740
|
+
(--base <ref> [--head <ref>] [--include-dependents],
|
|
1741
|
+
or --from-affected <file>; --dry-run prints the
|
|
1742
|
+
derivation and dispatches nothing; --gate <name>
|
|
1743
|
+
puts one approval over the whole set;
|
|
1744
|
+
--wave-gate <name> puts one on each wave, planned
|
|
1745
|
+
when the wave is reached, with --canary <name>
|
|
1746
|
+
for wave 1 and --wave <n> for one wave per CI
|
|
1747
|
+
job; --resume <file> finishes an attempt that
|
|
1748
|
+
stopped)
|
|
1749
|
+
components pr-plan Plan the components a pull request reaches and
|
|
1750
|
+
the ones that depend on them, and write the
|
|
1751
|
+
report and note (--base <ref> --pr <n>
|
|
1752
|
+
[--forge github|gitlab|forgejo] posts them);
|
|
1753
|
+
applies nothing
|
|
1754
|
+
components pr-apply On merge: plan the same members again and apply
|
|
1755
|
+
them only if an approval stands for that digest
|
|
1756
|
+
(chant approve pr-<n> pr-apply --plan <digest>);
|
|
1757
|
+
a moved plan refuses with exit 3
|
|
1758
|
+
(--require-review: the approver must have
|
|
1759
|
+
approved the pull request on the forge;
|
|
1760
|
+
--member <name>, both commands: a workspace
|
|
1761
|
+
member's loop, gate op pr-<n>-<member>;
|
|
1762
|
+
--resume <file> finishes an apply that failed
|
|
1763
|
+
partway under the same approval)
|
|
1764
|
+
components release <env> Append one immutable release record
|
|
1765
|
+
(--component <name> --digest <sha256:...>
|
|
1766
|
+
[--git-sha <sha>] [--run-id <id>] [--actor <name>]);
|
|
1767
|
+
--release-plan <file> takes --digest's place,
|
|
1768
|
+
persisting the release plan the file holds to
|
|
1769
|
+
_plans/<digest>.json (ws-055) and recording its
|
|
1770
|
+
own digest
|
|
1771
|
+
components export <env> Materialize a persisted build archive manifest to
|
|
1772
|
+
a portable directory (--component <name>
|
|
1773
|
+
[--digest <manifestDigest>] -o <dir> [--json]);
|
|
1774
|
+
copies every image/template/asset/sbom entry
|
|
1775
|
+
byte-for-byte plus a self-describing manifest.json
|
|
1776
|
+
components promote Deploy the digests one environment's release
|
|
1777
|
+
ledger records to another, without a build
|
|
1778
|
+
(--from <env> --to <env> [--component <name>
|
|
1779
|
+
[--digest <sha256:...>]]; --dry-run prints the
|
|
1780
|
+
plan; the target's gates still apply)
|
|
1781
|
+
components rollback <env> Redeploy an earlier release of an environment
|
|
1782
|
+
from its recorded digest (--component <name>
|
|
1783
|
+
[--digest <sha256:...>]; defaults to the release
|
|
1784
|
+
before the current one; --dry-run prints the plan)
|
|
1785
|
+
components redeploy <env> Redeploy the release an environment's ledger
|
|
1786
|
+
records as current, after a deploy that failed
|
|
1787
|
+
partway (--component <name> [--digest <sha256:...>];
|
|
1788
|
+
--dry-run prints the plan; gates still apply)
|
|
1789
|
+
|
|
1790
|
+
Lexicon development:
|
|
1791
|
+
dev generate Generate lexicon artifacts (+ validate + coverage)
|
|
1792
|
+
dev publish Package lexicon for distribution
|
|
1793
|
+
dev onboard <name> Patch CI, Dockerfiles, and workflows for a new lexicon
|
|
1794
|
+
dev check-lexicon <dir> Check lexicon completeness (tier 1/2/3)
|
|
1795
|
+
dev surface-diff <dir> Regen lexicon, validate, diff API surface vs committed baseline
|
|
1796
|
+
(--force: bypass spec cache; --update-snapshot: write new baseline;
|
|
1797
|
+
--bump: with --update-snapshot, bump package version by drift severity;
|
|
1798
|
+
--check: fail if the committed baseline drifted (never writes);
|
|
1799
|
+
--run-examples: also run example build harness;
|
|
1800
|
+
--pinned-digest <file>: verify spec digest before regen)
|
|
1801
|
+
dev pinned-upgrade <dir> [pin]
|
|
1802
|
+
Report if a lexicon that declares upstreamPin (k8s, k3s, gcp, docker,
|
|
1803
|
+
gitlab, cedar, sql) has a newer upstream release; dry-run bump + regen +
|
|
1804
|
+
surface-diff, then revert. A pin that moves with other constants (sql's
|
|
1805
|
+
image digest) is reported with how to move it, not edited. A lexicon
|
|
1806
|
+
with several pins (sql: clickhouse, postgres-14 .. postgres-18) gets one
|
|
1807
|
+
report per pin; name a pin to check only that one
|
|
1808
|
+
(reports only; --force bypasses the spec cache, -f json for JSON)
|
|
1809
|
+
dev rolling-upgrade <dir> Report rolling-spec drift (aws, azure, github): regen from
|
|
1810
|
+
latest, diff surface vs committed baseline, print delta + PR
|
|
1811
|
+
label (dry run; --force bypasses the spec cache, --format json)
|
|
1812
|
+
|
|
1813
|
+
Local:
|
|
1814
|
+
emulator <up|down|status> Boot/stop/inspect configured lexicons' local
|
|
1815
|
+
emulators (Floci etc.); --lexicon <name>, --json,
|
|
1816
|
+
--port; \`chant emulator --help\` lists ports and logins
|
|
1817
|
+
|
|
1818
|
+
Servers:
|
|
1819
|
+
serve lsp Start the LSP server (stdio)
|
|
1820
|
+
serve mcp Start the MCP server (stdio)
|
|
1821
|
+
|
|
1822
|
+
Project:
|
|
1823
|
+
update Sync lexicon types into .chant/types/
|
|
1824
|
+
doctor Check project health and configuration
|
|
1825
|
+
|
|
1826
|
+
Options:
|
|
1827
|
+
-o, --output <file> Write output to file instead of stdout
|
|
1828
|
+
-f, --format <fmt> Output format (command-specific):
|
|
1829
|
+
- build: json (default) or yaml
|
|
1830
|
+
- list: text (default) or json
|
|
1831
|
+
- lint: stylish (default), json, or sarif
|
|
1832
|
+
--lexicon-output <lexicon>=<path>
|
|
1833
|
+
build: write that lexicon's output to its own file
|
|
1834
|
+
(repeatable). Lexicons not named go to --output when
|
|
1835
|
+
given, and are skipped otherwise
|
|
1836
|
+
-d, --lexicon <name> Build only the specified lexicon (e.g. aws, gitlab);
|
|
1837
|
+
import: use this lexicon instead of detecting one
|
|
1838
|
+
--env <name> Active environment: sets CHANT_ENV so env-aware source
|
|
1839
|
+
re-evaluates for that environment (build + graph), and
|
|
1840
|
+
drives organizational policy. Must be in chant.config
|
|
1841
|
+
\`environments\` when declared.
|
|
1842
|
+
-t, --template <name> Init template (e.g. node-pipeline, docker-build);
|
|
1843
|
+
records its lineage in .chant/workspace.lock.json
|
|
1844
|
+
--skill <name> Init: install only this skill from the lexicon
|
|
1845
|
+
--skip-mcp Init: scaffold without writing the project's .mcp.json
|
|
1846
|
+
--fix Auto-fix fixable issues (lint command)
|
|
1847
|
+
--force Force overwrite existing files (import command)
|
|
1848
|
+
-w, --watch Watch for changes and rebuild/re-lint (build, lint)
|
|
1849
|
+
-v, --verbose Show stack traces on errors; (build) list every
|
|
1850
|
+
resolved build parameter and per-file fold decision
|
|
1851
|
+
instead of the one-line summaries
|
|
1852
|
+
-h, --help Show this help message
|
|
1853
|
+
-V, --version Print the installed chant's version
|
|
1854
|
+
--on <lexicon> Which runtime hosts the run: a configured lexicon with
|
|
1855
|
+
an opRuntime, or local. Omitted, run.on in
|
|
1856
|
+
chant.config.ts decides, then the built-in local
|
|
1857
|
+
runtime (every run subcommand; #2121, #2523)
|
|
1858
|
+
--local Run an Op with the local in-process executor (default)
|
|
1859
|
+
-p, --profile <name> Named connection profile the hosting runtime targets
|
|
1860
|
+
(fountain.profiles in chant.config.ts); each runtime's
|
|
1861
|
+
own default when omitted (#2124)
|
|
1862
|
+
--json Emit the structured run result as JSON (run command)
|
|
1863
|
+
--report With a path arg: SARIF report destination (migrate)
|
|
1864
|
+
OR '--report gitlab-mr': emit the GitLab MR plan-widget
|
|
1865
|
+
JSON (lifecycle plan)
|
|
1866
|
+
OR '--report markdown': emit a reviewer-facing markdown
|
|
1867
|
+
render, holes and disruption included (lifecycle plan)
|
|
1868
|
+
--from <name> Source lexicon for migrate (default: github)
|
|
1869
|
+
--to <name> Target lexicon for migrate (default: gitlab)
|
|
1870
|
+
--emit <fmt> Migration output format: yaml (default) or ts
|
|
1871
|
+
--strict Escalate needs-review/validation to errors (migrate);
|
|
1872
|
+
exit nonzero on an unresolved identity (lifecycle whoami)
|
|
1873
|
+
--validate Run external validator (glci/glab) after migrate
|
|
1874
|
+
--use-composites Rewrite to composite calls when patterns match (migrate)
|
|
1875
|
+
--components Target discovered Component declarations instead of
|
|
1876
|
+
lexicon resources (list, describe, graph, build, run)
|
|
1877
|
+
--generate <lexicon> Generate mode: synthesize CI YAML for <lexicon> (github,
|
|
1878
|
+
gitlab or forgejo) instead of running. build
|
|
1879
|
+
--components: one pipeline for the components; run:
|
|
1880
|
+
one pipeline file per scheduled Op
|
|
1881
|
+
--spec <file> (run --generate) JSON Op specs: an array, or
|
|
1882
|
+
{ ops, options }
|
|
1883
|
+
--promote-to <env> (build --components --generate) Add a job that
|
|
1884
|
+
promotes the deployed releases to <env>
|
|
1885
|
+
--no-release-record Skip auto-emitting a release-ledger record after a
|
|
1886
|
+
successful \`run --components\` deploy (default: on;
|
|
1887
|
+
also settable via chant.config.ts's
|
|
1888
|
+
release.autoRecord: false; #597)
|
|
1889
|
+
--fold (build) Fold source modules statically instead of
|
|
1890
|
+
running them; folds resource constructors and
|
|
1891
|
+
composite factory calls (#1022/#1023), falling back
|
|
1892
|
+
to run per-file for anything else outside the fold
|
|
1893
|
+
subset (a cross-file-only reference, a re-export,
|
|
1894
|
+
\`export default\`, ...). Logs a fold/run count
|
|
1895
|
+
(per-file lines under --verbose). DEFAULT since #1134 — this flag forces it on
|
|
1896
|
+
over a chant.config.ts \`build.fold: false\`.
|
|
1897
|
+
--no-fold (build) Opt out of folding for this invocation: every
|
|
1898
|
+
source module is imported and run, the pre-#1134
|
|
1899
|
+
behavior. Beats chant.config.ts's build.fold.
|
|
1900
|
+
--fold-rank [<path>] (build, with --fold) Rank run-mode files by dominator
|
|
1901
|
+
retained-count over the forward import-failure graph
|
|
1902
|
+
(#1083) — fixing the top blocker unblocks the most
|
|
1903
|
+
files. Files held back only by the reverse rule
|
|
1904
|
+
(#1044) are reported separately, never folded into
|
|
1905
|
+
the ranking. With a path argument, also writes a
|
|
1906
|
+
Brendan Gregg collapsed-format export (weighted by
|
|
1907
|
+
retained count) there, for any flame/icicle viewer.
|
|
1908
|
+
--sandbox (build) Run run-fallback source files (or every
|
|
1909
|
+
file, without --fold) together, isolated, in one
|
|
1910
|
+
sandboxed child process instead of in-process
|
|
1911
|
+
(#1045). No filesystem write, no child process, no
|
|
1912
|
+
worker threads, no ambient environment visible to
|
|
1913
|
+
project source; network egress is NOT blocked (see
|
|
1914
|
+
docs). Default: off (also settable via
|
|
1915
|
+
chant.config.ts's build.sandbox: true; #1045)
|
|
1916
|
+
--param <name=value> (build, graph, run --components, components fan-out,
|
|
1917
|
+
components promote, components rollback,
|
|
1918
|
+
components redeploy) Bind a
|
|
1919
|
+
declared build-time parameter (chant.config.ts's buildParams)
|
|
1920
|
+
to a value, for source to read as params.<name>
|
|
1921
|
+
(#1064) instead of process.env — repeatable.
|
|
1922
|
+
Distinct from the AWS lexicon's deploy-time
|
|
1923
|
+
Parameter(): this resolves before synthesis, so it
|
|
1924
|
+
can change which resources are produced at all.
|
|
1925
|
+
Highest precedence. With init --from, it sets a
|
|
1926
|
+
template parameter that the template's
|
|
1927
|
+
chant.template.json declares instead (#2627).
|
|
1928
|
+
--params-file <path> (build, graph, run --components, components fan-out,
|
|
1929
|
+
components promote, components rollback,
|
|
1930
|
+
components redeploy) JSON file
|
|
1931
|
+
of { "name": value } build-time parameter values
|
|
1932
|
+
(#1064). Second precedence, after --param.
|
|
1933
|
+
init --from refuses it: pass --param instead.
|
|
1934
|
+
|
|
1935
|
+
Examples:
|
|
1936
|
+
chant build ./infra/
|
|
1937
|
+
chant build ./infra/ --output stack.json
|
|
1938
|
+
chant build ./infra/ --format yaml
|
|
1939
|
+
chant build ./infra/ --watch
|
|
1940
|
+
chant build ./infra/ --fold
|
|
1941
|
+
chant build ./infra/ --components --generate gitlab
|
|
1942
|
+
chant build ./infra/ --components --generate gitlab --output .gitlab-ci.yml
|
|
1943
|
+
chant run --generate github
|
|
1944
|
+
chant run --components search-service --env staging
|
|
1945
|
+
chant run --components all --env production
|
|
1946
|
+
chant components export prod --component search-service -o ./dist/search-service
|
|
1947
|
+
chant import template.json --output ./infra/
|
|
1948
|
+
chant import manifest.yaml --lexicon k8s --output ./infra/
|
|
1949
|
+
chant import dash.json --lexicon grafana --parser-option acceptLossyV1
|
|
1950
|
+
chant import --from prod --name my-bucket --output src/
|
|
1951
|
+
chant lint ./infra/
|
|
1952
|
+
chant lint ./infra/ --format sarif
|
|
1953
|
+
chant lint ./infra/ --watch
|
|
1954
|
+
chant list ./infra/
|
|
1955
|
+
chant list ./infra/ --format json
|
|
1956
|
+
chant describe myComponent src/
|
|
1957
|
+
chant describe myComponent src/ --format json
|
|
1958
|
+
`);
|
|
1959
|
+
const groupsHelp = formatCommandGroupsHelp(groups);
|
|
1960
|
+
if (groupsHelp)
|
|
1961
|
+
console.log(groupsHelp);
|
|
1962
|
+
}
|
|
1963
|
+
/**
|
|
1964
|
+
* Best-effort load the current project's lexicon plugins for a purely
|
|
1965
|
+
* read-only lookup (help composition, plugin-command dispatch) — never
|
|
1966
|
+
* throws, empty on any failure (no config, no lexicons, not a chant
|
|
1967
|
+
* project at all). Mirrors the existing best-effort loading already used
|
|
1968
|
+
* for `emulator`/`components status` in {@link main} below.
|
|
1969
|
+
*/
|
|
1970
|
+
async function loadPluginsBestEffort() {
|
|
1971
|
+
try {
|
|
1972
|
+
const lexiconNames = await resolveProjectLexicons(resolve("."));
|
|
1973
|
+
return await loadPlugins(lexiconNames);
|
|
1974
|
+
}
|
|
1975
|
+
catch {
|
|
1976
|
+
return [];
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
/**
|
|
1980
|
+
* chant #1078 — the lexicon command-group seam's dispatch-time half. Core's
|
|
1981
|
+
* own `parseArgs`/`resolveCommand` know nothing about a lexicon's mounted
|
|
1982
|
+
* verbs, so this is only ever consulted after BOTH of those have already
|
|
1983
|
+
* failed to make sense of the invocation: either `parseArgs` threw on a flag
|
|
1984
|
+
* it doesn't recognize (which is *expected* for a mounted command's own
|
|
1985
|
+
* vocabulary — core has none), or it parsed fine but `resolveCommand` found
|
|
1986
|
+
* no match in the static registry (a mounted command with no extra flags,
|
|
1987
|
+
* e.g. `chant kube version`). Either way, a lexicon-mounted command's group
|
|
1988
|
+
* name and verb are always the first two CLI tokens (mirrors the `emulator
|
|
1989
|
+
* <up|down|status>` compound shape from #920), so `rawArgv` — the untouched
|
|
1990
|
+
* `process.argv.slice(2)` — is all this needs; nothing from the partially or
|
|
1991
|
+
* fully parsed `ParsedArgs` is used, on purpose, since core's flag-parsing
|
|
1992
|
+
* failure or success is irrelevant to a namespace it doesn't own.
|
|
1993
|
+
*
|
|
1994
|
+
* Returns `undefined` when nothing claims the leading token as a command
|
|
1995
|
+
* group at all, so the caller falls back to its own error handling
|
|
1996
|
+
* unchanged — a project with no lexicon exposing `commands()` (or none of
|
|
1997
|
+
* its plugins matching) is completely unaffected.
|
|
1998
|
+
*/
|
|
1999
|
+
async function tryPluginCommand(rawArgv) {
|
|
2000
|
+
const [groupName, verbName] = rawArgv;
|
|
2001
|
+
if (!groupName || groupName.startsWith("-"))
|
|
2002
|
+
return undefined;
|
|
2003
|
+
const plugins = await loadPluginsBestEffort();
|
|
2004
|
+
// A group declaring a `defaultVerb` (#2125) answers its bare name, so
|
|
2005
|
+
// `chant acp` and `chant acp --durable-requests` both reach that verb. The
|
|
2006
|
+
// slicing follows: with no verb token consumed, everything after the group
|
|
2007
|
+
// name is the default verb's own argument list.
|
|
2008
|
+
const group = collectCommandGroups(plugins).find((g) => g.name === groupName);
|
|
2009
|
+
const useDefault = group?.defaultVerb !== undefined && (verbName === undefined || verbName.startsWith("-"));
|
|
2010
|
+
const verb = useDefault ? group?.defaultVerb : verbName;
|
|
2011
|
+
const rawArgs = rawArgv.slice(useDefault ? 1 : 2);
|
|
2012
|
+
const result = await dispatchCommandGroup(plugins, groupName, verb, rawArgs);
|
|
2013
|
+
if (result.kind === "no-group")
|
|
2014
|
+
return undefined;
|
|
2015
|
+
if (result.kind === "usage-error") {
|
|
2016
|
+
console.error(formatError({ message: result.message, hint: result.hint }));
|
|
2017
|
+
return 1;
|
|
2018
|
+
}
|
|
2019
|
+
return result.exitCode;
|
|
2020
|
+
}
|
|
2021
|
+
/**
|
|
2022
|
+
* Load lexicon plugins for the given project path, or exit with an error.
|
|
2023
|
+
*/
|
|
2024
|
+
async function loadPluginsOrExit(path, lexicon) {
|
|
2025
|
+
let plugins;
|
|
2026
|
+
try {
|
|
2027
|
+
// chant #3648 — `--lexicon <name>` loads that lexicon even when the
|
|
2028
|
+
// project's config and imports name none.
|
|
2029
|
+
const lexiconNames = await resolveProjectLexicons(resolve(path), { lexicon });
|
|
2030
|
+
plugins = await loadPlugins(lexiconNames);
|
|
2031
|
+
}
|
|
2032
|
+
catch (error) {
|
|
2033
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
2034
|
+
console.error(formatError({ message: errorMessage }));
|
|
2035
|
+
process.exit(1);
|
|
2036
|
+
}
|
|
2037
|
+
if (plugins.length === 0) {
|
|
2038
|
+
console.error(formatError({
|
|
2039
|
+
message: "No lexicon detected",
|
|
2040
|
+
hint: 'Run "chant init --lexicon <name>" to initialize a project, or add a lexicon to chant.config.ts',
|
|
2041
|
+
}));
|
|
2042
|
+
process.exit(1);
|
|
2043
|
+
}
|
|
2044
|
+
// #1344 — a lexicon that declares the shape of its own `chant.config.ts`
|
|
2045
|
+
// namespace gets it validated here, once, before any command runs. The
|
|
2046
|
+
// config schema is `.passthrough()`, so before this an unknown key inside a
|
|
2047
|
+
// namespace was accepted and silently ignored: `forgejo: { runnerLabel: … }`
|
|
2048
|
+
// left the dialect on its defaults with nothing said. A namespace whose
|
|
2049
|
+
// lexicon declares no schema keeps that passthrough.
|
|
2050
|
+
try {
|
|
2051
|
+
const { config } = await loadChantConfigUpward(resolve(path));
|
|
2052
|
+
const problems = validateLexiconConfig(plugins, config);
|
|
2053
|
+
if (problems.length > 0) {
|
|
2054
|
+
console.error(formatError({
|
|
2055
|
+
message: `Invalid lexicon configuration in chant.config:\n${formatLexiconConfigProblems(problems)}`,
|
|
2056
|
+
hint: "Remove or correct the key. A lexicon's namespace accepts only the keys it declares.",
|
|
2057
|
+
}));
|
|
2058
|
+
process.exit(1);
|
|
2059
|
+
}
|
|
2060
|
+
}
|
|
2061
|
+
catch {
|
|
2062
|
+
// No config, or one that failed to load — the caller's own handling stands.
|
|
2063
|
+
}
|
|
2064
|
+
return plugins;
|
|
2065
|
+
}
|
|
2066
|
+
/**
|
|
2067
|
+
* #2700 — whether `path` is the root of a declared workspace and holds no
|
|
2068
|
+
* lexicon of its own: no `lexicons` in a root config, and no lexicon import in
|
|
2069
|
+
* the root's source, which leaves the members' directories out (#2527). A
|
|
2070
|
+
* generated app repo can be this shape: its lexicons are all under a
|
|
2071
|
+
* delivery directory, not the root. `chant serve mcp` starts there instead of
|
|
2072
|
+
* refusing with "No lexicon detected", and serves core with the chant
|
|
2073
|
+
* members' lexicons.
|
|
2074
|
+
*
|
|
2075
|
+
* A directory with no workspace declaration costs only `findWorkspaceRoot`'s
|
|
2076
|
+
* existence checks, so a level-0 project reaches `loadPluginsOrExit` as before.
|
|
2077
|
+
*/
|
|
2078
|
+
async function isLexiconlessWorkspaceRoot(path) {
|
|
2079
|
+
const target = resolve(path);
|
|
2080
|
+
if (findWorkspaceRoot(target)?.dir !== target)
|
|
2081
|
+
return false;
|
|
2082
|
+
try {
|
|
2083
|
+
await resolveProjectLexicons(target);
|
|
2084
|
+
return false;
|
|
2085
|
+
}
|
|
2086
|
+
catch (error) {
|
|
2087
|
+
return isNoLexiconDetected(error);
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
/** Whether `def` must run without evaluating the project's `chant.config.ts` (chant#2591). */
|
|
2091
|
+
function commandRunsNoConfig(def, args) {
|
|
2092
|
+
return typeof def.runsNoConfig === "function" ? def.runsNoConfig(args) : def.runsNoConfig === true;
|
|
2093
|
+
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Run one level-0 command line in this process and return its exit code
|
|
2096
|
+
* (#2537). `chant workspace member-run` calls it once per member, from inside
|
|
2097
|
+
* the member's directory, so each member is built, linted, audited or graphed
|
|
2098
|
+
* as `chant <verb> .` would do it there, while members that share a toolchain
|
|
2099
|
+
* share one process. It is main()'s dispatch without the help, the root
|
|
2100
|
+
* refusal and the lexicon command groups: the config is loaded, `--env` is
|
|
2101
|
+
* checked, plugins are loaded when the command needs them, and the handler
|
|
2102
|
+
* runs. A `process.exit` inside (loadPluginsOrExit's, say) is the caller's to
|
|
2103
|
+
* catch.
|
|
2104
|
+
*/
|
|
2105
|
+
export async function runCommandInProcess(argv) {
|
|
2106
|
+
const args = parseArgs(argv);
|
|
2107
|
+
const match = resolveCommand(args, commandRegistry);
|
|
2108
|
+
if (!match) {
|
|
2109
|
+
console.error(formatError({ message: `Unknown command: ${args.command}` }));
|
|
2110
|
+
return 1;
|
|
2111
|
+
}
|
|
2112
|
+
if (args.env)
|
|
2113
|
+
process.env[ENV_VAR] = args.env;
|
|
2114
|
+
let loadedConfig;
|
|
2115
|
+
try {
|
|
2116
|
+
// chant#2618 — `workspace audit` reaches `audit` through here, once per
|
|
2117
|
+
// member. A `runsNoConfig` command skips the load, as it does in main().
|
|
2118
|
+
if (!commandRunsNoConfig(match.def, args))
|
|
2119
|
+
loadedConfig = await loadChantConfigUpward(resolve(args.path));
|
|
2120
|
+
}
|
|
2121
|
+
catch {
|
|
2122
|
+
// A project with no config is the handler's to report, as in main().
|
|
2123
|
+
}
|
|
2124
|
+
const envErr = unknownEnvError(args.env, loadedConfig?.config.environments);
|
|
2125
|
+
if (envErr) {
|
|
2126
|
+
console.error(formatError({ message: envErr, hint: "Declare it in chant.config `environments`, or omit --env." }));
|
|
2127
|
+
return 1;
|
|
2128
|
+
}
|
|
2129
|
+
const plugins = match.def.requiresPlugins ? await loadPluginsOrExit(match.compound ? "." : args.path, args.lexicon) : [];
|
|
2130
|
+
return match.def.handler({ args, plugins, serializers: plugins.map((p) => p.serializer) });
|
|
2131
|
+
}
|
|
2132
|
+
// ── Command registry ──────────────────────────────────────────────
|
|
2133
|
+
/**
|
|
2134
|
+
* Every command word `chant` answers to, and the handler behind it.
|
|
2135
|
+
*
|
|
2136
|
+
* Exported because a caller other than `main()` now needs to ask "is this a
|
|
2137
|
+
* chant verb, and what runs it?" — the fountain lexicon's ACP server (#2125)
|
|
2138
|
+
* treats a prompt as a chant command line, and the only honest answer to
|
|
2139
|
+
* whether `chant lifecycle diff` is a verb is this list. A hand-kept copy
|
|
2140
|
+
* would be wrong the first time a command is added, and the ACP server would
|
|
2141
|
+
* refuse a verb that works at the terminal.
|
|
2142
|
+
*/
|
|
2143
|
+
export const commandRegistry = [
|
|
2144
|
+
// Primary commands
|
|
2145
|
+
{ name: "build", requiresPlugins: true, handler: runBuild },
|
|
2146
|
+
{ name: "lint", handler: runLint },
|
|
2147
|
+
{ name: "list", handler: runList },
|
|
2148
|
+
{ name: "describe", handler: runDescribe },
|
|
2149
|
+
{ name: "explain", handler: runExplain },
|
|
2150
|
+
{ name: "search", handler: runSearch },
|
|
2151
|
+
// chant#2591 — `import --agents` and `audit` read chant.config statically
|
|
2152
|
+
// and never evaluate it (chant#2589 for audit, which audits code it must not run).
|
|
2153
|
+
{ name: "import", handler: runImport, runsNoConfig: (args) => args.agents === true },
|
|
2154
|
+
{ name: "audit", handler: runAudit, runsNoConfig: true },
|
|
2155
|
+
{ name: "migrate", handler: runMigrate },
|
|
2156
|
+
// Read-only Terraform peelability advisor (#214). Compound so "advise" lands
|
|
2157
|
+
// in args.path; the estate dir comes from --from. No plugins, no project.
|
|
2158
|
+
{ name: "carve advise", handler: runCarveAdvise },
|
|
2159
|
+
// Emit step (#197): adopt a selected TF resource into chant source. The
|
|
2160
|
+
// --state path is offline (no plugins); the --env live path loads the target
|
|
2161
|
+
// lexicon lazily in the handler, so this command does not require plugins.
|
|
2162
|
+
{ name: "carve emit", handler: runCarveEmit },
|
|
2163
|
+
// Boundary bridging (#197): patch the surviving TF (data sources + rewired
|
|
2164
|
+
// refs) + runbook. No plugins; Terraform-side only. Read-only unless
|
|
2165
|
+
// --apply-rewrites.
|
|
2166
|
+
{ name: "carve bridge", handler: runCarveBridge },
|
|
2167
|
+
// Apply graduation (#197): ownership marker + finalized apply runbook.
|
|
2168
|
+
// BYOL-honest — no cloud call; --write saves the graduation doc.
|
|
2169
|
+
{ name: "carve apply", handler: runCarveApply },
|
|
2170
|
+
// Status read over a tree of carve manifests (#2038): the contract a
|
|
2171
|
+
// renderer replaces its own walk-and-guess discovery with. Read-only.
|
|
2172
|
+
{ name: "carve status", handler: runCarveStatus },
|
|
2173
|
+
// #3573 — which commits passed CI, kept as ci/green and ci/revoked tags (ws-103). Imported on first use.
|
|
2174
|
+
{ name: "ci last-green", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli.js")).runCiLastGreen(ctx) },
|
|
2175
|
+
{ name: "ci tick", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli.js")).runCiTick(ctx) },
|
|
2176
|
+
{ name: "ci workflow", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/ci-green-cli.js")).runCiWorkflow(ctx) },
|
|
2177
|
+
// #3188 — the grouped plan summary of a change-set document. Reads one file; imported on first use.
|
|
2178
|
+
{ name: "change-set summary", runsNoConfig: true, handler: async (ctx) => (await import("./handlers/change-set.js")).runChangeSetSummary(ctx) },
|
|
2179
|
+
{ name: "init", handler: runInit, runsNoConfig: true },
|
|
2180
|
+
{ name: "init lexicon", handler: runInitLexicon },
|
|
2181
|
+
{ name: "update", handler: runUpdate },
|
|
2182
|
+
{ name: "doctor", handler: runDoctor },
|
|
2183
|
+
// Dev subcommands
|
|
2184
|
+
{ name: "dev generate", requiresPlugins: true, handler: runDevGenerate },
|
|
2185
|
+
{ name: "dev publish", requiresPlugins: true, handler: runDevPublish },
|
|
2186
|
+
{ name: "dev onboard", handler: runDevOnboard, runsNoConfig: true },
|
|
2187
|
+
{ name: "dev check-lexicon", handler: runDevCheckLexicon },
|
|
2188
|
+
{ name: "dev surface-diff", handler: runDevSurfaceDiff },
|
|
2189
|
+
{ name: "dev pinned-upgrade", handler: runDevPinnedUpgrade },
|
|
2190
|
+
{ name: "dev rolling-upgrade", handler: runDevRollingUpgrade },
|
|
2191
|
+
// Op / run subcommands
|
|
2192
|
+
{ name: "run list", handler: runOpList },
|
|
2193
|
+
{ name: "run status", handler: runOpStatus },
|
|
2194
|
+
{ name: "run approve", handler: runOpApprove },
|
|
2195
|
+
{ name: "run signal", handler: runOpSignalRenamed },
|
|
2196
|
+
{ name: "run cancel", handler: runOpCancel },
|
|
2197
|
+
{ name: "run log", handler: runOpLog },
|
|
2198
|
+
{ name: "run wave", handler: runOpWaveCommand },
|
|
2199
|
+
// #3683 — start the CI jobs that wait at gates whose approval arrived. Imported on first use.
|
|
2200
|
+
{ name: "run resume", handler: async (ctx) => (await import("./handlers/gate-resume.js")).runResumeCommand(ctx) },
|
|
2201
|
+
{ name: "run", handler: runOp },
|
|
2202
|
+
{ name: "operator status", handler: runOperatorStatus },
|
|
2203
|
+
{ name: "operator log", handler: runOperatorLog },
|
|
2204
|
+
{ name: "operator", handler: runOperator },
|
|
2205
|
+
{ name: "approve", handler: runApprove },
|
|
2206
|
+
{ name: "graph", handler: runGraph },
|
|
2207
|
+
{ name: "vendor", handler: runVendor },
|
|
2208
|
+
// Project-local codegen: typed code from sources chant.config declares
|
|
2209
|
+
// (k8s.crds, helm.charts). Imported on first use.
|
|
2210
|
+
{ name: "generate", requiresPlugins: true, handler: async (ctx) => (await import("./handlers/generate.js")).runGenerate(ctx) },
|
|
2211
|
+
// Workspace reads (#2524). Imported on first use, so a level-0 command never
|
|
2212
|
+
// loads anything under workspace/ (#2525 rule 5, pinned by #2526's goldens).
|
|
2213
|
+
{ name: "workspace records", handler: async (ctx) => (await import("../workspace/records-cli.js")).runWorkspaceRecords(ctx) },
|
|
2214
|
+
// ws-058 (#2739) — decision points and the questions asked of them; never calls a model.
|
|
2215
|
+
{ name: "workspace points", handler: async (ctx) => (await import("../workspace/points-cli.js")).runWorkspacePoints(ctx) },
|
|
2216
|
+
{ name: "workspace init", handler: async (ctx) => (await import("../workspace/init.js")).runWorkspaceInit(ctx) },
|
|
2217
|
+
{ name: "workspace ls", handler: async (ctx) => (await import("../workspace/ls.js")).runWorkspaceLs(ctx) },
|
|
2218
|
+
// #2732 — the work lease: claim, renew and release a work item.
|
|
2219
|
+
{ name: "workspace work", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/work-cli.js")).runWorkspaceWork(ctx) },
|
|
2220
|
+
// #3033 — the agent run record: what each run cost and which commits it made. chant records runs and never starts one.
|
|
2221
|
+
{ name: "workspace runs", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/runs-cli.js")).runWorkspaceRuns(ctx) },
|
|
2222
|
+
{ name: "workspace status", handler: async (ctx) => (await import("../workspace/status.js")).runWorkspaceStatus(ctx) },
|
|
2223
|
+
{ name: "workspace lineage", handler: async (ctx) => (await import("../workspace/lineage-cli.js")).runWorkspaceLineage(ctx) },
|
|
2224
|
+
{ name: "workspace upgrade", handler: async (ctx) => (await import("../workspace/lineage-upgrade-cli.js")).runWorkspaceUpgrade(ctx) },
|
|
2225
|
+
// #2551 — adopt a lineage, the hash index it matches against, and the versions of a family of workspaces.
|
|
2226
|
+
{ name: "workspace adopt-lineage", handler: async (ctx) => (await import("../workspace/lineage-adopt-cli.js")).runWorkspaceAdoptLineage(ctx) },
|
|
2227
|
+
{ name: "workspace hash-index", handler: async (ctx) => (await import("../workspace/lineage-adopt-cli.js")).runWorkspaceHashIndex(ctx) },
|
|
2228
|
+
// #2552 — export a workspace or members, bring an export back, and admit a return's signers.
|
|
2229
|
+
{ name: "workspace export", handler: async (ctx) => (await import("../workspace/export-cli.js")).runWorkspaceExport(ctx) },
|
|
2230
|
+
{ name: "workspace import", handler: async (ctx) => (await import("../workspace/export-cli")).runWorkspaceImport(ctx) },
|
|
2231
|
+
{ name: "workspace admit", handler: async (ctx) => (await import("../workspace/export-cli.js")).runWorkspaceAdmit(ctx) },
|
|
2232
|
+
{ name: "workspace versions", handler: async (ctx) => (await import("../workspace/lineage-versions.js")).runWorkspaceVersions(ctx) },
|
|
2233
|
+
// #2641 — workspace check reads member configs statically and never runs one.
|
|
2234
|
+
{ name: "workspace check", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/lineage-check.js")).runWorkspaceCheck(ctx) },
|
|
2235
|
+
// The hunks of a diff, for a reader that runs no git of its own.
|
|
2236
|
+
{ name: "workspace patch", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/patch.js")).runWorkspacePatch(ctx) },
|
|
2237
|
+
// #2537 — per-member commands. Each member runs under its own chant, one
|
|
2238
|
+
// process per toolchain identity; `member-run` is that process's entry.
|
|
2239
|
+
{ name: "workspace build", handler: async (ctx) => (await import("../workspace/member-commands.js")).runWorkspaceMembers(ctx, "build") },
|
|
2240
|
+
{ name: "workspace lint", handler: async (ctx) => (await import("../workspace/member-commands.js")).runWorkspaceMembers(ctx, "lint") },
|
|
2241
|
+
// chant#2618 — audit runs no project code, at the workspace level too.
|
|
2242
|
+
{ name: "workspace audit", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/member-commands.js")).runWorkspaceMembers(ctx, "audit") },
|
|
2243
|
+
{ name: "workspace graph", handler: async (ctx) => (await import("../workspace/member-commands.js")).runWorkspaceMembers(ctx, "graph") },
|
|
2244
|
+
// Each unit decides for itself whether its config is loaded (runCommandInProcess).
|
|
2245
|
+
{ name: "workspace member-run", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/member-run.js")).runWorkspaceMemberRun(ctx, runCommandInProcess) },
|
|
2246
|
+
// #3308 — a box's listing, written through chant so a tool never edits the declaration itself (ws-074).
|
|
2247
|
+
{ name: "workspace box", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/box-cli.js")).runWorkspaceBox(ctx) },
|
|
2248
|
+
// #3596 — a declaration's members and hosts, written through chant so a lobby never edits the declaration itself (ws-074).
|
|
2249
|
+
{ name: "workspace member", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/declaration-write-cli.js")).runWorkspaceMember(ctx) },
|
|
2250
|
+
{ name: "workspace host", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/declaration-write-cli.js")).runWorkspaceHost(ctx) },
|
|
2251
|
+
// #3173 — the working tree's write lock, held across chant calls for a batch of writes (ws-089).
|
|
2252
|
+
{ name: "workspace lock", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/write-lock-cli.js")).runWorkspaceLock(ctx) },
|
|
2253
|
+
// #3172 — work in progress under refs/chant/wip/<branch>, replicated under the box's policy (ws-085).
|
|
2254
|
+
{ name: "workspace wip", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/wip-cli.js")).runWorkspaceWip(ctx) },
|
|
2255
|
+
{ name: "workspace pin", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/pin-cli.js")).runWorkspacePin(ctx) },
|
|
2256
|
+
// #2548 — an agent session's member, write scope and spec, for a session that resumes.
|
|
2257
|
+
{ name: "workspace agent", runsNoConfig: true, handler: async (ctx) => (await import("../workspace/agent-cli.js")).runWorkspaceAgent(ctx) },
|
|
2258
|
+
{ name: "workspace verify", handler: async (ctx) => (await import("../workspace/trust/verify-cli.js")).runWorkspaceVerify(ctx) },
|
|
2259
|
+
{ name: "workspace signers", handler: async (ctx) => (await import("../workspace/trust/signers-cli.js")).runWorkspaceSigners(ctx) },
|
|
2260
|
+
{ name: "workspace evidence", handler: async (ctx) => (await import("../workspace/trust/evidence-cli.js")).runWorkspaceEvidence(ctx) },
|
|
2261
|
+
// State subcommands
|
|
2262
|
+
{ name: "lifecycle snapshot", requiresPlugins: true, handler: runLifecycleSnapshot },
|
|
2263
|
+
{ name: "lifecycle show", handler: runLifecycleShow },
|
|
2264
|
+
{ name: "lifecycle diff", requiresPlugins: true, handler: runLifecycleDiff },
|
|
2265
|
+
{ name: "lifecycle rollback", handler: runLifecycleRollback },
|
|
2266
|
+
{ name: "lifecycle plan", requiresPlugins: true, handler: runLifecyclePlan },
|
|
2267
|
+
{ name: "lifecycle affected", requiresPlugins: true, handler: runLifecycleAffected },
|
|
2268
|
+
{ name: "lifecycle whoami", requiresPlugins: true, handler: runLifecycleWhoami },
|
|
2269
|
+
{ name: "lifecycle teardown", requiresPlugins: true, handler: runLifecycleTeardown },
|
|
2270
|
+
{ name: "lifecycle log", handler: runLifecycleLog },
|
|
2271
|
+
// Plan scenarios (#1292) — fully offline, no plugin network calls, but
|
|
2272
|
+
// requiresPlugins:true so the build step has serializers to partition
|
|
2273
|
+
// against, same as every other build-then-something verb.
|
|
2274
|
+
{ name: "scenario check", requiresPlugins: true, handler: runScenarioCheck },
|
|
2275
|
+
// Component release ledger + status surface (#568, epic #551)
|
|
2276
|
+
{ name: "components fan-out", requiresPlugins: true, handler: runComponentsFanOut },
|
|
2277
|
+
// #3183 — the pull-request loop the generated CI runs. Imported on first use.
|
|
2278
|
+
{ name: "components pr-plan", requiresPlugins: true, handler: async (ctx) => (await import("./handlers/pr.js")).runComponentsPrPlan(ctx) },
|
|
2279
|
+
{ name: "components pr-apply", requiresPlugins: true, handler: async (ctx) => (await import("./handlers/pr.js")).runComponentsPrApply(ctx) },
|
|
2280
|
+
{ name: "components status", requiresPlugins: true, handler: runComponentsStatus },
|
|
2281
|
+
{ name: "components release", handler: runComponentsReleaseRecord },
|
|
2282
|
+
{ name: "components export", handler: runComponentsExport },
|
|
2283
|
+
{ name: "components promote", handler: runComponentsPromote },
|
|
2284
|
+
{ name: "components rollback", handler: runComponentsRollback },
|
|
2285
|
+
{ name: "components redeploy", handler: runComponentsRedeploy },
|
|
2286
|
+
// Local emulators of configured lexicons (#920). Compound so the action word
|
|
2287
|
+
// lands in args.path (not consumed as a project dir) and projectPath is forced ".".
|
|
2288
|
+
{ name: "emulator up", requiresPlugins: true, handler: runEmulator },
|
|
2289
|
+
{ name: "emulator down", requiresPlugins: true, handler: runEmulator },
|
|
2290
|
+
{ name: "emulator status", requiresPlugins: true, handler: runEmulator },
|
|
2291
|
+
// Serve subcommands
|
|
2292
|
+
{ name: "serve lsp", requiresPlugins: true, handler: runServeLsp },
|
|
2293
|
+
{ name: "serve mcp", requiresPlugins: true, handler: runServeMcp },
|
|
2294
|
+
// Fallback for unknown subcommands (must come after compound entries)
|
|
2295
|
+
{ name: "carve", handler: runCarveUnknown },
|
|
2296
|
+
{ name: "emulator", requiresPlugins: true, handler: runEmulator },
|
|
2297
|
+
{ name: "lifecycle", handler: runLifecycleUnknown },
|
|
2298
|
+
{ name: "scenario", handler: runScenarioUnknown },
|
|
2299
|
+
{ name: "dev", handler: runDevUnknown },
|
|
2300
|
+
{ name: "serve", handler: runServeUnknown },
|
|
2301
|
+
{ name: "components", handler: runComponentsUnknown },
|
|
2302
|
+
{ name: "workspace", handler: async (ctx) => (await import("../workspace/records-cli.js")).runWorkspaceUnknown(ctx) },
|
|
2303
|
+
];
|
|
2304
|
+
/**
|
|
2305
|
+
* Main entry point
|
|
2306
|
+
*/
|
|
2307
|
+
async function main() {
|
|
2308
|
+
// #3878 — run from dist/ with plain node, TypeScript loads only when
|
|
2309
|
+
// something imports it. A no-op from source.
|
|
2310
|
+
installCompiledCli();
|
|
2311
|
+
const rawArgv = process.argv.slice(2);
|
|
2312
|
+
let args;
|
|
2313
|
+
try {
|
|
2314
|
+
args = parseArgs(rawArgv);
|
|
2315
|
+
}
|
|
2316
|
+
catch (err) {
|
|
2317
|
+
// chant #1078 — core's parser has no idea what flags a lexicon's own
|
|
2318
|
+
// mounted verb accepts, so an "unknown flag" here is expected, not a
|
|
2319
|
+
// real error, until we've checked whether this invocation actually
|
|
2320
|
+
// targets a command group. `tryPluginCommand` returns `undefined` when
|
|
2321
|
+
// nothing claims the leading token, in which case this was a genuine
|
|
2322
|
+
// core-flag error and the original is rethrown unchanged.
|
|
2323
|
+
const code = await tryPluginCommand(rawArgv);
|
|
2324
|
+
if (code !== undefined) {
|
|
2325
|
+
await flushAndExit(code);
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
throw err;
|
|
2329
|
+
}
|
|
2330
|
+
// #2701 — `chant --version` / `-V` prints the installed chant's version, the
|
|
2331
|
+
// one the MCP server reports (./version.ts). With a command word it answers
|
|
2332
|
+
// only for one of core's own commands; a lexicon-mounted verb keeps the flag.
|
|
2333
|
+
if (args.version && (!args.command || resolveCommand(args, commandRegistry))) {
|
|
2334
|
+
console.log(CHANT_VERSION);
|
|
2335
|
+
await flushAndExit(0);
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
// #3673 — `chant emulator --help` is the emulator's own usage, with the
|
|
2339
|
+
// ports and sign-in each configured lexicon's emulator uses, not the
|
|
2340
|
+
// global command list it used to print.
|
|
2341
|
+
if (args.help && args.command === "emulator") {
|
|
2342
|
+
console.log((await emulatorHandlers()).formatEmulatorHelp(await loadPluginsBestEffort().catch(() => [])));
|
|
2343
|
+
await flushAndExit(0);
|
|
2344
|
+
return;
|
|
2345
|
+
}
|
|
2346
|
+
if (args.help || !args.command) {
|
|
2347
|
+
const groups = await loadPluginsBestEffort().then(collectCommandGroups).catch(() => []);
|
|
2348
|
+
printHelp(groups);
|
|
2349
|
+
process.exit(args.help ? 0 : 1);
|
|
2350
|
+
}
|
|
2351
|
+
// `--env <name>` is a build-context switch for the whole invocation: set it
|
|
2352
|
+
// *before* anything imports the project so env-aware source (and thus the graph
|
|
2353
|
+
// / build) reflects that environment. Set early, before config import, since
|
|
2354
|
+
// chant.config itself may branch on the env. (#505)
|
|
2355
|
+
if (args.env)
|
|
2356
|
+
process.env[ENV_VAR] = args.env;
|
|
2357
|
+
// chant #1113 — `--sandbox` is a property of the whole invocation, and it
|
|
2358
|
+
// has to be known BEFORE the first config load, because `chant.config.ts` is
|
|
2359
|
+
// itself project-authored code. Arming here, straight off the parsed flag,
|
|
2360
|
+
// is the only ordering that works: the project's own `build.sandbox: true`
|
|
2361
|
+
// cannot cover its own evaluation (reading it means running it), so the
|
|
2362
|
+
// command-line flag is what puts the config inside the boundary. See
|
|
2363
|
+
// `../config-sandbox.ts`.
|
|
2364
|
+
if (args.sandbox)
|
|
2365
|
+
armSandboxConfigEvaluation();
|
|
2366
|
+
// chant #1131 — the same for `lint.policies`. Armed from the flag here so
|
|
2367
|
+
// the mode is set for the whole invocation, not just `chant build`; the build
|
|
2368
|
+
// command arms it again from the RESOLVED value (a project's own
|
|
2369
|
+
// `build.sandbox: true` also sandboxes its policies — unlike the config,
|
|
2370
|
+
// policies have no bootstrap limit, since they load long after the config is
|
|
2371
|
+
// known). See `../lint/policy-sandbox.ts`.
|
|
2372
|
+
if (args.sandbox)
|
|
2373
|
+
armSandboxPolicyExecution();
|
|
2374
|
+
// Initialize runtime adapter early — before plugins or commands run.
|
|
2375
|
+
// chant #1117 — walks up from `args.path` to the project root: for a
|
|
2376
|
+
// subdirectory build/command (`chant build src/<stack> --env prod`) the
|
|
2377
|
+
// declared `environments` almost always live in the root `chant.config.ts`,
|
|
2378
|
+
// not `args.path` itself.
|
|
2379
|
+
//
|
|
2380
|
+
// chant#2591 — a command marked `runsNoConfig` skips this load: it must not
|
|
2381
|
+
// run the project's `chant.config.ts` (see `CommandDef.runsNoConfig`). Such a
|
|
2382
|
+
// command gets no `--env` check against the declared environments either.
|
|
2383
|
+
const earlyMatch = resolveCommand(args, commandRegistry);
|
|
2384
|
+
const runsNoConfig = earlyMatch != null && commandRunsNoConfig(earlyMatch.def, args);
|
|
2385
|
+
// #3878 — load the command's own modules (and the plugin loader, when it
|
|
2386
|
+
// needs plugins) before anything imports TypeScript: once a chant.config.ts
|
|
2387
|
+
// has registered tsx, every module after it is resolved and loaded through
|
|
2388
|
+
// tsx's hooks, which costs far more than plain node.
|
|
2389
|
+
await Promise.all([
|
|
2390
|
+
earlyMatch ? handlerModules.get(earlyMatch.def.handler)?.() : undefined,
|
|
2391
|
+
earlyMatch?.def.requiresPlugins ? import("./plugins.js") : undefined,
|
|
2392
|
+
]);
|
|
2393
|
+
const projectPath0 = resolve(args.path === "." ? "." : args.path);
|
|
2394
|
+
let loadedConfig;
|
|
2395
|
+
try {
|
|
2396
|
+
if (!runsNoConfig)
|
|
2397
|
+
loadedConfig = await loadChantConfigUpward(projectPath0);
|
|
2398
|
+
initRuntime();
|
|
2399
|
+
}
|
|
2400
|
+
catch {
|
|
2401
|
+
// Config may not exist yet (e.g. `chant init`)
|
|
2402
|
+
initRuntime();
|
|
2403
|
+
}
|
|
2404
|
+
// Reject an --env that isn't among the project's declared `environments`.
|
|
2405
|
+
const envErr = unknownEnvError(args.env, loadedConfig?.config.environments);
|
|
2406
|
+
if (envErr) {
|
|
2407
|
+
console.error(formatError({ message: envErr, hint: 'Declare it in chant.config `environments`, or omit --env.' }));
|
|
2408
|
+
process.exit(1);
|
|
2409
|
+
}
|
|
2410
|
+
const match = earlyMatch;
|
|
2411
|
+
if (!match) {
|
|
2412
|
+
// chant #1078 — not one of core's own commands; check whether a lexicon
|
|
2413
|
+
// mounted a command group under this name before giving up. This is the
|
|
2414
|
+
// "parsed fine, matched nothing" trigger for the seam — the flag-error
|
|
2415
|
+
// trigger is above, in the `parseArgs` catch block.
|
|
2416
|
+
const code = await tryPluginCommand(rawArgv);
|
|
2417
|
+
if (code !== undefined) {
|
|
2418
|
+
await flushAndExit(code);
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2421
|
+
console.error(formatError({
|
|
2422
|
+
message: `Unknown command: ${args.command}`,
|
|
2423
|
+
hint: 'Run "chant --help" to see available commands',
|
|
2424
|
+
}));
|
|
2425
|
+
process.exit(1);
|
|
2426
|
+
}
|
|
2427
|
+
// #2537 (#2524 D0) — at the root of a declared workspace, `build` and
|
|
2428
|
+
// `lint` refuse with WSP000 unless `--root-only` or `rootOnly: true` says
|
|
2429
|
+
// to run on the root project alone. Both lookups only test whether files
|
|
2430
|
+
// exist; the workspace code loads only when this project is a declared root.
|
|
2431
|
+
if (match.def.name === "build" || match.def.name === "lint") {
|
|
2432
|
+
const target = resolve(args.path);
|
|
2433
|
+
const workspace = findWorkspaceRoot(target);
|
|
2434
|
+
if (workspace && findProjectRoot(target) === workspace.dir) {
|
|
2435
|
+
const { guardRootCommand } = await import("../workspace/root-refusal.js");
|
|
2436
|
+
const refused = guardRootCommand({
|
|
2437
|
+
verb: match.def.name,
|
|
2438
|
+
target,
|
|
2439
|
+
workspaceDir: workspace.dir,
|
|
2440
|
+
rootOnly: args.rootOnly === true || loadedConfig?.config.rootOnly === true,
|
|
2441
|
+
});
|
|
2442
|
+
if (refused !== undefined) {
|
|
2443
|
+
await flushAndExit(refused);
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
// For compound commands (e.g. "run list", "lifecycle plan <env>"), the first
|
|
2449
|
+
// positional is a subcommand argument — an environment, op, or lexicon name —
|
|
2450
|
+
// not a project path. Plugins always load from the cwd; the handler reads its
|
|
2451
|
+
// own positionals from args.extraPositional. Using extraPositional as the path
|
|
2452
|
+
// here pointed plugin resolution at e.g. "./local" for `lifecycle plan local`,
|
|
2453
|
+
// which then fell through to import-detection on an empty file set and failed
|
|
2454
|
+
// with "No lexicon detected" even though chant.config.ts lists the lexicons.
|
|
2455
|
+
const projectPath = match.compound ? "." : args.path;
|
|
2456
|
+
// `chant build --components --generate <lexicon>` (#563, generate mode)
|
|
2457
|
+
// discovers `Component` declarations, not lexicon resources — a project
|
|
2458
|
+
// made entirely of components has no reason to declare a chant lexicon
|
|
2459
|
+
// plugin at all. Load plugins best-effort here instead of exiting, so
|
|
2460
|
+
// generate mode works whether or not `chant.config.ts` names a lexicon.
|
|
2461
|
+
// `components status` (#568) is the same shape: a components-only project
|
|
2462
|
+
// may have no lexicon plugin, and `--live` reconciliation is opt-in, so
|
|
2463
|
+
// missing plugins there is "no live evidence" (a warning), not a hard exit.
|
|
2464
|
+
const isGenerateComponents = match.def.name === "build" && args.components && !!args.generate;
|
|
2465
|
+
const isComponentsStatus = match.def.name === "components status";
|
|
2466
|
+
// `components fan-out` (#2420) needs serializers only when it derives the
|
|
2467
|
+
// change signal itself (`--base` builds both refs). Reading one somebody
|
|
2468
|
+
// else already produced (`--from-affected`) touches no lexicon at all, so a
|
|
2469
|
+
// components-only project is not turned away for a step it will not run.
|
|
2470
|
+
const isFanOutFromFile = match.def.name === "components fan-out" && !args.base;
|
|
2471
|
+
// `emulator` (#920) is a property of the *configured* lexicons, not of any infra
|
|
2472
|
+
// file — a fresh/local project with no declarables still boots Floci. Load from
|
|
2473
|
+
// chant.config best-effort, like components status, rather than detectLexicon.
|
|
2474
|
+
const isEmulator = match.def.name === "emulator" || match.def.name.startsWith("emulator ");
|
|
2475
|
+
const plugins = match.def.requiresPlugins
|
|
2476
|
+
? isGenerateComponents || isComponentsStatus || isEmulator || isFanOutFromFile
|
|
2477
|
+
? await loadPlugins(await resolveProjectLexicons(resolve(projectPath)).catch(() => [])).catch(() => [])
|
|
2478
|
+
: match.def.name === "serve mcp" && (await isLexiconlessWorkspaceRoot(projectPath))
|
|
2479
|
+
? [] // #2700 — runServeMcp loads the chant members' lexicons itself.
|
|
2480
|
+
: await loadPluginsOrExit(projectPath, args.lexicon)
|
|
2481
|
+
: [];
|
|
2482
|
+
const serializers = plugins.map((p) => p.serializer);
|
|
2483
|
+
const ctx = { args, plugins, serializers };
|
|
2484
|
+
await flushAndExit(await match.def.handler(ctx));
|
|
2485
|
+
}
|
|
2486
|
+
/**
|
|
2487
|
+
* Wait until a writable stream has flushed its buffer. `process.exit()` discards
|
|
2488
|
+
* data still buffered for an async sink (a pipe or file), truncating large output
|
|
2489
|
+
* at the ~64 KB pipe buffer — so `chant graph --format ir` piped into a consumer
|
|
2490
|
+
* loses everything past 64 KB and its JSON won't parse. A TTY writes
|
|
2491
|
+
* synchronously (`writableLength` stays 0), so this is a no-op there. Resolves on
|
|
2492
|
+
* `error`/`close` too, so a reader that closes early (EPIPE) can't hang exit.
|
|
2493
|
+
* Exported for testing.
|
|
2494
|
+
*/
|
|
2495
|
+
export function waitForStreamDrain(stream) {
|
|
2496
|
+
return new Promise((resolve) => {
|
|
2497
|
+
const tick = () => {
|
|
2498
|
+
if (stream.writableLength === 0 || stream.writableEnded || stream.destroyed) {
|
|
2499
|
+
cleanup();
|
|
2500
|
+
resolve();
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
stream.once("drain", tick);
|
|
2504
|
+
};
|
|
2505
|
+
const stop = () => {
|
|
2506
|
+
cleanup();
|
|
2507
|
+
resolve();
|
|
2508
|
+
};
|
|
2509
|
+
const cleanup = () => {
|
|
2510
|
+
stream.off("drain", tick);
|
|
2511
|
+
stream.off("error", stop);
|
|
2512
|
+
stream.off("close", stop);
|
|
2513
|
+
};
|
|
2514
|
+
stream.once("error", stop);
|
|
2515
|
+
stream.once("close", stop);
|
|
2516
|
+
tick();
|
|
2517
|
+
});
|
|
2518
|
+
}
|
|
2519
|
+
/** Flush stdout+stderr, then exit — so a large piped payload isn't truncated. */
|
|
2520
|
+
async function flushAndExit(code) {
|
|
2521
|
+
await waitForStreamDrain(process.stdout);
|
|
2522
|
+
await waitForStreamDrain(process.stderr);
|
|
2523
|
+
process.exit(code);
|
|
2524
|
+
}
|
|
2525
|
+
// Only run main when executed directly, not when imported. Robust to symlinked
|
|
2526
|
+
// invocation paths — see isEntryPoint (a raw string compare silently no-ops the
|
|
2527
|
+
// whole CLI through the npm .bin shim / a symlinked checkout).
|
|
2528
|
+
const isMain = isEntryPoint(process.argv[1], import.meta.url);
|
|
2529
|
+
if (isMain) {
|
|
2530
|
+
main().catch(async (err) => {
|
|
2531
|
+
const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
|
|
2532
|
+
if (verbose && err instanceof Error && err.stack) {
|
|
2533
|
+
console.error(err.stack);
|
|
2534
|
+
}
|
|
2535
|
+
else {
|
|
2536
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
2537
|
+
}
|
|
2538
|
+
await flushAndExit(1);
|
|
2539
|
+
});
|
|
2540
|
+
}
|