@intentius/chant 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audit/catalog.d.ts +45 -5
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/fetch.d.ts.map +1 -1
- package/dist/audit/proof.d.ts +3 -0
- package/dist/audit/proof.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +4 -1
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/report.d.ts +3 -0
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/rules-doc.d.ts +8 -2
- package/dist/audit/rules-doc.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/lexicon-rolling-upgrade.d.ts +37 -0
- package/dist/cli/commands/lexicon-rolling-upgrade.d.ts.map +1 -0
- package/dist/cli/commands/lexicon-surface-diff.d.ts +48 -0
- package/dist/cli/commands/lexicon-surface-diff.d.ts.map +1 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +41 -0
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -0
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +39 -0
- package/dist/cli/handlers/components.d.ts.map +1 -0
- package/dist/cli/handlers/dev.d.ts +3 -0
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts +4 -2
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts +49 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +35 -0
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts +22 -0
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/lexicon-regen.d.ts +110 -0
- package/dist/codegen/lexicon-regen.d.ts.map +1 -0
- package/dist/codegen/pinned-upgrade.d.ts +153 -0
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -0
- package/dist/codegen/rolling-upgrade.d.ts +138 -0
- package/dist/codegen/rolling-upgrade.d.ts.map +1 -0
- package/dist/codegen/surface-snapshot.d.ts +173 -0
- package/dist/codegen/surface-snapshot.d.ts.map +1 -0
- package/dist/codegen/version-bump.d.ts +21 -0
- package/dist/codegen/version-bump.d.ts.map +1 -0
- package/dist/components/auto-release.d.ts +93 -0
- package/dist/components/auto-release.d.ts.map +1 -0
- package/dist/components/builders.d.ts +37 -0
- package/dist/components/builders.d.ts.map +1 -0
- package/dist/components/capability-plugin-loader.d.ts +111 -0
- package/dist/components/capability-plugin-loader.d.ts.map +1 -0
- package/dist/components/capability-plugin-schema.d.ts +24 -0
- package/dist/components/capability-plugin-schema.d.ts.map +1 -0
- package/dist/components/capability-plugin.d.ts +85 -0
- package/dist/components/capability-plugin.d.ts.map +1 -0
- package/dist/components/capability.d.ts +89 -0
- package/dist/components/capability.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +204 -0
- package/dist/components/cli-support.d.ts.map +1 -0
- package/dist/components/component.d.ts +179 -0
- package/dist/components/component.d.ts.map +1 -0
- package/dist/components/config-defaults.d.ts +41 -0
- package/dist/components/config-defaults.d.ts.map +1 -0
- package/dist/components/discover.d.ts +60 -0
- package/dist/components/discover.d.ts.map +1 -0
- package/dist/components/driver-output.d.ts +20 -0
- package/dist/components/driver-output.d.ts.map +1 -0
- package/dist/components/driver.d.ts +209 -0
- package/dist/components/driver.d.ts.map +1 -0
- package/dist/components/index.d.ts +22 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/manifest-persistence.d.ts +79 -0
- package/dist/components/manifest-persistence.d.ts.map +1 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts +27 -0
- package/dist/components/pilots/alb-ecs.pilot.d.ts.map +1 -0
- package/dist/components/pilots/dynamodb.pilot.d.ts +22 -0
- package/dist/components/pilots/dynamodb.pilot.d.ts.map +1 -0
- package/dist/components/pilots/jar-emr.pilot.d.ts +37 -0
- package/dist/components/pilots/jar-emr.pilot.d.ts.map +1 -0
- package/dist/components/pilots/lambda.pilot.d.ts +35 -0
- package/dist/components/pilots/lambda.pilot.d.ts.map +1 -0
- package/dist/components/pilots/neo4j-fanout.pilot.d.ts +17 -0
- package/dist/components/pilots/neo4j-fanout.pilot.d.ts.map +1 -0
- package/dist/components/pilots/project.d.ts +13 -0
- package/dist/components/pilots/project.d.ts.map +1 -0
- package/dist/components/presets/ecs-fargate.d.ts +59 -0
- package/dist/components/presets/ecs-fargate.d.ts.map +1 -0
- package/dist/components/presets/index.d.ts +29 -0
- package/dist/components/presets/index.d.ts.map +1 -0
- package/dist/components/presets/lambda.d.ts +35 -0
- package/dist/components/presets/lambda.d.ts.map +1 -0
- package/dist/components/presets/single-host-compose.d.ts +43 -0
- package/dist/components/presets/single-host-compose.d.ts.map +1 -0
- package/dist/components/registry.d.ts +29 -0
- package/dist/components/registry.d.ts.map +1 -0
- package/dist/components/starter-plugin.d.ts +51 -0
- package/dist/components/starter-plugin.d.ts.map +1 -0
- package/dist/components/temporal-codegen-loader.d.ts +27 -0
- package/dist/components/temporal-codegen-loader.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts +35 -0
- package/dist/components/verbs/__tests__/mock-cloud-executor.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-process-runner.d.ts +45 -0
- package/dist/components/verbs/__tests__/mock-process-runner.d.ts.map +1 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts +33 -0
- package/dist/components/verbs/__tests__/mock-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/bom-writer.d.ts +155 -0
- package/dist/components/verbs/bom-writer.d.ts.map +1 -0
- package/dist/components/verbs/build-archive.d.ts +205 -0
- package/dist/components/verbs/build-archive.d.ts.map +1 -0
- package/dist/components/verbs/build.d.ts +150 -0
- package/dist/components/verbs/build.d.ts.map +1 -0
- package/dist/components/verbs/cloud-executor.d.ts +88 -0
- package/dist/components/verbs/cloud-executor.d.ts.map +1 -0
- package/dist/components/verbs/component-bom.d.ts +103 -0
- package/dist/components/verbs/component-bom.d.ts.map +1 -0
- package/dist/components/verbs/index.d.ts +49 -0
- package/dist/components/verbs/index.d.ts.map +1 -0
- package/dist/components/verbs/license-policy.d.ts +56 -0
- package/dist/components/verbs/license-policy.d.ts.map +1 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts +81 -0
- package/dist/components/verbs/lockfile-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/process-runner.d.ts +64 -0
- package/dist/components/verbs/process-runner.d.ts.map +1 -0
- package/dist/components/verbs/reproducibility.d.ts +80 -0
- package/dist/components/verbs/reproducibility.d.ts.map +1 -0
- package/dist/components/verbs/sbom-generator.d.ts +157 -0
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/sbom.d.ts +79 -0
- package/dist/components/verbs/sbom.d.ts.map +1 -0
- package/dist/components/verbs/shell.d.ts +35 -0
- package/dist/components/verbs/shell.d.ts.map +1 -0
- package/dist/components/verbs/sign.d.ts +222 -0
- package/dist/components/verbs/sign.d.ts.map +1 -0
- package/dist/components/verbs/stub.d.ts +18 -0
- package/dist/components/verbs/stub.d.ts.map +1 -0
- package/dist/components/verbs/tool-sbom-generator.d.ts +51 -0
- package/dist/components/verbs/tool-sbom-generator.d.ts.map +1 -0
- package/dist/components/verbs/verify.d.ts +106 -0
- package/dist/components/verbs/verify.d.ts.map +1 -0
- package/dist/components/verbs/vex.d.ts +65 -0
- package/dist/components/verbs/vex.d.ts.map +1 -0
- package/dist/components/verbs/vuln-gate.d.ts +91 -0
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -0
- package/dist/components/verbs/vuln-scan.d.ts +116 -0
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -0
- package/dist/components/verbs/wait-verify.d.ts +85 -0
- package/dist/components/verbs/wait-verify.d.ts.map +1 -0
- package/dist/config.d.ts +205 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicon.d.ts +78 -0
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/build-ledger-store.d.ts +121 -0
- package/dist/lifecycle/build-ledger-store.d.ts.map +1 -0
- package/dist/lifecycle/build-ledger.d.ts +225 -0
- package/dist/lifecycle/build-ledger.d.ts.map +1 -0
- package/dist/lifecycle/git.d.ts +84 -0
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +5 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/oras-referrer-lookup.d.ts +41 -0
- package/dist/lifecycle/oras-referrer-lookup.d.ts.map +1 -0
- package/dist/lifecycle/release-ledger.d.ts +122 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -0
- package/dist/lifecycle/status.d.ts +150 -0
- package/dist/lifecycle/status.d.ts.map +1 -0
- package/dist/lint/component-checks.d.ts +95 -0
- package/dist/lint/component-checks.d.ts.map +1 -0
- package/dist/lint/engine.d.ts +23 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lint/presets/strict.json +8 -1
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts +10 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts +3 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts +3 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts +4 -0
- package/dist/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts +20 -0
- package/dist/lint/rules/comp/comp001-publishes-never-applies.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts +28 -0
- package/dist/lint/rules/comp/comp002-dangling-wiring-ref.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts +39 -0
- package/dist/lint/rules/comp/comp003-mutating-no-rollback.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +37 -0
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts +43 -0
- package/dist/lint/rules/comp/comp005-capability-kind-is-noun.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts +22 -0
- package/dist/lint/rules/comp/comp006-shell-needs-reason.d.ts.map +1 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts +33 -0
- package/dist/lint/rules/comp/comp007-composition-sprawl.d.ts.map +1 -0
- package/dist/lint/rules/comp/index.d.ts +18 -0
- package/dist/lint/rules/comp/index.d.ts.map +1 -0
- package/dist/lint/rules/comp/support.d.ts +71 -0
- package/dist/lint/rules/comp/support.d.ts.map +1 -0
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activity-registry.d.ts +11 -6
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/activity-runtime.d.ts +24 -0
- package/dist/op/activity-runtime.d.ts.map +1 -0
- package/dist/op/builders.d.ts +56 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/index.d.ts +2 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/ownership.d.ts +20 -14
- package/dist/ownership.d.ts.map +1 -1
- package/package.json +14 -1
- package/src/audit/catalog.test.ts +74 -22
- package/src/audit/catalog.ts +74 -471
- package/src/audit/fetch.test.ts +112 -8
- package/src/audit/fetch.ts +53 -8
- package/src/audit/proof.ts +4 -2
- package/src/audit/report-html.test.ts +14 -7
- package/src/audit/report-model.ts +20 -9
- package/src/audit/report.test.ts +36 -13
- package/src/audit/report.ts +2 -0
- package/src/audit/rules-doc.test.ts +8 -6
- package/src/audit/rules-doc.ts +13 -5
- package/src/cli/commands/audit.ts +23 -18
- package/src/cli/commands/component-lint.test.ts +158 -0
- package/src/cli/commands/doctor.test.ts +116 -2
- package/src/cli/commands/doctor.ts +46 -0
- package/src/cli/commands/lexicon-rolling-upgrade.ts +198 -0
- package/src/cli/commands/lexicon-surface-diff.test.ts +104 -0
- package/src/cli/commands/lexicon-surface-diff.ts +185 -0
- package/src/cli/commands/lint.ts +142 -1
- package/src/cli/commands/pinned-upgrade.ts +204 -0
- package/src/cli/handlers/build.ts +58 -1
- package/src/cli/handlers/components.test.ts +504 -0
- package/src/cli/handlers/components.ts +404 -0
- package/src/cli/handlers/dev.ts +60 -1
- package/src/cli/handlers/graph.ts +47 -2
- package/src/cli/handlers/misc.ts +45 -1
- package/src/cli/handlers/run.test.ts +967 -3
- package/src/cli/handlers/run.ts +618 -11
- package/src/cli/main.test.ts +66 -0
- package/src/cli/main.ts +105 -2
- package/src/cli/registry.ts +35 -0
- package/src/codegen/fetch.test.ts +84 -3
- package/src/codegen/fetch.ts +76 -2
- package/src/codegen/lexicon-regen.test.ts +298 -0
- package/src/codegen/lexicon-regen.ts +545 -0
- package/src/codegen/pinned-upgrade.test.ts +399 -0
- package/src/codegen/pinned-upgrade.ts +423 -0
- package/src/codegen/rolling-upgrade.test.ts +333 -0
- package/src/codegen/rolling-upgrade.ts +320 -0
- package/src/codegen/surface-snapshot.test.ts +461 -0
- package/src/codegen/surface-snapshot.ts +546 -0
- package/src/codegen/version-bump.test.ts +47 -0
- package/src/codegen/version-bump.ts +39 -0
- package/src/components/README.md +130 -0
- package/src/components/SPRAWL-VALIDATION.md +181 -0
- package/src/components/__fixtures__/alb-ecs-service.json +51 -0
- package/src/components/__fixtures__/dynamodb-infra.json +32 -0
- package/src/components/__fixtures__/emr-job-consumer.json +26 -0
- package/src/components/__fixtures__/jar-lib-producer.json +16 -0
- package/src/components/__fixtures__/lambda-image-processor.json +28 -0
- package/src/components/__fixtures__/neo4j-fanout.json +34 -0
- package/src/components/__fixtures__/single-host-compose.json +29 -0
- package/src/components/auto-release.test.ts +217 -0
- package/src/components/auto-release.ts +216 -0
- package/src/components/builders.test.ts +45 -0
- package/src/components/builders.ts +71 -0
- package/src/components/capability-plugin-loader.ts +218 -0
- package/src/components/capability-plugin-schema.ts +56 -0
- package/src/components/capability-plugin.test.ts +235 -0
- package/src/components/capability-plugin.ts +108 -0
- package/src/components/capability.ts +117 -0
- package/src/components/cli-support.test.ts +579 -0
- package/src/components/cli-support.ts +481 -0
- package/src/components/component-schema.test.ts +265 -0
- package/src/components/component.schema.json +235 -0
- package/src/components/component.test.ts +251 -0
- package/src/components/component.ts +255 -0
- package/src/components/config-defaults.test.ts +263 -0
- package/src/components/config-defaults.ts +145 -0
- package/src/components/discover.test.ts +352 -0
- package/src/components/discover.ts +167 -0
- package/src/components/driver-output.ts +71 -0
- package/src/components/driver.test.ts +638 -0
- package/src/components/driver.ts +690 -0
- package/src/components/index.ts +113 -0
- package/src/components/manifest-persistence.test.ts +152 -0
- package/src/components/manifest-persistence.ts +164 -0
- package/src/components/pilots/README.md +33 -0
- package/src/components/pilots/alb-ecs.pilot.ts +63 -0
- package/src/components/pilots/dynamodb.pilot.ts +59 -0
- package/src/components/pilots/jar-emr.pilot.ts +69 -0
- package/src/components/pilots/lambda.pilot.ts +55 -0
- package/src/components/pilots/neo4j-fanout.pilot.ts +92 -0
- package/src/components/pilots/pilots-lint-clean.test.ts +78 -0
- package/src/components/pilots/pilots.test.ts +126 -0
- package/src/components/pilots/project.ts +13 -0
- package/src/components/presets/comp007-reduction.test.ts +122 -0
- package/src/components/presets/ecs-fargate.test.ts +84 -0
- package/src/components/presets/ecs-fargate.ts +103 -0
- package/src/components/presets/index.ts +32 -0
- package/src/components/presets/lambda.test.ts +35 -0
- package/src/components/presets/lambda.ts +53 -0
- package/src/components/presets/single-host-compose.test.ts +65 -0
- package/src/components/presets/single-host-compose.ts +64 -0
- package/src/components/registry.test.ts +112 -0
- package/src/components/registry.ts +37 -0
- package/src/components/starter-plugin.ts +105 -0
- package/src/components/temporal-codegen-loader.ts +41 -0
- package/src/components/verbs/__fixtures__/package-lock.json +45 -0
- package/src/components/verbs/__fixtures__/pom.xml +37 -0
- package/src/components/verbs/__fixtures__/schemas/cyclonedx-1.5.schema.json +3800 -0
- package/src/components/verbs/__fixtures__/schemas/cyclonedx-spdx-license.schema.json +621 -0
- package/src/components/verbs/__fixtures__/schemas/jsf-0.82.schema.json +240 -0
- package/src/components/verbs/__fixtures__/schemas/spdx-2.3.schema.json +740 -0
- package/src/components/verbs/__tests__/mock-cloud-executor.ts +102 -0
- package/src/components/verbs/__tests__/mock-process-runner.ts +79 -0
- package/src/components/verbs/__tests__/mock-sbom-generator.ts +85 -0
- package/src/components/verbs/bom-writer.test.ts +331 -0
- package/src/components/verbs/bom-writer.ts +386 -0
- package/src/components/verbs/build-archive.test.ts +251 -0
- package/src/components/verbs/build-archive.ts +296 -0
- package/src/components/verbs/build.test.ts +222 -0
- package/src/components/verbs/build.ts +252 -0
- package/src/components/verbs/cloud-executor.ts +181 -0
- package/src/components/verbs/component-bom.test.ts +219 -0
- package/src/components/verbs/component-bom.ts +189 -0
- package/src/components/verbs/index.ts +49 -0
- package/src/components/verbs/license-policy.ts +115 -0
- package/src/components/verbs/lockfile-sbom-generator.test.ts +195 -0
- package/src/components/verbs/lockfile-sbom-generator.ts +236 -0
- package/src/components/verbs/process-runner.test.ts +79 -0
- package/src/components/verbs/process-runner.ts +113 -0
- package/src/components/verbs/reproducibility.test.ts +24 -0
- package/src/components/verbs/reproducibility.ts +100 -0
- package/src/components/verbs/sbom-generator.test.ts +96 -0
- package/src/components/verbs/sbom-generator.ts +209 -0
- package/src/components/verbs/sbom.test.ts +184 -0
- package/src/components/verbs/sbom.ts +152 -0
- package/src/components/verbs/shell.test.ts +36 -0
- package/src/components/verbs/shell.ts +51 -0
- package/src/components/verbs/sign.test.ts +210 -0
- package/src/components/verbs/sign.ts +350 -0
- package/src/components/verbs/stub.ts +34 -0
- package/src/components/verbs/tool-sbom-generator.test.ts +194 -0
- package/src/components/verbs/tool-sbom-generator.ts +192 -0
- package/src/components/verbs/verify.test.ts +159 -0
- package/src/components/verbs/verify.ts +179 -0
- package/src/components/verbs/vex.ts +182 -0
- package/src/components/verbs/vuln-gate.test.ts +201 -0
- package/src/components/verbs/vuln-gate.ts +170 -0
- package/src/components/verbs/vuln-scan.test.ts +145 -0
- package/src/components/verbs/vuln-scan.ts +266 -0
- package/src/components/verbs/wait-verify.test.ts +111 -0
- package/src/components/verbs/wait-verify.ts +171 -0
- package/src/config.test.ts +74 -1
- package/src/config.ts +219 -0
- package/src/index.ts +32 -0
- package/src/lexicon.ts +88 -0
- package/src/lifecycle/build-ledger-store.test.ts +217 -0
- package/src/lifecycle/build-ledger-store.ts +165 -0
- package/src/lifecycle/build-ledger.test.ts +349 -0
- package/src/lifecycle/build-ledger.ts +305 -0
- package/src/lifecycle/git.test.ts +118 -0
- package/src/lifecycle/git.ts +149 -14
- package/src/lifecycle/index.ts +5 -0
- package/src/lifecycle/oras-referrer-lookup.test.ts +116 -0
- package/src/lifecycle/oras-referrer-lookup.ts +110 -0
- package/src/lifecycle/release-ledger.test.ts +209 -0
- package/src/lifecycle/release-ledger.ts +185 -0
- package/src/lifecycle/status.test.ts +330 -0
- package/src/lifecycle/status.ts +278 -0
- package/src/lint/component-checks.ts +148 -0
- package/src/lint/config.test.ts +21 -0
- package/src/lint/engine.ts +11 -2
- package/src/lint/presets/relaxed.json +8 -1
- package/src/lint/presets/strict.json +8 -1
- package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-a.component.ts +9 -0
- package/src/lint/rules/__fixtures__/comp/comp000-discovery-error/broken-b.component.ts +9 -0
- package/src/lint/rules/__fixtures__/comp/comp001/fail/orphan-lib.component.ts +11 -0
- package/src/lint/rules/__fixtures__/comp/comp001/pass/emr-job.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp001/pass/jar-lib.component.ts +11 -0
- package/src/lint/rules/__fixtures__/comp/comp002/fail/search-service.component.ts +27 -0
- package/src/lint/rules/__fixtures__/comp/comp002/pass/jar-lib.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp002/pass/search-service.component.ts +23 -0
- package/src/lint/rules/__fixtures__/comp/comp003/fail/migrator.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/migrator.component.ts +19 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/orders-table.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp004/fail/neo4j-cluster.component.ts +20 -0
- package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +23 -0
- package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp005/fail/search-service.component.ts +14 -0
- package/src/lint/rules/__fixtures__/comp/comp005/pass/search-service.component.ts +18 -0
- package/src/lint/rules/__fixtures__/comp/comp006/fail/legacy-tool.component.ts +10 -0
- package/src/lint/rules/__fixtures__/comp/comp006/pass/legacy-tool.component.ts +14 -0
- package/src/lint/rules/__fixtures__/comp/comp007/fail/inventory-table.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp007/fail/orders-table.component.ts +13 -0
- package/src/lint/rules/__fixtures__/comp/comp007/pass/orders-table.component.ts +12 -0
- package/src/lint/rules/__fixtures__/comp/comp007/pass/search-service.component.ts +18 -0
- package/src/lint/rules/comp/comp.test.ts +378 -0
- package/src/lint/rules/comp/comp001-publishes-never-applies.ts +78 -0
- package/src/lint/rules/comp/comp002-dangling-wiring-ref.ts +94 -0
- package/src/lint/rules/comp/comp003-mutating-no-rollback.ts +115 -0
- package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +66 -0
- package/src/lint/rules/comp/comp005-capability-kind-is-noun.ts +113 -0
- package/src/lint/rules/comp/comp006-shell-needs-reason.ts +55 -0
- package/src/lint/rules/comp/comp007-composition-sprawl.ts +71 -0
- package/src/lint/rules/comp/index.ts +37 -0
- package/src/lint/rules/comp/support.ts +173 -0
- package/src/lsp/lexicon-providers.test.ts +55 -0
- package/src/lsp/lexicon-providers.ts +13 -3
- package/src/op/activity-registry.test.ts +38 -0
- package/src/op/activity-registry.ts +31 -12
- package/src/op/activity-runtime.ts +73 -0
- package/src/op/builders.ts +92 -0
- package/src/op/index.ts +3 -1
- package/src/ownership.test.ts +24 -26
- package/src/ownership.ts +26 -38
package/src/cli/handlers/run.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { resolve, join } from "node:path";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
1
|
+
import { resolve, join, dirname } from "node:path";
|
|
2
|
+
import { existsSync, writeFileSync, mkdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { createConnection } from "node:net";
|
|
4
4
|
import { spawn as spawnChild, type ChildProcess } from "node:child_process";
|
|
5
|
-
import { loadChantConfig } from "../../config";
|
|
5
|
+
import { loadChantConfig, resolveAutoReleaseDisabled } from "../../config";
|
|
6
6
|
import { discoverOps } from "../../op/discover";
|
|
7
7
|
import { loadActivities, loadProfiles } from "../../op/activity-registry";
|
|
8
8
|
import { runOpLocally, findGate, LocalGateUnsupportedError, OpRunFailure } from "../../op/local-executor";
|
|
@@ -19,6 +19,13 @@ import {
|
|
|
19
19
|
type WorkflowHistoryRaw,
|
|
20
20
|
} from "./run-client";
|
|
21
21
|
import { generateReport, writeReport } from "./run-report";
|
|
22
|
+
import { runComponents, resolveComponentTargets, findComponentGate, listComponents } from "../../components/cli-support";
|
|
23
|
+
import { renderDriverHuman, renderDriverJson } from "../../components/driver-output";
|
|
24
|
+
import { loadComponentTemporalCodegen } from "../../components/temporal-codegen-loader";
|
|
25
|
+
import { applyConfigDefaults } from "../../components/config-defaults";
|
|
26
|
+
import { maybeRecordAutoRelease, extractRunDigestFromPhaseOutputs } from "../../components/auto-release";
|
|
27
|
+
import { maybePersistBuildManifest, extractRunManifestFromPhaseOutputs } from "../../components/manifest-persistence";
|
|
28
|
+
import type { DriverComponentResult } from "../../components/driver";
|
|
22
29
|
|
|
23
30
|
function kebabToCamel(s: string): string {
|
|
24
31
|
return s.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());
|
|
@@ -55,6 +62,8 @@ export async function makeTemporalClient(profileName: string | undefined, projec
|
|
|
55
62
|
// ── chant run list ──────────────────────────────────���─────────────────────────
|
|
56
63
|
|
|
57
64
|
export async function runOpList(ctx: CommandContext): Promise<number> {
|
|
65
|
+
if (ctx.args.components) return runComponentsList(ctx);
|
|
66
|
+
|
|
58
67
|
if (!requireTemporalMode(ctx, "chant run list")) return 1;
|
|
59
68
|
const { ops, errors } = await discoverOps();
|
|
60
69
|
|
|
@@ -118,16 +127,99 @@ export async function runOpList(ctx: CommandContext): Promise<number> {
|
|
|
118
127
|
return 0;
|
|
119
128
|
}
|
|
120
129
|
|
|
130
|
+
/**
|
|
131
|
+
* `chant run list --components` (#599) — the component counterpart of
|
|
132
|
+
* `runOpList` above, mirrored shape-for-shape: discover, print a header,
|
|
133
|
+
* best-effort annotate with Temporal run status, print one row per entry.
|
|
134
|
+
* Kept behind the same `requireTemporalMode` gate as the Op path — the whole
|
|
135
|
+
* point of this subcommand is the run-status annotation, and components have
|
|
136
|
+
* no local notion of a "run" to list either (mirrors the "Temporal-only
|
|
137
|
+
* subcommand guards" test coverage for the Op list/status/log/signal/cancel
|
|
138
|
+
* set).
|
|
139
|
+
*
|
|
140
|
+
* Discovery + column shape reuses `listComponents` (../../components/cli-
|
|
141
|
+
* support.ts), the same helper `chant list --components` already uses, so
|
|
142
|
+
* archetype inference/field projection isn't duplicated here — this function
|
|
143
|
+
* only adds the Temporal status column. Status lookups use
|
|
144
|
+
* `componentWorkflowId`, the id space `runOpSignal`/`runOpCancel` established
|
|
145
|
+
* for components (#589) — kept distinct from `resolveWorkflowId`'s Op id
|
|
146
|
+
* space so an Op and a component can share a name.
|
|
147
|
+
*/
|
|
148
|
+
async function runComponentsList(ctx: CommandContext): Promise<number> {
|
|
149
|
+
if (!requireTemporalMode(ctx, "chant run list --components")) return 1;
|
|
150
|
+
|
|
151
|
+
const projectPath = resolve(".");
|
|
152
|
+
const result = await listComponents(projectPath);
|
|
153
|
+
|
|
154
|
+
if (!result.success) {
|
|
155
|
+
for (const err of result.errors) console.error(formatError({ message: err }));
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (result.components.length === 0) {
|
|
160
|
+
console.error(formatWarning({ message: "No component definitions found (*.component.ts)" }));
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log(
|
|
165
|
+
"NAME".padEnd(22) +
|
|
166
|
+
"ARCHETYPE".padEnd(18) +
|
|
167
|
+
"PHASES".padEnd(8) +
|
|
168
|
+
"DEPENDS".padEnd(20) +
|
|
169
|
+
"FILE",
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
let runStatus: Map<string, string> | undefined;
|
|
173
|
+
try {
|
|
174
|
+
const { config } = await loadChantConfig(projectPath);
|
|
175
|
+
const profile = resolveProfile(config as Record<string, unknown>, ctx.args.profile);
|
|
176
|
+
const { Connection, Client } = await loadTemporalClient();
|
|
177
|
+
const connection = await Connection.connect(connectionOptions(profile));
|
|
178
|
+
const client = new Client({ connection, namespace: profile.namespace });
|
|
179
|
+
runStatus = new Map();
|
|
180
|
+
for (const { name } of result.components) {
|
|
181
|
+
try {
|
|
182
|
+
const desc = await client.workflow.getHandle(componentWorkflowId(name)).describe();
|
|
183
|
+
runStatus.set(name, desc.status.name);
|
|
184
|
+
} catch {
|
|
185
|
+
runStatus.set(name, "—");
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
} catch {
|
|
189
|
+
// Temporal not available — degrade gracefully
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (const c of result.components) {
|
|
193
|
+
const phases = String(c.phases.length);
|
|
194
|
+
const deps = c.dependsOn.join(",") || "—";
|
|
195
|
+
const status = runStatus?.get(c.name);
|
|
196
|
+
const statusStr = status ? ` [${status}]` : "";
|
|
197
|
+
|
|
198
|
+
console.log(
|
|
199
|
+
(c.name + statusStr).padEnd(22) +
|
|
200
|
+
c.archetype.padEnd(18) +
|
|
201
|
+
phases.padEnd(8) +
|
|
202
|
+
deps.padEnd(20) +
|
|
203
|
+
c.filePath,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
121
210
|
// ── chant run status <name> ───────────────────────────────────────────────────
|
|
122
211
|
|
|
123
212
|
export async function runOpStatus(ctx: CommandContext): Promise<number> {
|
|
124
213
|
if (!requireTemporalMode(ctx, "chant run status")) return 1;
|
|
125
214
|
const name = ctx.args.extraPositional;
|
|
126
215
|
if (!name) {
|
|
127
|
-
|
|
216
|
+
const label = ctx.args.components ? "Component" : "Op";
|
|
217
|
+
console.error(formatError({ message: `${label} name is required: chant run status <name>` }));
|
|
128
218
|
return 1;
|
|
129
219
|
}
|
|
130
220
|
|
|
221
|
+
if (ctx.args.components) return runComponentStatus(ctx, name);
|
|
222
|
+
|
|
131
223
|
const projectPath = resolve(".");
|
|
132
224
|
let client, desc: WorkflowExecutionDescription, history: WorkflowHistoryRaw;
|
|
133
225
|
try {
|
|
@@ -158,16 +250,57 @@ export async function runOpStatus(ctx: CommandContext): Promise<number> {
|
|
|
158
250
|
return 0;
|
|
159
251
|
}
|
|
160
252
|
|
|
253
|
+
/**
|
|
254
|
+
* `chant run status <name> --components` (#599) — the component counterpart
|
|
255
|
+
* of `runOpStatus` above. Identical describe+history rendering; the only
|
|
256
|
+
* difference is the workflow id (`componentWorkflowId`, not
|
|
257
|
+
* `resolveWorkflowId`) and the "Component:" label, mirroring how
|
|
258
|
+
* `runOpSignal`/`runOpCancel` already distinguish the two id spaces (#589).
|
|
259
|
+
*/
|
|
260
|
+
async function runComponentStatus(ctx: CommandContext, name: string): Promise<number> {
|
|
261
|
+
const projectPath = resolve(".");
|
|
262
|
+
let client, desc: WorkflowExecutionDescription, history: WorkflowHistoryRaw;
|
|
263
|
+
try {
|
|
264
|
+
({ client } = await makeTemporalClient(ctx.args.profile, projectPath));
|
|
265
|
+
const handle = client.workflow.getHandle(componentWorkflowId(name));
|
|
266
|
+
desc = await handle.describe();
|
|
267
|
+
history = await handle.fetchHistory();
|
|
268
|
+
} catch (err) {
|
|
269
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
270
|
+
return 1;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
console.log(formatBold(`Component: ${name}`));
|
|
274
|
+
console.log(` Workflow ID : ${desc.workflowId}`);
|
|
275
|
+
console.log(` Run ID : ${desc.runId}`);
|
|
276
|
+
console.log(` Status : ${desc.status.name}`);
|
|
277
|
+
console.log(` Task Queue : ${desc.taskQueue}`);
|
|
278
|
+
console.log(` Started : ${desc.startTime.toISOString()}`);
|
|
279
|
+
if (desc.closeTime) console.log(` Closed : ${desc.closeTime.toISOString()}`);
|
|
280
|
+
|
|
281
|
+
const events = history.events ?? [];
|
|
282
|
+
const completed = events.filter((e) => e.eventType === "ActivityTaskCompleted").length;
|
|
283
|
+
const scheduled = events.filter((e) => e.eventType === "ActivityTaskScheduled").length;
|
|
284
|
+
if (scheduled > 0) {
|
|
285
|
+
console.log(` Activities : ${completed}/${scheduled} completed`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
return 0;
|
|
289
|
+
}
|
|
290
|
+
|
|
161
291
|
// ── chant run log <name> ──────────────────────────────────────────────────────
|
|
162
292
|
|
|
163
293
|
export async function runOpLog(ctx: CommandContext): Promise<number> {
|
|
164
294
|
if (!requireTemporalMode(ctx, "chant run log")) return 1;
|
|
165
295
|
const name = ctx.args.extraPositional;
|
|
166
296
|
if (!name) {
|
|
167
|
-
|
|
297
|
+
const label = ctx.args.components ? "Component" : "Op";
|
|
298
|
+
console.error(formatError({ message: `${label} name is required: chant run log <name>` }));
|
|
168
299
|
return 1;
|
|
169
300
|
}
|
|
170
301
|
|
|
302
|
+
if (ctx.args.components) return runComponentLog(ctx, name);
|
|
303
|
+
|
|
171
304
|
const projectPath = resolve(".");
|
|
172
305
|
let client;
|
|
173
306
|
try {
|
|
@@ -204,35 +337,101 @@ export async function runOpLog(ctx: CommandContext): Promise<number> {
|
|
|
204
337
|
return 0;
|
|
205
338
|
}
|
|
206
339
|
|
|
340
|
+
/**
|
|
341
|
+
* `chant run log <name> --components` (#599) — the component counterpart of
|
|
342
|
+
* `runOpLog` above. Same table shape; the `WorkflowType` query needs the
|
|
343
|
+
* component's generated workflow function name rather than
|
|
344
|
+
* `workflowFnName`'s Op convention, so this loads the Temporal component
|
|
345
|
+
* codegen module (`../../components/temporal-codegen-loader.ts`, the same
|
|
346
|
+
* loader `runComponentTemporal` already uses) purely for its
|
|
347
|
+
* `componentWorkflowFnName` helper — no compilation happens here, `log` only
|
|
348
|
+
* reads past run history.
|
|
349
|
+
*/
|
|
350
|
+
async function runComponentLog(ctx: CommandContext, name: string): Promise<number> {
|
|
351
|
+
const projectPath = resolve(".");
|
|
352
|
+
let client;
|
|
353
|
+
try {
|
|
354
|
+
({ client } = await makeTemporalClient(ctx.args.profile, projectPath));
|
|
355
|
+
} catch (err) {
|
|
356
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
357
|
+
return 1;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
let fnName: string;
|
|
361
|
+
try {
|
|
362
|
+
const codegen = await loadComponentTemporalCodegen();
|
|
363
|
+
fnName = codegen.componentWorkflowFnName(name);
|
|
364
|
+
} catch (err) {
|
|
365
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
366
|
+
return 1;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
console.log(
|
|
370
|
+
"RUN-ID".padEnd(36) +
|
|
371
|
+
"STATUS".padEnd(16) +
|
|
372
|
+
"STARTED".padEnd(26) +
|
|
373
|
+
"CLOSED",
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
try {
|
|
377
|
+
for await (const run of client.workflow.list({ query: `WorkflowType = "${fnName}"` })) {
|
|
378
|
+
const start = run.startTime.toISOString().slice(0, 19).replace("T", " ");
|
|
379
|
+
const close = run.closeTime ? run.closeTime.toISOString().slice(0, 19).replace("T", " ") : "—";
|
|
380
|
+
console.log(
|
|
381
|
+
run.runId.padEnd(36) +
|
|
382
|
+
run.status.name.padEnd(16) +
|
|
383
|
+
start.padEnd(26) +
|
|
384
|
+
close,
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
} catch (err) {
|
|
388
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
389
|
+
return 1;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return 0;
|
|
393
|
+
}
|
|
394
|
+
|
|
207
395
|
// ── chant run signal <name> <signal> ─────────────────────────────────────────
|
|
208
396
|
|
|
397
|
+
/**
|
|
398
|
+
* `chant run signal <name> <signal> [--components]` — sends a signal to a
|
|
399
|
+
* running Op workflow by default, or a component workflow when `--components`
|
|
400
|
+
* is passed (#589): the durable path's gate is otherwise unclearable from the
|
|
401
|
+
* CLI. Resolves the workflow id via `componentWorkflowId` (`chant-component-
|
|
402
|
+
* <name>`) instead of `resolveWorkflowId` (`chant-op-<name>`) in that case —
|
|
403
|
+
* the two id spaces are kept distinct so an Op and a component can share a
|
|
404
|
+
* name without colliding.
|
|
405
|
+
*/
|
|
209
406
|
export async function runOpSignal(ctx: CommandContext): Promise<number> {
|
|
210
407
|
if (!requireTemporalMode(ctx, "chant run signal")) return 1;
|
|
211
408
|
const name = ctx.args.extraPositional;
|
|
212
409
|
const signalName = ctx.args.extraPositional2;
|
|
213
410
|
|
|
214
411
|
if (!name || !signalName) {
|
|
215
|
-
console.error(formatError({ message: "Usage: chant run signal <
|
|
412
|
+
console.error(formatError({ message: "Usage: chant run signal <name> <signal-name>" }));
|
|
216
413
|
return 1;
|
|
217
414
|
}
|
|
218
415
|
|
|
219
416
|
const projectPath = resolve(".");
|
|
417
|
+
const workflowId = ctx.args.components ? componentWorkflowId(name) : resolveWorkflowId(name);
|
|
220
418
|
let handle: WorkflowHandleRaw;
|
|
221
419
|
try {
|
|
222
420
|
const { client } = await makeTemporalClient(ctx.args.profile, projectPath);
|
|
223
|
-
handle = client.workflow.getHandle(
|
|
421
|
+
handle = client.workflow.getHandle(workflowId);
|
|
224
422
|
await handle.signal(signalName);
|
|
225
423
|
} catch (err) {
|
|
226
424
|
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
227
425
|
return 1;
|
|
228
426
|
}
|
|
229
427
|
|
|
230
|
-
console.error(formatSuccess(`Signal "${signalName}" sent to Op "${name}"`));
|
|
428
|
+
console.error(formatSuccess(`Signal "${signalName}" sent to ${ctx.args.components ? "component" : "Op"} "${name}"`));
|
|
231
429
|
return 0;
|
|
232
430
|
}
|
|
233
431
|
|
|
234
432
|
// ── chant run cancel <name> ───────────────────────────────────────────────────
|
|
235
433
|
|
|
434
|
+
/** `chant run cancel <name> [--components]` — cancels an Op workflow by default, or a component workflow when `--components` is passed (#589), mirroring `runOpSignal`'s id resolution. */
|
|
236
435
|
export async function runOpCancel(ctx: CommandContext): Promise<number> {
|
|
237
436
|
if (!requireTemporalMode(ctx, "chant run cancel")) return 1;
|
|
238
437
|
const name = ctx.args.extraPositional;
|
|
@@ -250,17 +449,18 @@ export async function runOpCancel(ctx: CommandContext): Promise<number> {
|
|
|
250
449
|
}
|
|
251
450
|
|
|
252
451
|
const projectPath = resolve(".");
|
|
452
|
+
const workflowId = ctx.args.components ? componentWorkflowId(name) : resolveWorkflowId(name);
|
|
253
453
|
let handle: WorkflowHandleRaw;
|
|
254
454
|
try {
|
|
255
455
|
const { client } = await makeTemporalClient(ctx.args.profile, projectPath);
|
|
256
|
-
handle = client.workflow.getHandle(
|
|
456
|
+
handle = client.workflow.getHandle(workflowId);
|
|
257
457
|
await handle.cancel();
|
|
258
458
|
} catch (err) {
|
|
259
459
|
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
260
460
|
return 1;
|
|
261
461
|
}
|
|
262
462
|
|
|
263
|
-
console.error(formatSuccess(`Cancellation requested for Op "${name}"`));
|
|
463
|
+
console.error(formatSuccess(`Cancellation requested for ${ctx.args.components ? "component" : "Op"} "${name}"`));
|
|
264
464
|
return 0;
|
|
265
465
|
}
|
|
266
466
|
|
|
@@ -303,8 +503,15 @@ function renderProgress(opName: string, history: WorkflowHistoryRaw): void {
|
|
|
303
503
|
* Local mode is the default — it runs the Op in-process with no Temporal
|
|
304
504
|
* server. `--temporal` opts into a cluster (gates, schedules, durable resume).
|
|
305
505
|
* `--report` reads a past durable run and is therefore Temporal-only.
|
|
506
|
+
*
|
|
507
|
+
* `chant run --components <name|all>` (#585) is a separate target: discovered
|
|
508
|
+
* `Component` declarations dispatched through the interpret driver
|
|
509
|
+
* (`../../components/driver.ts`) rather than a `*.op.ts` Op. Checked first,
|
|
510
|
+
* mirroring `runGraph`'s `if (ctx.args.components) return
|
|
511
|
+
* runComponentGraph(ctx)` branch (../handlers/graph.ts).
|
|
306
512
|
*/
|
|
307
513
|
export async function runOp(ctx: CommandContext): Promise<number> {
|
|
514
|
+
if (ctx.args.components) return runOpComponents(ctx);
|
|
308
515
|
if (ctx.args.local && ctx.args.temporal) {
|
|
309
516
|
console.error(formatError({
|
|
310
517
|
message: "--local and --temporal are mutually exclusive",
|
|
@@ -319,6 +526,396 @@ export async function runOp(ctx: CommandContext): Promise<number> {
|
|
|
319
526
|
return ctx.args.temporal ? runOpTemporal(ctx) : runOpLocal(ctx);
|
|
320
527
|
}
|
|
321
528
|
|
|
529
|
+
// ── Auto-release recording post-run (#597) ──────────────────────────────────
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* After a successful `chant run --components` (local executor), auto-emit
|
|
533
|
+
* one release record per successfully deployed component that published a
|
|
534
|
+
* digest-bearing artifact — reusing `maybeRecordAutoRelease`
|
|
535
|
+
* (../../components/auto-release.ts), which itself reuses
|
|
536
|
+
* `../../lifecycle/release-ledger.ts`'s `appendReleaseRecord` verbatim. Never
|
|
537
|
+
* called on a failed run: both call sites below only reach this after
|
|
538
|
+
* confirming `result.success`/`componentResult.ok`, so a failed deploy writes
|
|
539
|
+
* nothing, by construction.
|
|
540
|
+
*
|
|
541
|
+
* Also persists the component's accumulated `BuildArchiveManifest`, when its
|
|
542
|
+
* composition produced one, to the durable build-manifest store (#609,
|
|
543
|
+
* ../../components/manifest-persistence.ts, ../../lifecycle/build-ledger-
|
|
544
|
+
* store.ts) — the missing piece that lets `chant components status`'s
|
|
545
|
+
* `componentBom`/`build.reproducibility` resolve to a real manifest instead
|
|
546
|
+
* of always reporting `null`. Same `disabled` opt-out flag as the release
|
|
547
|
+
* record: both are "durably record this successful deploy" side effects, so
|
|
548
|
+
* `--no-release-record`/`release.autoRecord: false` gates persistence too
|
|
549
|
+
* rather than needing a second, easy-to-forget knob (see
|
|
550
|
+
* `ManifestPersistOptions.disabled`'s doc).
|
|
551
|
+
*
|
|
552
|
+
* Best-effort and silent on the happy path: a skip (opted out, no digest/
|
|
553
|
+
* manifest, no actor) is unremarkable and not printed; only an actual write
|
|
554
|
+
* failure (`reason: "error"`) is surfaced, as a warning — never a nonzero
|
|
555
|
+
* exit, since the deploy itself already succeeded and a ledger-write hiccup
|
|
556
|
+
* must not retroactively fail it.
|
|
557
|
+
*/
|
|
558
|
+
async function recordAutoReleasesForRun(
|
|
559
|
+
results: DriverComponentResult[],
|
|
560
|
+
env: string,
|
|
561
|
+
runId: string,
|
|
562
|
+
disabled: boolean,
|
|
563
|
+
): Promise<void> {
|
|
564
|
+
for (const componentResult of results) {
|
|
565
|
+
if (!componentResult.ok) continue;
|
|
566
|
+
const outcome = await maybeRecordAutoRelease(
|
|
567
|
+
{
|
|
568
|
+
component: componentResult.component,
|
|
569
|
+
env,
|
|
570
|
+
success: true,
|
|
571
|
+
records: componentResult.records,
|
|
572
|
+
runId,
|
|
573
|
+
},
|
|
574
|
+
{ disabled },
|
|
575
|
+
);
|
|
576
|
+
if (!outcome.recorded && outcome.reason === "error") {
|
|
577
|
+
console.error(formatWarning({
|
|
578
|
+
message: `release record for "${componentResult.component}"@${env} was not recorded: ${outcome.error}`,
|
|
579
|
+
}));
|
|
580
|
+
} else if (outcome.recorded) {
|
|
581
|
+
console.error(formatInfo(
|
|
582
|
+
`Recorded release: ${formatBold(componentResult.component)}@${env} -> ${outcome.record.digest} (commit ${outcome.commit.slice(0, 7)})`,
|
|
583
|
+
));
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const manifestOutcome = await maybePersistBuildManifest(
|
|
587
|
+
{ success: true, records: componentResult.records },
|
|
588
|
+
{ disabled },
|
|
589
|
+
);
|
|
590
|
+
if (!manifestOutcome.persisted && manifestOutcome.reason === "error") {
|
|
591
|
+
console.error(formatWarning({
|
|
592
|
+
message: `build manifest for "${componentResult.component}"@${env} was not persisted: ${manifestOutcome.error}`,
|
|
593
|
+
}));
|
|
594
|
+
} else if (manifestOutcome.persisted) {
|
|
595
|
+
console.error(formatInfo(
|
|
596
|
+
`Persisted build manifest: ${formatBold(componentResult.component)} -> ${manifestOutcome.manifestDigest} (commit ${manifestOutcome.commit.slice(0, 7)})`,
|
|
597
|
+
));
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// ── chant run --components <name|all> ────────────────────────────────────────
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* `chant run --components <name|all> [--env <env>] [--temporal]` (#585, and
|
|
606
|
+
* #589 for `--temporal`) — the interpret driver's CLI entrypoint. `args.path`
|
|
607
|
+
* is the component name (or `all`), matching `chant run <name>`'s Op-dispatch
|
|
608
|
+
* convention exactly (`args.path` is the Op name there too) rather than a
|
|
609
|
+
* project directory — components are always discovered from the current
|
|
610
|
+
* working directory, the same way Op discovery (`discoverOps()`) never takes
|
|
611
|
+
* a project-path argument either.
|
|
612
|
+
*
|
|
613
|
+
* Local mode (the default) resolves the selector through `runComponents`
|
|
614
|
+
* (`../../components/cli-support.ts`) and runs it on the local in-process
|
|
615
|
+
* executor; gated components are rejected before any step runs (matching
|
|
616
|
+
* `runOpLocal`'s pre-flight `findGate` guard) with an actionable message
|
|
617
|
+
* pointing at `--temporal`.
|
|
618
|
+
*
|
|
619
|
+
* `--temporal` (#589) takes the durable path instead: compiles the named
|
|
620
|
+
* component's composition to a Temporal workflow/worker (mirroring
|
|
621
|
+
* `Temporal::Op` codegen — see `runComponentTemporal` below), and gates are
|
|
622
|
+
* now ACCEPTED — a gate is durable wait-for-signal there, not a local
|
|
623
|
+
* in-process block. Scoped to a single named component (`all --temporal` is
|
|
624
|
+
* out of scope for #589: coordinating N durable workflows' cross-component
|
|
625
|
+
* `dependsOn` durably is a follow-up, not part of "compile a component's
|
|
626
|
+
* `deploy` composition into a durable orchestrator").
|
|
627
|
+
*
|
|
628
|
+
* On a successful run, auto-emits one release-ledger record per component
|
|
629
|
+
* that published a digest (#597, `recordAutoReleasesForRun` above) — a
|
|
630
|
+
* *post-run* CLI step, not a change to the driver itself (`../../components/
|
|
631
|
+
* driver.ts` stays capability-agnostic and knows nothing about the ledger).
|
|
632
|
+
* Opt out with `--no-release-record` or `chant.config.ts`'s
|
|
633
|
+
* `release.autoRecord: false`; the default is ON. A failed run never reaches
|
|
634
|
+
* this step, so it writes nothing.
|
|
635
|
+
*/
|
|
636
|
+
export async function runOpComponents(ctx: CommandContext): Promise<number> {
|
|
637
|
+
const selector = ctx.args.path;
|
|
638
|
+
if (!selector || selector === ".") {
|
|
639
|
+
console.error(formatError({
|
|
640
|
+
message: "Component name is required: chant run --components <name|all>",
|
|
641
|
+
hint: "Run `chant list --components` to see available components.",
|
|
642
|
+
}));
|
|
643
|
+
return 1;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (ctx.args.temporal) return runComponentTemporal(ctx, selector);
|
|
647
|
+
|
|
648
|
+
const env = ctx.args.env ?? "local";
|
|
649
|
+
// Seed cross-component/cross-stack outputs from upstream jobs' dumped files
|
|
650
|
+
// (`--seed-outputs`), so a single-component run resolves references to a
|
|
651
|
+
// component that ran in an earlier CI job.
|
|
652
|
+
const seededOutputs: Record<string, Record<string, unknown>> = {};
|
|
653
|
+
for (const file of ctx.args.seedOutputs ?? []) {
|
|
654
|
+
try {
|
|
655
|
+
Object.assign(seededOutputs, JSON.parse(readFileSync(resolve(file), "utf8")));
|
|
656
|
+
} catch (err) {
|
|
657
|
+
console.error(formatError({
|
|
658
|
+
message: `--seed-outputs: could not read "${file}": ${err instanceof Error ? err.message : String(err)}`,
|
|
659
|
+
}));
|
|
660
|
+
return 1;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
const result = await runComponents(resolve("."), selector, { env: ctx.args.env, componentOutputs: seededOutputs });
|
|
664
|
+
|
|
665
|
+
// Dump the accumulated outputs for a downstream job to seed from. Written
|
|
666
|
+
// even on failure (partial outputs) so a resumed run still has what completed.
|
|
667
|
+
if (ctx.args.dumpOutputs && result.run) {
|
|
668
|
+
const dumpPath = resolve(ctx.args.dumpOutputs);
|
|
669
|
+
mkdirSync(dirname(dumpPath), { recursive: true });
|
|
670
|
+
writeFileSync(dumpPath, JSON.stringify(result.run.componentOutputs, null, 2));
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (result.gateUnsupported) {
|
|
674
|
+
console.error(formatError({
|
|
675
|
+
message:
|
|
676
|
+
`component "${result.gateUnsupported.component}": gate "${result.gateUnsupported.signalName}" is not ` +
|
|
677
|
+
`supported on the local executor — gates need a durable runtime.`,
|
|
678
|
+
hint: "Re-run with `chant run --components " + result.gateUnsupported.component + " --temporal`.",
|
|
679
|
+
}));
|
|
680
|
+
return 1;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
if (!result.success && !result.run) {
|
|
684
|
+
console.error(formatError({ message: result.error ?? "Failed to run component(s)" }));
|
|
685
|
+
return 1;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (result.run) {
|
|
689
|
+
if (ctx.args.json) renderDriverJson(result.run); else renderDriverHuman(result.run);
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (result.success && result.run) {
|
|
693
|
+
const { config } = await loadChantConfig(resolve(".")).catch(() => ({ config: {} }));
|
|
694
|
+
const disabled = resolveAutoReleaseDisabled(config, ctx.args.noReleaseRecord);
|
|
695
|
+
await recordAutoReleasesForRun(result.run.results, env, `local-${Date.now()}`, disabled);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return result.success ? 0 : 1;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// ── chant run --components <name> --temporal (#589) ─────────────────────────
|
|
702
|
+
|
|
703
|
+
function componentWorkflowId(componentName: string): string {
|
|
704
|
+
return `chant-component-${componentName}`;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* `chant run --components <name> --temporal` (#589, epic #551 §5/§8) — the
|
|
709
|
+
* durable counterpart to `runOpComponents`'s local path. Mirrors
|
|
710
|
+
* `runOpTemporal`'s shape exactly (build+spawn worker, submit workflow, poll,
|
|
711
|
+
* report) but "build" here means compiling the component's composition
|
|
712
|
+
* on-the-fly via `loadComponentTemporalCodegen` (the Temporal lexicon's
|
|
713
|
+
* `serializeComponent`, mirroring `serializeOps`) rather than reading a
|
|
714
|
+
* pre-existing `dist/ops/<name>/worker.ts` — components have no separate
|
|
715
|
+
* `chant build` step that already produced generated files the way Ops do, so
|
|
716
|
+
* this generates `dist/components/<name>/{workflow,worker,activities}.ts`
|
|
717
|
+
* itself before spawning.
|
|
718
|
+
*
|
|
719
|
+
* Unlike the local executor, a `gate` anywhere in the component's
|
|
720
|
+
* composition is fully supported: the generated workflow durably waits for
|
|
721
|
+
* the signal (see `serializeComponent`'s codegen), survivable across a worker
|
|
722
|
+
* crash and clearable via `chant run signal <name> <signal> --components
|
|
723
|
+
* --temporal` (`runOpSignal` above, extended for components alongside this
|
|
724
|
+
* issue).
|
|
725
|
+
*/
|
|
726
|
+
async function runComponentTemporal(ctx: CommandContext, selector: string): Promise<number> {
|
|
727
|
+
if (selector === "all") {
|
|
728
|
+
console.error(formatError({
|
|
729
|
+
message: "`chant run --components all --temporal` is not supported",
|
|
730
|
+
hint: "Pass a single component name — durable execution is compiled and run per component (see epic #551 #589).",
|
|
731
|
+
}));
|
|
732
|
+
return 1;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
const projectPath = resolve(".");
|
|
736
|
+
const resolved = await resolveComponentTargets(projectPath, selector);
|
|
737
|
+
if (!resolved.success || resolved.targets.length === 0) {
|
|
738
|
+
console.error(formatError({ message: resolved.error ?? `Component "${selector}" not found` }));
|
|
739
|
+
return 1;
|
|
740
|
+
}
|
|
741
|
+
const component = resolved.targets[0];
|
|
742
|
+
|
|
743
|
+
// Load config + profile (mirrors runOpTemporal).
|
|
744
|
+
const { config: chantConfig } = await loadChantConfig(projectPath);
|
|
745
|
+
let profile;
|
|
746
|
+
try {
|
|
747
|
+
profile = resolveProfile(chantConfig as Record<string, unknown>, ctx.args.profile);
|
|
748
|
+
} catch (err) {
|
|
749
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
750
|
+
return 1;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// Compile the component to workflow/worker/activities under dist/components/<name>/.
|
|
754
|
+
let codegen;
|
|
755
|
+
try {
|
|
756
|
+
codegen = await loadComponentTemporalCodegen();
|
|
757
|
+
} catch (err) {
|
|
758
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
759
|
+
return 1;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// (#629) Fill `chant.config.ts`'s `sbom`/`signing`/`vulnPolicy` defaults into
|
|
763
|
+
// every recognized step BEFORE codegen — same pass the interpret/local path
|
|
764
|
+
// runs in `runComponents` (../../components/cli-support.ts). The Temporal path
|
|
765
|
+
// *inlines* the resolved composition into the generated workflow/activities,
|
|
766
|
+
// so if we serialized the raw component the durable path would silently drop
|
|
767
|
+
// project-level supply-chain defaults the local path honors. (The GitLab
|
|
768
|
+
// generate path needs no equivalent: it emits thin `chant run --components`
|
|
769
|
+
// trigger jobs, so defaults are applied at run time inside the triggered job.)
|
|
770
|
+
const resolvedComponent = applyConfigDefaults(component, chantConfig);
|
|
771
|
+
const files = codegen.serializeComponent(resolvedComponent, { env: ctx.args.env });
|
|
772
|
+
for (const [relPath, content] of Object.entries(files)) {
|
|
773
|
+
const outPath = join(projectPath, "dist", relPath);
|
|
774
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
775
|
+
writeFileSync(outPath, content);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
const workerPath = join(projectPath, "dist", "components", component.name, "worker.ts");
|
|
779
|
+
|
|
780
|
+
// autoStart: spin up temporal server if needed (mirrors runOpTemporal).
|
|
781
|
+
if (profile.autoStart) {
|
|
782
|
+
console.error(formatInfo("autoStart: checking Temporal server..."));
|
|
783
|
+
try {
|
|
784
|
+
await waitForTemporalServer(profile.address, 2000);
|
|
785
|
+
console.error(formatInfo("Temporal server already running."));
|
|
786
|
+
} catch {
|
|
787
|
+
console.error(formatInfo("Starting temporal server start-dev..."));
|
|
788
|
+
spawnChild("temporal", ["server", "start-dev"], {
|
|
789
|
+
cwd: projectPath,
|
|
790
|
+
stdio: "ignore",
|
|
791
|
+
detached: true,
|
|
792
|
+
}).unref();
|
|
793
|
+
await waitForTemporalServer(profile.address, 30_000);
|
|
794
|
+
console.error(formatSuccess("Temporal server ready."));
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
let client;
|
|
799
|
+
try {
|
|
800
|
+
({ client } = await makeTemporalClient(ctx.args.profile, projectPath));
|
|
801
|
+
} catch (err) {
|
|
802
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
803
|
+
return 1;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
const profileName = ctx.args.profile ??
|
|
807
|
+
(((chantConfig as Record<string, unknown>).temporal as Record<string, unknown> | undefined)?.defaultProfile as string | undefined) ??
|
|
808
|
+
"local";
|
|
809
|
+
|
|
810
|
+
console.error(formatInfo(`Spawning worker for component "${component.name}" (profile: ${profileName})...`));
|
|
811
|
+
const workerProcess: ChildProcess = spawnChild("npx", ["tsx", workerPath], {
|
|
812
|
+
cwd: projectPath,
|
|
813
|
+
env: { ...process.env, TEMPORAL_PROFILE: profileName },
|
|
814
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
const workflowId = componentWorkflowId(component.name);
|
|
818
|
+
const fnName = codegen.componentWorkflowFnName(component.name);
|
|
819
|
+
const taskQueue = profile.taskQueue ?? component.name;
|
|
820
|
+
|
|
821
|
+
let handle: WorkflowHandleRaw;
|
|
822
|
+
try {
|
|
823
|
+
handle = await client.workflow.start(fnName, {
|
|
824
|
+
taskQueue,
|
|
825
|
+
workflowId,
|
|
826
|
+
workflowIdConflictPolicy: "FAIL",
|
|
827
|
+
});
|
|
828
|
+
console.error(formatSuccess(`Workflow started: ${workflowId}`));
|
|
829
|
+
} catch (err) {
|
|
830
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
831
|
+
try { workerProcess.kill(); } catch { /* ignore */ }
|
|
832
|
+
return 1;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
const gate = findComponentGate(component);
|
|
836
|
+
if (gate) {
|
|
837
|
+
console.error(formatInfo(
|
|
838
|
+
`Component has a gate ("${gate.signalName}") — unblock it with: chant run signal ${component.name} ${gate.signalName} --components --temporal`,
|
|
839
|
+
));
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
let finalDesc: WorkflowExecutionDescription | undefined;
|
|
843
|
+
|
|
844
|
+
try {
|
|
845
|
+
while (true) {
|
|
846
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
847
|
+
const desc = await handle.describe();
|
|
848
|
+
const history = await handle.fetchHistory();
|
|
849
|
+
renderProgress(component.name, history);
|
|
850
|
+
if (TERMINAL_STATUSES.has(desc.status.name)) {
|
|
851
|
+
process.stderr.write("\n");
|
|
852
|
+
finalDesc = desc;
|
|
853
|
+
break;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
} catch (err) {
|
|
857
|
+
process.stderr.write("\n");
|
|
858
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
859
|
+
return 1;
|
|
860
|
+
} finally {
|
|
861
|
+
try { workerProcess.kill(); } catch { /* ignore */ }
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
if (!finalDesc) return 1;
|
|
865
|
+
|
|
866
|
+
const status = finalDesc.status.name;
|
|
867
|
+
console.error(status === "COMPLETED"
|
|
868
|
+
? formatSuccess(`Component "${component.name}" completed successfully.`)
|
|
869
|
+
: formatError({ message: `Component "${component.name}" ended with status: ${status}` }),
|
|
870
|
+
);
|
|
871
|
+
|
|
872
|
+
if (status === "COMPLETED") {
|
|
873
|
+
// (#597) Auto-emit a release record post-run — never inside the generated
|
|
874
|
+
// workflow (determinism). The workflow returns its final phaseOutputs
|
|
875
|
+
// (see serializeComponent's codegen) precisely so this read is possible;
|
|
876
|
+
// handle.result() on an already-COMPLETED workflow is a plain historical
|
|
877
|
+
// read, not a new activity/side effect.
|
|
878
|
+
let digest: string | undefined;
|
|
879
|
+
let manifest: ReturnType<typeof extractRunManifestFromPhaseOutputs>;
|
|
880
|
+
try {
|
|
881
|
+
const workflowResult = await handle.result() as { phaseOutputs?: Record<string, Record<string, unknown>> } | undefined;
|
|
882
|
+
digest = extractRunDigestFromPhaseOutputs(workflowResult?.phaseOutputs);
|
|
883
|
+
manifest = extractRunManifestFromPhaseOutputs(workflowResult?.phaseOutputs);
|
|
884
|
+
} catch {
|
|
885
|
+
digest = undefined;
|
|
886
|
+
manifest = undefined;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const { config } = await loadChantConfig(projectPath).catch(() => ({ config: {} }));
|
|
890
|
+
const disabled = resolveAutoReleaseDisabled(config, ctx.args.noReleaseRecord);
|
|
891
|
+
const env = ctx.args.env ?? "local";
|
|
892
|
+
const outcome = await maybeRecordAutoRelease(
|
|
893
|
+
{ component: component.name, env, success: true, digest, runId: finalDesc.runId },
|
|
894
|
+
{ disabled },
|
|
895
|
+
);
|
|
896
|
+
if (!outcome.recorded && outcome.reason === "error") {
|
|
897
|
+
console.error(formatWarning({ message: `release record for "${component.name}"@${env} was not recorded: ${outcome.error}` }));
|
|
898
|
+
} else if (outcome.recorded) {
|
|
899
|
+
console.error(formatInfo(
|
|
900
|
+
`Recorded release: ${formatBold(component.name)}@${env} -> ${outcome.record.digest} (commit ${outcome.commit.slice(0, 7)})`,
|
|
901
|
+
));
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
// (#609) Persist the run's build manifest post-run, same opt-out flag as
|
|
905
|
+
// the release record above — see ../../components/manifest-persistence.ts.
|
|
906
|
+
const manifestOutcome = await maybePersistBuildManifest({ success: true, manifest }, { disabled });
|
|
907
|
+
if (!manifestOutcome.persisted && manifestOutcome.reason === "error") {
|
|
908
|
+
console.error(formatWarning({ message: `build manifest for "${component.name}"@${env} was not persisted: ${manifestOutcome.error}` }));
|
|
909
|
+
} else if (manifestOutcome.persisted) {
|
|
910
|
+
console.error(formatInfo(
|
|
911
|
+
`Persisted build manifest: ${formatBold(component.name)} -> ${manifestOutcome.manifestDigest} (commit ${manifestOutcome.commit.slice(0, 7)})`,
|
|
912
|
+
));
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
return status === "COMPLETED" ? 0 : 1;
|
|
917
|
+
}
|
|
918
|
+
|
|
322
919
|
/**
|
|
323
920
|
* Run an Op in-process via the local executor — no Temporal worker, server, or
|
|
324
921
|
* built `worker.ts`. Reads the Op config straight from discovery and resolves
|
|
@@ -360,9 +957,19 @@ export async function runOpLocal(ctx: CommandContext): Promise<number> {
|
|
|
360
957
|
return 1;
|
|
361
958
|
}
|
|
362
959
|
|
|
960
|
+
// The project's configured lexicons decide which cloud appliers to load
|
|
961
|
+
// (aws → floci, gcp → gcpApply, azure → az group). Best-effort: an unreadable
|
|
962
|
+
// config just yields the temporal base activities.
|
|
963
|
+
let lexicons: string[] = [];
|
|
964
|
+
try {
|
|
965
|
+
lexicons = (await loadChantConfig(process.cwd())).config.lexicons ?? [];
|
|
966
|
+
} catch {
|
|
967
|
+
// No/invalid chant.config — fall back to base activities only.
|
|
968
|
+
}
|
|
969
|
+
|
|
363
970
|
let activities, profiles;
|
|
364
971
|
try {
|
|
365
|
-
[activities, profiles] = await Promise.all([loadActivities(), loadProfiles()]);
|
|
972
|
+
[activities, profiles] = await Promise.all([loadActivities(lexicons), loadProfiles()]);
|
|
366
973
|
} catch (err) {
|
|
367
974
|
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
368
975
|
return 1;
|