@intentius/chant 0.46.0 → 0.50.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 +13 -3
- package/dist/audit/catalog.d.ts.map +1 -1
- package/dist/audit/core.d.ts +30 -3
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts +9 -2
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/fetch.d.ts.map +1 -1
- package/dist/audit/report-html.d.ts.map +1 -1
- package/dist/audit/report-model.d.ts +6 -0
- 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.map +1 -1
- package/dist/audit/secrets.d.ts +95 -0
- package/dist/audit/secrets.d.ts.map +1 -0
- package/dist/audit/wrangler.d.ts +33 -0
- package/dist/audit/wrangler.d.ts.map +1 -0
- package/dist/build.d.ts +3 -3
- package/dist/build.d.ts.map +1 -1
- package/dist/cli/commands/audit.d.ts +7 -0
- package/dist/cli/commands/audit.d.ts.map +1 -1
- package/dist/cli/commands/build.d.ts +23 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/components.d.ts +31 -0
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts +12 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +32 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -0
- package/dist/cli/handlers/scenario.d.ts +39 -0
- package/dist/cli/handlers/scenario.d.ts.map +1 -0
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
- package/dist/cli/mcp/server.d.ts +35 -2
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/tools/explain.d.ts +6 -0
- package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
- package/dist/cli/mcp/types.d.ts +29 -1
- package/dist/cli/mcp/types.d.ts.map +1 -1
- package/dist/cli/plugins.d.ts +1 -1
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +14 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/cli/reporters/stylish.d.ts +15 -1
- package/dist/cli/reporters/stylish.d.ts.map +1 -1
- package/dist/codegen/docs-rule-scanning.d.ts.map +1 -1
- package/dist/components/auto-release.d.ts +4 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability.d.ts +17 -2
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/cli-support.d.ts +7 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +15 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/starter-plugin.d.ts +2 -0
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/verbs/ensure-secret.d.ts +50 -0
- package/dist/components/verbs/ensure-secret.d.ts.map +1 -0
- package/dist/components/verbs/index.d.ts +13 -0
- package/dist/components/verbs/index.d.ts.map +1 -1
- package/dist/components/verbs/r2-sync.d.ts +76 -0
- package/dist/components/verbs/r2-sync.d.ts.map +1 -0
- package/dist/components/verbs/run-agent.d.ts +499 -0
- package/dist/components/verbs/run-agent.d.ts.map +1 -0
- package/dist/components/verbs/sign.d.ts +30 -0
- package/dist/components/verbs/sign.d.ts.map +1 -1
- package/dist/components/verbs/wrangler.d.ts +108 -0
- package/dist/components/verbs/wrangler.d.ts.map +1 -0
- package/dist/composite.d.ts +6 -1
- package/dist/composite.d.ts.map +1 -1
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/deep-observation.d.ts +14 -0
- package/dist/deep-observation.d.ts.map +1 -1
- package/dist/discovery/collect.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +15 -1
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/fold-rank.d.ts +66 -0
- package/dist/discovery/fold-rank.d.ts.map +1 -0
- package/dist/discovery/index.d.ts +15 -0
- package/dist/discovery/index.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +17 -0
- package/dist/discovery/param-deps.d.ts.map +1 -0
- package/dist/effect-receipt.d.ts +177 -0
- package/dist/effect-receipt.d.ts.map +1 -0
- package/dist/fold/fold.d.ts +55 -2
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/fold/subset.d.ts +20 -0
- package/dist/fold/subset.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lexicon-schema.d.ts +2 -0
- package/dist/lexicon-schema.d.ts.map +1 -1
- package/dist/lexicon.d.ts +137 -3
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/change-set.d.ts +33 -5
- package/dist/lifecycle/change-set.d.ts.map +1 -1
- package/dist/lifecycle/converge-ledger.d.ts +90 -0
- package/dist/lifecycle/converge-ledger.d.ts.map +1 -0
- package/dist/lifecycle/deep-diff.d.ts +18 -0
- package/dist/lifecycle/deep-diff.d.ts.map +1 -1
- package/dist/lifecycle/deep-observe.d.ts +9 -1
- package/dist/lifecycle/deep-observe.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +33 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -0
- package/dist/lifecycle/git.d.ts +145 -21
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/index.d.ts +6 -0
- package/dist/lifecycle/index.d.ts.map +1 -1
- package/dist/lifecycle/lease.d.ts +113 -0
- package/dist/lifecycle/lease.d.ts.map +1 -0
- package/dist/lifecycle/observation-baseline.d.ts +21 -3
- package/dist/lifecycle/observation-baseline.d.ts.map +1 -1
- package/dist/lifecycle/receipt-plan.d.ts +62 -0
- package/dist/lifecycle/receipt-plan.d.ts.map +1 -0
- package/dist/lifecycle/release-ledger.d.ts +20 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/scenario-eval.d.ts +42 -0
- package/dist/lifecycle/scenario-eval.d.ts.map +1 -0
- package/dist/lifecycle/scenario.d.ts +163 -0
- package/dist/lifecycle/scenario.d.ts.map +1 -0
- package/dist/lifecycle/symptoms.d.ts +63 -0
- package/dist/lifecycle/symptoms.d.ts.map +1 -0
- package/dist/lifecycle/teardown.d.ts +6 -4
- package/dist/lifecycle/teardown.d.ts.map +1 -1
- package/dist/lifecycle/unobserved-gate.d.ts +67 -0
- package/dist/lifecycle/unobserved-gate.d.ts.map +1 -0
- package/dist/lint/knowledge-checks.d.ts +48 -0
- package/dist/lint/knowledge-checks.d.ts.map +1 -0
- package/dist/lint/output-checks.d.ts +5 -0
- package/dist/lint/output-checks.d.ts.map +1 -0
- package/dist/lint/output-docs.d.ts +94 -0
- package/dist/lint/output-docs.d.ts.map +1 -0
- package/dist/lint/pipeline-change-gate.d.ts +101 -0
- package/dist/lint/pipeline-change-gate.d.ts.map +1 -0
- package/dist/lint/post-synth.d.ts +41 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lint/receipt-checks.d.ts +9 -0
- package/dist/lint/receipt-checks.d.ts.map +1 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.d.ts +11 -0
- package/dist/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.d.ts.map +1 -0
- package/dist/lint/rules/cor022-receipt-leaf.d.ts +13 -0
- package/dist/lint/rules/cor022-receipt-leaf.d.ts.map +1 -0
- package/dist/lint/rules/cor024-receipt-secret-pointer.d.ts +3 -0
- package/dist/lint/rules/cor024-receipt-secret-pointer.d.ts.map +1 -0
- package/dist/lint/rules/evl001-non-literal-expression.d.ts.map +1 -1
- package/dist/lint/rules/index.d.ts +3 -1
- package/dist/lint/rules/index.d.ts.map +1 -1
- package/dist/lsp/lexicon-providers.d.ts +7 -0
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/okf-read.d.ts +78 -0
- package/dist/okf-read.d.ts.map +1 -0
- package/dist/op/activity-contract.d.ts +139 -0
- package/dist/op/activity-contract.d.ts.map +1 -0
- package/dist/op/builders.d.ts +140 -3
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/converge-rule.d.ts +161 -0
- package/dist/op/converge-rule.d.ts.map +1 -0
- package/dist/op/generate-pipeline.d.ts +39 -0
- package/dist/op/generate-pipeline.d.ts.map +1 -0
- package/dist/op/index.d.ts +18 -2
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +2 -1
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts +42 -0
- package/dist/op/op-verb-class.d.ts.map +1 -0
- package/dist/op/operator.d.ts +128 -0
- package/dist/op/operator.d.ts.map +1 -0
- package/dist/op/receipt-store.d.ts +138 -0
- package/dist/op/receipt-store.d.ts.map +1 -0
- package/dist/op/step-output-ref.d.ts +187 -0
- package/dist/op/step-output-ref.d.ts.map +1 -0
- package/dist/op/types.d.ts +49 -2
- package/dist/op/types.d.ts.map +1 -1
- package/dist/provenance.d.ts +73 -3
- package/dist/provenance.d.ts.map +1 -1
- package/dist/runtime-adapter.d.ts +7 -1
- package/dist/runtime-adapter.d.ts.map +1 -1
- package/dist/secret-materialization.d.ts +138 -0
- package/dist/secret-materialization.d.ts.map +1 -0
- package/dist/secret-provenance.d.ts +218 -0
- package/dist/secret-provenance.d.ts.map +1 -0
- package/dist/serializer.d.ts +29 -0
- package/dist/serializer.d.ts.map +1 -1
- package/dist/toml.d.ts +40 -5
- package/dist/toml.d.ts.map +1 -1
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +4 -1
- package/src/audit/catalog.test.ts +1 -1
- package/src/audit/catalog.ts +75 -3
- package/src/audit/core.test.ts +57 -0
- package/src/audit/core.ts +0 -0
- package/src/audit/detect-bundle.test.ts +1 -1
- package/src/audit/discover.test.ts +24 -0
- package/src/audit/discover.ts +40 -4
- package/src/audit/fetch.test.ts +216 -3
- package/src/audit/fetch.ts +270 -59
- package/src/audit/report-html.ts +5 -2
- package/src/audit/report-model.ts +9 -0
- package/src/audit/report.test.ts +22 -0
- package/src/audit/report.ts +3 -2
- package/src/audit/rules-doc.ts +13 -1
- package/src/audit/secrets.test.ts +303 -0
- package/src/audit/secrets.ts +406 -0
- package/src/audit/wrangler.test.ts +230 -0
- package/src/audit/wrangler.ts +290 -0
- package/src/build.test.ts +41 -0
- package/src/build.ts +39 -6
- package/src/cli/command-group.ts +1 -1
- package/src/cli/commands/__fixtures__/audit-fountain/agents/fleet.yaml +27 -0
- package/src/cli/commands/__fixtures__/audit-fountain/k8s/deploy.yaml +16 -0
- package/src/cli/commands/__fixtures__/audit-fountain-clean/fleet.yaml +20 -0
- package/src/cli/commands/__fixtures__/schemas/sarif-2.1.0.schema.json +2882 -0
- package/src/cli/commands/audit.test.ts +268 -1
- package/src/cli/commands/audit.ts +87 -18
- package/src/cli/commands/build.test.ts +245 -0
- package/src/cli/commands/build.ts +210 -21
- package/src/cli/commands/lint.ts +15 -3
- package/src/cli/handlers/build.ts +2 -0
- package/src/cli/handlers/components.test.ts +199 -1
- package/src/cli/handlers/components.ts +160 -3
- package/src/cli/handlers/explain.test.ts +70 -1
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +12 -3
- package/src/cli/handlers/lifecycle.test.ts +115 -1
- package/src/cli/handlers/lifecycle.ts +96 -15
- package/src/cli/handlers/operator.test.ts +255 -0
- package/src/cli/handlers/operator.ts +240 -0
- package/src/cli/handlers/scenario.test.ts +456 -0
- package/src/cli/handlers/scenario.ts +330 -0
- package/src/cli/main.test.ts +23 -0
- package/src/cli/main.ts +72 -1
- package/src/cli/mcp/resource-handlers.ts +38 -1
- package/src/cli/mcp/server.test.ts +323 -3
- package/src/cli/mcp/server.ts +84 -7
- package/src/cli/mcp/tools/explain.ts +51 -2
- package/src/cli/mcp/types.ts +27 -1
- package/src/cli/plugins.ts +4 -2
- package/src/cli/registry.ts +14 -2
- package/src/cli/reporters/stylish.test.ts +154 -0
- package/src/cli/reporters/stylish.ts +154 -33
- package/src/codegen/docs-rule-scanning.test.ts +42 -0
- package/src/codegen/docs-rule-scanning.ts +25 -2
- package/src/components/README.md +7 -0
- package/src/components/auto-release.ts +6 -0
- package/src/components/capability.ts +17 -2
- package/src/components/cli-support.test.ts +17 -0
- package/src/components/cli-support.ts +13 -1
- package/src/components/component-schema.test.ts +32 -0
- package/src/components/component.schema.json +6 -0
- package/src/components/component.test.ts +21 -0
- package/src/components/component.ts +15 -0
- package/src/components/driver.ts +12 -4
- package/src/components/registry.test.ts +7 -2
- package/src/components/starter-plugin.ts +17 -0
- package/src/components/verbs/ensure-secret.test.ts +130 -0
- package/src/components/verbs/ensure-secret.ts +79 -0
- package/src/components/verbs/index.ts +13 -0
- package/src/components/verbs/r2-sync.test.ts +107 -0
- package/src/components/verbs/r2-sync.ts +124 -0
- package/src/components/verbs/run-agent.test.ts +683 -0
- package/src/components/verbs/run-agent.ts +786 -0
- package/src/components/verbs/sign.test.ts +19 -0
- package/src/components/verbs/sign.ts +34 -2
- package/src/components/verbs/wrangler.test.ts +170 -0
- package/src/components/verbs/wrangler.ts +241 -0
- package/src/composite.ts +31 -2
- package/src/config.test.ts +15 -0
- package/src/config.ts +30 -0
- package/src/deep-observation.test.ts +19 -0
- package/src/deep-observation.ts +17 -0
- package/src/discovery/collect.ts +11 -2
- package/src/discovery/fold-import.test.ts +54 -0
- package/src/discovery/fold-import.ts +178 -38
- package/src/discovery/fold-rank.test.ts +197 -0
- package/src/discovery/fold-rank.ts +346 -0
- package/src/discovery/index.ts +16 -1
- package/src/discovery/param-deps.test.ts +118 -0
- package/src/discovery/param-deps.ts +170 -0
- package/src/effect-receipt-exclusion.test.ts +190 -0
- package/src/effect-receipt.test.ts +419 -0
- package/src/effect-receipt.ts +412 -0
- package/src/fold/fold.test.ts +6 -2
- package/src/fold/fold.ts +184 -3
- package/src/fold/subset.test.ts +95 -6
- package/src/fold/subset.ts +66 -2
- package/src/index.ts +4 -0
- package/src/lexicon-schema.ts +3 -0
- package/src/lexicon.ts +151 -5
- package/src/lifecycle/change-set.ts +46 -7
- package/src/lifecycle/converge-ledger.test.ts +199 -0
- package/src/lifecycle/converge-ledger.ts +179 -0
- package/src/lifecycle/deep-diff.test.ts +79 -1
- package/src/lifecycle/deep-diff.ts +23 -0
- package/src/lifecycle/deep-observe.ts +13 -2
- package/src/lifecycle/gate-ledger.test.ts +103 -0
- package/src/lifecycle/gate-ledger.ts +140 -0
- package/src/lifecycle/git.test.ts +430 -0
- package/src/lifecycle/git.ts +446 -84
- package/src/lifecycle/index.ts +6 -0
- package/src/lifecycle/lease.test.ts +343 -0
- package/src/lifecycle/lease.ts +270 -0
- package/src/lifecycle/observation-baseline.test.ts +46 -0
- package/src/lifecycle/observation-baseline.ts +33 -1
- package/src/lifecycle/receipt-plan.test.ts +250 -0
- package/src/lifecycle/receipt-plan.ts +249 -0
- package/src/lifecycle/release-ledger.ts +20 -0
- package/src/lifecycle/scenario-eval.test.ts +199 -0
- package/src/lifecycle/scenario-eval.ts +158 -0
- package/src/lifecycle/scenario.test.ts +195 -0
- package/src/lifecycle/scenario.ts +321 -0
- package/src/lifecycle/symptoms.test.ts +116 -0
- package/src/lifecycle/symptoms.ts +126 -0
- package/src/lifecycle/teardown.test.ts +31 -0
- package/src/lifecycle/teardown.ts +6 -4
- package/src/lifecycle/unobserved-gate.test.ts +109 -0
- package/src/lifecycle/unobserved-gate.ts +102 -0
- package/src/lint/knowledge-checks.test.ts +80 -0
- package/src/lint/knowledge-checks.ts +74 -0
- package/src/lint/output-checks.test.ts +85 -0
- package/src/lint/output-checks.ts +99 -0
- package/src/lint/output-docs.test.ts +220 -0
- package/src/lint/output-docs.ts +204 -0
- package/src/lint/pipeline-change-gate.test.ts +144 -0
- package/src/lint/pipeline-change-gate.ts +153 -0
- package/src/lint/post-synth.test.ts +97 -0
- package/src/lint/post-synth.ts +60 -0
- package/src/lint/receipt-checks.test.ts +101 -0
- package/src/lint/receipt-checks.ts +93 -0
- package/src/lint/rules/__fixtures__/comp/comp003/pass/agent-turn.component.ts +26 -0
- package/src/lint/rules/comp/comp.test.ts +49 -1
- package/src/lint/rules/cor022-receipt-leaf.test.ts +116 -0
- package/src/lint/rules/cor022-receipt-leaf.ts +130 -0
- package/src/lint/rules/cor024-receipt-secret-pointer.test.ts +121 -0
- package/src/lint/rules/cor024-receipt-secret-pointer.ts +218 -0
- package/src/lint/rules/evl001-non-literal-expression.test.ts +35 -3
- package/src/lint/rules/evl001-non-literal-expression.ts +7 -0
- package/src/lint/rules/index.ts +7 -1
- package/src/lsp/lexicon-providers.test.ts +44 -0
- package/src/lsp/lexicon-providers.ts +11 -1
- package/src/okf-read.test.ts +149 -0
- package/src/okf-read.ts +197 -0
- package/src/op/activity-contract.test.ts +180 -0
- package/src/op/activity-contract.ts +278 -0
- package/src/op/builders-exports.test.ts +17 -1
- package/src/op/builders.ts +198 -6
- package/src/op/converge-rule.test.ts +179 -0
- package/src/op/converge-rule.ts +311 -0
- package/src/op/effect-step.test.ts +311 -0
- package/src/op/generate-pipeline.test.ts +53 -0
- package/src/op/generate-pipeline.ts +99 -0
- package/src/op/index.ts +40 -3
- package/src/op/local-executor.test.ts +92 -0
- package/src/op/local-executor.ts +212 -29
- package/src/op/op-verb-class.test.ts +126 -0
- package/src/op/op-verb-class.ts +115 -0
- package/src/op/op.test.ts +25 -2
- package/src/op/operator.test.ts +346 -0
- package/src/op/operator.ts +213 -0
- package/src/op/receipt-store.ts +211 -0
- package/src/op/step-output-ref.test.ts +334 -0
- package/src/op/step-output-ref.ts +453 -0
- package/src/op/types.ts +51 -2
- package/src/provenance.test.ts +151 -4
- package/src/provenance.ts +118 -4
- package/src/runtime-adapter.ts +31 -10
- package/src/secret-materialization.test.ts +199 -0
- package/src/secret-materialization.ts +235 -0
- package/src/secret-provenance.test.ts +388 -0
- package/src/secret-provenance.ts +475 -0
- package/src/serializer.ts +30 -0
- package/src/toml.test.ts +157 -384
- package/src/toml.ts +371 -5
- package/src/yaml.test.ts +88 -0
- package/src/yaml.ts +76 -6
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chant operator` / `chant operator status` / `chant approve` (#1485,
|
|
3
|
+
* epic #1487) — the CLI surface for the native durable-tick operator. See
|
|
4
|
+
* `../../op/operator.ts` for the loop itself; this module is the thin CLI
|
|
5
|
+
* shell around it (discover, load activities, print), mirroring
|
|
6
|
+
* `run.ts`'s `runOpLocal` shape (SIGINT → AbortController, `loadActivities`/
|
|
7
|
+
* `loadProfiles` from the project's configured lexicons).
|
|
8
|
+
*/
|
|
9
|
+
import { loadChantConfig } from "../../config";
|
|
10
|
+
import { discoverOps } from "../../op/discover";
|
|
11
|
+
import { loadActivities, loadProfiles } from "../../op/activity-registry";
|
|
12
|
+
import { parseDuration } from "../../op/local-executor";
|
|
13
|
+
import {
|
|
14
|
+
discoverConvergeOps,
|
|
15
|
+
runOperatorRound,
|
|
16
|
+
runOperatorForever,
|
|
17
|
+
formatRoundLine,
|
|
18
|
+
DEFAULT_OPERATOR_INTERVAL_MS,
|
|
19
|
+
type OperatorTickEvent,
|
|
20
|
+
} from "../../op/operator";
|
|
21
|
+
import { readLease, DEFAULT_LEASE_TTL_MS } from "../../lifecycle/lease";
|
|
22
|
+
import { readConvergeLedger, type ConvergeTickRecord } from "../../lifecycle/converge-ledger";
|
|
23
|
+
import { appendGateResolution, readGateResolutions, latestResolutionSince } from "../../lifecycle/gate-ledger";
|
|
24
|
+
import { pushLifecycle } from "../../lifecycle/git";
|
|
25
|
+
import { formatError, formatWarning, formatSuccess, formatBold, formatInfo } from "../format";
|
|
26
|
+
import type { CommandContext } from "../registry";
|
|
27
|
+
|
|
28
|
+
/** Load the activities a local tick needs, the same way `runOpLocal` does: base temporal activities plus whatever the project's configured lexicons contribute. Best-effort on the lexicon list — an unreadable `chant.config.ts` falls back to base activities only. */
|
|
29
|
+
async function loadOperatorActivities() {
|
|
30
|
+
let lexicons: string[] = [];
|
|
31
|
+
try {
|
|
32
|
+
lexicons = (await loadChantConfig(process.cwd())).config.lexicons ?? [];
|
|
33
|
+
} catch {
|
|
34
|
+
// No/invalid chant.config — fall back to base activities only.
|
|
35
|
+
}
|
|
36
|
+
return Promise.all([loadActivities(lexicons), loadProfiles()]);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ── chant operator ──────────────────────────────────────────────────────────
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* `chant operator [--env <env>] [--interval <duration>] [--lease-ttl
|
|
43
|
+
* <duration>] [--once]` — run scheduled ticks for this project's discovered
|
|
44
|
+
* ConvergeOps, locally, with no Temporal installed (issue's own worked
|
|
45
|
+
* example). `--once` runs a single round and exits (also the offline test
|
|
46
|
+
* story, and what a cron/systemd-timer/k8s-CronJob invoker uses instead of
|
|
47
|
+
* leaving the daemon running); omitted, the daemon loops until Ctrl-C.
|
|
48
|
+
*/
|
|
49
|
+
export async function runOperator(ctx: CommandContext): Promise<number> {
|
|
50
|
+
const { ops, errors } = await discoverConvergeOps({ env: ctx.args.env });
|
|
51
|
+
for (const err of errors) console.error(formatWarning({ message: err }));
|
|
52
|
+
|
|
53
|
+
if (ops.length === 0) {
|
|
54
|
+
console.error(formatWarning({
|
|
55
|
+
message: ctx.args.env
|
|
56
|
+
? `No ConvergeOp declarations found for env "${ctx.args.env}"`
|
|
57
|
+
: "No ConvergeOp declarations found (*.op.ts built with ConvergeOp(...))",
|
|
58
|
+
}));
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
let activities, profiles;
|
|
63
|
+
try {
|
|
64
|
+
[activities, profiles] = await loadOperatorActivities();
|
|
65
|
+
} catch (err) {
|
|
66
|
+
console.error(formatError({ message: err instanceof Error ? err.message : String(err) }));
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const intervalMs = ctx.args.interval ? parseDuration(ctx.args.interval) : DEFAULT_OPERATOR_INTERVAL_MS;
|
|
71
|
+
const leaseTtlMs = ctx.args.leaseTtl ? parseDuration(ctx.args.leaseTtl) : DEFAULT_LEASE_TTL_MS;
|
|
72
|
+
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const onSigint = () => {
|
|
75
|
+
console.error(formatWarning({ message: "interrupted — stopping operator" }));
|
|
76
|
+
controller.abort();
|
|
77
|
+
};
|
|
78
|
+
process.once("SIGINT", onSigint);
|
|
79
|
+
|
|
80
|
+
const printRound = (events: OperatorTickEvent[]) => {
|
|
81
|
+
for (const event of events) console.error(formatInfo(formatRoundLine(event)));
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
if (ctx.args.once) {
|
|
86
|
+
const events = await runOperatorRound({ env: ctx.args.env, leaseTtlMs, activities, profiles, signal: controller.signal });
|
|
87
|
+
printRound(events);
|
|
88
|
+
return events.some((e) => e.kind === "tick-failed") ? 1 : 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.error(formatInfo(
|
|
92
|
+
`chant operator: watching ${ops.length} ConvergeOp(s) every ${intervalMs}ms (Ctrl-C to stop)`,
|
|
93
|
+
));
|
|
94
|
+
await runOperatorForever({
|
|
95
|
+
env: ctx.args.env,
|
|
96
|
+
intervalMs,
|
|
97
|
+
leaseTtlMs,
|
|
98
|
+
activities,
|
|
99
|
+
profiles,
|
|
100
|
+
signal: controller.signal,
|
|
101
|
+
onRound: printRound,
|
|
102
|
+
});
|
|
103
|
+
return 0;
|
|
104
|
+
} finally {
|
|
105
|
+
process.removeListener("SIGINT", onSigint);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ── chant operator status ───────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
interface OpStatusLine {
|
|
112
|
+
op: string;
|
|
113
|
+
env: string;
|
|
114
|
+
lastTick?: ConvergeTickRecord;
|
|
115
|
+
pendingGates: { rule: string; op?: string; gate: string }[];
|
|
116
|
+
lease?: { holder: string; expiresAt: string };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function statusFor(opName: string, env: string, cwd?: string): Promise<OpStatusLine> {
|
|
120
|
+
const [{ records }, { record: lease }] = await Promise.all([
|
|
121
|
+
readConvergeLedger(env, { cwd }),
|
|
122
|
+
readLease(opName, { cwd }),
|
|
123
|
+
]);
|
|
124
|
+
const ownRecords = records.filter((r) => r.op === opName);
|
|
125
|
+
const lastTick = ownRecords.at(-1);
|
|
126
|
+
|
|
127
|
+
const pendingGates: OpStatusLine["pendingGates"] = [];
|
|
128
|
+
if (lastTick) {
|
|
129
|
+
for (const outcome of lastTick.outcomes) {
|
|
130
|
+
if (outcome.action !== "gated" || !outcome.gateName || !outcome.op) continue;
|
|
131
|
+
const { records: resolutions } = await readGateResolutions(outcome.op, { cwd });
|
|
132
|
+
const resolved = latestResolutionSince(resolutions, outcome.gateName, lastTick.timestamp);
|
|
133
|
+
if (!resolved) pendingGates.push({ rule: outcome.ruleId, op: outcome.op, gate: outcome.gateName });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
op: opName,
|
|
139
|
+
env,
|
|
140
|
+
lastTick,
|
|
141
|
+
pendingGates,
|
|
142
|
+
lease: lease ? { holder: lease.holder, expiresAt: lease.expiresAt } : undefined,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* `chant operator status [--env <env>] [--json]` — last tick, outcome
|
|
148
|
+
* counts, and pending gates, read from the `chant/lifecycle` orphan branch
|
|
149
|
+
* alone (issue acceptance criterion). No live query, no daemon needs to be
|
|
150
|
+
* running: everything here was already durably recorded by whichever
|
|
151
|
+
* process (this operator, a bare `chant run <op>`, or another machine's
|
|
152
|
+
* operator) ran the last tick.
|
|
153
|
+
*/
|
|
154
|
+
export async function runOperatorStatus(ctx: CommandContext): Promise<number> {
|
|
155
|
+
const { ops, errors } = await discoverConvergeOps({ env: ctx.args.env });
|
|
156
|
+
for (const err of errors) console.error(formatWarning({ message: err }));
|
|
157
|
+
|
|
158
|
+
if (ops.length === 0) {
|
|
159
|
+
console.error(formatWarning({ message: "No ConvergeOp declarations found" }));
|
|
160
|
+
return 0;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const rows = await Promise.all(
|
|
164
|
+
ops.map((d) => statusFor(d.config.name, d.config.searchAttributes?.Env ?? "unknown")),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
if (ctx.args.json) {
|
|
168
|
+
console.log(JSON.stringify(rows, null, 2));
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const row of rows) {
|
|
173
|
+
console.log(formatBold(`${row.op} (${row.env})`));
|
|
174
|
+
if (!row.lastTick) {
|
|
175
|
+
console.log(" no ticks recorded yet");
|
|
176
|
+
} else {
|
|
177
|
+
console.log(` last tick : ${row.lastTick.timestamp}`);
|
|
178
|
+
console.log(` ${row.lastTick.log}`);
|
|
179
|
+
}
|
|
180
|
+
console.log(` lease : ${row.lease ? `held by ${row.lease.holder} (expires ${row.lease.expiresAt})` : "free"}`);
|
|
181
|
+
if (row.pendingGates.length > 0) {
|
|
182
|
+
console.log(` pending gates:`);
|
|
183
|
+
for (const g of row.pendingGates) {
|
|
184
|
+
console.log(` - ${g.op ?? row.op} gate "${g.gate}" (rule ${g.rule}) — resolve: chant approve ${g.op ?? row.op} ${g.gate}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
console.log("");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ── chant approve <op> <gate> ───────────────────────────────────────────────
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* `chant approve <op> <gate> [--actor <name>] [--note <text>]` — record the
|
|
197
|
+
* out-of-band resolution fact for a gate a converge tick recorded as gated
|
|
198
|
+
* (issue: "resolution is an out-of-band act that writes the counterpart
|
|
199
|
+
* fact"). Per the issue's own leaning on open question 3 ("local trust in
|
|
200
|
+
* v1"), this performs no authorization check beyond "you can run `chant
|
|
201
|
+
* approve` locally" — see `../../lifecycle/gate-ledger.ts`'s doc for what
|
|
202
|
+
* this record does and, just as importantly, does not (yet) do: it does
|
|
203
|
+
* not retroactively unblock the gated op's own local dispatch, which the
|
|
204
|
+
* local executor still refuses unconditionally.
|
|
205
|
+
*/
|
|
206
|
+
export async function runApprove(ctx: CommandContext): Promise<number> {
|
|
207
|
+
const opName = ctx.args.path;
|
|
208
|
+
const gate = ctx.args.extraPositional;
|
|
209
|
+
if (!opName || opName === "." || !gate) {
|
|
210
|
+
console.error(formatError({ message: "Usage: chant approve <op> <gate>" }));
|
|
211
|
+
return 1;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const { ops } = await discoverOps();
|
|
215
|
+
if (!ops.has(opName)) {
|
|
216
|
+
console.error(formatWarning({
|
|
217
|
+
message: `Op "${opName}" was not found among discovered *.op.ts declarations — recording the resolution anyway`,
|
|
218
|
+
}));
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const resolvedBy = ctx.args.actor ?? process.env.GITHUB_ACTOR ?? process.env.GITLAB_USER_LOGIN ?? process.env.USER ?? "unknown";
|
|
222
|
+
|
|
223
|
+
const { record } = await appendGateResolution({
|
|
224
|
+
op: opName,
|
|
225
|
+
gate,
|
|
226
|
+
resolvedBy,
|
|
227
|
+
timestamp: new Date().toISOString(),
|
|
228
|
+
...(ctx.args.note ? { note: ctx.args.note } : {}),
|
|
229
|
+
});
|
|
230
|
+
await pushLifecycle().catch(() => undefined);
|
|
231
|
+
|
|
232
|
+
console.error(formatSuccess(
|
|
233
|
+
`Gate "${gate}" on "${opName}" resolved by ${record.resolvedBy} at ${record.timestamp}`,
|
|
234
|
+
));
|
|
235
|
+
console.error(formatInfo(
|
|
236
|
+
"This records the resolution as a fact; it does not itself re-run the gated dispatch — " +
|
|
237
|
+
"the local executor still refuses any op with a gate. Re-run it with --temporal, or via the PR that carries the change.",
|
|
238
|
+
));
|
|
239
|
+
return 0;
|
|
240
|
+
}
|