memnant 1.2.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -49
- package/dist/analytics/analytics.d.ts +36 -0
- package/dist/analytics/analytics.d.ts.map +1 -0
- package/dist/analytics/analytics.js +133 -0
- package/dist/analytics/analytics.js.map +1 -0
- package/dist/cli/analytics.d.ts +7 -0
- package/dist/cli/analytics.d.ts.map +1 -0
- package/dist/cli/analytics.js +59 -0
- package/dist/cli/analytics.js.map +1 -0
- package/dist/cli/export.d.ts.map +1 -1
- package/dist/cli/export.js +5 -2
- package/dist/cli/export.js.map +1 -1
- package/dist/cli/harvest.d.ts +7 -0
- package/dist/cli/harvest.d.ts.map +1 -0
- package/dist/cli/harvest.js +53 -0
- package/dist/cli/harvest.js.map +1 -0
- package/dist/cli/history.d.ts +7 -0
- package/dist/cli/history.d.ts.map +1 -0
- package/dist/cli/history.js +55 -0
- package/dist/cli/history.js.map +1 -0
- package/dist/cli/import.js +2 -2
- package/dist/cli/import.js.map +1 -1
- package/dist/cli/index.js +13 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/instructions.d.ts.map +1 -1
- package/dist/cli/instructions.js +13 -6
- package/dist/cli/instructions.js.map +1 -1
- package/dist/cli/observe.d.ts +8 -0
- package/dist/cli/observe.d.ts.map +1 -0
- package/dist/cli/observe.js +54 -0
- package/dist/cli/observe.js.map +1 -0
- package/dist/cli/promote.d.ts +6 -4
- package/dist/cli/promote.d.ts.map +1 -1
- package/dist/cli/promote.js +76 -60
- package/dist/cli/promote.js.map +1 -1
- package/dist/cli/recall.d.ts.map +1 -1
- package/dist/cli/recall.js +6 -2
- package/dist/cli/recall.js.map +1 -1
- package/dist/cli/synthesise.d.ts.map +1 -1
- package/dist/cli/synthesise.js +24 -1
- package/dist/cli/synthesise.js.map +1 -1
- package/dist/colony/colony.d.ts +9 -0
- package/dist/colony/colony.d.ts.map +1 -0
- package/dist/colony/colony.js +32 -0
- package/dist/colony/colony.js.map +1 -0
- package/dist/colony/promote.d.ts +15 -0
- package/dist/colony/promote.d.ts.map +1 -0
- package/dist/colony/promote.js +55 -0
- package/dist/colony/promote.js.map +1 -0
- package/dist/colony/search.d.ts +19 -0
- package/dist/colony/search.d.ts.map +1 -0
- package/dist/colony/search.js +38 -0
- package/dist/colony/search.js.map +1 -0
- package/dist/context/assumptions.d.ts +16 -0
- package/dist/context/assumptions.d.ts.map +1 -0
- package/dist/context/assumptions.js +40 -0
- package/dist/context/assumptions.js.map +1 -0
- package/dist/context/compile.d.ts +5 -0
- package/dist/context/compile.d.ts.map +1 -1
- package/dist/context/compile.js +35 -10
- package/dist/context/compile.js.map +1 -1
- package/dist/context/narrative.d.ts +22 -0
- package/dist/context/narrative.d.ts.map +1 -0
- package/dist/context/narrative.js +106 -0
- package/dist/context/narrative.js.map +1 -0
- package/dist/graph/history.d.ts +16 -0
- package/dist/graph/history.d.ts.map +1 -0
- package/dist/graph/history.js +46 -0
- package/dist/graph/history.js.map +1 -0
- package/dist/graph/queries.d.ts.map +1 -1
- package/dist/graph/queries.js +19 -2
- package/dist/graph/queries.js.map +1 -1
- package/dist/graph/relationships.d.ts +2 -1
- package/dist/graph/relationships.d.ts.map +1 -1
- package/dist/graph/relationships.js +1 -1
- package/dist/graph/relationships.js.map +1 -1
- package/dist/harvest/discover.d.ts +10 -0
- package/dist/harvest/discover.d.ts.map +1 -0
- package/dist/harvest/discover.js +40 -0
- package/dist/harvest/discover.js.map +1 -0
- package/dist/harvest/extract-llm.d.ts +12 -0
- package/dist/harvest/extract-llm.d.ts.map +1 -0
- package/dist/harvest/extract-llm.js +47 -0
- package/dist/harvest/extract-llm.js.map +1 -0
- package/dist/harvest/extract.d.ts +14 -0
- package/dist/harvest/extract.d.ts.map +1 -0
- package/dist/harvest/extract.js +77 -0
- package/dist/harvest/extract.js.map +1 -0
- package/dist/harvest/harvest.d.ts +17 -0
- package/dist/harvest/harvest.d.ts.map +1 -0
- package/dist/harvest/harvest.js +86 -0
- package/dist/harvest/harvest.js.map +1 -0
- package/dist/harvest/parser.d.ts +13 -0
- package/dist/harvest/parser.d.ts.map +1 -0
- package/dist/harvest/parser.js +40 -0
- package/dist/harvest/parser.js.map +1 -0
- package/dist/ledger/database.d.ts.map +1 -1
- package/dist/ledger/database.js +13 -6
- package/dist/ledger/database.js.map +1 -1
- package/dist/ledger/migrations.d.ts.map +1 -1
- package/dist/ledger/migrations.js +46 -0
- package/dist/ledger/migrations.js.map +1 -1
- package/dist/ledger/records.d.ts +2 -0
- package/dist/ledger/records.d.ts.map +1 -1
- package/dist/ledger/records.js +14 -2
- package/dist/ledger/records.js.map +1 -1
- package/dist/ledger/templates.d.ts +13 -0
- package/dist/ledger/templates.d.ts.map +1 -0
- package/dist/ledger/templates.js +32 -0
- package/dist/ledger/templates.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +377 -8
- package/dist/mcp/server.js.map +1 -1
- package/dist/observe/observe.d.ts +13 -0
- package/dist/observe/observe.d.ts.map +1 -0
- package/dist/observe/observe.js +45 -0
- package/dist/observe/observe.js.map +1 -0
- package/dist/orchestrator/providers.d.ts +6 -0
- package/dist/orchestrator/providers.d.ts.map +1 -1
- package/dist/orchestrator/providers.js +41 -1
- package/dist/orchestrator/providers.js.map +1 -1
- package/dist/orchestrator/router.d.ts +1 -1
- package/dist/orchestrator/router.d.ts.map +1 -1
- package/dist/orchestrator/router.js +3 -1
- package/dist/orchestrator/router.js.map +1 -1
- package/dist/patterns/cluster.d.ts +21 -0
- package/dist/patterns/cluster.d.ts.map +1 -0
- package/dist/patterns/cluster.js +91 -0
- package/dist/patterns/cluster.js.map +1 -0
- package/dist/patterns/detect.d.ts +12 -0
- package/dist/patterns/detect.d.ts.map +1 -0
- package/dist/patterns/detect.js +110 -0
- package/dist/patterns/detect.js.map +1 -0
- package/dist/patterns/profile.d.ts +8 -0
- package/dist/patterns/profile.d.ts.map +1 -0
- package/dist/patterns/profile.js +82 -0
- package/dist/patterns/profile.js.map +1 -0
- package/dist/patterns/summarize.d.ts +9 -0
- package/dist/patterns/summarize.d.ts.map +1 -0
- package/dist/patterns/summarize.js +49 -0
- package/dist/patterns/summarize.js.map +1 -0
- package/dist/relevance/review-pressure.d.ts +17 -0
- package/dist/relevance/review-pressure.d.ts.map +1 -0
- package/dist/relevance/review-pressure.js +34 -0
- package/dist/relevance/review-pressure.js.map +1 -0
- package/dist/relevance/scoring.d.ts +4 -1
- package/dist/relevance/scoring.d.ts.map +1 -1
- package/dist/relevance/scoring.js +1 -0
- package/dist/relevance/scoring.js.map +1 -1
- package/dist/relevance/search.d.ts.map +1 -1
- package/dist/relevance/search.js +3 -0
- package/dist/relevance/search.js.map +1 -1
- package/dist/snapshot/scanner.d.ts.map +1 -1
- package/dist/snapshot/scanner.js +16 -14
- package/dist/snapshot/scanner.js.map +1 -1
- package/dist/synthesis/synthesise.d.ts +3 -0
- package/dist/synthesis/synthesise.d.ts.map +1 -1
- package/dist/synthesis/synthesise.js +61 -14
- package/dist/synthesis/synthesise.js.map +1 -1
- package/dist/team/sync.d.ts +18 -0
- package/dist/team/sync.d.ts.map +1 -0
- package/dist/team/sync.js +96 -0
- package/dist/team/sync.js.map +1 -0
- package/dist/types.d.ts +18 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/vector/embeddings.d.ts.map +1 -1
- package/dist/vector/embeddings.js +31 -1
- package/dist/vector/embeddings.js.map +1 -1
- package/dist/vector/runtime-download.d.ts +12 -0
- package/dist/vector/runtime-download.d.ts.map +1 -0
- package/dist/vector/runtime-download.js +71 -0
- package/dist/vector/runtime-download.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,20 +1,29 @@
|
|
|
1
1
|
# memnant
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
It just remembers.
|
|
4
4
|
|
|
5
5
|
## The problem
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Context windows die. Conversations end. Three weeks later you're re-explaining the same decisions to the same agent. The framework fix you solved in week two? Gone. The product decision from last month? Not in the context window.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
You forget. Your agent forgets faster.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
memnant is the remnant that survives. A small persistent thing that crawls across your projects and carries what you decided from one place to the next.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
12
14
|
|
|
13
15
|
```bash
|
|
14
|
-
|
|
16
|
+
curl -fsSL memnant.com/install.sh | sh
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Windows:
|
|
20
|
+
```powershell
|
|
21
|
+
irm memnant.com/install.ps1 | iex
|
|
15
22
|
```
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
Or via npm: `npx memnant`
|
|
25
|
+
|
|
26
|
+
First run creates your config, ledger, and auto-registers the MCP server for your agent. After that, `memnant` starts a session with compiled context.
|
|
18
27
|
|
|
19
28
|
That's it. The agent logs decisions silently as you work. Start your next session with full context.
|
|
20
29
|
|
|
@@ -26,8 +35,8 @@ If auto-registration doesn't work for your setup, add memnant to your agent's MC
|
|
|
26
35
|
{
|
|
27
36
|
"mcpServers": {
|
|
28
37
|
"memnant": {
|
|
29
|
-
"command": "
|
|
30
|
-
"args": ["
|
|
38
|
+
"command": "memnant",
|
|
39
|
+
"args": ["serve"]
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
}
|
|
@@ -36,63 +45,73 @@ If auto-registration doesn't work for your setup, add memnant to your agent's MC
|
|
|
36
45
|
## What a session looks like
|
|
37
46
|
|
|
38
47
|
```
|
|
39
|
-
$
|
|
48
|
+
$ memnant
|
|
40
49
|
|
|
41
50
|
▪ memnant · session start
|
|
42
|
-
|
|
51
|
+
21 days since last session.
|
|
43
52
|
|
|
44
|
-
──
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
── Briefing ──
|
|
54
|
+
You shipped the analytics pipeline three weeks ago. The analytics
|
|
55
|
+
schema decision is stale — analytics.ts changed since. Dashboard
|
|
56
|
+
filters are still on the TODO.
|
|
48
57
|
|
|
49
58
|
── Relevant Decisions (3) ──
|
|
50
59
|
[a3f2] Chose snapshot-first analytics — live adds 200ms
|
|
51
60
|
[b7e1] Dashboard uses server components, no client state
|
|
52
|
-
[c4d9] [stale 0.72] Analytics schema — analytics.ts changed
|
|
61
|
+
[c4d9] [stale 0.72] Analytics schema — analytics.ts changed
|
|
53
62
|
|
|
54
|
-
── Framework Fixes
|
|
63
|
+
── Framework Fixes ──
|
|
55
64
|
[d2a8] Next.js 15: useSearchParams needs Suspense boundary
|
|
65
|
+
[colony] React setState batching in concurrent mode
|
|
56
66
|
|
|
57
67
|
Session e8f3 started. Good building.
|
|
58
68
|
```
|
|
59
69
|
|
|
60
|
-
Three weeks away from a project. One command. Full context
|
|
70
|
+
Three weeks away from a project. One command. Full context. Colony fixes from your other projects included.
|
|
61
71
|
|
|
62
72
|
## How it works
|
|
63
73
|
|
|
64
|
-
**It remembers.** The agent silently
|
|
74
|
+
**It remembers.** The agent logs silently as you work. Decisions, framework fixes, rejections, product calls. Every record gets a vector embedding for semantic search. You don't do anything.
|
|
65
75
|
|
|
66
|
-
**It compiles.**
|
|
76
|
+
**It compiles.** Next session starts with what matters. Last session's summary, open TODOs, relevant decisions, staleness warnings. Not a raw dump — the relevant subset, with what's changed since you were last here.
|
|
67
77
|
|
|
68
|
-
**It
|
|
78
|
+
**It knows.** It knows when knowledge goes stale. When a file changes, memnant scores whether the change actually affects related decisions. Semantic confidence, not a binary flag. A renamed variable doesn't invalidate an architecture decision.
|
|
69
79
|
|
|
70
|
-
**It travels.**
|
|
80
|
+
**It travels.** Knowledge crosses projects automatically. Framework fixes and rejected approaches promote themselves to a machine-local colony at `~/.memnant/colony.db`. The gotcha you solved in one codebase is already waiting in the next — no export needed.
|
|
71
81
|
|
|
72
|
-
##
|
|
82
|
+
## The colony
|
|
73
83
|
|
|
74
|
-
|
|
75
|
-
# In project A — you solved a Next.js gotcha
|
|
76
|
-
memnant export --type framework_fix --format portable
|
|
84
|
+
Framework fixes aren't project-specific. When you solve a Next.js gotcha in one project, memnant auto-promotes it to your colony. Next time you start a session in any project, colony results appear marked `[colony]` — ranked below project results at the same similarity.
|
|
77
85
|
|
|
78
|
-
# In project B — it's already there before you hit it
|
|
79
|
-
memnant import .../framework-fixes.portable.json
|
|
80
|
-
# → Imported 3 framework fixes (1 skipped as duplicate)
|
|
81
86
|
```
|
|
87
|
+
── Framework Fixes ──
|
|
88
|
+
[d2a8] Next.js 15: useSearchParams needs Suspense boundary
|
|
89
|
+
[colony] React setState batching in concurrent mode
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Rejected approaches promote too — so you never retry something that already failed.
|
|
93
|
+
|
|
94
|
+
Deduplication by embedding similarity (>0.92). Manual promotion for anything else: `memnant promote <record-id>`.
|
|
82
95
|
|
|
83
|
-
|
|
96
|
+
## Narrative briefings
|
|
84
97
|
|
|
85
|
-
|
|
98
|
+
Session context rendered as a story, not a database dump. Delta-focused — only what changed since you were last here. Empty sections omitted. The briefing shrinks when things are quiet.
|
|
86
99
|
|
|
87
|
-
|
|
100
|
+
When an API key is available, memnant composes a conversational narrative. Offline, it falls back to a smart template. Either way, you get caught up in seconds.
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
## More than memory
|
|
90
103
|
|
|
91
|
-
**
|
|
104
|
+
**Connection graph.** Records link themselves by semantic similarity. Supersession chains track when new decisions replace old ones. Contradictions are flagged automatically.
|
|
92
105
|
|
|
93
|
-
**Relevance decay.** Old
|
|
106
|
+
**Relevance decay.** Old knowledge fades. Frequently accessed records stay prominent. The ledger self-organises around what's actually useful.
|
|
94
107
|
|
|
95
|
-
**
|
|
108
|
+
**Synthesis.** Ask questions that span multiple records. "How did our auth approach evolve?" returns a composed answer with citations back to source.
|
|
109
|
+
|
|
110
|
+
**Governance.** Spec enforcement in pre-commit hooks. Override tracking — when overrides pile up, memnant suggests the spec might need updating.
|
|
111
|
+
|
|
112
|
+
**Predictive context.** File-aware. Branch-aware. Working patterns from past sessions boost future relevance. Surfaces the right records before you ask.
|
|
113
|
+
|
|
114
|
+
**Colony.** Machine-local cross-project ledger. Framework fixes and rejected approaches auto-promote. Search across all your projects at once.
|
|
96
115
|
|
|
97
116
|
## Under the hood
|
|
98
117
|
|
|
@@ -106,23 +125,11 @@ Framework fixes aren't project-specific. The caching bug you solved in your SaaS
|
|
|
106
125
|
|
|
107
126
|
**Export.** Markdown or JSON. Every record, every decision, every session log. Your history is never locked in.
|
|
108
127
|
|
|
109
|
-
**Runtime.** Node.js
|
|
110
|
-
|
|
111
|
-
## What it's not
|
|
112
|
-
|
|
113
|
-
**Not agent memory.** Agent memory stores preferences from conversations. memnant stores typed decisions with staleness tracking. It's a ledger, not a scratchpad.
|
|
114
|
-
|
|
115
|
-
**Not a context window.** Context windows are session-scoped. memnant is cross-session. It selects the right subset and injects it.
|
|
116
|
-
|
|
117
|
-
**Not CLAUDE.md.** Static instructions tell agents how to behave. memnant is dynamic institutional knowledge — what was decided, when, why, and whether it's still valid.
|
|
118
|
-
|
|
119
|
-
**Not chat history.** Chat history is what was said. memnant is what was decided.
|
|
128
|
+
**Runtime.** Standalone binary — no Node.js required. `curl memnant.com/install.sh | sh` and you're done. ONNX WASM and model files download automatically on first use (~30MB). Also available via `npx memnant` if you prefer npm. Optional `ANTHROPIC_API_KEY` for synthesis — core functionality works fully offline.
|
|
120
129
|
|
|
121
130
|
## Who it's for
|
|
122
131
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
If you only use one agent on one project, the built-in memory covers most of the same ground. memnant's edge is when your knowledge needs to work across multiple tools, multiple projects, or both.
|
|
132
|
+
You work in sessions. Days or weeks apart. You juggle multiple projects that share patterns. You want what you learned yesterday to be there tomorrow — across every tool, every codebase, every session.
|
|
126
133
|
|
|
127
134
|
## License
|
|
128
135
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ledger analytics — knowledge health metrics.
|
|
3
|
+
*
|
|
4
|
+
* Computes decision velocity, knowledge area distribution,
|
|
5
|
+
* coverage gaps, assumption load, and review pressure.
|
|
6
|
+
*/
|
|
7
|
+
export interface WeeklyCount {
|
|
8
|
+
week: string;
|
|
9
|
+
count: number;
|
|
10
|
+
}
|
|
11
|
+
export interface TagCount {
|
|
12
|
+
tag: string;
|
|
13
|
+
count: number;
|
|
14
|
+
}
|
|
15
|
+
export interface CoverageGaps {
|
|
16
|
+
forgottenDecisions: number;
|
|
17
|
+
forgottenFiles: string[];
|
|
18
|
+
undocumentedAreas: number;
|
|
19
|
+
undocumentedFiles: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface AnalyticsReport {
|
|
22
|
+
velocity: {
|
|
23
|
+
weeks: WeeklyCount[];
|
|
24
|
+
total: number;
|
|
25
|
+
trend: 'increasing' | 'decreasing' | 'stable';
|
|
26
|
+
trendPercent: number;
|
|
27
|
+
};
|
|
28
|
+
knowledgeAreas: TagCount[];
|
|
29
|
+
coverageGaps: CoverageGaps;
|
|
30
|
+
assumptionCount: number;
|
|
31
|
+
topAssumption: string | null;
|
|
32
|
+
topAssumptionDecisions: number;
|
|
33
|
+
reviewPressureCount: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function computeAnalytics(db: any, projectId: string): Promise<AnalyticsReport>;
|
|
36
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/analytics/analytics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE;QACR,KAAK,EAAE,WAAW,EAAE,CAAC;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;QAC9C,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,cAAc,EAAE,QAAQ,EAAE,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAUD,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,GAAG,EACP,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAiJ1B"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ledger analytics — knowledge health metrics.
|
|
3
|
+
*
|
|
4
|
+
* Computes decision velocity, knowledge area distribution,
|
|
5
|
+
* coverage gaps, assumption load, and review pressure.
|
|
6
|
+
*/
|
|
7
|
+
function getISOWeek(date) {
|
|
8
|
+
const d = new Date(date.getTime());
|
|
9
|
+
d.setHours(0, 0, 0, 0);
|
|
10
|
+
d.setDate(d.getDate() + 3 - ((d.getDay() + 6) % 7));
|
|
11
|
+
const week1 = new Date(d.getFullYear(), 0, 4);
|
|
12
|
+
return 1 + Math.round(((d.getTime() - week1.getTime()) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7);
|
|
13
|
+
}
|
|
14
|
+
export async function computeAnalytics(db, projectId) {
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const eightWeeksAgo = new Date(now.getTime() - 8 * 7 * 24 * 60 * 60 * 1000);
|
|
17
|
+
// Decision velocity — records per week (last 8 weeks)
|
|
18
|
+
const recentRecords = db.all(`SELECT created_at FROM record
|
|
19
|
+
WHERE project_id = ? AND retracted_at IS NULL AND archived_at IS NULL
|
|
20
|
+
AND created_at >= ?
|
|
21
|
+
ORDER BY created_at ASC`, [projectId, eightWeeksAgo.toISOString()]);
|
|
22
|
+
// Build week buckets
|
|
23
|
+
const weekCounts = new Map();
|
|
24
|
+
for (let i = 0; i < 8; i++) {
|
|
25
|
+
const weekDate = new Date(now.getTime() - (7 - i) * 7 * 24 * 60 * 60 * 1000);
|
|
26
|
+
const weekNum = getISOWeek(weekDate);
|
|
27
|
+
const label = `W${String(weekNum).padStart(2, '0')}`;
|
|
28
|
+
weekCounts.set(label, 0);
|
|
29
|
+
}
|
|
30
|
+
for (const row of recentRecords) {
|
|
31
|
+
const d = new Date(row.created_at);
|
|
32
|
+
const weekNum = getISOWeek(d);
|
|
33
|
+
const label = `W${String(weekNum).padStart(2, '0')}`;
|
|
34
|
+
if (weekCounts.has(label)) {
|
|
35
|
+
weekCounts.set(label, (weekCounts.get(label) ?? 0) + 1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const weeks = Array.from(weekCounts.entries()).map(([week, count]) => ({ week, count }));
|
|
39
|
+
const total = recentRecords.length;
|
|
40
|
+
// Trend: compare first 4 weeks vs last 4 weeks
|
|
41
|
+
const weekValues = weeks.map(w => w.count);
|
|
42
|
+
const firstHalf = weekValues.slice(0, 4).reduce((a, b) => a + b, 0);
|
|
43
|
+
const secondHalf = weekValues.slice(4).reduce((a, b) => a + b, 0);
|
|
44
|
+
let trend = 'stable';
|
|
45
|
+
let trendPercent = 0;
|
|
46
|
+
if (firstHalf > 0) {
|
|
47
|
+
trendPercent = Math.round(((secondHalf - firstHalf) / firstHalf) * 100);
|
|
48
|
+
if (trendPercent > 10)
|
|
49
|
+
trend = 'increasing';
|
|
50
|
+
else if (trendPercent < -10)
|
|
51
|
+
trend = 'decreasing';
|
|
52
|
+
}
|
|
53
|
+
else if (secondHalf > 0) {
|
|
54
|
+
trend = 'increasing';
|
|
55
|
+
trendPercent = 100;
|
|
56
|
+
}
|
|
57
|
+
// Knowledge area distribution — tag frequency
|
|
58
|
+
const allTags = db.all(`SELECT tags FROM record
|
|
59
|
+
WHERE project_id = ? AND retracted_at IS NULL AND archived_at IS NULL`, [projectId]);
|
|
60
|
+
const tagMap = new Map();
|
|
61
|
+
for (const row of allTags) {
|
|
62
|
+
try {
|
|
63
|
+
const tags = JSON.parse(row.tags);
|
|
64
|
+
for (const tag of tags) {
|
|
65
|
+
if (tag)
|
|
66
|
+
tagMap.set(tag, (tagMap.get(tag) ?? 0) + 1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch { /* skip bad tags */ }
|
|
70
|
+
}
|
|
71
|
+
const knowledgeAreas = Array.from(tagMap.entries())
|
|
72
|
+
.map(([tag, count]) => ({ tag, count }))
|
|
73
|
+
.sort((a, b) => b.count - a.count)
|
|
74
|
+
.slice(0, 10);
|
|
75
|
+
// Coverage gaps
|
|
76
|
+
const sixtyDaysAgo = new Date(now.getTime() - 60 * 24 * 60 * 60 * 1000).toISOString();
|
|
77
|
+
// Forgotten decisions: anchored to files, no access in 60 days
|
|
78
|
+
const forgottenRows = db.all(`SELECT DISTINCT r.target_file FROM record r
|
|
79
|
+
WHERE r.project_id = ? AND r.target_file IS NOT NULL
|
|
80
|
+
AND r.type = 'decision'
|
|
81
|
+
AND r.retracted_at IS NULL AND r.archived_at IS NULL
|
|
82
|
+
AND NOT EXISTS (
|
|
83
|
+
SELECT 1 FROM record_access ra WHERE ra.record_id = r.id AND ra.accessed_at >= ?
|
|
84
|
+
)`, [projectId, sixtyDaysAgo]);
|
|
85
|
+
const forgottenFiles = forgottenRows.map((r) => r.target_file);
|
|
86
|
+
// Undocumented areas: files in recent record_access context that look like file paths but have no anchored records
|
|
87
|
+
const accessedFiles = db.all(`SELECT DISTINCT ra.context as file FROM record_access ra
|
|
88
|
+
WHERE ra.accessed_at >= ?
|
|
89
|
+
AND ra.context LIKE '%.%'`, [sixtyDaysAgo]);
|
|
90
|
+
const anchoredFiles = new Set(db.all(`SELECT DISTINCT target_file FROM record
|
|
91
|
+
WHERE project_id = ? AND target_file IS NOT NULL
|
|
92
|
+
AND retracted_at IS NULL AND archived_at IS NULL`, [projectId]).map((r) => r.target_file));
|
|
93
|
+
const undocumentedFiles = accessedFiles
|
|
94
|
+
.map((r) => r.file)
|
|
95
|
+
.filter((f) => !anchoredFiles.has(f));
|
|
96
|
+
// Assumption load (reuse M13)
|
|
97
|
+
let assumptionCount = 0;
|
|
98
|
+
let topAssumption = null;
|
|
99
|
+
let topAssumptionDecisions = 0;
|
|
100
|
+
try {
|
|
101
|
+
const { getActiveAssumptions } = await import('../context/assumptions.js');
|
|
102
|
+
const assumptions = getActiveAssumptions(db, projectId);
|
|
103
|
+
assumptionCount = assumptions.length;
|
|
104
|
+
if (assumptions.length > 0) {
|
|
105
|
+
topAssumption = assumptions[0].assumption;
|
|
106
|
+
topAssumptionDecisions = assumptions[0].decisions.length;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch { /* best-effort */ }
|
|
110
|
+
// Review pressure (reuse M13)
|
|
111
|
+
let reviewPressureCount = 0;
|
|
112
|
+
try {
|
|
113
|
+
const { findDecisionsDueForReview } = await import('../relevance/review-pressure.js');
|
|
114
|
+
const candidates = findDecisionsDueForReview(db, projectId, 90);
|
|
115
|
+
reviewPressureCount = candidates.length;
|
|
116
|
+
}
|
|
117
|
+
catch { /* best-effort */ }
|
|
118
|
+
return {
|
|
119
|
+
velocity: { weeks, total, trend, trendPercent },
|
|
120
|
+
knowledgeAreas,
|
|
121
|
+
coverageGaps: {
|
|
122
|
+
forgottenDecisions: forgottenFiles.length,
|
|
123
|
+
forgottenFiles,
|
|
124
|
+
undocumentedAreas: undocumentedFiles.length,
|
|
125
|
+
undocumentedFiles,
|
|
126
|
+
},
|
|
127
|
+
assumptionCount,
|
|
128
|
+
topAssumption,
|
|
129
|
+
topAssumptionDecisions,
|
|
130
|
+
reviewPressureCount,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/analytics/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/cli/analytics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwD/D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI handler for `memnant analytics`.
|
|
3
|
+
* Shows ledger health metrics.
|
|
4
|
+
*/
|
|
5
|
+
import { openDatabase } from '../ledger/database.js';
|
|
6
|
+
import { loadConfig, findProjectRoot } from '../config/load.js';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
import { computeAnalytics } from '../analytics/analytics.js';
|
|
9
|
+
export function registerAnalyticsCommand(program) {
|
|
10
|
+
program
|
|
11
|
+
.command('analytics')
|
|
12
|
+
.description('Show ledger health: decision velocity, knowledge areas, coverage gaps')
|
|
13
|
+
.option('--json', 'Output as JSON')
|
|
14
|
+
.action(async (opts) => {
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
const projectRoot = findProjectRoot(cwd);
|
|
17
|
+
if (!projectRoot) {
|
|
18
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
const config = loadConfig(projectRoot);
|
|
22
|
+
const dbPath = join(projectRoot, config.memory.db_path);
|
|
23
|
+
const db = openDatabase(dbPath);
|
|
24
|
+
const report = await computeAnalytics(db, config.project.id);
|
|
25
|
+
db.close();
|
|
26
|
+
if (opts.json) {
|
|
27
|
+
console.log(JSON.stringify(report, null, 2));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Velocity
|
|
31
|
+
console.log('Decision Velocity (last 8 weeks):');
|
|
32
|
+
const maxCount = Math.max(...report.velocity.weeks.map(w => w.count), 1);
|
|
33
|
+
const line = report.velocity.weeks.map(w => {
|
|
34
|
+
const bar = '█'.repeat(Math.round((w.count / maxCount) * 8));
|
|
35
|
+
return ` ${w.week}: ${bar || '·'} ${w.count}`;
|
|
36
|
+
}).join('\n');
|
|
37
|
+
console.log(line);
|
|
38
|
+
const sign = report.velocity.trendPercent >= 0 ? '+' : '';
|
|
39
|
+
console.log(` Trend: ${report.velocity.trend} (${sign}${report.velocity.trendPercent}%)\n`);
|
|
40
|
+
// Knowledge areas
|
|
41
|
+
if (report.knowledgeAreas.length > 0) {
|
|
42
|
+
console.log('Knowledge Areas:');
|
|
43
|
+
console.log(' ' + report.knowledgeAreas.map(a => `${a.tag} (${a.count})`).join(' '));
|
|
44
|
+
console.log();
|
|
45
|
+
}
|
|
46
|
+
// Coverage gaps
|
|
47
|
+
console.log('Coverage Gaps:');
|
|
48
|
+
console.log(` ${report.coverageGaps.forgottenDecisions} forgotten decision${report.coverageGaps.forgottenDecisions !== 1 ? 's' : ''} (anchored files not accessed in 60+ days)`);
|
|
49
|
+
console.log(` ${report.coverageGaps.undocumentedAreas} undocumented area${report.coverageGaps.undocumentedAreas !== 1 ? 's' : ''} (active files with no decisions)\n`);
|
|
50
|
+
// Assumptions + review pressure
|
|
51
|
+
if (report.assumptionCount > 0) {
|
|
52
|
+
console.log(`Assumptions: ${report.assumptionCount} active${report.topAssumption ? `, "${report.topAssumption}" spans ${report.topAssumptionDecisions} decisions` : ''}`);
|
|
53
|
+
}
|
|
54
|
+
if (report.reviewPressureCount > 0) {
|
|
55
|
+
console.log(`Review Pressure: ${report.reviewPressureCount} decision${report.reviewPressureCount !== 1 ? 's' : ''} due for review`);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/cli/analytics.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/export.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6BpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4G5D"}
|
package/dist/cli/export.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Export is a full snapshot — previous files are overwritten.
|
|
7
7
|
*/
|
|
8
8
|
import { existsSync, mkdirSync, writeFileSync, rmSync } from 'fs';
|
|
9
|
+
import { VERSION } from '../version.js';
|
|
9
10
|
import { join } from 'path';
|
|
10
11
|
import { userInfo } from 'os';
|
|
11
12
|
import yaml from 'js-yaml';
|
|
@@ -18,6 +19,7 @@ const TYPE_SUBDIRS = {
|
|
|
18
19
|
orchestrator_task: 'orchestrator_tasks',
|
|
19
20
|
synthesis_cache: 'synthesis_cache',
|
|
20
21
|
governance_override: 'governance_overrides',
|
|
22
|
+
pattern: 'patterns',
|
|
21
23
|
};
|
|
22
24
|
export function registerExportCommand(program) {
|
|
23
25
|
program
|
|
@@ -137,7 +139,7 @@ function exportPortable(records, exportPath, projectName) {
|
|
|
137
139
|
mkdirSync(exportPath, { recursive: true });
|
|
138
140
|
const portablePath = join(exportPath, 'framework-fixes.portable.json');
|
|
139
141
|
const data = {
|
|
140
|
-
memnant_version:
|
|
142
|
+
memnant_version: VERSION,
|
|
141
143
|
source_project: projectName,
|
|
142
144
|
exported_at: new Date().toISOString(),
|
|
143
145
|
record_count: records.length,
|
|
@@ -160,6 +162,7 @@ const TYPE_LABELS_PLURAL = {
|
|
|
160
162
|
orchestrator_task: 'Orchestrator Tasks',
|
|
161
163
|
synthesis_cache: 'Synthesis Cache',
|
|
162
164
|
governance_override: 'Governance Overrides',
|
|
165
|
+
pattern: 'Patterns',
|
|
163
166
|
};
|
|
164
167
|
function exportNotebookLM(records, exportPath, projectName) {
|
|
165
168
|
mkdirSync(exportPath, { recursive: true });
|
|
@@ -214,7 +217,7 @@ function exportTeam(records, exportPath, projectName, projectId, builderId) {
|
|
|
214
217
|
const shareable = records.filter((r) => ['decision', 'framework_fix', 'session_log'].includes(r.type));
|
|
215
218
|
const portablePath = join(exportPath, 'team-export.portable.json');
|
|
216
219
|
const data = {
|
|
217
|
-
memnant_version:
|
|
220
|
+
memnant_version: VERSION,
|
|
218
221
|
source_project: projectName,
|
|
219
222
|
source_project_id: projectId,
|
|
220
223
|
builder_id: builderId,
|
package/dist/cli/export.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,IAAI,MAAM,SAAS,CAAC;AAG3B,MAAM,YAAY,GAA+B;IAC/C,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,cAAc;IAC3B,aAAa,EAAE,iBAAiB;IAChC,aAAa,EAAE,gBAAgB;IAC/B,iBAAiB,EAAE,oBAAoB;IACvC,iBAAiB,EAAE,oBAAoB;IACvC,eAAe,EAAE,iBAAiB;IAClC,mBAAmB,EAAE,sBAAsB;
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/cli/export.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC9B,OAAO,IAAI,MAAM,SAAS,CAAC;AAG3B,MAAM,YAAY,GAA+B;IAC/C,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,cAAc;IAC3B,aAAa,EAAE,iBAAiB;IAChC,aAAa,EAAE,gBAAgB;IAC/B,iBAAiB,EAAE,oBAAoB;IACvC,iBAAiB,EAAE,oBAAoB;IACvC,eAAe,EAAE,iBAAiB;IAClC,mBAAmB,EAAE,sBAAsB;IAC3C,OAAO,EAAE,UAAU;CACpB,CAAC;AAWF,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,uCAAuC,CAAC;SACpD,MAAM,CAAC,mBAAmB,EAAE,wDAAwD,EAAE,UAAU,CAAC;SACjG,MAAM,CAAC,gBAAgB,EAAE,sCAAsC,CAAC;SAChE,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC;SAC3D,MAAM,CAAC,QAAQ,EAAE,8DAA8D,CAAC;SAChF,MAAM,CAAC,KAAK,EAAE,IAAuE,EAAE,EAAE;QACxF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAC/D,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;QACrD,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAEvF,oBAAoB;QACpB,IAAI,CAAC,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACxF,OAAO,CAAC,KAAK,CACX,0BAA0B,IAAI,CAAC,MAAM,wDAAwD,CAC9F,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,kBAAkB;QAClB,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAqC,CAAC,EAAE,CAAC;YACpF,OAAO,CAAC,KAAK,CACX,wBAAwB,IAAI,CAAC,IAAI,mBAAmB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,mBAAmB;QACnB,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,KAAK,CACX,wBAAwB,IAAI,CAAC,KAAK,2CAA2C,CAC9E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,sBAAsB;QACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,qFAAqF,CAAC,CAAC;YACrG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAExD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CACX,gCAAgC,MAAM,CAAC,MAAM,CAAC,OAAO,qCAAqC,CAC3F,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEhC,IAAI,OAAoB,CAAC;QACzB,IAAI,CAAC;YACH,iDAAiD;YACjD,IAAI,KAAK,GAAG,iIAAiI,CAAC;YAC9I,MAAM,MAAM,GAAa,EAAE,CAAC;YAE5B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,KAAK,IAAI,sBAAsB,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC;YAC7C,CAAC;YAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,KAAK,IAAI,eAAe,CAAC;gBACzB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAED,KAAK,IAAI,0BAA0B,CAAC;YAEpC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAA2B,CAAC;QAC5D,CAAC;gBAAS,CAAC;YACT,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAEhE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ,EAAE,CAAC,QAAQ,CAAC;YAClG,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YACnF,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,6BAA6B,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAChG,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YACjC,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACtC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAClC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,cAAc,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,MAAM,eAAe,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACpF,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,cAAc,CAAC,OAAoB,EAAE,UAAkB;IAC9D,yCAAyC;IACzC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,OAAO,KAAK,CAAC;QAEzC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAa,CAAC;QACjD,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAa,CAAC;QAEtE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAC3B;YACE,EAAE,EAAE,MAAM,CAAC,EAAE;YACb,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,IAAI;YACJ,eAAe,EAAE,cAAc;SAChC,EACD,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAClB,CAAC,IAAI,EAAE,CAAC;QAET,MAAM,OAAO,GAAG,QAAQ,WAAW,YAAY,MAAM,CAAC,YAAY,IAAI,CAAC;QAEvE,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAoB,EAAE,UAAkB,EAAE,WAAmB;IACnF,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,+BAA+B,CAAC,CAAC;IAEvE,MAAM,IAAI,GAAG;QACX,eAAe,EAAE,OAAO;QACxB,cAAc,EAAE,WAAW;QAC3B,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAa;YACpC,WAAW,EAAE,CAAC,CAAC,EAAE;YACjB,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC;KACJ,CAAC;IAEF,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,kBAAkB,GAA+B;IACrD,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,cAAc;IAC3B,aAAa,EAAE,iBAAiB;IAChC,aAAa,EAAE,gBAAgB;IAC/B,iBAAiB,EAAE,oBAAoB;IACvC,iBAAiB,EAAE,oBAAoB;IACvC,eAAe,EAAE,iBAAiB;IAClC,mBAAmB,EAAE,sBAAsB;IAC3C,OAAO,EAAE,UAAU;CACpB,CAAC;AAEF,SAAS,gBAAgB,CAAC,OAAoB,EAAE,UAAkB,EAAE,WAAmB;IACrF,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IACnD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,KAAK,WAAW,6BAA6B,CAAC,CAAC;IAC1D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,4BAA4B,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC;IAC5G,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,gBAAgB;IAChB,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2B,CAAC;IAClD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAC/D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEf,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAa,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAE9D,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC;YACzD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,OAAoB,EAAE,UAAkB;IAC1D,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAEjD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/B,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAa;QACpC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAa;QAC1D,UAAU,EAAE,CAAC,CAAC,UAAU;KACzB,CAAC,CAAC,CAAC;IAEJ,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,UAAU,CAAC,OAAoB,EAAE,UAAkB,EAAE,WAAmB,EAAE,SAAiB,EAAE,SAAiB;IACrH,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE3C,qDAAqD;IACrD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACrC,CAAC,UAAU,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAC9D,CAAC;IAEF,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAC;IAEnE,MAAM,IAAI,GAAG;QACX,eAAe,EAAE,OAAO;QACxB,cAAc,EAAE,WAAW;QAC3B,iBAAiB,EAAE,SAAS;QAC5B,UAAU,EAAE,SAAS;QACrB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,YAAY,EAAE,SAAS,CAAC,MAAM;QAC9B,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,YAAY,EAAE,CAAC,CAAC,YAAY;YAC5B,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAa;YACpC,WAAW,EAAE,CAAC,CAAC,EAAE;YACjB,UAAU,EAAE,CAAC,CAAC,UAAU;SACzB,CAAC,CAAC;KACJ,CAAC;IAEF,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harvest.d.ts","sourceRoot":"","sources":["../../src/cli/harvest.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiD7D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI handler for `memnant harvest`.
|
|
3
|
+
* Scans the latest transcript and extracts missed records.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
export function registerHarvestCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command('harvest')
|
|
10
|
+
.description('Scan latest conversation transcript and extract missed records')
|
|
11
|
+
.action(async () => {
|
|
12
|
+
const { openDatabase } = await import('../ledger/database.js');
|
|
13
|
+
const { loadConfig, ConfigError, findProjectRoot } = await import('../config/load.js');
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
const projectRoot = findProjectRoot(cwd);
|
|
16
|
+
if (!projectRoot) {
|
|
17
|
+
console.error('No memnant project found in this or any parent directory. Run `memnant init` first.');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
let config;
|
|
21
|
+
try {
|
|
22
|
+
config = loadConfig(projectRoot);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.error(err instanceof ConfigError ? err.message : String(err));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const dbPath = join(projectRoot, config.memory.db_path);
|
|
29
|
+
if (!existsSync(dbPath)) {
|
|
30
|
+
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
const db = openDatabase(dbPath);
|
|
34
|
+
let tierConfig = null;
|
|
35
|
+
try {
|
|
36
|
+
if (config.orchestrator?.tiers?.analysis) {
|
|
37
|
+
tierConfig = config.orchestrator.tiers.analysis;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
console.error('harvest entry failed:', e?.message);
|
|
42
|
+
}
|
|
43
|
+
const { harvest } = await import('../harvest/harvest.js');
|
|
44
|
+
const result = await harvest(db, projectRoot, config.project.id, { tierConfig });
|
|
45
|
+
db.close();
|
|
46
|
+
if (!result.transcriptPath) {
|
|
47
|
+
console.log('No transcripts found.');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
console.log(`Harvested: ${result.messagesRead} messages → ${result.candidatesExtracted} candidates → ${result.recordsWritten} new records (${result.duplicatesSkipped} duplicates skipped)`);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=harvest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harvest.js","sourceRoot":"","sources":["../../src/cli/harvest.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,gEAAgE,CAAC;SAC7E,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAC/D,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAEvF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,qFAAqF,CAAC,CAAC;YACrG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,MAAM,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,MAAM,CAAC,OAAO,qCAAqC,CAAC,CAAC;YAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEhC,IAAI,UAAU,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC;YACH,IAAI,MAAM,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;gBACzC,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC;YAClD,CAAC;QACH,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAAC,CAAC;QAExE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;QACjF,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,YAAY,eAAe,MAAM,CAAC,mBAAmB,iBAAiB,MAAM,CAAC,cAAc,iBAAiB,MAAM,CAAC,iBAAiB,sBAAsB,CAAC,CAAC;IAC/L,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/cli/history.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkD7D"}
|