@intentius/chant 0.91.0 → 0.94.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/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/operator.d.ts +6 -0
- package/dist/cli/handlers/operator.d.ts.map +1 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/mcp/workspace-plugins.d.ts +6 -6
- package/dist/cli/mcp/workspace-tools.d.ts +2 -1
- package/dist/cli/mcp/workspace-tools.d.ts.map +1 -1
- package/dist/cli/plugins.d.ts.map +1 -1
- package/dist/cli/registry.d.ts +12 -2
- package/dist/cli/registry.d.ts.map +1 -1
- package/dist/codegen/pinned-upgrade.d.ts.map +1 -1
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/lexicon-module.d.ts +22 -0
- package/dist/lexicon-module.d.ts.map +1 -1
- package/dist/lifecycle/converge-ledger.d.ts +19 -0
- package/dist/lifecycle/converge-ledger.d.ts.map +1 -1
- package/dist/lifecycle/run-ledger.d.ts +2 -0
- package/dist/lifecycle/run-ledger.d.ts.map +1 -1
- package/dist/lifecycle/symptoms.d.ts +51 -0
- package/dist/lifecycle/symptoms.d.ts.map +1 -1
- package/dist/lint/rules/index.d.ts +4 -2
- package/dist/lint/rules/index.d.ts.map +1 -1
- package/dist/lint/rules/op/index.d.ts +14 -3
- package/dist/lint/rules/op/index.d.ts.map +1 -1
- package/dist/lint/rules/op/ops014-converge-rule-refusals.d.ts.map +1 -1
- package/dist/lint/rules/op/sys010-key-over-plain-http.d.ts +29 -0
- package/dist/lint/rules/op/sys010-key-over-plain-http.d.ts.map +1 -0
- package/dist/lint/rules/sys001-no-literal-key.d.ts +3 -0
- package/dist/lint/rules/sys001-no-literal-key.d.ts.map +1 -0
- package/dist/op/__fixtures__/decide-stub-backend.d.ts +53 -0
- package/dist/op/__fixtures__/decide-stub-backend.d.ts.map +1 -0
- package/dist/op/activities/activity-contracts.d.ts +201 -0
- package/dist/op/activities/activity-contracts.d.ts.map +1 -1
- package/dist/op/activities/apply.d.ts.map +1 -1
- package/dist/op/activities/change-coverage.d.ts +44 -0
- package/dist/op/activities/change-coverage.d.ts.map +1 -0
- package/dist/op/activities/converge.d.ts +24 -1
- package/dist/op/activities/converge.d.ts.map +1 -1
- package/dist/op/activities/decide.d.ts +107 -0
- package/dist/op/activities/decide.d.ts.map +1 -0
- package/dist/op/activities/index.d.ts +10 -0
- package/dist/op/activities/index.d.ts.map +1 -1
- package/dist/op/activities/shell.d.ts +32 -0
- package/dist/op/activities/shell.d.ts.map +1 -1
- package/dist/op/activities/source-release.d.ts +86 -0
- package/dist/op/activities/source-release.d.ts.map +1 -0
- package/dist/op/activities/source-rollback.d.ts +100 -0
- package/dist/op/activities/source-rollback.d.ts.map +1 -0
- package/dist/op/activities/work-evidence.d.ts +42 -0
- package/dist/op/activities/work-evidence.d.ts.map +1 -0
- package/dist/op/activity-contract.d.ts +1 -0
- package/dist/op/activity-contract.d.ts.map +1 -1
- package/dist/op/activity-profiles.d.ts +16 -0
- package/dist/op/activity-profiles.d.ts.map +1 -1
- package/dist/op/builders.d.ts +84 -2
- package/dist/op/builders.d.ts.map +1 -1
- package/dist/op/composites/converge-op.d.ts +31 -4
- package/dist/op/composites/converge-op.d.ts.map +1 -1
- package/dist/op/decide-backend.d.ts +116 -0
- package/dist/op/decide-backend.d.ts.map +1 -0
- package/dist/op/decide-config.d.ts +120 -0
- package/dist/op/decide-config.d.ts.map +1 -0
- package/dist/op/decide-read-inputs.d.ts +40 -0
- package/dist/op/decide-read-inputs.d.ts.map +1 -0
- package/dist/op/gate-wait.d.ts +43 -0
- package/dist/op/gate-wait.d.ts.map +1 -0
- package/dist/op/gate.d.ts +5 -2
- package/dist/op/gate.d.ts.map +1 -1
- package/dist/op/index.d.ts +11 -4
- package/dist/op/index.d.ts.map +1 -1
- package/dist/op/local-executor.d.ts +29 -4
- package/dist/op/local-executor.d.ts.map +1 -1
- package/dist/op/local-output.d.ts +2 -0
- package/dist/op/local-output.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 +97 -1
- package/dist/op/operator.d.ts.map +1 -1
- package/dist/op/runtime.d.ts +37 -5
- package/dist/op/runtime.d.ts.map +1 -1
- package/dist/op/runtimes/local.d.ts.map +1 -1
- package/dist/op/source-archive.d.ts +63 -0
- package/dist/op/source-archive.d.ts.map +1 -0
- package/dist/op/steward-points.d.ts +136 -0
- package/dist/op/steward-points.d.ts.map +1 -0
- package/dist/op/steward-turn.d.ts +53 -0
- package/dist/op/steward-turn.d.ts.map +1 -0
- package/dist/op/steward.d.ts +22 -1
- package/dist/op/steward.d.ts.map +1 -1
- package/dist/op/types.d.ts +7 -0
- package/dist/op/types.d.ts.map +1 -1
- package/dist/op/work-lease-run.d.ts +1 -1
- package/dist/op/work-lease-run.d.ts.map +1 -1
- package/dist/workspace/__fixtures__/decide-workspace.d.ts +100 -0
- package/dist/workspace/__fixtures__/decide-workspace.d.ts.map +1 -0
- package/dist/workspace/answers-ledger.d.ts +76 -0
- package/dist/workspace/answers-ledger.d.ts.map +1 -0
- package/dist/workspace/box-intent.d.ts +85 -0
- package/dist/workspace/box-intent.d.ts.map +1 -0
- package/dist/workspace/changes-cli.d.ts +16 -0
- package/dist/workspace/changes-cli.d.ts.map +1 -0
- package/dist/workspace/changes.d.ts +200 -0
- package/dist/workspace/changes.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.d.ts +59 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-fly-site.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.d.ts +51 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-live-names.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.d.ts +26 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-rollback.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.d.ts +59 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.d.ts +22 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit-ship-policy.d.ts.map +1 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts +71 -0
- package/dist/workspace/chant-migrations/chud-lexicon-exit.d.ts.map +1 -0
- package/dist/workspace/chant-migrations.d.ts +104 -0
- package/dist/workspace/chant-migrations.d.ts.map +1 -0
- package/dist/workspace/checks/boxes.d.ts +47 -1
- package/dist/workspace/checks/boxes.d.ts.map +1 -1
- package/dist/workspace/checks/diagrams.d.ts +31 -0
- package/dist/workspace/checks/diagrams.d.ts.map +1 -0
- package/dist/workspace/checks/records.d.ts +7 -0
- package/dist/workspace/checks/records.d.ts.map +1 -1
- package/dist/workspace/checks.d.ts +7 -0
- package/dist/workspace/checks.d.ts.map +1 -1
- package/dist/workspace/compose-graph.d.ts +2 -0
- package/dist/workspace/compose-graph.d.ts.map +1 -1
- package/dist/workspace/conformance/index.d.ts.map +1 -1
- package/dist/workspace/decide.d.ts +49 -4
- package/dist/workspace/decide.d.ts.map +1 -1
- package/dist/workspace/decision-points.schema.json +3 -3
- package/dist/workspace/declaration.d.ts +58 -0
- package/dist/workspace/declaration.d.ts.map +1 -1
- package/dist/workspace/declaration.schema.json +119 -1
- package/dist/workspace/declared-kinds.d.ts +20 -0
- package/dist/workspace/declared-kinds.d.ts.map +1 -1
- package/dist/workspace/generated-files.d.ts +7 -0
- package/dist/workspace/generated-files.d.ts.map +1 -1
- package/dist/workspace/intent-joins.d.ts +5 -5
- package/dist/workspace/intent.d.ts.map +1 -1
- package/dist/workspace/lineage-check.d.ts +3 -0
- package/dist/workspace/lineage-check.d.ts.map +1 -1
- package/dist/workspace/lineage-upgrade.d.ts +6 -1
- package/dist/workspace/lineage-upgrade.d.ts.map +1 -1
- package/dist/workspace/ls.d.ts +39 -1
- package/dist/workspace/ls.d.ts.map +1 -1
- package/dist/workspace/point-answer.schema.json +95 -0
- package/dist/workspace/points-cli.d.ts +2 -0
- package/dist/workspace/points-cli.d.ts.map +1 -1
- package/dist/workspace/points.d.ts +4 -6
- package/dist/workspace/points.d.ts.map +1 -1
- package/dist/workspace/reason-codes.d.ts +16 -2
- package/dist/workspace/reason-codes.d.ts.map +1 -1
- package/dist/workspace/records-cli.d.ts +11 -1
- package/dist/workspace/records-cli.d.ts.map +1 -1
- package/dist/workspace/records-close.d.ts +1 -1
- package/dist/workspace/records-close.d.ts.map +1 -1
- package/dist/workspace/records-write.d.ts +11 -5
- package/dist/workspace/records-write.d.ts.map +1 -1
- package/dist/workspace/records.d.ts +34 -4
- package/dist/workspace/records.d.ts.map +1 -1
- package/dist/workspace/status-gates.d.ts +7 -2
- package/dist/workspace/status-gates.d.ts.map +1 -1
- package/dist/workspace/status-stewards.d.ts +65 -1
- package/dist/workspace/status-stewards.d.ts.map +1 -1
- package/dist/workspace/status.d.ts +24 -0
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/work-cli.d.ts +113 -2
- package/dist/workspace/work-cli.d.ts.map +1 -1
- package/dist/workspace/work-evidence.d.ts +74 -0
- package/dist/workspace/work-evidence.d.ts.map +1 -0
- package/dist/workspace/work.d.ts +43 -1
- package/dist/workspace/work.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/audit.test.ts +9 -1
- package/src/cli/commands/build.ts +3 -2
- package/src/cli/commands/lint.ts +7 -1
- package/src/cli/handlers/graph.test.ts +20 -0
- package/src/cli/handlers/graph.ts +16 -2
- package/src/cli/handlers/operator.ts +34 -2
- package/src/cli/handlers/run.test.ts +154 -2
- package/src/cli/handlers/run.ts +121 -2
- package/src/cli/main.test.ts +10 -0
- package/src/cli/main.ts +23 -3
- package/src/cli/mcp/workspace-plugins.ts +6 -6
- package/src/cli/mcp/workspace-tools.test.ts +35 -19
- package/src/cli/mcp/workspace-tools.ts +62 -4
- package/src/cli/plugins.ts +11 -3
- package/src/cli/registry.ts +12 -2
- package/src/cli/serve-mcp-workspace.test.ts +6 -6
- package/src/codegen/pinned-upgrade.ts +2 -1
- package/src/codegen/release-wiring.test.ts +49 -2
- package/src/components/capability-plugin-loader.ts +3 -3
- package/src/components/cli-support.ts +2 -2
- package/src/config.ts +11 -0
- package/src/lexicon-module.ts +56 -1
- package/src/lexicon-package.test.ts +96 -0
- package/src/lifecycle/converge-ledger.ts +20 -0
- package/src/lifecycle/run-ledger.ts +6 -0
- package/src/lifecycle/symptoms.ts +95 -0
- package/src/lint/rules/index.ts +6 -2
- package/src/lint/rules/op/index.ts +17 -4
- package/src/lint/rules/op/ops014-converge-rule-refusals.test.ts +23 -1
- package/src/lint/rules/op/ops014-converge-rule-refusals.ts +10 -6
- package/src/lint/rules/op/sys010-key-over-plain-http.test.ts +52 -0
- package/src/lint/rules/op/sys010-key-over-plain-http.ts +100 -0
- package/src/lint/rules/sys001-no-literal-key.test.ts +31 -0
- package/src/lint/rules/sys001-no-literal-key.ts +67 -0
- package/src/op/__fixtures__/decide-stub-backend.ts +143 -0
- package/src/op/activities/activity-contracts.ts +190 -1
- package/src/op/activities/apply.ts +7 -6
- package/src/op/activities/change-coverage.ts +60 -0
- package/src/op/activities/converge.test.ts +55 -1
- package/src/op/activities/converge.ts +208 -29
- package/src/op/activities/decide.live.test.ts +78 -0
- package/src/op/activities/decide.test.ts +308 -0
- package/src/op/activities/decide.ts +267 -0
- package/src/op/activities/index.ts +21 -0
- package/src/op/activities/shell.test.ts +91 -1
- package/src/op/activities/shell.ts +91 -2
- package/src/op/activities/source-release.test.ts +118 -0
- package/src/op/activities/source-release.ts +168 -0
- package/src/op/activities/source-rollback.test.ts +131 -0
- package/src/op/activities/source-rollback.ts +239 -0
- package/src/op/activities/work-evidence.ts +62 -0
- package/src/op/activity-contract-registry.test.ts +2 -0
- package/src/op/activity-contract-registry.ts +2 -2
- package/src/op/activity-contract.test.ts +12 -0
- package/src/op/activity-contract.ts +6 -1
- package/src/op/activity-profiles.ts +29 -0
- package/src/op/activity-registry.test.ts +1 -1
- package/src/op/activity-registry.ts +2 -2
- package/src/op/builders.ts +119 -5
- package/src/op/command-gate.test.ts +192 -0
- package/src/op/composites/converge-op.test.ts +27 -1
- package/src/op/composites/converge-op.ts +69 -15
- package/src/op/decide-backend.test.ts +44 -0
- package/src/op/decide-backend.ts +212 -0
- package/src/op/decide-config.test.ts +52 -0
- package/src/op/decide-config.ts +80 -0
- package/src/op/decide-read-inputs.ts +117 -0
- package/src/op/gate-approval.ts +2 -2
- package/src/op/gate-wait.ts +57 -0
- package/src/op/gate.ts +8 -3
- package/src/op/generate-pipeline.ts +2 -2
- package/src/op/index.ts +18 -3
- package/src/op/local-executor.ts +151 -15
- package/src/op/local-output.test.ts +33 -0
- package/src/op/local-output.ts +20 -2
- package/src/op/op-ir.test.ts +10 -0
- package/src/op/op-ir.ts +4 -0
- package/src/op/op-verb-class.ts +1 -0
- package/src/op/operator.ts +290 -11
- package/src/op/runtime.ts +31 -8
- package/src/op/runtimes/local.ts +3 -1
- package/src/op/source-archive.ts +161 -0
- package/src/op/steward-points.test.ts +364 -0
- package/src/op/steward-points.ts +194 -0
- package/src/op/steward-turn.ts +79 -0
- package/src/op/steward.test.ts +87 -3
- package/src/op/steward.ts +25 -1
- package/src/op/types.ts +7 -0
- package/src/op/work-lease-run.test.ts +20 -1
- package/src/op/work-lease-run.ts +2 -2
- package/src/workspace/__fixtures__/decide-workspace.ts +129 -0
- package/src/workspace/__fixtures__/studio-template-84c8b21.json +67 -0
- package/src/workspace/answers-ledger.ts +118 -0
- package/src/workspace/box-intent.test.ts +205 -0
- package/src/workspace/box-intent.ts +159 -0
- package/src/workspace/changes-cli.ts +56 -0
- package/src/workspace/changes.schema.json +472 -0
- package/src/workspace/changes.test.ts +315 -0
- package/src/workspace/changes.ts +512 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-fly-site.ts +234 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-live-names.ts +164 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-rollback.ts +223 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-ship-inputs.ts +195 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit-ship-policy.ts +108 -0
- package/src/workspace/chant-migrations/chud-lexicon-exit.ts +882 -0
- package/src/workspace/chant-migrations.e2e.test.ts +1089 -0
- package/src/workspace/chant-migrations.ts +169 -0
- package/src/workspace/check-contract.test.ts +4 -2
- package/src/workspace/check.schema.json +19 -5
- package/src/workspace/checks/boxes.test.ts +82 -2
- package/src/workspace/checks/boxes.ts +202 -1
- package/src/workspace/checks/diagrams.test.ts +134 -0
- package/src/workspace/checks/diagrams.ts +108 -0
- package/src/workspace/checks/records.ts +47 -0
- package/src/workspace/checks.ts +20 -2
- package/src/workspace/compose-graph.ts +2 -0
- package/src/workspace/conformance/__fixture__/decisions/decision.kind.mjs +10 -0
- package/src/workspace/conformance/__fixture__/decisions/decision.schema.json +26 -0
- package/src/workspace/conformance/index.ts +5 -0
- package/src/workspace/decide.test.ts +1 -1
- package/src/workspace/decide.ts +156 -23
- package/src/workspace/decision-points.schema.json +3 -3
- package/src/workspace/declaration.schema.json +119 -1
- package/src/workspace/declaration.test.ts +58 -0
- package/src/workspace/declaration.ts +112 -0
- package/src/workspace/declared-kinds.test.ts +31 -5
- package/src/workspace/declared-kinds.ts +46 -1
- package/src/workspace/generated-files.ts +14 -0
- package/src/workspace/graph-cli.ts +1 -1
- package/src/workspace/graph.schema.json +9 -1
- package/src/workspace/intent-joins.test.ts +5 -5
- package/src/workspace/intent-joins.ts +5 -5
- package/src/workspace/intent.schema.json +8 -2
- package/src/workspace/intent.ts +3 -10
- package/src/workspace/lineage-check.ts +16 -1
- package/src/workspace/lineage-upgrade-cli.ts +1 -1
- package/src/workspace/lineage-upgrade.test.ts +70 -0
- package/src/workspace/lineage-upgrade.ts +81 -10
- package/src/workspace/ls-contract.test.ts +57 -0
- package/src/workspace/ls.schema.json +46 -1
- package/src/workspace/ls.ts +62 -3
- package/src/workspace/points-cli.ts +17 -3
- package/src/workspace/points-write.schema.json +11 -1
- package/src/workspace/points.schema.json +51 -0
- package/src/workspace/points.test.ts +16 -15
- package/src/workspace/points.ts +5 -17
- package/src/workspace/read-contract.test.ts +9 -1
- package/src/workspace/reason-codes.test.ts +18 -8
- package/src/workspace/reason-codes.ts +21 -2
- package/src/workspace/records-amend.schema.json +2 -0
- package/src/workspace/records-cli.ts +27 -4
- package/src/workspace/records-close.schema.json +2 -0
- package/src/workspace/records-formats.test.ts +15 -15
- package/src/workspace/records-new.schema.json +2 -0
- package/src/workspace/records-review.schema.json +2 -0
- package/src/workspace/records-sessions-write.e2e.test.ts +77 -0
- package/src/workspace/records-sessions-write.test.ts +2 -34
- package/src/workspace/records-since.test.ts +8 -7
- package/src/workspace/records-write.e2e.test.ts +108 -0
- package/src/workspace/records-write.test.ts +32 -41
- package/src/workspace/records-write.ts +33 -15
- package/src/workspace/records.schema.json +36 -2
- package/src/workspace/records.test.ts +49 -4
- package/src/workspace/records.ts +109 -3
- package/src/workspace/status-contract.test.ts +14 -8
- package/src/workspace/status-gates.ts +9 -4
- package/src/workspace/status-stewards.ts +155 -5
- package/src/workspace/status.schema.json +129 -8
- package/src/workspace/status.ts +46 -1
- package/src/workspace/work-acceptance.test.ts +274 -0
- package/src/workspace/{work-cli.test.ts → work-cli.e2e.test.ts} +1 -1
- package/src/workspace/work-cli.ts +193 -10
- package/src/workspace/work-evidence.schema.json +212 -0
- package/src/workspace/work-evidence.ts +169 -0
- package/src/workspace/work-history.schema.json +349 -0
- package/src/workspace/work-history.test.ts +156 -0
- package/src/workspace/{work-readiness-chud.test.ts → work-readiness.test.ts} +30 -32
- package/src/workspace/work.test.ts +20 -2
- package/src/workspace/work.ts +100 -1
- /package/src/cli/{discovery-skip.test.ts → discovery-skip.e2e.test.ts} +0 -0
- /package/src/workspace/conformance/{conformance.test.ts → conformance.e2e.test.ts} +0 -0
- /package/src/workspace/{which-chant.test.ts → which-chant.e2e.test.ts} +0 -0
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
36
|
import { execFileSync, spawn } from "node:child_process";
|
|
37
|
-
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
37
|
+
import { chmodSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
38
38
|
import { tmpdir } from "node:os";
|
|
39
|
-
import { basename, join, relative, resolve, sep } from "node:path";
|
|
39
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
40
40
|
import { computePlanDigest } from "../lifecycle/plan-digest";
|
|
41
41
|
import type { ResolvedGateApproval } from "../op/gate-approval";
|
|
42
42
|
import { checkLineage, findingKey, type CheckFinding } from "./lineage-check";
|
|
@@ -56,10 +56,13 @@ import {
|
|
|
56
56
|
type ManualStep,
|
|
57
57
|
} from "./lineage-lock";
|
|
58
58
|
import { mergeFile } from "./lineage-merge";
|
|
59
|
+
import { reportPlan, runChantMigrations, type ChantMigrationReport } from "./chant-migrations";
|
|
60
|
+
import { readDeclaration, readerVersion, WorkspaceReadError } from "./declaration";
|
|
59
61
|
import { assertCodeAllowed, planMigrations, runMigration, splitMigrations, type LoadedMigration } from "./lineage-migrations";
|
|
60
62
|
import { applyUpstream, type UpdateResult } from "./lineage-update";
|
|
61
63
|
import { carryParameters, readManifest, substituteParameters } from "./template-manifest";
|
|
62
64
|
import { repinSubstituted, type RepinnedRecord } from "./template-pins";
|
|
65
|
+
import { workingTree } from "./tree";
|
|
63
66
|
|
|
64
67
|
/** The kind the patch digest is taken under, so it never collides with another kind of plan. */
|
|
65
68
|
export const UPGRADE_PLAN_KIND = "workspace-upgrade";
|
|
@@ -74,10 +77,12 @@ export class UpgradeError extends LockError {
|
|
|
74
77
|
// ── Checks ───────────────────────────────────────────────────────────────────
|
|
75
78
|
|
|
76
79
|
export interface UpgradeCheck {
|
|
77
|
-
name: "build" | "lint" | "workspace check";
|
|
80
|
+
name: "build" | "lint" | "workspace check" | "migration";
|
|
78
81
|
status: "passed" | "failed" | "skipped";
|
|
79
82
|
/** Why a check was skipped, or the tail of a failed command's output. */
|
|
80
83
|
detail?: string;
|
|
84
|
+
/** The chant member `build` or `lint` ran in ("." for the scope root), when it is not the only one. */
|
|
85
|
+
member?: string;
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
/** Runs `chant build` or `chant lint` in a directory. */
|
|
@@ -141,6 +146,8 @@ export interface StagedUpgrade {
|
|
|
141
146
|
to: string | null;
|
|
142
147
|
commit?: { from?: string; to: string };
|
|
143
148
|
migrations: string[];
|
|
149
|
+
/** The migrations chant ships (./chant-migrations.ts) that found something to move, applied or not. */
|
|
150
|
+
chantMigrations: ChantMigrationReport[];
|
|
144
151
|
written: string[];
|
|
145
152
|
merged: string[];
|
|
146
153
|
removed: string[];
|
|
@@ -460,6 +467,25 @@ function tail(text: string, lines = 30): string {
|
|
|
460
467
|
return text.trimEnd().split("\n").slice(-lines).join("\n");
|
|
461
468
|
}
|
|
462
469
|
|
|
470
|
+
/**
|
|
471
|
+
* The `chant` members `chant.workspace.json` declares in `dir` (#2804): a
|
|
472
|
+
* template built as a workspace, such as the studio kit's, keeps its chant
|
|
473
|
+
* project in a member (`delivery`), not at the scope's root, and the root
|
|
474
|
+
* itself never has a `chant.config`. Empty when `dir` declares no workspace,
|
|
475
|
+
* or the declaration cannot be read: the caller then falls back to `dir`
|
|
476
|
+
* itself.
|
|
477
|
+
*/
|
|
478
|
+
function chantMemberDirs(dir: string): string[] {
|
|
479
|
+
try {
|
|
480
|
+
return readDeclaration(workingTree(dir))
|
|
481
|
+
.members.filter((m) => m.kind === "chant")
|
|
482
|
+
.map((m) => m.dir);
|
|
483
|
+
} catch (err) {
|
|
484
|
+
if (err instanceof WorkspaceReadError) return [];
|
|
485
|
+
throw err;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
463
489
|
/**
|
|
464
490
|
* Stage an upgrade: steps 1 to 5 and the digest of step 6. Nothing in the
|
|
465
491
|
* project's tree changes. The caller decides the gate, then applies the patch
|
|
@@ -568,6 +594,12 @@ export async function stageUpgrade(options: UpgradeOptions): Promise<StagedUpgra
|
|
|
568
594
|
rmSync(scratch, { recursive: true, force: true });
|
|
569
595
|
}
|
|
570
596
|
|
|
597
|
+
// chant's own migrations (#2737): planned from what the scope holds, and
|
|
598
|
+
// applied only when the plan has no conflict. A conflict fails the checks.
|
|
599
|
+
// Each is planned from the tree the ones before it left.
|
|
600
|
+
const chantRuns = lineage.kind === "template" ? runChantMigrations({ dir: scopeDir, lineage: staged, chantVersion: readerVersion() }) : [];
|
|
601
|
+
const chantMigrations: ChantMigrationReport[] = chantRuns.map((r) => reportPlan(r.plan, r.applied));
|
|
602
|
+
|
|
571
603
|
// 4. Merge per file.
|
|
572
604
|
const result = applyUpstream(scopeDir, staged, upstream.files, { base, merge: mergeFile });
|
|
573
605
|
for (const path of result.written) if (upstream.executable.has(path)) chmodSync(join(scopeDir, path), 0o755);
|
|
@@ -607,12 +639,40 @@ export async function stageUpgrade(options: UpgradeOptions): Promise<StagedUpgra
|
|
|
607
639
|
|
|
608
640
|
// 5. Checks.
|
|
609
641
|
const checks: UpgradeCheck[] = [];
|
|
642
|
+
for (const m of chantMigrations.filter((m) => !m.applied)) {
|
|
643
|
+
checks.push({
|
|
644
|
+
name: "migration",
|
|
645
|
+
status: "failed",
|
|
646
|
+
detail: `${m.id} was not applied: ${m.conflicts.map((c) => `${c.path}: ${c.reason}`).join("\n")}`,
|
|
647
|
+
});
|
|
648
|
+
}
|
|
610
649
|
if (changed) {
|
|
611
|
-
|
|
650
|
+
// Every `chant` member chant.workspace.json declares, so a template
|
|
651
|
+
// whose chant project sits in a member (the studio kit's `delivery/`)
|
|
652
|
+
// is built and linted there, not skipped for having no chant.config at
|
|
653
|
+
// the scope's root (#2804). A scope with no workspace declaration falls
|
|
654
|
+
// back to the root, as before.
|
|
655
|
+
const members = chantMemberDirs(worktreeProject);
|
|
656
|
+
const targets = members.length > 0 ? members : isChantProject(worktreeProject) ? ["."] : [];
|
|
657
|
+
if (targets.length > 0) {
|
|
612
658
|
const run = options.runChant ?? spawnChant;
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
659
|
+
const namedMember = targets.length > 1 || targets[0] !== ".";
|
|
660
|
+
// A member that installs its packages in its own directory resolves them from its node_modules, which is not
|
|
661
|
+
// an ancestor of the staging worktree: link it in from the project (#2847). The patch and its digest are
|
|
662
|
+
// computed above, so the links never reach them, and dispose() removes them with the worktree.
|
|
663
|
+
for (const member of targets) {
|
|
664
|
+
if (member === ".") continue;
|
|
665
|
+
const from = join(root, member, "node_modules");
|
|
666
|
+
const to = join(worktreeProject, member, "node_modules");
|
|
667
|
+
if (existsSync(from) && !existsSync(to) && existsSync(dirname(to))) symlinkSync(from, to, "dir");
|
|
668
|
+
}
|
|
669
|
+
for (const member of targets) {
|
|
670
|
+
const dir = member === "." ? worktreeProject : join(worktreeProject, member);
|
|
671
|
+
const at = namedMember ? { member } : {};
|
|
672
|
+
for (const command of ["build", "lint"] as const) {
|
|
673
|
+
const r = await run(command, dir);
|
|
674
|
+
checks.push(r.exitCode === 0 ? { name: command, status: "passed", ...at } : { name: command, status: "failed", detail: tail(r.output), ...at });
|
|
675
|
+
}
|
|
616
676
|
}
|
|
617
677
|
} else {
|
|
618
678
|
for (const name of ["build", "lint"] as const) checks.push({ name, status: "skipped", detail: "not a chant project (no chant.config)" });
|
|
@@ -627,7 +687,8 @@ export async function stageUpgrade(options: UpgradeOptions): Promise<StagedUpgra
|
|
|
627
687
|
from: fromDir ? sourcePin(lineage.source) : lineage.ref ?? null,
|
|
628
688
|
to: fromDir ? sourcePin(staged.source) : staged.ref ?? null,
|
|
629
689
|
...(upstream.commit ? { commit: { ...(lineage.address?.commit ? { from: lineage.address.commit } : {}), to: upstream.commit } } : {}),
|
|
630
|
-
migrations: plan.chain.map((m) => m.migration.id),
|
|
690
|
+
migrations: [...plan.chain.map((m) => m.migration.id), ...chantMigrations.filter((m) => m.applied).map((m) => m.id)],
|
|
691
|
+
chantMigrations,
|
|
631
692
|
written: result.written,
|
|
632
693
|
merged: result.merged,
|
|
633
694
|
removed: result.removed,
|
|
@@ -721,7 +782,14 @@ export function describeStaged(staged: StagedUpgrade): string[] {
|
|
|
721
782
|
const lines: string[] = [];
|
|
722
783
|
const at = (p: string) => (staged.scope === "." ? p : `${staged.scope}/${p}`);
|
|
723
784
|
lines.push(`${staged.scope} ${staged.template} ${staged.from ?? "(no ref)"} -> ${staged.to ?? "(no ref)"}`);
|
|
724
|
-
|
|
785
|
+
const chantIds = new Set(staged.chantMigrations.map((m) => m.id));
|
|
786
|
+
for (const id of staged.migrations) if (!chantIds.has(id)) lines.push(` migration: ${id}`);
|
|
787
|
+
for (const m of staged.chantMigrations) {
|
|
788
|
+
lines.push(` chant migration: ${m.id} (${m.applied ? "applied" : "not applied: it has conflicts"}), to ${m.description}`);
|
|
789
|
+
for (const c of m.changes) lines.push(` ${c.action === "delete" ? "delete" : "write"}: ${at(c.path)} (${c.why}${c.edited ? "; it was edited since the template, and the edit stays in git history" : ""})`);
|
|
790
|
+
for (const n of m.notMoved) lines.push(` not moved: ${n.what} -> ${n.where}`);
|
|
791
|
+
for (const c of m.conflicts) lines.push(` conflict: ${at(c.path)}: ${c.reason}`);
|
|
792
|
+
}
|
|
725
793
|
for (const p of staged.written) lines.push(` updated: ${at(p)}`);
|
|
726
794
|
for (const p of staged.merged) lines.push(` merged: ${at(p)}`);
|
|
727
795
|
for (const p of staged.removed) lines.push(` removed: ${at(p)}`);
|
|
@@ -735,7 +803,10 @@ export function describeStaged(staged: StagedUpgrade): string[] {
|
|
|
735
803
|
` governance: ${staged.governance.paths.join(", ")}; needs ${q.count} human approval(s)${q.roles ? ` with a role in ${q.roles.join(", ")}` : ""}, from the rules at ${staged.governance.rules.slice(0, 12)}`,
|
|
736
804
|
);
|
|
737
805
|
}
|
|
738
|
-
for (const c of staged.checks)
|
|
806
|
+
for (const c of staged.checks) {
|
|
807
|
+
const label = c.member !== undefined ? `${c.name} (${c.member})` : c.name;
|
|
808
|
+
lines.push(` ${label}: ${c.status}${c.status === "skipped" && c.detail ? ` (${c.detail})` : ""}`);
|
|
809
|
+
}
|
|
739
810
|
lines.push(` patch: ${staged.changedPaths.length} file(s)${staged.lock.tracked ? "" : ` and the untracked ${LOCK_FILE}`}, ${staged.digest}`);
|
|
740
811
|
return lines;
|
|
741
812
|
}
|
|
@@ -135,6 +135,63 @@ describe("chant workspace ls on built workspaces", () => {
|
|
|
135
135
|
expect(doc.summary).toEqual({ members: 5, unreadable: 3, groups: 1, matches: 0 });
|
|
136
136
|
});
|
|
137
137
|
|
|
138
|
+
test("lists declared diagrams flattened across the workspace and its members (#2764)", () => {
|
|
139
|
+
const root = repo({
|
|
140
|
+
"chant.workspace.json": JSON.stringify({
|
|
141
|
+
name: "acme",
|
|
142
|
+
schema: 1,
|
|
143
|
+
members: [
|
|
144
|
+
{
|
|
145
|
+
name: "docs",
|
|
146
|
+
dir: "docs",
|
|
147
|
+
kind: "other",
|
|
148
|
+
because: "the docs site",
|
|
149
|
+
diagrams: [
|
|
150
|
+
{
|
|
151
|
+
name: "architecture",
|
|
152
|
+
title: "Studio architecture",
|
|
153
|
+
source: "docs/diagrams/architecture.d2",
|
|
154
|
+
render: "docs/diagrams/architecture.svg",
|
|
155
|
+
renderer: { tool: "d2", version: "0.9.0", args: ["--layout=elk", "--theme=0", "--pad=40", "--omit-version"] },
|
|
156
|
+
sourceHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
diagrams: [
|
|
162
|
+
{
|
|
163
|
+
name: "boundary",
|
|
164
|
+
title: "chant and hud",
|
|
165
|
+
source: null,
|
|
166
|
+
render: "docs/diagrams/boundary.svg",
|
|
167
|
+
renderer: { tool: "graphviz", version: "9.0.0", args: [] },
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
}),
|
|
171
|
+
"docs/README.md": "",
|
|
172
|
+
});
|
|
173
|
+
const doc = result(listWorkspace({ cwd: root }));
|
|
174
|
+
expectValid(doc);
|
|
175
|
+
expect(doc.diagrams).toEqual([
|
|
176
|
+
{
|
|
177
|
+
name: "boundary",
|
|
178
|
+
title: "chant and hud",
|
|
179
|
+
source: null,
|
|
180
|
+
render: "docs/diagrams/boundary.svg",
|
|
181
|
+
renderer: { tool: "graphviz", version: "9.0.0", args: [] },
|
|
182
|
+
member: null,
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "architecture",
|
|
186
|
+
title: "Studio architecture",
|
|
187
|
+
source: "docs/diagrams/architecture.d2",
|
|
188
|
+
render: "docs/diagrams/architecture.svg",
|
|
189
|
+
renderer: { tool: "d2", version: "0.9.0", args: ["--layout=elk", "--theme=0", "--pad=40", "--omit-version"] },
|
|
190
|
+
member: "docs",
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
});
|
|
194
|
+
|
|
138
195
|
test("a nested workspace member is readable by its own declaration, and ls inside it lists the inner one", () => {
|
|
139
196
|
const root = repo({
|
|
140
197
|
"chant.workspace.json": declaration([{ name: "kit", dir: "vendor/kit", kind: "workspace" }]),
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"result": {
|
|
9
9
|
"description": "The declaration was read. Exit code 0, even when some members can't be read.",
|
|
10
10
|
"type": "object",
|
|
11
|
-
"required": ["$schema", "contract", "chant", "at", "workspace", "members", "groups", "summary"],
|
|
11
|
+
"required": ["$schema", "contract", "chant", "at", "workspace", "members", "groups", "diagrams", "summary"],
|
|
12
12
|
"properties": {
|
|
13
13
|
"$schema": { "const": "https://intentius.io/chant/schemas/workspace/ls/v1/ls.schema.json" },
|
|
14
14
|
"contract": { "const": 1 },
|
|
@@ -61,6 +61,11 @@
|
|
|
61
61
|
"type": "array",
|
|
62
62
|
"items": { "$ref": "#/$defs/group" }
|
|
63
63
|
},
|
|
64
|
+
"diagrams": {
|
|
65
|
+
"description": "Added in contract 1 by #2764. Every declared diagram artifact, flattened across the workspace and its members: the workspace's own first, then each member's, in file order.",
|
|
66
|
+
"type": "array",
|
|
67
|
+
"items": { "$ref": "#/$defs/diagram" }
|
|
68
|
+
},
|
|
64
69
|
"summary": {
|
|
65
70
|
"type": "object",
|
|
66
71
|
"required": ["members", "unreadable", "groups", "matches"],
|
|
@@ -138,9 +143,49 @@
|
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
]
|
|
146
|
+
},
|
|
147
|
+
"acceptance": {
|
|
148
|
+
"description": "Added in contract 1 by #2772. For a work kind whose work block names acceptance criteria: each current work item that lists some, in path order, with how many of its criteria passing evidence meets, read in the tree read. Null for any other kind, and when the kind or its records can't be read.",
|
|
149
|
+
"oneOf": [
|
|
150
|
+
{ "type": "null" },
|
|
151
|
+
{
|
|
152
|
+
"type": "array",
|
|
153
|
+
"items": {
|
|
154
|
+
"type": "object",
|
|
155
|
+
"required": ["item", "state", "met", "total"],
|
|
156
|
+
"properties": {
|
|
157
|
+
"item": { "type": "string", "description": "The work item's id." },
|
|
158
|
+
"state": { "type": ["string", "null"], "description": "The item's state." },
|
|
159
|
+
"met": { "type": "integer", "minimum": 0, "description": "Criteria met by evidence naming them, with result pass and the criterion's verification; a manual verdict counts only from someone other than the implementer." },
|
|
160
|
+
"total": { "type": "integer", "minimum": 0, "description": "Criteria the item lists." }
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
]
|
|
141
165
|
}
|
|
142
166
|
}
|
|
143
167
|
},
|
|
168
|
+
"diagram": {
|
|
169
|
+
"description": "A diagram artifact the declaration names (#2764), pinned to the renderer its render was made with. chant runs no renderer; everything here comes straight from the declaration.",
|
|
170
|
+
"type": "object",
|
|
171
|
+
"required": ["name", "title", "source", "render", "renderer", "member"],
|
|
172
|
+
"properties": {
|
|
173
|
+
"name": { "type": "string" },
|
|
174
|
+
"title": { "type": "string" },
|
|
175
|
+
"source": { "type": ["string", "null"], "description": "From the workspace root, with / separators. Null for an SVG with no source." },
|
|
176
|
+
"render": { "type": "string", "description": "From the workspace root, with / separators." },
|
|
177
|
+
"renderer": {
|
|
178
|
+
"type": "object",
|
|
179
|
+
"required": ["tool", "version", "args"],
|
|
180
|
+
"properties": {
|
|
181
|
+
"tool": { "enum": ["d2", "mermaid", "graphviz"] },
|
|
182
|
+
"version": { "type": "string", "description": "The exact release the render was made with, such as 0.9.0." },
|
|
183
|
+
"args": { "type": "array", "items": { "type": "string" }, "description": "Passed before the input and output paths, in order." }
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
"member": { "type": ["string", "null"], "description": "The member that declares it, or null for the workspace's own." }
|
|
187
|
+
}
|
|
188
|
+
},
|
|
144
189
|
"group": {
|
|
145
190
|
"type": "object",
|
|
146
191
|
"required": ["name", "kind", "glob", "matches", "skipped", "reason"],
|
package/src/workspace/ls.ts
CHANGED
|
@@ -13,6 +13,11 @@
|
|
|
13
13
|
* and each member's, with each kind file's own name when it loads (#2680).
|
|
14
14
|
* Loading one imports it, so {@link listWorkspace} lists them unloaded and
|
|
15
15
|
* {@link listWorkspaceWithKinds}, which the command runs, loads them.
|
|
16
|
+
*
|
|
17
|
+
* The declared diagram artifacts are listed too, flattened across the
|
|
18
|
+
* workspace and its members into one `diagrams` array (#2764). Unlike record
|
|
19
|
+
* kinds, nothing about a diagram is loaded: everything printed comes
|
|
20
|
+
* straight from the declaration, and chant runs no renderer to list it.
|
|
16
21
|
*/
|
|
17
22
|
|
|
18
23
|
import { existsSync } from "node:fs";
|
|
@@ -20,11 +25,13 @@ import { resolve } from "node:path";
|
|
|
20
25
|
import { formatError } from "../cli/format";
|
|
21
26
|
import type { CommandContext } from "../cli/registry";
|
|
22
27
|
import {
|
|
28
|
+
declaredDiagrams,
|
|
23
29
|
readDeclaration,
|
|
24
30
|
readerVersion,
|
|
25
31
|
resolveGroups,
|
|
26
32
|
WorkspaceReadError,
|
|
27
33
|
type Declaration,
|
|
34
|
+
type DiagramDeclaration,
|
|
28
35
|
type ErrorLocation,
|
|
29
36
|
type Member,
|
|
30
37
|
type WorkspaceErrorCode,
|
|
@@ -74,6 +81,20 @@ export interface LsRecordKind {
|
|
|
74
81
|
kind: string | null;
|
|
75
82
|
/** Why the kind file can't be loaded, or null. */
|
|
76
83
|
reason: { code: DeclaredKindReasonCode; message: string } | null;
|
|
84
|
+
/**
|
|
85
|
+
* For a work kind with acceptance criteria (#2772): each current work item
|
|
86
|
+
* that lists criteria, with how many passing evidence meets. Null for any
|
|
87
|
+
* other kind, and when the kind or its records can't be read.
|
|
88
|
+
*/
|
|
89
|
+
acceptance: LsAcceptance[] | null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** A work item's acceptance criteria, counted (#2772). */
|
|
93
|
+
export interface LsAcceptance {
|
|
94
|
+
item: string;
|
|
95
|
+
state: string | null;
|
|
96
|
+
met: number;
|
|
97
|
+
total: number;
|
|
77
98
|
}
|
|
78
99
|
|
|
79
100
|
export interface LsMember {
|
|
@@ -89,6 +110,25 @@ export interface LsMember {
|
|
|
89
110
|
records: LsRecordKind[];
|
|
90
111
|
}
|
|
91
112
|
|
|
113
|
+
/**
|
|
114
|
+
* A diagram artifact the declaration names (#2764), flattened across the
|
|
115
|
+
* workspace and its members: hud reads one list, the way it already reads
|
|
116
|
+
* `records --json`'s flat `assets[]`. `sourceHash`, the declaration's own
|
|
117
|
+
* bookkeeping for `chant workspace check`'s drift finding, is not printed
|
|
118
|
+
* here; a reader that draws diagrams has no use for it.
|
|
119
|
+
*/
|
|
120
|
+
export interface LsDiagram {
|
|
121
|
+
name: string;
|
|
122
|
+
title: string;
|
|
123
|
+
/** From the workspace root, with / separators. Null for an SVG with no source. */
|
|
124
|
+
source: string | null;
|
|
125
|
+
/** From the workspace root, with / separators. */
|
|
126
|
+
render: string;
|
|
127
|
+
renderer: DiagramDeclaration["renderer"];
|
|
128
|
+
/** The member that declares it, or null for the workspace's own. */
|
|
129
|
+
member: string | null;
|
|
130
|
+
}
|
|
131
|
+
|
|
92
132
|
export interface LsGroup {
|
|
93
133
|
name: string;
|
|
94
134
|
kind: "examples";
|
|
@@ -117,6 +157,8 @@ export type LsDocument =
|
|
|
117
157
|
};
|
|
118
158
|
members: LsMember[];
|
|
119
159
|
groups: LsGroup[];
|
|
160
|
+
/** Every declared diagram, the workspace's own first, then each member's, in file order (#2764). */
|
|
161
|
+
diagrams: LsDiagram[];
|
|
120
162
|
summary: { members: number; unreadable: number; groups: number; matches: number };
|
|
121
163
|
}
|
|
122
164
|
| {
|
|
@@ -162,11 +204,12 @@ export async function listWorkspaceWithKinds(query: LsQuery): Promise<LsDocument
|
|
|
162
204
|
const { doc, declaration, tree, rootOnDisk } = readListing(query);
|
|
163
205
|
if (!declaration || "error" in doc) return doc;
|
|
164
206
|
const { loadDeclaredKinds } = await import("./declared-kinds");
|
|
165
|
-
const loaded = await loadDeclaredKinds(declaration, tree!, rootOnDisk
|
|
207
|
+
const loaded = await loadDeclaredKinds(declaration, tree!, rootOnDisk!, { acceptance: true, ...(doc.at !== null ? { at: doc.at } : {}) });
|
|
166
208
|
const byPath = new Map(loaded.map((k) => [k.declared.path, k]));
|
|
167
209
|
const fill = (r: LsRecordKind): LsRecordKind => {
|
|
168
210
|
const k = byPath.get(r.path)!;
|
|
169
|
-
|
|
211
|
+
const acceptance = k.acceptance ? k.acceptance.map((a) => ({ item: a.item, state: a.state, met: a.met, total: a.total })) : null;
|
|
212
|
+
return { ...r, name: r.name ?? k.kind, kind: k.kind, reason: k.reason, acceptance };
|
|
170
213
|
};
|
|
171
214
|
return {
|
|
172
215
|
...doc,
|
|
@@ -175,7 +218,7 @@ export async function listWorkspaceWithKinds(query: LsQuery): Promise<LsDocument
|
|
|
175
218
|
};
|
|
176
219
|
}
|
|
177
220
|
|
|
178
|
-
const unloaded = (records: Declaration["records"]): LsRecordKind[] => records.map((r) => ({ name: r.name, path: r.path, kind: null, reason: null }));
|
|
221
|
+
const unloaded = (records: Declaration["records"]): LsRecordKind[] => records.map((r) => ({ name: r.name, path: r.path, kind: null, reason: null, acceptance: null }));
|
|
179
222
|
|
|
180
223
|
function readListing(query: LsQuery): { doc: LsDocument; declaration?: Declaration; tree?: WorkspaceTree; rootOnDisk?: string } {
|
|
181
224
|
const chant = readerVersion();
|
|
@@ -213,6 +256,14 @@ function readListing(query: LsQuery): { doc: LsDocument; declaration?: Declarati
|
|
|
213
256
|
? { code: "no-matches", message: `no directory ${g.group.globs.join(" or ")} matches${tree.label} holds a chant project` }
|
|
214
257
|
: null,
|
|
215
258
|
}));
|
|
259
|
+
const diagrams: LsDiagram[] = declaredDiagrams(declaration).map((d) => ({
|
|
260
|
+
name: d.name,
|
|
261
|
+
title: d.title,
|
|
262
|
+
source: d.source,
|
|
263
|
+
render: d.render,
|
|
264
|
+
renderer: d.renderer,
|
|
265
|
+
member: d.member,
|
|
266
|
+
}));
|
|
216
267
|
const doc: LsDocument = {
|
|
217
268
|
...head,
|
|
218
269
|
at,
|
|
@@ -227,6 +278,7 @@ function readListing(query: LsQuery): { doc: LsDocument; declaration?: Declarati
|
|
|
227
278
|
},
|
|
228
279
|
members,
|
|
229
280
|
groups: lsGroups,
|
|
281
|
+
diagrams,
|
|
230
282
|
summary: {
|
|
231
283
|
members: members.length,
|
|
232
284
|
unreadable: members.filter((m) => !m.readable).length,
|
|
@@ -296,8 +348,15 @@ function formatLs(doc: Extract<LsDocument, { members: unknown }>): string {
|
|
|
296
348
|
kinds.forEach(({ r }, i) => {
|
|
297
349
|
lines.push(rendered[i + 1]);
|
|
298
350
|
if (r.reason) lines.push(` ${r.reason.code}: ${r.reason.message}`);
|
|
351
|
+
for (const a of r.acceptance ?? []) lines.push(` ${a.item} ${a.state ?? "-"}: ${a.met}/${a.total} criteria met`);
|
|
299
352
|
});
|
|
300
353
|
}
|
|
354
|
+
if (doc.diagrams.length > 0) {
|
|
355
|
+
lines.push("");
|
|
356
|
+
const rows = [["DIAGRAM", "MEMBER", "SOURCE", "RENDER", "RENDERER"]];
|
|
357
|
+
for (const d of doc.diagrams) rows.push([d.name, d.member ?? "(workspace)", d.source ?? "-", d.render, `${d.renderer.tool} ${d.renderer.version}`]);
|
|
358
|
+
lines.push(...table(rows));
|
|
359
|
+
}
|
|
301
360
|
if (doc.groups.length > 0) {
|
|
302
361
|
lines.push("");
|
|
303
362
|
const rows = [["GROUP", "KIND", "GLOB", "PROJECTS"]];
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { readFileSync } from "node:fs";
|
|
18
|
-
import { resolve } from "node:path";
|
|
18
|
+
import { relative, resolve, sep } from "node:path";
|
|
19
19
|
import { formatError } from "../cli/format";
|
|
20
20
|
import type { CommandContext } from "../cli/registry";
|
|
21
21
|
import { declaredRecordKinds, readDeclaration, readerVersion, WorkspaceReadError, type ErrorLocation, type WorkspaceErrorCode } from "./declaration";
|
|
@@ -24,6 +24,7 @@ import { answerPoint, askPoint, questionView, POINTS_WRITE_CONTRACT_VERSION, POI
|
|
|
24
24
|
import { candidates, inputOutput, pointsFileOf, pointVersion, quorumOf, readPointsThrough, type Decider, type ModelAsk, type WireAnswer } from "./points";
|
|
25
25
|
import type { ReasonCode } from "./reason-codes";
|
|
26
26
|
import { gitRevisionSource, workingTreeSource } from "./record-source";
|
|
27
|
+
import { readLedgerAnswers, withLedgerAnswers, type LedgerAnswers } from "./answers-ledger";
|
|
27
28
|
import { loadRecordKind, RecordReadError, type ReadErrorCode } from "./records";
|
|
28
29
|
import { readRecordsFor } from "./records-cli";
|
|
29
30
|
import { locateWorkspace } from "./which-chant";
|
|
@@ -70,6 +71,8 @@ export interface PointView {
|
|
|
70
71
|
questionType: string;
|
|
71
72
|
instructions: string;
|
|
72
73
|
candidates: (string | boolean)[];
|
|
74
|
+
/** What each candidate means, as the points file declares it: an object of strings for noul and choice, an array for score. */
|
|
75
|
+
criteria: Record<string, string> | string[];
|
|
73
76
|
/** Each input: its name, the read-contract output it names, and its description. */
|
|
74
77
|
inputs: { name: string; output: string; description: string }[];
|
|
75
78
|
deciders: Decider[];
|
|
@@ -136,7 +139,17 @@ export async function workspacePoints(query: PointsQuery): Promise<PointsDocumen
|
|
|
136
139
|
if (k.given) sources.push({ kind: k.shown, points: null, reason: { code: "kind-invalid", message: `the ${loaded.kind.name} kind has no answers block, so it holds no answers to decision points` } });
|
|
137
140
|
continue;
|
|
138
141
|
}
|
|
139
|
-
|
|
142
|
+
// Without --at, the questions a steward keeps on the lifecycle ledger are read too (#2786).
|
|
143
|
+
let ledger = undefined as LedgerAnswers | undefined;
|
|
144
|
+
const read = await readRecordsFor({
|
|
145
|
+
kind: k.file,
|
|
146
|
+
cwd: query.cwd,
|
|
147
|
+
at: query.at,
|
|
148
|
+
overlay: async (base, { loaded: l, root }) => {
|
|
149
|
+
ledger = await readLedgerAnswers({ file: l.file, name: l.kind.name, dirRel: relative(root, l.dir).split(sep).join("/") || "." });
|
|
150
|
+
return withLedgerAnswers(base, ledger);
|
|
151
|
+
},
|
|
152
|
+
});
|
|
140
153
|
const source = read.at !== null && read.top ? gitRevisionSource(read.top, read.at) : workingTreeSource(read.root);
|
|
141
154
|
const file = pointsFileOf(read.loaded, read.root);
|
|
142
155
|
const parsed = readPointsThrough(source, file);
|
|
@@ -152,13 +165,14 @@ export async function workspacePoints(query: PointsQuery): Promise<PointsDocumen
|
|
|
152
165
|
questionType: p.question.type,
|
|
153
166
|
instructions: p.question.instructions,
|
|
154
167
|
candidates: candidates(p.question),
|
|
168
|
+
criteria: p.question.criteria,
|
|
155
169
|
inputs: Object.entries(p.inputs).map(([n, description]) => ({ name: n, output: inputOutput(n), description })),
|
|
156
170
|
deciders: p.deciders,
|
|
157
171
|
quorum: quorumOf(p),
|
|
158
172
|
});
|
|
159
173
|
}
|
|
160
174
|
for (const e of read.result.records) {
|
|
161
|
-
const view = questionView(e, typeof e.data?.point === "string" ? declared[e.data.point] : undefined);
|
|
175
|
+
const view = questionView(e, typeof e.data?.point === "string" ? declared[e.data.point] : undefined, ledger?.byPath.get(e.path)?.ledger ?? null);
|
|
162
176
|
if (view && (!query.open || view.open)) questions.push(view);
|
|
163
177
|
}
|
|
164
178
|
} catch (err) {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://intentius.io/chant/schemas/workspace/points-write/v1/points-write.schema.json",
|
|
4
4
|
"title": "chant workspace points ask and answer output",
|
|
5
|
-
"description": "What `chant workspace points ask` and `points answer` print (ws-058, #2739): the answer record asked for or written, as `points --json` lists a question. ask returns the record that is there when the same point, declaration and inputs were answered or proposed before (reused), and otherwise writes one: answered from a table, proposed from a model at or above its threshold, escalated to people below it. answer records people's answer to an open question once the point's quorum is met. Nothing is committed, and nothing is written on a refusal or with --dry-run. The error codes are a closed list, each in the one closed list of `reason-codes.ts`. Written at contract version 1 of the write documents.",
|
|
5
|
+
"description": "What `chant workspace points ask` and `points answer` print (ws-058, #2739): the answer record asked for or written, as `points --json` lists a question. ask returns the record that is there when the same point, declaration and inputs were answered or proposed before (reused), and otherwise writes one: answered from a table, proposed from a model at or above its threshold, escalated to people below it. answer records people's answer to an open question once the point's quorum is met. Nothing is committed to the working branch, and nothing is written on a refusal or with --dry-run. In a steward's turn a new record goes on the lifecycle ledger instead of the working tree (#2786), as a commit on chant/lifecycle, and a record already held there is rewritten there. The error codes are a closed list, each in the one closed list of `reason-codes.ts`. Written at contract version 1 of the write documents.",
|
|
6
6
|
"oneOf": [
|
|
7
7
|
{
|
|
8
8
|
"$ref": "#/$defs/result"
|
|
@@ -372,6 +372,13 @@
|
|
|
372
372
|
"type": "string"
|
|
373
373
|
}
|
|
374
374
|
},
|
|
375
|
+
"ledger": {
|
|
376
|
+
"type": [
|
|
377
|
+
"string",
|
|
378
|
+
"null"
|
|
379
|
+
],
|
|
380
|
+
"description": "Where the record is held when it is on the lifecycle ledger rather than in the working tree (#2786): chant/lifecycle:<path>, which git show reads. A question asked in a steward's turn is held there, since a steward never writes the checkout; people's answer to it is written there too. null for a record in the working tree. path is where the record reads as being either way."
|
|
381
|
+
},
|
|
375
382
|
"askedOn": {
|
|
376
383
|
"type": [
|
|
377
384
|
"string",
|
|
@@ -465,6 +472,7 @@
|
|
|
465
472
|
"point-decider-failed",
|
|
466
473
|
"answer-not-candidate",
|
|
467
474
|
"quorum-not-met",
|
|
475
|
+
"answer-in-steward-turn",
|
|
468
476
|
"record-not-found",
|
|
469
477
|
"record-closed",
|
|
470
478
|
"record-id-taken",
|
|
@@ -473,6 +481,8 @@
|
|
|
473
481
|
"record-id-duplicate",
|
|
474
482
|
"record-supersedes-unknown",
|
|
475
483
|
"record-supersedes-conflict",
|
|
484
|
+
"record-remediates-unknown",
|
|
485
|
+
"record-remediates-not-closed",
|
|
476
486
|
"session-seal-mismatch",
|
|
477
487
|
"session-verdict-unknown-record"
|
|
478
488
|
]
|
|
@@ -191,6 +191,7 @@
|
|
|
191
191
|
"questionType",
|
|
192
192
|
"instructions",
|
|
193
193
|
"candidates",
|
|
194
|
+
"criteria",
|
|
194
195
|
"inputs",
|
|
195
196
|
"deciders",
|
|
196
197
|
"quorum"
|
|
@@ -236,6 +237,23 @@
|
|
|
236
237
|
]
|
|
237
238
|
}
|
|
238
239
|
},
|
|
240
|
+
"criteria": {
|
|
241
|
+
"description": "What each candidate means, as the points file declares it: noul and choice give an object of strings keyed by candidate, score an array of ordered level descriptions.",
|
|
242
|
+
"oneOf": [
|
|
243
|
+
{
|
|
244
|
+
"type": "object",
|
|
245
|
+
"additionalProperties": {
|
|
246
|
+
"type": "string"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"type": "array",
|
|
251
|
+
"items": {
|
|
252
|
+
"type": "string"
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
},
|
|
239
257
|
"inputs": {
|
|
240
258
|
"type": "array",
|
|
241
259
|
"items": {
|
|
@@ -583,6 +601,39 @@
|
|
|
583
601
|
"type": "string"
|
|
584
602
|
}
|
|
585
603
|
},
|
|
604
|
+
"askedBy": {
|
|
605
|
+
"description": "The steward whose turn asked the question (#2749), and the run it was in, or null. The steward waits on the question and never answers it: a person does.",
|
|
606
|
+
"oneOf": [
|
|
607
|
+
{
|
|
608
|
+
"type": "null"
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"type": "object",
|
|
612
|
+
"required": [
|
|
613
|
+
"steward",
|
|
614
|
+
"run"
|
|
615
|
+
],
|
|
616
|
+
"properties": {
|
|
617
|
+
"steward": {
|
|
618
|
+
"type": "string"
|
|
619
|
+
},
|
|
620
|
+
"run": {
|
|
621
|
+
"type": [
|
|
622
|
+
"string",
|
|
623
|
+
"null"
|
|
624
|
+
]
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
]
|
|
629
|
+
},
|
|
630
|
+
"ledger": {
|
|
631
|
+
"type": [
|
|
632
|
+
"string",
|
|
633
|
+
"null"
|
|
634
|
+
],
|
|
635
|
+
"description": "Where the record is held when it is on the lifecycle ledger rather than in the working tree (#2786): chant/lifecycle:<path>, which git show reads. A question asked in a steward's turn is held there, since a steward never writes the checkout; people's answer to it is written there too. null for a record in the working tree. path is where the record reads as being either way."
|
|
636
|
+
},
|
|
586
637
|
"askedOn": {
|
|
587
638
|
"type": [
|
|
588
639
|
"string",
|