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
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { SourceFile, Span, WorldIR } from "../_internal/forma/world/index.js";
|
|
2
|
+
import { type CitationView } from "./projections.js";
|
|
3
|
+
/** Located prose: every rendered claim keeps the source span it was derived from. */
|
|
4
|
+
export interface ManualRow {
|
|
5
|
+
readonly label: string;
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly fallbacks: readonly {
|
|
8
|
+
readonly text: string;
|
|
9
|
+
readonly at: Span;
|
|
10
|
+
}[];
|
|
11
|
+
readonly notes: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
export interface ManualExample {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly doc: string;
|
|
16
|
+
readonly at: Span;
|
|
17
|
+
readonly firstObservation: string | null;
|
|
18
|
+
readonly assertions: readonly {
|
|
19
|
+
readonly text: string;
|
|
20
|
+
readonly at: Span;
|
|
21
|
+
}[];
|
|
22
|
+
readonly referenceOnly: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface ManualEntry {
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly kind: string;
|
|
27
|
+
readonly component: string;
|
|
28
|
+
readonly componentTitle: string;
|
|
29
|
+
readonly title: string;
|
|
30
|
+
readonly at: Span;
|
|
31
|
+
readonly rows: readonly ManualRow[];
|
|
32
|
+
readonly citations: readonly CitationView[];
|
|
33
|
+
readonly examples: readonly ManualExample[];
|
|
34
|
+
}
|
|
35
|
+
export interface ManualAccount {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly doc: string;
|
|
38
|
+
readonly at: Span;
|
|
39
|
+
readonly requirements: readonly ManualEntry[];
|
|
40
|
+
readonly records: readonly ManualEntry[];
|
|
41
|
+
readonly library: readonly ManualEntry[];
|
|
42
|
+
}
|
|
43
|
+
export interface ManualSource {
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly title: string;
|
|
46
|
+
readonly kind: string;
|
|
47
|
+
readonly jurisdiction: string | null;
|
|
48
|
+
readonly asOf: string;
|
|
49
|
+
readonly url: string;
|
|
50
|
+
readonly doc: string;
|
|
51
|
+
readonly at: Span;
|
|
52
|
+
}
|
|
53
|
+
export interface Manual {
|
|
54
|
+
readonly format: "worldvm/manual@1";
|
|
55
|
+
readonly notice: string;
|
|
56
|
+
readonly accounts: readonly ManualAccount[];
|
|
57
|
+
readonly sources: readonly ManualSource[];
|
|
58
|
+
}
|
|
59
|
+
export interface ManualOptions {
|
|
60
|
+
/** Restrict the manual to one account; all accounts render in declaration order otherwise. */
|
|
61
|
+
readonly account?: string;
|
|
62
|
+
/** Scenario examples shown per entry; the full list stays in source. */
|
|
63
|
+
readonly examplesPerEntry?: number;
|
|
64
|
+
}
|
|
65
|
+
export declare const manualNotice = "Derived from the compiled world. Sources record authored authority; executable examples illustrate behavior. This manual does not certify legal completeness; reference-world data is synthetic and its rules are illustrative, not legal advice.";
|
|
66
|
+
export declare class ManualAccountError extends Error {
|
|
67
|
+
readonly account: string;
|
|
68
|
+
readonly available: readonly string[];
|
|
69
|
+
constructor(account: string, available: readonly string[]);
|
|
70
|
+
}
|
|
71
|
+
/** Projects a compiled world into the manual model shared by the CLI and the World IDE. */
|
|
72
|
+
export declare const buildManual: (ir: WorldIR, files: readonly SourceFile[], options?: ManualOptions) => Manual;
|
|
73
|
+
/** Stable HTML fragment identifier for a manual entry; synthetic ids may contain any character. */
|
|
74
|
+
export declare const manualAnchor: (id: string) => string;
|
|
75
|
+
export declare const renderManualMarkdown: (manual: Manual) => string;
|
|
76
|
+
export declare const renderManualHtml: (manual: Manual) => string;
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { accountComponents } from "./catalog.js";
|
|
2
|
+
import { projectManual, } from "./projections.js";
|
|
3
|
+
import { firstLine, humanize, safeUrl, sourceTitle } from "./text.js";
|
|
4
|
+
export const manualNotice = "Derived from the compiled world. Sources record authored authority; executable examples illustrate behavior. This manual does not certify legal completeness; reference-world data is synthetic and its rules are illustrative, not legal advice.";
|
|
5
|
+
const row = (label, d) => ({
|
|
6
|
+
label,
|
|
7
|
+
text: d.text,
|
|
8
|
+
fallbacks: d.fallbacks.map((f) => ({ text: f.text, at: f.at })),
|
|
9
|
+
notes: [...new Set(d.notes ?? [])],
|
|
10
|
+
});
|
|
11
|
+
const componentTitle = (ir, name) => {
|
|
12
|
+
const doc = ir.components.find((c) => c.name === name)?.doc;
|
|
13
|
+
return doc ? firstLine(doc) : humanize(name);
|
|
14
|
+
};
|
|
15
|
+
const requirementEntry = (ir, r, limit) => ({
|
|
16
|
+
id: r.id,
|
|
17
|
+
kind: "Requirement",
|
|
18
|
+
component: r.component,
|
|
19
|
+
componentTitle: componentTitle(ir, r.component),
|
|
20
|
+
title: r.title,
|
|
21
|
+
at: r.at,
|
|
22
|
+
rows: r.rows.map((x) => row(x.label, x.description)),
|
|
23
|
+
citations: r.citations,
|
|
24
|
+
examples: r.exampleDetails.slice(0, limit).map((e) => {
|
|
25
|
+
const scenario = ir.scenarios?.find((s) => s.name === e.name);
|
|
26
|
+
return {
|
|
27
|
+
name: e.name,
|
|
28
|
+
doc: e.doc,
|
|
29
|
+
at: e.at,
|
|
30
|
+
firstObservation: scenario?.steps[0]?.date ?? null,
|
|
31
|
+
assertions: e.assertions.map((a) => ({ text: a.text, at: a.at })),
|
|
32
|
+
referenceOnly: e.referenceOnly,
|
|
33
|
+
};
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
const recordEntry = (ir, r) => ({
|
|
37
|
+
id: r.id,
|
|
38
|
+
kind: r.kind,
|
|
39
|
+
component: r.component,
|
|
40
|
+
componentTitle: componentTitle(ir, r.component),
|
|
41
|
+
title: r.title,
|
|
42
|
+
at: r.at,
|
|
43
|
+
rows: r.rows.map((x) => row(x.label, x.description)),
|
|
44
|
+
citations: r.citations,
|
|
45
|
+
examples: [],
|
|
46
|
+
});
|
|
47
|
+
export class ManualAccountError extends Error {
|
|
48
|
+
account;
|
|
49
|
+
available;
|
|
50
|
+
constructor(account, available) {
|
|
51
|
+
super(`Unknown account ${account}; declared accounts: ${available.join(", ") || "none"}.`);
|
|
52
|
+
this.account = account;
|
|
53
|
+
this.available = available;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Projects a compiled world into the manual model shared by the CLI and the World IDE. */
|
|
57
|
+
export const buildManual = (ir, files, options = {}) => {
|
|
58
|
+
const limit = options.examplesPerEntry ?? 2;
|
|
59
|
+
const names = ir.accounts.map((a) => a.name);
|
|
60
|
+
if (options.account !== undefined && !names.includes(options.account))
|
|
61
|
+
throw new ManualAccountError(options.account, names);
|
|
62
|
+
const accounts = ir.accounts
|
|
63
|
+
.filter((a) => options.account === undefined || a.name === options.account)
|
|
64
|
+
.map((account) => {
|
|
65
|
+
const data = projectManual(ir, files, account.name), used = accountComponents(ir, account.name);
|
|
66
|
+
return {
|
|
67
|
+
name: account.name,
|
|
68
|
+
doc: account.doc ?? "Declared account obligations.",
|
|
69
|
+
at: account.at,
|
|
70
|
+
requirements: data.used.map((r) => requirementEntry(ir, r, limit)),
|
|
71
|
+
records: data.people.filter((r) => used.has(r.component)).map((r) => recordEntry(ir, r)),
|
|
72
|
+
library: data.examples.map((r) => requirementEntry(ir, r, limit)),
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
format: "worldvm/manual@1",
|
|
77
|
+
notice: manualNotice,
|
|
78
|
+
accounts,
|
|
79
|
+
sources: (ir.references ?? []).map((s) => ({
|
|
80
|
+
name: s.name,
|
|
81
|
+
title: sourceTitle(s),
|
|
82
|
+
kind: s.kind,
|
|
83
|
+
jurisdiction: s.jurisdiction ?? null,
|
|
84
|
+
asOf: s.asOf,
|
|
85
|
+
url: s.url,
|
|
86
|
+
doc: s.doc ?? "",
|
|
87
|
+
at: s.at,
|
|
88
|
+
})),
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
/** Stable HTML fragment identifier for a manual entry; synthetic ids may contain any character. */
|
|
92
|
+
export const manualAnchor = (id) => id.replace(/[^A-Za-z0-9/_-]+/g, "-").replace(/^-+|-+$/g, "") || "entry";
|
|
93
|
+
const where = (at) => `${at.src}:${at.line}:${at.col}`;
|
|
94
|
+
const heading = (account) => `${humanize(account).replace(/^./, (c) => c.toUpperCase())} manual`;
|
|
95
|
+
// Markdown ------------------------------------------------------------------
|
|
96
|
+
/** Escapes characters that would otherwise start Markdown or HTML syntax inside prose. */
|
|
97
|
+
const md = (text) => text.replace(/[\\`*_[\]<>|#]/g, (c) => `\\${c}`).replace(/\n+/g, " ");
|
|
98
|
+
const code = (text) => {
|
|
99
|
+
const flat = text.replace(/\n+/g, " ");
|
|
100
|
+
const fence = flat.includes("`") ? "``" : "`";
|
|
101
|
+
return `${fence}${fence.length > 1 ? " " : ""}${flat}${fence.length > 1 ? " " : ""}${fence}`;
|
|
102
|
+
};
|
|
103
|
+
const citationMd = (c) => {
|
|
104
|
+
const title = c.url ? `[${md(c.title)}](${c.url})` : `**${md(c.title)}**`;
|
|
105
|
+
return `- ${title} ${md(c.clause)} (${md(c.kind)}, as of ${md(c.asOf)})${c.caveat ? ` — ${md(firstLine(c.caveat))}` : ""} · ${code(where(c.at))}`;
|
|
106
|
+
};
|
|
107
|
+
const entryMd = (e, level) => {
|
|
108
|
+
const h = "#".repeat(level);
|
|
109
|
+
const lines = [
|
|
110
|
+
`${h} ${md(e.title)}`,
|
|
111
|
+
"",
|
|
112
|
+
`${md(e.kind)} · ${md(e.componentTitle)} · ${code(e.id)} · ${code(where(e.at))}`,
|
|
113
|
+
"",
|
|
114
|
+
];
|
|
115
|
+
for (const r of e.rows) {
|
|
116
|
+
lines.push(`- **${md(r.label)}:** ${md(r.text)}`);
|
|
117
|
+
for (const note of r.notes)
|
|
118
|
+
lines.push(` - Note: ${md(note)}`);
|
|
119
|
+
for (const f of r.fallbacks)
|
|
120
|
+
lines.push(` - Source expression ${code(f.text)} at ${code(where(f.at))}`);
|
|
121
|
+
}
|
|
122
|
+
if (e.citations.length)
|
|
123
|
+
lines.push("", "Cited sources:", "", ...e.citations.map(citationMd));
|
|
124
|
+
for (const x of e.examples) {
|
|
125
|
+
lines.push("", `Example: ${md(x.doc)} (scenario ${code(x.name)} · ${code(where(x.at))}; first observation ${x.firstObservation ?? "not declared"})`);
|
|
126
|
+
if (x.referenceOnly)
|
|
127
|
+
lines.push("", "- Reachability reference only; no direct status or due assertion.");
|
|
128
|
+
else
|
|
129
|
+
lines.push("", ...x.assertions.map((a) => `- ${code(a.text)}`));
|
|
130
|
+
}
|
|
131
|
+
lines.push("");
|
|
132
|
+
return lines;
|
|
133
|
+
};
|
|
134
|
+
export const renderManualMarkdown = (manual) => {
|
|
135
|
+
const lines = [];
|
|
136
|
+
for (const account of manual.accounts) {
|
|
137
|
+
lines.push(`# ${md(heading(account.name))}`, "", `> ${md(manual.notice)}`, "");
|
|
138
|
+
lines.push(md(account.doc), "", `Account ${code(account.name)} · ${code(where(account.at))}`, "");
|
|
139
|
+
lines.push("## Requirements composed by this account", "");
|
|
140
|
+
if (!account.requirements.length)
|
|
141
|
+
lines.push("No requirements are reachable from this account.", "");
|
|
142
|
+
for (const e of account.requirements)
|
|
143
|
+
lines.push(...entryMd(e, 3));
|
|
144
|
+
lines.push("## Actions, decisions and records", "");
|
|
145
|
+
if (!account.records.length)
|
|
146
|
+
lines.push("No actions, decisions or records are declared.", "");
|
|
147
|
+
for (const e of account.records)
|
|
148
|
+
lines.push(...entryMd(e, 3));
|
|
149
|
+
if (account.library.length) {
|
|
150
|
+
lines.push(`## Library requirements not used by this account (${account.library.length})`, "");
|
|
151
|
+
for (const e of account.library)
|
|
152
|
+
lines.push(...entryMd(e, 3));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
lines.push("# Sources", "");
|
|
156
|
+
if (!manual.sources.length)
|
|
157
|
+
lines.push("No sources are declared.", "");
|
|
158
|
+
for (const s of manual.sources) {
|
|
159
|
+
lines.push(`## ${md(s.title)}`, "", `${md(s.kind)} · ${md(s.jurisdiction ?? "jurisdiction not declared")} · as of ${md(s.asOf)} · ${code(s.name)} · ${code(where(s.at))}`, "");
|
|
160
|
+
if (s.doc)
|
|
161
|
+
lines.push(md(s.doc), "");
|
|
162
|
+
lines.push(safeUrl(s.url) ? `<${s.url}>` : code(s.url), "");
|
|
163
|
+
}
|
|
164
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
165
|
+
};
|
|
166
|
+
// HTML ----------------------------------------------------------------------
|
|
167
|
+
const esc = (text) => text.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
168
|
+
const src = (at) => `<code class="src">${esc(where(at))}</code>`;
|
|
169
|
+
const citationHtml = (c) => {
|
|
170
|
+
const url = c.url ? safeUrl(c.url) : null;
|
|
171
|
+
const title = url
|
|
172
|
+
? `<a href="${esc(url)}" rel="noopener noreferrer">${esc(c.title)}</a>`
|
|
173
|
+
: `<strong>${esc(c.title)}</strong>`;
|
|
174
|
+
return `<li>${title} ${esc(c.clause)} <span class="meta">${esc(c.kind)} · as of ${esc(c.asOf)}</span>${c.caveat ? ` <span class="caveat">${esc(firstLine(c.caveat))}</span>` : ""} ${src(c.at)}</li>`;
|
|
175
|
+
};
|
|
176
|
+
const entryHtml = (e, level) => {
|
|
177
|
+
const parts = [
|
|
178
|
+
`<article class="entry" id="${esc(manualAnchor(e.id))}">`,
|
|
179
|
+
`<p class="eyebrow">${esc(e.kind)} · ${esc(e.componentTitle)}</p>`,
|
|
180
|
+
`<h${level}>${esc(e.title)}</h${level}>`,
|
|
181
|
+
`<p class="meta"><code>${esc(e.id)}</code> ${src(e.at)}</p>`,
|
|
182
|
+
"<dl>",
|
|
183
|
+
];
|
|
184
|
+
for (const r of e.rows) {
|
|
185
|
+
parts.push(`<dt>${esc(r.label)}</dt><dd><p>${esc(r.text)}</p>`);
|
|
186
|
+
for (const note of r.notes)
|
|
187
|
+
parts.push(`<p class="note">${esc(note)}</p>`);
|
|
188
|
+
for (const f of r.fallbacks)
|
|
189
|
+
parts.push(`<p class="fallback">Source expression <code>${esc(f.text)}</code> ${src(f.at)}</p>`);
|
|
190
|
+
parts.push("</dd>");
|
|
191
|
+
}
|
|
192
|
+
parts.push("</dl>");
|
|
193
|
+
if (e.citations.length)
|
|
194
|
+
parts.push(`<h${level + 1}>Cited sources</h${level + 1}><ul class="citations">`, ...e.citations.map(citationHtml), "</ul>");
|
|
195
|
+
for (const x of e.examples) {
|
|
196
|
+
parts.push(`<section class="example"><p><strong>Example: ${esc(x.doc)}</strong> <code>${esc(x.name)}</code> ${src(x.at)} · first observation ${esc(x.firstObservation ?? "not declared")}</p>`);
|
|
197
|
+
if (x.referenceOnly)
|
|
198
|
+
parts.push(`<p class="note">Reachability reference only; no direct status or due assertion.</p>`);
|
|
199
|
+
else
|
|
200
|
+
parts.push("<ul>", ...x.assertions.map((a) => `<li><code>${esc(a.text)}</code></li>`), "</ul>");
|
|
201
|
+
parts.push("</section>");
|
|
202
|
+
}
|
|
203
|
+
parts.push("</article>");
|
|
204
|
+
return parts.join("\n");
|
|
205
|
+
};
|
|
206
|
+
const style = `body{font:16px/1.5 system-ui,sans-serif;max-width:52rem;margin:2rem auto;padding:0 1rem;color:#1b1f24;background:#fff}
|
|
207
|
+
.notice{border-left:4px solid #b26b00;padding:.5rem 1rem;background:#fff7e6}
|
|
208
|
+
.entry{border-top:1px solid #d0d7de;padding:1rem 0}.eyebrow,.meta,.note{color:#57606a;font-size:.875rem}
|
|
209
|
+
dt{font-weight:600}dd{margin:0 0 .5rem 1rem}dd p{margin:.125rem 0}code{font-size:.875em}
|
|
210
|
+
.fallback code{white-space:pre-wrap}.caveat{font-style:italic}.example{background:#f6f8fa;padding:.5rem 1rem;margin:.5rem 0}
|
|
211
|
+
@media print{body{margin:0;max-width:none}.entry{break-inside:avoid}}`;
|
|
212
|
+
export const renderManualHtml = (manual) => {
|
|
213
|
+
const title = manual.accounts.length === 1 ? heading(manual.accounts[0].name) : "World manual";
|
|
214
|
+
const parts = [
|
|
215
|
+
"<!doctype html>",
|
|
216
|
+
'<html lang="en">',
|
|
217
|
+
"<head>",
|
|
218
|
+
'<meta charset="utf-8">',
|
|
219
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1">',
|
|
220
|
+
`<title>${esc(title)}</title>`,
|
|
221
|
+
`<style>${style}</style>`,
|
|
222
|
+
"</head>",
|
|
223
|
+
"<body>",
|
|
224
|
+
`<p class="notice">${esc(manual.notice)}</p>`,
|
|
225
|
+
];
|
|
226
|
+
for (const account of manual.accounts) {
|
|
227
|
+
parts.push(`<section class="account" id="account-${esc(account.name)}">`, `<h1>${esc(heading(account.name))}</h1>`, `<p>${esc(account.doc)}</p>`, `<p class="meta">Account <code>${esc(account.name)}</code> ${src(account.at)}</p>`, "<h2>Requirements composed by this account</h2>");
|
|
228
|
+
if (!account.requirements.length)
|
|
229
|
+
parts.push("<p>No requirements are reachable from this account.</p>");
|
|
230
|
+
parts.push(...account.requirements.map((e) => entryHtml(e, 3)));
|
|
231
|
+
parts.push("<h2>Actions, decisions and records</h2>");
|
|
232
|
+
if (!account.records.length)
|
|
233
|
+
parts.push("<p>No actions, decisions or records are declared.</p>");
|
|
234
|
+
parts.push(...account.records.map((e) => entryHtml(e, 3)));
|
|
235
|
+
if (account.library.length)
|
|
236
|
+
parts.push(`<h2>Library requirements not used by this account (${account.library.length})</h2>`, ...account.library.map((e) => entryHtml(e, 3)));
|
|
237
|
+
parts.push("</section>");
|
|
238
|
+
}
|
|
239
|
+
parts.push('<section class="sources"><h1>Sources</h1>');
|
|
240
|
+
if (!manual.sources.length)
|
|
241
|
+
parts.push("<p>No sources are declared.</p>");
|
|
242
|
+
for (const s of manual.sources) {
|
|
243
|
+
const url = safeUrl(s.url);
|
|
244
|
+
parts.push(`<article class="entry" id="source-${esc(s.name)}"><h2>${esc(s.title)}</h2>`, `<p class="meta">${esc(s.kind)} · ${esc(s.jurisdiction ?? "jurisdiction not declared")} · as of ${esc(s.asOf)} · <code>${esc(s.name)}</code> ${src(s.at)}</p>`, s.doc ? `<p>${esc(s.doc)}</p>` : "", url
|
|
245
|
+
? `<p><a href="${esc(url)}" rel="noopener noreferrer">${esc(url)}</a></p>`
|
|
246
|
+
: `<p><code>${esc(s.url)}</code></p>`, "</article>");
|
|
247
|
+
}
|
|
248
|
+
parts.push("</section>", "</body>", "</html>");
|
|
249
|
+
return `${parts.filter(Boolean).join("\n")}\n`;
|
|
250
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const firstLine: (doc: string) => string;
|
|
2
|
+
export declare const humanize: (name: string) => string;
|
|
3
|
+
export declare const sourceTitle: (source: {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly url: string;
|
|
6
|
+
}) => string;
|
|
7
|
+
export declare const safeUrl: (url: string) => string | null;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const firstLine = (doc) => doc.split(/\r?\n/)[0] ?? doc;
|
|
2
|
+
export const humanize = (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]/g, " ");
|
|
3
|
+
export const sourceTitle = (source) => {
|
|
4
|
+
try {
|
|
5
|
+
const url = new URL(source.url);
|
|
6
|
+
const match = /\/title-(\d+)\/section-([^/]+)/.exec(url.pathname);
|
|
7
|
+
if (/^(?:www\.)?ecfr\.gov$/.test(url.hostname) && match)
|
|
8
|
+
return `${match[1]} CFR ${match[2]}`;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
/* Authored non-URLs retain their source identifier as the label. */
|
|
12
|
+
}
|
|
13
|
+
return humanize(source.name).replace(/^./, (letter) => letter.toUpperCase());
|
|
14
|
+
};
|
|
15
|
+
export const safeUrl = (url) => (/^https?:\/\//i.test(url) ? url : null);
|
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Actor, World } from "./handle/world.js";
|
|
2
|
+
/**
|
|
3
|
+
* Model Context Protocol over newline-delimited JSON-RPC 2.0. Authoring tools return
|
|
4
|
+
* the CLI reports; optional operate mode shares the library/HTTP dispatcher and actor.
|
|
5
|
+
*/
|
|
6
|
+
export declare const serverInfo: {
|
|
7
|
+
readonly name: "worldvm";
|
|
8
|
+
readonly version: "0.0.0";
|
|
9
|
+
};
|
|
10
|
+
export declare const protocolVersions: readonly ["2025-06-18", "2025-03-26", "2024-11-05"];
|
|
11
|
+
type Json = null | boolean | number | string | readonly Json[] | {
|
|
12
|
+
readonly [k: string]: Json;
|
|
13
|
+
};
|
|
14
|
+
interface Tool {
|
|
15
|
+
readonly name: string;
|
|
16
|
+
readonly description: string;
|
|
17
|
+
readonly inputSchema: Json;
|
|
18
|
+
readonly run: (args: Record<string, unknown>) => Promise<{
|
|
19
|
+
readonly ok: boolean;
|
|
20
|
+
}>;
|
|
21
|
+
readonly mutating?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const tools: readonly Tool[];
|
|
24
|
+
/** Handles one JSON-RPC message; returns the response, or null for notifications. */
|
|
25
|
+
export interface OperateOptions {
|
|
26
|
+
readonly world: World;
|
|
27
|
+
readonly actor: Actor;
|
|
28
|
+
}
|
|
29
|
+
export declare const handleMessage: (message: unknown, operating?: OperateOptions) => Promise<unknown>;
|
|
30
|
+
/** Serves MCP over stdin/stdout until stdin closes. Logs never go to stdout. */
|
|
31
|
+
export declare const serveStdio: (input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream, operating?: OperateOptions) => Promise<void>;
|
|
32
|
+
export {};
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { formatForma } from "./_internal/forma-tools/index.js";
|
|
2
|
+
import { createInterface } from "node:readline";
|
|
3
|
+
import { checkDirectory } from "./index.js";
|
|
4
|
+
import { testDirectory } from "./test.js";
|
|
5
|
+
import { coverageDirectory } from "./coverage.js";
|
|
6
|
+
import { renderDirectory } from "./render.js";
|
|
7
|
+
import { explainDirectory } from "./explain.js";
|
|
8
|
+
import { diffDirectories } from "./diff.js";
|
|
9
|
+
import { impactDirectories } from "./impact.js";
|
|
10
|
+
import { mutations, requestJsonSchema, verbs } from "./_internal/protocol/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Model Context Protocol over newline-delimited JSON-RPC 2.0. Authoring tools return
|
|
13
|
+
* the CLI reports; optional operate mode shares the library/HTTP dispatcher and actor.
|
|
14
|
+
*/
|
|
15
|
+
export const serverInfo = { name: "worldvm", version: "0.0.0" };
|
|
16
|
+
export const protocolVersions = ["2025-06-18", "2025-03-26", "2024-11-05"];
|
|
17
|
+
const directory = {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "World source directory (contains .forma files).",
|
|
20
|
+
};
|
|
21
|
+
const seed = { type: "integer", minimum: 0, description: "Property seed (default 0)." };
|
|
22
|
+
const cases = { type: "integer", minimum: 1, description: "Property cases (default 100)." };
|
|
23
|
+
const instant = { type: "string", description: "Instant as YYYY-MM-DD or YYYY-MM-DDTHH:MM." };
|
|
24
|
+
const object = (properties, required) => ({
|
|
25
|
+
type: "object",
|
|
26
|
+
properties,
|
|
27
|
+
required,
|
|
28
|
+
additionalProperties: false,
|
|
29
|
+
});
|
|
30
|
+
const str = (args, key) => {
|
|
31
|
+
const v = args[key];
|
|
32
|
+
if (typeof v !== "string" || !v)
|
|
33
|
+
throw new ToolInputError(`${key} must be a non-empty string.`);
|
|
34
|
+
return v;
|
|
35
|
+
};
|
|
36
|
+
const opt = (args, key, kind) => {
|
|
37
|
+
const v = args[key];
|
|
38
|
+
if (v === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (typeof v !== kind || (kind === "number" && !Number.isInteger(v)))
|
|
41
|
+
throw new ToolInputError(`${key} must be ${kind === "number" ? "an integer" : "a string"}.`);
|
|
42
|
+
return v;
|
|
43
|
+
};
|
|
44
|
+
class ToolInputError extends Error {
|
|
45
|
+
}
|
|
46
|
+
const pick = (value) => Object.fromEntries(Object.entries(value).filter(([, v]) => v !== undefined));
|
|
47
|
+
export const tools = [
|
|
48
|
+
{
|
|
49
|
+
name: "check",
|
|
50
|
+
description: "Compile and link a world. Returns located diagnostics with help and machine-applicable fixes.",
|
|
51
|
+
inputSchema: object({
|
|
52
|
+
directory,
|
|
53
|
+
core: {
|
|
54
|
+
type: "boolean",
|
|
55
|
+
description: "Also report I_EXTENDED_FORM at declarations outside the core forms.",
|
|
56
|
+
},
|
|
57
|
+
}, ["directory"]),
|
|
58
|
+
run: (a) => checkDirectory(str(a, "directory"), { core: a["core"] === true }),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "test",
|
|
62
|
+
description: "Run authored scenarios and seeded properties; failures carry spans and counterexamples.",
|
|
63
|
+
inputSchema: object({
|
|
64
|
+
directory,
|
|
65
|
+
scenario: { type: "string", description: "Run only this scenario." },
|
|
66
|
+
seed,
|
|
67
|
+
cases,
|
|
68
|
+
}, ["directory"]),
|
|
69
|
+
run: (a) => testDirectory(str(a, "directory"), pick({
|
|
70
|
+
scenario: opt(a, "scenario", "string"),
|
|
71
|
+
seed: opt(a, "seed", "number"),
|
|
72
|
+
cases: opt(a, "cases", "number"),
|
|
73
|
+
})),
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "coverage",
|
|
77
|
+
description: "Map cited sources to requirements and scenarios, with observed applicability, statuses and due branches.",
|
|
78
|
+
inputSchema: object({ directory, seed, cases }, ["directory"]),
|
|
79
|
+
run: (a) => coverageDirectory(str(a, "directory"), pick({ seed: opt(a, "seed", "number"), cases: opt(a, "cases", "number") })),
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "render",
|
|
83
|
+
description: "Render the manual a person reviews: every obligation in prose with citations and scenario examples.",
|
|
84
|
+
inputSchema: object({
|
|
85
|
+
directory,
|
|
86
|
+
format: { type: "string", enum: ["markdown", "html"] },
|
|
87
|
+
account: { type: "string", description: "Render only this account." },
|
|
88
|
+
}, ["directory"]),
|
|
89
|
+
run: (a) => {
|
|
90
|
+
const format = opt(a, "format", "string");
|
|
91
|
+
if (format !== undefined && format !== "markdown" && format !== "html")
|
|
92
|
+
throw new ToolInputError("format must be markdown or html.");
|
|
93
|
+
return renderDirectory(str(a, "directory"), pick({
|
|
94
|
+
format: format,
|
|
95
|
+
account: opt(a, "account", "string"),
|
|
96
|
+
}));
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "explain",
|
|
101
|
+
description: "Explain why each status, due date and work item is what it is: at a scenario step, or for a subject in a recorded world snapshot.",
|
|
102
|
+
inputSchema: object({
|
|
103
|
+
directory,
|
|
104
|
+
scenario: { type: "string" },
|
|
105
|
+
world: { type: "string", description: "Path to a worldvm/world@1 snapshot." },
|
|
106
|
+
subject: { type: "string" },
|
|
107
|
+
at: instant,
|
|
108
|
+
}, ["directory"]),
|
|
109
|
+
run: (a) => explainDirectory(str(a, "directory"), pick({
|
|
110
|
+
scenario: opt(a, "scenario", "string"),
|
|
111
|
+
world: opt(a, "world", "string"),
|
|
112
|
+
subject: opt(a, "subject", "string"),
|
|
113
|
+
at: opt(a, "at", "string"),
|
|
114
|
+
})),
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: "diff",
|
|
118
|
+
description: "Semantic diff of two releases: added, removed and changed declarations with spans, aspects and breaking contracts.",
|
|
119
|
+
inputSchema: object({
|
|
120
|
+
old: { ...directory, description: "Previous release source directory." },
|
|
121
|
+
new: { ...directory, description: "Candidate release source directory." },
|
|
122
|
+
}, ["old", "new"]),
|
|
123
|
+
run: (a) => diffDirectories(str(a, "old"), str(a, "new")),
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "impact",
|
|
127
|
+
description: "Preview a release over a recorded population: occurrences and work gained, lost or changed, selected by dependency digests.",
|
|
128
|
+
inputSchema: object({
|
|
129
|
+
old: { ...directory, description: "Previous release source directory." },
|
|
130
|
+
new: { ...directory, description: "Candidate release source directory." },
|
|
131
|
+
world: { type: "string", description: "Path to a worldvm/world@1 snapshot." },
|
|
132
|
+
at: instant,
|
|
133
|
+
}, ["old", "new", "world", "at"]),
|
|
134
|
+
run: (a) => impactDirectories(str(a, "old"), str(a, "new"), { world: str(a, "world"), at: str(a, "at") }),
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "format",
|
|
138
|
+
description: "Format Forma source text without writing files. Preserves comments; uses a 100-column style.",
|
|
139
|
+
inputSchema: object({ text: { type: "string", description: "Forma source text." } }, ["text"]),
|
|
140
|
+
run: async (a) => {
|
|
141
|
+
if (typeof a.text !== "string")
|
|
142
|
+
throw new ToolInputError("text must be a string.");
|
|
143
|
+
try {
|
|
144
|
+
return { format: "worldvm/format@1", ok: true, text: formatForma(a.text) };
|
|
145
|
+
}
|
|
146
|
+
catch (cause) {
|
|
147
|
+
return { format: "worldvm/format@1", ok: false, message: String(cause) };
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
const error = (id, code, message) => ({
|
|
153
|
+
jsonrpc: "2.0",
|
|
154
|
+
id: id ?? null,
|
|
155
|
+
error: { code, message },
|
|
156
|
+
});
|
|
157
|
+
const operatingTools = ({ world, actor }) => verbs.map((verb) => ({
|
|
158
|
+
name: verb,
|
|
159
|
+
description: `Operate the running world: ${verb}. Actor is fixed by the server.`,
|
|
160
|
+
inputSchema: requestJsonSchema(verb),
|
|
161
|
+
mutating: mutations.includes(verb),
|
|
162
|
+
run: (args) => world.request(verb, args, actor),
|
|
163
|
+
}));
|
|
164
|
+
export const handleMessage = async (message, operating) => {
|
|
165
|
+
const available = operating
|
|
166
|
+
? [
|
|
167
|
+
...tools.map((t) => (t.name === "explain" ? { ...t, name: "authoring-explain" } : t)),
|
|
168
|
+
...operatingTools(operating),
|
|
169
|
+
]
|
|
170
|
+
: tools;
|
|
171
|
+
const request = message;
|
|
172
|
+
if (!request ||
|
|
173
|
+
typeof request !== "object" ||
|
|
174
|
+
request.jsonrpc !== "2.0" ||
|
|
175
|
+
typeof request.method !== "string")
|
|
176
|
+
return error(null, -32600, "Invalid JSON-RPC request.");
|
|
177
|
+
const notification = !("id" in request);
|
|
178
|
+
const respond = (result) => notification ? null : { jsonrpc: "2.0", id: request.id, result };
|
|
179
|
+
switch (request.method) {
|
|
180
|
+
case "initialize": {
|
|
181
|
+
const asked = request.params?.protocolVersion;
|
|
182
|
+
return respond({
|
|
183
|
+
protocolVersion: typeof asked === "string" && protocolVersions.includes(asked)
|
|
184
|
+
? asked
|
|
185
|
+
: protocolVersions[0],
|
|
186
|
+
capabilities: { tools: { listChanged: false } },
|
|
187
|
+
serverInfo,
|
|
188
|
+
instructions: operating
|
|
189
|
+
? "WorldVM operating protocol plus authoring tools. Identity is fixed by the server; agents propose and humans accept. authoring-explain explains source scenarios; explain explains live subjects."
|
|
190
|
+
: "Read-only WorldVM authoring tools. Paths are resolved against the server's working directory. Each result is the command's versioned JSON report; ok=false reports carry located diagnostics with help.",
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
case "ping":
|
|
194
|
+
return respond({});
|
|
195
|
+
case "tools/list":
|
|
196
|
+
return respond({
|
|
197
|
+
tools: available
|
|
198
|
+
.filter((t) => !(operating &&
|
|
199
|
+
typeof operating.actor !== "string" &&
|
|
200
|
+
operating.actor.kind === "agent" &&
|
|
201
|
+
t.mutating &&
|
|
202
|
+
t.name !== "propose"))
|
|
203
|
+
.map((t) => ({
|
|
204
|
+
name: t.name,
|
|
205
|
+
description: t.description,
|
|
206
|
+
inputSchema: t.inputSchema,
|
|
207
|
+
annotations: {
|
|
208
|
+
readOnlyHint: !t.mutating,
|
|
209
|
+
destructiveHint: !!t.mutating,
|
|
210
|
+
openWorldHint: false,
|
|
211
|
+
},
|
|
212
|
+
})),
|
|
213
|
+
});
|
|
214
|
+
case "tools/call": {
|
|
215
|
+
const name = request.params?.name, args = request.params?.arguments ?? {};
|
|
216
|
+
const tool = available.find((t) => t.name === name);
|
|
217
|
+
if (!tool)
|
|
218
|
+
return notification ? null : error(request.id, -32602, `Unknown tool ${String(name)}.`);
|
|
219
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
220
|
+
return notification ? null : error(request.id, -32602, "arguments must be an object.");
|
|
221
|
+
try {
|
|
222
|
+
const report = await tool.run(args);
|
|
223
|
+
return respond({
|
|
224
|
+
content: [{ type: "text", text: JSON.stringify(report) }],
|
|
225
|
+
structuredContent: report,
|
|
226
|
+
isError: !report.ok,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
catch (cause) {
|
|
230
|
+
if (cause instanceof ToolInputError)
|
|
231
|
+
return respond({ content: [{ type: "text", text: cause.message }], isError: true });
|
|
232
|
+
throw cause;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
default:
|
|
236
|
+
if (notification)
|
|
237
|
+
return null; // e.g. notifications/initialized, notifications/cancelled
|
|
238
|
+
return error(request.id, -32601, `Method ${request.method} is not supported.`);
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
/** Serves MCP over stdin/stdout until stdin closes. Logs never go to stdout. */
|
|
242
|
+
export const serveStdio = async (input = process.stdin, output = process.stdout, operating) => {
|
|
243
|
+
const lines = createInterface({ input, crlfDelay: Infinity });
|
|
244
|
+
let queue = Promise.resolve();
|
|
245
|
+
for await (const line of lines) {
|
|
246
|
+
if (!line.trim())
|
|
247
|
+
continue;
|
|
248
|
+
// Responses keep request order; tools are CPU-bound and run one at a time.
|
|
249
|
+
queue = queue.then(async () => {
|
|
250
|
+
let message, response;
|
|
251
|
+
try {
|
|
252
|
+
message = JSON.parse(line);
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
output.write(`${JSON.stringify(error(null, -32700, "Parse error."))}\n`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
response = await handleMessage(message, operating);
|
|
260
|
+
}
|
|
261
|
+
catch (cause) {
|
|
262
|
+
response = error(message?.id ?? null, -32603, String(cause));
|
|
263
|
+
}
|
|
264
|
+
if (response !== null)
|
|
265
|
+
output.write(`${JSON.stringify(response)}\n`);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
await queue;
|
|
269
|
+
};
|