memnant 0.2.0 → 1.0.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/README.md +10 -66
- package/dist/ast/parser.d.ts +80 -0
- package/dist/ast/parser.d.ts.map +1 -0
- package/dist/ast/parser.js +319 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/cli/archive.d.ts.map +1 -1
- package/dist/cli/archive.js +16 -13
- package/dist/cli/archive.js.map +1 -1
- package/dist/cli/ask.d.ts.map +1 -1
- package/dist/cli/ask.js +18 -14
- package/dist/cli/ask.js.map +1 -1
- package/dist/cli/check-copy.d.ts.map +1 -1
- package/dist/cli/check-copy.js +10 -8
- package/dist/cli/check-copy.js.map +1 -1
- package/dist/cli/check-design.d.ts.map +1 -1
- package/dist/cli/check-design.js +10 -8
- package/dist/cli/check-design.js.map +1 -1
- package/dist/cli/costs.d.ts +6 -0
- package/dist/cli/costs.d.ts.map +1 -0
- package/dist/cli/costs.js +104 -0
- package/dist/cli/costs.js.map +1 -0
- package/dist/cli/default-action.d.ts.map +1 -1
- package/dist/cli/default-action.js +15 -8
- package/dist/cli/default-action.js.map +1 -1
- package/dist/cli/eval-persona.d.ts +9 -0
- package/dist/cli/eval-persona.d.ts.map +1 -0
- package/dist/cli/eval-persona.js +99 -0
- package/dist/cli/eval-persona.js.map +1 -0
- package/dist/cli/export.d.ts.map +1 -1
- package/dist/cli/export.js +59 -21
- package/dist/cli/export.js.map +1 -1
- package/dist/cli/federated-search.d.ts +6 -0
- package/dist/cli/federated-search.d.ts.map +1 -0
- package/dist/cli/federated-search.js +57 -0
- package/dist/cli/federated-search.js.map +1 -0
- package/dist/cli/graph.d.ts.map +1 -1
- package/dist/cli/graph.js +31 -20
- package/dist/cli/graph.js.map +1 -1
- package/dist/cli/health.d.ts.map +1 -1
- package/dist/cli/health.js +11 -9
- package/dist/cli/health.js.map +1 -1
- package/dist/cli/import.d.ts.map +1 -1
- package/dist/cli/import.js +55 -40
- package/dist/cli/import.js.map +1 -1
- package/dist/cli/index.js +18 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ingest.d.ts +21 -0
- package/dist/cli/ingest.d.ts.map +1 -0
- package/dist/cli/ingest.js +177 -0
- package/dist/cli/ingest.js.map +1 -0
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +70 -14
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/instructions.d.ts.map +1 -1
- package/dist/cli/instructions.js +10 -10
- package/dist/cli/instructions.js.map +1 -1
- package/dist/cli/lint.d.ts.map +1 -1
- package/dist/cli/lint.js +39 -13
- package/dist/cli/lint.js.map +1 -1
- package/dist/cli/log.d.ts.map +1 -1
- package/dist/cli/log.js +54 -30
- package/dist/cli/log.js.map +1 -1
- package/dist/cli/patterns.d.ts.map +1 -1
- package/dist/cli/patterns.js +10 -8
- package/dist/cli/patterns.js.map +1 -1
- package/dist/cli/projects.d.ts +6 -0
- package/dist/cli/projects.d.ts.map +1 -0
- package/dist/cli/projects.js +89 -0
- package/dist/cli/projects.js.map +1 -0
- package/dist/cli/promote.d.ts.map +1 -1
- package/dist/cli/promote.js +13 -11
- package/dist/cli/promote.js.map +1 -1
- package/dist/cli/recall.d.ts.map +1 -1
- package/dist/cli/recall.js +28 -21
- package/dist/cli/recall.js.map +1 -1
- package/dist/cli/reindex.d.ts +6 -0
- package/dist/cli/reindex.d.ts.map +1 -0
- package/dist/cli/reindex.js +57 -0
- package/dist/cli/reindex.js.map +1 -0
- package/dist/cli/replay.d.ts +9 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +71 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/retract.d.ts.map +1 -1
- package/dist/cli/retract.js +16 -13
- package/dist/cli/retract.js.map +1 -1
- package/dist/cli/serve.d.ts.map +1 -1
- package/dist/cli/serve.js +1 -1
- package/dist/cli/serve.js.map +1 -1
- package/dist/cli/session.d.ts.map +1 -1
- package/dist/cli/session.js +26 -20
- package/dist/cli/session.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +32 -4
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/snapshot.d.ts.map +1 -1
- package/dist/cli/snapshot.js +13 -11
- package/dist/cli/snapshot.js.map +1 -1
- package/dist/cli/spec-diff.d.ts +6 -0
- package/dist/cli/spec-diff.d.ts.map +1 -0
- package/dist/cli/spec-diff.js +77 -0
- package/dist/cli/spec-diff.js.map +1 -0
- package/dist/cli/specs.d.ts.map +1 -1
- package/dist/cli/specs.js +9 -8
- package/dist/cli/specs.js.map +1 -1
- package/dist/cli/stats.d.ts.map +1 -1
- package/dist/cli/stats.js +33 -11
- package/dist/cli/stats.js.map +1 -1
- package/dist/cli/status.d.ts.map +1 -1
- package/dist/cli/status.js +18 -11
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/synthesise.d.ts.map +1 -1
- package/dist/cli/synthesise.js +10 -8
- package/dist/cli/synthesise.js.map +1 -1
- package/dist/cli/telegram.d.ts.map +1 -1
- package/dist/cli/telegram.js +1 -1
- package/dist/cli/telegram.js.map +1 -1
- package/dist/cli/test-persona.d.ts.map +1 -1
- package/dist/cli/test-persona.js +12 -10
- package/dist/cli/test-persona.js.map +1 -1
- package/dist/cli/webhook.d.ts +9 -0
- package/dist/cli/webhook.d.ts.map +1 -0
- package/dist/cli/webhook.js +106 -0
- package/dist/cli/webhook.js.map +1 -0
- package/dist/config/load.d.ts +22 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +70 -0
- package/dist/config/load.js.map +1 -0
- package/dist/context/compile.d.ts +15 -3
- package/dist/context/compile.d.ts.map +1 -1
- package/dist/context/compile.js +155 -14
- package/dist/context/compile.js.map +1 -1
- package/dist/context/file-context.js +1 -1
- package/dist/context/file-context.js.map +1 -1
- package/dist/context/replay.d.ts +19 -0
- package/dist/context/replay.d.ts.map +1 -0
- package/dist/context/replay.js +47 -0
- package/dist/context/replay.js.map +1 -0
- package/dist/context/spec-diff.d.ts +29 -0
- package/dist/context/spec-diff.d.ts.map +1 -0
- package/dist/context/spec-diff.js +108 -0
- package/dist/context/spec-diff.js.map +1 -0
- package/dist/governor/persona-eval.d.ts +51 -0
- package/dist/governor/persona-eval.d.ts.map +1 -0
- package/dist/governor/persona-eval.js +182 -0
- package/dist/governor/persona-eval.js.map +1 -0
- package/dist/governor/plugins.d.ts +34 -0
- package/dist/governor/plugins.d.ts.map +1 -0
- package/dist/governor/plugins.js +68 -0
- package/dist/governor/plugins.js.map +1 -0
- package/dist/graph/relationships.js +1 -1
- package/dist/graph/relationships.js.map +1 -1
- package/dist/ledger/database.d.ts.map +1 -1
- package/dist/ledger/database.js +25 -2
- package/dist/ledger/database.js.map +1 -1
- package/dist/ledger/migrations.d.ts.map +1 -1
- package/dist/ledger/migrations.js +54 -0
- package/dist/ledger/migrations.js.map +1 -1
- package/dist/ledger/records.d.ts +4 -0
- package/dist/ledger/records.d.ts.map +1 -1
- package/dist/ledger/records.js +11 -3
- package/dist/ledger/records.js.map +1 -1
- package/dist/ledger/stats.d.ts +9 -0
- package/dist/ledger/stats.d.ts.map +1 -1
- package/dist/ledger/stats.js +21 -0
- package/dist/ledger/stats.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +337 -13
- package/dist/mcp/server.js.map +1 -1
- package/dist/orchestrator/context.js +2 -2
- package/dist/orchestrator/context.js.map +1 -1
- package/dist/orchestrator/costs.d.ts +31 -0
- package/dist/orchestrator/costs.d.ts.map +1 -0
- package/dist/orchestrator/costs.js +60 -0
- package/dist/orchestrator/costs.js.map +1 -0
- package/dist/orchestrator/event-formatter.d.ts +17 -0
- package/dist/orchestrator/event-formatter.d.ts.map +1 -0
- package/dist/orchestrator/event-formatter.js +53 -0
- package/dist/orchestrator/event-formatter.js.map +1 -0
- package/dist/registry/federated-search.d.ts +34 -0
- package/dist/registry/federated-search.d.ts.map +1 -0
- package/dist/registry/federated-search.js +83 -0
- package/dist/registry/federated-search.js.map +1 -0
- package/dist/registry/registry.d.ts +50 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +83 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/relevance/access.d.ts.map +1 -1
- package/dist/relevance/access.js +30 -12
- package/dist/relevance/access.js.map +1 -1
- package/dist/relevance/scoring.d.ts +2 -0
- package/dist/relevance/scoring.d.ts.map +1 -1
- package/dist/relevance/scoring.js +3 -2
- package/dist/relevance/scoring.js.map +1 -1
- package/dist/relevance/search.d.ts +2 -1
- package/dist/relevance/search.d.ts.map +1 -1
- package/dist/relevance/search.js +16 -5
- package/dist/relevance/search.js.map +1 -1
- package/dist/synthesis/patterns.js +1 -1
- package/dist/synthesis/patterns.js.map +1 -1
- package/dist/synthesis/synthesise.js +1 -1
- package/dist/synthesis/synthesise.js.map +1 -1
- package/dist/telegram/bot.d.ts.map +1 -1
- package/dist/telegram/bot.js +3 -7
- package/dist/telegram/bot.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/vector/embedding-utils.d.ts +10 -0
- package/dist/vector/embedding-utils.d.ts.map +1 -0
- package/dist/vector/embedding-utils.js +15 -0
- package/dist/vector/embedding-utils.js.map +1 -0
- package/dist/vector/embeddings.d.ts +1 -2
- package/dist/vector/embeddings.d.ts.map +1 -1
- package/dist/vector/embeddings.js +2 -7
- package/dist/vector/embeddings.js.map +1 -1
- package/dist/vector/reindex.d.ts +22 -0
- package/dist/vector/reindex.d.ts.map +1 -0
- package/dist/vector/reindex.js +32 -0
- package/dist/vector/reindex.js.map +1 -0
- package/dist/vector/search.d.ts +1 -0
- package/dist/vector/search.d.ts.map +1 -1
- package/dist/vector/search.js +3 -2
- package/dist/vector/search.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -4,21 +4,19 @@ Shared project memory for any MCP client.
|
|
|
4
4
|
|
|
5
5
|
## The problem
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
But the real problem is bigger. Platform memory is locked to one client and one project. Claude Code's memory doesn't work in Cursor. Cursor's memory doesn't work in Windsurf. And none of them carry the framework fix you solved in project A into project B.
|
|
7
|
+
Platform memory is locked to one client and one project. Claude Code's memory doesn't work in Cursor. Cursor's memory doesn't work in Windsurf. None of them carry the framework fix you solved in project A into project B.
|
|
10
8
|
|
|
11
9
|
memnant is locked to nothing. It works across any MCP-compatible agent, any project, any session. Your engineering knowledge compounds everywhere you build.
|
|
12
10
|
|
|
13
11
|
## How it works
|
|
14
12
|
|
|
15
|
-
**It remembers.** The agent silently logs decisions, framework fixes, and rejections during conversation. Every record gets a vector embedding for semantic search.
|
|
13
|
+
**It remembers.** The agent silently logs decisions, framework fixes, and rejections during conversation. Every record gets a vector embedding for semantic search.
|
|
16
14
|
|
|
17
|
-
**It compiles.** Sessions start and close automatically. At session start, memnant compiles context: last session's log, open TODOs, relevant decisions,
|
|
15
|
+
**It compiles.** Sessions start and close automatically. At session start, memnant compiles context: last session's log, open TODOs, relevant decisions, staleness warnings. Three weeks away? One command. Full context.
|
|
18
16
|
|
|
19
|
-
**It flags.** Codebase snapshots track file hashes. When a file changes
|
|
17
|
+
**It flags.** Codebase snapshots track file hashes and AST structure. When a file changes, memnant scores whether the change actually affects related decisions — not a binary flag, a confidence score.
|
|
20
18
|
|
|
21
|
-
**It travels.** Export framework fixes from one project, import them into the next. The gotcha you solved once never bites you again — across any project, any codebase.
|
|
19
|
+
**It travels.** Export framework fixes from one project, import them into the next. The gotcha you solved once never bites you again — across any project, any codebase.
|
|
22
20
|
|
|
23
21
|
## Quick start
|
|
24
22
|
|
|
@@ -59,7 +57,7 @@ TODO: wire dashboard filters to snapshot queries
|
|
|
59
57
|
── Relevant Decisions (3) ──
|
|
60
58
|
[a3f2] Chose snapshot-first analytics — live adds 200ms
|
|
61
59
|
[b7e1] Dashboard uses server components, no client state
|
|
62
|
-
[c4d9] [stale] Analytics schema — analytics.ts changed Feb 24
|
|
60
|
+
[c4d9] [stale 0.72] Analytics schema — analytics.ts changed Feb 24
|
|
63
61
|
|
|
64
62
|
── Framework Fixes (1) ──
|
|
65
63
|
[d2a8] Next.js 15: useSearchParams needs Suspense boundary
|
|
@@ -88,59 +86,13 @@ Platform memory is siloed by project. Your experience isn't.
|
|
|
88
86
|
|
|
89
87
|
**Search.** Local vector embeddings via all-MiniLM-L6-v2. Semantic search on CPU. No API calls. Works on a plane.
|
|
90
88
|
|
|
91
|
-
**Integration.** MCP server over stdio.
|
|
89
|
+
**Integration.** MCP server over stdio. Plugs into Claude Code, Cursor, or any MCP-compatible agent.
|
|
92
90
|
|
|
93
91
|
**Config.** `memnant.yaml` at your project root. Version-controlled. No dashboard, no account, no login.
|
|
94
92
|
|
|
95
93
|
**Export.** Markdown or JSON. Every record, every decision, every session log. Your history is never locked in.
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
The core loop is four things: remember, compile, flag, travel. As records accumulate, memnant has depth that earns its way in.
|
|
100
|
-
|
|
101
|
-
| Capability | What it does | Requires |
|
|
102
|
-
|---|---|---|
|
|
103
|
-
| **Connection Graph** | Records auto-link, supersede, and contradict at write time | Records in the ledger |
|
|
104
|
-
| **Relevance Scoring** | 4-signal composite: similarity, recency, freshness, frequency | Configurable in memnant.yaml |
|
|
105
|
-
| **Synthesis** | Cross-record questions with citations | `ANTHROPIC_API_KEY` |
|
|
106
|
-
| **Spec Governor** | Copy audits, design checks, persona tests, CI lint | Spec docs in `docs/` |
|
|
107
|
-
| **Predictive Context** | File-aware search, branch detection, co-occurrence patterns | Builds over sessions |
|
|
108
|
-
| **Model Routing** | Route tasks to Haiku/Sonnet/Opus with tier-appropriate context | API keys |
|
|
109
|
-
| **Health Monitoring** | Staleness rate, contradictions, spec drift, status levels | — |
|
|
110
|
-
| **Continuous Governance** | Pre-commit hooks, override tracking, governance feedback | Spec docs + git hooks |
|
|
111
|
-
| **Telegram** | Triage from your phone | `MEMRANT_TELEGRAM_TOKEN` |
|
|
112
|
-
|
|
113
|
-
Every capability is independent. Use what you need. Ignore the rest.
|
|
114
|
-
|
|
115
|
-
## Core commands
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
npx memnant # auto-detect: init, start session, or status
|
|
119
|
-
memnant log --type decision # write a record
|
|
120
|
-
memnant recall "auth approach" # semantic search
|
|
121
|
-
memnant session start # compile context
|
|
122
|
-
memnant session close # capture what happened
|
|
123
|
-
memnant snapshot # codebase snapshot for staleness
|
|
124
|
-
memnant export # full ledger to markdown/JSON
|
|
125
|
-
memnant lint # validate against spec docs
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
25 commands total. Full reference in the [docs](docs/).
|
|
129
|
-
|
|
130
|
-
## MCP tools
|
|
131
|
-
|
|
132
|
-
| Tool | Purpose |
|
|
133
|
-
|---|---|
|
|
134
|
-
| `memnant_recall` | Semantic search over the ledger |
|
|
135
|
-
| `memnant_log` | Write a record (auto-starts session) |
|
|
136
|
-
| `memnant_session_context` | Compiled context for session start |
|
|
137
|
-
| `memnant_session_close` | Close session with summary |
|
|
138
|
-
| `memnant_status` | Project status |
|
|
139
|
-
| `memnant_check_copy` | Copy audit against spec |
|
|
140
|
-
| `memnant_check_design` | Design system validation |
|
|
141
|
-
| `memnant_synthesise` | Cross-record questions with citations |
|
|
142
|
-
| `memnant_context_for_file` | Records relevant to a specific file |
|
|
143
|
-
| `memnant_project_brief` | Dynamic 500-token project summary |
|
|
95
|
+
**Runtime.** Node.js >= 20. All dependencies bundled (SQLite WASM, local embeddings, MCP SDK). Optional `ANTHROPIC_API_KEY` for synthesis and model routing — core functionality works fully offline.
|
|
144
96
|
|
|
145
97
|
## What it's not
|
|
146
98
|
|
|
@@ -154,17 +106,9 @@ memnant lint # validate against spec docs
|
|
|
154
106
|
|
|
155
107
|
## Who it's for
|
|
156
108
|
|
|
157
|
-
Solo builders shipping multiple products with AI agents. You work in sessions — days or weeks apart. You juggle 3-4 projects. You
|
|
158
|
-
|
|
159
|
-
The test: three weeks away from a project, `npx memnant` gives full context in under two minutes. Switch to a new project, `memnant import` brings your framework fixes with you.
|
|
160
|
-
|
|
161
|
-
## Dependencies
|
|
162
|
-
|
|
163
|
-
**Required:** Node.js >= 20
|
|
164
|
-
|
|
165
|
-
**Bundled:** SQLite (WASM, no native deps), local embeddings, MCP SDK
|
|
109
|
+
Solo builders shipping multiple products with AI agents. You work in sessions — days or weeks apart. You juggle 3-4 projects. You need your engineering knowledge to compound across everything you build, not reset every time you switch projects.
|
|
166
110
|
|
|
167
|
-
|
|
111
|
+
The test: three weeks away from a project, `npx memnant` gives full context in under two minutes.
|
|
168
112
|
|
|
169
113
|
## License
|
|
170
114
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant — AST-anchored structural hashing via web-tree-sitter.
|
|
3
|
+
*
|
|
4
|
+
* Parses source files using WASM-compiled Tree-sitter grammars, locates
|
|
5
|
+
* named symbols (functions, classes, methods), and computes structural
|
|
6
|
+
* hashes that are immune to formatting and comment changes.
|
|
7
|
+
*
|
|
8
|
+
* Grammars are lazy-loaded: downloaded from CDN on first use for a given
|
|
9
|
+
* language, then cached at ~/.memnant/grammars/ for offline reuse.
|
|
10
|
+
*/
|
|
11
|
+
import type TSParser from 'web-tree-sitter';
|
|
12
|
+
type SyntaxNode = TSParser.Node;
|
|
13
|
+
/**
|
|
14
|
+
* Detect language from file extension.
|
|
15
|
+
* Returns null for unsupported languages.
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectLanguage(filePath: string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Get the list of supported file extensions.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getSupportedExtensions(): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Parse source code and return the syntax tree's root node.
|
|
24
|
+
* Returns null if parsing fails or language is unsupported.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseSource(source: string, language: string): Promise<SyntaxNode | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Find a named symbol (function, class, method, etc.) in the AST.
|
|
29
|
+
* Walks the tree looking for declaration nodes whose name matches.
|
|
30
|
+
* Returns the declaration node, or null if not found.
|
|
31
|
+
*/
|
|
32
|
+
export declare function findSymbolNode(rootNode: SyntaxNode, symbolName: string): SyntaxNode | null;
|
|
33
|
+
/**
|
|
34
|
+
* Compute a structural hash for an AST node.
|
|
35
|
+
*
|
|
36
|
+
* Traverses the node, ignoring comments and whitespace.
|
|
37
|
+
* For leaf nodes, appends type:text. For structural nodes, appends type.
|
|
38
|
+
* The resulting string is SHA256-hashed.
|
|
39
|
+
*
|
|
40
|
+
* This hash is stable across:
|
|
41
|
+
* - Formatting changes (indentation, blank lines)
|
|
42
|
+
* - Comment changes (added, removed, modified)
|
|
43
|
+
* - Whitespace changes
|
|
44
|
+
*
|
|
45
|
+
* This hash changes when:
|
|
46
|
+
* - Variable names change
|
|
47
|
+
* - Logic changes (new statements, different operators)
|
|
48
|
+
* - Type annotations change
|
|
49
|
+
* - Parameters change
|
|
50
|
+
*/
|
|
51
|
+
export declare function computeStructuralHash(node: SyntaxNode): string;
|
|
52
|
+
/**
|
|
53
|
+
* High-level API: compute the AST structural hash for a symbol in a file.
|
|
54
|
+
*
|
|
55
|
+
* @param filePath - Absolute path to the source file
|
|
56
|
+
* @param symbolName - Name of the symbol to hash, or 'global' for the entire file
|
|
57
|
+
* @returns The structural hash, or null if parsing/lookup fails
|
|
58
|
+
*/
|
|
59
|
+
export declare function computeAstHash(filePath: string, symbolName: string): Promise<string | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Compute AST hash from source code string (useful for testing).
|
|
62
|
+
*
|
|
63
|
+
* @param source - Source code string
|
|
64
|
+
* @param symbolName - Symbol to hash, or 'global' for entire file
|
|
65
|
+
* @param language - Tree-sitter language name
|
|
66
|
+
* @returns The structural hash, or null if parsing/lookup fails
|
|
67
|
+
*/
|
|
68
|
+
export declare function computeAstHashFromSource(source: string, symbolName: string, language: string): Promise<string | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Compute AST hash for a symbol in a file, resolving relative paths
|
|
71
|
+
* against the project root.
|
|
72
|
+
*
|
|
73
|
+
* @param targetFile - Relative file path (from project root)
|
|
74
|
+
* @param symbolName - Symbol to hash, or 'global' for entire file
|
|
75
|
+
* @param projectRoot - Project root directory
|
|
76
|
+
* @returns The structural hash, or null if unavailable
|
|
77
|
+
*/
|
|
78
|
+
export declare function computeAstHashForRecord(targetFile: string, symbolName: string, projectRoot: string): Promise<string | null>;
|
|
79
|
+
export {};
|
|
80
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/ast/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAK5C,KAAK,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;AAgGhC;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG9D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAEjD;AAuDD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAU5B;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,UAAU,EACpB,UAAU,EAAE,MAAM,GACjB,UAAU,GAAG,IAAI,CAmBnB;AA8BD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAuB9D;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGxB"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant — AST-anchored structural hashing via web-tree-sitter.
|
|
3
|
+
*
|
|
4
|
+
* Parses source files using WASM-compiled Tree-sitter grammars, locates
|
|
5
|
+
* named symbols (functions, classes, methods), and computes structural
|
|
6
|
+
* hashes that are immune to formatting and comment changes.
|
|
7
|
+
*
|
|
8
|
+
* Grammars are lazy-loaded: downloaded from CDN on first use for a given
|
|
9
|
+
* language, then cached at ~/.memnant/grammars/ for offline reuse.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from 'crypto';
|
|
12
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
13
|
+
import { join, extname } from 'path';
|
|
14
|
+
import { homedir } from 'os';
|
|
15
|
+
/** Supported languages and their file extensions */
|
|
16
|
+
const EXTENSION_TO_LANGUAGE = {
|
|
17
|
+
'.ts': 'typescript',
|
|
18
|
+
'.tsx': 'tsx',
|
|
19
|
+
'.js': 'javascript',
|
|
20
|
+
'.jsx': 'javascript',
|
|
21
|
+
'.mjs': 'javascript',
|
|
22
|
+
'.cjs': 'javascript',
|
|
23
|
+
'.py': 'python',
|
|
24
|
+
'.go': 'go',
|
|
25
|
+
'.rs': 'rust',
|
|
26
|
+
'.java': 'java',
|
|
27
|
+
'.c': 'c',
|
|
28
|
+
'.h': 'c',
|
|
29
|
+
'.cpp': 'cpp',
|
|
30
|
+
'.hpp': 'cpp',
|
|
31
|
+
'.cc': 'cpp',
|
|
32
|
+
'.rb': 'ruby',
|
|
33
|
+
};
|
|
34
|
+
/** CDN base URL for tree-sitter WASM grammar files */
|
|
35
|
+
const GRAMMAR_CDN_BASE = 'https://cdn.jsdelivr.net/npm/tree-sitter-wasms@0.0.11/out';
|
|
36
|
+
/** Local grammar cache directory */
|
|
37
|
+
function getGrammarCacheDir() {
|
|
38
|
+
return join(homedir(), '.memnant', 'grammars');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Node types that represent named declarations across languages.
|
|
42
|
+
* Used by findSymbolNode to locate symbols in the AST.
|
|
43
|
+
*/
|
|
44
|
+
const DECLARATION_NODE_TYPES = [
|
|
45
|
+
// JavaScript / TypeScript
|
|
46
|
+
'function_declaration',
|
|
47
|
+
'class_declaration',
|
|
48
|
+
'method_definition',
|
|
49
|
+
'variable_declarator',
|
|
50
|
+
'interface_declaration',
|
|
51
|
+
'type_alias_declaration',
|
|
52
|
+
'enum_declaration',
|
|
53
|
+
// Python
|
|
54
|
+
'function_definition',
|
|
55
|
+
'class_definition',
|
|
56
|
+
// Go
|
|
57
|
+
'function_declaration',
|
|
58
|
+
'method_declaration',
|
|
59
|
+
'type_declaration',
|
|
60
|
+
'type_spec',
|
|
61
|
+
// Rust
|
|
62
|
+
'function_item',
|
|
63
|
+
'struct_item',
|
|
64
|
+
'enum_item',
|
|
65
|
+
'impl_item',
|
|
66
|
+
'trait_item',
|
|
67
|
+
// Java
|
|
68
|
+
'class_declaration',
|
|
69
|
+
'method_declaration',
|
|
70
|
+
'interface_declaration',
|
|
71
|
+
// Ruby
|
|
72
|
+
'method',
|
|
73
|
+
'class',
|
|
74
|
+
'module',
|
|
75
|
+
];
|
|
76
|
+
// Comment node types across languages
|
|
77
|
+
const COMMENT_NODE_TYPES = new Set([
|
|
78
|
+
'comment',
|
|
79
|
+
'line_comment',
|
|
80
|
+
'block_comment',
|
|
81
|
+
'doc_comment',
|
|
82
|
+
]);
|
|
83
|
+
// Lazy-loaded state
|
|
84
|
+
let ParserCtor = null;
|
|
85
|
+
let LanguageCtor = null;
|
|
86
|
+
let parserInstance = null;
|
|
87
|
+
const loadedLanguages = new Map();
|
|
88
|
+
/**
|
|
89
|
+
* Initialise the Tree-sitter WASM parser. Lazy-loaded on first use.
|
|
90
|
+
*/
|
|
91
|
+
async function initParser() {
|
|
92
|
+
if (parserInstance)
|
|
93
|
+
return parserInstance;
|
|
94
|
+
const mod = await import('web-tree-sitter');
|
|
95
|
+
const P = mod.Parser;
|
|
96
|
+
await P.init();
|
|
97
|
+
ParserCtor = P;
|
|
98
|
+
LanguageCtor = mod.Language;
|
|
99
|
+
parserInstance = new P();
|
|
100
|
+
return parserInstance;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Detect language from file extension.
|
|
104
|
+
* Returns null for unsupported languages.
|
|
105
|
+
*/
|
|
106
|
+
export function detectLanguage(filePath) {
|
|
107
|
+
const ext = extname(filePath).toLowerCase();
|
|
108
|
+
return EXTENSION_TO_LANGUAGE[ext] ?? null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get the list of supported file extensions.
|
|
112
|
+
*/
|
|
113
|
+
export function getSupportedExtensions() {
|
|
114
|
+
return Object.keys(EXTENSION_TO_LANGUAGE);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Download a WASM grammar file from CDN to the local cache.
|
|
118
|
+
* Returns the local file path, or null if download failed.
|
|
119
|
+
*/
|
|
120
|
+
async function downloadGrammar(language) {
|
|
121
|
+
const cacheDir = getGrammarCacheDir();
|
|
122
|
+
const localPath = join(cacheDir, `tree-sitter-${language}.wasm`);
|
|
123
|
+
if (existsSync(localPath))
|
|
124
|
+
return localPath;
|
|
125
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
126
|
+
const url = `${GRAMMAR_CDN_BASE}/tree-sitter-${language}.wasm`;
|
|
127
|
+
try {
|
|
128
|
+
const response = await fetch(url);
|
|
129
|
+
if (!response.ok) {
|
|
130
|
+
process.stderr.write(`[memnant] Failed to download grammar for ${language}: HTTP ${response.status}\n`);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
134
|
+
writeFileSync(localPath, buffer);
|
|
135
|
+
process.stderr.write(`[memnant] Downloaded grammar: tree-sitter-${language}.wasm (${Math.round(buffer.length / 1024)} KB)\n`);
|
|
136
|
+
return localPath;
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
process.stderr.write(`[memnant] Grammar download failed for ${language}: ${err}\n`);
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Load a language grammar, downloading it if necessary.
|
|
145
|
+
* Returns null if the language is unsupported or download fails.
|
|
146
|
+
*/
|
|
147
|
+
async function ensureLanguage(language) {
|
|
148
|
+
if (loadedLanguages.has(language))
|
|
149
|
+
return loadedLanguages.get(language);
|
|
150
|
+
if (!LanguageCtor)
|
|
151
|
+
await initParser();
|
|
152
|
+
const grammarPath = await downloadGrammar(language);
|
|
153
|
+
if (!grammarPath)
|
|
154
|
+
return null;
|
|
155
|
+
try {
|
|
156
|
+
const lang = await LanguageCtor.load(grammarPath);
|
|
157
|
+
loadedLanguages.set(language, lang);
|
|
158
|
+
return lang;
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
process.stderr.write(`[memnant] Failed to load grammar for ${language}: ${err}\n`);
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Parse source code and return the syntax tree's root node.
|
|
167
|
+
* Returns null if parsing fails or language is unsupported.
|
|
168
|
+
*/
|
|
169
|
+
export async function parseSource(source, language) {
|
|
170
|
+
const parser = await initParser();
|
|
171
|
+
const lang = await ensureLanguage(language);
|
|
172
|
+
if (!lang)
|
|
173
|
+
return null;
|
|
174
|
+
parser.setLanguage(lang);
|
|
175
|
+
const tree = parser.parse(source);
|
|
176
|
+
if (!tree)
|
|
177
|
+
return null;
|
|
178
|
+
return tree.rootNode;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Find a named symbol (function, class, method, etc.) in the AST.
|
|
182
|
+
* Walks the tree looking for declaration nodes whose name matches.
|
|
183
|
+
* Returns the declaration node, or null if not found.
|
|
184
|
+
*/
|
|
185
|
+
export function findSymbolNode(rootNode, symbolName) {
|
|
186
|
+
// BFS through the tree to find the symbol
|
|
187
|
+
const queue = [rootNode];
|
|
188
|
+
while (queue.length > 0) {
|
|
189
|
+
const node = queue.shift();
|
|
190
|
+
if (isDeclarationWithName(node, symbolName)) {
|
|
191
|
+
return node;
|
|
192
|
+
}
|
|
193
|
+
// Add children to queue
|
|
194
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
195
|
+
const child = node.child(i);
|
|
196
|
+
if (child)
|
|
197
|
+
queue.push(child);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if a node is a named declaration that matches the given symbol name.
|
|
204
|
+
*/
|
|
205
|
+
function isDeclarationWithName(node, symbolName) {
|
|
206
|
+
const nodeType = node.type;
|
|
207
|
+
// Check if this is a declaration type
|
|
208
|
+
if (!DECLARATION_NODE_TYPES.includes(nodeType))
|
|
209
|
+
return false;
|
|
210
|
+
// Try to find the name via the 'name' field
|
|
211
|
+
const nameNode = node.childForFieldName('name');
|
|
212
|
+
if (nameNode && nameNode.text === symbolName)
|
|
213
|
+
return true;
|
|
214
|
+
// For variable_declarator, the name is in the 'name' field
|
|
215
|
+
if (nodeType === 'variable_declarator') {
|
|
216
|
+
const varName = node.childForFieldName('name');
|
|
217
|
+
if (varName && varName.text === symbolName)
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
// For type_spec in Go, the name is in the 'name' field
|
|
221
|
+
if (nodeType === 'type_spec') {
|
|
222
|
+
const typeName = node.childForFieldName('name');
|
|
223
|
+
if (typeName && typeName.text === symbolName)
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Compute a structural hash for an AST node.
|
|
230
|
+
*
|
|
231
|
+
* Traverses the node, ignoring comments and whitespace.
|
|
232
|
+
* For leaf nodes, appends type:text. For structural nodes, appends type.
|
|
233
|
+
* The resulting string is SHA256-hashed.
|
|
234
|
+
*
|
|
235
|
+
* This hash is stable across:
|
|
236
|
+
* - Formatting changes (indentation, blank lines)
|
|
237
|
+
* - Comment changes (added, removed, modified)
|
|
238
|
+
* - Whitespace changes
|
|
239
|
+
*
|
|
240
|
+
* This hash changes when:
|
|
241
|
+
* - Variable names change
|
|
242
|
+
* - Logic changes (new statements, different operators)
|
|
243
|
+
* - Type annotations change
|
|
244
|
+
* - Parameters change
|
|
245
|
+
*/
|
|
246
|
+
export function computeStructuralHash(node) {
|
|
247
|
+
let hashString = '';
|
|
248
|
+
const traverse = (n) => {
|
|
249
|
+
// Skip comments entirely
|
|
250
|
+
if (COMMENT_NODE_TYPES.has(n.type) || n.isExtra)
|
|
251
|
+
return;
|
|
252
|
+
if (n.childCount === 0) {
|
|
253
|
+
// Leaf node — include type and text
|
|
254
|
+
hashString += `${n.type}:${n.text}|`;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// Structural node — include type only
|
|
258
|
+
hashString += `${n.type}|`;
|
|
259
|
+
for (let i = 0; i < n.childCount; i++) {
|
|
260
|
+
const child = n.child(i);
|
|
261
|
+
if (child)
|
|
262
|
+
traverse(child);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
traverse(node);
|
|
267
|
+
return createHash('sha256').update(hashString).digest('hex');
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* High-level API: compute the AST structural hash for a symbol in a file.
|
|
271
|
+
*
|
|
272
|
+
* @param filePath - Absolute path to the source file
|
|
273
|
+
* @param symbolName - Name of the symbol to hash, or 'global' for the entire file
|
|
274
|
+
* @returns The structural hash, or null if parsing/lookup fails
|
|
275
|
+
*/
|
|
276
|
+
export async function computeAstHash(filePath, symbolName) {
|
|
277
|
+
if (!existsSync(filePath))
|
|
278
|
+
return null;
|
|
279
|
+
const ext = extname(filePath).toLowerCase();
|
|
280
|
+
const language = EXTENSION_TO_LANGUAGE[ext];
|
|
281
|
+
if (!language)
|
|
282
|
+
return null;
|
|
283
|
+
const source = readFileSync(filePath, 'utf-8');
|
|
284
|
+
return computeAstHashFromSource(source, symbolName, language);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Compute AST hash from source code string (useful for testing).
|
|
288
|
+
*
|
|
289
|
+
* @param source - Source code string
|
|
290
|
+
* @param symbolName - Symbol to hash, or 'global' for entire file
|
|
291
|
+
* @param language - Tree-sitter language name
|
|
292
|
+
* @returns The structural hash, or null if parsing/lookup fails
|
|
293
|
+
*/
|
|
294
|
+
export async function computeAstHashFromSource(source, symbolName, language) {
|
|
295
|
+
const rootNode = await parseSource(source, language);
|
|
296
|
+
if (!rootNode)
|
|
297
|
+
return null;
|
|
298
|
+
if (symbolName === 'global') {
|
|
299
|
+
return computeStructuralHash(rootNode);
|
|
300
|
+
}
|
|
301
|
+
const symbolNode = findSymbolNode(rootNode, symbolName);
|
|
302
|
+
if (!symbolNode)
|
|
303
|
+
return null;
|
|
304
|
+
return computeStructuralHash(symbolNode);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Compute AST hash for a symbol in a file, resolving relative paths
|
|
308
|
+
* against the project root.
|
|
309
|
+
*
|
|
310
|
+
* @param targetFile - Relative file path (from project root)
|
|
311
|
+
* @param symbolName - Symbol to hash, or 'global' for entire file
|
|
312
|
+
* @param projectRoot - Project root directory
|
|
313
|
+
* @returns The structural hash, or null if unavailable
|
|
314
|
+
*/
|
|
315
|
+
export async function computeAstHashForRecord(targetFile, symbolName, projectRoot) {
|
|
316
|
+
const absPath = join(projectRoot, targetFile);
|
|
317
|
+
return computeAstHash(absPath, symbolName);
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/ast/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/cli/archive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/cli/archive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqCpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoE7D"}
|
package/dist/cli/archive.js
CHANGED
|
@@ -4,19 +4,20 @@
|
|
|
4
4
|
* Archived records are excluded from recall, context compilation, and export.
|
|
5
5
|
* They are not deleted — they can be unarchived later.
|
|
6
6
|
*/
|
|
7
|
-
import { existsSync
|
|
7
|
+
import { existsSync } from 'fs';
|
|
8
8
|
import { join } from 'path';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function loadDb() {
|
|
9
|
+
async function loadDb() {
|
|
10
|
+
const { openDatabase } = await import('../ledger/database.js');
|
|
11
|
+
const { loadConfig, ConfigError } = await import('../config/load.js');
|
|
13
12
|
const cwd = process.cwd();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
let config;
|
|
14
|
+
try {
|
|
15
|
+
config = loadConfig(cwd);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error(err instanceof ConfigError ? err.message : String(err));
|
|
17
19
|
process.exit(1);
|
|
18
20
|
}
|
|
19
|
-
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
20
21
|
const dbPath = join(cwd, config.memory.db_path);
|
|
21
22
|
if (!existsSync(dbPath)) {
|
|
22
23
|
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
@@ -39,12 +40,13 @@ export function registerArchiveCommand(program) {
|
|
|
39
40
|
.option('--id <id>', 'Archive a single record')
|
|
40
41
|
.option('--superseded', 'Archive all superseded records')
|
|
41
42
|
.option('--stale-older-than <duration>', 'Archive stale records older than duration (e.g. 90d)')
|
|
42
|
-
.action((opts) => {
|
|
43
|
+
.action(async (opts) => {
|
|
44
|
+
const { archiveRecord, archiveSuperseded, archiveStaleOlderThan } = await import('../ledger/admin.js');
|
|
43
45
|
if (!opts.id && !opts.superseded && !opts.staleOlderThan) {
|
|
44
46
|
console.error('Specify at least one: --id <id>, --superseded, or --stale-older-than <duration>');
|
|
45
47
|
process.exit(1);
|
|
46
48
|
}
|
|
47
|
-
const db = loadDb();
|
|
49
|
+
const db = await loadDb();
|
|
48
50
|
try {
|
|
49
51
|
if (opts.id) {
|
|
50
52
|
archiveRecord(db, opts.id);
|
|
@@ -73,12 +75,13 @@ export function registerArchiveCommand(program) {
|
|
|
73
75
|
.description('Restore archived records')
|
|
74
76
|
.option('--id <id>', 'Unarchive a single record')
|
|
75
77
|
.option('--all', 'Unarchive all archived records')
|
|
76
|
-
.action((opts) => {
|
|
78
|
+
.action(async (opts) => {
|
|
79
|
+
const { unarchiveRecord, unarchiveAll } = await import('../ledger/admin.js');
|
|
77
80
|
if (!opts.id && !opts.all) {
|
|
78
81
|
console.error('Specify at least one: --id <id> or --all');
|
|
79
82
|
process.exit(1);
|
|
80
83
|
}
|
|
81
|
-
const db = loadDb();
|
|
84
|
+
const db = await loadDb();
|
|
82
85
|
try {
|
|
83
86
|
if (opts.id) {
|
|
84
87
|
unarchiveRecord(db, opts.id);
|
package/dist/cli/archive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/cli/archive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/cli/archive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,KAAK,UAAU,MAAM;IACnB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAC/D,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEtE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEhD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,MAAM,CAAC,OAAO,qCAAqC,CAAC,CAAC;QAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,qBAAqB,QAAQ,uDAAuD,CAAC,CAAC;QACpG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,WAAW,EAAE,yBAAyB,CAAC;SAC9C,MAAM,CAAC,cAAc,EAAE,gCAAgC,CAAC;SACxD,MAAM,CAAC,+BAA+B,EAAE,sDAAsD,CAAC;SAC/F,MAAM,CAAC,KAAK,EAAE,IAAoE,EAAE,EAAE;QACrF,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAEvG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,iFAAiF,CAAC,CAAC;YACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACZ,aAAa,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YACzD,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,wBAAwB,CAAC,CAAC;YACzD,CAAC;YACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBAChD,MAAM,KAAK,GAAG,qBAAqB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,+BAA+B,IAAI,QAAQ,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,0BAA0B,CAAC;SACvC,MAAM,CAAC,WAAW,EAAE,2BAA2B,CAAC;SAChD,MAAM,CAAC,OAAO,EAAE,gCAAgC,CAAC;SACjD,MAAM,CAAC,KAAK,EAAE,IAAoC,EAAE,EAAE;QACrD,MAAM,EAAE,eAAe,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE7E,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;gBACZ,eAAe,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,oCAAoC,CAAC,CAAC;YAC5F,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACb,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,aAAa,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/cli/ask.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/cli/ask.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/cli/ask.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiHzD"}
|