@intentius/chant 0.57.0 → 0.58.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 +51 -1
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/core.d.ts +20 -1
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +14 -8
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/lineage.d.ts +10 -0
- package/dist/audit/lineage.d.ts.map +1 -0
- package/dist/audit/prior-art.d.ts +385 -0
- package/dist/audit/prior-art.d.ts.map +1 -0
- package/dist/audit/proof.d.ts +16 -0
- package/dist/audit/proof.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +8 -1
- package/dist/audit/report-model.d.ts.map +1 -1
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/rules-doc.d.ts +3 -0
- package/dist/audit/rules-doc.d.ts.map +1 -1
- package/dist/audit/secrets.d.ts +15 -0
- package/dist/audit/secrets.d.ts.map +1 -1
- package/dist/audit/terraform-state.d.ts +46 -0
- package/dist/audit/terraform-state.d.ts.map +1 -0
- package/dist/build.d.ts +17 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/claimed-fields.d.ts +161 -0
- package/dist/claimed-fields.d.ts.map +1 -0
- package/dist/cli/build-params-cli.d.ts +2 -2
- package/dist/cli/command-group.d.ts +14 -0
- package/dist/cli/command-group.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +17 -1
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon-docs.d.ts +1 -1
- package/dist/cli/commands/check-lexicon-examples.d.ts +16 -6
- package/dist/cli/commands/check-lexicon-examples.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/codegen.d.ts +1 -0
- package/dist/cli/commands/init-lexicon/templates/codegen.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon/templates/project.d.ts +7 -0
- package/dist/cli/commands/init-lexicon/templates/project.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts +2 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +82 -16
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts +49 -42
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts +28 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts +16 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/resources/context.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +26 -9
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/generate-post-synth-barrel.d.ts +1 -1
- package/dist/components/auto-release.d.ts +10 -20
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability.d.ts +4 -4
- package/dist/components/cli-support.d.ts +20 -21
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +3 -3
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/driver-output.d.ts.map +1 -1
- package/dist/components/driver.d.ts +66 -36
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/manifest-persistence.d.ts +1 -9
- package/dist/components/manifest-persistence.d.ts.map +1 -1
- package/dist/components/run-progress.d.ts +6 -6
- package/dist/components/run-progress.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts +9 -15
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/components/verbs/verify.d.ts +2 -2
- package/dist/deep-observation.d.ts +17 -0
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/discovery/files.d.ts +4 -4
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +33 -0
- package/dist/discovery/param-deps.d.ts.map +1 -1
- package/dist/discovery/sandbox/bundle.d.ts.map +1 -1
- package/dist/discovery/sandbox/config-wire.d.ts +2 -2
- package/dist/fold/foldable-helpers.d.ts +5 -1
- package/dist/fold/foldable-helpers.d.ts.map +1 -1
- package/dist/fold-provenance.d.ts +236 -0
- package/dist/fold-provenance.d.ts.map +1 -0
- package/dist/graph-ops.d.ts +1 -1
- package/dist/held-elsewhere.d.ts +85 -0
- package/dist/held-elsewhere.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts +3 -3
- package/dist/lexicon-config.d.ts +4 -4
- package/dist/lexicon-plugin-helpers.d.ts +1 -1
- package/dist/lexicon.d.ts +104 -14
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/change-set.d.ts +13 -0
- package/dist/lifecycle/change-set.d.ts.map +1 -1
- package/dist/lifecycle/deep-diff.d.ts +133 -6
- package/dist/lifecycle/deep-diff.d.ts.map +1 -1
- package/dist/lifecycle/deep-observe.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +71 -3
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts +2 -2
- package/dist/lifecycle/run-ledger.d.ts +53 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -0
- package/dist/lifecycle/symptoms.d.ts +3 -3
- package/dist/lifecycle/symptoms.d.ts.map +1 -1
- package/dist/lint/config.d.ts +81 -2
- package/dist/lint/config.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +55 -2
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.d.ts.map +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts +1 -1
- package/dist/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.d.ts.map +1 -1
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts +44 -0
- package/dist/lint/rules/comp/comp004-gate-needs-durable-runtime.d.ts.map +1 -0
- package/dist/lint/rules/comp/index.d.ts +1 -1
- package/dist/lint/rules/comp/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.d.ts +16 -0
- package/dist/lint/rules/op/index.d.ts.map +1 -0
- package/dist/lint/rules/op/ops012-activity-contract.d.ts +27 -0
- package/dist/lint/rules/op/ops012-activity-contract.d.ts.map +1 -0
- package/dist/lint/rules/op/ops013-step-output-ref.d.ts +61 -0
- package/dist/lint/rules/op/ops013-step-output-ref.d.ts.map +1 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts +55 -0
- package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -0
- package/dist/lint/rules/op/support.d.ts +12 -0
- package/dist/lint/rules/op/support.d.ts.map +1 -0
- package/dist/lint/suppressions.d.ts +108 -0
- package/dist/lint/suppressions.d.ts.map +1 -0
- package/dist/live-endpoint.d.ts +1 -1
- package/dist/op/activities/activity-contracts.d.ts +54 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -0
- package/dist/op/activities/apply.d.ts +262 -0
- package/dist/op/activities/apply.d.ts.map +1 -0
- package/dist/op/activities/build.d.ts +13 -0
- package/dist/op/activities/build.d.ts.map +1 -0
- package/dist/op/activities/converge.d.ts +110 -0
- package/dist/op/activities/converge.d.ts.map +1 -0
- package/dist/op/activities/env-teardown.d.ts +76 -0
- package/dist/op/activities/env-teardown.d.ts.map +1 -0
- package/dist/op/activities/guard-validate.d.ts +64 -0
- package/dist/op/activities/guard-validate.d.ts.map +1 -0
- package/dist/op/activities/http-check.d.ts +34 -0
- package/dist/op/activities/http-check.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +31 -0
- package/dist/op/activities/index.d.ts.map +1 -0
- package/dist/op/activities/lexicon-upgrade.d.ts +182 -0
- package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -0
- package/dist/op/activities/lifecycle.d.ts +42 -0
- package/dist/op/activities/lifecycle.d.ts.map +1 -0
- package/dist/op/activities/pipeline-audit.d.ts +84 -0
- package/dist/op/activities/pipeline-audit.d.ts.map +1 -0
- package/dist/op/activities/policy.d.ts +17 -0
- package/dist/op/activities/policy.d.ts.map +1 -0
- package/dist/op/activities/reconcile.d.ts +89 -0
- package/dist/op/activities/reconcile.d.ts.map +1 -0
- package/dist/op/activities/shell.d.ts +13 -0
- package/dist/op/activities/shell.d.ts.map +1 -0
- package/dist/op/activities/teardown.d.ts +10 -0
- package/dist/op/activities/teardown.d.ts.map +1 -0
- package/dist/op/activities/util.d.ts +7 -0
- package/dist/op/activities/util.d.ts.map +1 -0
- package/dist/op/activities/wait.d.ts +28 -0
- package/dist/op/activities/wait.d.ts.map +1 -0
- package/dist/op/activities/workflow-audit.d.ts +92 -0
- package/dist/op/activities/workflow-audit.d.ts.map +1 -0
- package/dist/op/activity-contract-registry.d.ts +76 -0
- package/dist/op/activity-contract-registry.d.ts.map +1 -0
- package/dist/op/activity-contract.d.ts +25 -18
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/activity-failure.d.ts +28 -0
- package/dist/op/activity-failure.d.ts.map +1 -0
- package/dist/op/activity-profiles.d.ts +118 -0
- package/dist/op/activity-profiles.d.ts.map +1 -0
- package/dist/op/activity-registry.d.ts +22 -38
- package/dist/op/activity-registry.d.ts.map +1 -1
- package/dist/op/activity-runtime.d.ts +3 -14
- package/dist/op/activity-runtime.d.ts.map +1 -1
- package/dist/op/builders.d.ts +84 -29
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/apply-op.d.ts +113 -0
- package/dist/op/composites/apply-op.d.ts.map +1 -0
- package/dist/op/composites/converge-op.d.ts +120 -0
- package/dist/op/composites/converge-op.d.ts.map +1 -0
- package/dist/op/composites/index.d.ts +26 -0
- package/dist/op/composites/index.d.ts.map +1 -0
- package/dist/op/composites/lexicon-upgrade-op.d.ts +78 -0
- package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -0
- package/dist/op/composites/pipeline-audit-op.d.ts +50 -0
- package/dist/op/composites/pipeline-audit-op.d.ts.map +1 -0
- package/dist/op/composites/reconcile-op.d.ts +57 -0
- package/dist/op/composites/reconcile-op.d.ts.map +1 -0
- package/dist/op/composites/watch-op.d.ts +60 -0
- package/dist/op/composites/watch-op.d.ts.map +1 -0
- package/dist/op/composites/workflow-audit-op.d.ts +57 -0
- package/dist/op/composites/workflow-audit-op.d.ts.map +1 -0
- package/dist/op/converge-rule.d.ts +12 -10
- package/dist/op/converge-rule.d.ts.map +1 -1
- package/dist/op/cron.d.ts +51 -0
- package/dist/op/cron.d.ts.map +1 -0
- package/dist/op/discover.d.ts +9 -0
- package/dist/op/discover.d.ts.map +1 -1
- package/dist/op/duration.d.ts +11 -0
- package/dist/op/duration.d.ts.map +1 -0
- package/dist/op/emulator-lifecycle.d.ts.map +1 -1
- package/dist/op/gate.d.ts +90 -0
- package/dist/op/gate.d.ts.map +1 -0
- package/dist/op/generate-pipeline.d.ts +9 -0
- package/dist/op/generate-pipeline.d.ts.map +1 -1
- package/dist/op/index.d.ts +23 -7
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +114 -28
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-output.d.ts +11 -1
- package/dist/op/local-output.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +184 -0
- package/dist/op/op-ir.d.ts.map +1 -0
- package/dist/op/op-verb-class.d.ts +10 -2
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/operator.d.ts +30 -5
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/receipt-store.d.ts +1 -1
- package/dist/op/receipt-store.d.ts.map +1 -1
- package/dist/op/resource.d.ts +15 -1
- package/dist/op/resource.d.ts.map +1 -1
- package/dist/op/runtime.d.ts +200 -0
- package/dist/op/runtime.d.ts.map +1 -0
- package/dist/op/runtimes/local.d.ts +29 -0
- package/dist/op/runtimes/local.d.ts.map +1 -0
- package/dist/op/step-output-ref.d.ts +15 -13
- package/dist/op/step-output-ref.d.ts.map +1 -1
- package/dist/op/types.d.ts +79 -27
- package/dist/op/types.d.ts.map +1 -1
- package/dist/ownership.d.ts +1 -1
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/serializer-walker.d.ts.map +1 -1
- package/package.json +6 -1
- package/src/audit/catalog.test.ts +79 -3
- package/src/audit/catalog.ts +111 -13
- package/src/audit/core.test.ts +26 -0
- package/src/audit/core.ts +61 -17
- package/src/audit/discover.test.ts +39 -0
- package/src/audit/discover.ts +91 -15
- package/src/audit/lineage.ts +100 -0
- package/src/audit/prior-art.ts +153 -0
- package/src/audit/proof.test.ts +67 -0
- package/src/audit/proof.ts +70 -0
- package/src/audit/report-html.ts +9 -4
- package/src/audit/report-model.ts +16 -2
- package/src/audit/report.test.ts +33 -0
- package/src/audit/report.ts +5 -3
- package/src/audit/rules-doc.test.ts +34 -2
- package/src/audit/rules-doc.ts +82 -9
- package/src/audit/secrets.ts +15 -3
- package/src/audit/terraform-state.test.ts +144 -0
- package/src/audit/terraform-state.ts +131 -0
- package/src/build.ts +31 -1
- package/src/claimed-fields.test.ts +145 -0
- package/src/claimed-fields.ts +208 -0
- package/src/cli/build-params-cli.ts +2 -2
- package/src/cli/command-group.ts +14 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/.terraform/providers/lock.txt +1 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/main.tf +1 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/modules/foo/main.tf +1 -0
- package/src/cli/commands/__fixtures__/audit-terraform/infra/variables.tf +3 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +13 -4
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/docs-cli.ts +4 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/codegen/package.ts +1 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/src/package-cli.ts +21 -0
- package/src/cli/commands/__snapshots__/init-lexicon.test.ts.snap +1 -0
- package/src/cli/commands/audit.test.ts +189 -11
- package/src/cli/commands/audit.ts +73 -27
- package/src/cli/commands/build.test.ts +292 -9
- package/src/cli/commands/build.ts +156 -24
- package/src/cli/commands/check-lexicon-docs.ts +1 -1
- package/src/cli/commands/check-lexicon-examples.test.ts +29 -1
- package/src/cli/commands/check-lexicon-examples.ts +42 -10
- package/src/cli/commands/init-lexicon/templates/codegen.ts +9 -0
- package/src/cli/commands/init-lexicon/templates/project.ts +44 -4
- package/src/cli/commands/init-lexicon.test.ts +97 -2
- package/src/cli/commands/init-lexicon.ts +4 -2
- package/src/cli/commands/init.test.ts +35 -1
- package/src/cli/commands/init.ts +14 -3
- package/src/cli/commands/lint.test.ts +48 -0
- package/src/cli/commands/lint.ts +123 -0
- package/src/cli/commands/onboard.test.ts +75 -0
- package/src/cli/commands/onboard.ts +54 -23
- package/src/cli/handlers/build.test.ts +81 -1
- package/src/cli/handlers/build.ts +15 -1
- package/src/cli/handlers/graph.test.ts +3 -3
- package/src/cli/handlers/lifecycle.test.ts +195 -12
- package/src/cli/handlers/lifecycle.ts +123 -6
- package/src/cli/handlers/misc.ts +1 -1
- package/src/cli/handlers/operator.test.ts +183 -11
- package/src/cli/handlers/operator.ts +260 -55
- package/src/cli/handlers/run.test.ts +431 -1287
- package/src/cli/handlers/run.ts +365 -915
- package/src/cli/main.test.ts +23 -15
- package/src/cli/main.ts +88 -33
- package/src/cli/mcp/op-tools.ts +147 -88
- package/src/cli/mcp/resource-handlers.ts +10 -37
- package/src/cli/mcp/resources/context.ts +11 -12
- package/src/cli/mcp/server.test.ts +25 -27
- package/src/cli/mcp/server.ts +2 -2
- package/src/cli/registry.ts +26 -9
- package/src/codegen/docs.ts +1 -1
- package/src/codegen/generate-post-synth-barrel.test.ts +1 -1
- package/src/codegen/generate-post-synth-barrel.ts +1 -1
- package/src/components/README.md +3 -2
- package/src/components/auto-release.test.ts +4 -20
- package/src/components/auto-release.ts +17 -42
- package/src/components/capability.ts +4 -4
- package/src/components/cli-support.test.ts +10 -5
- package/src/components/cli-support.ts +52 -44
- package/src/components/component.schema.json +2 -2
- package/src/components/component.ts +3 -3
- package/src/components/driver-output.ts +14 -2
- package/src/components/driver.test.ts +92 -22
- package/src/components/driver.ts +193 -83
- package/src/components/index.ts +1 -6
- package/src/components/manifest-persistence.test.ts +2 -20
- package/src/components/manifest-persistence.ts +4 -24
- package/src/components/pilots/pilots-lint-clean.test.ts +11 -10
- package/src/components/run-progress.ts +6 -6
- package/src/components/verbs/run-agent.ts +11 -17
- package/src/components/verbs/verify.ts +2 -2
- package/src/deep-observation.test.ts +75 -0
- package/src/deep-observation.ts +48 -0
- package/src/discovery/collect.test.ts +3 -3
- package/src/discovery/files.ts +4 -4
- package/src/discovery/fold-import.ts +105 -2
- package/src/discovery/param-deps.test.ts +112 -1
- package/src/discovery/param-deps.ts +193 -0
- package/src/discovery/sandbox/bundle.ts +15 -1
- package/src/discovery/sandbox/config-wire.test.ts +2 -2
- package/src/discovery/sandbox/config-wire.ts +2 -2
- package/src/fold/fold.test.ts +56 -0
- package/src/fold/foldable-helpers.ts +81 -1
- package/src/fold-provenance-exclusion.test.ts +186 -0
- package/src/fold-provenance.test.ts +495 -0
- package/src/fold-provenance.ts +441 -0
- package/src/graph-ops.test.ts +2 -2
- package/src/graph-ops.ts +1 -1
- package/src/held-elsewhere.test.ts +102 -0
- package/src/held-elsewhere.ts +114 -0
- package/src/index.ts +3 -0
- package/src/kubectl-context.ts +3 -3
- package/src/lexicon-config.test.ts +5 -5
- package/src/lexicon-config.ts +4 -4
- package/src/lexicon-plugin-helpers.ts +1 -1
- package/src/lexicon.ts +120 -14
- package/src/lifecycle/change-set.test.ts +49 -0
- package/src/lifecycle/change-set.ts +67 -0
- package/src/lifecycle/converge-ledger.ts +1 -1
- package/src/lifecycle/deep-diff.test.ts +267 -14
- package/src/lifecycle/deep-diff.ts +217 -14
- package/src/lifecycle/deep-observe.test.ts +3 -1
- package/src/lifecycle/deep-observe.ts +16 -6
- package/src/lifecycle/gate-ledger.test.ts +74 -2
- package/src/lifecycle/gate-ledger.ts +143 -36
- package/src/lifecycle/index.ts +1 -0
- package/src/lifecycle/release-ledger.ts +2 -2
- package/src/lifecycle/run-ledger.test.ts +268 -0
- package/src/lifecycle/run-ledger.ts +201 -0
- package/src/lifecycle/symptoms.ts +3 -3
- package/src/lint/config.test.ts +82 -1
- package/src/lint/config.ts +112 -3
- package/src/lint/policy.test.ts +1 -1
- package/src/lint/post-synth.test.ts +31 -0
- package/src/lint/post-synth.ts +54 -1
- package/src/lint/rules/__fixtures__/comp/comp004/pass/neo4j-cluster.component.ts +2 -2
- package/src/lint/rules/__fixtures__/comp/comp004/pass/orders-table.component.ts +1 -1
- package/src/lint/rules/comp/comp.test.ts +1 -1
- package/src/lint/rules/comp/comp004-gate-needs-durable-runtime.ts +74 -0
- package/src/lint/rules/comp/index.ts +3 -3
- package/src/lint/rules/op/index.ts +23 -0
- package/src/lint/rules/op/ops012-activity-contract.test.ts +161 -0
- package/src/lint/rules/op/ops012-activity-contract.ts +64 -0
- package/src/lint/rules/op/ops013-step-output-ref.test.ts +237 -0
- package/src/lint/rules/op/ops013-step-output-ref.ts +98 -0
- package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +263 -0
- package/src/lint/rules/op/ops014-converge-rule-refusals.ts +179 -0
- package/src/lint/rules/op/support.ts +11 -0
- package/src/lint/suppressions.test.ts +163 -0
- package/src/lint/suppressions.ts +204 -0
- package/src/live-endpoint.ts +1 -1
- package/src/op/activities/activity-contracts.ts +66 -0
- package/src/op/activities/apply.test.ts +567 -0
- package/src/op/activities/apply.ts +662 -0
- package/src/op/activities/build.ts +26 -0
- package/src/op/activities/converge.test.ts +330 -0
- package/src/op/activities/converge.ts +449 -0
- package/src/op/activities/env-teardown.test.ts +187 -0
- package/src/op/activities/env-teardown.ts +171 -0
- package/src/op/activities/guard-validate.test.ts +139 -0
- package/src/op/activities/guard-validate.ts +223 -0
- package/src/op/activities/http-check.test.ts +48 -0
- package/src/op/activities/http-check.ts +55 -0
- package/src/op/activities/index.ts +119 -0
- package/src/op/activities/lexicon-upgrade.test.ts +492 -0
- package/src/op/activities/lexicon-upgrade.ts +673 -0
- package/src/op/activities/lifecycle.ts +85 -0
- package/src/op/activities/pipeline-audit.test.ts +67 -0
- package/src/op/activities/pipeline-audit.ts +201 -0
- package/src/op/activities/policy.test.ts +19 -0
- package/src/op/activities/policy.ts +37 -0
- package/src/op/activities/reconcile.test.ts +81 -0
- package/src/op/activities/reconcile.ts +187 -0
- package/src/op/activities/shell.ts +26 -0
- package/src/op/activities/teardown.ts +22 -0
- package/src/op/activities/util.ts +6 -0
- package/src/op/activities/wait.ts +69 -0
- package/src/op/activities/workflow-audit.test.ts +90 -0
- package/src/op/activities/workflow-audit.ts +203 -0
- package/src/op/activity-contract-registry.test.ts +98 -0
- package/src/op/activity-contract-registry.ts +114 -0
- package/src/op/activity-contract.test.ts +1 -1
- package/src/op/activity-contract.ts +37 -33
- package/src/op/activity-failure.ts +34 -0
- package/src/op/activity-profiles.test.ts +56 -0
- package/src/op/activity-profiles.ts +116 -0
- package/src/op/activity-registry.test.ts +37 -28
- package/src/op/activity-registry.ts +27 -56
- package/src/op/activity-runtime.ts +3 -47
- package/src/op/builders-exports.test.ts +0 -49
- package/src/op/builders-typed.test.ts +164 -0
- package/src/op/builders.ts +123 -39
- package/src/op/composites/apply-op.ts +208 -0
- package/src/op/composites/composites.test.ts +366 -0
- package/src/op/composites/converge-op.test.ts +168 -0
- package/src/op/composites/converge-op.ts +214 -0
- package/src/op/composites/index.ts +26 -0
- package/src/op/composites/lexicon-upgrade-op.test.ts +68 -0
- package/src/op/composites/lexicon-upgrade-op.ts +134 -0
- package/src/op/composites/pipeline-audit-op.test.ts +25 -0
- package/src/op/composites/pipeline-audit-op.ts +78 -0
- package/src/op/composites/reconcile-op.test.ts +51 -0
- package/src/op/composites/reconcile-op.ts +107 -0
- package/src/op/composites/watch-op.ts +108 -0
- package/src/op/composites/workflow-audit-op.test.ts +25 -0
- package/src/op/composites/workflow-audit-op.ts +88 -0
- package/src/op/converge-rule.ts +12 -10
- package/src/op/cron.test.ts +128 -0
- package/src/op/cron.ts +149 -0
- package/src/op/discover-root.test.ts +105 -1
- package/src/op/discover.test.ts +6 -2
- package/src/op/discover.ts +84 -16
- package/src/op/duration.ts +21 -0
- package/src/op/effect-step.test.ts +26 -11
- package/src/op/emulator-lifecycle.ts +1 -2
- package/src/op/gate.ts +155 -0
- package/src/op/generate-pipeline.test.ts +65 -3
- package/src/op/generate-pipeline.ts +19 -2
- package/src/op/index.ts +39 -6
- package/src/op/local-executor.test.ts +163 -34
- package/src/op/local-executor.ts +370 -102
- package/src/op/local-output.test.ts +95 -11
- package/src/op/local-output.ts +33 -4
- package/src/op/op-ir.test.ts +281 -0
- package/src/op/op-ir.ts +417 -0
- package/src/op/op-verb-class.ts +19 -5
- package/src/op/op.test.ts +26 -5
- package/src/op/operator.test.ts +175 -6
- package/src/op/operator.ts +63 -16
- package/src/op/receipt-store.ts +1 -1
- package/src/op/resource.ts +20 -2
- package/src/op/runtime.ts +203 -0
- package/src/op/runtimes/local.test.ts +181 -0
- package/src/op/runtimes/local.ts +212 -0
- package/src/op/step-output-ref.ts +15 -13
- package/src/op/types.ts +84 -24
- package/src/ownership.ts +1 -1
- package/src/provenance.test.ts +6 -0
- package/src/provenance.ts +21 -1
- package/src/serializer-walker.test.ts +42 -0
- package/src/serializer-walker.ts +21 -2
- package/dist/cli/handlers/op-progress.d.ts +0 -90
- package/dist/cli/handlers/op-progress.d.ts.map +0 -1
- package/dist/cli/handlers/run-client.d.ts +0 -127
- package/dist/cli/handlers/run-client.d.ts.map +0 -1
- package/dist/cli/handlers/run-report.d.ts +0 -5
- package/dist/cli/handlers/run-report.d.ts.map +0 -1
- package/dist/components/temporal-codegen-loader.d.ts +0 -27
- package/dist/components/temporal-codegen-loader.d.ts.map +0 -1
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts +0 -37
- package/dist/lint/rules/comp/comp004-gate-needs-temporal.d.ts.map +0 -1
- package/src/cli/handlers/op-progress.test.ts +0 -268
- package/src/cli/handlers/op-progress.ts +0 -248
- package/src/cli/handlers/run-client.test.ts +0 -82
- package/src/cli/handlers/run-client.ts +0 -219
- package/src/cli/handlers/run-report.test.ts +0 -62
- package/src/cli/handlers/run-report.ts +0 -122
- package/src/components/temporal-codegen-loader.ts +0 -41
- package/src/lint/rules/comp/comp004-gate-needs-temporal.ts +0 -66
package/src/cli/mcp/op-tools.ts
CHANGED
|
@@ -1,56 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tools over Ops — on the runtime seam (#2121), not on any one runtime's
|
|
3
|
+
* own client.
|
|
4
|
+
*
|
|
5
|
+
* Every tool here goes through an {@link OpRuntimeProvider} — the built-in
|
|
6
|
+
* `local` one by default, or the `runtime` argument's lexicon `opRuntime` when
|
|
7
|
+
* an agent names one. One provider is built per call, so a long-lived server
|
|
8
|
+
* picks up a project's config as it is now rather than as it was at boot; the
|
|
9
|
+
* local provider's in-process run history is the exception and is held for the
|
|
10
|
+
* life of the module, so `op-status` can answer for a run `op-run` started.
|
|
11
|
+
*
|
|
12
|
+
* #2118 owns the ledger-backed record shape; when it lands, `status`/`log`
|
|
13
|
+
* read the ledger and this file stops depending on the process outliving the
|
|
14
|
+
* run.
|
|
15
|
+
*/
|
|
16
|
+
|
|
1
17
|
import { resolve } from "node:path";
|
|
2
18
|
import { discoverOps } from "../../op/discover";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
19
|
+
import { createLocalOpRuntime } from "../../op/runtimes/local";
|
|
20
|
+
import type { OpRuntimeProvider } from "../../op/runtime";
|
|
21
|
+
import { loadChantConfig } from "../../config";
|
|
22
|
+
import { loadPlugins } from "../plugins";
|
|
23
|
+
import { recordGateApproval } from "../handlers/operator";
|
|
7
24
|
import type { ToolRegistration } from "./lifecycle-tools";
|
|
8
25
|
|
|
9
|
-
|
|
10
|
-
|
|
26
|
+
/** The `local` provider, shared so an `op-run` is visible to a later `op-status`. */
|
|
27
|
+
let localRuntime: OpRuntimeProvider | undefined;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the runtime a tool call addresses. `runtime` names a configured
|
|
31
|
+
* lexicon's `opRuntime`; omitted (or `local`) it is core's built-in provider.
|
|
32
|
+
* Throws with an actionable message — the MCP layer turns that into `isError`.
|
|
33
|
+
*/
|
|
34
|
+
async function runtimeFor(name: unknown): Promise<OpRuntimeProvider> {
|
|
35
|
+
const wanted = typeof name === "string" && name.length > 0 ? name : "local";
|
|
36
|
+
if (wanted === "local") {
|
|
37
|
+
localRuntime ??= createLocalOpRuntime({ projectPath: resolve(".") });
|
|
38
|
+
return localRuntime;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const configured = await loadChantConfig(resolve("."))
|
|
42
|
+
.then(({ config }) => config.lexicons ?? [])
|
|
43
|
+
.catch(() => [] as string[]);
|
|
44
|
+
if (!configured.includes(wanted)) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
`runtime "${wanted}" is not a configured lexicon` +
|
|
47
|
+
(configured.length > 0 ? ` (configured: ${configured.join(", ")})` : ""),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const plugin = (await loadPlugins([wanted]))[0];
|
|
51
|
+
if (!plugin?.opRuntime) throw new Error(`lexicon "${wanted}" does not host Op runs`);
|
|
52
|
+
return plugin.opRuntime;
|
|
11
53
|
}
|
|
12
54
|
|
|
55
|
+
const RUNTIME_PARAM = {
|
|
56
|
+
type: "string",
|
|
57
|
+
description: 'Runtime to address: a lexicon name with an opRuntime, or "local" (the default)',
|
|
58
|
+
} as const;
|
|
59
|
+
|
|
13
60
|
export function createOpListTool(): ToolRegistration {
|
|
14
61
|
return {
|
|
15
62
|
definition: {
|
|
16
63
|
name: "op-list",
|
|
17
|
-
description: "List all Op definitions discovered from *.op.ts files with their current run
|
|
64
|
+
description: "List all Op definitions discovered from *.op.ts files with their current run state",
|
|
18
65
|
inputSchema: {
|
|
19
66
|
type: "object",
|
|
20
67
|
properties: {
|
|
21
|
-
|
|
68
|
+
runtime: RUNTIME_PARAM,
|
|
22
69
|
},
|
|
23
70
|
},
|
|
24
71
|
},
|
|
25
72
|
handler: async (params) => {
|
|
26
73
|
const { ops, errors } = await discoverOps();
|
|
27
|
-
const profile = params.profile as string | undefined;
|
|
28
74
|
|
|
29
|
-
let
|
|
75
|
+
let states: Map<string, { state: string } | undefined> = new Map();
|
|
30
76
|
try {
|
|
31
|
-
|
|
77
|
+
const runtime = await runtimeFor(params.runtime);
|
|
78
|
+
states = await runtime.list([...ops.values()].map((d) => d.config));
|
|
32
79
|
} catch {
|
|
33
|
-
//
|
|
80
|
+
// Runtime unavailable — the definitions are still worth listing.
|
|
34
81
|
}
|
|
35
82
|
|
|
36
83
|
const result = [];
|
|
37
84
|
for (const [name, { config }] of ops) {
|
|
38
|
-
let runStatus = "—";
|
|
39
|
-
if (client) {
|
|
40
|
-
try {
|
|
41
|
-
const desc = await client.workflow.getHandle(resolveWorkflowId(name)).describe();
|
|
42
|
-
runStatus = desc.status.name;
|
|
43
|
-
} catch {
|
|
44
|
-
// workflow not found or Temporal error
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
85
|
result.push({
|
|
48
86
|
name,
|
|
49
87
|
overview: config.overview,
|
|
50
88
|
phases: config.phases.length,
|
|
51
|
-
|
|
89
|
+
labels: config.labels ?? {},
|
|
52
90
|
depends: config.depends ?? [],
|
|
53
|
-
|
|
91
|
+
runState: states.get(name)?.state ?? "—",
|
|
54
92
|
});
|
|
55
93
|
}
|
|
56
94
|
|
|
@@ -64,19 +102,18 @@ export function createOpRunTool(): ToolRegistration {
|
|
|
64
102
|
definition: {
|
|
65
103
|
name: "op-run",
|
|
66
104
|
description:
|
|
67
|
-
"
|
|
105
|
+
"Run an Op on a runtime and return its result. Defaults to the built-in local runtime, which executes the Op in this process.",
|
|
68
106
|
inputSchema: {
|
|
69
107
|
type: "object",
|
|
70
108
|
properties: {
|
|
71
109
|
name: { type: "string", description: "Op name (e.g. alb-deploy)" },
|
|
72
|
-
|
|
110
|
+
runtime: RUNTIME_PARAM,
|
|
73
111
|
},
|
|
74
112
|
required: ["name"],
|
|
75
113
|
},
|
|
76
114
|
},
|
|
77
115
|
handler: async (params) => {
|
|
78
116
|
const name = params.name as string;
|
|
79
|
-
const profile = params.profile as string | undefined;
|
|
80
117
|
|
|
81
118
|
const { ops } = await discoverOps();
|
|
82
119
|
if (!ops.has(name)) {
|
|
@@ -84,18 +121,19 @@ export function createOpRunTool(): ToolRegistration {
|
|
|
84
121
|
return `Op "${name}" not found. Available: ${available.join(", ") || "none"}`;
|
|
85
122
|
}
|
|
86
123
|
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const taskQueue = resolvedProfile.taskQueue ?? config.taskQueue ?? name;
|
|
91
|
-
|
|
92
|
-
await client.workflow.start(workflowFnName(name), {
|
|
93
|
-
taskQueue,
|
|
94
|
-
workflowId,
|
|
95
|
-
workflowIdConflictPolicy: "FAIL",
|
|
96
|
-
});
|
|
124
|
+
const runtime = await runtimeFor(params.runtime);
|
|
125
|
+
const handle = await runtime.start(ops.get(name)!.config, {});
|
|
126
|
+
const status = await handle.result();
|
|
97
127
|
|
|
98
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
op: status.op,
|
|
130
|
+
runId: status.runId,
|
|
131
|
+
state: status.state,
|
|
132
|
+
startedAt: status.startedAt,
|
|
133
|
+
endedAt: status.endedAt ?? null,
|
|
134
|
+
...(status.records ? { records: status.records } : {}),
|
|
135
|
+
...(status.gate ? { gate: status.gate } : {}),
|
|
136
|
+
};
|
|
99
137
|
},
|
|
100
138
|
};
|
|
101
139
|
}
|
|
@@ -104,78 +142,81 @@ export function createOpStatusTool(): ToolRegistration {
|
|
|
104
142
|
return {
|
|
105
143
|
definition: {
|
|
106
144
|
name: "op-status",
|
|
107
|
-
description: "Return the current run state of an Op
|
|
145
|
+
description: "Return the current run state of an Op on a runtime",
|
|
108
146
|
inputSchema: {
|
|
109
147
|
type: "object",
|
|
110
148
|
properties: {
|
|
111
149
|
name: { type: "string", description: "Op name (e.g. alb-deploy)" },
|
|
112
|
-
|
|
150
|
+
runtime: RUNTIME_PARAM,
|
|
113
151
|
},
|
|
114
152
|
required: ["name"],
|
|
115
153
|
},
|
|
116
154
|
},
|
|
117
155
|
handler: async (params) => {
|
|
118
156
|
const name = params.name as string;
|
|
119
|
-
const profile = params.profile as string | undefined;
|
|
120
157
|
|
|
121
158
|
const { ops } = await discoverOps();
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
const history = await fetchNormalizedHistory(handle);
|
|
128
|
-
|
|
129
|
-
const { completed: activitiesCompleted, scheduled: activitiesScheduled } = countActivities(history);
|
|
130
|
-
// Per-phase progress (#1676) — the same StepRecord shape `chant run
|
|
131
|
-
// <name> --json` uses locally, so a consumer renders one way
|
|
132
|
-
// regardless of executor. Only buildable when the Op's config was
|
|
133
|
-
// discoverable (a *.op.ts file on disk); absent otherwise rather than
|
|
134
|
-
// guessed at.
|
|
135
|
-
const progress = config ? extractStepRecords(config, history, { final: Boolean(desc.closeTime) }) : undefined;
|
|
136
|
-
const gate = await queryGateState(handle);
|
|
159
|
+
if (!ops.has(name)) throw new Error(`Op "${name}" not found`);
|
|
160
|
+
|
|
161
|
+
const runtime = await runtimeFor(params.runtime);
|
|
162
|
+
const status = await runtime.status(name);
|
|
163
|
+
if (!status) return { op: name, runtime: runtime.name, state: null, message: "no run recorded" };
|
|
137
164
|
|
|
138
165
|
return {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
...(progress ? { progress } : {}),
|
|
148
|
-
gate: gate ?? null,
|
|
166
|
+
op: status.op,
|
|
167
|
+
runtime: runtime.name,
|
|
168
|
+
runId: status.runId,
|
|
169
|
+
state: status.state,
|
|
170
|
+
startedAt: status.startedAt,
|
|
171
|
+
endedAt: status.endedAt ?? null,
|
|
172
|
+
...(status.records ? { records: status.records } : {}),
|
|
173
|
+
gate: status.gate ?? null,
|
|
149
174
|
};
|
|
150
175
|
},
|
|
151
176
|
};
|
|
152
177
|
}
|
|
153
178
|
|
|
154
|
-
export function
|
|
179
|
+
export function createOpApproveTool(): ToolRegistration {
|
|
155
180
|
return {
|
|
156
181
|
definition: {
|
|
157
|
-
name: "op-
|
|
158
|
-
description:
|
|
182
|
+
name: "op-approve",
|
|
183
|
+
description:
|
|
184
|
+
"Record a gate's resolution on the gate ledger and wake the runtime hosting the gated run. The rename of op-signal: a gate is resolved by recording the fact, not by sending a message.",
|
|
159
185
|
inputSchema: {
|
|
160
186
|
type: "object",
|
|
161
187
|
properties: {
|
|
162
188
|
name: { type: "string", description: "Op name (e.g. alb-deploy)" },
|
|
163
|
-
|
|
164
|
-
|
|
189
|
+
gate: { type: "string", description: "Gate name (e.g. gate-dns-delegation)" },
|
|
190
|
+
approver: { type: "string", description: "Who approved; defaults to the CI or shell identity" },
|
|
191
|
+
note: { type: "string", description: "Free-text context recorded on the resolution" },
|
|
192
|
+
url: { type: "string", description: "Absolute http/https URL this resolution happened at" },
|
|
193
|
+
runtime: RUNTIME_PARAM,
|
|
165
194
|
},
|
|
166
|
-
required: ["name", "
|
|
195
|
+
required: ["name", "gate"],
|
|
167
196
|
},
|
|
168
197
|
},
|
|
169
198
|
handler: async (params) => {
|
|
170
199
|
const name = params.name as string;
|
|
171
|
-
const
|
|
172
|
-
|
|
200
|
+
const gate = params.gate as string;
|
|
201
|
+
if (!name || !gate) throw new Error("op-approve needs both an Op name and a gate name");
|
|
173
202
|
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
|
|
203
|
+
const runtime = await runtimeFor(params.runtime);
|
|
204
|
+
const outcome = await recordGateApproval(name, gate, {
|
|
205
|
+
actor: params.approver as string | undefined,
|
|
206
|
+
note: params.note as string | undefined,
|
|
207
|
+
url: params.url as string | undefined,
|
|
208
|
+
});
|
|
209
|
+
if (!outcome.ok) throw new Error(`Gate "${gate}" on "${name}" was not recorded`);
|
|
210
|
+
|
|
211
|
+
if (runtime.resolveGate) await runtime.resolveGate(name, gate, outcome.record);
|
|
177
212
|
|
|
178
|
-
return
|
|
213
|
+
return {
|
|
214
|
+
op: name,
|
|
215
|
+
gate,
|
|
216
|
+
resolvedBy: outcome.record.resolvedBy,
|
|
217
|
+
timestamp: outcome.record.timestamp,
|
|
218
|
+
runtimeNotified: Boolean(runtime.resolveGate),
|
|
219
|
+
};
|
|
179
220
|
},
|
|
180
221
|
};
|
|
181
222
|
}
|
|
@@ -184,32 +225,50 @@ export function createOpReportTool(): ToolRegistration {
|
|
|
184
225
|
return {
|
|
185
226
|
definition: {
|
|
186
227
|
name: "op-report",
|
|
187
|
-
description: "Return a markdown
|
|
228
|
+
description: "Return a markdown report for the latest run of an Op on a runtime",
|
|
188
229
|
inputSchema: {
|
|
189
230
|
type: "object",
|
|
190
231
|
properties: {
|
|
191
232
|
name: { type: "string", description: "Op name (e.g. alb-deploy)" },
|
|
192
|
-
|
|
233
|
+
runtime: RUNTIME_PARAM,
|
|
193
234
|
},
|
|
194
235
|
required: ["name"],
|
|
195
236
|
},
|
|
196
237
|
},
|
|
197
238
|
handler: async (params) => {
|
|
198
239
|
const name = params.name as string;
|
|
199
|
-
const profile = params.profile as string | undefined;
|
|
200
240
|
|
|
201
241
|
const { ops } = await discoverOps();
|
|
202
|
-
if (!ops.has(name)) {
|
|
203
|
-
return `Op "${name}" not found`;
|
|
204
|
-
}
|
|
242
|
+
if (!ops.has(name)) return `Op "${name}" not found`;
|
|
205
243
|
const { config } = ops.get(name)!;
|
|
206
244
|
|
|
207
|
-
const
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
245
|
+
const runtime = await runtimeFor(params.runtime);
|
|
246
|
+
const status = await runtime.status(name);
|
|
247
|
+
if (!status) return `# ${name}\n\n${config.overview}\n\nNo run is recorded on the "${runtime.name}" runtime.\n`;
|
|
248
|
+
|
|
249
|
+
const lines = [
|
|
250
|
+
`# ${name}`,
|
|
251
|
+
"",
|
|
252
|
+
config.overview,
|
|
253
|
+
"",
|
|
254
|
+
`- Runtime: ${runtime.name}`,
|
|
255
|
+
`- Run: ${status.runId}`,
|
|
256
|
+
`- State: ${status.state}`,
|
|
257
|
+
`- Started: ${status.startedAt}`,
|
|
258
|
+
...(status.endedAt ? [`- Ended: ${status.endedAt}`] : []),
|
|
259
|
+
...(status.gate ? [`- Gate: ${status.gate.name} (pending since ${status.gate.since})`] : []),
|
|
260
|
+
"",
|
|
261
|
+
];
|
|
262
|
+
|
|
263
|
+
if (status.records?.length) {
|
|
264
|
+
lines.push("| Phase | Step | Status | Duration |", "|---|---|---|---|");
|
|
265
|
+
for (const record of status.records) {
|
|
266
|
+
lines.push(`| ${record.phase} | ${record.fn} | ${record.status} | ${record.durationMs}ms |`);
|
|
267
|
+
}
|
|
268
|
+
lines.push("");
|
|
269
|
+
}
|
|
211
270
|
|
|
212
|
-
return
|
|
271
|
+
return lines.join("\n");
|
|
213
272
|
},
|
|
214
273
|
};
|
|
215
274
|
}
|
|
@@ -4,9 +4,7 @@ import type { ResourceDefinition } from "./types";
|
|
|
4
4
|
import { getContext } from "./resources/context";
|
|
5
5
|
import { readSnapshot, readEnvironmentSnapshots } from "../../lifecycle/git";
|
|
6
6
|
import { discoverOps } from "../../op/discover";
|
|
7
|
-
import {
|
|
8
|
-
import { resolveWorkflowId, fetchNormalizedHistory } from "../handlers/run-client";
|
|
9
|
-
import { extractStepRecords, countActivities, queryGateState } from "../handlers/op-progress";
|
|
7
|
+
import { createLocalOpRuntime } from "../../op/runtimes/local";
|
|
10
8
|
import { loadOkfBundle } from "../../okf-read";
|
|
11
9
|
import { loadChantConfigUpward, resolveKnowledgeDir } from "../../config";
|
|
12
10
|
|
|
@@ -37,7 +35,7 @@ export const coreResourceDefinitions: ResourceDefinition[] = [
|
|
|
37
35
|
{
|
|
38
36
|
uri: "chant://ops/{name}/runs",
|
|
39
37
|
name: "Op run history",
|
|
40
|
-
description: "
|
|
38
|
+
description: "Run history for a named Op, newest first",
|
|
41
39
|
mimeType: "application/json",
|
|
42
40
|
},
|
|
43
41
|
{
|
|
@@ -95,10 +93,6 @@ export function collectExamples(
|
|
|
95
93
|
return examples;
|
|
96
94
|
}
|
|
97
95
|
|
|
98
|
-
function opWorkflowFnName(opName: string): string {
|
|
99
|
-
return opName.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase()) + "Workflow";
|
|
100
|
-
}
|
|
101
|
-
|
|
102
96
|
/**
|
|
103
97
|
* Handle resources/read request — checks plugin resources after core
|
|
104
98
|
*/
|
|
@@ -167,7 +161,7 @@ export async function handleResourcesRead(
|
|
|
167
161
|
name: config.name,
|
|
168
162
|
overview: config.overview,
|
|
169
163
|
phases: config.phases.length,
|
|
170
|
-
|
|
164
|
+
labels: config.labels ?? {},
|
|
171
165
|
depends: config.depends ?? [],
|
|
172
166
|
}));
|
|
173
167
|
return {
|
|
@@ -175,33 +169,16 @@ export async function handleResourcesRead(
|
|
|
175
169
|
};
|
|
176
170
|
}
|
|
177
171
|
|
|
172
|
+
// Both run resources read the built-in local runtime (#2121, #2116) — the
|
|
173
|
+
// one an MCP client can address without naming a lexicon. `status` and `log`
|
|
174
|
+
// answer from the run ledger (#2118), so a run that ended in an earlier
|
|
175
|
+
// process still reads back here.
|
|
178
176
|
if (uri.startsWith("chant://ops/") && uri.endsWith("/runs/latest")) {
|
|
179
177
|
const name = uri.replace("chant://ops/", "").replace("/runs/latest", "");
|
|
180
178
|
try {
|
|
181
|
-
const
|
|
182
|
-
const config = ops.get(name)?.config;
|
|
183
|
-
|
|
184
|
-
const { client } = await makeTemporalClient(undefined, resolve("."));
|
|
185
|
-
const handle = client.workflow.getHandle(resolveWorkflowId(name));
|
|
186
|
-
const desc = await handle.describe();
|
|
187
|
-
const history = await fetchNormalizedHistory(handle);
|
|
188
|
-
const { completed: activitiesCompleted, scheduled: activitiesScheduled } = countActivities(history);
|
|
189
|
-
const progress = config ? extractStepRecords(config, history, { final: Boolean(desc.closeTime) }) : undefined;
|
|
190
|
-
const gate = await queryGateState(handle);
|
|
191
|
-
const result = {
|
|
192
|
-
workflowId: desc.workflowId,
|
|
193
|
-
runId: desc.runId,
|
|
194
|
-
status: desc.status.name,
|
|
195
|
-
startTime: desc.startTime,
|
|
196
|
-
closeTime: desc.closeTime ?? null,
|
|
197
|
-
taskQueue: desc.taskQueue,
|
|
198
|
-
activitiesCompleted,
|
|
199
|
-
activitiesScheduled,
|
|
200
|
-
...(progress ? { progress } : {}),
|
|
201
|
-
gate: gate ?? null,
|
|
202
|
-
};
|
|
179
|
+
const status = await createLocalOpRuntime({ projectPath: resolve(".") }).status(name);
|
|
203
180
|
return {
|
|
204
|
-
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(
|
|
181
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(status ?? null, null, 2) }],
|
|
205
182
|
};
|
|
206
183
|
} catch (err) {
|
|
207
184
|
return {
|
|
@@ -213,11 +190,7 @@ export async function handleResourcesRead(
|
|
|
213
190
|
if (uri.startsWith("chant://ops/") && uri.endsWith("/runs")) {
|
|
214
191
|
const name = uri.replace("chant://ops/", "").replace("/runs", "");
|
|
215
192
|
try {
|
|
216
|
-
const
|
|
217
|
-
const runs: unknown[] = [];
|
|
218
|
-
for await (const run of client.workflow.list({ query: `WorkflowType = "${opWorkflowFnName(name)}"` })) {
|
|
219
|
-
runs.push({ runId: run.runId, status: run.status.name, startTime: run.startTime, closeTime: run.closeTime ?? null });
|
|
220
|
-
}
|
|
193
|
+
const runs = await createLocalOpRuntime({ projectPath: resolve(".") }).log(name);
|
|
221
194
|
return {
|
|
222
195
|
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(runs, null, 2) }],
|
|
223
196
|
};
|
|
@@ -49,32 +49,31 @@ chant import template.json # Convert external template
|
|
|
49
49
|
chant import template.json -o ./src/ # Custom output dir
|
|
50
50
|
\`\`\`
|
|
51
51
|
|
|
52
|
-
## Ops
|
|
52
|
+
## Ops
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
An Op is a convergent verb. Each \`*.op.ts\` file declares one with named phases and activity steps; \`--on <lexicon>\` picks the runtime that hosts the run, and the built-in local runtime runs it in-process otherwise.
|
|
55
55
|
|
|
56
56
|
### Op MCP Tools
|
|
57
57
|
|
|
58
58
|
| Tool | Description |
|
|
59
59
|
|---|---|
|
|
60
|
-
| \`op-list\` | List all discovered Ops with current run
|
|
61
|
-
| \`op-run\` |
|
|
62
|
-
| \`op-status\` | Get current run state (
|
|
63
|
-
| \`op-
|
|
64
|
-
| \`op-report\` | Return a markdown
|
|
60
|
+
| \`op-list\` | List all discovered Ops with their current run state. |
|
|
61
|
+
| \`op-run\` | Run an Op and return its result. Requires \`name\`. |
|
|
62
|
+
| \`op-status\` | Get current run state (state, step records, times). Requires \`name\`. |
|
|
63
|
+
| \`op-approve\` | Record a gate's resolution and wake the runtime hosting the run. Requires \`name\` and \`gate\`. |
|
|
64
|
+
| \`op-report\` | Return a markdown report for the latest run. Requires \`name\`. |
|
|
65
65
|
|
|
66
|
-
All Op tools accept an optional \`
|
|
66
|
+
All Op tools accept an optional \`runtime\` parameter: a lexicon name whose \`opRuntime\` hosts the run, or \`local\` (the default) for the built-in in-process runtime.
|
|
67
67
|
|
|
68
68
|
### Op MCP Resources
|
|
69
69
|
|
|
70
70
|
| URI | Description |
|
|
71
71
|
|---|---|
|
|
72
|
-
| \`chant://ops\` | JSON array of all Op definitions (name, overview,
|
|
73
|
-
| \`chant://ops/{name}/runs\` |
|
|
72
|
+
| \`chant://ops\` | JSON array of all Op definitions (name, overview, phase count, labels, depends) |
|
|
73
|
+
| \`chant://ops/{name}/runs\` | Run ledger history for a named Op, newest first |
|
|
74
74
|
| \`chant://ops/{name}/runs/latest\` | Latest run state for a named Op |
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
Ops use deterministic workflow IDs: \`chant-op-<opName>\` (e.g. \`chant-op-alb-deploy\`).
|
|
76
|
+
Both run resources read the built-in local runtime, the one an MCP client can address without naming a lexicon.
|
|
78
77
|
|
|
79
78
|
## Best Practices
|
|
80
79
|
|
|
@@ -467,50 +467,50 @@ describe("McpServer", () => {
|
|
|
467
467
|
return tool.inputSchema.properties as Record<string, unknown>;
|
|
468
468
|
}
|
|
469
469
|
|
|
470
|
-
test("op-list has
|
|
470
|
+
test("op-list has a runtime property", async () => {
|
|
471
471
|
const props = await getToolProps("op-list");
|
|
472
|
-
expect(props.
|
|
472
|
+
expect(props.runtime).toBeDefined();
|
|
473
473
|
});
|
|
474
474
|
|
|
475
|
-
test("op-run has name (required) and
|
|
475
|
+
test("op-run has name (required) and runtime", async () => {
|
|
476
476
|
const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
|
|
477
477
|
const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
|
|
478
478
|
const tool = result.tools.find((t) => t.name === "op-run")!;
|
|
479
479
|
const props = tool.inputSchema.properties as Record<string, unknown>;
|
|
480
480
|
expect(props.name).toBeDefined();
|
|
481
|
-
expect(props.
|
|
481
|
+
expect(props.runtime).toBeDefined();
|
|
482
482
|
expect(tool.inputSchema.required).toContain("name");
|
|
483
483
|
});
|
|
484
484
|
|
|
485
|
-
test("op-status has name (required) and
|
|
485
|
+
test("op-status has name (required) and runtime", async () => {
|
|
486
486
|
const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
|
|
487
487
|
const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
|
|
488
488
|
const tool = result.tools.find((t) => t.name === "op-status")!;
|
|
489
489
|
const props = tool.inputSchema.properties as Record<string, unknown>;
|
|
490
490
|
expect(props.name).toBeDefined();
|
|
491
|
-
expect(props.
|
|
491
|
+
expect(props.runtime).toBeDefined();
|
|
492
492
|
expect(tool.inputSchema.required).toContain("name");
|
|
493
493
|
});
|
|
494
494
|
|
|
495
|
-
test("op-
|
|
495
|
+
test("op-approve has name and gate (both required), plus runtime (#2121)", async () => {
|
|
496
496
|
const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
|
|
497
497
|
const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
|
|
498
|
-
const tool = result.tools.find((t) => t.name === "op-
|
|
498
|
+
const tool = result.tools.find((t) => t.name === "op-approve")!;
|
|
499
499
|
const props = tool.inputSchema.properties as Record<string, unknown>;
|
|
500
500
|
expect(props.name).toBeDefined();
|
|
501
|
-
expect(props.
|
|
502
|
-
expect(props.
|
|
501
|
+
expect(props.gate).toBeDefined();
|
|
502
|
+
expect(props.runtime).toBeDefined();
|
|
503
503
|
expect(tool.inputSchema.required).toContain("name");
|
|
504
|
-
expect(tool.inputSchema.required).toContain("
|
|
504
|
+
expect(tool.inputSchema.required).toContain("gate");
|
|
505
505
|
});
|
|
506
506
|
|
|
507
|
-
test("op-report has name (required) and
|
|
507
|
+
test("op-report has name (required) and runtime", async () => {
|
|
508
508
|
const response = await server.handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list" });
|
|
509
509
|
const result = response.result as { tools: Array<{ name: string; inputSchema: Record<string, unknown> }> };
|
|
510
510
|
const tool = result.tools.find((t) => t.name === "op-report")!;
|
|
511
511
|
const props = tool.inputSchema.properties as Record<string, unknown>;
|
|
512
512
|
expect(props.name).toBeDefined();
|
|
513
|
-
expect(props.
|
|
513
|
+
expect(props.runtime).toBeDefined();
|
|
514
514
|
expect(tool.inputSchema.required).toContain("name");
|
|
515
515
|
});
|
|
516
516
|
});
|
|
@@ -640,7 +640,7 @@ describe("McpServer", () => {
|
|
|
640
640
|
});
|
|
641
641
|
|
|
642
642
|
describe("Op tool handlers", () => {
|
|
643
|
-
test("op-list returns list without throwing when
|
|
643
|
+
test("op-list returns list without throwing when no runtime has a record", async () => {
|
|
644
644
|
const response = await server.handleRequest({
|
|
645
645
|
jsonrpc: "2.0",
|
|
646
646
|
id: 1,
|
|
@@ -654,7 +654,7 @@ describe("McpServer", () => {
|
|
|
654
654
|
expect(result.isError).toBeUndefined();
|
|
655
655
|
});
|
|
656
656
|
|
|
657
|
-
test("op-run
|
|
657
|
+
test("op-run answers for an Op that does not exist", async () => {
|
|
658
658
|
const response = await server.handleRequest({
|
|
659
659
|
jsonrpc: "2.0",
|
|
660
660
|
id: 1,
|
|
@@ -663,11 +663,11 @@ describe("McpServer", () => {
|
|
|
663
663
|
});
|
|
664
664
|
expect(response.error).toBeUndefined();
|
|
665
665
|
const result = response.result as { content: Array<{ text: string }>; isError?: boolean };
|
|
666
|
-
// Either "not found" or
|
|
666
|
+
// Either "not found" or a runtime error — either way, not a protocol error
|
|
667
667
|
expect(result.content[0].text.length).toBeGreaterThan(0);
|
|
668
668
|
});
|
|
669
669
|
|
|
670
|
-
test("op-status returns isError
|
|
670
|
+
test("op-status returns isError for an Op that does not exist", async () => {
|
|
671
671
|
const response = await server.handleRequest({
|
|
672
672
|
jsonrpc: "2.0",
|
|
673
673
|
id: 1,
|
|
@@ -680,12 +680,12 @@ describe("McpServer", () => {
|
|
|
680
680
|
expect(result.content[0].text).toContain("Error:");
|
|
681
681
|
});
|
|
682
682
|
|
|
683
|
-
test("op-
|
|
683
|
+
test("op-approve returns isError without a gate name (#2121)", async () => {
|
|
684
684
|
const response = await server.handleRequest({
|
|
685
685
|
jsonrpc: "2.0",
|
|
686
686
|
id: 1,
|
|
687
687
|
method: "tools/call",
|
|
688
|
-
params: { name: "op-
|
|
688
|
+
params: { name: "op-approve", arguments: { name: "nonexistent-op" } },
|
|
689
689
|
});
|
|
690
690
|
expect(response.error).toBeUndefined();
|
|
691
691
|
const result = response.result as { content: Array<{ text: string }>; isError: boolean };
|
|
@@ -702,7 +702,7 @@ describe("McpServer", () => {
|
|
|
702
702
|
});
|
|
703
703
|
expect(response.error).toBeUndefined();
|
|
704
704
|
const result = response.result as { content: Array<{ text: string }>; isError?: boolean };
|
|
705
|
-
// Op not found → returns a "not found" message or
|
|
705
|
+
// Op not found → returns a "not found" message or a runtime error, not a protocol error
|
|
706
706
|
expect(result.content[0].text.length).toBeGreaterThan(0);
|
|
707
707
|
});
|
|
708
708
|
});
|
|
@@ -973,7 +973,7 @@ describe("McpServer", () => {
|
|
|
973
973
|
expect(Array.isArray(ops)).toBe(true);
|
|
974
974
|
});
|
|
975
975
|
|
|
976
|
-
test("chant://ops/{name}/runs
|
|
976
|
+
test("chant://ops/{name}/runs is an empty list for an Op with no recorded run", async () => {
|
|
977
977
|
const response = await server.handleRequest({
|
|
978
978
|
jsonrpc: "2.0",
|
|
979
979
|
id: 1,
|
|
@@ -982,11 +982,10 @@ describe("McpServer", () => {
|
|
|
982
982
|
});
|
|
983
983
|
expect(response.error).toBeUndefined();
|
|
984
984
|
const result = response.result as { contents: Array<{ text: string }> };
|
|
985
|
-
|
|
986
|
-
expect(data.error).toBeDefined();
|
|
985
|
+
expect(JSON.parse(result.contents[0].text)).toEqual([]);
|
|
987
986
|
});
|
|
988
987
|
|
|
989
|
-
test("chant://ops/{name}/runs/latest
|
|
988
|
+
test("chant://ops/{name}/runs/latest is null for an Op with no recorded run", async () => {
|
|
990
989
|
const response = await server.handleRequest({
|
|
991
990
|
jsonrpc: "2.0",
|
|
992
991
|
id: 1,
|
|
@@ -995,8 +994,7 @@ describe("McpServer", () => {
|
|
|
995
994
|
});
|
|
996
995
|
expect(response.error).toBeUndefined();
|
|
997
996
|
const result = response.result as { contents: Array<{ text: string }> };
|
|
998
|
-
|
|
999
|
-
expect(data.error).toBeDefined();
|
|
997
|
+
expect(JSON.parse(result.contents[0].text)).toBeNull();
|
|
1000
998
|
});
|
|
1001
999
|
});
|
|
1002
1000
|
|
|
@@ -1471,7 +1469,7 @@ describe("McpServer", () => {
|
|
|
1471
1469
|
expect(tools).toHaveLength(13);
|
|
1472
1470
|
expect(tools.map((t) => t.name).sort()).toEqual([
|
|
1473
1471
|
"build", "explain", "import", "lifecycle-diff", "lifecycle-snapshot", "lint",
|
|
1474
|
-
"op-
|
|
1472
|
+
"op-approve", "op-list", "op-report", "op-run", "op-status",
|
|
1475
1473
|
"scaffold", "search",
|
|
1476
1474
|
]);
|
|
1477
1475
|
|