worldvm 0.0.0-stage → 0.1.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/AUTHORING.md +833 -0
- package/README.md +154 -2
- package/bin/worldvm.mjs +3 -0
- package/dist/_internal/forma/index.d.ts +1 -0
- package/dist/_internal/forma/index.js +1 -0
- package/dist/_internal/forma/world/authoring-help.d.ts +25 -0
- package/dist/_internal/forma/world/authoring-help.js +130 -0
- package/dist/_internal/forma/world/citations.d.ts +3 -0
- package/dist/_internal/forma/world/citations.js +26 -0
- package/dist/_internal/forma/world/clock-bindings.d.ts +4 -0
- package/dist/_internal/forma/world/clock-bindings.js +45 -0
- package/dist/_internal/forma/world/compile.d.ts +13 -0
- package/dist/_internal/forma/world/compile.js +190 -0
- package/dist/_internal/forma/world/coverage.d.ts +10 -0
- package/dist/_internal/forma/world/coverage.js +242 -0
- package/dist/_internal/forma/world/digest.d.ts +1 -0
- package/dist/_internal/forma/world/digest.js +1 -0
- package/dist/_internal/forma/world/documentation.d.ts +3 -0
- package/dist/_internal/forma/world/documentation.js +38 -0
- package/dist/_internal/forma/world/homes.d.ts +4 -0
- package/dist/_internal/forma/world/homes.js +202 -0
- package/dist/_internal/forma/world/index.d.ts +6 -0
- package/dist/_internal/forma/world/index.js +5 -0
- package/dist/_internal/forma/world/lowering/accounts.d.ts +4 -0
- package/dist/_internal/forma/world/lowering/accounts.js +36 -0
- package/dist/_internal/forma/world/lowering/action-policy.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/action-policy.js +16 -0
- package/dist/_internal/forma/world/lowering/agents.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/agents.js +116 -0
- package/dist/_internal/forma/world/lowering/bundles.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/bundles.js +13 -0
- package/dist/_internal/forma/world/lowering/child-parameters.d.ts +14 -0
- package/dist/_internal/forma/world/lowering/child-parameters.js +36 -0
- package/dist/_internal/forma/world/lowering/collects.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/collects.js +51 -0
- package/dist/_internal/forma/world/lowering/component-operations.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/component-operations.js +26 -0
- package/dist/_internal/forma/world/lowering/components.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/components.js +236 -0
- package/dist/_internal/forma/world/lowering/connectors.d.ts +4 -0
- package/dist/_internal/forma/world/lowering/connectors.js +31 -0
- package/dist/_internal/forma/world/lowering/context.d.ts +80 -0
- package/dist/_internal/forma/world/lowering/context.js +316 -0
- package/dist/_internal/forma/world/lowering/contracts.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/contracts.js +73 -0
- package/dist/_internal/forma/world/lowering/decisions.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/decisions.js +164 -0
- package/dist/_internal/forma/world/lowering/derives.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/derives.js +22 -0
- package/dist/_internal/forma/world/lowering/discretionary.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/discretionary.js +15 -0
- package/dist/_internal/forma/world/lowering/documents.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/documents.js +68 -0
- package/dist/_internal/forma/world/lowering/effective.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/effective.js +26 -0
- package/dist/_internal/forma/world/lowering/entities.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/entities.js +43 -0
- package/dist/_internal/forma/world/lowering/escalations.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/escalations.js +31 -0
- package/dist/_internal/forma/world/lowering/evidence.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/evidence.js +75 -0
- package/dist/_internal/forma/world/lowering/files.d.ts +4 -0
- package/dist/_internal/forma/world/lowering/files.js +56 -0
- package/dist/_internal/forma/world/lowering/holds.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/holds.js +35 -0
- package/dist/_internal/forma/world/lowering/index.d.ts +89 -0
- package/dist/_internal/forma/world/lowering/index.js +115 -0
- package/dist/_internal/forma/world/lowering/interactions.d.ts +7 -0
- package/dist/_internal/forma/world/lowering/interactions.js +190 -0
- package/dist/_internal/forma/world/lowering/library.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/library.js +41 -0
- package/dist/_internal/forma/world/lowering/milestones.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/milestones.js +17 -0
- package/dist/_internal/forma/world/lowering/notices.d.ts +3 -0
- package/dist/_internal/forma/world/lowering/notices.js +33 -0
- package/dist/_internal/forma/world/lowering/param-bounds.d.ts +15 -0
- package/dist/_internal/forma/world/lowering/param-bounds.js +71 -0
- package/dist/_internal/forma/world/lowering/policies.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/policies.js +95 -0
- package/dist/_internal/forma/world/lowering/principals.d.ts +62 -0
- package/dist/_internal/forma/world/lowering/principals.js +32 -0
- package/dist/_internal/forma/world/lowering/recurrences.d.ts +9 -0
- package/dist/_internal/forma/world/lowering/recurrences.js +56 -0
- package/dist/_internal/forma/world/lowering/renewal.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/renewal.js +21 -0
- package/dist/_internal/forma/world/lowering/resources.d.ts +6 -0
- package/dist/_internal/forma/world/lowering/resources.js +19 -0
- package/dist/_internal/forma/world/lowering/reuse.d.ts +5 -0
- package/dist/_internal/forma/world/lowering/reuse.js +75 -0
- package/dist/_internal/forma/world/lowering/sources.d.ts +10 -0
- package/dist/_internal/forma/world/lowering/sources.js +47 -0
- package/dist/_internal/forma/world/lowering/syntax.d.ts +84 -0
- package/dist/_internal/forma/world/lowering/syntax.js +94 -0
- package/dist/_internal/forma/world/lowering/vaults.d.ts +11 -0
- package/dist/_internal/forma/world/lowering/vaults.js +148 -0
- package/dist/_internal/forma/world/prelude.generated.d.ts +1 -0
- package/dist/_internal/forma/world/prelude.generated.js +2 -0
- package/dist/_internal/forma/world/properties.d.ts +9 -0
- package/dist/_internal/forma/world/properties.js +387 -0
- package/dist/_internal/forma/world/scenarios.d.ts +10 -0
- package/dist/_internal/forma/world/scenarios.js +757 -0
- package/dist/_internal/forma/world/sensitivity.d.ts +3 -0
- package/dist/_internal/forma/world/sensitivity.js +118 -0
- package/dist/_internal/forma/world/source-syntax.d.ts +6 -0
- package/dist/_internal/forma/world/source-syntax.js +27 -0
- package/dist/_internal/forma/world/status-handling.d.ts +3 -0
- package/dist/_internal/forma/world/status-handling.js +143 -0
- package/dist/_internal/forma/world/surface.d.ts +30 -0
- package/dist/_internal/forma/world/surface.js +213 -0
- package/dist/_internal/forma/world/table-expressions.d.ts +3 -0
- package/dist/_internal/forma/world/table-expressions.js +41 -0
- package/dist/_internal/forma-tools/index.d.ts +17 -0
- package/dist/_internal/forma-tools/index.js +124 -0
- package/dist/_internal/ir-checks/advances.d.ts +7 -0
- package/dist/_internal/ir-checks/advances.js +6 -0
- package/dist/_internal/ir-checks/agent-reads.d.ts +14 -0
- package/dist/_internal/ir-checks/agent-reads.js +118 -0
- package/dist/_internal/ir-checks/amendments.d.ts +3 -0
- package/dist/_internal/ir-checks/amendments.js +21 -0
- package/dist/_internal/ir-checks/canonical-json.d.ts +3 -0
- package/dist/_internal/ir-checks/canonical-json.js +85 -0
- package/dist/_internal/ir-checks/child-parameters.d.ts +2 -0
- package/dist/_internal/ir-checks/child-parameters.js +43 -0
- package/dist/_internal/ir-checks/clock-bindings.d.ts +3 -0
- package/dist/_internal/ir-checks/clock-bindings.js +43 -0
- package/dist/_internal/ir-checks/collect-types.d.ts +14 -0
- package/dist/_internal/ir-checks/collect-types.js +34 -0
- package/dist/_internal/ir-checks/component-operations.d.ts +4 -0
- package/dist/_internal/ir-checks/component-operations.js +23 -0
- package/dist/_internal/ir-checks/content-digest.d.ts +4 -0
- package/dist/_internal/ir-checks/content-digest.js +78 -0
- package/dist/_internal/ir-checks/contract-validation.d.ts +3 -0
- package/dist/_internal/ir-checks/contract-validation.js +307 -0
- package/dist/_internal/ir-checks/contracts.d.ts +25 -0
- package/dist/_internal/ir-checks/contracts.js +80 -0
- package/dist/_internal/ir-checks/dates.d.ts +2 -0
- package/dist/_internal/ir-checks/dates.js +7 -0
- package/dist/_internal/ir-checks/documents.d.ts +3 -0
- package/dist/_internal/ir-checks/documents.js +45 -0
- package/dist/_internal/ir-checks/evidence.d.ts +20 -0
- package/dist/_internal/ir-checks/evidence.js +56 -0
- package/dist/_internal/ir-checks/files.d.ts +7 -0
- package/dist/_internal/ir-checks/files.js +47 -0
- package/dist/_internal/ir-checks/index.d.ts +59 -0
- package/dist/_internal/ir-checks/index.js +166 -0
- package/dist/_internal/ir-checks/instants.d.ts +7 -0
- package/dist/_internal/ir-checks/instants.js +61 -0
- package/dist/_internal/ir-checks/notices.d.ts +4 -0
- package/dist/_internal/ir-checks/notices.js +58 -0
- package/dist/_internal/ir-checks/policy-bounds.d.ts +5 -0
- package/dist/_internal/ir-checks/policy-bounds.js +28 -0
- package/dist/_internal/ir-checks/principals.d.ts +26 -0
- package/dist/_internal/ir-checks/principals.js +162 -0
- package/dist/_internal/ir-checks/prior-cycle.d.ts +41 -0
- package/dist/_internal/ir-checks/prior-cycle.js +21 -0
- package/dist/_internal/ir-checks/read-classification.d.ts +12 -0
- package/dist/_internal/ir-checks/read-classification.js +67 -0
- package/dist/_internal/ir-checks/read-types.d.ts +2 -0
- package/dist/_internal/ir-checks/read-types.js +40 -0
- package/dist/_internal/ir-checks/resource-proofs.d.ts +4 -0
- package/dist/_internal/ir-checks/resource-proofs.js +98 -0
- package/dist/_internal/ir-checks/resources.d.ts +3 -0
- package/dist/_internal/ir-checks/resources.js +30 -0
- package/dist/_internal/ir-checks/reuse.d.ts +10 -0
- package/dist/_internal/ir-checks/reuse.js +99 -0
- package/dist/_internal/ir-checks/sealing.d.ts +14 -0
- package/dist/_internal/ir-checks/sealing.js +123 -0
- package/dist/_internal/ir-checks/sensitive-flow.d.ts +4 -0
- package/dist/_internal/ir-checks/sensitive-flow.js +240 -0
- package/dist/_internal/ir-checks/sensitivity.d.ts +19 -0
- package/dist/_internal/ir-checks/sensitivity.js +133 -0
- package/dist/_internal/ir-checks/signatures.d.ts +4 -0
- package/dist/_internal/ir-checks/signatures.js +22 -0
- package/dist/_internal/ir-checks/vaults.d.ts +10 -0
- package/dist/_internal/ir-checks/vaults.js +140 -0
- package/dist/_internal/protocol/index.d.ts +1234 -0
- package/dist/_internal/protocol/index.js +215 -0
- package/dist/_internal/reconciler/action-intents.d.ts +17 -0
- package/dist/_internal/reconciler/action-intents.js +161 -0
- package/dist/_internal/reconciler/actions.d.ts +7 -0
- package/dist/_internal/reconciler/actions.js +134 -0
- package/dist/_internal/reconciler/amendments.d.ts +12 -0
- package/dist/_internal/reconciler/amendments.js +52 -0
- package/dist/_internal/reconciler/basis.d.ts +253 -0
- package/dist/_internal/reconciler/basis.js +16 -0
- package/dist/_internal/reconciler/bundles.d.ts +22 -0
- package/dist/_internal/reconciler/bundles.js +110 -0
- package/dist/_internal/reconciler/change-detection.d.ts +5 -0
- package/dist/_internal/reconciler/change-detection.js +82 -0
- package/dist/_internal/reconciler/collection-rules.d.ts +7 -0
- package/dist/_internal/reconciler/collection-rules.js +46 -0
- package/dist/_internal/reconciler/collection-state.d.ts +11 -0
- package/dist/_internal/reconciler/collection-state.js +62 -0
- package/dist/_internal/reconciler/collection-values.d.ts +5 -0
- package/dist/_internal/reconciler/collection-values.js +60 -0
- package/dist/_internal/reconciler/collections.d.ts +35 -0
- package/dist/_internal/reconciler/collections.js +141 -0
- package/dist/_internal/reconciler/commands.d.ts +60 -0
- package/dist/_internal/reconciler/commands.js +468 -0
- package/dist/_internal/reconciler/component-operations.d.ts +48 -0
- package/dist/_internal/reconciler/component-operations.js +256 -0
- package/dist/_internal/reconciler/context.d.ts +38 -0
- package/dist/_internal/reconciler/context.js +44 -0
- package/dist/_internal/reconciler/coverage.d.ts +31 -0
- package/dist/_internal/reconciler/coverage.js +124 -0
- package/dist/_internal/reconciler/dates.d.ts +38 -0
- package/dist/_internal/reconciler/dates.js +121 -0
- package/dist/_internal/reconciler/decide.d.ts +25 -0
- package/dist/_internal/reconciler/decide.js +263 -0
- package/dist/_internal/reconciler/decision-evaluation.d.ts +9 -0
- package/dist/_internal/reconciler/decision-evaluation.js +67 -0
- package/dist/_internal/reconciler/decision-records.d.ts +14 -0
- package/dist/_internal/reconciler/decision-records.js +77 -0
- package/dist/_internal/reconciler/decision-release.d.ts +3 -0
- package/dist/_internal/reconciler/decision-release.js +12 -0
- package/dist/_internal/reconciler/dependencies.d.ts +179 -0
- package/dist/_internal/reconciler/dependencies.js +372 -0
- package/dist/_internal/reconciler/discovery.d.ts +9 -0
- package/dist/_internal/reconciler/discovery.js +65 -0
- package/dist/_internal/reconciler/document-corrections.d.ts +18 -0
- package/dist/_internal/reconciler/document-corrections.js +59 -0
- package/dist/_internal/reconciler/documents.d.ts +26 -0
- package/dist/_internal/reconciler/documents.js +88 -0
- package/dist/_internal/reconciler/effective.d.ts +6 -0
- package/dist/_internal/reconciler/effective.js +17 -0
- package/dist/_internal/reconciler/escalations.d.ts +4 -0
- package/dist/_internal/reconciler/escalations.js +76 -0
- package/dist/_internal/reconciler/evaluation.d.ts +56 -0
- package/dist/_internal/reconciler/evaluation.js +704 -0
- package/dist/_internal/reconciler/evidence-authority.d.ts +6 -0
- package/dist/_internal/reconciler/evidence-authority.js +70 -0
- package/dist/_internal/reconciler/evidence-history.d.ts +5 -0
- package/dist/_internal/reconciler/evidence-history.js +22 -0
- package/dist/_internal/reconciler/evidence-validity.d.ts +17 -0
- package/dist/_internal/reconciler/evidence-validity.js +135 -0
- package/dist/_internal/reconciler/fact-validation.d.ts +5 -0
- package/dist/_internal/reconciler/fact-validation.js +49 -0
- package/dist/_internal/reconciler/files.d.ts +9 -0
- package/dist/_internal/reconciler/files.js +56 -0
- package/dist/_internal/reconciler/graph.d.ts +40 -0
- package/dist/_internal/reconciler/graph.js +298 -0
- package/dist/_internal/reconciler/holds.d.ts +6 -0
- package/dist/_internal/reconciler/holds.js +18 -0
- package/dist/_internal/reconciler/home-definitions.d.ts +11 -0
- package/dist/_internal/reconciler/home-definitions.js +25 -0
- package/dist/_internal/reconciler/homes.d.ts +6 -0
- package/dist/_internal/reconciler/homes.js +32 -0
- package/dist/_internal/reconciler/index.d.ts +42 -0
- package/dist/_internal/reconciler/index.js +58 -0
- package/dist/_internal/reconciler/instants.d.ts +17 -0
- package/dist/_internal/reconciler/instants.js +56 -0
- package/dist/_internal/reconciler/interaction-fields.d.ts +10 -0
- package/dist/_internal/reconciler/interaction-fields.js +30 -0
- package/dist/_internal/reconciler/invariants.d.ts +8 -0
- package/dist/_internal/reconciler/invariants.js +34 -0
- package/dist/_internal/reconciler/journal.d.ts +3 -0
- package/dist/_internal/reconciler/journal.js +4 -0
- package/dist/_internal/reconciler/linking.d.ts +10 -0
- package/dist/_internal/reconciler/linking.js +259 -0
- package/dist/_internal/reconciler/memory.d.ts +32 -0
- package/dist/_internal/reconciler/memory.js +190 -0
- package/dist/_internal/reconciler/milestones.d.ts +7 -0
- package/dist/_internal/reconciler/milestones.js +58 -0
- package/dist/_internal/reconciler/missing.d.ts +18 -0
- package/dist/_internal/reconciler/missing.js +79 -0
- package/dist/_internal/reconciler/model.d.ts +350 -0
- package/dist/_internal/reconciler/model.js +9 -0
- package/dist/_internal/reconciler/notices.d.ts +14 -0
- package/dist/_internal/reconciler/notices.js +80 -0
- package/dist/_internal/reconciler/occurrences.d.ts +3 -0
- package/dist/_internal/reconciler/occurrences.js +30 -0
- package/dist/_internal/reconciler/outputs.d.ts +12 -0
- package/dist/_internal/reconciler/outputs.js +132 -0
- package/dist/_internal/reconciler/parameters.d.ts +4 -0
- package/dist/_internal/reconciler/parameters.js +27 -0
- package/dist/_internal/reconciler/policies.d.ts +22 -0
- package/dist/_internal/reconciler/policies.js +94 -0
- package/dist/_internal/reconciler/policy-edits.d.ts +11 -0
- package/dist/_internal/reconciler/policy-edits.js +42 -0
- package/dist/_internal/reconciler/policy-linking.d.ts +4 -0
- package/dist/_internal/reconciler/policy-linking.js +104 -0
- package/dist/_internal/reconciler/principal-types.d.ts +2 -0
- package/dist/_internal/reconciler/principal-types.js +38 -0
- package/dist/_internal/reconciler/prior-decisions.d.ts +3 -0
- package/dist/_internal/reconciler/prior-decisions.js +34 -0
- package/dist/_internal/reconciler/projections.d.ts +4 -0
- package/dist/_internal/reconciler/projections.js +85 -0
- package/dist/_internal/reconciler/proofs.d.ts +9 -0
- package/dist/_internal/reconciler/proofs.js +24 -0
- package/dist/_internal/reconciler/properties.d.ts +25 -0
- package/dist/_internal/reconciler/properties.js +67 -0
- package/dist/_internal/reconciler/property-eval.d.ts +5 -0
- package/dist/_internal/reconciler/property-eval.js +101 -0
- package/dist/_internal/reconciler/property-generator.d.ts +9 -0
- package/dist/_internal/reconciler/property-generator.js +288 -0
- package/dist/_internal/reconciler/property-shrink.d.ts +14 -0
- package/dist/_internal/reconciler/property-shrink.js +183 -0
- package/dist/_internal/reconciler/provenance.d.ts +8 -0
- package/dist/_internal/reconciler/provenance.js +61 -0
- package/dist/_internal/reconciler/reconcile.d.ts +32 -0
- package/dist/_internal/reconciler/reconcile.js +164 -0
- package/dist/_internal/reconciler/recurrence.d.ts +9 -0
- package/dist/_internal/reconciler/recurrence.js +44 -0
- package/dist/_internal/reconciler/requirements.d.ts +5 -0
- package/dist/_internal/reconciler/requirements.js +331 -0
- package/dist/_internal/reconciler/resource-generation.d.ts +9 -0
- package/dist/_internal/reconciler/resource-generation.js +17 -0
- package/dist/_internal/reconciler/resource-scenarios.d.ts +26 -0
- package/dist/_internal/reconciler/resource-scenarios.js +78 -0
- package/dist/_internal/reconciler/resources.d.ts +24 -0
- package/dist/_internal/reconciler/resources.js +178 -0
- package/dist/_internal/reconciler/result-digest.d.ts +13 -0
- package/dist/_internal/reconciler/result-digest.js +66 -0
- package/dist/_internal/reconciler/reuse.d.ts +16 -0
- package/dist/_internal/reconciler/reuse.js +119 -0
- package/dist/_internal/reconciler/scenarios.d.ts +32 -0
- package/dist/_internal/reconciler/scenarios.js +442 -0
- package/dist/_internal/reconciler/scheduling.d.ts +9 -0
- package/dist/_internal/reconciler/scheduling.js +203 -0
- package/dist/_internal/reconciler/sha256.d.ts +1 -0
- package/dist/_internal/reconciler/sha256.js +1 -0
- package/dist/_internal/reconciler/signatures.d.ts +13 -0
- package/dist/_internal/reconciler/signatures.js +37 -0
- package/dist/_internal/reconciler/temporal.d.ts +10 -0
- package/dist/_internal/reconciler/temporal.js +46 -0
- package/dist/_internal/reconciler/upgrades.d.ts +6 -0
- package/dist/_internal/reconciler/upgrades.js +65 -0
- package/dist/_internal/reconciler/wire.d.ts +2 -0
- package/dist/_internal/reconciler/wire.js +5 -0
- package/dist/_internal/reconciler/work.d.ts +32 -0
- package/dist/_internal/reconciler/work.js +101 -0
- package/dist/_internal/world-ir/schema.generated.d.ts +180 -0
- package/dist/_internal/world-ir/schema.generated.js +1127 -0
- package/dist/_internal/world-ir/types.generated.d.ts +1011 -0
- package/dist/_internal/world-ir/types.generated.js +1 -0
- package/dist/authoring.d.ts +9 -0
- package/dist/authoring.js +10 -0
- package/dist/catalogue.d.ts +20 -0
- package/dist/catalogue.js +531 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +553 -0
- package/dist/codegen.d.ts +6 -0
- package/dist/codegen.js +89 -0
- package/dist/coverage.d.ts +60 -0
- package/dist/coverage.js +128 -0
- package/dist/deploy.d.ts +21 -0
- package/dist/deploy.js +72 -0
- package/dist/diagnostics.d.ts +9 -0
- package/dist/diagnostics.js +37 -0
- package/dist/diff.d.ts +17 -0
- package/dist/diff.js +19 -0
- package/dist/durable-object.d.ts +14 -0
- package/dist/durable-object.js +30 -0
- package/dist/explain.d.ts +113 -0
- package/dist/explain.js +225 -0
- package/dist/fixes.d.ts +4 -0
- package/dist/fixes.js +70 -0
- package/dist/fmt.d.ts +12 -0
- package/dist/fmt.js +39 -0
- package/dist/handle/open.d.ts +18 -0
- package/dist/handle/open.js +28 -0
- package/dist/handle/protocol.d.ts +12 -0
- package/dist/handle/protocol.js +96 -0
- package/dist/handle/store.d.ts +31 -0
- package/dist/handle/store.js +11 -0
- package/dist/handle/types.d.ts +37 -0
- package/dist/handle/types.js +1 -0
- package/dist/handle/world.d.ts +190 -0
- package/dist/handle/world.js +533 -0
- package/dist/http.d.ts +3 -0
- package/dist/http.js +72 -0
- package/dist/impact.d.ts +21 -0
- package/dist/impact.js +57 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +43 -0
- package/dist/init.d.ts +13 -0
- package/dist/init.js +99 -0
- package/dist/ir-schema.json +4213 -0
- package/dist/lints.d.ts +8 -0
- package/dist/lints.js +154 -0
- package/dist/lsp.d.ts +14 -0
- package/dist/lsp.js +380 -0
- package/dist/manual/catalog.d.ts +12 -0
- package/dist/manual/catalog.js +23 -0
- package/dist/manual/examples.d.ts +15 -0
- package/dist/manual/examples.js +39 -0
- package/dist/manual/projections.d.ts +77 -0
- package/dist/manual/projections.js +344 -0
- package/dist/manual/prose.d.ts +19 -0
- package/dist/manual/prose.js +215 -0
- package/dist/manual/render.d.ts +76 -0
- package/dist/manual/render.js +250 -0
- package/dist/manual/text.d.ts +7 -0
- package/dist/manual/text.js +15 -0
- package/dist/mcp.d.ts +32 -0
- package/dist/mcp.js +269 -0
- package/dist/mutate.d.ts +36 -0
- package/dist/mutate.js +123 -0
- package/dist/project.d.ts +26 -0
- package/dist/project.js +80 -0
- package/dist/refine.d.ts +18 -0
- package/dist/refine.js +197 -0
- package/dist/release/diff.d.ts +45 -0
- package/dist/release/diff.js +103 -0
- package/dist/release/impact.d.ts +83 -0
- package/dist/release/impact.js +214 -0
- package/dist/release/nodes.d.ts +20 -0
- package/dist/release/nodes.js +118 -0
- package/dist/render.d.ts +19 -0
- package/dist/render.js +43 -0
- package/dist/serve.d.ts +18 -0
- package/dist/serve.js +140 -0
- package/dist/snapshot.d.ts +19 -0
- package/dist/snapshot.js +45 -0
- package/dist/sqlite.d.ts +16 -0
- package/dist/sqlite.js +151 -0
- package/dist/test.d.ts +54 -0
- package/dist/test.js +131 -0
- package/dist/world.d.ts +7 -0
- package/dist/world.js +5 -0
- package/docs/authoring/vendor-risk/example.forma +11 -0
- package/docs/authoring/vendor-risk/library/vendor.forma +76 -0
- package/docs/authoring/vendor-risk/scenarios/reviews.forma +107 -0
- package/docs/protocol.md +195 -0
- package/docs/reference.md +258 -0
- package/package.json +81 -3
package/dist/cli.js
ADDED
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
import { DIAGNOSTIC_RENAMES } from "./_internal/forma/world/index.js";
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { codegenDirectory } from "./codegen.js";
|
|
4
|
+
import { formatPaths } from "./fmt.js";
|
|
5
|
+
import { serveLsp } from "./lsp.js";
|
|
6
|
+
import { parseArgs } from "node:util";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { checkDirectory, testDirectory, coverageDirectory, renderDirectory, explainDirectory, diffDirectories, impactDirectories, serveStdio, } from "./index.js";
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { CATALOGUE, catalogueEntry, explain } from "./catalogue.js";
|
|
12
|
+
import { initWorld } from "./init.js";
|
|
13
|
+
import { decodeActor } from "./_internal/protocol/index.js";
|
|
14
|
+
import { open } from "./handle/open.js";
|
|
15
|
+
import { sqlite } from "./sqlite.js";
|
|
16
|
+
import { serve, scheduleTicks } from "./serve.js";
|
|
17
|
+
import { deployDirectory } from "./deploy.js";
|
|
18
|
+
import { snapshotDatabase } from "./snapshot.js";
|
|
19
|
+
const guide = fileURLToPath(new URL("../AUTHORING.md", import.meta.url));
|
|
20
|
+
const usage = `Usage:\n worldvm init <directory> (scaffold a minimal passing world)\n worldvm codegen <directory> [--out file]\n worldvm check <directory> [--json] [--core]\n worldvm test <directory> [--json] [--scenario name] [--seed n] [--cases n]\n worldvm coverage <directory> [--json] [--seed n] [--cases n] [--mutate]\n worldvm render <directory> [--json] [--format markdown|html] [--account name]\n worldvm explain <directory> --scenario name [--at instant] [--subject id] [--json]\n worldvm explain <directory> --world snapshot.json --subject id --at instant [--json]\n worldvm explain <diagnostic-code> | --list [--json]\n worldvm diff <old-directory> <new-directory> [--json]\n worldvm impact <old-directory> <new-directory> --world snapshot.json --at instant [--json]\n worldvm snapshot --db file.db --account id [--out snapshot.json]\n worldvm fmt [--check] <directory|files> [--json]\n worldvm lsp (Language Server Protocol on stdio)\n worldvm deploy <directory> --db file.db --account id [--at instant] [--dry-run] [--json]\n worldvm serve [directory] --db file.db [--port n] [--clock instant] [--ui] (runs the deployed release; directory is the deploy-then-serve shortcut)\n worldvm mcp [--world <directory>] [--db file.db --actor json] (Model Context Protocol server on stdio)\n\nA world is a directory of .forma files. To write one, read the authoring guide shipped\nwith this package: layout, a minimal world, every form, Truth and comparisons, scenarios\nand the diagnostics catalogue.\n ${guide}\n\nThe authoring loop: worldvm check → worldvm test → worldvm coverage.\nRun worldvm <command> --help for that command's options.`;
|
|
21
|
+
/** Per-subcommand help; `worldvm <command> --help` prints the matching entry. */
|
|
22
|
+
const HELP = {
|
|
23
|
+
deploy: `Usage: worldvm deploy <directory> --db file.db --account id [--at instant] [--dry-run] [--json]
|
|
24
|
+
|
|
25
|
+
Check, report live population impact, retain the compiled release and activate it.
|
|
26
|
+
--at defaults to now. --dry-run leaves the database unchanged.
|
|
27
|
+
Stop serve before deploying; one process per SQLite file.`,
|
|
28
|
+
snapshot: `Usage: worldvm snapshot --db file.db --account id [--out snapshot.json]
|
|
29
|
+
|
|
30
|
+
Export a committed SQLite world as worldvm/world@1 JSON. Defaults to stdout.
|
|
31
|
+
--account names the account whose committed records are exported.
|
|
32
|
+
The export includes its recorded release and is safe while serve is running.`,
|
|
33
|
+
codegen: "Usage: worldvm codegen <directory> [--out file]\n\nEmit entity, evidence and operation types. Defaults to stdout.",
|
|
34
|
+
init: `Usage: worldvm init <directory>
|
|
35
|
+
|
|
36
|
+
Write a minimal passing world: a library with one role, evidence, interaction and
|
|
37
|
+
component, an example account with entities, one scenario and one property.
|
|
38
|
+
The directory must be new or empty. Then run the authoring loop:
|
|
39
|
+
worldvm check <directory> && worldvm test <directory> && worldvm coverage <directory>`,
|
|
40
|
+
check: `Usage: worldvm check <directory> [--json] [--core]
|
|
41
|
+
|
|
42
|
+
Compile every visible .forma file under <directory>, link each account and run the
|
|
43
|
+
authoring lints. Diagnostics include a location, specific help and, where the edit
|
|
44
|
+
is mechanical, a fix with the expected old text. Exit 0 when there are no errors
|
|
45
|
+
(warnings and info are allowed), 1 when there are errors, 2 for invalid usage.
|
|
46
|
+
--core adds I_EXTENDED_FORM information at declarations outside the ten core forms.
|
|
47
|
+
Explain any code with: worldvm explain <code>`,
|
|
48
|
+
test: `Usage: worldvm test <directory> [--json] [--scenario name] [--seed n] [--cases n]
|
|
49
|
+
|
|
50
|
+
Run every scenario and seeded property (defaults: seed 0, 100 cases). A property
|
|
51
|
+
failure prints a shrunk counterexample scenario you can paste and replay.
|
|
52
|
+
--scenario name run only that scenario (properties are skipped)
|
|
53
|
+
--seed n property generation seed
|
|
54
|
+
--cases n property cases per property
|
|
55
|
+
Exit 0 when everything passes, 1 on any failure, 2 for invalid usage.`,
|
|
56
|
+
coverage: `Usage: worldvm coverage <directory> [--json] [--seed n] [--cases n] [--mutate]
|
|
57
|
+
|
|
58
|
+
Run the same scenarios and properties as test, then report per requirement which
|
|
59
|
+
scenarios/properties reference it and which applicability, status and due branches
|
|
60
|
+
were actually observed. References are not proof of behaviour: a requirement can be
|
|
61
|
+
"covered" by a scenario that never checks the branch that matters.
|
|
62
|
+
--mutate also apply semantic mutants one at a time (valid->attested,
|
|
63
|
+
attested->valid, drop a conjunct/disjunct, flip = and !=, remove
|
|
64
|
+
:applies-when), rerun every test, and report each mutant that no
|
|
65
|
+
scenario or property catches as a gap
|
|
66
|
+
Exit 0 when tests pass, 1 when they fail, 2 for invalid usage.`,
|
|
67
|
+
render: `Usage: worldvm render <directory> [--json] [--format markdown|html] [--account name]
|
|
68
|
+
|
|
69
|
+
Render the world as a manual a person can review and sign off.`,
|
|
70
|
+
explain: `Usage: worldvm explain <directory> --scenario name [--at instant] [--subject id] [--json]
|
|
71
|
+
worldvm explain <directory> --world snapshot.json --subject id --at instant [--json]
|
|
72
|
+
worldvm explain <diagnostic-code> [--json]
|
|
73
|
+
worldvm explain --list [--json]
|
|
74
|
+
|
|
75
|
+
With a directory, explain each requirement's status, due date and proof at a scenario
|
|
76
|
+
step or snapshot instant. With a diagnostic code (e.g. W_ATTESTED_EXPIRING,
|
|
77
|
+
elaborate/unknown-form), print its cause, an example and the fix. --list lists codes.`,
|
|
78
|
+
diff: `Usage: worldvm diff <old-directory> <new-directory> [--json]
|
|
79
|
+
|
|
80
|
+
Semantic diff of two releases: added, removed and changed declarations, breaking changes
|
|
81
|
+
and example changes.`,
|
|
82
|
+
impact: `Usage: worldvm impact <old-directory> <new-directory> --world snapshot.json --at instant [--json]
|
|
83
|
+
|
|
84
|
+
Preview which subjects, occurrences and work a release change would affect.`,
|
|
85
|
+
fmt: `Usage: worldvm fmt [--check] <directory|files> [--json]
|
|
86
|
+
|
|
87
|
+
Format visible .forma sources. --check reports changes without writing (exit 1).`,
|
|
88
|
+
lsp: `Usage: worldvm lsp
|
|
89
|
+
|
|
90
|
+
Serve the Forma Language Server Protocol on stdio.`,
|
|
91
|
+
serve: `Usage: worldvm serve [directory] --db file.db [--port 3000] [--clock fixed-instant] [--ui]
|
|
92
|
+
|
|
93
|
+
Runs the deployed release. A directory is a development shortcut: deploy, then serve.
|
|
94
|
+
|
|
95
|
+
Serve the operating protocol on loopback HTTP. x-worldvm-actor is trusted, dev-only identity.
|
|
96
|
+
See docs/protocol.md.`,
|
|
97
|
+
mcp: `Usage: worldvm mcp [--world directory] [--db file.db --actor '{"id":"agent:x","kind":"agent"}']
|
|
98
|
+
|
|
99
|
+
Serve authoring tools over stdio. With --db and --actor, also expose operating
|
|
100
|
+
tools for the deployed release. --world supplies source for development. See docs/protocol.md.`,
|
|
101
|
+
};
|
|
102
|
+
/** A diagnostic code rather than a directory: catalogued, or code-shaped and not on disk. */
|
|
103
|
+
const isCode = (arg) => !!catalogueEntry(arg) || (/^(?:[EWI]_[A-Z0-9_]+|[a-z]+\/[a-z-]+)$/.test(arg) && !existsSync(arg));
|
|
104
|
+
const display = (directory, d) => {
|
|
105
|
+
const location = d.at ? `${resolve(directory, d.at.src)}:${d.at.line}:${d.at.col}: ` : "";
|
|
106
|
+
console.error(`${location}${d.severity} ${d.code}: ${d.message}\n help: ${d.help}${d.fix ? `\n fix: replace [${d.fix.from}, ${d.fix.to}) with ${d.fix.text}` : ""}${catalogueEntry(d.code) ? `\n explain: worldvm explain ${d.code}` : ""}`);
|
|
107
|
+
};
|
|
108
|
+
const printExplanation = (report) => {
|
|
109
|
+
const at = (s) => `${s.src}:${s.line}:${s.col}`;
|
|
110
|
+
console.log(`explain ${report.source?.kind === "scenario" ? `scenario ${report.source.name} step ${report.source.step}` : `snapshot ${report.source?.kind === "snapshot" ? report.source.path : ""}`} at ${report.now}${report.subject ? ` for ${report.subject}` : ""}`);
|
|
111
|
+
for (const inst of report.instances) {
|
|
112
|
+
console.log(`\n${inst.component} ${inst.instance}`);
|
|
113
|
+
for (const q of inst.requirements) {
|
|
114
|
+
console.log(` ${q.name}: ${q.status}; due ${q.due ?? `unknown${q.dueUnknown ? ` (${q.dueUnknown})` : ""}`} · ${at(q.rule.at)}`);
|
|
115
|
+
for (const r of q.reasons)
|
|
116
|
+
console.log(` ${r.outcome} ${r.label}: ${r.detail}${r.at ? ` · ${at(r.at)}` : ""}`);
|
|
117
|
+
for (const s of q.dueSteps)
|
|
118
|
+
console.log(` due step ${JSON.stringify(s.value)}${s.branch ? ` [${s.branch}]` : ""}${s.note ? ` ${s.note}` : ""} · ${at(s.at)}`);
|
|
119
|
+
if (q.evidence)
|
|
120
|
+
console.log(` evidence ${q.evidence.id} (${q.evidence.status}, ${q.evidence.by})`);
|
|
121
|
+
if (q.blocked)
|
|
122
|
+
console.log(` blocked: ${q.blocked}`);
|
|
123
|
+
for (const c of q.rule.cites)
|
|
124
|
+
console.log(` cites ${c.title} ${c.clause}`);
|
|
125
|
+
console.log(` proof ${q.proof}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (const w of report.work)
|
|
129
|
+
console.log(`work ${w.key}: ${w.state}; ${w.assignee.kind} ${w.assignee.id ?? "unresolved"}${w.reason ? `; ${w.reason}` : ""}`);
|
|
130
|
+
};
|
|
131
|
+
const printDiff = (report) => {
|
|
132
|
+
if (!report.diff)
|
|
133
|
+
return;
|
|
134
|
+
const at = (s) => (s ? `${s.src}:${s.line}` : "-");
|
|
135
|
+
for (const c of report.diff.changes)
|
|
136
|
+
console.log(`${c.change} ${c.kind} ${c.name}${c.fields.length ? `: ${c.fields.map((f) => (f.aspect === "other" ? f.field : f.aspect)).join(", ")}` : ""}${c.presentationOnly ? " (wording only)" : ""}${c.breaking ? " BREAKING" : ""} · ${at(c.old)} → ${at(c.new)}`);
|
|
137
|
+
const s = report.diff.summary;
|
|
138
|
+
console.log(`diff: ${s.added} added, ${s.removed} removed, ${s.changed} changed (${s.presentationOnly} wording only, ${s.breaking} breaking); requirements ${s.requirements.added}/${s.requirements.removed}/${s.requirements.changed}; ${report.diff.examples.length} example changes`);
|
|
139
|
+
};
|
|
140
|
+
const printImpact = (report) => {
|
|
141
|
+
const impact = report.impact;
|
|
142
|
+
if (!impact)
|
|
143
|
+
return;
|
|
144
|
+
console.log(`impact at ${impact.at}: ${impact.affected.components.length} affected components (${impact.affected.components.join(", ") || "none"})${impact.affected.accounts.length ? `; accounts ${impact.affected.accounts.join(", ")}` : ""}`);
|
|
145
|
+
for (const c of impact.occurrences.changes) {
|
|
146
|
+
const s = (c.after ?? c.before);
|
|
147
|
+
console.log(`${c.change} ${s.component}/${s.requirement} ${s.occurrence}: ${c.before ? `${c.before.status} due ${c.before.due ?? "unknown"}` : "absent"} → ${c.after ? `${c.after.status} due ${c.after.due ?? "unknown"}` : "absent"}`);
|
|
148
|
+
}
|
|
149
|
+
for (const c of impact.work.changes)
|
|
150
|
+
console.log(`work ${c.change} ${(c.after ?? c.before).key}: ${c.before?.state ?? "absent"} → ${c.after?.state ?? "absent"}`);
|
|
151
|
+
console.log(`subjects: ${impact.subjects.changed} changed of ${impact.subjects.considered} considered (${impact.subjects.total} total); occurrences ${impact.occurrences.changes.length} changed of ${impact.occurrences.considered} considered (${impact.occurrences.total} total); work ${impact.work.before} → ${impact.work.after}`);
|
|
152
|
+
for (const [label, subjects] of Object.entries(impact.samples))
|
|
153
|
+
if (subjects.length)
|
|
154
|
+
console.log(` ${label}: ${subjects.join(", ")}`);
|
|
155
|
+
};
|
|
156
|
+
export const main = async () => {
|
|
157
|
+
let json = process.argv.includes("--json");
|
|
158
|
+
let help = usage;
|
|
159
|
+
try {
|
|
160
|
+
const { values, positionals } = parseArgs({
|
|
161
|
+
options: {
|
|
162
|
+
out: { type: "string" },
|
|
163
|
+
db: { type: "string" },
|
|
164
|
+
"dry-run": { type: "boolean" },
|
|
165
|
+
port: { type: "string" },
|
|
166
|
+
ui: { type: "boolean" },
|
|
167
|
+
clock: { type: "string" },
|
|
168
|
+
actor: { type: "string" },
|
|
169
|
+
check: { type: "boolean" },
|
|
170
|
+
core: { type: "boolean" },
|
|
171
|
+
json: { type: "boolean" },
|
|
172
|
+
help: { type: "boolean", short: "h" },
|
|
173
|
+
scenario: { type: "string" },
|
|
174
|
+
seed: { type: "string" },
|
|
175
|
+
cases: { type: "string" },
|
|
176
|
+
format: { type: "string" },
|
|
177
|
+
account: { type: "string" },
|
|
178
|
+
world: { type: "string" },
|
|
179
|
+
subject: { type: "string" },
|
|
180
|
+
at: { type: "string" },
|
|
181
|
+
list: { type: "boolean" },
|
|
182
|
+
mutate: { type: "boolean" },
|
|
183
|
+
},
|
|
184
|
+
allowPositionals: true,
|
|
185
|
+
strict: true,
|
|
186
|
+
});
|
|
187
|
+
json = values.json ?? false;
|
|
188
|
+
const command = positionals[0];
|
|
189
|
+
if (command !== undefined && Object.hasOwn(HELP, command))
|
|
190
|
+
help = HELP[command];
|
|
191
|
+
if (values.help) {
|
|
192
|
+
console.log(help);
|
|
193
|
+
return 0;
|
|
194
|
+
}
|
|
195
|
+
if (command === "deploy") {
|
|
196
|
+
if (positionals.length !== 2 ||
|
|
197
|
+
!values.db ||
|
|
198
|
+
!values.account ||
|
|
199
|
+
Object.keys(values).some((k) => !["db", "account", "at", "dry-run", "json"].includes(k)))
|
|
200
|
+
throw new Error(HELP.deploy);
|
|
201
|
+
const report = await deployDirectory(positionals[1], {
|
|
202
|
+
db: values.db,
|
|
203
|
+
account: values.account,
|
|
204
|
+
...(values.at ? { at: values.at } : {}),
|
|
205
|
+
...(values["dry-run"] ? { dryRun: true } : {}),
|
|
206
|
+
});
|
|
207
|
+
if (json)
|
|
208
|
+
console.log(JSON.stringify(report, null, 2));
|
|
209
|
+
else {
|
|
210
|
+
report.diagnostics.forEach((d) => display(report.directory, d));
|
|
211
|
+
if (report.ok) {
|
|
212
|
+
console.log(`${report.dryRun ? "preview" : "deployed"}: ${report.old ?? "none"} → ${report.new}`);
|
|
213
|
+
printImpact(report);
|
|
214
|
+
console.log(`subjects changed: ${report.subjects.join(", ") || "none"}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return report.ok ? 0 : 1;
|
|
218
|
+
}
|
|
219
|
+
if (values["dry-run"] !== undefined)
|
|
220
|
+
throw new Error("--dry-run requires deploy.");
|
|
221
|
+
if (command === "snapshot") {
|
|
222
|
+
if (positionals.length !== 1 ||
|
|
223
|
+
!values.db ||
|
|
224
|
+
!values.account ||
|
|
225
|
+
Object.keys(values).some((k) => !["db", "account", "out"].includes(k)))
|
|
226
|
+
throw new Error(HELP.snapshot);
|
|
227
|
+
if (values.out && resolve(values.out) === resolve(values.db))
|
|
228
|
+
throw new Error("--out must differ from --db.");
|
|
229
|
+
const snapshot = await snapshotDatabase(values.db, values.account);
|
|
230
|
+
const output = `${JSON.stringify(snapshot, null, 2)}\n`;
|
|
231
|
+
if (values.out)
|
|
232
|
+
await writeFile(values.out, output);
|
|
233
|
+
else
|
|
234
|
+
process.stdout.write(output);
|
|
235
|
+
return 0;
|
|
236
|
+
}
|
|
237
|
+
if (command === "serve") {
|
|
238
|
+
if ((positionals.length !== 1 && positionals.length !== 2) ||
|
|
239
|
+
!values.db ||
|
|
240
|
+
Object.keys(values).some((k) => !["db", "port", "clock", "ui"].includes(k)))
|
|
241
|
+
throw new Error(HELP.serve);
|
|
242
|
+
const port = values.port === undefined ? 3000 : Number(values.port);
|
|
243
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535)
|
|
244
|
+
throw new Error("--port must be an integer from 0 to 65535.");
|
|
245
|
+
if (values.clock && !Number.isFinite(Date.parse(values.clock)))
|
|
246
|
+
throw new Error("--clock must be an ISO instant.");
|
|
247
|
+
const fixed = values.clock;
|
|
248
|
+
const running = await serve({
|
|
249
|
+
...(positionals[1] ? { source: positionals[1] } : {}),
|
|
250
|
+
db: values.db,
|
|
251
|
+
port,
|
|
252
|
+
...(values.ui ? { ui: true } : {}),
|
|
253
|
+
...(fixed ? { clock: () => fixed } : {}),
|
|
254
|
+
});
|
|
255
|
+
console.error(`WorldVM listening on http://127.0.0.1:${running.server.address().port}; trusted identity header is dev-only.`);
|
|
256
|
+
await new Promise((resolve) => {
|
|
257
|
+
const stop = () => {
|
|
258
|
+
process.removeListener("SIGINT", stop);
|
|
259
|
+
process.removeListener("SIGTERM", stop);
|
|
260
|
+
resolve();
|
|
261
|
+
};
|
|
262
|
+
process.once("SIGINT", stop);
|
|
263
|
+
process.once("SIGTERM", stop);
|
|
264
|
+
});
|
|
265
|
+
await running.close();
|
|
266
|
+
return 0;
|
|
267
|
+
}
|
|
268
|
+
if (command === "mcp") {
|
|
269
|
+
if (positionals.length !== 1 ||
|
|
270
|
+
Object.keys(values).some((k) => !["world", "db", "actor"].includes(k)))
|
|
271
|
+
throw new Error(HELP.mcp);
|
|
272
|
+
if (!Object.keys(values).length) {
|
|
273
|
+
await serveStdio();
|
|
274
|
+
return 0;
|
|
275
|
+
}
|
|
276
|
+
if (!values.db || !values.actor)
|
|
277
|
+
throw new Error(HELP.mcp);
|
|
278
|
+
const actor = decodeActor(JSON.parse(values.actor));
|
|
279
|
+
const world = await open({
|
|
280
|
+
...(values.world ? { source: values.world } : {}),
|
|
281
|
+
store: sqlite(values.db),
|
|
282
|
+
});
|
|
283
|
+
const stopTicks = scheduleTicks(world);
|
|
284
|
+
try {
|
|
285
|
+
await serveStdio(process.stdin, process.stdout, { world, actor });
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
stopTicks();
|
|
289
|
+
await world.close();
|
|
290
|
+
}
|
|
291
|
+
return 0;
|
|
292
|
+
}
|
|
293
|
+
if (values.ui !== undefined)
|
|
294
|
+
throw new Error("--ui requires serve.");
|
|
295
|
+
if (values.db !== undefined ||
|
|
296
|
+
values.port !== undefined ||
|
|
297
|
+
values.clock !== undefined ||
|
|
298
|
+
values.actor !== undefined)
|
|
299
|
+
throw new Error("--db requires deploy, serve, snapshot or mcp; --port/--clock/--actor require serve or mcp.");
|
|
300
|
+
if (values.core !== undefined && command !== "check")
|
|
301
|
+
throw new Error("--core requires check.");
|
|
302
|
+
if (values.check !== undefined && command !== "fmt")
|
|
303
|
+
throw new Error("--check requires fmt.");
|
|
304
|
+
if (command === "fmt") {
|
|
305
|
+
if (positionals.length < 2 || Object.keys(values).some((k) => !["json", "check"].includes(k)))
|
|
306
|
+
throw new Error(HELP.fmt);
|
|
307
|
+
const report = await formatPaths(positionals.slice(1), values.check ?? false);
|
|
308
|
+
if (json)
|
|
309
|
+
console.log(JSON.stringify(report, null, 2));
|
|
310
|
+
else
|
|
311
|
+
for (const file of report.files)
|
|
312
|
+
if (file.changed)
|
|
313
|
+
console.log(`${values.check ? "unformatted" : "formatted"} ${file.path}`);
|
|
314
|
+
return report.ok ? 0 : 1;
|
|
315
|
+
}
|
|
316
|
+
if (command === "lsp") {
|
|
317
|
+
if (positionals.length !== 1 || Object.keys(values).length)
|
|
318
|
+
throw new Error("lsp takes no arguments.");
|
|
319
|
+
await serveLsp();
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
if (values.list !== undefined && command !== "explain")
|
|
323
|
+
throw new Error("--list requires the explain command.");
|
|
324
|
+
if (values.mutate !== undefined && command !== "coverage")
|
|
325
|
+
throw new Error("--mutate requires the coverage command.");
|
|
326
|
+
if (command === "explain" && (values.list || (positionals[1] && isCode(positionals[1])))) {
|
|
327
|
+
if (values.list) {
|
|
328
|
+
if (json)
|
|
329
|
+
console.log(JSON.stringify({ format: "worldvm/explain-code@1", codes: CATALOGUE }, null, 2));
|
|
330
|
+
else
|
|
331
|
+
for (const code of Object.keys(CATALOGUE).sort())
|
|
332
|
+
console.log(`${code} ${CATALOGUE[code].title}`);
|
|
333
|
+
return 0;
|
|
334
|
+
}
|
|
335
|
+
if (positionals.length !== 2)
|
|
336
|
+
throw new Error("Expected one diagnostic code.");
|
|
337
|
+
const code = positionals[1], entry = catalogueEntry(code);
|
|
338
|
+
if (!entry) {
|
|
339
|
+
const message = `No catalogue entry for ${code}; its diagnostic help is the best guide. List codes with worldvm explain --list.`;
|
|
340
|
+
if (json)
|
|
341
|
+
console.log(JSON.stringify({ format: "worldvm/explain-code@1", code, ok: false, message }, null, 2));
|
|
342
|
+
else
|
|
343
|
+
console.error(message);
|
|
344
|
+
return 1;
|
|
345
|
+
}
|
|
346
|
+
if (json)
|
|
347
|
+
console.log(JSON.stringify({
|
|
348
|
+
format: "worldvm/explain-code@1",
|
|
349
|
+
code,
|
|
350
|
+
ok: true,
|
|
351
|
+
...(DIAGNOSTIC_RENAMES[code] ? { renamedTo: DIAGNOSTIC_RENAMES[code] } : {}),
|
|
352
|
+
...entry,
|
|
353
|
+
}, null, 2));
|
|
354
|
+
else
|
|
355
|
+
console.log(explain(code));
|
|
356
|
+
return 0;
|
|
357
|
+
}
|
|
358
|
+
if (values.out !== undefined && command !== "codegen")
|
|
359
|
+
throw new Error("--out requires codegen.");
|
|
360
|
+
if (command === "codegen") {
|
|
361
|
+
if (positionals.length !== 2 || Object.keys(values).some((k) => k !== "out"))
|
|
362
|
+
throw new Error("Expected worldvm codegen <directory> [--out file].");
|
|
363
|
+
const module = await codegenDirectory(positionals[1]);
|
|
364
|
+
if (values.out)
|
|
365
|
+
await writeFile(values.out, module);
|
|
366
|
+
else
|
|
367
|
+
process.stdout.write(module);
|
|
368
|
+
return 0;
|
|
369
|
+
}
|
|
370
|
+
if (command === "init") {
|
|
371
|
+
if (positionals.length !== 2)
|
|
372
|
+
throw new Error("Expected worldvm init <directory>.");
|
|
373
|
+
const directory = positionals[1];
|
|
374
|
+
const result = await initWorld(directory);
|
|
375
|
+
if (json)
|
|
376
|
+
console.log(JSON.stringify({ format: "worldvm/init@1", ok: true, ...result }, null, 2));
|
|
377
|
+
else {
|
|
378
|
+
for (const file of result.files)
|
|
379
|
+
console.log(`created ${file}`);
|
|
380
|
+
console.log(`\nNext: worldvm check ${directory} && worldvm test ${directory} && worldvm coverage ${directory}`);
|
|
381
|
+
}
|
|
382
|
+
return 0;
|
|
383
|
+
}
|
|
384
|
+
if (positionals[0] === "impact") {
|
|
385
|
+
if (positionals.length !== 3)
|
|
386
|
+
throw new Error("impact needs an old and a new source directory.");
|
|
387
|
+
if (Object.keys(values).some((k) => !["json", "world", "at"].includes(k)))
|
|
388
|
+
throw new Error("impact accepts --world, --at and --json.");
|
|
389
|
+
if (values.world === undefined || values.at === undefined)
|
|
390
|
+
throw new Error("impact needs --world snapshot.json and --at instant.");
|
|
391
|
+
const report = await impactDirectories(positionals[1], positionals[2], {
|
|
392
|
+
world: values.world,
|
|
393
|
+
at: values.at,
|
|
394
|
+
});
|
|
395
|
+
if (json)
|
|
396
|
+
console.log(JSON.stringify(report, null, 2));
|
|
397
|
+
else {
|
|
398
|
+
report.diagnostics.forEach((d) => display("side" in d && d.side === "new" ? report.new : report.old, d));
|
|
399
|
+
printImpact(report);
|
|
400
|
+
}
|
|
401
|
+
return report.ok ? 0 : 1;
|
|
402
|
+
}
|
|
403
|
+
if (positionals[0] === "diff") {
|
|
404
|
+
if (positionals.length !== 3)
|
|
405
|
+
throw new Error("diff needs an old and a new source directory.");
|
|
406
|
+
if (Object.keys(values).some((k) => k !== "json"))
|
|
407
|
+
throw new Error("diff accepts only --json.");
|
|
408
|
+
const report = await diffDirectories(positionals[1], positionals[2]);
|
|
409
|
+
if (json)
|
|
410
|
+
console.log(JSON.stringify(report, null, 2));
|
|
411
|
+
else {
|
|
412
|
+
report.diagnostics.forEach((d) => display(d.side === "old" ? report.old : report.new, d));
|
|
413
|
+
printDiff(report);
|
|
414
|
+
}
|
|
415
|
+
return report.ok ? 0 : 1;
|
|
416
|
+
}
|
|
417
|
+
if (positionals.length !== 2 ||
|
|
418
|
+
!["check", "test", "coverage", "render", "explain"].includes(positionals[0]))
|
|
419
|
+
throw new Error("Expected init/check/test/coverage/render/explain/diff/impact/mcp and a source directory.");
|
|
420
|
+
if (positionals[0] !== "explain" &&
|
|
421
|
+
positionals[0] !== "impact" &&
|
|
422
|
+
(values.world !== undefined || values.subject !== undefined || values.at !== undefined))
|
|
423
|
+
throw new Error("--world, --subject and --at require the explain command.");
|
|
424
|
+
if (positionals[0] === "explain") {
|
|
425
|
+
if (values.seed !== undefined ||
|
|
426
|
+
values.cases !== undefined ||
|
|
427
|
+
values.format !== undefined ||
|
|
428
|
+
values.account !== undefined)
|
|
429
|
+
throw new Error("explain accepts --scenario, --world, --subject and --at.");
|
|
430
|
+
const report = await explainDirectory(positionals[1], {
|
|
431
|
+
...(values.scenario === undefined ? {} : { scenario: values.scenario }),
|
|
432
|
+
...(values.world === undefined ? {} : { world: values.world }),
|
|
433
|
+
...(values.subject === undefined ? {} : { subject: values.subject }),
|
|
434
|
+
...(values.at === undefined ? {} : { at: values.at }),
|
|
435
|
+
});
|
|
436
|
+
if (json)
|
|
437
|
+
console.log(JSON.stringify(report, null, 2));
|
|
438
|
+
else {
|
|
439
|
+
report.diagnostics
|
|
440
|
+
.filter((d) => d.severity === "error")
|
|
441
|
+
.forEach((d) => display(report.directory, d));
|
|
442
|
+
if (report.ok)
|
|
443
|
+
printExplanation(report);
|
|
444
|
+
}
|
|
445
|
+
return report.ok ? 0 : 1;
|
|
446
|
+
}
|
|
447
|
+
if (positionals[0] !== "render" &&
|
|
448
|
+
(values.format !== undefined || values.account !== undefined))
|
|
449
|
+
throw new Error("--format and --account require the render command.");
|
|
450
|
+
if (positionals[0] === "render") {
|
|
451
|
+
if (values.scenario !== undefined || values.seed !== undefined || values.cases !== undefined)
|
|
452
|
+
throw new Error("Test options require the test command.");
|
|
453
|
+
const format = values.format ?? "markdown";
|
|
454
|
+
if (format !== "markdown" && format !== "html")
|
|
455
|
+
throw new Error("--format must be markdown or html.");
|
|
456
|
+
const report = await renderDirectory(positionals[1], {
|
|
457
|
+
format,
|
|
458
|
+
...(values.account === undefined ? {} : { account: values.account }),
|
|
459
|
+
});
|
|
460
|
+
if (json)
|
|
461
|
+
console.log(JSON.stringify(report, null, 2));
|
|
462
|
+
else {
|
|
463
|
+
report.diagnostics
|
|
464
|
+
.filter((d) => d.severity === "error")
|
|
465
|
+
.forEach((d) => display(report.directory, d));
|
|
466
|
+
if (report.document !== null)
|
|
467
|
+
process.stdout.write(report.document);
|
|
468
|
+
}
|
|
469
|
+
return report.ok ? 0 : 1;
|
|
470
|
+
}
|
|
471
|
+
if (positionals[0] === "coverage") {
|
|
472
|
+
if (values.scenario !== undefined)
|
|
473
|
+
throw new Error("--scenario requires the test command.");
|
|
474
|
+
const report = await coverageDirectory(positionals[1], {
|
|
475
|
+
seed: values.seed === undefined ? 0 : Number(values.seed),
|
|
476
|
+
cases: values.cases === undefined ? 100 : Number(values.cases),
|
|
477
|
+
mutate: values.mutate ?? false,
|
|
478
|
+
});
|
|
479
|
+
if (json)
|
|
480
|
+
console.log(JSON.stringify(report, null, 2));
|
|
481
|
+
else {
|
|
482
|
+
report.diagnostics.forEach((d) => display(report.directory, d));
|
|
483
|
+
for (const row of report.definitions)
|
|
484
|
+
console.log(`${row.key}: ${row.references.length ? row.references.map((r) => `${r.kind} ${r.name}`).join(", ") : "unreferenced"}`);
|
|
485
|
+
for (const row of report.branchCoverage?.requirements ?? [])
|
|
486
|
+
console.log(`${row.key}: ${row.observations} observed; applicability ${row.applicability.seen.join(", ") || "none"}; statuses ${row.statuses.seen.join(", ") || "none"}; due branches ${row.due?.branches.map((b) => `${b.seen.length}/${b.expected.length}`).join(", ") || "none"}`);
|
|
487
|
+
for (const property of report.branchCoverage?.tests.properties ?? [])
|
|
488
|
+
for (const [index, antecedent] of property.antecedents.entries())
|
|
489
|
+
console.log(`${property.name} implies ${index + 1}: antecedent true in ${antecedent.cases}/${property.cases} cases`);
|
|
490
|
+
for (const m of report.mutation?.mutants ?? [])
|
|
491
|
+
if (m.outcome === "survived")
|
|
492
|
+
console.log(`gap: mutant ${m.id} survived (${m.operator}, ${m.requirement}) at ${m.at.src}:${m.at.line}:${m.at.col}: ${m.description}`);
|
|
493
|
+
if (report.mutation)
|
|
494
|
+
console.log(`mutation: ${report.mutation.killed} killed, ${report.mutation.survived} survived, ${report.mutation.invalid} invalid`);
|
|
495
|
+
console.log(`coverage references: ${report.totals.requirementsReferenced}/${report.totals.requirements} requirements, ${report.totals.clausesReferenced}/${report.totals.clauses} cited clauses; ${report.ok ? "tests passed" : "tests failed"}`);
|
|
496
|
+
}
|
|
497
|
+
return report.ok ? 0 : 1;
|
|
498
|
+
}
|
|
499
|
+
if (positionals[0] === "check") {
|
|
500
|
+
if (values.scenario !== undefined || values.seed !== undefined || values.cases !== undefined)
|
|
501
|
+
throw new Error("Test options require the test command.");
|
|
502
|
+
const report = await checkDirectory(positionals[1], { core: values.core ?? false });
|
|
503
|
+
if (json)
|
|
504
|
+
console.log(JSON.stringify(report, null, 2));
|
|
505
|
+
else {
|
|
506
|
+
report.diagnostics.forEach((d) => display(report.directory, d));
|
|
507
|
+
console.log(`check: ${report.ok ? "passed" : "failed"}; ${report.files.length} source files${report.statistics ? `, ${report.statistics.requirements} requirements` : ""}`);
|
|
508
|
+
}
|
|
509
|
+
return report.ok ? 0 : 1;
|
|
510
|
+
}
|
|
511
|
+
const report = await testDirectory(positionals[1], {
|
|
512
|
+
seed: values.seed === undefined ? 0 : Number(values.seed),
|
|
513
|
+
cases: values.cases === undefined ? 100 : Number(values.cases),
|
|
514
|
+
...(values.scenario === undefined ? {} : { scenario: values.scenario }),
|
|
515
|
+
});
|
|
516
|
+
if (json)
|
|
517
|
+
console.log(JSON.stringify(report, null, 2));
|
|
518
|
+
else {
|
|
519
|
+
report.diagnostics.forEach((d) => display(report.directory, d));
|
|
520
|
+
for (const scenario of report.scenarios) {
|
|
521
|
+
console.log(`${scenario.passed ? "PASS" : "FAIL"} scenario ${scenario.name} (${scenario.assertions} assertions)`);
|
|
522
|
+
scenario.failures.forEach((f) => display(report.directory, f));
|
|
523
|
+
}
|
|
524
|
+
for (const property of report.properties) {
|
|
525
|
+
console.log(`${property.passed ? "PASS" : "FAIL"} property ${property.name} (seed ${property.seed}, ${property.cases} cases, ${property.checks} checks)`);
|
|
526
|
+
for (const [index, antecedent] of property.antecedents.entries())
|
|
527
|
+
console.log(` implies ${index + 1}: antecedent true in ${antecedent.cases}/${property.cases} cases`);
|
|
528
|
+
if (property.failure) {
|
|
529
|
+
display(report.directory, property.failure);
|
|
530
|
+
console.error(property.failure.counterexample.source);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
console.log(`test: ${report.ok ? "passed" : "failed"}; ${report.scenarios.length} scenarios, ${report.properties.length} properties`);
|
|
534
|
+
}
|
|
535
|
+
return report.ok ? 0 : 1;
|
|
536
|
+
}
|
|
537
|
+
catch (cause) {
|
|
538
|
+
const d = {
|
|
539
|
+
code: "E_USAGE",
|
|
540
|
+
severity: "error",
|
|
541
|
+
message: String(cause),
|
|
542
|
+
at: null,
|
|
543
|
+
help,
|
|
544
|
+
fix: null,
|
|
545
|
+
};
|
|
546
|
+
if (json)
|
|
547
|
+
console.log(JSON.stringify({ format: "worldvm/error@1", ok: false, diagnostics: [d] }, null, 2));
|
|
548
|
+
else
|
|
549
|
+
console.error(`${d.message}\n${help}`);
|
|
550
|
+
return 2;
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
export * from "./index.js";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IR } from "./_internal/reconciler/index.js";
|
|
2
|
+
/** Translate IR types to the values accepted by the embedding API. */
|
|
3
|
+
export declare const typescriptType: (type: IR.TypeRef, aliases: readonly IR.TypeAlias[], seen?: ReadonlySet<string>) => string;
|
|
4
|
+
/** A declaration-only module: safe as either .ts or .d.ts, without runtime imports. */
|
|
5
|
+
export declare const generateTypes: (ir: IR.WorldIR) => string;
|
|
6
|
+
export declare const codegenDirectory: (directory: string) => Promise<string>;
|
package/dist/codegen.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { loadProject } from "./project.js";
|
|
2
|
+
import { WorldError } from "./handle/world.js";
|
|
3
|
+
/** Translate IR types to the values accepted by the embedding API. */
|
|
4
|
+
export const typescriptType = (type, aliases, seen = new Set()) => {
|
|
5
|
+
const next = (t) => typescriptType(t, aliases, seen);
|
|
6
|
+
if (typeof type === "string") {
|
|
7
|
+
if (type.startsWith(":"))
|
|
8
|
+
return JSON.stringify(type.slice(1));
|
|
9
|
+
const alias = aliases.find((a) => a.name === type);
|
|
10
|
+
if (alias) {
|
|
11
|
+
if (seen.has(type))
|
|
12
|
+
throw new WorldError("E_CODEGEN_TYPE", `Recursive type alias ${type}.`);
|
|
13
|
+
return typescriptType(alias.type, aliases, new Set([...seen, type]));
|
|
14
|
+
}
|
|
15
|
+
if (["String", "Keyword", "Group", "Date", "Instant", "File"].includes(type))
|
|
16
|
+
return "string";
|
|
17
|
+
if (["Int", "Float"].includes(type))
|
|
18
|
+
return "number";
|
|
19
|
+
if (type === "Bool")
|
|
20
|
+
return "boolean";
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const [head, ...args] = type;
|
|
24
|
+
if (head === "Id")
|
|
25
|
+
return "string";
|
|
26
|
+
if (head === "Union")
|
|
27
|
+
return args.map(next).join(" | ") || "never";
|
|
28
|
+
if (head === "Option")
|
|
29
|
+
return `(${next(args[0])}) | null`;
|
|
30
|
+
if (head === "Brand")
|
|
31
|
+
return next(args[0]);
|
|
32
|
+
if (head === "Sensitive")
|
|
33
|
+
return next(args[1]);
|
|
34
|
+
if (head === "List" || head === "Set" || head === "Vec")
|
|
35
|
+
return `ReadonlyArray<${next(args[0])}>`;
|
|
36
|
+
}
|
|
37
|
+
// Never silently widen a new IR form to any/string; that would hide misspellings.
|
|
38
|
+
throw new WorldError("E_CODEGEN_TYPE", `Unsupported TypeRef ${JSON.stringify(type)}.`);
|
|
39
|
+
};
|
|
40
|
+
/** A declaration-only module: safe as either .ts or .d.ts, without runtime imports. */
|
|
41
|
+
export const generateTypes = (ir) => {
|
|
42
|
+
const field = (f) => `readonly ${JSON.stringify(f.name)}: ${typescriptType(f.type, ir.types)};`;
|
|
43
|
+
const shape = (fields) => `{ ${fields.map(field).join(" ")} }`;
|
|
44
|
+
const operations = new Map();
|
|
45
|
+
const add = (name, input) => {
|
|
46
|
+
if (!operations.has(name))
|
|
47
|
+
operations.set(name, new Set());
|
|
48
|
+
operations.get(name).add(input);
|
|
49
|
+
};
|
|
50
|
+
for (const component of ir.components) {
|
|
51
|
+
const contracts = (ir.componentContracts ?? []).filter((c) => c.component === component.name);
|
|
52
|
+
const publicNames = component.operations ??
|
|
53
|
+
(contracts.length
|
|
54
|
+
? contracts.flatMap((c) => c.operations.map((o) => o.name))
|
|
55
|
+
: [
|
|
56
|
+
...component.actions.map((a) => a.name),
|
|
57
|
+
...(ir.decisions ?? []).filter((d) => d.of === component.name).map((d) => d.name),
|
|
58
|
+
]);
|
|
59
|
+
for (const action of component.actions) {
|
|
60
|
+
if (!publicNames.includes(action.name))
|
|
61
|
+
continue;
|
|
62
|
+
const via = action.via;
|
|
63
|
+
const evidence = via.kind === "interaction"
|
|
64
|
+
? ir.evidence.find((e) => e.name === ir.interactions.find((i) => i.name === via.name)?.produces)
|
|
65
|
+
: undefined;
|
|
66
|
+
add(action.name, evidence?.fields.length
|
|
67
|
+
? `{ readonly unsigned?: false; readonly values: ${shape(evidence.fields)}; readonly reason?: never } | { readonly unsigned: true; readonly values?: Partial<${shape(evidence.fields)}>; readonly reason?: never }`
|
|
68
|
+
: "{ readonly values?: never; readonly reason?: never }");
|
|
69
|
+
}
|
|
70
|
+
for (const decision of (ir.decisions ?? []).filter((d) => d.of === component.name))
|
|
71
|
+
if (publicNames.includes(decision.name)) {
|
|
72
|
+
const reason = typescriptType(decision.reason, ir.types);
|
|
73
|
+
add(decision.name, `{ readonly reason${reason.includes(" | null") ? "?" : ""}: ${reason}; readonly values?: never }`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const entries = (rows) => rows.map(([name, value]) => ` readonly ${JSON.stringify(name)}: ${value};`).join("\n");
|
|
77
|
+
return (`// Generated by worldvm codegen. Regenerate after changing the world.\n` +
|
|
78
|
+
`export interface Entities {\n${entries(ir.entities.map((e) => [e.name, shape(e.fields)]))}\n}\n` +
|
|
79
|
+
`export interface Evidence {\n${entries(ir.evidence.map((e) => [e.name, shape(e.fields)]))}\n}\n` +
|
|
80
|
+
`export interface Operations {\n${entries([...operations].sort(([a], [b]) => a.localeCompare(b)).map(([name, inputs]) => [name, [...inputs].join(" | ")]))}\n}\n` +
|
|
81
|
+
`export interface WorldTypes { readonly entities: Entities; readonly operations: Operations }\n`);
|
|
82
|
+
};
|
|
83
|
+
export const codegenDirectory = async (directory) => {
|
|
84
|
+
const project = await loadProject(directory);
|
|
85
|
+
const errors = project.diagnostics.filter((d) => d.severity === "error");
|
|
86
|
+
if (!project.ir || errors.length)
|
|
87
|
+
throw new WorldError("E_CHECK", "Cannot generate types for an invalid world.", errors);
|
|
88
|
+
return generateTypes(project.ir);
|
|
89
|
+
};
|