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
package/dist/memory/query.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.E_EMPTY_SEARCH_QUERY = void 0;
|
|
3
|
+
exports.E_EMPTY_SEARCH_QUERY = exports.W_MEMORY_UNREADABLE = void 0;
|
|
4
4
|
exports.computeMemoryContentRoots = computeMemoryContentRoots;
|
|
5
|
+
exports.memoryUnreadableDiagnostic = memoryUnreadableDiagnostic;
|
|
6
|
+
exports.firstLineOf = firstLineOf;
|
|
5
7
|
exports.listMemoryDocumentPaths = listMemoryDocumentPaths;
|
|
6
8
|
exports.loadMemoryDocumentSummary = loadMemoryDocumentSummary;
|
|
9
|
+
exports.loadMemoryDocuments = loadMemoryDocuments;
|
|
10
|
+
exports.listMemoryDocumentPathsAtRev = listMemoryDocumentPathsAtRev;
|
|
11
|
+
exports.loadMemoryDocumentsAtRev = loadMemoryDocumentsAtRev;
|
|
12
|
+
exports.loadMemoryDocumentsAtCommit = loadMemoryDocumentsAtCommit;
|
|
13
|
+
exports.loadMemoryDocumentSummaryAtRev = loadMemoryDocumentSummaryAtRev;
|
|
7
14
|
exports.findMemoryDocumentById = findMemoryDocumentById;
|
|
15
|
+
exports.findMemoryDocumentByIdAtRev = findMemoryDocumentByIdAtRev;
|
|
8
16
|
exports.listMemoryDocumentsByType = listMemoryDocumentsByType;
|
|
9
17
|
exports.findMemoryDocumentByTypeAndId = findMemoryDocumentByTypeAndId;
|
|
18
|
+
exports.findMemoryDocumentByTypeAndIdAtRev = findMemoryDocumentByTypeAndIdAtRev;
|
|
10
19
|
exports.validateSearchQuery = validateSearchQuery;
|
|
11
20
|
exports.searchMemoryDocuments = searchMemoryDocuments;
|
|
21
|
+
exports.loadTypeDocumentCopiesAtRevs = loadTypeDocumentCopiesAtRevs;
|
|
12
22
|
/**
|
|
13
23
|
* Memory query primitives (task-008-dna-memory-query-latency, REQ-PERF-02; match/rank algorithm and
|
|
14
24
|
* empty-query validation hardened by task-023-implement-keyword-search, P1.12) — the performance-
|
|
@@ -53,12 +63,34 @@ exports.searchMemoryDocuments = searchMemoryDocuments;
|
|
|
53
63
|
* `draft` is deliberately NOT excluded here: spec-012 §6 excludes drafts from an assembled agent
|
|
54
64
|
* *context*, but REQ-STATE-06 scopes default-search exclusion to archived content only, so a draft
|
|
55
65
|
* document a user is actively working on stays findable. The two filters are different sets on purpose.
|
|
66
|
+
*
|
|
67
|
+
* **Fail closed on archived elements (task-171, `dl-038` option 1).** {@link listMemoryDocumentsByType}
|
|
68
|
+
* and {@link findMemoryDocumentByTypeAndId} (and its `…AtRev` sibling) exclude archived documents by
|
|
69
|
+
* default too, so a consumer that forgets to filter does not reach them; the one that must —
|
|
70
|
+
* `wingfoil://memory/{type}/{id}` — passes `includeArchived: true`. {@link findMemoryDocumentById}
|
|
71
|
+
* stays neutral: `memory history` and the transition verbs act on archived elements.
|
|
72
|
+
*
|
|
73
|
+
* **Tolerant reads (task-171, `bug-031`, `spec-017` §1.4).** A scan never throws on a document it
|
|
74
|
+
* cannot read. A document whose frontmatter does not parse, and a symbolic link (never followed and
|
|
75
|
+
* never parsed, by either baseline, `bug-189`), are left out and reported to the caller's
|
|
76
|
+
* {@link MemoryScanOptions.onDiagnostic} as {@link W_MEMORY_UNREADABLE}, in path order. Only the
|
|
77
|
+
* single-file read {@link loadMemoryDocumentSummary} still throws: its caller named that file.
|
|
78
|
+
*
|
|
79
|
+
* **The `format` key (task-257, `bug-241`, `dl-149`).** An element keeps the `format` of the template
|
|
80
|
+
* it was copied from and reads with that counter, `MEMORY_TEMPLATE_FORMAT`; absent reads as `1`. An
|
|
81
|
+
* element written in a newer format is not read by today's rules: a collection scan leaves it out and
|
|
82
|
+
* reports it as {@link W_MEMORY_UNREADABLE}, naming the file and the "upgrade WingFoil" refusal; a
|
|
83
|
+
* single-file read, and a lookup by id that reaches the element it names, throw that refusal
|
|
84
|
+
* (`ValidationError`, `E_INVALID_FORMAT`, exit `1`); a lookup reports one it passes on its way.
|
|
56
85
|
*/
|
|
57
86
|
const fs_1 = require("fs");
|
|
58
87
|
const path_1 = require("path");
|
|
59
88
|
const validation_1 = require("../validation");
|
|
60
89
|
const state_machine_1 = require("./state-machine");
|
|
61
90
|
const storage_1 = require("../storage");
|
|
91
|
+
// The module, not the `../core` barrel: `src/core` imports this module, and `./revision` depends on
|
|
92
|
+
// `../storage` alone, so nothing here closes a load-time cycle.
|
|
93
|
+
const revision_1 = require("../core/revision");
|
|
62
94
|
/**
|
|
63
95
|
* The static (placeholder-free) directory prefix of a `memory.yaml` type `path` pattern — e.g.
|
|
64
96
|
* `"docs/04_memory/design/adrs/{id}.md"` -> `"docs/04_memory/design/adrs"`. A pattern whose first
|
|
@@ -88,8 +120,43 @@ function computeMemoryContentRoots(memoryYaml) {
|
|
|
88
120
|
const all = [...dirs].sort();
|
|
89
121
|
return all.filter((dir) => !all.some((other) => other !== dir && dir.startsWith(`${other}/`)));
|
|
90
122
|
}
|
|
91
|
-
/**
|
|
92
|
-
|
|
123
|
+
/** `W_MEMORY_UNREADABLE` (`spec-017` §1.4, §2): a Memory file a scan left out because it cannot read it. */
|
|
124
|
+
exports.W_MEMORY_UNREADABLE = 'W_MEMORY_UNREADABLE';
|
|
125
|
+
/** The reason {@link W_MEMORY_UNREADABLE} gives for a symbolic link (task-171, `bug-189`). */
|
|
126
|
+
const SYMLINK_REASON = 'a symbolic link is not read as a Memory document';
|
|
127
|
+
/**
|
|
128
|
+
* The one builder of a {@link W_MEMORY_UNREADABLE} diagnostic, shared by the scan here and by
|
|
129
|
+
* `spec-017`'s deduction: `spec-003`'s shape, `file` repository-relative, `path` `''` (the whole file),
|
|
130
|
+
* and `spec-017` §1.4's message `unreadable frontmatter in <file>: <reason>`.
|
|
131
|
+
*/
|
|
132
|
+
function memoryUnreadableDiagnostic(file, reason) {
|
|
133
|
+
return { code: exports.W_MEMORY_UNREADABLE, severity: 'warning', file, path: '', message: `unreadable frontmatter in ${file}: ${reason}` };
|
|
134
|
+
}
|
|
135
|
+
/** The first line of a parse error: js-yaml appends a multi-line excerpt a one-line warning cannot carry. */
|
|
136
|
+
function firstLineOf(message) {
|
|
137
|
+
return message.split('\n')[0].trim();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Code-unit order of two strings, as `Array.prototype.sort()` orders them by default, written without
|
|
141
|
+
* a branch: `1`, `0` or `-1`.
|
|
142
|
+
*/
|
|
143
|
+
function compareText(a, b) {
|
|
144
|
+
return Number(a > b) - Number(a < b);
|
|
145
|
+
}
|
|
146
|
+
/** Ascending by path. */
|
|
147
|
+
function byPath(a, b) {
|
|
148
|
+
return compareText(a.path, b.path);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Recursively list every `.md` entry under `root/dir`, as root-relative POSIX paths, sorted.
|
|
152
|
+
*
|
|
153
|
+
* One rule with the read at a commit (task-171, `bug-189`): a symbolic link is never followed — a
|
|
154
|
+
* `.md` link is listed as a link, so the caller can report it, and a link to a directory is not
|
|
155
|
+
* entered — and a directory holding `.git` (a nested repository, which a commit records as a gitlink
|
|
156
|
+
* at most) is not entered. With `followSymlinks` the walk is the pre-task-171 one, for
|
|
157
|
+
* {@link MemoryIdLookupOptions.followSymlinks}'s explain-only use.
|
|
158
|
+
*/
|
|
159
|
+
function listMarkdownFilesUnder(root, dir, followSymlinks) {
|
|
93
160
|
const absoluteDir = (0, path_1.join)(root, dir);
|
|
94
161
|
if (!(0, fs_1.existsSync)(absoluteDir) || !(0, fs_1.statSync)(absoluteDir).isDirectory())
|
|
95
162
|
return [];
|
|
@@ -98,47 +165,275 @@ function listMarkdownFilesUnder(root, dir) {
|
|
|
98
165
|
for (const entry of (0, fs_1.readdirSync)(current).sort()) {
|
|
99
166
|
const full = (0, path_1.join)(current, entry);
|
|
100
167
|
const relative = `${relativePrefix}/${entry}`;
|
|
101
|
-
|
|
168
|
+
const own = (0, fs_1.lstatSync)(full);
|
|
169
|
+
if (own.isSymbolicLink() && !followSymlinks) {
|
|
170
|
+
if (entry.endsWith('.md'))
|
|
171
|
+
out.push({ path: relative, symlink: true });
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
// Following (explain-only): a dangling link names nothing to read, so it is passed over.
|
|
175
|
+
if (own.isSymbolicLink() && !(0, fs_1.existsSync)(full))
|
|
176
|
+
continue;
|
|
177
|
+
const stats = own.isSymbolicLink() ? (0, fs_1.statSync)(full) : own;
|
|
178
|
+
if (stats.isDirectory()) {
|
|
179
|
+
if (!followSymlinks && (0, fs_1.existsSync)((0, path_1.join)(full, '.git')))
|
|
180
|
+
continue;
|
|
102
181
|
walk(full, relative);
|
|
103
182
|
}
|
|
104
183
|
else if (entry.endsWith('.md')) {
|
|
105
|
-
out.push(relative);
|
|
184
|
+
out.push({ path: relative, symlink: false });
|
|
106
185
|
}
|
|
107
186
|
}
|
|
108
187
|
};
|
|
109
188
|
walk(absoluteDir, dir);
|
|
110
189
|
return out;
|
|
111
190
|
}
|
|
191
|
+
/** Every `.md` entry under the scan roots of `memoryYaml`, sorted, links marked (see {@link listMarkdownFilesUnder}). */
|
|
192
|
+
function scanWorkingTree(root, memoryYaml, followSymlinks = false) {
|
|
193
|
+
const out = new Map();
|
|
194
|
+
for (const dir of computeMemoryContentRoots(memoryYaml)) {
|
|
195
|
+
for (const file of listMarkdownFilesUnder(root, dir, followSymlinks))
|
|
196
|
+
out.set(file.path, file);
|
|
197
|
+
}
|
|
198
|
+
return [...out.values()].sort(byPath);
|
|
199
|
+
}
|
|
112
200
|
/**
|
|
113
201
|
* List every Memory document under `root`, as root-relative POSIX paths, sorted lexicographically
|
|
114
202
|
* (REQ-SYS-07 — deterministic, no unordered iteration). Scans only the directories
|
|
115
|
-
* {@link computeMemoryContentRoots} derives from `memoryYaml`, never the whole project tree.
|
|
203
|
+
* {@link computeMemoryContentRoots} derives from `memoryYaml`, never the whole project tree. A
|
|
204
|
+
* symbolic link is not a document and is not listed (task-171, `bug-189`), the same as
|
|
205
|
+
* {@link listMemoryDocumentPathsAtRev} at a commit.
|
|
116
206
|
*/
|
|
117
207
|
function listMemoryDocumentPaths(root, memoryYaml) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
out.add(path);
|
|
122
|
-
}
|
|
123
|
-
return [...out].sort();
|
|
208
|
+
return scanWorkingTree(root, memoryYaml)
|
|
209
|
+
.filter((file) => !file.symlink)
|
|
210
|
+
.map((file) => file.path);
|
|
124
211
|
}
|
|
125
212
|
/**
|
|
126
213
|
* Read one Memory document and split it into its parsed frontmatter and body text, without running
|
|
127
214
|
* it through any type's Zod schema — `memory search`/`history` must handle documents of every type
|
|
128
215
|
* and any (even structurally imperfect) state, so this is a read, never a validation.
|
|
216
|
+
*
|
|
217
|
+
* This single-file read **throws** `ValidationError` (`E_YAML_PARSE_ERROR`) when the frontmatter does
|
|
218
|
+
* not parse: its caller named the file. The scans built on it are what is tolerant (task-171,
|
|
219
|
+
* `bug-031`): each one leaves such a document out and reports it as {@link W_MEMORY_UNREADABLE} to its
|
|
220
|
+
* {@link MemoryScanOptions.onDiagnostic}, so one malformed document never fails a query about another.
|
|
129
221
|
*/
|
|
130
222
|
function loadMemoryDocumentSummary(root, relativePath) {
|
|
131
223
|
const absolute = (0, path_1.join)(root, relativePath);
|
|
132
|
-
|
|
224
|
+
return refuseNewerElement(parseMemoryDocument((0, storage_1.readDocument)(absolute), relativePath, absolute));
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* A Memory document's bytes split into parsed frontmatter and body — the one parse both baselines use
|
|
228
|
+
* ({@link loadMemoryDocumentSummary} for the working tree, {@link loadMemoryDocumentsAtRev} and its
|
|
229
|
+
* siblings for a commit), so they cannot drift on what a document *is*. `label` is what a parse error
|
|
230
|
+
* names: the absolute path, or `<rev>:<path>`.
|
|
231
|
+
*/
|
|
232
|
+
function parseMemoryDocument(raw, relativePath, label) {
|
|
133
233
|
const { frontmatter: frontmatterText, body } = (0, storage_1.splitFrontmatter)(raw);
|
|
134
234
|
let frontmatter = {};
|
|
135
235
|
if (frontmatterText) {
|
|
136
|
-
const parsed = (0, validation_1.parseYaml)(frontmatterText,
|
|
236
|
+
const parsed = (0, validation_1.parseYaml)(frontmatterText, label);
|
|
137
237
|
if (parsed !== null && typeof parsed === 'object')
|
|
138
238
|
frontmatter = parsed;
|
|
139
239
|
}
|
|
140
240
|
return { path: relativePath, frontmatter, body };
|
|
141
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* The `format` check of an element (`dl-149`, task-257, `bug-241`): `E_INVALID_FORMAT` on `format`
|
|
244
|
+
* when the document's frontmatter declares a format newer than this build reads, else `null`. An
|
|
245
|
+
* element is its template's copy (`spec-001`: the scaffold is copied verbatim, `format` line included),
|
|
246
|
+
* and keeps the format its template carries (approver ruling at the W2 B2 gate, task-251 decision 4),
|
|
247
|
+
* so it reads with the template's counter, `MEMORY_TEMPLATE_FORMAT`. An absent `format` reads as `1`.
|
|
248
|
+
* The issue names the repository-relative path, whichever baseline was read, as a scan diagnostic does.
|
|
249
|
+
*
|
|
250
|
+
* Only a newer format is checked here. The element read is loose by design (no type's schema runs on
|
|
251
|
+
* it, see {@link loadMemoryDocumentSummary}), so a `format` that is not a positive integer is left to
|
|
252
|
+
* the rules that validate an element's frontmatter, as every other field is.
|
|
253
|
+
*/
|
|
254
|
+
function newerElementFormat(summary) {
|
|
255
|
+
return (0, validation_1.newerFormatIssue)(summary.frontmatter, validation_1.MEMORY_TEMPLATE_FORMAT, summary.path);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* `summary`, or the `dl-149` refusal of it as a `ValidationError` at exit `1` when it is written in a
|
|
259
|
+
* newer format: a read whose caller named this document — a single-file read, or a lookup that reached
|
|
260
|
+
* the element it looks for — refuses it, where a scan reports it ({@link readableDocuments}).
|
|
261
|
+
*/
|
|
262
|
+
function refuseNewerElement(summary) {
|
|
263
|
+
const newer = newerElementFormat(summary);
|
|
264
|
+
if (newer !== null)
|
|
265
|
+
throw new validation_1.ValidationError([newer], validation_1.EXIT_VALIDATION);
|
|
266
|
+
return summary;
|
|
267
|
+
}
|
|
268
|
+
/** The {@link W_MEMORY_UNREADABLE} report of a document written in a newer format: the file and the `dl-149` refusal. */
|
|
269
|
+
function newerFormatDiagnostic(newer) {
|
|
270
|
+
return memoryUnreadableDiagnostic(newer.file, `${newer.code}: ${newer.message}`);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* {@link parseMemoryDocument} for a scan: the document with its format check, or `undefined` after
|
|
274
|
+
* reporting it as {@link W_MEMORY_UNREADABLE} when its frontmatter does not parse. The diagnostic names
|
|
275
|
+
* the repository-relative path, whichever baseline was read.
|
|
276
|
+
*/
|
|
277
|
+
function parseScanned(raw, relativePath, label, options) {
|
|
278
|
+
let summary;
|
|
279
|
+
try {
|
|
280
|
+
summary = parseMemoryDocument(raw, relativePath, label);
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
// `parseYaml` is the only thing in the parse that throws, and it throws only
|
|
284
|
+
// `ValidationError.yamlParse`, whose one issue carries the parser's message.
|
|
285
|
+
const parseError = error.issues[0];
|
|
286
|
+
options.onDiagnostic?.(memoryUnreadableDiagnostic(relativePath, firstLineOf(parseError.message)));
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
return { summary, newer: newerElementFormat(summary) };
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* The documents of a scan a **collection** reader may use: one written in a newer format is left out
|
|
293
|
+
* and reported as {@link W_MEMORY_UNREADABLE}, naming the file and the `dl-149` refusal (task-257,
|
|
294
|
+
* `bug-241`), so it is neither read by today's rules nor dropped silently.
|
|
295
|
+
*/
|
|
296
|
+
function* readableDocuments(documents, options) {
|
|
297
|
+
for (const { summary, newer } of documents) {
|
|
298
|
+
if (newer !== null) {
|
|
299
|
+
options.onDiagnostic?.(newerFormatDiagnostic(newer));
|
|
300
|
+
continue;
|
|
301
|
+
}
|
|
302
|
+
yield summary;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* The first document of a scan whose frontmatter `matches`, for a **lookup**: the caller named that
|
|
307
|
+
* element, so one written in a newer format is refused (`ValidationError`, `E_INVALID_FORMAT`, exit
|
|
308
|
+
* `1`), as a single-file read refuses it; a newer-format document the lookup passes on its way is
|
|
309
|
+
* reported, as a collection scan reports it (task-257, `bug-241`).
|
|
310
|
+
*/
|
|
311
|
+
function findFirst(documents, matches, options) {
|
|
312
|
+
for (const { summary, newer } of documents) {
|
|
313
|
+
if (matches(summary.frontmatter))
|
|
314
|
+
return refuseNewerElement(summary);
|
|
315
|
+
if (newer !== null)
|
|
316
|
+
options.onDiagnostic?.(newerFormatDiagnostic(newer));
|
|
317
|
+
}
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* The working-tree scan every tolerant reader is built on: each document under the scan roots, parsed,
|
|
322
|
+
* lazily and in path order, so a lookup can stop at its match. A link and an unparsable document are
|
|
323
|
+
* reported and skipped.
|
|
324
|
+
*/
|
|
325
|
+
function* scanWorkingTreeDocuments(root, memoryYaml, options) {
|
|
326
|
+
for (const file of scanWorkingTree(root, memoryYaml, options.followSymlinks === true)) {
|
|
327
|
+
if (file.symlink) {
|
|
328
|
+
options.onDiagnostic?.(memoryUnreadableDiagnostic(file.path, SYMLINK_REASON));
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
const absolute = (0, path_1.join)(root, file.path);
|
|
332
|
+
const summary = parseScanned((0, storage_1.readDocument)(absolute), file.path, absolute, options);
|
|
333
|
+
if (summary !== undefined)
|
|
334
|
+
yield summary;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Every Memory document **in the working tree** under `root`, parsed — {@link loadMemoryDocumentsAtRev}
|
|
339
|
+
* for the live files, in {@link listMemoryDocumentPaths}'s sorted order. Archived documents are
|
|
340
|
+
* included: the caller decides what to drop. A document whose frontmatter does not parse, and a
|
|
341
|
+
* symbolic link, are left out and reported to `options.onDiagnostic` as {@link W_MEMORY_UNREADABLE}
|
|
342
|
+
* (task-171, task-253 / `bug-230`), so one malformed document never fails a read of the others.
|
|
343
|
+
*/
|
|
344
|
+
function loadMemoryDocuments(root, memoryYaml, options = {}) {
|
|
345
|
+
return [...readableDocuments(scanWorkingTreeDocuments(root, memoryYaml, options), options)];
|
|
346
|
+
}
|
|
347
|
+
// --- The same scan at a revision (task-137) -----------------------------------------------------
|
|
348
|
+
//
|
|
349
|
+
// `spec-012` §2 pins an agent context to `stateRef`, a commit sha, and `spec-017` §1.1/§1.3 deduce
|
|
350
|
+
// workflow state from every Memory document "enumerated from `HEAD`'s tree in sorted path order". The
|
|
351
|
+
// readers below are the working-tree scan above, read at one commit instead: the same scan roots
|
|
352
|
+
// ({@link computeMemoryContentRoots}), the same `.md` filter, the same sort, the same parse, the same
|
|
353
|
+
// tolerance and the same rule for links (task-171). Each resolves `rev` once (`resolveRevision`) and
|
|
354
|
+
// reads every byte at that sha; an unknown or malformed rev throws `RevisionError` rather than
|
|
355
|
+
// answering with an empty scan. Pass the `memoryYaml` loaded at the same rev (`loadMemoryYamlAtRev`),
|
|
356
|
+
// and a resolved sha when several calls must see one commit.
|
|
357
|
+
/** Every `.md` blob under the scan roots at `sha`, sorted, links marked (git mode `120000`). */
|
|
358
|
+
function scanCommit(root, sha, memoryYaml) {
|
|
359
|
+
const out = new Map();
|
|
360
|
+
for (const dir of computeMemoryContentRoots(memoryYaml)) {
|
|
361
|
+
for (const entry of (0, revision_1.listBlobEntriesAtCommit)(root, sha, dir))
|
|
362
|
+
if (entry.path.endsWith('.md'))
|
|
363
|
+
out.set(entry.path, entry);
|
|
364
|
+
}
|
|
365
|
+
return [...out.values()].sort(byPath);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Every Memory document **commit `rev` holds**, as root-relative POSIX paths sorted the way
|
|
369
|
+
* {@link listMemoryDocumentPaths} sorts the working tree's (REQ-SYS-07). A document added after `rev`,
|
|
370
|
+
* or present only in the working tree, is not listed; nor is a symbolic link (task-171, `bug-189`).
|
|
371
|
+
*
|
|
372
|
+
* @throws `RevisionError` when `rev` is malformed or names no commit.
|
|
373
|
+
*/
|
|
374
|
+
function listMemoryDocumentPathsAtRev(root, rev, memoryYaml) {
|
|
375
|
+
return scanCommit(root, (0, revision_1.resolveRevision)(root, rev), memoryYaml)
|
|
376
|
+
.filter((file) => !file.symlink)
|
|
377
|
+
.map((file) => file.path);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Read `files` at `sha` in one batch and parse them **lazily**, in path order; a path the commit does
|
|
381
|
+
* holds every one of them (they were listed at it); a link or an unparsable document is reported and
|
|
382
|
+
* skipped (task-171). Lazy
|
|
383
|
+
* so that a lookup can stop at its match, as the working-tree lookup does.
|
|
384
|
+
*/
|
|
385
|
+
function* parseMemoryDocumentsAtSha(root, sha, rev, files, options) {
|
|
386
|
+
const raws = (0, storage_1.readPathsAtRev)(root, sha, files.filter((file) => !file.symlink).map((file) => file.path));
|
|
387
|
+
let next = 0;
|
|
388
|
+
for (const file of files) {
|
|
389
|
+
if (file.symlink) {
|
|
390
|
+
options.onDiagnostic?.(memoryUnreadableDiagnostic(file.path, SYMLINK_REASON));
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
// Every path here was listed as a blob of this very commit, so the commit holds it and the batch
|
|
394
|
+
// answers its bytes, never `null`.
|
|
395
|
+
const raw = raws[next++];
|
|
396
|
+
const summary = parseScanned(raw, file.path, `${rev}:${file.path}`, options);
|
|
397
|
+
if (summary !== undefined)
|
|
398
|
+
yield summary;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Every Memory document **commit `rev` holds**, parsed — the paths of
|
|
403
|
+
* {@link listMemoryDocumentPathsAtRev}, in its order, each read in one batch (`storage.readPathsAtRev`)
|
|
404
|
+
* and split as {@link loadMemoryDocumentSummary} splits a working-tree file. This is the snapshot a
|
|
405
|
+
* reader pinned to one commit builds from (`spec-012` §6 relevance, `spec-017` §4 deduction). A
|
|
406
|
+
* document whose frontmatter does not parse, and a link, are left out and reported (task-171).
|
|
407
|
+
*
|
|
408
|
+
* @throws `RevisionError` when `rev` is malformed or names no commit.
|
|
409
|
+
*/
|
|
410
|
+
function loadMemoryDocumentsAtRev(root, rev, memoryYaml, options = {}) {
|
|
411
|
+
const sha = (0, revision_1.resolveRevision)(root, rev);
|
|
412
|
+
return [...readableDocuments(parseMemoryDocumentsAtSha(root, sha, rev, scanCommit(root, sha, memoryYaml), options), options)];
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* {@link loadMemoryDocumentsAtRev} for a `sha` already resolved to a commit (`resolveRevision`,
|
|
416
|
+
* `src/core/revision.ts`): the same scan and parse, without resolving the revision again. A reader that
|
|
417
|
+
* resolves its commit once and reads several pillars at it (the workflow deduction's snapshot, task-283,
|
|
418
|
+
* `bug-309`) uses this, so one call spends one `git rev-parse`, not one per loader.
|
|
419
|
+
*
|
|
420
|
+
* @param sha - The full sha of a commit, as `resolveRevision` returned it; labels name it.
|
|
421
|
+
*/
|
|
422
|
+
function loadMemoryDocumentsAtCommit(root, sha, memoryYaml, options) {
|
|
423
|
+
return [...readableDocuments(parseMemoryDocumentsAtSha(root, sha, sha, scanCommit(root, sha, memoryYaml), options), options)];
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* One Memory document **as commit `rev` holds it** — {@link loadMemoryDocumentSummary} at a commit.
|
|
427
|
+
* `null` when that commit does not hold `relativePath` as a file. Like its working-tree counterpart,
|
|
428
|
+
* this single-file read throws when the frontmatter does not parse.
|
|
429
|
+
*
|
|
430
|
+
* @throws `RevisionError` when `rev` is malformed or names no commit; `ValidationError` when the
|
|
431
|
+
* frontmatter does not parse.
|
|
432
|
+
*/
|
|
433
|
+
function loadMemoryDocumentSummaryAtRev(root, rev, relativePath) {
|
|
434
|
+
const raw = (0, storage_1.readPathsAtRev)(root, (0, revision_1.resolveRevision)(root, rev), [relativePath])[0];
|
|
435
|
+
return raw === null ? null : refuseNewerElement(parseMemoryDocument(raw, relativePath, `${rev}:${relativePath}`));
|
|
436
|
+
}
|
|
142
437
|
function asStringArray(value) {
|
|
143
438
|
return Array.isArray(value) ? value.filter((entry) => typeof entry === 'string') : [];
|
|
144
439
|
}
|
|
@@ -153,25 +448,40 @@ function asString(value) {
|
|
|
153
448
|
* (single document) — there is no bare, single-segment `wingfoil://memory/{id}` form there, and this
|
|
154
449
|
* `{id}` segment would collide with spec-004's `{type}` segment. task-011-mcp-resources-read-only has
|
|
155
450
|
* since replaced the `wingfoil://memory/{id}` *Resource* this primitive originally backed with the
|
|
156
|
-
* conformant `wingfoil://memory/{type}/{id}` form (see {@link findMemoryDocumentByTypeAndId})
|
|
157
|
-
* bare-id primitive
|
|
158
|
-
*
|
|
159
|
-
* `src/mcp` calls it anymore.
|
|
451
|
+
* conformant `wingfoil://memory/{type}/{id}` form (see {@link findMemoryDocumentByTypeAndId}). This
|
|
452
|
+
* bare-id primitive is what `memory history` resolves its `<id>` with, and what the transition verbs
|
|
453
|
+
* use to explain a refusal; it is neutral about archived documents, since both act on them.
|
|
160
454
|
*
|
|
161
|
-
* A linear scan
|
|
162
|
-
* already-deterministic sorted order, stopping at the first document whose frontmatter `id` matches
|
|
455
|
+
* A linear scan, in sorted path order, stopping at the first document whose frontmatter `id` matches
|
|
163
456
|
* *exactly* (never a substring — that remains `searchMemoryDocuments`'/task-021's keyword-search
|
|
164
|
-
* surface, not this primitive's). Returns `undefined` — never throws — when no document matches;
|
|
165
|
-
*
|
|
166
|
-
* (spec-004 §2.2's general unresolvable-URI contract), not this primitive's.
|
|
457
|
+
* surface, not this primitive's). Returns `undefined` — never throws — when no document matches; a
|
|
458
|
+
* document it cannot read on the way is reported to `options.onDiagnostic` and skipped (task-171).
|
|
167
459
|
*/
|
|
168
|
-
function findMemoryDocumentById(root, memoryYaml, id) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
460
|
+
function findMemoryDocumentById(root, memoryYaml, id, options = {}) {
|
|
461
|
+
return findFirst(scanWorkingTreeDocuments(root, memoryYaml, options), (frontmatter) => asString(frontmatter.id) === id, options);
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* {@link findMemoryDocumentById} **at commit `rev`** (task-247, `bug-187`): the first document, in
|
|
465
|
+
* the sorted path order of {@link listMemoryDocumentPathsAtRev}, whose own frontmatter `id` matches
|
|
466
|
+
* exactly, with its frontmatter and body as `rev` holds them; `undefined` when that commit holds none.
|
|
467
|
+
* A document present only in the working tree, or added after `rev`, is never returned. This is the
|
|
468
|
+
* lookup the Memory transition verbs decide from (`spec-006-core-domain-api` §6 item 1). A document it
|
|
469
|
+
* cannot read on the way is reported to `options.onDiagnostic` and skipped (task-171).
|
|
470
|
+
*
|
|
471
|
+
* @throws `RevisionError` when `rev` is malformed or names no commit.
|
|
472
|
+
*/
|
|
473
|
+
function findMemoryDocumentByIdAtRev(root, rev, memoryYaml, id, options = {}) {
|
|
474
|
+
const sha = (0, revision_1.resolveRevision)(root, rev);
|
|
475
|
+
const documents = parseMemoryDocumentsAtSha(root, sha, rev, scanCommit(root, sha, memoryYaml), options);
|
|
476
|
+
return findFirst(documents, (frontmatter) => asString(frontmatter.id) === id, options);
|
|
477
|
+
}
|
|
478
|
+
/** The match of the (`type`, `id`) lookups: both are the document's own frontmatter values. */
|
|
479
|
+
function isTypeAndId(type, id) {
|
|
480
|
+
return (frontmatter) => asString(frontmatter.type) === type && asString(frontmatter.id) === id;
|
|
481
|
+
}
|
|
482
|
+
/** Whether a document is kept under the archived default of {@link MemoryTypeScanOptions}. */
|
|
483
|
+
function keptByArchivedDefault(frontmatter, options) {
|
|
484
|
+
return options.includeArchived === true || !(0, state_machine_1.isArchivedStatus)(asString(frontmatter.status));
|
|
175
485
|
}
|
|
176
486
|
/**
|
|
177
487
|
* List every Memory document whose frontmatter `type:` field equals `type` (a `memory.yaml` `types:`
|
|
@@ -184,13 +494,17 @@ function findMemoryDocumentById(root, memoryYaml, id) {
|
|
|
184
494
|
* `release`/`release-line` both resolve to `docs/04_memory/planning`; `task`'s own pattern collapses
|
|
185
495
|
* all the way to `docs/04_memory` itself — see {@link computeMemoryContentRoots}'s doc comment), so a
|
|
186
496
|
* directory-only filter would wrongly fold sibling types' documents into this type's collection.
|
|
497
|
+
*
|
|
498
|
+
* Archived documents are left out unless `options.includeArchived` (task-171, `dl-038` option 1), and
|
|
499
|
+
* a document the scan cannot read is reported to `options.onDiagnostic` and skipped.
|
|
187
500
|
*/
|
|
188
|
-
function listMemoryDocumentsByType(root, memoryYaml, type) {
|
|
501
|
+
function listMemoryDocumentsByType(root, memoryYaml, type, options = {}) {
|
|
189
502
|
const out = [];
|
|
190
|
-
for (const path of
|
|
191
|
-
const { frontmatter } = loadMemoryDocumentSummary(root, path);
|
|
503
|
+
for (const { path, frontmatter } of readableDocuments(scanWorkingTreeDocuments(root, memoryYaml, options), options)) {
|
|
192
504
|
if (asString(frontmatter.type) !== type)
|
|
193
505
|
continue;
|
|
506
|
+
if (!keptByArchivedDefault(frontmatter, options))
|
|
507
|
+
continue;
|
|
194
508
|
out.push({
|
|
195
509
|
path,
|
|
196
510
|
id: asString(frontmatter.id),
|
|
@@ -199,11 +513,9 @@ function listMemoryDocumentsByType(root, memoryYaml, type) {
|
|
|
199
513
|
tags: asStringArray(frontmatter.tags),
|
|
200
514
|
});
|
|
201
515
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;
|
|
206
|
-
});
|
|
516
|
+
// By `id`, a document with none by its path, then by path: a total order even when two files carry
|
|
517
|
+
// one `id` (REQ-SYS-07).
|
|
518
|
+
return out.sort((a, b) => compareText(a.id ?? a.path, b.id ?? b.path) || compareText(a.path, b.path));
|
|
207
519
|
}
|
|
208
520
|
/**
|
|
209
521
|
* Resolve a single Memory document by (`type`, `id`) — spec-004 §2.1's `wingfoil://memory/{type}/{id}`
|
|
@@ -214,14 +526,25 @@ function listMemoryDocumentsByType(root, memoryYaml, type) {
|
|
|
214
526
|
* because that type's path pattern happens to also resolve under the same directory. Returns
|
|
215
527
|
* `undefined` — never throws — when nothing matches; surfacing that as a protocol-level "resource not
|
|
216
528
|
* found" failure is the MCP Resource adapter's job (spec-004 §2.2), not this primitive's.
|
|
529
|
+
*
|
|
530
|
+
* An archived document matches only with `options.includeArchived` (task-171, `dl-038` option 1); the
|
|
531
|
+
* single-document Resource passes it, since REQ-STATE-06 keeps archived content retrievable.
|
|
217
532
|
*/
|
|
218
|
-
function findMemoryDocumentByTypeAndId(root, memoryYaml, type, id) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
533
|
+
function findMemoryDocumentByTypeAndId(root, memoryYaml, type, id, options = {}) {
|
|
534
|
+
const found = findFirst(scanWorkingTreeDocuments(root, memoryYaml, options), isTypeAndId(type, id), options);
|
|
535
|
+
return found !== undefined && keptByArchivedDefault(found.frontmatter, options) ? found : undefined;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* {@link findMemoryDocumentByTypeAndId} **at commit `rev`**: the document whose own frontmatter `type`
|
|
539
|
+
* and `id` match, with its frontmatter and body as `rev` holds them; `undefined` when that commit holds
|
|
540
|
+
* none, or holds it archived without `options.includeArchived`.
|
|
541
|
+
*
|
|
542
|
+
* @throws `RevisionError` when `rev` is malformed or names no commit.
|
|
543
|
+
*/
|
|
544
|
+
function findMemoryDocumentByTypeAndIdAtRev(root, rev, memoryYaml, type, id, options = {}) {
|
|
545
|
+
const sha = (0, revision_1.resolveRevision)(root, rev);
|
|
546
|
+
const found = findFirst(parseMemoryDocumentsAtSha(root, sha, rev, scanCommit(root, sha, memoryYaml), options), isTypeAndId(type, id), options);
|
|
547
|
+
return found !== undefined && keptByArchivedDefault(found.frontmatter, options) ? found : undefined;
|
|
225
548
|
}
|
|
226
549
|
/** `E_EMPTY_SEARCH_QUERY` field-level code (spec-009-validation-strategy §3) for a rejected empty
|
|
227
550
|
* or whitespace-only `wingfoil memory search` query. */
|
|
@@ -256,8 +579,13 @@ function validateSearchQuery(query) {
|
|
|
256
579
|
* concern, task-021's, not this primitive's).
|
|
257
580
|
*
|
|
258
581
|
* Ordering is a total, deterministic order (REQ-SYS-07): metadata matches before body-only matches,
|
|
259
|
-
* then by `id
|
|
260
|
-
*
|
|
582
|
+
* then by `id`, then by `path` (two files may carry one `id`) ascending — so calling this twice
|
|
583
|
+
* against unchanged state always returns the exact same array.
|
|
584
|
+
*
|
|
585
|
+
* **Only elements, never a throw (task-171).** A match has an `id` and a `type` (`bug-164`); a file
|
|
586
|
+
* with neither is left out without a report. A document whose frontmatter does not parse, or a
|
|
587
|
+
* symbolic link, is left out and reported to `options.onDiagnostic` as {@link W_MEMORY_UNREADABLE}
|
|
588
|
+
* (`bug-031`), so one malformed file never fails a search.
|
|
261
589
|
*
|
|
262
590
|
* **REQ-STATE-06:** a document whose frontmatter `status` is archived — `deprecated` or `superseded`
|
|
263
591
|
* (`isArchivedStatus`, `dl-028`) — is excluded by default, so it never appears in these "default
|
|
@@ -270,8 +598,13 @@ function validateSearchQuery(query) {
|
|
|
270
598
|
function searchMemoryDocuments(root, memoryYaml, query, options = {}) {
|
|
271
599
|
const needle = query.trim().toLowerCase();
|
|
272
600
|
const matches = [];
|
|
273
|
-
for (const path of
|
|
274
|
-
|
|
601
|
+
for (const { path, frontmatter, body } of readableDocuments(scanWorkingTreeDocuments(root, memoryYaml, options), options)) {
|
|
602
|
+
// Only an element is a match (task-171, `bug-164`): a file with no `id` or no `type` — a plan
|
|
603
|
+
// `dl-019` grandfathered without frontmatter — is left out, silently: it is not unreadable.
|
|
604
|
+
const id = asString(frontmatter.id);
|
|
605
|
+
const type = asString(frontmatter.type);
|
|
606
|
+
if (id === undefined || type === undefined)
|
|
607
|
+
continue;
|
|
275
608
|
const status = asString(frontmatter.status);
|
|
276
609
|
if (!options.includeArchived && (0, state_machine_1.isArchivedStatus)(status))
|
|
277
610
|
continue;
|
|
@@ -279,14 +612,12 @@ function searchMemoryDocuments(root, memoryYaml, query, options = {}) {
|
|
|
279
612
|
if (options.tag && !tags.includes(options.tag))
|
|
280
613
|
continue;
|
|
281
614
|
const title = asString(frontmatter.title);
|
|
282
|
-
const id = asString(frontmatter.id);
|
|
283
|
-
const type = asString(frontmatter.type);
|
|
284
615
|
let metadataMatch = false;
|
|
285
616
|
let bodyMatch = false;
|
|
286
617
|
if (needle.length > 0) {
|
|
287
618
|
metadataMatch =
|
|
288
619
|
(title !== undefined && title.toLowerCase().includes(needle)) ||
|
|
289
|
-
|
|
620
|
+
id.toLowerCase().includes(needle) ||
|
|
290
621
|
tags.some((tag) => tag.toLowerCase().includes(needle));
|
|
291
622
|
bodyMatch = body.toLowerCase().includes(needle);
|
|
292
623
|
if (!metadataMatch && !bodyMatch)
|
|
@@ -299,9 +630,58 @@ function searchMemoryDocuments(root, memoryYaml, query, options = {}) {
|
|
|
299
630
|
const scoreB = b.metadataMatch ? 1 : 0;
|
|
300
631
|
if (scoreA !== scoreB)
|
|
301
632
|
return scoreB - scoreA;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
633
|
+
return compareText(a.id, b.id) || compareText(a.path, b.path);
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* The documents of type `type` each of `revs` holds, one sorted list per revision, in input order —
|
|
638
|
+
* the read the WIP-limit count across refs takes (`requireWipSlot`, `dl-156` Q1 (a), task-274).
|
|
639
|
+
*
|
|
640
|
+
* Narrow and batched, unlike one {@link loadMemoryDocumentsAtRev} per revision (which parses every
|
|
641
|
+
* document of every type at each commit): only the type's own static directory is listed, every
|
|
642
|
+
* revision's listing in one batched walk (`listBlobsAtRevs`), every distinct blob read in one batch and
|
|
643
|
+
* parsed **once** however many revisions hold it. A document counts when its own frontmatter `type` is
|
|
644
|
+
* `type`, as in every Memory scan. A link, an unparsable document and one written in a newer format are
|
|
645
|
+
* left out and reported through `options.onDiagnostic` as {@link W_MEMORY_UNREADABLE} (task-171,
|
|
646
|
+
* task-257), once per blob.
|
|
647
|
+
*
|
|
648
|
+
* @throws `StorageError` `E_GIT_READ_FAILED` when a revision names no commit or a batch read fails.
|
|
649
|
+
*/
|
|
650
|
+
function loadTypeDocumentCopiesAtRevs(root, revs, memoryYaml, type, options = {}) {
|
|
651
|
+
const typeEntry = memoryYaml.types[type];
|
|
652
|
+
const directory = typeEntry === undefined ? '' : staticDirPrefix(typeEntry.path);
|
|
653
|
+
const listings = (0, storage_1.listBlobsAtRevs)(root, revs, directory).map((blobs) => blobs.filter((blob) => blob.path.endsWith('.md')));
|
|
654
|
+
const reported = new Set();
|
|
655
|
+
const contents = (0, storage_1.readBlobs)(root, listings.flatMap((blobs) => blobs.filter((blob) => !blob.symlink).map((blob) => blob.oid)));
|
|
656
|
+
const parsed = new Map();
|
|
657
|
+
const frontmatterOf = (path, oid) => {
|
|
658
|
+
if (parsed.has(oid))
|
|
659
|
+
return parsed.get(oid);
|
|
660
|
+
const scanned = parseScanned(contents.get(oid), path, `${oid}:${path}`, options);
|
|
661
|
+
let frontmatter = null;
|
|
662
|
+
if (scanned !== undefined) {
|
|
663
|
+
if (scanned.newer !== null)
|
|
664
|
+
options.onDiagnostic?.(newerFormatDiagnostic(scanned.newer));
|
|
665
|
+
else
|
|
666
|
+
frontmatter = scanned.summary.frontmatter;
|
|
667
|
+
}
|
|
668
|
+
parsed.set(oid, frontmatter);
|
|
669
|
+
return frontmatter;
|
|
670
|
+
};
|
|
671
|
+
return listings.map((blobs) => {
|
|
672
|
+
const copies = [];
|
|
673
|
+
for (const blob of blobs) {
|
|
674
|
+
if (blob.symlink) {
|
|
675
|
+
if (!reported.has(blob.path))
|
|
676
|
+
options.onDiagnostic?.(memoryUnreadableDiagnostic(blob.path, SYMLINK_REASON));
|
|
677
|
+
reported.add(blob.path);
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
const frontmatter = frontmatterOf(blob.path, blob.oid);
|
|
681
|
+
if (frontmatter !== null && frontmatter.type === type)
|
|
682
|
+
copies.push({ path: blob.path, oid: blob.oid, frontmatter });
|
|
683
|
+
}
|
|
684
|
+
return copies;
|
|
305
685
|
});
|
|
306
686
|
}
|
|
307
687
|
//# sourceMappingURL=query.js.map
|