@intentius/chant 0.101.0 → 0.104.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/agents/checks.d.ts.map +1 -1
- package/dist/attrref.d.ts.map +1 -1
- package/dist/audit/core.d.ts +2 -0
- package/dist/audit/core.d.ts.map +1 -1
- package/dist/audit/discover.d.ts.map +1 -1
- package/dist/audit/nginx.d.ts.map +1 -1
- package/dist/audit/prior-art.d.ts +48 -0
- package/dist/audit/prior-art.d.ts.map +1 -1
- package/dist/behaviour-kinds.d.ts.map +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/change-set.d.ts +232 -0
- package/dist/change-set.d.ts.map +1 -0
- 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.map +1 -1
- package/dist/cli/commands/carve-emit.d.ts.map +1 -1
- package/dist/cli/commands/check-lexicon.d.ts +16 -0
- package/dist/cli/commands/check-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/import.d.ts +8 -0
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/init-lexicon.d.ts.map +1 -1
- package/dist/cli/commands/init.d.ts +19 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/onboard.d.ts +9 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -1
- package/dist/cli/commands/pinned-upgrade.d.ts +19 -5
- package/dist/cli/commands/pinned-upgrade.d.ts.map +1 -1
- package/dist/cli/handlers/build.d.ts.map +1 -1
- package/dist/cli/handlers/change-set.d.ts +11 -0
- package/dist/cli/handlers/change-set.d.ts.map +1 -0
- package/dist/cli/handlers/dev.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.d.ts +33 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/cli/handlers/misc.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +16 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/pr.d.ts +31 -0
- package/dist/cli/handlers/pr.d.ts.map +1 -0
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/lsp/server.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/op-tools.d.ts.map +1 -1
- package/dist/cli/mcp/server.d.ts.map +1 -1
- package/dist/cli/mcp/tools/build.d.ts.map +1 -1
- package/dist/cli/mcp/tools/composites.d.ts.map +1 -1
- package/dist/cli/mcp/tools/explain.d.ts.map +1 -1
- package/dist/cli/mcp/tools/import.d.ts.map +1 -1
- package/dist/cli/mcp/tools/lint.d.ts.map +1 -1
- package/dist/cli/mcp/tools/scaffold.d.ts.map +1 -1
- package/dist/cli/mcp/tools/search.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-tools.d.ts +4 -3
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +74 -3
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/fetch.d.ts.map +1 -1
- package/dist/codegen/naming.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.d.ts +67 -3
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/codegen/registry.d.ts.map +1 -1
- package/dist/components/auto-release.d.ts +16 -0
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/capability-plugin-loader.d.ts.map +1 -1
- package/dist/components/capability.d.ts +53 -0
- package/dist/components/capability.d.ts.map +1 -1
- package/dist/components/changed-files.d.ts +31 -0
- package/dist/components/changed-files.d.ts.map +1 -0
- package/dist/components/cli-support.d.ts +9 -1
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/component.d.ts +24 -0
- package/dist/components/component.d.ts.map +1 -1
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/driver.d.ts +13 -0
- package/dist/components/driver.d.ts.map +1 -1
- package/dist/components/fan-out-output.d.ts +6 -0
- package/dist/components/fan-out-output.d.ts.map +1 -1
- package/dist/components/fan-out-record.d.ts +41 -0
- package/dist/components/fan-out-record.d.ts.map +1 -0
- package/dist/components/fan-out-run.d.ts +65 -0
- package/dist/components/fan-out-run.d.ts.map +1 -1
- package/dist/components/fan-out-support.d.ts +2 -0
- package/dist/components/fan-out-support.d.ts.map +1 -1
- package/dist/components/fan-out.d.ts +6 -0
- package/dist/components/fan-out.d.ts.map +1 -1
- package/dist/components/gated-wave-pipeline.d.ts +50 -0
- package/dist/components/gated-wave-pipeline.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layers.d.ts +25 -0
- package/dist/components/layers.d.ts.map +1 -0
- package/dist/components/pr-pipeline.d.ts +61 -0
- package/dist/components/pr-pipeline.d.ts.map +1 -0
- package/dist/components/pr-run.d.ts +119 -0
- package/dist/components/pr-run.d.ts.map +1 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/starter-plugin.d.ts.map +1 -1
- package/dist/components/verbs/process-runner.d.ts.map +1 -1
- package/dist/components/verbs/r2-sync.d.ts.map +1 -1
- package/dist/components/verbs/run-agent.d.ts.map +1 -1
- package/dist/components/verbs/sbom-generator.d.ts.map +1 -1
- package/dist/components/verbs/shell.d.ts.map +1 -1
- package/dist/components/verbs/sign.d.ts.map +1 -1
- package/dist/components/verbs/verify.d.ts.map +1 -1
- package/dist/components/verbs/vuln-gate.d.ts.map +1 -1
- package/dist/components/verbs/vuln-scan.d.ts.map +1 -1
- package/dist/components/verbs/wrangler.d.ts.map +1 -1
- package/dist/components/wave-plan.d.ts +49 -0
- package/dist/components/wave-plan.d.ts.map +1 -0
- package/dist/composite.d.ts.map +1 -1
- package/dist/config.d.ts +19 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/declarable.d.ts +16 -0
- package/dist/declarable.d.ts.map +1 -1
- package/dist/discovery/cache.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +15 -5
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/param-deps.d.ts +16 -0
- package/dist/discovery/param-deps.d.ts.map +1 -1
- package/dist/discovery/sandbox/policy-wire.d.ts.map +1 -1
- package/dist/discovery/specifier-resolve.d.ts +37 -0
- package/dist/discovery/specifier-resolve.d.ts.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/fold/fold.d.ts +3 -1
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/gated-waves.d.ts +147 -0
- package/dist/gated-waves.d.ts.map +1 -0
- package/dist/graph-detail.d.ts.map +1 -1
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/graph-layout.d.ts.map +1 -1
- package/dist/import/base-parser.d.ts.map +1 -1
- package/dist/import/embedded.d.ts +7 -0
- package/dist/import/embedded.d.ts.map +1 -1
- package/dist/import/parser-options.d.ts +14 -0
- package/dist/import/parser-options.d.ts.map +1 -0
- package/dist/import/parser.d.ts +17 -0
- package/dist/import/parser.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts.map +1 -1
- package/dist/lexicon-output.d.ts.map +1 -1
- package/dist/lexicon-schema.d.ts +3 -3
- package/dist/lexicon.d.ts +103 -3
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/assert-live.d.ts.map +1 -1
- package/dist/lifecycle/gate-ledger.d.ts +22 -0
- package/dist/lifecycle/gate-ledger.d.ts.map +1 -1
- package/dist/lifecycle/git.d.ts +46 -1
- package/dist/lifecycle/git.d.ts.map +1 -1
- package/dist/lifecycle/member-ledger.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/plan-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/scenario.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/work-lease.d.ts +61 -2
- package/dist/lifecycle/work-lease.d.ts.map +1 -1
- package/dist/lint/config.d.ts +8 -8
- package/dist/lint/engine.d.ts +6 -0
- package/dist/lint/engine.d.ts.map +1 -1
- package/dist/lint/post-synth.d.ts +18 -0
- package/dist/lint/post-synth.d.ts.map +1 -1
- package/dist/lsp/lexicon-providers.d.ts.map +1 -1
- package/dist/op/activities/activity-contracts.d.ts +137 -11
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/apply.d.ts +79 -9
- package/dist/op/activities/apply.d.ts.map +1 -1
- package/dist/op/activities/change-set.d.ts +62 -0
- package/dist/op/activities/change-set.d.ts.map +1 -0
- package/dist/op/activities/decide.d.ts +2 -0
- package/dist/op/activities/decide.d.ts.map +1 -1
- package/dist/op/activities/factory.d.ts +137 -0
- package/dist/op/activities/factory.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +5 -1
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/lexicon-upgrade.d.ts +44 -12
- package/dist/op/activities/lexicon-upgrade.d.ts.map +1 -1
- package/dist/op/activity-contract.d.ts +1 -1
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/activity-failure.d.ts.map +1 -1
- package/dist/op/activity-profiles.d.ts.map +1 -1
- package/dist/op/builders.d.ts +11 -0
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/apply-op.d.ts +12 -5
- package/dist/op/composites/apply-op.d.ts.map +1 -1
- package/dist/op/composites/lexicon-upgrade-op.d.ts +22 -6
- package/dist/op/composites/lexicon-upgrade-op.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts +5 -1
- package/dist/op/decide-backend.d.ts.map +1 -1
- package/dist/op/decide-read-inputs.d.ts +4 -2
- package/dist/op/decide-read-inputs.d.ts.map +1 -1
- package/dist/op/emulator-lifecycle.d.ts +21 -2
- package/dist/op/emulator-lifecycle.d.ts.map +1 -1
- package/dist/op/factory.d.ts +83 -0
- package/dist/op/factory.d.ts.map +1 -0
- package/dist/op/gate-approval.d.ts +5 -1
- package/dist/op/gate-approval.d.ts.map +1 -1
- package/dist/op/gate-wait.d.ts.map +1 -1
- package/dist/op/gate.d.ts +19 -3
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/index.d.ts +6 -1
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +6 -0
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/op-ir.d.ts +2 -0
- package/dist/op/op-ir.d.ts.map +1 -1
- package/dist/op/op-verb-class.d.ts.map +1 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/run-context.d.ts +39 -0
- package/dist/op/run-context.d.ts.map +1 -0
- package/dist/op/run-live.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/source-archive.d.ts.map +1 -1
- package/dist/op/steward-beside.d.ts.map +1 -1
- package/dist/op/steward-points.d.ts.map +1 -1
- package/dist/op/steward.d.ts.map +1 -1
- package/dist/op/types.d.ts +16 -3
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts +24 -4
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/plan-summary.d.ts +207 -0
- package/dist/plan-summary.d.ts.map +1 -0
- package/dist/pr-forge.d.ts +105 -0
- package/dist/pr-forge.d.ts.map +1 -0
- package/dist/pr-loop.d.ts +178 -0
- package/dist/pr-loop.d.ts.map +1 -0
- package/dist/project-root.d.ts.map +1 -1
- package/dist/provenance.d.ts +21 -0
- package/dist/provenance.d.ts.map +1 -1
- package/dist/pseudo-parameter.d.ts.map +1 -1
- package/dist/reconcile.d.ts.map +1 -1
- package/dist/secret-materialization.d.ts.map +1 -1
- package/dist/telemetry-attribution.d.ts +31 -0
- package/dist/telemetry-attribution.d.ts.map +1 -1
- package/dist/terraform/emit-source.d.ts.map +1 -1
- package/dist/terraform/hcl2json.d.ts +45 -0
- package/dist/terraform/hcl2json.d.ts.map +1 -0
- package/dist/terraform/parse.d.ts +4 -40
- package/dist/terraform/parse.d.ts.map +1 -1
- package/dist/testing.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -1
- package/dist/workspace/agent-cli.d.ts +5 -0
- package/dist/workspace/agent-cli.d.ts.map +1 -1
- package/dist/workspace/box-cli.d.ts +12 -0
- package/dist/workspace/box-cli.d.ts.map +1 -0
- package/dist/workspace/box-factory.d.ts +97 -0
- package/dist/workspace/box-factory.d.ts.map +1 -0
- package/dist/workspace/box-listing.d.ts +85 -0
- package/dist/workspace/box-listing.d.ts.map +1 -0
- package/dist/workspace/box-publish.d.ts +147 -0
- package/dist/workspace/box-publish.d.ts.map +1 -0
- package/dist/workspace/broker-protocol.d.ts +190 -0
- package/dist/workspace/broker-protocol.d.ts.map +1 -0
- package/dist/workspace/changes.d.ts.map +1 -1
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -1
- package/dist/workspace/checks/boxes.d.ts.map +1 -1
- package/dist/workspace/checks.d.ts +5 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +10 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/composites.d.ts +2 -2
- package/dist/workspace/composites.d.ts.map +1 -1
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts +17 -0
- package/dist/workspace/conformance/__fixtures__/reference-broker.d.ts.map +1 -0
- package/dist/workspace/conformance/broker.d.ts +202 -0
- package/dist/workspace/conformance/broker.d.ts.map +1 -0
- package/dist/workspace/conformance/index.d.ts +68 -6
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/conformance/vitest.d.ts +19 -3
- package/dist/workspace/conformance/vitest.d.ts.map +1 -1
- package/dist/workspace/conformance/writer.d.ts +462 -0
- package/dist/workspace/conformance/writer.d.ts.map +1 -0
- package/dist/workspace/decide.d.ts +126 -12
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/decision-points.schema.json +11 -4
- package/dist/workspace/declaration.d.ts +156 -4
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +383 -5
- package/dist/workspace/environments.d.ts +36 -10
- package/dist/workspace/environments.d.ts.map +1 -1
- package/dist/workspace/factory-rules.d.ts +180 -0
- package/dist/workspace/factory-rules.d.ts.map +1 -0
- package/dist/workspace/generated-files.d.ts.map +1 -1
- package/dist/workspace/graph-cache.d.ts.map +1 -1
- package/dist/workspace/graph-cli.d.ts +2 -0
- package/dist/workspace/graph-cli.d.ts.map +1 -1
- package/dist/workspace/identity.d.ts +111 -0
- package/dist/workspace/identity.d.ts.map +1 -0
- package/dist/workspace/init.d.ts +21 -0
- package/dist/workspace/init.d.ts.map +1 -1
- package/dist/workspace/intent-cli.d.ts +7 -4
- package/dist/workspace/intent-cli.d.ts.map +1 -1
- package/dist/workspace/intent-record.d.ts +36 -2
- package/dist/workspace/intent-record.d.ts.map +1 -1
- package/dist/workspace/intent.d.ts +249 -8
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/json-edit.d.ts +24 -0
- package/dist/workspace/json-edit.d.ts.map +1 -0
- package/dist/workspace/jsonc.d.ts +11 -0
- package/dist/workspace/jsonc.d.ts.map +1 -1
- package/dist/workspace/kinds.d.ts +66 -4
- package/dist/workspace/kinds.d.ts.map +1 -1
- package/dist/workspace/lexicon-symbols.d.ts +29 -0
- package/dist/workspace/lexicon-symbols.d.ts.map +1 -0
- package/dist/workspace/lineage-hash-index.d.ts.map +1 -1
- package/dist/workspace/lineage-lock.d.ts +2 -2
- package/dist/workspace/lineage-lock.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts +31 -2
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/links.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +42 -2
- package/dist/workspace/points-cli.d.ts +10 -3
- package/dist/workspace/points-cli.d.ts.map +1 -1
- package/dist/workspace/points.d.ts +66 -5
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/principal-classes.d.ts +114 -0
- package/dist/workspace/principal-classes.d.ts.map +1 -0
- package/dist/workspace/reason-codes.d.ts +53 -4
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/record-assets.d.ts.map +1 -1
- package/dist/workspace/record-sessions.d.ts +5 -7
- package/dist/workspace/record-sessions.d.ts.map +1 -1
- package/dist/workspace/records-checkout.d.ts +54 -0
- package/dist/workspace/records-checkout.d.ts.map +1 -0
- package/dist/workspace/records-cli.d.ts +34 -1
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +7 -3
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-since.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +68 -7
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +43 -9
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/runs-cli.d.ts +296 -0
- package/dist/workspace/runs-cli.d.ts.map +1 -0
- package/dist/workspace/runs.d.ts +544 -0
- package/dist/workspace/runs.d.ts.map +1 -0
- package/dist/workspace/session-kinds.d.ts +1 -1
- package/dist/workspace/session-kinds.d.ts.map +1 -1
- package/dist/workspace/source-block.d.ts +1 -1
- package/dist/workspace/source-block.d.ts.map +1 -1
- package/dist/workspace/squash.d.ts +80 -0
- package/dist/workspace/squash.d.ts.map +1 -0
- package/dist/workspace/status-gates.d.ts +17 -3
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +64 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/symbols.d.ts +63 -0
- package/dist/workspace/symbols.d.ts.map +1 -0
- package/dist/workspace/trailer-joins.d.ts +46 -0
- package/dist/workspace/trailer-joins.d.ts.map +1 -0
- package/dist/workspace/trailers.d.ts +89 -0
- package/dist/workspace/trailers.d.ts.map +1 -0
- package/dist/workspace/trust/attestor.d.ts.map +1 -1
- package/dist/workspace/trust/rotation.d.ts.map +1 -1
- package/dist/workspace/trust/run-commits.d.ts +46 -0
- package/dist/workspace/trust/run-commits.d.ts.map +1 -0
- package/dist/workspace/trust/run-statement.d.ts +128 -0
- package/dist/workspace/trust/run-statement.d.ts.map +1 -0
- package/dist/workspace/trust/seal.d.ts +38 -0
- package/dist/workspace/trust/seal.d.ts.map +1 -1
- package/dist/workspace/trust/test-repo.d.ts.map +1 -1
- package/dist/workspace/trust/verify-cli.d.ts +1 -1
- package/dist/workspace/trust/verify.d.ts +16 -2
- package/dist/workspace/trust/verify.d.ts.map +1 -1
- package/dist/workspace/wip-cli.d.ts +21 -0
- package/dist/workspace/wip-cli.d.ts.map +1 -0
- package/dist/workspace/wip.d.ts +268 -0
- package/dist/workspace/wip.d.ts.map +1 -0
- package/dist/workspace/work-cli.d.ts +39 -3
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +1 -1
- package/dist/workspace/work-evidence.d.ts.map +1 -1
- package/dist/workspace/work-size.d.ts +55 -0
- package/dist/workspace/work-size.d.ts.map +1 -0
- package/dist/workspace/work.d.ts +26 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/dist/workspace/workspace-kinds.schema.json +122 -0
- package/dist/workspace/workspace-principals.schema.json +60 -0
- package/dist/workspace/write-lock-cli.d.ts +60 -0
- package/dist/workspace/write-lock-cli.d.ts.map +1 -0
- package/dist/workspace/write-lock.d.ts +152 -0
- package/dist/workspace/write-lock.d.ts.map +1 -0
- package/dist/workspace/write-scope.d.ts +83 -19
- package/dist/workspace/write-scope.d.ts.map +1 -1
- package/dist/yaml.d.ts +21 -39
- package/dist/yaml.d.ts.map +1 -1
- package/package.json +7 -2
- package/src/__fixtures__/change-set/lifecycle-plan.floci.json +59 -0
- package/src/__fixtures__/change-set/lifecycle-v1.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle-v2.ts.txt +4 -0
- package/src/__fixtures__/change-set/lifecycle.change-set.golden.json +95 -0
- package/src/__fixtures__/change-set/warden.change-set.golden.json +106 -0
- package/src/__fixtures__/change-set/warden.plan.json +44 -0
- package/src/__fixtures__/plan-summary/normalization-vectors.json +1593 -0
- package/src/__fixtures__/pr-loop/pr-apply-applied.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-apply-refused.note.golden.md +31 -0
- package/src/__fixtures__/pr-loop/pr-plan.golden.json +127 -0
- package/src/__fixtures__/pr-loop/pr-plan.note.golden.md +37 -0
- package/src/audit/core.test.ts +15 -0
- package/src/audit/core.ts +8 -2
- package/src/audit/discover.test.ts +11 -0
- package/src/audit/discover.ts +7 -2
- package/src/audit/prior-art.ts +15 -0
- package/src/change-set-bundle.test.ts +57 -0
- package/src/change-set.test.ts +215 -0
- package/src/change-set.ts +445 -0
- package/src/cli/commands/__fixtures__/init-lexicon-output/package.json +1 -1
- package/src/cli/commands/audit-opt-in.test.ts +54 -0
- package/src/cli/commands/audit.ts +29 -2
- package/src/cli/commands/build.test.ts +19 -0
- package/src/cli/commands/build.ts +3 -2
- package/src/cli/commands/carve-emit-state.test.ts +4 -0
- package/src/cli/commands/carve-emit.ts +5 -19
- package/src/cli/commands/check-lexicon.test.ts +62 -1
- package/src/cli/commands/check-lexicon.ts +36 -6
- package/src/cli/commands/import-live.test.ts +18 -0
- package/src/cli/commands/import-parser-options.test.ts +133 -0
- package/src/cli/commands/import.ts +21 -3
- package/src/cli/commands/init-lexicon/templates/project.ts +1 -1
- package/src/cli/commands/init.test.ts +8 -1
- package/src/cli/commands/init.ts +23 -8
- package/src/cli/commands/lint.test.ts +37 -0
- package/src/cli/commands/onboard.test.ts +53 -3
- package/src/cli/commands/onboard.ts +52 -4
- package/src/cli/commands/pinned-upgrade.ts +73 -33
- package/src/cli/handlers/__snapshots__/build-member.test.ts.snap +2 -2
- package/src/cli/handlers/build.ts +13 -1
- package/src/cli/handlers/change-set.test.ts +56 -0
- package/src/cli/handlers/change-set.ts +44 -0
- package/src/cli/handlers/components.ts +2 -2
- package/src/cli/handlers/dev.ts +8 -6
- package/src/cli/handlers/fan-out.test.ts +221 -2
- package/src/cli/handlers/fan-out.ts +165 -75
- package/src/cli/handlers/graph.ts +3 -0
- package/src/cli/handlers/lifecycle.test.ts +67 -0
- package/src/cli/handlers/lifecycle.ts +6 -5
- package/src/cli/handlers/misc.ts +2 -0
- package/src/cli/handlers/operator.test.ts +21 -0
- package/src/cli/handlers/operator.ts +121 -6
- package/src/cli/handlers/pr.ts +373 -0
- package/src/cli/handlers/run.test.ts +111 -0
- package/src/cli/handlers/run.ts +86 -24
- package/src/cli/handlers/scenario.ts +2 -2
- package/src/cli/main.test.ts +21 -0
- package/src/cli/main.ts +246 -30
- package/src/cli/mcp/never-over-mcp.test.ts +101 -0
- package/src/cli/mcp/op-tools.ts +24 -2
- package/src/cli/mcp/workspace-tools.test.ts +5 -2
- package/src/cli/mcp/workspace-tools.ts +62 -7
- package/src/cli/registry.ts +74 -3
- package/src/codegen/pinned-upgrade-multi.test.ts +157 -0
- package/src/codegen/pinned-upgrade-tags.test.ts +112 -0
- package/src/codegen/pinned-upgrade.test.ts +104 -0
- package/src/codegen/pinned-upgrade.ts +250 -56
- package/src/codegen/testdata/postgres-tags.json +242 -0
- package/src/components/auto-release.ts +1 -1
- package/src/components/capability.ts +55 -0
- package/src/components/changed-files.ts +66 -0
- package/src/components/cli-support.ts +28 -5
- package/src/components/component.schema.json +17 -0
- package/src/components/component.ts +25 -0
- package/src/components/deploy-units.ts +3 -0
- package/src/components/driver.test.ts +52 -0
- package/src/components/driver.ts +31 -13
- package/src/components/fan-out-output.ts +42 -1
- package/src/components/fan-out-record.ts +69 -0
- package/src/components/fan-out-run.test.ts +17 -0
- package/src/components/fan-out-run.ts +304 -1
- package/src/components/fan-out-support.ts +3 -0
- package/src/components/fan-out-waves.test.ts +375 -0
- package/src/components/fan-out.ts +18 -17
- package/src/components/gated-wave-pipeline.ts +82 -0
- package/src/components/index.ts +1 -0
- package/src/components/layers.ts +30 -0
- package/src/components/pr-pipeline.ts +91 -0
- package/src/components/pr-run.test.ts +205 -0
- package/src/components/pr-run.ts +280 -0
- package/src/components/promote.ts +5 -0
- package/src/components/verbs/shell.test.ts +11 -0
- package/src/components/verbs/shell.ts +7 -3
- package/src/components/wave-plan.ts +124 -0
- package/src/config.test.ts +21 -0
- package/src/config.ts +15 -0
- package/src/declarable.test.ts +21 -0
- package/src/declarable.ts +19 -0
- package/src/discovery/fold-composite.test.ts +41 -5
- package/src/discovery/fold-import.test.ts +129 -0
- package/src/discovery/fold-import.ts +643 -131
- package/src/discovery/fold-package-composite.test.ts +264 -0
- package/src/discovery/fold-specifiers.test.ts +191 -0
- package/src/discovery/param-deps.test.ts +66 -1
- package/src/discovery/param-deps.ts +45 -0
- package/src/discovery/sandbox/bundle.ts +1 -1
- package/src/discovery/specifier-resolve.ts +344 -0
- package/src/fold/fold.test.ts +39 -1
- package/src/fold/fold.ts +83 -9
- package/src/fold-provenance.test.ts +140 -0
- package/src/gated-waves-bundle.test.ts +62 -0
- package/src/gated-waves.test.ts +118 -0
- package/src/gated-waves.ts +240 -0
- package/src/graph-ir.test.ts +83 -0
- package/src/graph-ir.ts +29 -0
- package/src/import/embedded.test.ts +20 -0
- package/src/import/embedded.ts +13 -0
- package/src/import/parser-options.ts +46 -0
- package/src/import/parser.ts +20 -0
- package/src/index.ts +1 -0
- package/src/lexicon.ts +106 -3
- package/src/lifecycle/gate-ledger.ts +23 -0
- package/src/lifecycle/git.ts +102 -16
- package/src/lifecycle/observe.test.ts +18 -0
- package/src/lifecycle/observe.ts +6 -4
- package/src/lifecycle/snapshot.ts +2 -2
- package/src/lifecycle/work-lease.test.ts +1 -1
- package/src/lifecycle/work-lease.ts +93 -2
- package/src/lint/engine.test.ts +55 -0
- package/src/lint/engine.ts +30 -4
- package/src/lint/output-docs.test.ts +59 -56
- package/src/lint/post-synth.test.ts +19 -0
- package/src/lint/post-synth.ts +19 -1
- package/src/meta/declared-imports.test.ts +1 -1
- package/src/op/activities/activity-contracts.ts +84 -0
- package/src/op/activities/apply.test.ts +189 -5
- package/src/op/activities/apply.ts +230 -8
- package/src/op/activities/change-set.ts +114 -0
- package/src/op/activities/decide.ts +3 -0
- package/src/op/activities/factory.ts +675 -0
- package/src/op/activities/index.ts +9 -0
- package/src/op/activities/lexicon-upgrade.test.ts +160 -6
- package/src/op/activities/lexicon-upgrade.ts +154 -51
- package/src/op/activity-contract.test.ts +21 -1
- package/src/op/activity-contract.ts +19 -9
- package/src/op/builders.ts +23 -0
- package/src/op/composites/apply-op.ts +12 -5
- package/src/op/composites/composites.test.ts +30 -3
- package/src/op/composites/lexicon-upgrade-op.test.ts +7 -2
- package/src/op/composites/lexicon-upgrade-op.ts +29 -8
- package/src/op/decide-backend.ts +5 -1
- package/src/op/decide-read-inputs.ts +33 -5
- package/src/op/emulator-lifecycle.test.ts +23 -0
- package/src/op/emulator-lifecycle.ts +52 -14
- package/src/op/factory.e2e.test.ts +232 -0
- package/src/op/factory.ts +118 -0
- package/src/op/gate-approval.test.ts +74 -0
- package/src/op/gate-approval.ts +5 -1
- package/src/op/gate.ts +31 -5
- package/src/op/index.ts +11 -1
- package/src/op/local-executor.test.ts +15 -0
- package/src/op/local-executor.ts +40 -12
- package/src/op/local-output.ts +1 -1
- package/src/op/op-ir.test.ts +9 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +3 -0
- package/src/op/operator.ts +4 -0
- package/src/op/run-context.test.ts +141 -0
- package/src/op/run-context.ts +51 -0
- package/src/op/runtimes/local.test.ts +14 -0
- package/src/op/runtimes/local.ts +2 -0
- package/src/op/steward-beside.ts +2 -0
- package/src/op/types.ts +16 -3
- package/src/op/work-lease-run.test.ts +47 -0
- package/src/op/work-lease-run.ts +76 -11
- package/src/plan-summary.test.ts +263 -0
- package/src/plan-summary.ts +845 -0
- package/src/pr-forge.test.ts +237 -0
- package/src/pr-forge.ts +332 -0
- package/src/pr-loop-bundle.test.ts +46 -0
- package/src/pr-loop.test.ts +171 -0
- package/src/pr-loop.ts +324 -0
- package/src/provenance.ts +35 -0
- package/src/telemetry-attribution.test.ts +23 -1
- package/src/telemetry-attribution.ts +51 -0
- package/src/terraform/hcl2json.test.ts +21 -0
- package/src/terraform/hcl2json.ts +81 -0
- package/src/terraform/parse.ts +11 -74
- package/src/workspace/agent-cli.ts +7 -3
- package/src/workspace/agent.schema.json +22 -0
- package/src/workspace/app-kind.test.ts +196 -0
- package/src/workspace/box-cli.ts +113 -0
- package/src/workspace/box-factory.test.ts +323 -0
- package/src/workspace/box-factory.ts +136 -0
- package/src/workspace/box-listing-write.schema.json +204 -0
- package/src/workspace/box-listing.test.ts +234 -0
- package/src/workspace/box-listing.ts +324 -0
- package/src/workspace/box-publish.schema.json +498 -0
- package/src/workspace/box-publish.test.ts +204 -0
- package/src/workspace/box-publish.ts +420 -0
- package/src/workspace/box-ship.test.ts +96 -0
- package/src/workspace/broker-protocol.schema.json +186 -0
- package/src/workspace/broker-protocol.test.ts +122 -0
- package/src/workspace/broker-protocol.ts +317 -0
- package/src/workspace/builder-tiers.test.ts +146 -0
- package/src/workspace/change-set.schema.json +460 -0
- package/src/workspace/changes.schema.json +12 -20
- package/src/workspace/changes.ts +4 -1
- package/src/workspace/chant-migrations.e2e.test.ts +17 -5
- package/src/workspace/checks/boxes.test.ts +5 -0
- package/src/workspace/checks.ts +39 -8
- package/src/workspace/component-environments.test.ts +105 -0
- package/src/workspace/compose-graph.ts +7 -0
- package/src/workspace/composites.schema.json +23 -4
- package/src/workspace/composites.test.ts +8 -8
- package/src/workspace/composites.ts +13 -2
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +2 -2
- package/src/workspace/conformance/__fixtures__/reference-broker.ts +207 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.kind.mjs +32 -0
- package/src/workspace/conformance/__writer_fixture__/answers/answer.schema.json +135 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.kind.mjs +37 -0
- package/src/workspace/conformance/__writer_fixture__/contracts/contract.schema.json +213 -0
- package/src/workspace/conformance/__writer_fixture__/decisions/points.json +228 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.kind.mjs +15 -0
- package/src/workspace/conformance/__writer_fixture__/drivers/driver.schema.json +38 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.kind.mjs +54 -0
- package/src/workspace/conformance/__writer_fixture__/sessions/session.schema.json +289 -0
- package/src/workspace/conformance/__writer_fixture__/work/W-001-the-writer-suite-works-this-item.md +25 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.kind.mjs +60 -0
- package/src/workspace/conformance/__writer_fixture__/work/work.schema.json +603 -0
- package/src/workspace/conformance/broker.test.ts +122 -0
- package/src/workspace/conformance/broker.ts +792 -0
- package/src/workspace/conformance/conformance.e2e.test.ts +36 -3
- package/src/workspace/conformance/index.mjs +51 -3
- package/src/workspace/conformance/index.ts +107 -15
- package/src/workspace/conformance/vitest.ts +76 -2
- package/src/workspace/conformance/writer-conformance.e2e.test.ts +177 -0
- package/src/workspace/conformance/writer.test.ts +186 -0
- package/src/workspace/conformance/writer.ts +1191 -0
- package/src/workspace/decide.test.ts +208 -4
- package/src/workspace/decide.ts +433 -73
- package/src/workspace/decision-points.schema.json +11 -4
- package/src/workspace/declaration.schema.json +383 -5
- package/src/workspace/declaration.ts +315 -10
- package/src/workspace/environments.ts +66 -14
- package/src/workspace/factory-rules.test.ts +62 -0
- package/src/workspace/factory-rules.ts +218 -0
- package/src/workspace/graph-cli.ts +6 -3
- package/src/workspace/graph.schema.json +314 -0
- package/src/workspace/identity.test.ts +219 -0
- package/src/workspace/identity.ts +186 -0
- package/src/workspace/init.ts +82 -2
- package/src/workspace/intent-cli.ts +84 -13
- package/src/workspace/intent-patch-id.test.ts +162 -0
- package/src/workspace/intent-record.schema.json +336 -1
- package/src/workspace/intent-record.ts +96 -16
- package/src/workspace/intent-reviews.test.ts +76 -0
- package/src/workspace/intent-squash.test.ts +213 -0
- package/src/workspace/intent-why.test.ts +274 -0
- package/src/workspace/intent.schema.json +950 -9
- package/src/workspace/intent.test.ts +11 -2
- package/src/workspace/intent.ts +722 -65
- package/src/workspace/json-edit.test.ts +121 -0
- package/src/workspace/json-edit.ts +142 -0
- package/src/workspace/jsonc.ts +20 -0
- package/src/workspace/kinds.ts +201 -39
- package/src/workspace/lexicon-symbols.test.ts +148 -0
- package/src/workspace/lexicon-symbols.ts +125 -0
- package/src/workspace/lineage-upgrade.test.ts +63 -0
- package/src/workspace/lineage-upgrade.ts +146 -5
- package/src/workspace/plan-summary.schema.json +155 -0
- package/src/workspace/point-answer.schema.json +42 -2
- package/src/workspace/points-cli.ts +42 -16
- package/src/workspace/points-write.schema.json +163 -4
- package/src/workspace/points.schema.json +157 -2
- package/src/workspace/points.test.ts +13 -1
- package/src/workspace/points.ts +118 -12
- package/src/workspace/pr-report.schema.json +95 -0
- package/src/workspace/principal-classes.test.ts +175 -0
- package/src/workspace/principal-classes.ts +307 -0
- package/src/workspace/profiles.test.ts +159 -0
- package/src/workspace/read-contract.test.ts +2 -2
- package/src/workspace/reason-codes.test.ts +23 -3
- package/src/workspace/reason-codes.ts +61 -4
- package/src/workspace/record-sessions.ts +9 -8
- package/src/workspace/records-amend.schema.json +80 -0
- package/src/workspace/records-checkout.ts +106 -0
- package/src/workspace/records-cli.ts +123 -17
- package/src/workspace/records-close.schema.json +79 -0
- package/src/workspace/records-close.ts +31 -7
- package/src/workspace/records-concurrent.e2e.test.ts +135 -0
- package/src/workspace/records-concurrent.test.ts +145 -0
- package/src/workspace/records-formats.test.ts +46 -10
- package/src/workspace/records-new.schema.json +9 -0
- package/src/workspace/records-review.schema.json +80 -0
- package/src/workspace/records-sessions-write.test.ts +69 -0
- package/src/workspace/records-sessions.test.ts +22 -0
- package/src/workspace/records-uncommitted.test.ts +171 -0
- package/src/workspace/records-write.ts +219 -30
- package/src/workspace/records.schema.json +88 -1
- package/src/workspace/records.ts +76 -8
- package/src/workspace/reference-kinds/app/package.json +10 -0
- package/src/workspace/reference-kinds/app/workspace-kinds.json +45 -0
- package/src/workspace/run-statement.schema.json +622 -0
- package/src/workspace/runs-cli.ts +710 -0
- package/src/workspace/runs-statement.test.ts +239 -0
- package/src/workspace/runs-write.schema.json +994 -0
- package/src/workspace/runs.schema.json +1257 -0
- package/src/workspace/runs.test.ts +281 -0
- package/src/workspace/runs.ts +970 -0
- package/src/workspace/session-kinds.ts +3 -3
- package/src/workspace/squash.ts +198 -0
- package/src/workspace/status-contract.test.ts +10 -2
- package/src/workspace/status-gates.ts +25 -9
- package/src/workspace/status.schema.json +252 -4
- package/src/workspace/status.ts +110 -1
- package/src/workspace/symbols.ts +191 -0
- package/src/workspace/trailer-joins.test.ts +171 -0
- package/src/workspace/trailer-joins.ts +82 -0
- package/src/workspace/trailers.ts +148 -0
- package/src/workspace/trust/run-commits.ts +115 -0
- package/src/workspace/trust/run-statement.ts +226 -0
- package/src/workspace/trust/seal.ts +58 -1
- package/src/workspace/trust/verify-cli.ts +6 -5
- package/src/workspace/trust/verify.ts +39 -6
- package/src/workspace/wip-cli.ts +97 -0
- package/src/workspace/wip-write.schema.json +504 -0
- package/src/workspace/wip.schema.json +334 -0
- package/src/workspace/wip.test.ts +294 -0
- package/src/workspace/wip.ts +753 -0
- package/src/workspace/work-cli.e2e.test.ts +28 -1
- package/src/workspace/work-cli.ts +136 -8
- package/src/workspace/work-evidence.schema.json +5 -0
- package/src/workspace/work-history.schema.json +73 -1
- package/src/workspace/work-history.test.ts +48 -5
- package/src/workspace/work-kind-fields.test.ts +154 -0
- package/src/workspace/work-lease.schema.json +14 -1
- package/src/workspace/work-size.test.ts +77 -0
- package/src/workspace/work-size.ts +93 -0
- package/src/workspace/work.ts +82 -0
- package/src/workspace/workspace-kinds.schema.json +122 -0
- package/src/workspace/workspace-principals.schema.json +60 -0
- package/src/workspace/write-lock-cli.ts +131 -0
- package/src/workspace/write-lock.schema.json +172 -0
- package/src/workspace/write-lock.test.ts +189 -0
- package/src/workspace/write-lock.ts +474 -0
- package/src/workspace/write-scope.test.ts +144 -3
- package/src/workspace/write-scope.ts +192 -45
- package/src/yaml.test.ts +111 -1
- package/src/yaml.ts +141 -549
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbol regions for the intent walk (#3034): `graph --intent <path>#<symbol>`
|
|
3
|
+
* names a function, class, method, type or constant instead of a line range,
|
|
4
|
+
* because a line range means something else once the file is edited.
|
|
5
|
+
*
|
|
6
|
+
* A resolver turns a symbol into its current lines in the tree read, and the
|
|
7
|
+
* walk follows those lines through history as it follows any line range
|
|
8
|
+
* (`git log -L`). Resolvers are chosen by file extension. Core ships one for
|
|
9
|
+
* TypeScript and JavaScript, parsed with the TypeScript compiler chant already
|
|
10
|
+
* depends on. A lexicon can contribute more through its plugin's
|
|
11
|
+
* `symbolResolvers()` (#3313), which the intent walk loads for a file in a
|
|
12
|
+
* member that configures the lexicon (`lexicon-symbols.ts`); core's resolver
|
|
13
|
+
* stays the one for `.ts` and `.js`. A file with no resolver is refused with
|
|
14
|
+
* `intent-symbol-unsupported`, and a line range still works for it.
|
|
15
|
+
*
|
|
16
|
+
* A symbol is a name, or a dotted path through classes, namespaces,
|
|
17
|
+
* interfaces, enums and object literals bound to a constant, such as
|
|
18
|
+
* `createApp` or `Server.listen`. A bare name is looked up among the
|
|
19
|
+
* file's top-level declarations first, then among every nested one; when it
|
|
20
|
+
* matches more than one declaration it is refused as ambiguous, with the
|
|
21
|
+
* qualified names that would pick one. The lines run from the declaration's
|
|
22
|
+
* doc comment, when it has one, to its last line.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import * as ts from "typescript";
|
|
26
|
+
import type { LineRange } from "./intent";
|
|
27
|
+
|
|
28
|
+
/** One declaration a resolver found. */
|
|
29
|
+
export interface SymbolDeclaration {
|
|
30
|
+
/** The dotted path from the file's top level, such as `Server.listen`. */
|
|
31
|
+
qualified: string;
|
|
32
|
+
/** What declares it: function, class, method, property, interface, type, enum, namespace, variable, member. */
|
|
33
|
+
kind: string;
|
|
34
|
+
lines: LineRange;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type SymbolResolution =
|
|
38
|
+
| { ok: true; declaration: SymbolDeclaration }
|
|
39
|
+
| { ok: false; reason: "unsupported" | "unknown" | "ambiguous"; message: string; candidates: string[] };
|
|
40
|
+
|
|
41
|
+
/** A language-aware resolver: every declaration in a file, by qualified name. */
|
|
42
|
+
export interface SymbolResolver {
|
|
43
|
+
/** The language it reads, for messages. */
|
|
44
|
+
language: string;
|
|
45
|
+
extensions: readonly string[];
|
|
46
|
+
declarations(path: string, text: string): SymbolDeclaration[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ── TypeScript and JavaScript ────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
function scriptKind(path: string): ts.ScriptKind {
|
|
52
|
+
if (/\.tsx$/.test(path)) return ts.ScriptKind.TSX;
|
|
53
|
+
if (/\.jsx$/.test(path)) return ts.ScriptKind.JSX;
|
|
54
|
+
if (/\.[cm]?js$/.test(path)) return ts.ScriptKind.JS;
|
|
55
|
+
return ts.ScriptKind.TS;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function nameText(name: ts.PropertyName | ts.BindingName | ts.ModuleName | undefined): string | undefined {
|
|
59
|
+
if (!name) return undefined;
|
|
60
|
+
if (ts.isIdentifier(name) || ts.isPrivateIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) return name.text;
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const typescriptResolver: SymbolResolver = {
|
|
65
|
+
language: "TypeScript and JavaScript",
|
|
66
|
+
extensions: [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"],
|
|
67
|
+
declarations(path, text) {
|
|
68
|
+
const sf = ts.createSourceFile(path, text, ts.ScriptTarget.Latest, true, scriptKind(path));
|
|
69
|
+
const out: SymbolDeclaration[] = [];
|
|
70
|
+
const lineOf = (pos: number) => sf.getLineAndCharacterOfPosition(pos).line + 1;
|
|
71
|
+
// The span: from the doc comment (or the statement holding a lone variable) to the node's end.
|
|
72
|
+
const push = (qualified: string, kind: string, node: ts.Node) => {
|
|
73
|
+
out.push({ qualified, kind, lines: { start: lineOf(node.getStart(sf, true)), end: lineOf(node.getEnd()) } });
|
|
74
|
+
};
|
|
75
|
+
const visitMembers = (prefix: string, members: ts.NodeArray<ts.Node>) => {
|
|
76
|
+
for (const m of members) {
|
|
77
|
+
const name = nameText((m as ts.NamedDeclaration).name as ts.PropertyName | undefined);
|
|
78
|
+
if (name === undefined) {
|
|
79
|
+
if (ts.isConstructorDeclaration(m)) push(`${prefix}.constructor`, "method", m);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const q = `${prefix}.${name}`;
|
|
83
|
+
if (ts.isMethodDeclaration(m) || ts.isMethodSignature(m) || ts.isGetAccessorDeclaration(m) || ts.isSetAccessorDeclaration(m)) push(q, "method", m);
|
|
84
|
+
else if (ts.isPropertyDeclaration(m) || ts.isPropertySignature(m)) {
|
|
85
|
+
push(q, "property", m);
|
|
86
|
+
if (ts.isPropertyDeclaration(m) && m.initializer) visitValue(q, m.initializer);
|
|
87
|
+
} else if (ts.isEnumMember(m)) push(q, "member", m);
|
|
88
|
+
else if (ts.isPropertyAssignment(m)) {
|
|
89
|
+
push(q, "property", m);
|
|
90
|
+
visitValue(q, m.initializer);
|
|
91
|
+
} else if (ts.isShorthandPropertyAssignment(m)) push(q, "property", m);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
// A class expression or object literal bound to a name has members of its own.
|
|
95
|
+
const visitValue = (prefix: string, value: ts.Expression) => {
|
|
96
|
+
let v = value;
|
|
97
|
+
while (ts.isParenthesizedExpression(v) || ts.isAsExpression(v) || ts.isSatisfiesExpression(v)) v = v.expression;
|
|
98
|
+
if (ts.isClassExpression(v)) visitMembers(prefix, v.members);
|
|
99
|
+
else if (ts.isObjectLiteralExpression(v)) visitMembers(prefix, v.properties);
|
|
100
|
+
};
|
|
101
|
+
const visitStatements = (prefix: string, statements: ts.NodeArray<ts.Statement>) => {
|
|
102
|
+
const q = (name: string) => (prefix ? `${prefix}.${name}` : name);
|
|
103
|
+
for (const s of statements) {
|
|
104
|
+
if (ts.isFunctionDeclaration(s) && s.name) push(q(s.name.text), "function", s);
|
|
105
|
+
else if (ts.isClassDeclaration(s) && s.name) {
|
|
106
|
+
push(q(s.name.text), "class", s);
|
|
107
|
+
visitMembers(q(s.name.text), s.members);
|
|
108
|
+
} else if (ts.isInterfaceDeclaration(s)) {
|
|
109
|
+
push(q(s.name.text), "interface", s);
|
|
110
|
+
visitMembers(q(s.name.text), s.members);
|
|
111
|
+
} else if (ts.isTypeAliasDeclaration(s)) push(q(s.name.text), "type", s);
|
|
112
|
+
else if (ts.isEnumDeclaration(s)) {
|
|
113
|
+
push(q(s.name.text), "enum", s);
|
|
114
|
+
visitMembers(q(s.name.text), s.members);
|
|
115
|
+
} else if (ts.isModuleDeclaration(s)) {
|
|
116
|
+
const name = nameText(s.name);
|
|
117
|
+
if (name === undefined) continue;
|
|
118
|
+
push(q(name), "namespace", s);
|
|
119
|
+
let body = s.body;
|
|
120
|
+
let inner = q(name);
|
|
121
|
+
while (body && ts.isModuleDeclaration(body)) {
|
|
122
|
+
inner = `${inner}.${nameText(body.name)}`;
|
|
123
|
+
body = body.body;
|
|
124
|
+
}
|
|
125
|
+
if (body && ts.isModuleBlock(body)) visitStatements(inner, body.statements);
|
|
126
|
+
} else if (ts.isVariableStatement(s)) {
|
|
127
|
+
const lone = s.declarationList.declarations.length === 1;
|
|
128
|
+
for (const d of s.declarationList.declarations) {
|
|
129
|
+
const name = nameText(d.name);
|
|
130
|
+
if (name === undefined) continue;
|
|
131
|
+
// A lone declaration takes its statement's lines, so `export const x = ...` and its doc comment are in the region.
|
|
132
|
+
push(q(name), "variable", lone ? s : d);
|
|
133
|
+
if (d.initializer) visitValue(q(name), d.initializer);
|
|
134
|
+
}
|
|
135
|
+
} else if (ts.isExportAssignment(s) && !s.isExportEquals) {
|
|
136
|
+
push(q("default"), "variable", s);
|
|
137
|
+
visitValue(q("default"), s.expression);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
visitStatements("", sf.statements);
|
|
142
|
+
return out;
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/** The resolvers core ships, chosen by the file's extension. */
|
|
147
|
+
export const SYMBOL_RESOLVERS: readonly SymbolResolver[] = [typescriptResolver];
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The resolver for a path, or undefined when none reads its language. Core's
|
|
151
|
+
* resolvers come first, so a lexicon's never takes `.ts` or `.js` from them;
|
|
152
|
+
* among `extra`, the first that names the extension wins.
|
|
153
|
+
*/
|
|
154
|
+
export function symbolResolverFor(path: string, extra: readonly SymbolResolver[] = []): SymbolResolver | undefined {
|
|
155
|
+
const lower = path.toLowerCase();
|
|
156
|
+
return [...SYMBOL_RESOLVERS, ...extra].find((r) => r.extensions.some((e) => lower.endsWith(e.toLowerCase())));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Resolve `symbol` in the file `path` holding `text`: its current lines, or
|
|
161
|
+
* why it can't be. `extra` are the resolvers a lexicon contributed for the
|
|
162
|
+
* file's member (#3313).
|
|
163
|
+
*/
|
|
164
|
+
export function resolveSymbol(path: string, text: string, symbol: string, extra: readonly SymbolResolver[] = []): SymbolResolution {
|
|
165
|
+
const resolver = symbolResolverFor(path, extra);
|
|
166
|
+
if (!resolver) {
|
|
167
|
+
const known = [...new Set([...SYMBOL_RESOLVERS, ...extra].flatMap((r) => r.extensions))].join(", ");
|
|
168
|
+
return { ok: false, reason: "unsupported", message: `${path} has no symbol resolver: symbols resolve in ${known} files. Give a line range, ${path}:<start>-<end>, instead`, candidates: [] };
|
|
169
|
+
}
|
|
170
|
+
const all = resolver.declarations(path, text);
|
|
171
|
+
const exact = all.filter((d) => d.qualified === symbol);
|
|
172
|
+
// A name declared twice at one path, such as an overload or a merged declaration, is one region from the first to the last.
|
|
173
|
+
if (exact.length > 0) {
|
|
174
|
+
const start = Math.min(...exact.map((d) => d.lines.start));
|
|
175
|
+
const end = Math.max(...exact.map((d) => d.lines.end));
|
|
176
|
+
return { ok: true, declaration: { qualified: symbol, kind: exact[0].kind, lines: { start, end } } };
|
|
177
|
+
}
|
|
178
|
+
const nested = [...new Set(all.filter((d) => d.qualified.endsWith(`.${symbol}`)).map((d) => d.qualified))];
|
|
179
|
+
if (nested.length === 1) return resolveSymbol(path, text, nested[0], extra);
|
|
180
|
+
if (nested.length > 1) {
|
|
181
|
+
return { ok: false, reason: "ambiguous", message: `${symbol} names ${nested.length} declarations in ${path}: ${nested.join(", ")}. Give the qualified name`, candidates: nested };
|
|
182
|
+
}
|
|
183
|
+
const top = [...new Set(all.filter((d) => !d.qualified.includes(".")).map((d) => d.qualified))];
|
|
184
|
+
const shown = top.slice(0, 20);
|
|
185
|
+
return {
|
|
186
|
+
ok: false,
|
|
187
|
+
reason: "unknown",
|
|
188
|
+
message: `${path} declares no ${symbol}${top.length > 0 ? `; its top-level declarations are ${shown.join(", ")}${top.length > shown.length ? `, and ${top.length - shown.length} more` : ""}` : ", and no top-level declaration a resolver reads"}`,
|
|
189
|
+
candidates: shown,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* chant's commit trailers (#3149): the vocabulary, and the joins `graph
|
|
3
|
+
* --intent` and `graph --intent --record` make through it.
|
|
4
|
+
*
|
|
5
|
+
* - c0 adds the workspace and s-001, decided, which constrains path:app.
|
|
6
|
+
* - c1 adds W-001, open, implementing s-001.
|
|
7
|
+
* - c2 edits app/main.js with Chant-Record: work:W-001, Chant-Run and Chant-Agent.
|
|
8
|
+
* - c3 edits app/main.js with only a Chant-Lease, whose token the lease
|
|
9
|
+
* history of W-001 on chant/lifecycle names.
|
|
10
|
+
* - c4 edits app/main.js with Chant-Record: decision:s-001.
|
|
11
|
+
* - c5 edits app/main.js with nothing to account for it.
|
|
12
|
+
* - c6 edits app/main.js with a Chant-Record no kind has, and the apply trailers.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { readFileSync } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { afterAll, beforeAll, describe, expect, test } from "vitest";
|
|
18
|
+
import { writeBlobToPath } from "../lifecycle/git";
|
|
19
|
+
import { cleanScratch, contract, git, REPO, repo, writeFiles } from "./__fixtures__/contract-repo";
|
|
20
|
+
import { intentGraph, type CommitNode, type IntentDocument } from "./intent";
|
|
21
|
+
import { intentRecord, type IntentRecordDocument } from "./intent-record";
|
|
22
|
+
import intentRecordSchema from "./intent-record.schema.json";
|
|
23
|
+
import intentSchema from "./intent.schema.json";
|
|
24
|
+
import { parseFrontMatter } from "./records";
|
|
25
|
+
import { formatChantTrailers, parseRecordRef, readChantTrailers } from "./trailers";
|
|
26
|
+
|
|
27
|
+
const REF = join(REPO, "reference-workspace");
|
|
28
|
+
const BASE = (() => {
|
|
29
|
+
const fm = parseFrontMatter(readFileSync(join(REF, "decisions", "ref-001-how-the-app-is-deployed.md"), "utf-8"));
|
|
30
|
+
if (!fm.ok) throw new Error(fm.message);
|
|
31
|
+
return fm.value;
|
|
32
|
+
})();
|
|
33
|
+
|
|
34
|
+
function decision(id: string, fields: Record<string, unknown>): string {
|
|
35
|
+
const data = { ...BASE, id, title: `Decision ${id}`, state: "decided", supersedes: [], evidence: [], reviews: [], ...fields };
|
|
36
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function work(id: string, fields: Record<string, unknown>): string {
|
|
40
|
+
const data = { schema: 1, id, title: `Work ${id}`, state: "open", implements: [], needs: [], constrains: [], evidence: [], opened_on: "2026-10-01", supersedes: [], ...fields };
|
|
41
|
+
return `---\n${JSON.stringify(data, null, 2)}\n---\n\n# ${id}\n\nWhat the work is.\n`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const TOKEN = "3f0c7d2e-lease-token";
|
|
45
|
+
const TIP = "a".repeat(40);
|
|
46
|
+
let root: string;
|
|
47
|
+
const sha: Record<string, string> = {};
|
|
48
|
+
let tick = 0;
|
|
49
|
+
|
|
50
|
+
function commit(message: string[]): string {
|
|
51
|
+
const date = `2026-10-01T12:00:${String(tick++).padStart(2, "0")}Z`;
|
|
52
|
+
process.env.GIT_AUTHOR_DATE = date;
|
|
53
|
+
process.env.GIT_COMMITTER_DATE = date;
|
|
54
|
+
try {
|
|
55
|
+
git(root, "add", "-A");
|
|
56
|
+
git(root, "commit", "-q", ...message.flatMap((m) => ["-m", m]));
|
|
57
|
+
} finally {
|
|
58
|
+
delete process.env.GIT_AUTHOR_DATE;
|
|
59
|
+
delete process.env.GIT_COMMITTER_DATE;
|
|
60
|
+
}
|
|
61
|
+
return git(root, "rev-parse", "HEAD");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const KINDS = ["decisions/decision.kind.mjs", "work/work.kind.mjs"];
|
|
65
|
+
|
|
66
|
+
beforeAll(async () => {
|
|
67
|
+
root = repo({
|
|
68
|
+
"chant.workspace.json": JSON.stringify({ name: "trailers", schema: 1, members: [{ name: "app", dir: "app", kind: "other", because: "the app" }] }),
|
|
69
|
+
"decisions/decision.kind.mjs": readFileSync(join(REF, "decisions", "decision.kind.mjs"), "utf-8"),
|
|
70
|
+
"decisions/decision.schema.json": readFileSync(join(REF, "decisions", "decision.schema.json"), "utf-8"),
|
|
71
|
+
"work/work.kind.mjs": readFileSync(join(REF, "work", "work.kind.mjs"), "utf-8"),
|
|
72
|
+
"work/work.schema.json": readFileSync(join(REF, "work", "work.schema.json"), "utf-8"),
|
|
73
|
+
"app/main.js": "export const n = 0;\n",
|
|
74
|
+
"decisions/s-001-app.md": decision("s-001", { constrains: ["path:app"] }),
|
|
75
|
+
});
|
|
76
|
+
sha.c0 = commit(["the workspace, and s-001"]);
|
|
77
|
+
writeFiles(root, { "work/W-001-app.md": work("W-001", { implements: ["s-001"] }) });
|
|
78
|
+
sha.c1 = commit(["W-001"]);
|
|
79
|
+
writeFiles(root, { "app/main.js": "export const n = 1;\n" });
|
|
80
|
+
sha.c2 = commit(["one", formatChantTrailers({ agent: "factory", run: "r-0001", records: ["work:W-001"] }).join("\n")]);
|
|
81
|
+
writeFiles(root, { "app/main.js": "export const n = 2;\n" });
|
|
82
|
+
sha.c3 = commit(["two", `Chant-Lease: ${TOKEN}`]);
|
|
83
|
+
writeFiles(root, { "app/main.js": "export const n = 3;\n" });
|
|
84
|
+
sha.c4 = commit(["three", "Chant-Record: decision:s-001"]);
|
|
85
|
+
writeFiles(root, { "app/main.js": "export const n = 4;\n" });
|
|
86
|
+
sha.c5 = commit(["four"]);
|
|
87
|
+
writeFiles(root, { "app/main.js": "export const n = 5;\n" });
|
|
88
|
+
sha.c6 = commit(["five", formatChantTrailers({ records: [{ kind: "contract", id: "C-001" }], applied: { by: "alice", at: "2026-10-01T12:00:06Z", commit: TIP } }).join("\n")]);
|
|
89
|
+
const line = { version: 1, event: "claim", item: "W-001", holder: "factory", by: "factory", token: TOKEN, acquiredAt: "2026-10-01T12:00:00Z", expiresAt: "2026-10-01T12:10:00Z", timestamp: "2026-10-01T12:00:00Z" };
|
|
90
|
+
await writeBlobToPath("_leases", "W-001.jsonl", JSON.stringify(line), "Work lease claim: W-001", { cwd: root });
|
|
91
|
+
});
|
|
92
|
+
afterAll(cleanScratch);
|
|
93
|
+
|
|
94
|
+
describe("the trailer vocabulary", () => {
|
|
95
|
+
test("formats in a fixed order and reads back what it wrote", () => {
|
|
96
|
+
const lines = formatChantTrailers({ applied: { by: "bob", commit: TIP }, records: ["work:W-1", { kind: "decision", id: "ws-075" }], run: "r-1", lease: "tok", agent: "factory" });
|
|
97
|
+
expect(lines).toEqual(["Chant-Agent: factory", "Chant-Lease: tok", "Chant-Run: r-1", "Chant-Record: work:W-1", "Chant-Record: decision:ws-075", "Chant-Applied-By: bob", `Chant-Applied-Commit: ${TIP}`]);
|
|
98
|
+
const trailers: Record<string, string[]> = {};
|
|
99
|
+
for (const l of lines) (trailers[l.slice(0, l.indexOf(":"))] ??= []).push(l.slice(l.indexOf(":") + 1).trim());
|
|
100
|
+
expect(readChantTrailers(trailers)).toEqual({
|
|
101
|
+
agent: "factory",
|
|
102
|
+
lease: "tok",
|
|
103
|
+
run: "r-1",
|
|
104
|
+
records: [
|
|
105
|
+
{ kind: "work", id: "W-1" },
|
|
106
|
+
{ kind: "decision", id: "ws-075" },
|
|
107
|
+
],
|
|
108
|
+
applied: { by: "bob", at: null, commit: TIP },
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("refuses a value git would read differently", () => {
|
|
113
|
+
expect(() => formatChantTrailers({ run: "a\nb" })).toThrow(/one line/);
|
|
114
|
+
expect(() => formatChantTrailers({ records: ["W-1"] })).toThrow(/<kind>:<id>/);
|
|
115
|
+
expect(() => formatChantTrailers({ applied: { by: "x", commit: "abc" } })).toThrow(/full commit id/);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test("reads keys without case and skips malformed record refs", () => {
|
|
119
|
+
expect(parseRecordRef("Work:W-1")).toBeUndefined();
|
|
120
|
+
const t = readChantTrailers({ "chant-record": ["work:W-1", "nonsense", "work:W-1"], "CHANT-RUN": ["r-9"] });
|
|
121
|
+
expect(t.records).toEqual([{ kind: "work", id: "W-1" }]);
|
|
122
|
+
expect(t.run).toBe("r-9");
|
|
123
|
+
expect(t.applied).toBeNull();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const intentContract = contract(intentSchema);
|
|
128
|
+
const recordContract = contract(intentRecordSchema);
|
|
129
|
+
|
|
130
|
+
async function region(): Promise<Exclude<IntentDocument, { error: unknown }>> {
|
|
131
|
+
const { doc } = await intentGraph({ cwd: root, region: "app/main.js", kinds: KINDS.map((k) => join(root, k)) });
|
|
132
|
+
intentContract.expectValid(doc);
|
|
133
|
+
if ("error" in doc) throw new Error(`${doc.error.code}: ${doc.error.message}`);
|
|
134
|
+
return doc;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
describe("graph --intent joins a commit through chant's trailers", () => {
|
|
138
|
+
test("each commit node reports what its trailers name", async () => {
|
|
139
|
+
const doc = await region();
|
|
140
|
+
const commit = (k: string) => doc.nodes.find((n) => n.id === `commit:${sha[k]}`) as CommitNode;
|
|
141
|
+
expect(commit("c2").joins).toEqual({ agent: "factory", lease: null, run: "r-0001", records: [{ kind: "work", id: "W-001", node: "record:work/W-001" }], applied: null });
|
|
142
|
+
expect(commit("c3").joins.lease).toEqual({ token: TOKEN, item: "W-001" });
|
|
143
|
+
expect(commit("c4").joins.records).toEqual([{ kind: "decision", id: "s-001", node: "record:decision/s-001" }]);
|
|
144
|
+
expect(commit("c5").joins).toEqual({ agent: null, lease: null, run: null, records: [], applied: null });
|
|
145
|
+
expect(commit("c6").joins.records).toEqual([{ kind: "contract", id: "C-001", node: null }]);
|
|
146
|
+
expect(commit("c6").joins.applied).toEqual({ by: "alice", at: "2026-10-01T12:00:06Z", commit: TIP });
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("a carried record makes the commit the decision's own work", async () => {
|
|
150
|
+
const doc = await region();
|
|
151
|
+
const state = (k: string) => (doc.nodes.find((n) => n.id === `commit:${sha[k]}`) as CommitNode).state;
|
|
152
|
+
expect(state("c2")).toBe("decided");
|
|
153
|
+
expect(state("c3")).toBe("decided");
|
|
154
|
+
expect(state("c4")).toBe("decided");
|
|
155
|
+
expect(state("c5")).toBe("decided-by-window");
|
|
156
|
+
expect(state("c6")).toBe("decided-by-window");
|
|
157
|
+
const carries = doc.edges.filter((e) => e.kind === "carries").map((e) => `${e.from} ${e.to}`);
|
|
158
|
+
// Newest first, as the history lists the commits.
|
|
159
|
+
expect(carries).toEqual([`commit:${sha.c4} record:decision/s-001`, `commit:${sha.c3} record:work/W-001`, `commit:${sha.c2} record:work/W-001`]);
|
|
160
|
+
expect(doc.nodes.some((n) => n.id === "record:work/W-001" && n.kind === "work")).toBe(true);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test("graph --intent --record buckets the same commits as own", async () => {
|
|
164
|
+
const { doc } = await intentRecord({ cwd: root, record: "s-001", kinds: KINDS.map((k) => join(root, k)) });
|
|
165
|
+
recordContract.expectValid(doc);
|
|
166
|
+
if ("error" in doc) throw new Error(doc.error.message);
|
|
167
|
+
const bucket = (k: string) => (doc as Exclude<IntentRecordDocument, { error: unknown }>).commits.find((c) => c.sha === sha[k])?.bucket;
|
|
168
|
+
expect([bucket("c2"), bucket("c3"), bucket("c4"), bucket("c5")]).toEqual(["own", "own", "own", "worked"]);
|
|
169
|
+
expect(doc.commits.find((c) => c.sha === sha.c3)?.joins.lease).toEqual({ token: TOKEN, item: "W-001" });
|
|
170
|
+
});
|
|
171
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Joining a commit through chant's own trailers (#3149, ws-075), for `graph
|
|
3
|
+
* --intent` and `graph --intent --record`.
|
|
4
|
+
*
|
|
5
|
+
* A plugin's `commitJoins` reads a kind's own trailers (`intent-joins.ts`).
|
|
6
|
+
* These are core's: a `Chant-Record` names a record by kind and id, and a
|
|
7
|
+
* `Chant-Lease` names a work lease by its fencing token, which the lease
|
|
8
|
+
* histories on `chant/lifecycle` turn into the work item it was taken on.
|
|
9
|
+
* Both read the local branch and never fetch.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { execFileSync } from "node:child_process";
|
|
13
|
+
import { parseLeaseHistory } from "../lifecycle/work-lease";
|
|
14
|
+
import { readChantTrailers, type AppliedTrailers, type ChantTrailers } from "./trailers";
|
|
15
|
+
|
|
16
|
+
/** The branch the lease histories are on. */
|
|
17
|
+
const LEDGER_BRANCH = "refs/heads/chant/lifecycle";
|
|
18
|
+
|
|
19
|
+
/** What chant's trailers on one commit join it to, as a commit in `graph --intent` reports it. */
|
|
20
|
+
export interface CommitTrailerJoins {
|
|
21
|
+
/** `Chant-Agent`: the agent session that wrote the commit. */
|
|
22
|
+
agent: string | null;
|
|
23
|
+
/** `Chant-Lease`: the work lease's token, and the work item a lease history on `chant/lifecycle` names for it, or null when none does. */
|
|
24
|
+
lease: { token: string; item: string | null } | null;
|
|
25
|
+
/** `Chant-Run`: the agent run that made the commit. */
|
|
26
|
+
run: string | null;
|
|
27
|
+
/** Each `Chant-Record`, with the id of its node in the graph, or null when no kind read has the record. */
|
|
28
|
+
records: { kind: string; id: string; node: string | null }[];
|
|
29
|
+
/** The `Chant-Applied-*` trailers of a commit that applied a leased branch. */
|
|
30
|
+
applied: AppliedTrailers | null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function git(top: string, args: string[]): string | undefined {
|
|
34
|
+
try {
|
|
35
|
+
return execFileSync("git", args, { cwd: top, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], maxBuffer: 256 * 1024 * 1024 });
|
|
36
|
+
} catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The work item each lease token names, from the lease histories
|
|
43
|
+
* (`_leases/<item>.jsonl`, any member's) on the local `chant/lifecycle`
|
|
44
|
+
* branch. A token no history names is left out. Never fetches.
|
|
45
|
+
*/
|
|
46
|
+
export function leaseItemsByToken(top: string, tokens: string[]): Map<string, string> {
|
|
47
|
+
const out = new Map<string, string>();
|
|
48
|
+
const wanted = [...new Set(tokens.filter((t) => t !== ""))];
|
|
49
|
+
if (wanted.length === 0 || git(top, ["rev-parse", "--verify", "--quiet", LEDGER_BRANCH]) === undefined) return out;
|
|
50
|
+
const listed = git(top, ["grep", "-l", "-F", ...wanted.flatMap((t) => ["-e", t]), LEDGER_BRANCH, "--", ":(glob)**/_leases/*.jsonl"]);
|
|
51
|
+
for (const line of (listed ?? "").split("\n")) {
|
|
52
|
+
const path = line.startsWith(`${LEDGER_BRANCH}:`) ? line.slice(LEDGER_BRANCH.length + 1) : "";
|
|
53
|
+
const m = path.match(/(?:^|\/)_leases\/([^/]+)\.jsonl$/);
|
|
54
|
+
if (!m) continue;
|
|
55
|
+
const text = git(top, ["show", `${LEDGER_BRANCH}:${path}`]);
|
|
56
|
+
for (const r of parseLeaseHistory(text ?? "").records) if (wanted.includes(r.token) && r.item === m[1] && !out.has(r.token)) out.set(r.token, r.item);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Read chant's trailers from each commit, and the work items their lease tokens name. */
|
|
62
|
+
export function readTrailerJoins(top: string, commits: { sha: string; trailers: Record<string, string[]> }[]): Map<string, { trailers: ChantTrailers; joins: CommitTrailerJoins }> {
|
|
63
|
+
const read = commits.map((c) => ({ sha: c.sha, trailers: readChantTrailers(c.trailers) }));
|
|
64
|
+
const items = leaseItemsByToken(
|
|
65
|
+
top,
|
|
66
|
+
read.map((r) => r.trailers.lease).filter((t): t is string => t !== null),
|
|
67
|
+
);
|
|
68
|
+
const out = new Map<string, { trailers: ChantTrailers; joins: CommitTrailerJoins }>();
|
|
69
|
+
for (const { sha, trailers } of read) {
|
|
70
|
+
out.set(sha, {
|
|
71
|
+
trailers,
|
|
72
|
+
joins: {
|
|
73
|
+
agent: trailers.agent,
|
|
74
|
+
lease: trailers.lease === null ? null : { token: trailers.lease, item: items.get(trailers.lease) ?? null },
|
|
75
|
+
run: trailers.run,
|
|
76
|
+
records: trailers.records.map((r) => ({ kind: r.kind, id: r.id, node: null })),
|
|
77
|
+
applied: trailers.applied,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* chant's commit trailers (#3149, ws-075): the vocabulary a commit uses to
|
|
3
|
+
* name the lease, the agent run, the records and the apply behind it.
|
|
4
|
+
*
|
|
5
|
+
* A trailer is how a commit points at a fact kept elsewhere: a work lease on
|
|
6
|
+
* `chant/lifecycle`, an agent run in the run ledger (#3033), a record in the
|
|
7
|
+
* working tree. Provenance is keyed to those ids, never to commit SHAs, so a
|
|
8
|
+
* commit that keeps its message through a rebase or a cherry-pick keeps its
|
|
9
|
+
* joins (#3037). chant never writes a commit itself (ws-074): whoever makes
|
|
10
|
+
* the commit adds the trailers, and chant reads them back in `graph
|
|
11
|
+
* --intent`, `graph --intent --record` and `workspace runs`.
|
|
12
|
+
*
|
|
13
|
+
* | Trailer | Value | Names |
|
|
14
|
+
* |---|---|---|
|
|
15
|
+
* | `Chant-Agent` | an agent session | the session that wrote the commit (ws-067) |
|
|
16
|
+
* | `Chant-Lease` | a fencing token | the work lease the commit was made under |
|
|
17
|
+
* | `Chant-Run` | a run id | the agent run that made the commit (#3033) |
|
|
18
|
+
* | `Chant-Record` | `<kind>:<id>` | a record the commit carries out or changes; repeatable |
|
|
19
|
+
* | `Chant-Applied-By` | a principal | who applied a leased branch, on the apply commit |
|
|
20
|
+
* | `Chant-Applied-At` | ISO 8601 | when it was applied |
|
|
21
|
+
* | `Chant-Applied-Commit` | a commit id | the tip of the branch that was applied |
|
|
22
|
+
*
|
|
23
|
+
* Every other trailer is a plugin's, and core gives it no meaning; a kind's
|
|
24
|
+
* `commitJoins` may (`intent-joins.ts`).
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import { trailerValue, trailerValues } from "./intent-joins";
|
|
28
|
+
|
|
29
|
+
/** The agent session that wrote a commit (ws-067). */
|
|
30
|
+
export const AGENT_TRAILER = "Chant-Agent";
|
|
31
|
+
/** The fencing token of the work lease a commit was made under. */
|
|
32
|
+
export const LEASE_TRAILER = "Chant-Lease";
|
|
33
|
+
/** The agent run that made a commit (#3033). */
|
|
34
|
+
export const RUN_TRAILER = "Chant-Run";
|
|
35
|
+
/** A record a commit carries out or changes, as `<kind>:<id>`. Repeatable. */
|
|
36
|
+
export const RECORD_TRAILER = "Chant-Record";
|
|
37
|
+
/** Who applied a leased branch, on the commit that applied it. */
|
|
38
|
+
export const APPLIED_BY_TRAILER = "Chant-Applied-By";
|
|
39
|
+
/** When the branch was applied, ISO 8601. */
|
|
40
|
+
export const APPLIED_AT_TRAILER = "Chant-Applied-At";
|
|
41
|
+
/** The tip of the branch that was applied. */
|
|
42
|
+
export const APPLIED_COMMIT_TRAILER = "Chant-Applied-Commit";
|
|
43
|
+
|
|
44
|
+
/** Every trailer key core reads, in the order a writer should add them. */
|
|
45
|
+
export const CHANT_TRAILERS = [AGENT_TRAILER, LEASE_TRAILER, RUN_TRAILER, RECORD_TRAILER, APPLIED_BY_TRAILER, APPLIED_AT_TRAILER, APPLIED_COMMIT_TRAILER] as const;
|
|
46
|
+
|
|
47
|
+
/** A record kind's name, as a kind file's `recordKind.name` gives it. */
|
|
48
|
+
const KIND_NAME = /^[a-z][a-z0-9-]*$/;
|
|
49
|
+
/** A record id, as the record kinds allocate them and as a work lease keys them. */
|
|
50
|
+
const RECORD_ID = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
51
|
+
const COMMIT_ID = /^[0-9a-f]{40,64}$/;
|
|
52
|
+
|
|
53
|
+
/** One `Chant-Record` value. */
|
|
54
|
+
export interface RecordRef {
|
|
55
|
+
/** The record kind's name, such as `decision` or `work`. */
|
|
56
|
+
kind: string;
|
|
57
|
+
id: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** An apply, from the `Chant-Applied-*` trailers. */
|
|
61
|
+
export interface AppliedTrailers {
|
|
62
|
+
by: string;
|
|
63
|
+
/** ISO 8601, or null when the trailer is missing. */
|
|
64
|
+
at: string | null;
|
|
65
|
+
/** The applied branch's tip, or null when the trailer is missing or is not a commit id. */
|
|
66
|
+
commit: string | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** What chant's own trailers on one commit say. */
|
|
70
|
+
export interface ChantTrailers {
|
|
71
|
+
agent: string | null;
|
|
72
|
+
lease: string | null;
|
|
73
|
+
run: string | null;
|
|
74
|
+
/** Each well-formed `Chant-Record` value, in order, without repeats. */
|
|
75
|
+
records: RecordRef[];
|
|
76
|
+
applied: AppliedTrailers | null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Parse one `Chant-Record` value, `<kind>:<id>`, or undefined when it is not one. */
|
|
80
|
+
export function parseRecordRef(value: string): RecordRef | undefined {
|
|
81
|
+
const colon = value.indexOf(":");
|
|
82
|
+
if (colon <= 0) return undefined;
|
|
83
|
+
const kind = value.slice(0, colon).trim();
|
|
84
|
+
const id = value.slice(colon + 1).trim();
|
|
85
|
+
return KIND_NAME.test(kind) && RECORD_ID.test(id) ? { kind, id } : undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Read chant's own trailers from a commit's parsed trailers. Keys compare without case, as git's do. */
|
|
89
|
+
export function readChantTrailers(trailers: Record<string, string[]>): ChantTrailers {
|
|
90
|
+
const records: RecordRef[] = [];
|
|
91
|
+
for (const v of trailerValues(trailers, RECORD_TRAILER)) {
|
|
92
|
+
const ref = parseRecordRef(v);
|
|
93
|
+
if (ref && !records.some((r) => r.kind === ref.kind && r.id === ref.id)) records.push(ref);
|
|
94
|
+
}
|
|
95
|
+
const by = trailerValue(trailers, APPLIED_BY_TRAILER) ?? null;
|
|
96
|
+
const commit = trailerValue(trailers, APPLIED_COMMIT_TRAILER) ?? null;
|
|
97
|
+
return {
|
|
98
|
+
agent: trailerValue(trailers, AGENT_TRAILER) ?? null,
|
|
99
|
+
lease: trailerValue(trailers, LEASE_TRAILER) ?? null,
|
|
100
|
+
run: trailerValue(trailers, RUN_TRAILER) ?? null,
|
|
101
|
+
records,
|
|
102
|
+
applied: by === null ? null : { by, at: trailerValue(trailers, APPLIED_AT_TRAILER) ?? null, commit: commit !== null && COMMIT_ID.test(commit) ? commit : null },
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Whether a commit carries any of chant's own trailers. */
|
|
107
|
+
export function hasChantTrailers(t: ChantTrailers): boolean {
|
|
108
|
+
return t.agent !== null || t.lease !== null || t.run !== null || t.records.length > 0 || t.applied !== null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** What a writer passes to {@link formatChantTrailers}. */
|
|
112
|
+
export interface ChantTrailerInput {
|
|
113
|
+
agent?: string;
|
|
114
|
+
lease?: string;
|
|
115
|
+
run?: string;
|
|
116
|
+
records?: (RecordRef | string)[];
|
|
117
|
+
applied?: { by: string; at?: string; commit?: string };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The trailer lines for a commit message, in {@link CHANT_TRAILERS} order.
|
|
122
|
+
* Throws when a value holds a line break or a record ref is malformed, since
|
|
123
|
+
* either would write a trailer git parses differently.
|
|
124
|
+
*/
|
|
125
|
+
export function formatChantTrailers(input: ChantTrailerInput): string[] {
|
|
126
|
+
const lines: string[] = [];
|
|
127
|
+
const add = (key: string, value: string | undefined) => {
|
|
128
|
+
if (value === undefined) return;
|
|
129
|
+
const v = value.trim();
|
|
130
|
+
if (v === "" || /[\r\n]/.test(v)) throw new Error(`${key} takes one line of text, not ${JSON.stringify(value)}`);
|
|
131
|
+
lines.push(`${key}: ${v}`);
|
|
132
|
+
};
|
|
133
|
+
add(AGENT_TRAILER, input.agent);
|
|
134
|
+
add(LEASE_TRAILER, input.lease);
|
|
135
|
+
add(RUN_TRAILER, input.run);
|
|
136
|
+
for (const r of input.records ?? []) {
|
|
137
|
+
const ref = typeof r === "string" ? parseRecordRef(r) : r;
|
|
138
|
+
if (!ref || !KIND_NAME.test(ref.kind) || !RECORD_ID.test(ref.id)) throw new Error(`${RECORD_TRAILER} takes <kind>:<id>, not ${JSON.stringify(r)}`);
|
|
139
|
+
add(RECORD_TRAILER, `${ref.kind}:${ref.id}`);
|
|
140
|
+
}
|
|
141
|
+
if (input.applied) {
|
|
142
|
+
add(APPLIED_BY_TRAILER, input.applied.by);
|
|
143
|
+
add(APPLIED_AT_TRAILER, input.applied.at);
|
|
144
|
+
if (input.applied.commit !== undefined && !COMMIT_ID.test(input.applied.commit)) throw new Error(`${APPLIED_COMMIT_TRAILER} takes a full commit id, not ${JSON.stringify(input.applied.commit)}`);
|
|
145
|
+
add(APPLIED_COMMIT_TRAILER, input.applied.commit);
|
|
146
|
+
}
|
|
147
|
+
return lines;
|
|
148
|
+
}
|