wingfoil 0.2.2 → 0.3.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/README.md +83 -43
- package/dist/agent/discovery.d.ts +72 -0
- package/dist/agent/discovery.d.ts.map +1 -0
- package/dist/agent/discovery.js +210 -0
- package/dist/agent/discovery.js.map +1 -0
- package/dist/agent/execute.d.ts +206 -0
- package/dist/agent/execute.d.ts.map +1 -0
- package/dist/agent/execute.js +581 -0
- package/dist/agent/execute.js.map +1 -0
- package/dist/agent/index.d.ts +23 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +85 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/launch.d.ts +133 -0
- package/dist/agent/launch.d.ts.map +1 -0
- package/dist/agent/launch.js +380 -0
- package/dist/agent/launch.js.map +1 -0
- package/dist/agent/manifest.d.ts +30 -0
- package/dist/agent/manifest.d.ts.map +1 -0
- package/dist/agent/manifest.js +93 -0
- package/dist/agent/manifest.js.map +1 -0
- package/dist/agent/placeholders.d.ts +49 -0
- package/dist/agent/placeholders.d.ts.map +1 -0
- package/dist/agent/placeholders.js +177 -0
- package/dist/agent/placeholders.js.map +1 -0
- package/dist/agent/run-log.d.ts +254 -0
- package/dist/agent/run-log.d.ts.map +1 -0
- package/dist/agent/run-log.js +612 -0
- package/dist/agent/run-log.js.map +1 -0
- package/dist/agent/schema.d.ts +100 -0
- package/dist/agent/schema.d.ts.map +1 -0
- package/dist/agent/schema.js +89 -0
- package/dist/agent/schema.js.map +1 -0
- package/dist/agent/step.d.ts +41 -0
- package/dist/agent/step.d.ts.map +1 -0
- package/dist/agent/step.js +95 -0
- package/dist/agent/step.js.map +1 -0
- package/dist/build-info.json +4 -0
- package/dist/cli/error.d.ts +11 -2
- package/dist/cli/error.d.ts.map +1 -1
- package/dist/cli/error.js +27 -6
- package/dist/cli/error.js.map +1 -1
- package/dist/cli/exit.d.ts +33 -3
- package/dist/cli/exit.d.ts.map +1 -1
- package/dist/cli/exit.js +54 -3
- package/dist/cli/exit.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init-command.d.ts.map +1 -1
- package/dist/cli/init-command.js +4 -2
- package/dist/cli/init-command.js.map +1 -1
- package/dist/cli/mcp-command.d.ts +13 -4
- package/dist/cli/mcp-command.d.ts.map +1 -1
- package/dist/cli/mcp-command.js +25 -8
- package/dist/cli/mcp-command.js.map +1 -1
- package/dist/cli/output.d.ts +12 -4
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +15 -4
- package/dist/cli/output.js.map +1 -1
- package/dist/cli/program.d.ts +1 -1
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +162 -40
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/registrar.d.ts +1 -1
- package/dist/cli/registrar.d.ts.map +1 -1
- package/dist/cli/registrar.js +67 -6
- package/dist/cli/registrar.js.map +1 -1
- package/dist/cli/suggest.d.ts +20 -0
- package/dist/cli/suggest.d.ts.map +1 -0
- package/dist/cli/suggest.js +49 -0
- package/dist/cli/suggest.js.map +1 -0
- package/dist/cli/warning.d.ts +26 -0
- package/dist/cli/warning.d.ts.map +1 -0
- package/dist/cli/warning.js +66 -0
- package/dist/cli/warning.js.map +1 -0
- package/dist/cli.js +11 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-execute.d.ts +44 -0
- package/dist/core/agent-execute.d.ts.map +1 -0
- package/dist/core/agent-execute.js +71 -0
- package/dist/core/agent-execute.js.map +1 -0
- package/dist/core/agent-list.d.ts +95 -0
- package/dist/core/agent-list.d.ts.map +1 -0
- package/dist/core/agent-list.js +207 -0
- package/dist/core/agent-list.js.map +1 -0
- package/dist/core/agent-show.d.ts +44 -0
- package/dist/core/agent-show.d.ts.map +1 -0
- package/dist/core/agent-show.js +188 -0
- package/dist/core/agent-show.js.map +1 -0
- package/dist/core/approval-authority.d.ts +17 -14
- package/dist/core/approval-authority.d.ts.map +1 -1
- package/dist/core/approval-authority.js +9 -9
- package/dist/core/approval-authority.js.map +1 -1
- package/dist/core/builtin-asset.d.ts +18 -15
- package/dist/core/builtin-asset.d.ts.map +1 -1
- package/dist/core/builtin-asset.js +17 -14
- package/dist/core/builtin-asset.js.map +1 -1
- package/dist/core/builtin-integrity.d.ts +12 -2
- package/dist/core/builtin-integrity.d.ts.map +1 -1
- package/dist/core/builtin-integrity.js +85 -9
- package/dist/core/builtin-integrity.js.map +1 -1
- package/dist/core/confinement.d.ts +3 -1
- package/dist/core/confinement.d.ts.map +1 -1
- package/dist/core/confinement.js +7 -4
- package/dist/core/confinement.js.map +1 -1
- package/dist/core/context.d.ts +150 -98
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +602 -66
- package/dist/core/context.js.map +1 -1
- package/dist/core/directive-assign.d.ts +33 -7
- package/dist/core/directive-assign.d.ts.map +1 -1
- package/dist/core/directive-assign.js +67 -27
- package/dist/core/directive-assign.js.map +1 -1
- package/dist/core/directive-scope.d.ts +36 -0
- package/dist/core/directive-scope.d.ts.map +1 -0
- package/dist/core/directive-scope.js +34 -0
- package/dist/core/directive-scope.js.map +1 -0
- package/dist/core/directives-list.d.ts +13 -3
- package/dist/core/directives-list.d.ts.map +1 -1
- package/dist/core/directives-list.js +18 -6
- package/dist/core/directives-list.js.map +1 -1
- package/dist/core/dry-run.d.ts +33 -0
- package/dist/core/dry-run.d.ts.map +1 -0
- package/dist/core/dry-run.js +45 -0
- package/dist/core/dry-run.js.map +1 -0
- package/dist/core/element-ref.d.ts +23 -0
- package/dist/core/element-ref.d.ts.map +1 -0
- package/dist/core/element-ref.js +24 -0
- package/dist/core/element-ref.js.map +1 -0
- package/dist/core/error-details.d.ts +20 -0
- package/dist/core/error-details.d.ts.map +1 -0
- package/dist/core/error-details.js +65 -0
- package/dist/core/error-details.js.map +1 -0
- package/dist/core/exit-code.d.ts.map +1 -1
- package/dist/core/exit-code.js +6 -7
- package/dist/core/exit-code.js.map +1 -1
- package/dist/core/git-identity.d.ts +46 -11
- package/dist/core/git-identity.d.ts.map +1 -1
- package/dist/core/git-identity.js +140 -27
- package/dist/core/git-identity.js.map +1 -1
- package/dist/core/index.d.ts +184 -10
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1045 -185
- package/dist/core/index.js.map +1 -1
- package/dist/core/init.d.ts +45 -5
- package/dist/core/init.d.ts.map +1 -1
- package/dist/core/init.js +134 -24
- package/dist/core/init.js.map +1 -1
- package/dist/core/loaders.d.ts +170 -14
- package/dist/core/loaders.d.ts.map +1 -1
- package/dist/core/loaders.js +570 -89
- package/dist/core/loaders.js.map +1 -1
- package/dist/core/memory-add-link.d.ts +28 -0
- package/dist/core/memory-add-link.d.ts.map +1 -0
- package/dist/core/memory-add-link.js +67 -0
- package/dist/core/memory-add-link.js.map +1 -0
- package/dist/core/memory-add-type.d.ts +25 -1
- package/dist/core/memory-add-type.d.ts.map +1 -1
- package/dist/core/memory-add-type.js +59 -1
- package/dist/core/memory-add-type.js.map +1 -1
- package/dist/core/memory-amend.d.ts +80 -0
- package/dist/core/memory-amend.d.ts.map +1 -0
- package/dist/core/memory-amend.js +160 -0
- package/dist/core/memory-amend.js.map +1 -0
- package/dist/core/memory-supersede.d.ts +28 -0
- package/dist/core/memory-supersede.d.ts.map +1 -0
- package/dist/core/memory-supersede.js +79 -0
- package/dist/core/memory-supersede.js.map +1 -0
- package/dist/core/memory-transition.d.ts +190 -30
- package/dist/core/memory-transition.d.ts.map +1 -1
- package/dist/core/memory-transition.js +480 -59
- package/dist/core/memory-transition.js.map +1 -1
- package/dist/core/registry.d.ts +82 -10
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +50 -0
- package/dist/core/registry.js.map +1 -1
- package/dist/core/relevance.d.ts +74 -12
- package/dist/core/relevance.d.ts.map +1 -1
- package/dist/core/relevance.js +45 -27
- package/dist/core/relevance.js.map +1 -1
- package/dist/core/require-reason.d.ts.map +1 -1
- package/dist/core/require-reason.js +6 -5
- package/dist/core/require-reason.js.map +1 -1
- package/dist/core/required-fields.d.ts +28 -0
- package/dist/core/required-fields.d.ts.map +1 -0
- package/dist/core/required-fields.js +60 -0
- package/dist/core/required-fields.js.map +1 -0
- package/dist/core/revision.d.ts +82 -0
- package/dist/core/revision.d.ts.map +1 -0
- package/dist/core/revision.js +144 -0
- package/dist/core/revision.js.map +1 -0
- package/dist/core/types.d.ts +28 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +12 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/workflow-core-checks.d.ts +34 -0
- package/dist/core/workflow-core-checks.d.ts.map +1 -0
- package/dist/core/workflow-core-checks.js +403 -0
- package/dist/core/workflow-core-checks.js.map +1 -0
- package/dist/core/workflow-create-remove.d.ts +65 -0
- package/dist/core/workflow-create-remove.d.ts.map +1 -0
- package/dist/core/workflow-create-remove.js +277 -0
- package/dist/core/workflow-create-remove.js.map +1 -0
- package/dist/core/workflow-deduction.d.ts +48 -0
- package/dist/core/workflow-deduction.d.ts.map +1 -0
- package/dist/core/workflow-deduction.js +523 -0
- package/dist/core/workflow-deduction.js.map +1 -0
- package/dist/core/workflow-diagnostics.d.ts +83 -0
- package/dist/core/workflow-diagnostics.d.ts.map +1 -0
- package/dist/core/workflow-diagnostics.js +375 -0
- package/dist/core/workflow-diagnostics.js.map +1 -0
- package/dist/core/workflow-exit-state.d.ts +125 -0
- package/dist/core/workflow-exit-state.d.ts.map +1 -0
- package/dist/core/workflow-exit-state.js +243 -0
- package/dist/core/workflow-exit-state.js.map +1 -0
- package/dist/core/workflow-finalize.d.ts +37 -0
- package/dist/core/workflow-finalize.d.ts.map +1 -0
- package/dist/core/workflow-finalize.js +153 -0
- package/dist/core/workflow-finalize.js.map +1 -0
- package/dist/core/workflow-list-show.d.ts +176 -0
- package/dist/core/workflow-list-show.d.ts.map +1 -0
- package/dist/core/workflow-list-show.js +268 -0
- package/dist/core/workflow-list-show.js.map +1 -0
- package/dist/core/workflow-next.d.ts +268 -0
- package/dist/core/workflow-next.d.ts.map +1 -0
- package/dist/core/workflow-next.js +503 -0
- package/dist/core/workflow-next.js.map +1 -0
- package/dist/core/workflow-registry.d.ts +52 -0
- package/dist/core/workflow-registry.d.ts.map +1 -0
- package/dist/core/workflow-registry.js +158 -0
- package/dist/core/workflow-registry.js.map +1 -0
- package/dist/core/workflow-start-end.d.ts +71 -0
- package/dist/core/workflow-start-end.d.ts.map +1 -0
- package/dist/core/workflow-start-end.js +298 -0
- package/dist/core/workflow-start-end.js.map +1 -0
- package/dist/core/workflow-status.d.ts +83 -0
- package/dist/core/workflow-status.d.ts.map +1 -0
- package/dist/core/workflow-status.js +125 -0
- package/dist/core/workflow-status.js.map +1 -0
- package/dist/core/write-guard.d.ts +51 -8
- package/dist/core/write-guard.d.ts.map +1 -1
- package/dist/core/write-guard.js +139 -9
- package/dist/core/write-guard.js.map +1 -1
- package/dist/directives/index.d.ts +3 -2
- package/dist/directives/index.d.ts.map +1 -1
- package/dist/directives/index.js +5 -3
- package/dist/directives/index.js.map +1 -1
- package/dist/directives/schema.d.ts +34 -29
- package/dist/directives/schema.d.ts.map +1 -1
- package/dist/directives/schema.js +35 -29
- package/dist/directives/schema.js.map +1 -1
- package/dist/directives/version.d.ts +28 -0
- package/dist/directives/version.d.ts.map +1 -0
- package/dist/directives/version.js +51 -0
- package/dist/directives/version.js.map +1 -0
- package/dist/dna/edit.d.ts +7 -6
- package/dist/dna/edit.d.ts.map +1 -1
- package/dist/dna/edit.js +96 -41
- package/dist/dna/edit.js.map +1 -1
- package/dist/dna/mutate.js +18 -3
- package/dist/dna/mutate.js.map +1 -1
- package/dist/dna/path.d.ts +2 -2
- package/dist/dna/roles.d.ts +1 -1
- package/dist/dna/schema.d.ts +61 -3
- package/dist/dna/schema.d.ts.map +1 -1
- package/dist/dna/schema.js +121 -6
- package/dist/dna/schema.js.map +1 -1
- package/dist/mcp/dna-resource.d.ts.map +1 -1
- package/dist/mcp/dna-resource.js +4 -4
- package/dist/mcp/dna-resource.js.map +1 -1
- package/dist/mcp/index.d.ts +8 -4
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +13 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/memory-resource.d.ts.map +1 -1
- package/dist/mcp/memory-resource.js +30 -19
- package/dist/mcp/memory-resource.js.map +1 -1
- package/dist/mcp/prompt.d.ts +61 -24
- package/dist/mcp/prompt.d.ts.map +1 -1
- package/dist/mcp/prompt.js +176 -47
- package/dist/mcp/prompt.js.map +1 -1
- package/dist/mcp/read-only.d.ts +39 -0
- package/dist/mcp/read-only.d.ts.map +1 -1
- package/dist/mcp/read-only.js +61 -0
- package/dist/mcp/read-only.js.map +1 -1
- package/dist/mcp/registrar.d.ts +10 -0
- package/dist/mcp/registrar.d.ts.map +1 -1
- package/dist/mcp/registrar.js +48 -12
- package/dist/mcp/registrar.js.map +1 -1
- package/dist/mcp/server.d.ts +21 -14
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +41 -15
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/session-resource.d.ts +13 -0
- package/dist/mcp/session-resource.d.ts.map +1 -0
- package/dist/mcp/session-resource.js +65 -0
- package/dist/mcp/session-resource.js.map +1 -0
- package/dist/mcp/workflow-resource.d.ts +18 -0
- package/dist/mcp/workflow-resource.d.ts.map +1 -1
- package/dist/mcp/workflow-resource.js +37 -8
- package/dist/mcp/workflow-resource.js.map +1 -1
- package/dist/memory/add.d.ts +110 -24
- package/dist/memory/add.d.ts.map +1 -1
- package/dist/memory/add.js +251 -64
- package/dist/memory/add.js.map +1 -1
- package/dist/memory/audit.d.ts +152 -39
- package/dist/memory/audit.d.ts.map +1 -1
- package/dist/memory/audit.js +257 -103
- package/dist/memory/audit.js.map +1 -1
- package/dist/memory/commit-message.d.ts +60 -38
- package/dist/memory/commit-message.d.ts.map +1 -1
- package/dist/memory/commit-message.js +167 -21
- package/dist/memory/commit-message.js.map +1 -1
- package/dist/memory/entry.d.ts.map +1 -1
- package/dist/memory/entry.js +1 -2
- package/dist/memory/entry.js.map +1 -1
- package/dist/memory/frontmatter-edit.d.ts +16 -4
- package/dist/memory/frontmatter-edit.d.ts.map +1 -1
- package/dist/memory/frontmatter-edit.js +13 -1
- package/dist/memory/frontmatter-edit.js.map +1 -1
- package/dist/memory/git-log.d.ts +18 -6
- package/dist/memory/git-log.d.ts.map +1 -1
- package/dist/memory/git-log.js +40 -13
- package/dist/memory/git-log.js.map +1 -1
- package/dist/memory/history.d.ts +73 -12
- package/dist/memory/history.d.ts.map +1 -1
- package/dist/memory/history.js +128 -44
- package/dist/memory/history.js.map +1 -1
- package/dist/memory/index.d.ts +13 -11
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +34 -3
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/query.d.ts +161 -19
- package/dist/memory/query.d.ts.map +1 -1
- package/dist/memory/query.js +435 -55
- package/dist/memory/query.js.map +1 -1
- package/dist/memory/schema.d.ts +52 -3
- package/dist/memory/schema.d.ts.map +1 -1
- package/dist/memory/schema.js +132 -8
- package/dist/memory/schema.js.map +1 -1
- package/dist/memory/state-machine.d.ts +65 -10
- package/dist/memory/state-machine.d.ts.map +1 -1
- package/dist/memory/state-machine.js +134 -46
- package/dist/memory/state-machine.js.map +1 -1
- package/dist/memory/submit.d.ts +52 -3
- package/dist/memory/submit.d.ts.map +1 -1
- package/dist/memory/submit.js +118 -11
- package/dist/memory/submit.js.map +1 -1
- package/dist/storage/build-stamp.d.ts +18 -0
- package/dist/storage/build-stamp.d.ts.map +1 -0
- package/dist/storage/build-stamp.js +68 -0
- package/dist/storage/build-stamp.js.map +1 -0
- package/dist/storage/builtin-adapters.d.ts +32 -0
- package/dist/storage/builtin-adapters.d.ts.map +1 -0
- package/dist/storage/builtin-adapters.js +100 -0
- package/dist/storage/builtin-adapters.js.map +1 -0
- package/dist/storage/builtin-directives.d.ts +0 -29
- package/dist/storage/builtin-directives.d.ts.map +1 -1
- package/dist/storage/builtin-directives.js +9 -4
- package/dist/storage/builtin-directives.js.map +1 -1
- package/dist/storage/commit.d.ts +310 -3
- package/dist/storage/commit.d.ts.map +1 -1
- package/dist/storage/commit.js +807 -33
- package/dist/storage/commit.js.map +1 -1
- package/dist/storage/document.d.ts +6 -0
- package/dist/storage/document.d.ts.map +1 -1
- package/dist/storage/document.js +10 -1
- package/dist/storage/document.js.map +1 -1
- package/dist/storage/dry-run.d.ts +65 -0
- package/dist/storage/dry-run.d.ts.map +1 -0
- package/dist/storage/dry-run.js +150 -0
- package/dist/storage/dry-run.js.map +1 -0
- package/dist/storage/errors.d.ts +26 -0
- package/dist/storage/errors.d.ts.map +1 -1
- package/dist/storage/errors.js +27 -1
- package/dist/storage/errors.js.map +1 -1
- package/dist/storage/frontmatter.d.ts +1 -1
- package/dist/storage/frontmatter.js +1 -1
- package/dist/storage/git-read.d.ts +64 -0
- package/dist/storage/git-read.d.ts.map +1 -0
- package/dist/storage/git-read.js +107 -0
- package/dist/storage/git-read.js.map +1 -0
- package/dist/storage/index.d.ts +13 -5
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +39 -2
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/layout.d.ts +2 -2
- package/dist/storage/layout.d.ts.map +1 -1
- package/dist/storage/layout.js +2 -7
- package/dist/storage/layout.js.map +1 -1
- package/dist/storage/memory-path.d.ts +18 -5
- package/dist/storage/memory-path.d.ts.map +1 -1
- package/dist/storage/memory-path.js +41 -5
- package/dist/storage/memory-path.js.map +1 -1
- package/dist/storage/snapshot.js +1 -1
- package/dist/storage/templates.d.ts +33 -6
- package/dist/storage/templates.d.ts.map +1 -1
- package/dist/storage/templates.js +170 -16
- package/dist/storage/templates.js.map +1 -1
- package/dist/validation/config-version.d.ts +19 -0
- package/dist/validation/config-version.d.ts.map +1 -0
- package/dist/validation/config-version.js +53 -0
- package/dist/validation/config-version.js.map +1 -0
- package/dist/validation/diagnostic.d.ts +40 -0
- package/dist/validation/diagnostic.d.ts.map +1 -0
- package/dist/validation/diagnostic.js +41 -0
- package/dist/validation/diagnostic.js.map +1 -0
- package/dist/validation/format.d.ts +74 -0
- package/dist/validation/format.d.ts.map +1 -0
- package/dist/validation/format.js +104 -0
- package/dist/validation/format.js.map +1 -0
- package/dist/validation/id.d.ts +14 -0
- package/dist/validation/id.d.ts.map +1 -1
- package/dist/validation/id.js +35 -11
- package/dist/validation/id.js.map +1 -1
- package/dist/validation/identity.d.ts +40 -0
- package/dist/validation/identity.d.ts.map +1 -0
- package/dist/validation/identity.js +78 -0
- package/dist/validation/identity.js.map +1 -0
- package/dist/validation/index.d.ts +9 -3
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +30 -1
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/secret-scan.d.ts +3 -2
- package/dist/validation/secret-scan.d.ts.map +1 -1
- package/dist/validation/secret-scan.js +32 -11
- package/dist/validation/secret-scan.js.map +1 -1
- package/dist/validation/warning.d.ts +30 -16
- package/dist/validation/warning.d.ts.map +1 -1
- package/dist/validation/warning.js +74 -7
- package/dist/validation/warning.js.map +1 -1
- package/dist/workflow/bindings.d.ts +152 -0
- package/dist/workflow/bindings.d.ts.map +1 -0
- package/dist/workflow/bindings.js +249 -0
- package/dist/workflow/bindings.js.map +1 -0
- package/dist/workflow/create.d.ts +13 -0
- package/dist/workflow/create.d.ts.map +1 -0
- package/dist/workflow/create.js +41 -0
- package/dist/workflow/create.js.map +1 -0
- package/dist/workflow/deduce.d.ts +400 -0
- package/dist/workflow/deduce.d.ts.map +1 -0
- package/dist/workflow/deduce.js +1109 -0
- package/dist/workflow/deduce.js.map +1 -0
- package/dist/workflow/manifest-edit.d.ts +19 -0
- package/dist/workflow/manifest-edit.d.ts.map +1 -0
- package/dist/workflow/manifest-edit.js +124 -0
- package/dist/workflow/manifest-edit.js.map +1 -0
- package/dist/workflow/schema.d.ts +158 -19
- package/dist/workflow/schema.d.ts.map +1 -1
- package/dist/workflow/schema.js +163 -15
- package/dist/workflow/schema.js.map +1 -1
- package/package.json +18 -8
|
@@ -1,31 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WIP_REFS_SENTENCE = void 0;
|
|
3
4
|
exports.prepareMemoryTransition = prepareMemoryTransition;
|
|
5
|
+
exports.prepareMemoryTransitionAtRev = prepareMemoryTransitionAtRev;
|
|
6
|
+
exports.requireWipSlot = requireWipSlot;
|
|
7
|
+
exports.isMoreAdvancedState = isMoreAdvancedState;
|
|
8
|
+
exports.beginMemoryTransition = beginMemoryTransition;
|
|
4
9
|
exports.verifyCommittedScope = verifyCommittedScope;
|
|
10
|
+
exports.checkMemoryTransition = checkMemoryTransition;
|
|
5
11
|
exports.commitMemoryTransition = commitMemoryTransition;
|
|
6
12
|
/**
|
|
7
13
|
* The shared skeleton of every Memory state-transition verb (task-045-memory-submit; reused by
|
|
8
|
-
* `memory approve`/`reject`/`deprecate`, task-046/047/048
|
|
14
|
+
* `memory approve`/`reject`/`deprecate`, task-046/047/048, by `memory amend`, task-127, whose
|
|
15
|
+
* edge is the self-loop of the current state, and by `memory park`, task-180, which takes a declared
|
|
16
|
+
* `returns` edge).
|
|
9
17
|
*
|
|
10
18
|
* A transition verb always does the same two things around its own verb-specific rules:
|
|
11
19
|
*
|
|
12
20
|
* 1. {@link prepareMemoryTransition} — find the document by its bare id (spec-008-cli-grammar §7), read
|
|
13
|
-
* its declared `type` and current `status`, and resolve the legal target for the verb **
|
|
14
|
-
* `memory.yaml`
|
|
21
|
+
* its declared `type` and current `status`, and resolve the legal target for the verb, **all at
|
|
22
|
+
* `HEAD`**: the committed `memory.yaml` (task-091, `bug-081`, `dl-080` (B)) and the committed
|
|
23
|
+
* document (task-247, `bug-187`); the working tree supplies the content to commit and is checked to
|
|
24
|
+
* be the same element `HEAD` records. Every expected
|
|
15
25
|
* refusal is returned as a `CoreResult.error` (exit `1`), **before anything is written**, so "the
|
|
16
26
|
* state is unchanged" (P1.6 sc.2, REQ-STATE-01) holds by construction.
|
|
17
27
|
* 2. {@link commitMemoryTransition} — write the new bytes and turn them into exactly one commit scoped
|
|
18
28
|
* to that one document.
|
|
19
29
|
*
|
|
20
30
|
* What happens in between (required-field checks, which fields change, the commit message) is the
|
|
21
|
-
* verb's own business; see `memorySubmitFn` in `./index.ts`.
|
|
31
|
+
* verb's own business; see `memorySubmitFn` in `./index.ts`. One verb makes a second commit: an
|
|
32
|
+
* approve that fires the `supersedes:` trigger (task-162, `./memory-supersede.ts`) prepares the
|
|
33
|
+
* superseded element with {@link prepareMemoryTransitionAtRev} at the approve's own sha and runs
|
|
34
|
+
* {@link checkMemoryTransition} on both documents before either commit.
|
|
22
35
|
*/
|
|
36
|
+
const fs_1 = require("fs");
|
|
23
37
|
const path_1 = require("path");
|
|
24
38
|
const memory_1 = require("../memory");
|
|
25
39
|
const storage_1 = require("../storage");
|
|
26
40
|
const validation_1 = require("../validation");
|
|
27
41
|
const confinement_1 = require("./confinement");
|
|
42
|
+
const git_identity_1 = require("./git-identity");
|
|
28
43
|
const loaders_1 = require("./loaders");
|
|
44
|
+
const revision_1 = require("./revision");
|
|
29
45
|
const types_1 = require("./types");
|
|
30
46
|
const write_guard_1 = require("./write-guard");
|
|
31
47
|
/**
|
|
@@ -51,36 +67,137 @@ function uncommittedMachineNote(root) {
|
|
|
51
67
|
`committed copy (dl-080); commit '${loaders_1.MEMORY_YAML_PATH}' first if this transition depends on that change`);
|
|
52
68
|
}
|
|
53
69
|
/**
|
|
54
|
-
*
|
|
55
|
-
* `HEAD
|
|
70
|
+
* A second sentence for `document not found` when the lookup at `HEAD` skipped documents it could not
|
|
71
|
+
* read (task-171): the id may be in one of them, so they are named as `HEAD:<path>`. Empty otherwise,
|
|
72
|
+
* so the pinned first sentence (P1.6 sc.3) is unchanged.
|
|
73
|
+
*/
|
|
74
|
+
function unreadableNote(unreadable) {
|
|
75
|
+
if (unreadable.length === 0)
|
|
76
|
+
return '';
|
|
77
|
+
const named = unreadable.map((diagnostic) => `HEAD:${diagnostic.file} (${diagnostic.message.slice(diagnostic.message.indexOf(': ') + 2)})`);
|
|
78
|
+
return ` — it may be in a Memory document committed at HEAD that could not be read: ${named.join('; ')}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The refusal of a transition whose element is written in a `format` newer than this build reads
|
|
82
|
+
* (`dl-149`, task-257, `bug-241`): `VALIDATION`, exit `1`, before anything is written, carrying the
|
|
83
|
+
* loader's own `E_INVALID_FORMAT format (<file>): … upgrade WingFoil` text and naming which copy said so —
|
|
84
|
+
* `HEAD`'s, which decides, or the working tree's, which the verb would commit. Anything other than that
|
|
85
|
+
* refusal is rethrown.
|
|
86
|
+
*/
|
|
87
|
+
function newerFormatRefusal(op, id, where, error) {
|
|
88
|
+
if (!(0, validation_1.isNewerFormatError)(error))
|
|
89
|
+
throw error;
|
|
90
|
+
return (0, types_1.coreErr)({
|
|
91
|
+
code: 'VALIDATION',
|
|
92
|
+
message: `refusing to ${op} ${id}: its document, as ${where} holds it, is written in a newer format: ${error.message}`,
|
|
93
|
+
details: { issues: error.issues },
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** Whether `full` names a directory entry at all — `lstat`, so a link is present even when dangling. */
|
|
97
|
+
function isPresent(full) {
|
|
98
|
+
try {
|
|
99
|
+
(0, fs_1.lstatSync)(full);
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The working-tree path of a document carrying frontmatter `id`, or `undefined` — read only to
|
|
108
|
+
* **explain** a refusal already decided at `HEAD`, never to decide one (the `command-baseline`
|
|
109
|
+
* directive: "the working tree may be read to explain a refusal, never to decide one"). A document
|
|
110
|
+
* elsewhere whose frontmatter does not parse is skipped by the scan (task-171), and any failure to
|
|
111
|
+
* walk the working tree yields `undefined`, so the refusal keeps its plain wording and no branch of
|
|
112
|
+
* this read can change an outcome.
|
|
113
|
+
*/
|
|
114
|
+
function uncommittedDocumentPath(root, memoryYaml, id) {
|
|
115
|
+
// `followSymlinks`: this read only words a refusal, so it may follow a link the deciding scan skips
|
|
116
|
+
// (task-171, `bug-189`), and the confinement guards then refuse the link by name.
|
|
117
|
+
try {
|
|
118
|
+
return (0, memory_1.findMemoryDocumentById)(root, memoryYaml, id, { followSymlinks: true })?.path;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Explain-only: a working tree the walk cannot read (an unreadable directory, `EACCES`) leaves
|
|
122
|
+
// the refusal its plain wording rather than becoming the outcome (task-171 re-review A).
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The frontmatter `id` commit `sha` records for `path`, or `undefined` when the commit does not hold
|
|
128
|
+
* the path, or holds it with frontmatter that does not parse (the scan at the same sha skipped it,
|
|
129
|
+
* task-171). Like {@link uncommittedDocumentPath}, it only words a refusal, so no branch of it can
|
|
130
|
+
* change an outcome.
|
|
131
|
+
*/
|
|
132
|
+
function recordedIdAt(root, sha, path) {
|
|
133
|
+
let id;
|
|
134
|
+
try {
|
|
135
|
+
id = (0, memory_1.loadMemoryDocumentSummaryAtRev)(root, sha, path)?.frontmatter.id;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Explain-only: a document HEAD holds but cannot be read records no id to name.
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
return id === undefined ? undefined : String(id);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Locate document `id` and resolve verb `op` on it, **at `HEAD`**: the `memory.yaml`, the document
|
|
145
|
+
* the id names and its current `status` are all read from the one commit `HEAD` resolves to, once
|
|
146
|
+
* (`resolveRevision`, then `loadMemoryYamlAtRev` and `findMemoryDocumentByIdAtRev` at that sha).
|
|
147
|
+
*
|
|
148
|
+
* The baseline is the point (`spec-006-core-domain-api` §6 item 1, `dl-080` option (B)). This
|
|
149
|
+
* function takes no `MemoryYaml` and no document: a caller cannot hand it a working-tree machine or a
|
|
150
|
+
* working-tree `status` even by accident. Two defects motivated it. An uncommitted edit to a type's
|
|
151
|
+
* `sequence` used to decide the transition a verb performed (task-091, `bug-081`); and until task-247
|
|
152
|
+
* (`bug-187`) the id was looked up by scanning the working tree and `from` was the working-tree
|
|
153
|
+
* frontmatter's `status`, so an element already past `draft` at `HEAD` but edited back to `draft` on
|
|
154
|
+
* disk was submitted again, and a hand-made document no commit holds was transitioned as if `memory
|
|
155
|
+
* add` had registered it.
|
|
56
156
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* the
|
|
60
|
-
*
|
|
61
|
-
* verb performed and the `status` it committed — through `memory submit`, which requires no
|
|
62
|
-
* authority — and stranded the element in a state the committed machine rejects.
|
|
157
|
+
* **Content from the working tree, state from `HEAD`.** The `content` and `frontmatter` this returns
|
|
158
|
+
* are the working tree's, because that is what `memory submit` and `memory amend` commit; `from`, the
|
|
159
|
+
* `type` and the target are `HEAD`'s. The working tree must still carry the same `id` and `type` the
|
|
160
|
+
* commit records — a verb decides on one element and writes that element.
|
|
63
161
|
*
|
|
64
162
|
* Refusals, all returned (never thrown) and all exit `1`:
|
|
65
163
|
*
|
|
66
|
-
* - `HEAD` holds no `memory.yaml` → `VALIDATION`, fail-closed: with no
|
|
67
|
-
* `from → to` to record, and the only fail-open available is the
|
|
68
|
-
* `wingfoil init` commits the scaffold, so no legitimate flow
|
|
164
|
+
* - `HEAD` holds no `memory.yaml` (or there is no commit) → `VALIDATION`, fail-closed: with no
|
|
165
|
+
* committed machine there is no `from → to` to record, and the only fail-open available is the
|
|
166
|
+
* working tree, which is the defect. `wingfoil init` commits the scaffold, so no legitimate flow
|
|
167
|
+
* reaches this;
|
|
69
168
|
* - the committed `memory.yaml` does not parse or validate → `VALIDATION`, same reasoning;
|
|
70
|
-
* - no document carries that frontmatter `id` → `NOT_FOUND` `document not found: <id>`
|
|
169
|
+
* - no document at `HEAD` carries that frontmatter `id` → `NOT_FOUND` `document not found: <id>`
|
|
170
|
+
* (P1.6 sc.3); when a working-tree document carries it, the message says so and names `memory add`
|
|
171
|
+
* (task-247), since a transition acts only on an element a commit records — or, when `HEAD` holds
|
|
172
|
+
* that path under another id, `VALIDATION` naming the renamed `id` field;
|
|
173
|
+
* - `HEAD` holds the document but the working tree deleted it → `VALIDATION`, naming the path;
|
|
174
|
+
* - the working tree changes the document's `id` or `type` → `VALIDATION`;
|
|
71
175
|
* - its `type` is not registered → `NOT_FOUND` with `memory add`'s unknown-type message;
|
|
72
|
-
* - its `status` is not a state of the type → `VALIDATION` `invalid state '<s>' for type
|
|
73
|
-
* (task-036's `validateFrontmatterState`);
|
|
176
|
+
* - its committed `status` is not a state of the type → `VALIDATION` `invalid state '<s>' for type
|
|
177
|
+
* '<t>'` (task-036's `validateFrontmatterState`);
|
|
74
178
|
* - the verb is illegal from that state → `INVALID_TRANSITION` with the `dl-032` contract message
|
|
75
|
-
* (`resolveTypeTransition`), the engine's explanation in `details.issues[0].detail`.
|
|
179
|
+
* (`resolveTypeTransition`), the engine's explanation in `details.issues[0].detail`. `amend`
|
|
180
|
+
* (task-127) never takes this branch: its target is the current state.
|
|
181
|
+
* - the document, as `HEAD` records it or as the working tree would have it committed, declares a
|
|
182
|
+
* `format` newer than this build reads → `VALIDATION` with the `dl-149` `E_INVALID_FORMAT` text, the
|
|
183
|
+
* file named (task-257, `bug-241`);
|
|
184
|
+
* - the target state declares a WIP limit its holders have reached → `CONFLICT`
|
|
185
|
+
* ({@link requireWipSlot}, task-180), the holders counted across every ref (task-274). Every
|
|
186
|
+
* transition into a state goes through here, so the limit holds whichever verb or engine action
|
|
187
|
+
* moves the element — except `reject` and `park`, which send it back along a reject or `returns`
|
|
188
|
+
* edge and are exempt (`dl-156` Q2 (i)).
|
|
76
189
|
*
|
|
77
|
-
* The
|
|
78
|
-
* {@link uncommittedMachineNote} may append a second one.
|
|
190
|
+
* The unknown-type, invalid-state and illegal-transition refusals keep their pinned messages
|
|
191
|
+
* verbatim as the first sentence; {@link uncommittedMachineNote} may append a second one.
|
|
79
192
|
*/
|
|
80
193
|
function prepareMemoryTransition(root, id, op) {
|
|
194
|
+
// Resolved ONCE: every read below is at this sha, so the machine and the document cannot come from
|
|
195
|
+
// two commits even if `HEAD` moves while the verb runs (task-137). No commit at all is the same
|
|
196
|
+
// answer as a commit without `memory.yaml`.
|
|
197
|
+
const sha = (0, revision_1.atHeadOr)(root, () => (0, revision_1.resolveRevision)(root, 'HEAD'), null);
|
|
81
198
|
let memoryYaml;
|
|
82
199
|
try {
|
|
83
|
-
memoryYaml = (0, loaders_1.
|
|
200
|
+
memoryYaml = sha === null ? null : (0, loaders_1.loadMemoryYamlAtRev)(root, sha);
|
|
84
201
|
}
|
|
85
202
|
catch (error) {
|
|
86
203
|
if (!(error instanceof validation_1.ValidationError))
|
|
@@ -93,18 +210,102 @@ function prepareMemoryTransition(root, id, op) {
|
|
|
93
210
|
details: { issues: error.issues },
|
|
94
211
|
});
|
|
95
212
|
}
|
|
96
|
-
if (memoryYaml === null) {
|
|
213
|
+
if (sha === null || memoryYaml === null) {
|
|
97
214
|
return (0, types_1.coreErr)({
|
|
98
215
|
code: 'VALIDATION',
|
|
99
216
|
message: `cannot resolve the state machine: '${loaders_1.MEMORY_YAML_PATH}' is not committed at HEAD. A transition is decided by ` +
|
|
100
217
|
`the machine the repository records, not by a working tree (dl-080); commit '${loaders_1.MEMORY_YAML_PATH}' first, then retry.`,
|
|
101
218
|
});
|
|
102
219
|
}
|
|
103
|
-
|
|
220
|
+
return prepareMemoryTransitionAtRev(root, sha, memoryYaml, id, op);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The body of {@link prepareMemoryTransition}, at a sha and a committed `memory.yaml` the caller has
|
|
224
|
+
* already resolved: locate document `id` at `sha`, check the working tree carries the same element,
|
|
225
|
+
* and resolve `op` on its committed `status`. Every refusal {@link prepareMemoryTransition} documents
|
|
226
|
+
* past the `memory.yaml` read comes from here, unchanged.
|
|
227
|
+
*
|
|
228
|
+
* It exists so that a second decision in one command reads the same commit as the first: the
|
|
229
|
+
* `supersedes:` trigger (task-162) prepares the superseded element at the sha its superseding
|
|
230
|
+
* element's approve was decided at, with `op` `supersede`. With `expectedType`, a document of another
|
|
231
|
+
* type is refused (`VALIDATION`) before its own machine is consulted, since the caller's rule is about
|
|
232
|
+
* the type, not about that machine's states.
|
|
233
|
+
*/
|
|
234
|
+
function prepareMemoryTransitionAtRev(root, sha, memoryYaml, id, op, expectedType) {
|
|
235
|
+
// Tolerant (task-171, `bug-031`): a committed document the scan cannot read no longer refuses the
|
|
236
|
+
// transition of another element. It is skipped and reported; the verb's success carries it as a
|
|
237
|
+
// warning, and a miss names it, since the id may be in it.
|
|
238
|
+
const unreadable = [];
|
|
239
|
+
let found;
|
|
240
|
+
try {
|
|
241
|
+
found = (0, memory_1.findMemoryDocumentByIdAtRev)(root, sha, memoryYaml, id, { onDiagnostic: (diagnostic) => unreadable.push(diagnostic) });
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
// The lookup throws only the `dl-149` refusal of the element it names (task-257, `bug-241`).
|
|
245
|
+
return newerFormatRefusal(op, id, 'HEAD', error);
|
|
246
|
+
}
|
|
104
247
|
if (!found) {
|
|
105
|
-
|
|
248
|
+
const onDisk = uncommittedDocumentPath(root, memoryYaml, id);
|
|
249
|
+
if (onDisk !== undefined) {
|
|
250
|
+
// A document reached through a symbolic link (its own name, or its type directory) is not a
|
|
251
|
+
// tree entry under the scan roots at HEAD, so the HEAD lookup cannot find it; the refusal is
|
|
252
|
+
// already decided, and the filesystem guard words it truthfully (bug-117, bug-120 D2).
|
|
253
|
+
const confined = (0, confinement_1.requireConfinedWriteTarget)(root, onDisk, 'write');
|
|
254
|
+
if (!confined.ok)
|
|
255
|
+
return confined;
|
|
256
|
+
const inspectable = (0, write_guard_1.requireInspectableTarget)(root, onDisk, TRANSITION_CONTRACT);
|
|
257
|
+
if (!inspectable.ok)
|
|
258
|
+
return inspectable;
|
|
259
|
+
const recorded = recordedIdAt(root, sha, onDisk);
|
|
260
|
+
if (recorded !== undefined) {
|
|
261
|
+
return (0, types_1.coreErr)({
|
|
262
|
+
code: 'VALIDATION',
|
|
263
|
+
message: `refusing to ${op} ${id}: the working tree changes frontmatter field 'id' of ${onDisk}, which HEAD records ` +
|
|
264
|
+
`as '${recorded}'. A transition acts on the element the commit records; restore the id, then retry.`,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return (0, types_1.coreErr)({
|
|
268
|
+
code: 'NOT_FOUND',
|
|
269
|
+
message: `document not found: ${id} — ${onDisk} is not committed at HEAD, though it carries that id in the working tree. ` +
|
|
270
|
+
'A transition is decided by the status the repository records (spec-006 §6 item 1, dl-080), so it acts only ' +
|
|
271
|
+
'on a committed element; register a new element with `memory add`, then retry.',
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return (0, types_1.coreErr)({
|
|
275
|
+
code: 'NOT_FOUND',
|
|
276
|
+
message: `document not found: ${id}${unreadableNote(unreadable)}${uncommittedMachineNote(root)}`,
|
|
277
|
+
...(unreadable.length > 0 ? { details: { issues: unreadable } } : {}),
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
const path = found.path;
|
|
281
|
+
// `lstat`, which never follows a link: a symbolic link in place of the document is present even when
|
|
282
|
+
// it dangles. A live one reaches the write-side guards `commitMemoryTransition` runs (REQ-SEC-06,
|
|
283
|
+
// `bug-120`); a dangling one is refused here, because the content read below would fail on it first
|
|
284
|
+
// (task-247 review).
|
|
285
|
+
const present = isPresent((0, path_1.join)(root, path));
|
|
286
|
+
if (present && !(0, fs_1.existsSync)((0, path_1.join)(root, path))) {
|
|
287
|
+
return (0, types_1.coreErr)({
|
|
288
|
+
code: 'VALIDATION',
|
|
289
|
+
message: `refusing to ${op} ${id}: its document '${path}' is a symbolic link whose target does not exist in the working ` +
|
|
290
|
+
`tree. Restore the committed file (git restore --source=HEAD --staged --worktree -- ${path}) and retry.`,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (!present) {
|
|
294
|
+
// `--source=HEAD --staged --worktree`: a plain `git restore -- <path>` restores from the index,
|
|
295
|
+
// which no longer holds the path after `git rm` or `git mv` (task-247 review).
|
|
296
|
+
return (0, types_1.coreErr)({
|
|
297
|
+
code: 'VALIDATION',
|
|
298
|
+
message: `refusing to ${op} ${id}: its document '${path}' is held by HEAD but deleted in the working tree. Restore it ` +
|
|
299
|
+
`(git restore --source=HEAD --staged --worktree -- ${path}) and retry.`,
|
|
300
|
+
});
|
|
106
301
|
}
|
|
107
302
|
const type = found.frontmatter.type;
|
|
303
|
+
if (expectedType !== undefined && type !== expectedType) {
|
|
304
|
+
return (0, types_1.coreErr)({
|
|
305
|
+
code: 'VALIDATION',
|
|
306
|
+
message: `${id}, which is of type '${String(type)}', not of type '${expectedType}': only an element of the same type can be ${op}d`,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
108
309
|
if (typeof type !== 'string' || memoryYaml.types[type] === undefined) {
|
|
109
310
|
return (0, types_1.coreErr)({
|
|
110
311
|
code: 'NOT_FOUND',
|
|
@@ -122,10 +323,66 @@ function prepareMemoryTransition(root, id, op) {
|
|
|
122
323
|
// A missing or non-string `status` is reported as an invalid state, never as the text 'undefined'.
|
|
123
324
|
const from = typeof status === 'string' ? status : String(status ?? '');
|
|
124
325
|
try {
|
|
125
|
-
(0, memory_1.validateFrontmatterState)(machine, type, from,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
326
|
+
(0, memory_1.validateFrontmatterState)(machine, type, from, path);
|
|
327
|
+
// `amend` moves no state (`dl-108`): its edge is the self-loop `[s → s]` in every state, so no
|
|
328
|
+
// machine lookup can refuse it. Whether the TYPE may be amended is the verb's own check.
|
|
329
|
+
const to = op === 'amend'
|
|
330
|
+
? from
|
|
331
|
+
: op === 'supersede'
|
|
332
|
+
? (0, memory_1.resolveSupersedeTarget)(memoryYaml, type, from, path)
|
|
333
|
+
: op === 'finalize'
|
|
334
|
+
? (0, memory_1.resolveWaitingTarget)(memoryYaml, type, from, path)
|
|
335
|
+
: (0, memory_1.resolveTypeTransition)(memoryYaml, type, from, op, path);
|
|
336
|
+
// A self-loop (`amend`) enters no state, so it takes no slot. Nor does a return (`dl-156` Q2 (i),
|
|
337
|
+
// task-274): `reject` only ever takes a `gates.<from>.reject` edge and `park` only a
|
|
338
|
+
// `returns.<from>` edge (`resolveTransitionTarget`), and a reject or returns edge is exempt: the
|
|
339
|
+
// approver's verdict and a scheduling step are not capped by a capacity rule (a `bug`'s reject edges
|
|
340
|
+
// even lead forward, to `closed`). Keyed on the verb, not on the target, so an `approve` whose
|
|
341
|
+
// forward target equals the gate's reject target still takes the check. A `finalize` (task-217)
|
|
342
|
+
// enters a state like any forward move, so it takes the check too.
|
|
343
|
+
if (to !== from && op !== 'reject' && op !== 'park') {
|
|
344
|
+
const slot = requireWipSlot(root, sha, memoryYaml, type, to, id);
|
|
345
|
+
if (!slot.ok)
|
|
346
|
+
return slot;
|
|
347
|
+
// The documents the slot count could not read, if the lookup above has not already named them.
|
|
348
|
+
for (const diagnostic of slot.value) {
|
|
349
|
+
if (!unreadable.some((known) => known.file === diagnostic.file))
|
|
350
|
+
unreadable.push(diagnostic);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Content from the working tree: what `submit` and `amend` commit, and what the other verbs'
|
|
354
|
+
// unmodified-document guard compares with `HEAD`. A working-tree edit that declares a newer
|
|
355
|
+
// `format` is refused before it can be committed (task-257, `bug-241`).
|
|
356
|
+
let frontmatter;
|
|
357
|
+
try {
|
|
358
|
+
({ frontmatter } = (0, memory_1.loadMemoryDocumentSummary)(root, path));
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
return newerFormatRefusal(op, id, 'the working tree', error);
|
|
362
|
+
}
|
|
363
|
+
const changed = ['id', 'type'].filter((key) => frontmatter[key] !== found.frontmatter[key]);
|
|
364
|
+
if (changed.length > 0) {
|
|
365
|
+
return (0, types_1.coreErr)({
|
|
366
|
+
code: 'VALIDATION',
|
|
367
|
+
message: `refusing to ${op} ${id}: the working tree changes ${changed.map((key) => `frontmatter field '${key}'`).join(' and ')} ` +
|
|
368
|
+
`of ${path}, which HEAD records as ${changed.map((key) => `'${String(found.frontmatter[key])}'`).join(' and ')}. ` +
|
|
369
|
+
'A transition acts on the element the commit records; restore the recorded value, then retry.',
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
const content = (0, storage_1.readDocument)((0, path_1.join)(root, path));
|
|
373
|
+
return (0, types_1.coreOk)({
|
|
374
|
+
memoryYaml,
|
|
375
|
+
id,
|
|
376
|
+
type,
|
|
377
|
+
path,
|
|
378
|
+
frontmatter,
|
|
379
|
+
content,
|
|
380
|
+
from,
|
|
381
|
+
to,
|
|
382
|
+
sha,
|
|
383
|
+
committedFrontmatter: found.frontmatter,
|
|
384
|
+
warnings: unreadable.map(validation_1.formatDiagnostic),
|
|
385
|
+
});
|
|
129
386
|
}
|
|
130
387
|
catch (error) {
|
|
131
388
|
if (!(error instanceof validation_1.ValidationError))
|
|
@@ -135,6 +392,148 @@ function prepareMemoryTransition(root, id, op) {
|
|
|
135
392
|
return (0, types_1.coreErr)({ code, message, details: { issues: error.issues } });
|
|
136
393
|
}
|
|
137
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* The sentence every WIP refusal ends with (`dl-156` Q1 (a), task-274): where the holders were counted,
|
|
397
|
+
* that a clone sees only the refs it has fetched, and where a holder recorded elsewhere is moved out.
|
|
398
|
+
*/
|
|
399
|
+
exports.WIP_REFS_SENTENCE = 'The holders are counted at HEAD and on every local and remote-tracking branch that changed them since it forked from HEAD, ' +
|
|
400
|
+
'so the count depends on which refs were last fetched; a holder another branch records is moved out on that branch.';
|
|
401
|
+
/**
|
|
402
|
+
* Refuse to move an element into `state` when the type's machine declares a WIP limit there
|
|
403
|
+
* (`limits: { <state>: N }`, `spec-001`, `dl-110` P3 (a), task-180) and N elements of the type already
|
|
404
|
+
* hold it — `CONFLICT`, exit `1`, naming every holder in path order, before anything is written.
|
|
405
|
+
*
|
|
406
|
+
* The one shared check: {@link prepareMemoryTransitionAtRev} calls it for every transition into a new
|
|
407
|
+
* state except along a reject or `returns` edge (`submit`, `approve`, the `supersedes:` trigger, and
|
|
408
|
+
* any workflow emitter that prepares its transition there — not `reject` nor `park`, `dl-156` Q2 (i)),
|
|
409
|
+
* and `memory add` calls it for the initial state, since `add` is the verb that enters that state.
|
|
410
|
+
*
|
|
411
|
+
* **Where the holders are counted** (`dl-156` Q1 (a), task-274, as the approver ruled on 2026-10-11 at
|
|
412
|
+
* its review, option (a)): each element of the type counts in one state —
|
|
413
|
+
*
|
|
414
|
+
* - the state a ref records, when that ref **changed** the element since its merge-base with commit
|
|
415
|
+
* `sha` (the one the transition is decided at, `dl-080`): its `status` differs from the merge-base
|
|
416
|
+
* copy's, or the merge-base has no copy (an element added on the ref; a ref sharing no history with
|
|
417
|
+
* `sha` counts every copy it holds). The refs are those {@link refBaselineCommits} lists for
|
|
418
|
+
* `memory add`'s id counter (`dl-101` §2 (a)); a ref that is an ancestor of `sha` changed nothing.
|
|
419
|
+
* When several refs changed it, the most advanced of their copies wins
|
|
420
|
+
* ({@link isMoreAdvancedState}), the decided commit's copy not competing;
|
|
421
|
+
* - otherwise the state commit `sha` records.
|
|
422
|
+
*
|
|
423
|
+
* So a stale branch does not keep a parked holder counted, and an older copy elsewhere does not hide an
|
|
424
|
+
* element a reject moved back into the state. "Changed" compares `status`, not bytes: an edit that
|
|
425
|
+
* leaves the status alone (Execution Notes, an amend) is not a move. `exceptId`, the element being
|
|
426
|
+
* moved, is never its own holder. The refusal ends with {@link WIP_REFS_SENTENCE}. This read is wider
|
|
427
|
+
* than `HEAD`, which the `command-baseline` directive declares by name.
|
|
428
|
+
*
|
|
429
|
+
* Only the type's directory is read, every commit's listing and every distinct blob in one batch each,
|
|
430
|
+
* each blob parsed once (`loadTypeDocumentCopiesAtRevs`; task-274 review F2, the `bug-178` class);
|
|
431
|
+
* one `git merge-base` per ref. A document none of those reads can parse is not counted (task-171's
|
|
432
|
+
* tolerant scan) and is returned as a `W_MEMORY_UNREADABLE` diagnostic, once per file, which the
|
|
433
|
+
* caller's success carries as a warning and a refusal carries in `details.issues`, so a limit that may
|
|
434
|
+
* be undercounted says so. Without a declared limit nothing is read and nothing is returned.
|
|
435
|
+
*/
|
|
436
|
+
function requireWipSlot(root, sha, memoryYaml, type, state, exceptId) {
|
|
437
|
+
const machine = (0, memory_1.resolveStateMachine)(memoryYaml, type);
|
|
438
|
+
const limit = machine.limits?.[state];
|
|
439
|
+
if (limit === undefined)
|
|
440
|
+
return (0, types_1.coreOk)([]);
|
|
441
|
+
const decided = (0, revision_1.resolveRevision)(root, sha);
|
|
442
|
+
const refs = (0, memory_1.refBaselineCommits)(root).filter((commit) => commit !== decided);
|
|
443
|
+
const bases = (0, storage_1.mergeBasesWith)(root, decided, refs);
|
|
444
|
+
// A ref that is an ancestor of the decided commit changed nothing the decided commit lacks.
|
|
445
|
+
const moved = refs.map((ref, index) => ({ ref, base: bases[index] })).filter(({ ref, base }) => base !== ref);
|
|
446
|
+
const revs = [...new Set([decided, ...moved.map(({ ref }) => ref), ...moved.flatMap(({ base }) => (base === null ? [] : [base]))])];
|
|
447
|
+
const unreadable = [];
|
|
448
|
+
const onDiagnostic = (diagnostic) => {
|
|
449
|
+
if (!unreadable.some((known) => known.file === diagnostic.file))
|
|
450
|
+
unreadable.push(diagnostic);
|
|
451
|
+
};
|
|
452
|
+
const copiesAt = new Map();
|
|
453
|
+
(0, memory_1.loadTypeDocumentCopiesAtRevs)(root, revs, memoryYaml, type, { onDiagnostic }).forEach((copies, index) => {
|
|
454
|
+
const byKey = new Map();
|
|
455
|
+
for (const { frontmatter, path } of copies) {
|
|
456
|
+
// A copy with no string `status` holds no state, and is no move either.
|
|
457
|
+
if (typeof frontmatter.status !== 'string')
|
|
458
|
+
continue;
|
|
459
|
+
const id = frontmatter.id === undefined ? undefined : String(frontmatter.id);
|
|
460
|
+
byKey.set(id === undefined ? `path:${path}` : `id:${id}`, { name: id ?? path, path, state: frontmatter.status });
|
|
461
|
+
}
|
|
462
|
+
copiesAt.set(revs[index], byKey);
|
|
463
|
+
});
|
|
464
|
+
// The decided commit's copy, unless a ref changed the element since the fork.
|
|
465
|
+
const elements = new Map(copiesAt.get(decided));
|
|
466
|
+
const changed = new Map();
|
|
467
|
+
for (const { ref, base } of moved) {
|
|
468
|
+
const atBase = base === null ? new Map() : copiesAt.get(base);
|
|
469
|
+
for (const [key, copy] of copiesAt.get(ref)) {
|
|
470
|
+
if (atBase.get(key)?.state === copy.state)
|
|
471
|
+
continue;
|
|
472
|
+
const known = changed.get(key);
|
|
473
|
+
if (known === undefined || isMoreAdvancedState(machine, copy.state, known.state))
|
|
474
|
+
changed.set(key, copy);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
for (const [key, copy] of changed)
|
|
478
|
+
elements.set(key, copy);
|
|
479
|
+
// Path order, then the element key (unique), as one string each: the default sort is by UTF-16 code
|
|
480
|
+
// units, independent of locale and of the order the commits were read in (REQ-SYS-07).
|
|
481
|
+
const named = new Map();
|
|
482
|
+
for (const [key, element] of elements) {
|
|
483
|
+
if (element.state === state && element.name !== exceptId)
|
|
484
|
+
named.set(`${element.path}\u0000${key}`, element.name);
|
|
485
|
+
}
|
|
486
|
+
const holders = [...named.keys()].sort().map((order) => named.get(order));
|
|
487
|
+
if (holders.length < limit)
|
|
488
|
+
return (0, types_1.coreOk)(unreadable);
|
|
489
|
+
return (0, types_1.coreErr)({
|
|
490
|
+
code: 'CONFLICT',
|
|
491
|
+
message: `WIP limit reached for '${state}' on type '${type}' (limit ${limit}): held by ${holders.join(', ')}. ` +
|
|
492
|
+
`Move one of them out of '${state}', then retry. ${exports.WIP_REFS_SENTENCE}`,
|
|
493
|
+
...(unreadable.length > 0 ? { details: { issues: unreadable } } : {}),
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Whether state `a` is further along `machine` than state `b` — the rule that picks the one state an
|
|
498
|
+
* element counts in when the refs disagree (`dl-156` Q1 (a): "the most advanced state wins"). A
|
|
499
|
+
* `sequence` state ranks by its position; a state outside `sequence` (an off-chain `gates` reject
|
|
500
|
+
* target, `deprecated`, or a value the machine does not declare) ranks after every `sequence` state,
|
|
501
|
+
* since the element has left the chain, and `deprecated` ranks last of all. Equal ranks are ordered by
|
|
502
|
+
* name, so the answer never depends on the order the commits were read in (REQ-SYS-07). Pure.
|
|
503
|
+
*/
|
|
504
|
+
function isMoreAdvancedState(machine, a, b) {
|
|
505
|
+
const rank = (state) => {
|
|
506
|
+
if (state === memory_1.DEPRECATED_STATE)
|
|
507
|
+
return machine.sequence.length + 1;
|
|
508
|
+
const index = machine.sequence.indexOf(state);
|
|
509
|
+
return index === -1 ? machine.sequence.length : index;
|
|
510
|
+
};
|
|
511
|
+
const ra = rank(a);
|
|
512
|
+
const rb = rank(b);
|
|
513
|
+
return ra !== rb ? ra > rb : a > b;
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* The shared preamble of every state-moving `memory` verb — `submit`, `approve`, `reject`,
|
|
517
|
+
* `deprecate`, `amend` — written once (task-132, `bug-142`): resolve the git identity
|
|
518
|
+
* (`requireGitIdentity`, REQ-SEC-01, exit `1`), then locate the document and resolve verb `op` on it
|
|
519
|
+
* ({@link prepareMemoryTransition}, exit `1`). The first refusal is returned unchanged; nothing is
|
|
520
|
+
* written either way.
|
|
521
|
+
*
|
|
522
|
+
* The identity is read here ONCE and rides the result, so no verb reads it again (the structural test
|
|
523
|
+
* `test/core/memory-transition-preamble.test.ts` holds every registered transition verb to that).
|
|
524
|
+
* The order matches `spec-006` §7: a verb's usage checks run before it calls this (task-125,
|
|
525
|
+
* `bug-172`), and an approver-gated verb's authority check runs after it, because that check's
|
|
526
|
+
* message names the document's type, which only this step knows.
|
|
527
|
+
*/
|
|
528
|
+
function beginMemoryTransition(root, id, op) {
|
|
529
|
+
const identity = (0, git_identity_1.requireGitIdentity)(root);
|
|
530
|
+
if (!identity.ok)
|
|
531
|
+
return identity;
|
|
532
|
+
const prepared = prepareMemoryTransition(root, id, op);
|
|
533
|
+
if (!prepared.ok)
|
|
534
|
+
return prepared;
|
|
535
|
+
return (0, types_1.coreOk)({ ...prepared.value, identity: identity.value });
|
|
536
|
+
}
|
|
138
537
|
/**
|
|
139
538
|
* Refuse, before anything is written, a document that already carries modifications this transition
|
|
140
539
|
* does not own (task-088, `bug-076`; AC2 option (b)).
|
|
@@ -148,10 +547,10 @@ function prepareMemoryTransition(root, id, op) {
|
|
|
148
547
|
*
|
|
149
548
|
* **Why refusing rather than committing only the status hunk.** Partial staging is undefined here
|
|
150
549
|
* before it is difficult: there are two candidate baselines on disk (the index and the working tree)
|
|
151
|
-
* and they can disagree, so "only the status hunk" does not say onto which text. Worse,
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* asserting something that did not happen, which is the defect, not a fix for it. And the edits a
|
|
550
|
+
* and they can disagree, so "only the status hunk" does not say onto which text. Worse, a
|
|
551
|
+
* hand-edited-but-uncommitted `status` riding along would have the commit record `draft → approved`
|
|
552
|
+
* under a subject declaring `pending → approved` (the subject's `from` is `HEAD`'s since task-247) —
|
|
553
|
+
* the audit trail asserting something that did not happen, which is the defect, not a fix for it. And the edits a
|
|
155
554
|
* partial commit left behind would be invisible, deferred, and swept into whatever commits next. A
|
|
156
555
|
* refusal costs the user two commands, now, on a document this function has provably not touched.
|
|
157
556
|
*
|
|
@@ -193,11 +592,41 @@ function verifyCommittedScope(root, sha, path, expected, scope) {
|
|
|
193
592
|
return [...problems, `it does not contain '${path}'`];
|
|
194
593
|
return [...problems, ...(0, memory_1.verifyDocumentEdit)((0, storage_1.readPathAtRev)(root, parent, path) ?? '', after, expected, scope)];
|
|
195
594
|
}
|
|
595
|
+
/**
|
|
596
|
+
* The pre-write half of {@link commitMemoryTransition} — its checks 1 to 3 (confinement, an
|
|
597
|
+
* unmodified working tree under `declared-fields-only` or no divergent stage under
|
|
598
|
+
* `carries-content`, and the rendering's post-condition), with nothing written. A command that makes
|
|
599
|
+
* more than one commit runs it on every document first, so a refusal of any of them leaves the
|
|
600
|
+
* repository as it was (the `supersedes:` trigger, task-162). {@link commitMemoryTransition} runs it
|
|
601
|
+
* again before its own write, so calling it first is never required for safety.
|
|
602
|
+
*/
|
|
603
|
+
function checkMemoryTransition(root, prepared, content, expected = {}, scope = 'declared-fields-only') {
|
|
604
|
+
const owned = { status: prepared.to, ...expected };
|
|
605
|
+
const confined = (0, confinement_1.requireConfinedWriteTarget)(root, prepared.path, 'write');
|
|
606
|
+
if (!confined.ok)
|
|
607
|
+
return confined;
|
|
608
|
+
const unmodified = scope === 'declared-fields-only'
|
|
609
|
+
? requireUnmodifiedDocument(root, prepared)
|
|
610
|
+
: (0, write_guard_1.requireNoDivergentStage)(root, prepared.path, TRANSITION_CONTRACT);
|
|
611
|
+
if (!unmodified.ok)
|
|
612
|
+
return unmodified;
|
|
613
|
+
const problems = (0, memory_1.verifyDocumentEdit)(prepared.content, content, owned, 'declared-fields-only');
|
|
614
|
+
if (problems.length > 0) {
|
|
615
|
+
return (0, types_1.coreErr)({
|
|
616
|
+
code: 'VALIDATION',
|
|
617
|
+
message: `refusing to write ${prepared.path}: the rendered document failed its post-condition: ${problems.join('; ')}`,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
return (0, types_1.coreOk)(undefined);
|
|
621
|
+
}
|
|
196
622
|
/**
|
|
197
623
|
* Write `content` over the prepared document and commit exactly that one path with `message`,
|
|
198
624
|
* returning the new commit's sha (`commitPaths`, task-018; scoped to that path even when other changes
|
|
199
|
-
* are staged, bug-027).
|
|
200
|
-
*
|
|
625
|
+
* are staged, bug-027). The commit's author is pinned to `prepared.identity` — the identity the
|
|
626
|
+
* pre-flight checked, and the one any `Approver:` line names — so git's own author resolution cannot
|
|
627
|
+
* substitute another (task-132, `bug-149`). `prepared` comes from {@link beginMemoryTransition}, which
|
|
628
|
+
* is how the git-identity pre-flight (REQ-SEC-01) is guaranteed to have run; callers run every other
|
|
629
|
+
* refusal check first, and this step is the only write.
|
|
201
630
|
*
|
|
202
631
|
* Four checks bound what reaches the repository, in this order — they are not redundant, they catch
|
|
203
632
|
* different defects:
|
|
@@ -216,7 +645,10 @@ function verifyCommittedScope(root, sha, path, expected, scope) {
|
|
|
216
645
|
* --porcelain` reports a path beyond a symbolic link as clean, which is `bug-118`).
|
|
217
646
|
* 2. **The working tree is unmodified** ({@link requireUnmodifiedDocument}, `declared-fields-only`
|
|
218
647
|
* only) — catches a wrong *baseline*: content that was already on disk before the verb ran
|
|
219
|
-
* (`bug-076`).
|
|
648
|
+
* (`bug-076`). Under `carries-content` the working tree IS the content, so the check narrows to
|
|
649
|
+
* `requireNoDivergentStage`: a staged version differing from both `HEAD` and the working tree,
|
|
650
|
+
* which `git add` would silently discard, is refused (task-131, `bug-182`). Both shapes first
|
|
651
|
+
* refuse a document behind a symlinked directory, which git cannot report on (`bug-118`).
|
|
220
652
|
* 3. **The rendering is in scope** ({@link verifyDocumentEdit} against the prepared document) —
|
|
221
653
|
* catches a defect in the *editor*: `status` must be the prepared target, every field in `expected`
|
|
222
654
|
* must have its value (`undefined` = absent), and no other field and no byte of the body may have
|
|
@@ -229,34 +661,23 @@ function verifyCommittedScope(root, sha, path, expected, scope) {
|
|
|
229
661
|
* Checks 1–3 report a `VALIDATION` error (exit 1) with nothing written or committed. Check 4 can
|
|
230
662
|
* only report; see {@link verifyCommittedScope}.
|
|
231
663
|
*
|
|
232
|
-
* Check 1 resolves on the **working tree**, not at `HEAD
|
|
233
|
-
*
|
|
234
|
-
* `dl-086-a-guard-over-a-filesystem-effect-resolves-on-the-filesystem`
|
|
235
|
-
* rather than re-made: it predicts where `writeDocument` will land, and that follows
|
|
236
|
-
* disk rather than the ones a commit records.
|
|
664
|
+
* Check 1 resolves on the **working tree**, not at `HEAD`: it is the filesystem-effect read
|
|
665
|
+
* `command-baseline` and `spec-006-core-domain-api` §6 declare, ratified in
|
|
666
|
+
* `dl-086-a-guard-over-a-filesystem-effect-resolves-on-the-filesystem` from `task-102`'s argument,
|
|
667
|
+
* which is cited rather than re-made: it predicts where `writeDocument` will land, and that follows
|
|
668
|
+
* the symlinks on disk rather than the ones a commit records.
|
|
237
669
|
*
|
|
238
670
|
* @param scope - How much of the document this operation owns; defaults to the strict
|
|
239
671
|
* `declared-fields-only`, so a new verb is guarded unless it opts out deliberately.
|
|
672
|
+
* @param warnings - The success warnings the verb will report, handed to the commit primitive so a dry
|
|
673
|
+
* run carries them (task-210 review, F4); defaults to the lookup's own, `prepared.warnings`.
|
|
240
674
|
*/
|
|
241
|
-
function commitMemoryTransition(root, prepared, content, message, expected = {}, scope = 'declared-fields-only') {
|
|
675
|
+
function commitMemoryTransition(root, prepared, content, message, expected = {}, scope = 'declared-fields-only', warnings = prepared.warnings) {
|
|
676
|
+
const checked = checkMemoryTransition(root, prepared, content, expected, scope);
|
|
677
|
+
if (!checked.ok)
|
|
678
|
+
return checked;
|
|
242
679
|
const owned = { status: prepared.to, ...expected };
|
|
243
|
-
const
|
|
244
|
-
if (!confined.ok)
|
|
245
|
-
return confined;
|
|
246
|
-
if (scope === 'declared-fields-only') {
|
|
247
|
-
const unmodified = requireUnmodifiedDocument(root, prepared);
|
|
248
|
-
if (!unmodified.ok)
|
|
249
|
-
return unmodified;
|
|
250
|
-
}
|
|
251
|
-
const problems = (0, memory_1.verifyDocumentEdit)(prepared.content, content, owned, 'declared-fields-only');
|
|
252
|
-
if (problems.length > 0) {
|
|
253
|
-
return (0, types_1.coreErr)({
|
|
254
|
-
code: 'VALIDATION',
|
|
255
|
-
message: `refusing to write ${prepared.path}: the rendered document failed its post-condition: ${problems.join('; ')}`,
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
(0, storage_1.writeDocument)((0, path_1.join)(root, prepared.path), content);
|
|
259
|
-
const sha = (0, storage_1.commitPaths)(root, [prepared.path], message);
|
|
680
|
+
const sha = (0, storage_1.writeAndCommit)(root, [{ path: prepared.path, content }], message, { author: prepared.identity, warnings });
|
|
260
681
|
const leaked = verifyCommittedScope(root, sha, prepared.path, owned, scope);
|
|
261
682
|
if (leaked.length > 0) {
|
|
262
683
|
return (0, types_1.coreErr)({
|