wingfoil 0.2.1
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/LICENSE +21 -0
- package/README.md +334 -0
- package/dist/cli/error.d.ts +11 -0
- package/dist/cli/error.d.ts.map +1 -0
- package/dist/cli/error.js +27 -0
- package/dist/cli/error.js.map +1 -0
- package/dist/cli/exit.d.ts +19 -0
- package/dist/cli/exit.d.ts.map +1 -0
- package/dist/cli/exit.js +14 -0
- package/dist/cli/exit.js.map +1 -0
- package/dist/cli/index.d.ts +28 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-command.d.ts +34 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +100 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/mcp-command.d.ts +24 -0
- package/dist/cli/mcp-command.d.ts.map +1 -0
- package/dist/cli/mcp-command.js +42 -0
- package/dist/cli/mcp-command.js.map +1 -0
- package/dist/cli/output.d.ts +13 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +28 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/program.d.ts +12 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +279 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/registrar.d.ts +69 -0
- package/dist/cli/registrar.d.ts.map +1 -0
- package/dist/cli/registrar.js +82 -0
- package/dist/cli/registrar.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +45 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/approval-authority.d.ts +83 -0
- package/dist/core/approval-authority.d.ts.map +1 -0
- package/dist/core/approval-authority.js +112 -0
- package/dist/core/approval-authority.js.map +1 -0
- package/dist/core/builtin-asset.d.ts +71 -0
- package/dist/core/builtin-asset.d.ts.map +1 -0
- package/dist/core/builtin-asset.js +137 -0
- package/dist/core/builtin-asset.js.map +1 -0
- package/dist/core/builtin-integrity.d.ts +32 -0
- package/dist/core/builtin-integrity.d.ts.map +1 -0
- package/dist/core/builtin-integrity.js +148 -0
- package/dist/core/builtin-integrity.js.map +1 -0
- package/dist/core/confinement.d.ts +57 -0
- package/dist/core/confinement.d.ts.map +1 -0
- package/dist/core/confinement.js +108 -0
- package/dist/core/confinement.js.map +1 -0
- package/dist/core/context.d.ts +187 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +192 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/directive-assign.d.ts +131 -0
- package/dist/core/directive-assign.d.ts.map +1 -0
- package/dist/core/directive-assign.js +352 -0
- package/dist/core/directive-assign.js.map +1 -0
- package/dist/core/directives-list.d.ts +80 -0
- package/dist/core/directives-list.d.ts.map +1 -0
- package/dist/core/directives-list.js +148 -0
- package/dist/core/directives-list.js.map +1 -0
- package/dist/core/exit-code.d.ts +85 -0
- package/dist/core/exit-code.d.ts.map +1 -0
- package/dist/core/exit-code.js +163 -0
- package/dist/core/exit-code.js.map +1 -0
- package/dist/core/git-identity.d.ts +32 -0
- package/dist/core/git-identity.d.ts.map +1 -0
- package/dist/core/git-identity.js +72 -0
- package/dist/core/git-identity.js.map +1 -0
- package/dist/core/index.d.ts +388 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1331 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/init.d.ts +78 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +167 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/loaders.d.ts +174 -0
- package/dist/core/loaders.d.ts.map +1 -0
- package/dist/core/loaders.js +364 -0
- package/dist/core/loaders.js.map +1 -0
- package/dist/core/memory-add-type.d.ts +43 -0
- package/dist/core/memory-add-type.d.ts.map +1 -0
- package/dist/core/memory-add-type.js +151 -0
- package/dist/core/memory-add-type.js.map +1 -0
- package/dist/core/memory-transition.d.ts +111 -0
- package/dist/core/memory-transition.d.ts.map +1 -0
- package/dist/core/memory-transition.js +269 -0
- package/dist/core/memory-transition.js.map +1 -0
- package/dist/core/registry.d.ts +189 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +66 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/relevance.d.ts +86 -0
- package/dist/core/relevance.d.ts.map +1 -0
- package/dist/core/relevance.js +258 -0
- package/dist/core/relevance.js.map +1 -0
- package/dist/core/require-reason.d.ts +27 -0
- package/dist/core/require-reason.d.ts.map +1 -0
- package/dist/core/require-reason.js +95 -0
- package/dist/core/require-reason.js.map +1 -0
- package/dist/core/types.d.ts +45 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +22 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage-error.d.ts +20 -0
- package/dist/core/usage-error.d.ts.map +1 -0
- package/dist/core/usage-error.js +29 -0
- package/dist/core/usage-error.js.map +1 -0
- package/dist/core/write-guard.d.ts +99 -0
- package/dist/core/write-guard.d.ts.map +1 -0
- package/dist/core/write-guard.js +247 -0
- package/dist/core/write-guard.js.map +1 -0
- package/dist/directives/create.d.ts +47 -0
- package/dist/directives/create.d.ts.map +1 -0
- package/dist/directives/create.js +82 -0
- package/dist/directives/create.js.map +1 -0
- package/dist/directives/index.d.ts +20 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/directives/index.js +32 -0
- package/dist/directives/index.js.map +1 -0
- package/dist/directives/roles-edit.d.ts +53 -0
- package/dist/directives/roles-edit.d.ts.map +1 -0
- package/dist/directives/roles-edit.js +286 -0
- package/dist/directives/roles-edit.js.map +1 -0
- package/dist/directives/schema.d.ts +65 -0
- package/dist/directives/schema.d.ts.map +1 -0
- package/dist/directives/schema.js +68 -0
- package/dist/directives/schema.js.map +1 -0
- package/dist/dna/edit.d.ts +61 -0
- package/dist/dna/edit.d.ts.map +1 -0
- package/dist/dna/edit.js +429 -0
- package/dist/dna/edit.js.map +1 -0
- package/dist/dna/index.d.ts +24 -0
- package/dist/dna/index.d.ts.map +1 -0
- package/dist/dna/index.js +59 -0
- package/dist/dna/index.js.map +1 -0
- package/dist/dna/mutate.d.ts +74 -0
- package/dist/dna/mutate.d.ts.map +1 -0
- package/dist/dna/mutate.js +318 -0
- package/dist/dna/mutate.js.map +1 -0
- package/dist/dna/path.d.ts +175 -0
- package/dist/dna/path.d.ts.map +1 -0
- package/dist/dna/path.js +289 -0
- package/dist/dna/path.js.map +1 -0
- package/dist/dna/roles.d.ts +57 -0
- package/dist/dna/roles.d.ts.map +1 -0
- package/dist/dna/roles.js +50 -0
- package/dist/dna/roles.js.map +1 -0
- package/dist/dna/schema.d.ts +172 -0
- package/dist/dna/schema.d.ts.map +1 -0
- package/dist/dna/schema.js +182 -0
- package/dist/dna/schema.js.map +1 -0
- package/dist/dna/set.d.ts +145 -0
- package/dist/dna/set.d.ts.map +1 -0
- package/dist/dna/set.js +428 -0
- package/dist/dna/set.js.map +1 -0
- package/dist/mcp/dna-resource.d.ts +16 -0
- package/dist/mcp/dna-resource.d.ts.map +1 -0
- package/dist/mcp/dna-resource.js +56 -0
- package/dist/mcp/dna-resource.js.map +1 -0
- package/dist/mcp/index.d.ts +49 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +60 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/memory-resource.d.ts +17 -0
- package/dist/mcp/memory-resource.d.ts.map +1 -0
- package/dist/mcp/memory-resource.js +133 -0
- package/dist/mcp/memory-resource.js.map +1 -0
- package/dist/mcp/prompt.d.ts +48 -0
- package/dist/mcp/prompt.d.ts.map +1 -0
- package/dist/mcp/prompt.js +176 -0
- package/dist/mcp/prompt.js.map +1 -0
- package/dist/mcp/read-only.d.ts +42 -0
- package/dist/mcp/read-only.d.ts.map +1 -0
- package/dist/mcp/read-only.js +93 -0
- package/dist/mcp/read-only.js.map +1 -0
- package/dist/mcp/registrar.d.ts +54 -0
- package/dist/mcp/registrar.d.ts.map +1 -0
- package/dist/mcp/registrar.js +72 -0
- package/dist/mcp/registrar.js.map +1 -0
- package/dist/mcp/server.d.ts +58 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +64 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/workflow-resource.d.ts +17 -0
- package/dist/mcp/workflow-resource.d.ts.map +1 -0
- package/dist/mcp/workflow-resource.js +63 -0
- package/dist/mcp/workflow-resource.js.map +1 -0
- package/dist/memory/add.d.ts +50 -0
- package/dist/memory/add.d.ts.map +1 -0
- package/dist/memory/add.js +131 -0
- package/dist/memory/add.js.map +1 -0
- package/dist/memory/audit.d.ts +177 -0
- package/dist/memory/audit.d.ts.map +1 -0
- package/dist/memory/audit.js +287 -0
- package/dist/memory/audit.js.map +1 -0
- package/dist/memory/commit-message.d.ts +146 -0
- package/dist/memory/commit-message.d.ts.map +1 -0
- package/dist/memory/commit-message.js +203 -0
- package/dist/memory/commit-message.js.map +1 -0
- package/dist/memory/entry.d.ts +56 -0
- package/dist/memory/entry.d.ts.map +1 -0
- package/dist/memory/entry.js +28 -0
- package/dist/memory/entry.js.map +1 -0
- package/dist/memory/frontmatter-edit.d.ts +68 -0
- package/dist/memory/frontmatter-edit.d.ts.map +1 -0
- package/dist/memory/frontmatter-edit.js +333 -0
- package/dist/memory/frontmatter-edit.js.map +1 -0
- package/dist/memory/git-log.d.ts +32 -0
- package/dist/memory/git-log.d.ts.map +1 -0
- package/dist/memory/git-log.js +100 -0
- package/dist/memory/git-log.js.map +1 -0
- package/dist/memory/history.d.ts +142 -0
- package/dist/memory/history.d.ts.map +1 -0
- package/dist/memory/history.js +250 -0
- package/dist/memory/history.js.map +1 -0
- package/dist/memory/index.d.ts +58 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +107 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/query.d.ts +150 -0
- package/dist/memory/query.d.ts.map +1 -0
- package/dist/memory/query.js +307 -0
- package/dist/memory/query.js.map +1 -0
- package/dist/memory/reject.d.ts +11 -0
- package/dist/memory/reject.d.ts.map +1 -0
- package/dist/memory/reject.js +32 -0
- package/dist/memory/reject.js.map +1 -0
- package/dist/memory/schema.d.ts +104 -0
- package/dist/memory/schema.d.ts.map +1 -0
- package/dist/memory/schema.js +161 -0
- package/dist/memory/schema.js.map +1 -0
- package/dist/memory/state-machine.d.ts +166 -0
- package/dist/memory/state-machine.d.ts.map +1 -0
- package/dist/memory/state-machine.js +431 -0
- package/dist/memory/state-machine.js.map +1 -0
- package/dist/memory/submit.d.ts +11 -0
- package/dist/memory/submit.d.ts.map +1 -0
- package/dist/memory/submit.js +44 -0
- package/dist/memory/submit.js.map +1 -0
- package/dist/storage/builtin-directives.d.ts +54 -0
- package/dist/storage/builtin-directives.d.ts.map +1 -0
- package/dist/storage/builtin-directives.js +152 -0
- package/dist/storage/builtin-directives.js.map +1 -0
- package/dist/storage/commit.d.ts +92 -0
- package/dist/storage/commit.d.ts.map +1 -0
- package/dist/storage/commit.js +201 -0
- package/dist/storage/commit.js.map +1 -0
- package/dist/storage/confinement.d.ts +93 -0
- package/dist/storage/confinement.d.ts.map +1 -0
- package/dist/storage/confinement.js +164 -0
- package/dist/storage/confinement.js.map +1 -0
- package/dist/storage/document.d.ts +27 -0
- package/dist/storage/document.d.ts.map +1 -0
- package/dist/storage/document.js +52 -0
- package/dist/storage/document.js.map +1 -0
- package/dist/storage/errors.d.ts +36 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +46 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/frontmatter.d.ts +27 -0
- package/dist/storage/frontmatter.d.ts.map +1 -0
- package/dist/storage/frontmatter.js +37 -0
- package/dist/storage/frontmatter.js.map +1 -0
- package/dist/storage/git-root.d.ts +17 -0
- package/dist/storage/git-root.d.ts.map +1 -0
- package/dist/storage/git-root.js +49 -0
- package/dist/storage/git-root.js.map +1 -0
- package/dist/storage/index.d.ts +29 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +66 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/init-state.d.ts +9 -0
- package/dist/storage/init-state.d.ts.map +1 -0
- package/dist/storage/init-state.js +24 -0
- package/dist/storage/init-state.js.map +1 -0
- package/dist/storage/layout.d.ts +51 -0
- package/dist/storage/layout.d.ts.map +1 -0
- package/dist/storage/layout.js +88 -0
- package/dist/storage/layout.js.map +1 -0
- package/dist/storage/memory-path.d.ts +72 -0
- package/dist/storage/memory-path.d.ts.map +1 -0
- package/dist/storage/memory-path.js +127 -0
- package/dist/storage/memory-path.js.map +1 -0
- package/dist/storage/snapshot.d.ts +16 -0
- package/dist/storage/snapshot.d.ts.map +1 -0
- package/dist/storage/snapshot.js +72 -0
- package/dist/storage/snapshot.js.map +1 -0
- package/dist/storage/templates.d.ts +88 -0
- package/dist/storage/templates.d.ts.map +1 -0
- package/dist/storage/templates.js +422 -0
- package/dist/storage/templates.js.map +1 -0
- package/dist/validation/error-mapper.d.ts +16 -0
- package/dist/validation/error-mapper.d.ts.map +1 -0
- package/dist/validation/error-mapper.js +18 -0
- package/dist/validation/error-mapper.js.map +1 -0
- package/dist/validation/errors.d.ts +69 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +69 -0
- package/dist/validation/errors.js.map +1 -0
- package/dist/validation/id.d.ts +16 -0
- package/dist/validation/id.d.ts.map +1 -0
- package/dist/validation/id.js +177 -0
- package/dist/validation/id.js.map +1 -0
- package/dist/validation/index.d.ts +18 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +37 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/secret-scan.d.ts +129 -0
- package/dist/validation/secret-scan.d.ts.map +1 -0
- package/dist/validation/secret-scan.js +367 -0
- package/dist/validation/secret-scan.js.map +1 -0
- package/dist/validation/two-pass.d.ts +24 -0
- package/dist/validation/two-pass.d.ts.map +1 -0
- package/dist/validation/two-pass.js +24 -0
- package/dist/validation/two-pass.js.map +1 -0
- package/dist/validation/warning.d.ts +31 -0
- package/dist/validation/warning.d.ts.map +1 -0
- package/dist/validation/warning.js +81 -0
- package/dist/validation/warning.js.map +1 -0
- package/dist/validation/yaml.d.ts +9 -0
- package/dist/validation/yaml.d.ts.map +1 -0
- package/dist/validation/yaml.js +30 -0
- package/dist/validation/yaml.js.map +1 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +16 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/schema.d.ts +89 -0
- package/dist/workflow/schema.d.ts.map +1 -0
- package/dist/workflow/schema.js +73 -0
- package/dist/workflow/schema.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/memory/history.ts"],"names":[],"mappings":"AAiCA,sGAAsG;AACtG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAexF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,kBAAkB,EAAE,CAUtB;AAmBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA+B9F;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,kBAAkB,EAAE,EACtC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,YAAY,EAAE,MAAM,GACnB,kBAAkB,EAAE,CAEtB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA4BzF"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findElementCreationSha = findElementCreationSha;
|
|
4
|
+
exports.dropPreCreationAncestry = dropPreCreationAncestry;
|
|
5
|
+
exports.collectHistoricalPaths = collectHistoricalPaths;
|
|
6
|
+
exports.attachHistoricalPaths = attachHistoricalPaths;
|
|
7
|
+
exports.getMemoryHistory = getMemoryHistory;
|
|
8
|
+
/**
|
|
9
|
+
* Memory history primitive (task-008-dna-memory-query-latency, REQ-PERF-02) — the git-log walk
|
|
10
|
+
* underneath `wingfoil memory history` (P1.10), which shipped in `task-049-memory-history` as
|
|
11
|
+
* `src/core`'s `memoryHistory` operation. Per ADR-007 (stateless-state-derivation), git history is
|
|
12
|
+
* the sole audit trail for a Memory element's transitions — there is no secondary `.wingfoil/state/`
|
|
13
|
+
* log to query instead — so this walks `git log` directly over the element's file.
|
|
14
|
+
*
|
|
15
|
+
* Scope (see task-008's Execution Notes): this returns *structured commit records* (sha, author
|
|
16
|
+
* name/email, ISO-8601 author date, subject, body) — the walk itself. Deriving a human-facing
|
|
17
|
+
* "state change" (e.g. "pending -> backlog") from the commit body's `Approver:`/`Reason:` lines
|
|
18
|
+
* (CLAUDE.md §5.1) is not this primitive's concern; the raw `body` field carries that text verbatim
|
|
19
|
+
* for a caller to parse, and `./audit`'s `reconstructMemoryTransitions` is the caller that does — the
|
|
20
|
+
* `memoryHistory` operation projects that reconstruction rather than re-reading this walk itself.
|
|
21
|
+
*
|
|
22
|
+
* The `git log` walk/record-splitting plumbing itself lives in `./git-log` (factored out by
|
|
23
|
+
* task-015-complete-audit-trail, which needs the same plumbing for its own attribution audit) — this
|
|
24
|
+
* module owns only the `MemoryHistoryEntry` shape and the `--follow` single-document semantics.
|
|
25
|
+
*
|
|
26
|
+
* Those `--follow` semantics are this module's real subject, and they are not the ones the flag's
|
|
27
|
+
* name suggests (`task-089-fix-history-walk-attributes-only-real-commits`,
|
|
28
|
+
* `bug-077-history-follow-attributes-template-commits`). `--follow` does not only follow renames:
|
|
29
|
+
* git's path search runs with **copy** detection enabled, so when the path is absent from a parent
|
|
30
|
+
* commit git will accept a source that still exists there. Every Memory element is created by
|
|
31
|
+
* copying its type's template, which `wingfoil init` has already committed — so the walk crossed
|
|
32
|
+
* that copy edge and reported the commit that added the TEMPLATE as an entry of the element's own
|
|
33
|
+
* history, carrying a real sha, author and timestamp with every derived field null. See
|
|
34
|
+
* {@link findElementCreationSha} for the distinction that resolves it and why rename-following is
|
|
35
|
+
* kept rather than traded away.
|
|
36
|
+
*/
|
|
37
|
+
const child_process_1 = require("child_process");
|
|
38
|
+
const git_log_1 = require("./git-log");
|
|
39
|
+
const LOG_FIELDS = ['%H', '%an', '%ae', '%aI', '%s', '%b'];
|
|
40
|
+
/**
|
|
41
|
+
* The same `--follow` walk as {@link getMemoryHistory}, narrowed by git to the commits whose edge for
|
|
42
|
+
* this path is a **copy**, and printing nothing but the sha. Deliberately a second `git log`
|
|
43
|
+
* invocation rather than extra output threaded through the first: `walkGitLogFields` recovers
|
|
44
|
+
* records by field arity over a stream of `<field>NUL` groups, so anything git appends outside the
|
|
45
|
+
* `--format` string — `--name-status` output, for instance — would be read as the next record's
|
|
46
|
+
* first field (task-086).
|
|
47
|
+
*/
|
|
48
|
+
const CREATION_PROBE_ARGS = ['--follow', '--diff-filter=C', '--format=%H'];
|
|
49
|
+
/**
|
|
50
|
+
* The sha of the commit that introduced `relativePath` as a COPY of a file that outlives it — the
|
|
51
|
+
* element's own creation — or `null` when the followed chain contains no copy edge at all.
|
|
52
|
+
*
|
|
53
|
+
* This is the distinction the fix turns on. `git log --follow` can change path across two different
|
|
54
|
+
* kinds of edge, and they mean opposite things for an audit trail:
|
|
55
|
+
*
|
|
56
|
+
* - **`R` (rename)** — the element continuing under a new name. Keep following. This is not a
|
|
57
|
+
* hypothetical requirement: `docs/self/docs/04_memory/planning/v1/*` became `planning/rl-v1/*` in
|
|
58
|
+
* one commit in this repository, moving five `release` elements at once, because the `release`
|
|
59
|
+
* type's `path` pattern interpolates the release-line id (`memory.yaml`). For one of them a plain
|
|
60
|
+
* `git log -- <path>` returns a single commit where the followed walk returns seven, so dropping
|
|
61
|
+
* `--follow` would delete five sixths of that element's recorded history.
|
|
62
|
+
* - **`C` (copy)** — the element being born out of a file that still exists. `wingfoil memory add`
|
|
63
|
+
* copies the type's template verbatim (CLAUDE.md §5.1), and `wingfoil init` has already committed
|
|
64
|
+
* that template, so this edge is how every scaffolded element begins. Everything strictly older
|
|
65
|
+
* than it is the template's history, not the element's.
|
|
66
|
+
*
|
|
67
|
+
* Only the newest copy edge matters — it is the element's own creation; any older one belongs to
|
|
68
|
+
* whatever the source itself was copied from. `git log` prints newest first, so that is the first
|
|
69
|
+
* line.
|
|
70
|
+
*
|
|
71
|
+
* **Throws** — never returns `null` — when git itself fails. "git could not answer" and "this
|
|
72
|
+
* element was never copied from anything" are different answers, and collapsing the first into the
|
|
73
|
+
* second would silently restore the phantom entry; it is also why this cannot borrow
|
|
74
|
+
* `walkGitLogFields`, whose `catch` returns `[]` (`bug-072-oversized-git-log-becomes-empty-history`).
|
|
75
|
+
* {@link getMemoryHistory} calls this only once the main walk has already returned commits, so at
|
|
76
|
+
* that point the repository and the path are both known good and a failure here is genuinely
|
|
77
|
+
* exceptional.
|
|
78
|
+
*
|
|
79
|
+
* @param root - Absolute path of the repository to walk.
|
|
80
|
+
* @param relativePath - The element's root-relative path, as {@link getMemoryHistory} takes it.
|
|
81
|
+
* @returns The creation commit's full sha, or `null` when the chain has no copy edge.
|
|
82
|
+
*/
|
|
83
|
+
function findElementCreationSha(root, relativePath) {
|
|
84
|
+
let stdout;
|
|
85
|
+
try {
|
|
86
|
+
stdout = (0, child_process_1.execFileSync)('git', ['-C', root, 'log', ...CREATION_PROBE_ARGS, '--', relativePath], {
|
|
87
|
+
encoding: 'utf-8',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (cause) {
|
|
91
|
+
throw new Error(`git log --follow --diff-filter=C failed for ${relativePath}: cannot establish where the element was created`, { cause });
|
|
92
|
+
}
|
|
93
|
+
const newestCopy = stdout.split('\n').find((line) => line.trim().length > 0);
|
|
94
|
+
return newestCopy === undefined ? null : newestCopy.trim();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Drop the part of an oldest-first walk that precedes the element's creation, keeping the creation
|
|
98
|
+
* commit itself — the ancestry `--follow` reached through a copy edge, which belongs to the file the
|
|
99
|
+
* element was copied from. `creationSha` of `null` (no copy edge: the document was authored in
|
|
100
|
+
* place) leaves the walk untouched.
|
|
101
|
+
*
|
|
102
|
+
* Pure: no git, no filesystem. Separated from {@link findElementCreationSha} so the truncation rule
|
|
103
|
+
* and the invariant below are exercised directly rather than through a repository fixture.
|
|
104
|
+
*
|
|
105
|
+
* **Throws** when `creationSha` is absent from `entries`. The two walks are the same walk — one is
|
|
106
|
+
* the other filtered by git — so a sha in the narrower one that is missing from the wider one is a
|
|
107
|
+
* broken invariant, not a case to absorb. Defaulting to "no truncation" there would report the
|
|
108
|
+
* phantom entry again while reporting success.
|
|
109
|
+
*
|
|
110
|
+
* @param entries - The full `--follow` walk, oldest first.
|
|
111
|
+
* @param creationSha - The element's creation commit, from {@link findElementCreationSha}.
|
|
112
|
+
* @returns `entries` from the creation commit onward (a new array; `entries` is not mutated).
|
|
113
|
+
*/
|
|
114
|
+
function dropPreCreationAncestry(entries, creationSha) {
|
|
115
|
+
if (creationSha === null)
|
|
116
|
+
return [...entries];
|
|
117
|
+
const creationIndex = entries.findIndex((entry) => entry.sha === creationSha);
|
|
118
|
+
if (creationIndex === -1) {
|
|
119
|
+
throw new Error(`creation commit ${creationSha} is not present in the history walk it was derived from`);
|
|
120
|
+
}
|
|
121
|
+
return entries.slice(creationIndex);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The same `--follow` walk again, printing each commit's sha followed by its name-status line for
|
|
125
|
+
* the followed path. A third `git log` invocation for the same reason as {@link CREATION_PROBE_ARGS}
|
|
126
|
+
* and stated in full there: `--name-status` output is appended OUTSIDE the `--format` string, and
|
|
127
|
+
* `walkGitLogFields` recovers records by field arity over a stream of `<field>NUL` groups, so it
|
|
128
|
+
* would read those lines as the next record's first field (task-086).
|
|
129
|
+
*
|
|
130
|
+
* `core.quotePath=false` is set for the invocation (never written to the repository's config) so a
|
|
131
|
+
* path carrying non-ASCII bytes arrives as its own UTF-8 rather than as git's `"\303\251"` escape
|
|
132
|
+
* form — the parser would otherwise have to un-escape it to hand `git show` something that resolves.
|
|
133
|
+
*/
|
|
134
|
+
const PATH_PROBE_ARGS = ['-c', 'core.quotePath=false'];
|
|
135
|
+
const PATH_PROBE_LOG_ARGS = ['--follow', '--name-status', '--format=%H'];
|
|
136
|
+
/** A full sha on a line of its own — git's `--format=%H` output, which carries nothing else. */
|
|
137
|
+
const SHA_LINE_RE = /^[0-9a-f]{40}$/;
|
|
138
|
+
/**
|
|
139
|
+
* Where `relativePath`'s document lived at each commit of its `--follow` walk, keyed by sha.
|
|
140
|
+
*
|
|
141
|
+
* `git log --follow --name-status` prints, per commit, the sha then that commit's status line for
|
|
142
|
+
* the followed path — `A <path>`, `M <path>`, `D <path>`, or `R<score> <old> <new>` at a rename. The
|
|
143
|
+
* path the file occupies **at** a commit is always the LAST tab-separated field of that line: the
|
|
144
|
+
* destination of a rename, the single path otherwise. Everything older than that rename then reports
|
|
145
|
+
* the old path, which is the whole point — it is what
|
|
146
|
+
* `git show <sha>:<path>` needs in order to resolve at all.
|
|
147
|
+
*
|
|
148
|
+
* A commit git reports no status line for (it shows no diff for a merge without `-m`) is simply
|
|
149
|
+
* absent from the map; {@link attachHistoricalPaths} decides what to do about that, so the rule is
|
|
150
|
+
* testable without a repository.
|
|
151
|
+
*
|
|
152
|
+
* **Throws** — never returns an empty map — when git itself fails, for the same reason
|
|
153
|
+
* {@link findElementCreationSha} does: "git could not answer" and "this element was never renamed"
|
|
154
|
+
* are different answers, and folding the first into the second silently reinstates `bug-080` by
|
|
155
|
+
* reading every commit at the current path again. {@link getMemoryHistory} calls this only once the
|
|
156
|
+
* main walk has returned commits, so the repository and the path are both known good by then.
|
|
157
|
+
*
|
|
158
|
+
* @param root - Absolute path of the repository to walk.
|
|
159
|
+
* @param relativePath - The element's current root-relative path, as the caller named it.
|
|
160
|
+
* @returns sha → the root-relative path the document occupied at that commit.
|
|
161
|
+
*/
|
|
162
|
+
function collectHistoricalPaths(root, relativePath) {
|
|
163
|
+
let stdout;
|
|
164
|
+
try {
|
|
165
|
+
stdout = (0, child_process_1.execFileSync)('git', ['-C', root, ...PATH_PROBE_ARGS, 'log', ...PATH_PROBE_LOG_ARGS, '--', relativePath],
|
|
166
|
+
// Same `stdio` rule as `./audit`'s `readStatusAt`, for the same reason
|
|
167
|
+
// (`bug-071-read-status-at-leaks-git-stderr`): the failure is reported by the throw below, so
|
|
168
|
+
// git's own `fatal:` must land in a pipe this process owns rather than on the operator's
|
|
169
|
+
// terminal. A call added while closing that bug must not reopen it somewhere else.
|
|
170
|
+
{ encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
|
|
171
|
+
}
|
|
172
|
+
catch (cause) {
|
|
173
|
+
throw new Error(`git log --follow --name-status failed for ${relativePath}: cannot establish where the element lived at each commit`, { cause });
|
|
174
|
+
}
|
|
175
|
+
const pathBySha = new Map();
|
|
176
|
+
let currentSha = null;
|
|
177
|
+
for (const line of stdout.split('\n')) {
|
|
178
|
+
if (SHA_LINE_RE.test(line)) {
|
|
179
|
+
currentSha = line;
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (currentSha === null || !line.includes('\t') || pathBySha.has(currentSha))
|
|
183
|
+
continue;
|
|
184
|
+
const fields = line.split('\t');
|
|
185
|
+
pathBySha.set(currentSha, fields[fields.length - 1]);
|
|
186
|
+
}
|
|
187
|
+
return pathBySha;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Stamp each walked commit with the path the element occupied at it, from
|
|
191
|
+
* {@link collectHistoricalPaths}' map.
|
|
192
|
+
*
|
|
193
|
+
* Pure: no git, no filesystem — separated from the probe for the same reason
|
|
194
|
+
* {@link dropPreCreationAncestry} is separated from {@link findElementCreationSha}, so the rule and
|
|
195
|
+
* its fallback are exercised directly rather than through a repository fixture.
|
|
196
|
+
*
|
|
197
|
+
* Falls back to `fallbackPath` (the path the caller named) for a sha the probe reported no diff for,
|
|
198
|
+
* rather than throwing: unlike the creation probe's invariant, an absent entry here is not evidence
|
|
199
|
+
* of a broken walk — git shows no diff for a merge commit — and the fallback is precisely the
|
|
200
|
+
* behaviour that shipped before this field existed, so it can degrade no further than the status quo.
|
|
201
|
+
*
|
|
202
|
+
* @param entries - The `--follow` walk, oldest first.
|
|
203
|
+
* @param pathBySha - sha → historical path, from {@link collectHistoricalPaths}.
|
|
204
|
+
* @param fallbackPath - The element's current root-relative path.
|
|
205
|
+
* @returns A new array; `entries` is not mutated.
|
|
206
|
+
*/
|
|
207
|
+
function attachHistoricalPaths(entries, pathBySha, fallbackPath) {
|
|
208
|
+
return entries.map((entry) => ({ ...entry, path: pathBySha.get(entry.sha) ?? fallbackPath }));
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Walk every commit that touched `relativePath`, oldest first (P1.10-memory-history.feature: "lists
|
|
212
|
+
* ... entries in chronological order") — `git log` itself returns newest-first, reversed by
|
|
213
|
+
* {@link walkGitLogFields} — and only those commits. The walk follows renames, so an element moved on
|
|
214
|
+
* disk keeps its history, but stops at the element's own creation rather than continuing into the
|
|
215
|
+
* template it was copied from ({@link findElementCreationSha}).
|
|
216
|
+
*
|
|
217
|
+
* Returns `[]`, rather than throwing, both when `root` has no commits touching the path at all and
|
|
218
|
+
* when `root` is not a git repository — "document not found" is a caller/feature-layer concern
|
|
219
|
+
* (task-021/026-style CLI error rendering), not this primitive's. That is also why the creation
|
|
220
|
+
* probe runs only on a non-empty walk: on an empty one there is nothing to truncate and nothing to
|
|
221
|
+
* conclude from git's silence — and the same for the path probe.
|
|
222
|
+
*
|
|
223
|
+
* Every returned entry carries the path the element occupied at its own commit
|
|
224
|
+
* ({@link MemoryHistoryEntry.path}), not the one the caller named. That is what makes this walk the
|
|
225
|
+
* single source of truth for "where was this file at this commit": a consumer that reads content per
|
|
226
|
+
* commit — `./audit`'s `reconstructMemoryTransitions`, which reads the frontmatter `status:` — must
|
|
227
|
+
* take the path from here rather than re-using its own argument (`bug-080`).
|
|
228
|
+
*/
|
|
229
|
+
function getMemoryHistory(root, relativePath) {
|
|
230
|
+
const records = (0, git_log_1.walkGitLogFields)(root, LOG_FIELDS, [relativePath], ['--follow']);
|
|
231
|
+
// One field per slot, `%b` included. Two consequences of task-086's arity-based framing, both
|
|
232
|
+
// deliberate:
|
|
233
|
+
//
|
|
234
|
+
// - The body arrives WHOLE even when it carries a character that used to look like a delimiter.
|
|
235
|
+
// `%b` being LAST was the only thing that made a `0x1f` in a reason survive before, via an
|
|
236
|
+
// explicit `bodyParts.join(FIELD_SEP)` that undid the split it had just caused; that accident
|
|
237
|
+
// and the reassembly compensating for it are both gone (bug-050).
|
|
238
|
+
// - Every record has exactly `LOG_FIELDS.length` entries — `walkGitLogFields` emits whole groups
|
|
239
|
+
// or none — so the per-slot `= ''` defaults this used to carry could never fire. They are read
|
|
240
|
+
// as the cast below instead of kept as six permanently-unreachable branches.
|
|
241
|
+
const entries = records.map((record) => {
|
|
242
|
+
const [sha, authorName, authorEmail, date, subject, body] = record;
|
|
243
|
+
return { sha, authorName, authorEmail, date, subject, body: body.trim(), path: relativePath };
|
|
244
|
+
});
|
|
245
|
+
if (entries.length === 0)
|
|
246
|
+
return entries;
|
|
247
|
+
const located = attachHistoricalPaths(entries, collectHistoricalPaths(root, relativePath), relativePath);
|
|
248
|
+
return dropPreCreationAncestry(located, findElementCreationSha(root, relativePath));
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/memory/history.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `memory` module — Project Memory pillar; git-backed documents with per-type state machines
|
|
3
|
+
* (P1.13). `memory.yaml`'s schema (spec-001-memory-yaml-schema) lives here — the pillar owns its own
|
|
4
|
+
* independent schema (REQ-SYS-02); `src/core`'s loader wires it through the shared validation
|
|
5
|
+
* pipeline. The transition-legality engine (REQ-SYS-04, task-005-per-type-state-machines) also lives
|
|
6
|
+
* here — it consumes the schema's already-validated `StateMachine` shape, it does not re-validate it.
|
|
7
|
+
* Further Memory behavior (per-type CLI verbs, frontmatter schema) lands in later tasks.
|
|
8
|
+
*
|
|
9
|
+
* task-008-dna-memory-query-latency adds the `memory search`/`memory history` query-path
|
|
10
|
+
* *primitives* (REQ-PERF-02) `./query` and `./history` — the performance-bearing foundation
|
|
11
|
+
* `task-021-implement-memory-search` (P1.5) and `task-049-memory-history` (P1.10) built their
|
|
12
|
+
* CLI/MCP surface on top of; see those modules' own doc comments and the task's Execution Notes for
|
|
13
|
+
* the foundation/feature scoping decision.
|
|
14
|
+
*
|
|
15
|
+
* task-015-complete-audit-trail adds `./audit` (REQ-SEC-02) — the audit/verification layer built on
|
|
16
|
+
* `./history`'s raw git-log walk: attribution auditing (0 "unknown author"), `Approver:`/`Reason:`
|
|
17
|
+
* commit-body parsing, full transition reconstruction, and the frontmatter-vs-commit-message
|
|
18
|
+
* consistency check. It is deliberately read-only/verification-only — write-time git-identity
|
|
19
|
+
* enforcement is task-014-git-identity-required's (REQ-SEC-01) separate concern.
|
|
20
|
+
*
|
|
21
|
+
* task-022-implement-memory-entries adds `./entry` (P1.11) — `writeMemoryEntry`, the reusable,
|
|
22
|
+
* throwing library primitive that composes `resolveConfinedMemoryPath` (task-017, REQ-SEC-06),
|
|
23
|
+
* `writeDocument`, and `commitPaths` (task-018) into the one "resolve confined path, write bytes,
|
|
24
|
+
* one commit" Memory-entry write path (REQ-SYS-01/REQ-SYS-03). `wingfoil memory add`/`submit`
|
|
25
|
+
* (task-020) wire this in behind a `CoreResult`; this module stays a plain, throwing composition,
|
|
26
|
+
* matching every other `src/storage` primitive it builds on.
|
|
27
|
+
*
|
|
28
|
+
* task-036-frontmatter-lifecycle-validation adds `validateFrontmatterState` (REQ-STATE-01,
|
|
29
|
+
* spec-010-memory-frontmatter-schema) to `./state-machine` — the per-type membership check on a
|
|
30
|
+
* document's frontmatter `status` value itself, independent of any transition attempt (distinct from
|
|
31
|
+
* `resolveTransitionTarget`'s verb-based transition legality). `task-045-memory-submit` (P1.6) is the
|
|
32
|
+
* first CLI-facing consumer.
|
|
33
|
+
*
|
|
34
|
+
* task-045-memory-submit adds the pieces every Memory transition verb shares — `resolveTypeTransition`
|
|
35
|
+
* (the `dl-032` illegal-transition contract), `./commit-message` (the one commit-message formatter) and
|
|
36
|
+
* `./frontmatter-edit` (byte-preserving field edits) — plus `./submit`, the submit-specific rules.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MODULE_NAME: "memory";
|
|
39
|
+
export { MemoryYaml, MemoryTypeEntry, StateMachine, TemplateConfig } from './schema';
|
|
40
|
+
export { ARCHIVED_STATUSES, DEFAULT_STATE_MACHINE, DEPRECATED_STATE, E_INVALID_STATE, E_INVALID_TRANSITION, isArchivedStatus, resolveStateMachine, resolveTransitionTarget, resolveTypeTransition, SUPERSEDED_STATE, validateFrontmatterState, } from './state-machine';
|
|
41
|
+
export type { TransitionOp } from './state-machine';
|
|
42
|
+
export { computeMemoryContentRoots, E_EMPTY_SEARCH_QUERY, findMemoryDocumentById, findMemoryDocumentByTypeAndId, listMemoryDocumentPaths, listMemoryDocumentsByType, loadMemoryDocumentSummary, searchMemoryDocuments, validateSearchQuery, } from './query';
|
|
43
|
+
export type { MemoryDocumentFrontmatterSummary, MemoryDocumentSummary, MemorySearchMatch, MemorySearchOptions, } from './query';
|
|
44
|
+
export { getMemoryHistory } from './history';
|
|
45
|
+
export type { MemoryHistoryEntry } from './history';
|
|
46
|
+
export { writeMemoryEntry } from './entry';
|
|
47
|
+
export type { MemoryEntryWrite } from './entry';
|
|
48
|
+
export { hasNumericToken, nextSequenceNumber, parseTags, renderAddDocument, resolveTypeDirectory, slugifyTitle, } from './add';
|
|
49
|
+
export type { AddDocumentFields } from './add';
|
|
50
|
+
export { formatMemoryCommitMessage, normalizeReason, parseApproverTrailerLine, parseReasonBlock, reasonDefect, reasonDefectMessage, } from './commit-message';
|
|
51
|
+
export type { CommitApprover, MemoryCommitMessageInput, ReasonDefect } from './commit-message';
|
|
52
|
+
export { describeDocumentChanges, removeFrontmatterField, setFrontmatterField, verifyDocumentEdit, verifyFrontmatterEdit, } from './frontmatter-edit';
|
|
53
|
+
export type { DocumentScope } from './frontmatter-edit';
|
|
54
|
+
export { missingRequiredFields, REJECTION_REASON_FIELD, renderSubmitDocument } from './submit';
|
|
55
|
+
export { renderRejectDocument } from './reject';
|
|
56
|
+
export { auditAttribution, isValidAttribution, parseApprovalMetadata, parseCommitReason, reconstructMemoryTransitions, verifyTransitionConsistency, } from './audit';
|
|
57
|
+
export type { AttributionEntry, ApprovalMetadata, MemoryTransition, ConsistencyMismatch } from './audit';
|
|
58
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,WAAW,EAAG,QAAiB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,gCAAgC,EAChC,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,GACb,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EACL,yBAAyB,EACzB,eAAe,EACf,wBAAwB,EACxB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,cAAc,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isValidAttribution = exports.auditAttribution = exports.renderRejectDocument = exports.renderSubmitDocument = exports.REJECTION_REASON_FIELD = exports.missingRequiredFields = exports.verifyFrontmatterEdit = exports.verifyDocumentEdit = exports.setFrontmatterField = exports.removeFrontmatterField = exports.describeDocumentChanges = exports.reasonDefectMessage = exports.reasonDefect = exports.parseReasonBlock = exports.parseApproverTrailerLine = exports.normalizeReason = exports.formatMemoryCommitMessage = exports.slugifyTitle = exports.resolveTypeDirectory = exports.renderAddDocument = exports.parseTags = exports.nextSequenceNumber = exports.hasNumericToken = exports.writeMemoryEntry = exports.getMemoryHistory = exports.validateSearchQuery = exports.searchMemoryDocuments = exports.loadMemoryDocumentSummary = exports.listMemoryDocumentsByType = exports.listMemoryDocumentPaths = exports.findMemoryDocumentByTypeAndId = exports.findMemoryDocumentById = exports.E_EMPTY_SEARCH_QUERY = exports.computeMemoryContentRoots = exports.validateFrontmatterState = exports.SUPERSEDED_STATE = exports.resolveTypeTransition = exports.resolveTransitionTarget = exports.resolveStateMachine = exports.isArchivedStatus = exports.E_INVALID_TRANSITION = exports.E_INVALID_STATE = exports.DEPRECATED_STATE = exports.DEFAULT_STATE_MACHINE = exports.ARCHIVED_STATUSES = exports.TemplateConfig = exports.StateMachine = exports.MemoryTypeEntry = exports.MemoryYaml = exports.MODULE_NAME = void 0;
|
|
4
|
+
exports.verifyTransitionConsistency = exports.reconstructMemoryTransitions = exports.parseCommitReason = exports.parseApprovalMetadata = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* `memory` module — Project Memory pillar; git-backed documents with per-type state machines
|
|
7
|
+
* (P1.13). `memory.yaml`'s schema (spec-001-memory-yaml-schema) lives here — the pillar owns its own
|
|
8
|
+
* independent schema (REQ-SYS-02); `src/core`'s loader wires it through the shared validation
|
|
9
|
+
* pipeline. The transition-legality engine (REQ-SYS-04, task-005-per-type-state-machines) also lives
|
|
10
|
+
* here — it consumes the schema's already-validated `StateMachine` shape, it does not re-validate it.
|
|
11
|
+
* Further Memory behavior (per-type CLI verbs, frontmatter schema) lands in later tasks.
|
|
12
|
+
*
|
|
13
|
+
* task-008-dna-memory-query-latency adds the `memory search`/`memory history` query-path
|
|
14
|
+
* *primitives* (REQ-PERF-02) `./query` and `./history` — the performance-bearing foundation
|
|
15
|
+
* `task-021-implement-memory-search` (P1.5) and `task-049-memory-history` (P1.10) built their
|
|
16
|
+
* CLI/MCP surface on top of; see those modules' own doc comments and the task's Execution Notes for
|
|
17
|
+
* the foundation/feature scoping decision.
|
|
18
|
+
*
|
|
19
|
+
* task-015-complete-audit-trail adds `./audit` (REQ-SEC-02) — the audit/verification layer built on
|
|
20
|
+
* `./history`'s raw git-log walk: attribution auditing (0 "unknown author"), `Approver:`/`Reason:`
|
|
21
|
+
* commit-body parsing, full transition reconstruction, and the frontmatter-vs-commit-message
|
|
22
|
+
* consistency check. It is deliberately read-only/verification-only — write-time git-identity
|
|
23
|
+
* enforcement is task-014-git-identity-required's (REQ-SEC-01) separate concern.
|
|
24
|
+
*
|
|
25
|
+
* task-022-implement-memory-entries adds `./entry` (P1.11) — `writeMemoryEntry`, the reusable,
|
|
26
|
+
* throwing library primitive that composes `resolveConfinedMemoryPath` (task-017, REQ-SEC-06),
|
|
27
|
+
* `writeDocument`, and `commitPaths` (task-018) into the one "resolve confined path, write bytes,
|
|
28
|
+
* one commit" Memory-entry write path (REQ-SYS-01/REQ-SYS-03). `wingfoil memory add`/`submit`
|
|
29
|
+
* (task-020) wire this in behind a `CoreResult`; this module stays a plain, throwing composition,
|
|
30
|
+
* matching every other `src/storage` primitive it builds on.
|
|
31
|
+
*
|
|
32
|
+
* task-036-frontmatter-lifecycle-validation adds `validateFrontmatterState` (REQ-STATE-01,
|
|
33
|
+
* spec-010-memory-frontmatter-schema) to `./state-machine` — the per-type membership check on a
|
|
34
|
+
* document's frontmatter `status` value itself, independent of any transition attempt (distinct from
|
|
35
|
+
* `resolveTransitionTarget`'s verb-based transition legality). `task-045-memory-submit` (P1.6) is the
|
|
36
|
+
* first CLI-facing consumer.
|
|
37
|
+
*
|
|
38
|
+
* task-045-memory-submit adds the pieces every Memory transition verb shares — `resolveTypeTransition`
|
|
39
|
+
* (the `dl-032` illegal-transition contract), `./commit-message` (the one commit-message formatter) and
|
|
40
|
+
* `./frontmatter-edit` (byte-preserving field edits) — plus `./submit`, the submit-specific rules.
|
|
41
|
+
*/
|
|
42
|
+
exports.MODULE_NAME = 'memory';
|
|
43
|
+
var schema_1 = require("./schema");
|
|
44
|
+
Object.defineProperty(exports, "MemoryYaml", { enumerable: true, get: function () { return schema_1.MemoryYaml; } });
|
|
45
|
+
Object.defineProperty(exports, "MemoryTypeEntry", { enumerable: true, get: function () { return schema_1.MemoryTypeEntry; } });
|
|
46
|
+
Object.defineProperty(exports, "StateMachine", { enumerable: true, get: function () { return schema_1.StateMachine; } });
|
|
47
|
+
Object.defineProperty(exports, "TemplateConfig", { enumerable: true, get: function () { return schema_1.TemplateConfig; } });
|
|
48
|
+
var state_machine_1 = require("./state-machine");
|
|
49
|
+
Object.defineProperty(exports, "ARCHIVED_STATUSES", { enumerable: true, get: function () { return state_machine_1.ARCHIVED_STATUSES; } });
|
|
50
|
+
Object.defineProperty(exports, "DEFAULT_STATE_MACHINE", { enumerable: true, get: function () { return state_machine_1.DEFAULT_STATE_MACHINE; } });
|
|
51
|
+
Object.defineProperty(exports, "DEPRECATED_STATE", { enumerable: true, get: function () { return state_machine_1.DEPRECATED_STATE; } });
|
|
52
|
+
Object.defineProperty(exports, "E_INVALID_STATE", { enumerable: true, get: function () { return state_machine_1.E_INVALID_STATE; } });
|
|
53
|
+
Object.defineProperty(exports, "E_INVALID_TRANSITION", { enumerable: true, get: function () { return state_machine_1.E_INVALID_TRANSITION; } });
|
|
54
|
+
Object.defineProperty(exports, "isArchivedStatus", { enumerable: true, get: function () { return state_machine_1.isArchivedStatus; } });
|
|
55
|
+
Object.defineProperty(exports, "resolveStateMachine", { enumerable: true, get: function () { return state_machine_1.resolveStateMachine; } });
|
|
56
|
+
Object.defineProperty(exports, "resolveTransitionTarget", { enumerable: true, get: function () { return state_machine_1.resolveTransitionTarget; } });
|
|
57
|
+
Object.defineProperty(exports, "resolveTypeTransition", { enumerable: true, get: function () { return state_machine_1.resolveTypeTransition; } });
|
|
58
|
+
Object.defineProperty(exports, "SUPERSEDED_STATE", { enumerable: true, get: function () { return state_machine_1.SUPERSEDED_STATE; } });
|
|
59
|
+
Object.defineProperty(exports, "validateFrontmatterState", { enumerable: true, get: function () { return state_machine_1.validateFrontmatterState; } });
|
|
60
|
+
var query_1 = require("./query");
|
|
61
|
+
Object.defineProperty(exports, "computeMemoryContentRoots", { enumerable: true, get: function () { return query_1.computeMemoryContentRoots; } });
|
|
62
|
+
Object.defineProperty(exports, "E_EMPTY_SEARCH_QUERY", { enumerable: true, get: function () { return query_1.E_EMPTY_SEARCH_QUERY; } });
|
|
63
|
+
Object.defineProperty(exports, "findMemoryDocumentById", { enumerable: true, get: function () { return query_1.findMemoryDocumentById; } });
|
|
64
|
+
Object.defineProperty(exports, "findMemoryDocumentByTypeAndId", { enumerable: true, get: function () { return query_1.findMemoryDocumentByTypeAndId; } });
|
|
65
|
+
Object.defineProperty(exports, "listMemoryDocumentPaths", { enumerable: true, get: function () { return query_1.listMemoryDocumentPaths; } });
|
|
66
|
+
Object.defineProperty(exports, "listMemoryDocumentsByType", { enumerable: true, get: function () { return query_1.listMemoryDocumentsByType; } });
|
|
67
|
+
Object.defineProperty(exports, "loadMemoryDocumentSummary", { enumerable: true, get: function () { return query_1.loadMemoryDocumentSummary; } });
|
|
68
|
+
Object.defineProperty(exports, "searchMemoryDocuments", { enumerable: true, get: function () { return query_1.searchMemoryDocuments; } });
|
|
69
|
+
Object.defineProperty(exports, "validateSearchQuery", { enumerable: true, get: function () { return query_1.validateSearchQuery; } });
|
|
70
|
+
var history_1 = require("./history");
|
|
71
|
+
Object.defineProperty(exports, "getMemoryHistory", { enumerable: true, get: function () { return history_1.getMemoryHistory; } });
|
|
72
|
+
var entry_1 = require("./entry");
|
|
73
|
+
Object.defineProperty(exports, "writeMemoryEntry", { enumerable: true, get: function () { return entry_1.writeMemoryEntry; } });
|
|
74
|
+
var add_1 = require("./add");
|
|
75
|
+
Object.defineProperty(exports, "hasNumericToken", { enumerable: true, get: function () { return add_1.hasNumericToken; } });
|
|
76
|
+
Object.defineProperty(exports, "nextSequenceNumber", { enumerable: true, get: function () { return add_1.nextSequenceNumber; } });
|
|
77
|
+
Object.defineProperty(exports, "parseTags", { enumerable: true, get: function () { return add_1.parseTags; } });
|
|
78
|
+
Object.defineProperty(exports, "renderAddDocument", { enumerable: true, get: function () { return add_1.renderAddDocument; } });
|
|
79
|
+
Object.defineProperty(exports, "resolveTypeDirectory", { enumerable: true, get: function () { return add_1.resolveTypeDirectory; } });
|
|
80
|
+
Object.defineProperty(exports, "slugifyTitle", { enumerable: true, get: function () { return add_1.slugifyTitle; } });
|
|
81
|
+
var commit_message_1 = require("./commit-message");
|
|
82
|
+
Object.defineProperty(exports, "formatMemoryCommitMessage", { enumerable: true, get: function () { return commit_message_1.formatMemoryCommitMessage; } });
|
|
83
|
+
Object.defineProperty(exports, "normalizeReason", { enumerable: true, get: function () { return commit_message_1.normalizeReason; } });
|
|
84
|
+
Object.defineProperty(exports, "parseApproverTrailerLine", { enumerable: true, get: function () { return commit_message_1.parseApproverTrailerLine; } });
|
|
85
|
+
Object.defineProperty(exports, "parseReasonBlock", { enumerable: true, get: function () { return commit_message_1.parseReasonBlock; } });
|
|
86
|
+
Object.defineProperty(exports, "reasonDefect", { enumerable: true, get: function () { return commit_message_1.reasonDefect; } });
|
|
87
|
+
Object.defineProperty(exports, "reasonDefectMessage", { enumerable: true, get: function () { return commit_message_1.reasonDefectMessage; } });
|
|
88
|
+
var frontmatter_edit_1 = require("./frontmatter-edit");
|
|
89
|
+
Object.defineProperty(exports, "describeDocumentChanges", { enumerable: true, get: function () { return frontmatter_edit_1.describeDocumentChanges; } });
|
|
90
|
+
Object.defineProperty(exports, "removeFrontmatterField", { enumerable: true, get: function () { return frontmatter_edit_1.removeFrontmatterField; } });
|
|
91
|
+
Object.defineProperty(exports, "setFrontmatterField", { enumerable: true, get: function () { return frontmatter_edit_1.setFrontmatterField; } });
|
|
92
|
+
Object.defineProperty(exports, "verifyDocumentEdit", { enumerable: true, get: function () { return frontmatter_edit_1.verifyDocumentEdit; } });
|
|
93
|
+
Object.defineProperty(exports, "verifyFrontmatterEdit", { enumerable: true, get: function () { return frontmatter_edit_1.verifyFrontmatterEdit; } });
|
|
94
|
+
var submit_1 = require("./submit");
|
|
95
|
+
Object.defineProperty(exports, "missingRequiredFields", { enumerable: true, get: function () { return submit_1.missingRequiredFields; } });
|
|
96
|
+
Object.defineProperty(exports, "REJECTION_REASON_FIELD", { enumerable: true, get: function () { return submit_1.REJECTION_REASON_FIELD; } });
|
|
97
|
+
Object.defineProperty(exports, "renderSubmitDocument", { enumerable: true, get: function () { return submit_1.renderSubmitDocument; } });
|
|
98
|
+
var reject_1 = require("./reject");
|
|
99
|
+
Object.defineProperty(exports, "renderRejectDocument", { enumerable: true, get: function () { return reject_1.renderRejectDocument; } });
|
|
100
|
+
var audit_1 = require("./audit");
|
|
101
|
+
Object.defineProperty(exports, "auditAttribution", { enumerable: true, get: function () { return audit_1.auditAttribution; } });
|
|
102
|
+
Object.defineProperty(exports, "isValidAttribution", { enumerable: true, get: function () { return audit_1.isValidAttribution; } });
|
|
103
|
+
Object.defineProperty(exports, "parseApprovalMetadata", { enumerable: true, get: function () { return audit_1.parseApprovalMetadata; } });
|
|
104
|
+
Object.defineProperty(exports, "parseCommitReason", { enumerable: true, get: function () { return audit_1.parseCommitReason; } });
|
|
105
|
+
Object.defineProperty(exports, "reconstructMemoryTransitions", { enumerable: true, get: function () { return audit_1.reconstructMemoryTransitions; } });
|
|
106
|
+
Object.defineProperty(exports, "verifyTransitionConsistency", { enumerable: true, get: function () { return audit_1.verifyTransitionConsistency; } });
|
|
107
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/memory/index.ts"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACU,QAAA,WAAW,GAAG,QAAiB,CAAC;AAE7C,mCAAqF;AAA5E,oGAAA,UAAU,OAAA;AAAE,yGAAA,eAAe,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,wGAAA,cAAc,OAAA;AAClE,iDAYyB;AAXvB,kHAAA,iBAAiB,OAAA;AACjB,sHAAA,qBAAqB,OAAA;AACrB,iHAAA,gBAAgB,OAAA;AAChB,gHAAA,eAAe,OAAA;AACf,qHAAA,oBAAoB,OAAA;AACpB,iHAAA,gBAAgB,OAAA;AAChB,oHAAA,mBAAmB,OAAA;AACnB,wHAAA,uBAAuB,OAAA;AACvB,sHAAA,qBAAqB,OAAA;AACrB,iHAAA,gBAAgB,OAAA;AAChB,yHAAA,wBAAwB,OAAA;AAG1B,iCAUiB;AATf,kHAAA,yBAAyB,OAAA;AACzB,6GAAA,oBAAoB,OAAA;AACpB,+GAAA,sBAAsB,OAAA;AACtB,sHAAA,6BAA6B,OAAA;AAC7B,gHAAA,uBAAuB,OAAA;AACvB,kHAAA,yBAAyB,OAAA;AACzB,kHAAA,yBAAyB,OAAA;AACzB,8GAAA,qBAAqB,OAAA;AACrB,4GAAA,mBAAmB,OAAA;AAQrB,qCAA6C;AAApC,2GAAA,gBAAgB,OAAA;AAEzB,iCAA2C;AAAlC,yGAAA,gBAAgB,OAAA;AAEzB,6BAOe;AANb,sGAAA,eAAe,OAAA;AACf,yGAAA,kBAAkB,OAAA;AAClB,gGAAA,SAAS,OAAA;AACT,wGAAA,iBAAiB,OAAA;AACjB,2GAAA,oBAAoB,OAAA;AACpB,mGAAA,YAAY,OAAA;AAGd,mDAO0B;AANxB,2HAAA,yBAAyB,OAAA;AACzB,iHAAA,eAAe,OAAA;AACf,0HAAA,wBAAwB,OAAA;AACxB,kHAAA,gBAAgB,OAAA;AAChB,8GAAA,YAAY,OAAA;AACZ,qHAAA,mBAAmB,OAAA;AAGrB,uDAM4B;AAL1B,2HAAA,uBAAuB,OAAA;AACvB,0HAAA,sBAAsB,OAAA;AACtB,uHAAA,mBAAmB,OAAA;AACnB,sHAAA,kBAAkB,OAAA;AAClB,yHAAA,qBAAqB,OAAA;AAGvB,mCAA+F;AAAtF,+GAAA,qBAAqB,OAAA;AAAE,gHAAA,sBAAsB,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAC5E,mCAAgD;AAAvC,8GAAA,oBAAoB,OAAA;AAC7B,iCAOiB;AANf,yGAAA,gBAAgB,OAAA;AAChB,2GAAA,kBAAkB,OAAA;AAClB,8GAAA,qBAAqB,OAAA;AACrB,0GAAA,iBAAiB,OAAA;AACjB,qHAAA,4BAA4B,OAAA;AAC5B,oHAAA,2BAA2B,OAAA"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { MemoryYaml } from './schema';
|
|
2
|
+
/**
|
|
3
|
+
* Derive the minimal set of root-relative directories a scan needs to walk to see every Memory
|
|
4
|
+
* document declared by `memoryYaml`'s types (spec-011: path-pattern predictability, not a full-repo
|
|
5
|
+
* walk). A directory already covered by another (shorter) directory in the set is dropped, so the
|
|
6
|
+
* result never contains redundant, nested roots.
|
|
7
|
+
*/
|
|
8
|
+
export declare function computeMemoryContentRoots(memoryYaml: MemoryYaml): string[];
|
|
9
|
+
/**
|
|
10
|
+
* List every Memory document under `root`, as root-relative POSIX paths, sorted lexicographically
|
|
11
|
+
* (REQ-SYS-07 — deterministic, no unordered iteration). Scans only the directories
|
|
12
|
+
* {@link computeMemoryContentRoots} derives from `memoryYaml`, never the whole project tree.
|
|
13
|
+
*/
|
|
14
|
+
export declare function listMemoryDocumentPaths(root: string, memoryYaml: MemoryYaml): string[];
|
|
15
|
+
/** A Memory document's parsed frontmatter (loose — no Zod schema validation, see module doc) + body. */
|
|
16
|
+
export interface MemoryDocumentSummary {
|
|
17
|
+
readonly path: string;
|
|
18
|
+
readonly frontmatter: Record<string, unknown>;
|
|
19
|
+
readonly body: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read one Memory document and split it into its parsed frontmatter and body text, without running
|
|
23
|
+
* it through any type's Zod schema — `memory search`/`history` must handle documents of every type
|
|
24
|
+
* and any (even structurally imperfect) state, so this is a read, never a validation.
|
|
25
|
+
*/
|
|
26
|
+
export declare function loadMemoryDocumentSummary(root: string, relativePath: string): MemoryDocumentSummary;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve a single Memory document by its `id` frontmatter value alone — REQ-PERF-04 /
|
|
29
|
+
* task-009-mcp-resource-fetch-latency's Acceptance Criteria, which name a `wingfoil://memory/{id}`
|
|
30
|
+
* benchmark fetch. This is NOT spec-004-mcp-surface-contract §2.1's Resource addressing: spec-004's
|
|
31
|
+
* actual scheme is `wingfoil://memory/{type}` (collection listing) and `wingfoil://memory/{type}/{id}`
|
|
32
|
+
* (single document) — there is no bare, single-segment `wingfoil://memory/{id}` form there, and this
|
|
33
|
+
* `{id}` segment would collide with spec-004's `{type}` segment. task-011-mcp-resources-read-only has
|
|
34
|
+
* since replaced the `wingfoil://memory/{id}` *Resource* this primitive originally backed with the
|
|
35
|
+
* conformant `wingfoil://memory/{type}/{id}` form (see {@link findMemoryDocumentByTypeAndId}) — this
|
|
36
|
+
* bare-id primitive itself is left in place (still covered by its own `test/memory/query.test.ts`
|
|
37
|
+
* unit tests and REQ-PERF-04's ported benchmark) as a generic, type-agnostic lookup; nothing in
|
|
38
|
+
* `src/mcp` calls it anymore.
|
|
39
|
+
*
|
|
40
|
+
* A linear scan over every document {@link listMemoryDocumentPaths} returns, in its
|
|
41
|
+
* already-deterministic sorted order, stopping at the first document whose frontmatter `id` matches
|
|
42
|
+
* *exactly* (never a substring — that remains `searchMemoryDocuments`'/task-021's keyword-search
|
|
43
|
+
* surface, not this primitive's). Returns `undefined` — never throws — when no document matches;
|
|
44
|
+
* turning that into a protocol-level "resource not found" failure is the MCP Resource adapter's job
|
|
45
|
+
* (spec-004 §2.2's general unresolvable-URI contract), not this primitive's.
|
|
46
|
+
*/
|
|
47
|
+
export declare function findMemoryDocumentById(root: string, memoryYaml: MemoryYaml, id: string): MemoryDocumentSummary | undefined;
|
|
48
|
+
/** A Memory document's frontmatter-only summary — spec-004 §2.1's collection-listing shape
|
|
49
|
+
* (id, title, status, tags), deliberately omitting body content to keep listing calls cheap. */
|
|
50
|
+
export interface MemoryDocumentFrontmatterSummary {
|
|
51
|
+
readonly path: string;
|
|
52
|
+
readonly id?: string;
|
|
53
|
+
readonly title?: string;
|
|
54
|
+
readonly status?: string;
|
|
55
|
+
readonly tags: readonly string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* List every Memory document whose frontmatter `type:` field equals `type` (a `memory.yaml` `types:`
|
|
59
|
+
* key), as frontmatter-only summaries — spec-004 §2.1's `wingfoil://memory/{type}` collection
|
|
60
|
+
* addressing (task-011-mcp-resources-read-only, REQ-INT-01). Sorted by `id` (falling back to `path`
|
|
61
|
+
* when a document has no `id`) ascending (REQ-SYS-07 — deterministic, no unordered iteration).
|
|
62
|
+
*
|
|
63
|
+
* Membership is decided by each document's own frontmatter `type:` field, not by which directory it
|
|
64
|
+
* lives in: several types' `path` patterns collapse to the *same* static directory prefix (e.g.
|
|
65
|
+
* `release`/`release-line` both resolve to `docs/04_memory/planning`; `task`'s own pattern collapses
|
|
66
|
+
* all the way to `docs/04_memory` itself — see {@link computeMemoryContentRoots}'s doc comment), so a
|
|
67
|
+
* directory-only filter would wrongly fold sibling types' documents into this type's collection.
|
|
68
|
+
*/
|
|
69
|
+
export declare function listMemoryDocumentsByType(root: string, memoryYaml: MemoryYaml, type: string): MemoryDocumentFrontmatterSummary[];
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a single Memory document by (`type`, `id`) — spec-004 §2.1's `wingfoil://memory/{type}/{id}`
|
|
72
|
+
* single-document addressing (task-011-mcp-resources-read-only, REQ-INT-01), the conformant
|
|
73
|
+
* replacement for task-009's bare-`{id}` `findMemoryDocumentById` Resource usage. Both `type` and `id`
|
|
74
|
+
* must match a document's own frontmatter — same directory-collision reasoning as
|
|
75
|
+
* {@link listMemoryDocumentsByType} — so this never returns a document of a *different* type merely
|
|
76
|
+
* because that type's path pattern happens to also resolve under the same directory. Returns
|
|
77
|
+
* `undefined` — never throws — when nothing matches; surfacing that as a protocol-level "resource not
|
|
78
|
+
* found" failure is the MCP Resource adapter's job (spec-004 §2.2), not this primitive's.
|
|
79
|
+
*/
|
|
80
|
+
export declare function findMemoryDocumentByTypeAndId(root: string, memoryYaml: MemoryYaml, type: string, id: string): MemoryDocumentSummary | undefined;
|
|
81
|
+
/** Optional filters/refinements for {@link searchMemoryDocuments}. */
|
|
82
|
+
export interface MemorySearchOptions {
|
|
83
|
+
/** Only include documents whose `tags:` frontmatter contains this exact tag. */
|
|
84
|
+
readonly tag?: string;
|
|
85
|
+
/**
|
|
86
|
+
* Opt back into archived documents (`status: deprecated` or `superseded` — `ARCHIVED_STATUSES`,
|
|
87
|
+
* ratified by `dl-028-archived-states-excluded-from-context`) appearing in the result.
|
|
88
|
+
* REQ-STATE-06 excludes them by default — "default … results" in the Fit Criterion. Set this only
|
|
89
|
+
* for an explicit, intentional request to see archived documents (e.g. an `--status deprecated` or
|
|
90
|
+
* `--status superseded` narrow); never as the default for a general keyword/tag search.
|
|
91
|
+
* Defaults to `false`.
|
|
92
|
+
*/
|
|
93
|
+
readonly includeArchived?: boolean;
|
|
94
|
+
}
|
|
95
|
+
/** One ranked search result — enough for a future CLI/MCP surface to render without re-reading the file. */
|
|
96
|
+
export interface MemorySearchMatch {
|
|
97
|
+
readonly path: string;
|
|
98
|
+
readonly id?: string;
|
|
99
|
+
readonly title?: string;
|
|
100
|
+
readonly tags: readonly string[];
|
|
101
|
+
readonly status?: string;
|
|
102
|
+
/** The document's frontmatter `type:` field (spec-010-memory-frontmatter-schema base field) —
|
|
103
|
+
* projected here (task-021-implement-memory-search) alongside `status`/`tags` so `memorySearch`'s
|
|
104
|
+
* `--type` filter can narrow an already-ranked result without a second file read per match. */
|
|
105
|
+
readonly type?: string;
|
|
106
|
+
/** Query matched the title, id, or a tag (P1.12: ranks above a body-only match). */
|
|
107
|
+
readonly metadataMatch: boolean;
|
|
108
|
+
/** Query matched somewhere in the document body. */
|
|
109
|
+
readonly bodyMatch: boolean;
|
|
110
|
+
}
|
|
111
|
+
/** `E_EMPTY_SEARCH_QUERY` field-level code (spec-009-validation-strategy §3) for a rejected empty
|
|
112
|
+
* or whitespace-only `wingfoil memory search` query. */
|
|
113
|
+
export declare const E_EMPTY_SEARCH_QUERY = "E_EMPTY_SEARCH_QUERY";
|
|
114
|
+
/**
|
|
115
|
+
* Reject an empty or whitespace-only search query (P1.12 BDD Scenario "Error - empty query string":
|
|
116
|
+
* "no search is performed" and exit code 2, message "empty search query"). Mirrors
|
|
117
|
+
* `resolveTransitionTarget`'s `ValidationError.semantic` pattern (`./state-machine.ts`) so the shared
|
|
118
|
+
* exit-code mapping (spec-009 §3) surfaces this as exit 2 without a bespoke error path; task-021's
|
|
119
|
+
* `wingfoil memory search` CLI/MCP surface calls this on the user-supplied query string before it
|
|
120
|
+
* ever reaches {@link searchMemoryDocuments}.
|
|
121
|
+
*
|
|
122
|
+
* Deliberately a separate guard, not a change to `searchMemoryDocuments`'s own signature/behavior:
|
|
123
|
+
* `searchMemoryDocuments(root, memoryYaml, '', { tag })` remains a legitimate "browse by tag alone,
|
|
124
|
+
* no keyword" call (task-008's own characterization test) — the empty-query rejection is this task's
|
|
125
|
+
* (P1.12's) algorithm-level validation concern, applied at the point a *user-facing* query string is
|
|
126
|
+
* about to be searched, not baked into the lower-level scan primitive that also serves tag-only
|
|
127
|
+
* listing.
|
|
128
|
+
*/
|
|
129
|
+
export declare function validateSearchQuery(query: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* Deterministic keyword/frontmatter search over every Memory document `memoryYaml` declares
|
|
132
|
+
* (P1.5/P1.12): case-insensitive substring matching against title/id/tags (metadata) and body text,
|
|
133
|
+
* optionally narrowed to one exact `tag`. A query that matches nothing returns `[]` — a successful,
|
|
134
|
+
* empty result, never a thrown error (that "no documents matched" outcome is a CLI/MCP-surface
|
|
135
|
+
* concern, task-021's, not this primitive's).
|
|
136
|
+
*
|
|
137
|
+
* Ordering is a total, deterministic order (REQ-SYS-07): metadata matches before body-only matches,
|
|
138
|
+
* then by `id` (falling back to `path` when a document has no `id`) ascending — so calling this
|
|
139
|
+
* twice against unchanged state always returns the exact same array.
|
|
140
|
+
*
|
|
141
|
+
* **REQ-STATE-06:** a document whose frontmatter `status` is archived — `deprecated` or `superseded`
|
|
142
|
+
* (`isArchivedStatus`, `dl-028`) — is excluded by default, so it never appears in these "default
|
|
143
|
+
* `memory search` results", matching the Fit Criterion verbatim, while the file itself is untouched on
|
|
144
|
+
* disk and in git history (`memory deprecate`, P1.9, never deletes it; `superseded` is reached by an
|
|
145
|
+
* ordinary `approve`). Pass `options.includeArchived: true` for the one legitimate exception: an
|
|
146
|
+
* explicit, intentional request to see archived documents too. `draft` documents are NOT excluded
|
|
147
|
+
* here — see this module's header for why the search set and the context set differ.
|
|
148
|
+
*/
|
|
149
|
+
export declare function searchMemoryDocuments(root: string, memoryYaml: MemoryYaml, query: string, options?: MemorySearchOptions): MemorySearchMatch[];
|
|
150
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/memory/query.ts"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkB3C;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAQ1E;AAuBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE,CAMtF;AAED,wGAAwG;AACxG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,qBAAqB,CAYnG;AAUD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,MAAM,GACT,qBAAqB,GAAG,SAAS,CAMnC;AAED;gGACgG;AAChG,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,GACX,gCAAgC,EAAE,CAkBpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,qBAAqB,GAAG,SAAS,CAMnC;AAED,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACpC;AAED,4GAA4G;AAC5G,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;mGAE+F;IAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,oFAAoF;IACpF,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;wDACwD;AACxD,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMvD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,iBAAiB,EAAE,CAqCrB"}
|