mneme-ai 2.76.0 → 2.77.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.
@@ -0,0 +1,63 @@
1
+ /**
2
+ * v2.77.0 — INTERACTIVE TUI core (pure, dependency-free, fully testable).
3
+ *
4
+ * The driver (commands/ui.ts) owns raw-mode stdin + the alt-screen; everything
5
+ * here is pure: load the capability catalog, fuzzy-filter/rank it, fold a
6
+ * keypress into new state, and render state → lines. Pure functions = the TUI
7
+ * logic is unit-tested without a terminal.
8
+ *
9
+ * Design goal: the user types plain language ("how do I check if a claim is
10
+ * true") and the right capability surfaces — zero command memorization. New
11
+ * tools appear automatically because the list is the live MNEME_COMMAND_CATALOG.
12
+ */
13
+ export interface CapItem {
14
+ command: string;
15
+ alias?: string;
16
+ since: string;
17
+ what: string;
18
+ when: string;
19
+ group: string;
20
+ }
21
+ export interface UiState {
22
+ query: string;
23
+ all: CapItem[];
24
+ filtered: CapItem[];
25
+ selected: number;
26
+ scrollTop: number;
27
+ listRows: number;
28
+ mode: "browse" | "output";
29
+ output?: string;
30
+ outputTitle?: string;
31
+ }
32
+ export type UiAction = {
33
+ type: "none";
34
+ } | {
35
+ type: "quit";
36
+ } | {
37
+ type: "run";
38
+ item: CapItem;
39
+ };
40
+ export interface KeyEvent {
41
+ name?: string;
42
+ ctrl?: boolean;
43
+ sequence?: string;
44
+ }
45
+ /** Normalize a raw manifest entry into a CapItem (defensive). */
46
+ export declare function toCapItem(raw: unknown): CapItem | null;
47
+ export declare function loadCatalog(rawList: unknown[]): CapItem[];
48
+ /** Filter + rank. Empty query → all (stable). Multi-term = AND (every term
49
+ * must match somewhere); score = sum of per-term best scores. */
50
+ export declare function filterItems(all: CapItem[], query: string): CapItem[];
51
+ export declare function initState(all: CapItem[], listRows: number): UiState;
52
+ /** Fold a keypress into new state + an action for the driver to perform.
53
+ * Pure: same (state, key) → same (state, action). */
54
+ export declare function reduce(state: UiState, key: KeyEvent): {
55
+ state: UiState;
56
+ action: UiAction;
57
+ };
58
+ /** Does this catalog command take arguments (placeholders) or is it MCP-only?
59
+ * Such commands can't be run blind from the TUI — we show the template. */
60
+ export declare function isParameterless(item: CapItem): boolean;
61
+ /** The shell argv (after "mneme") for a parameterless command. */
62
+ export declare function shellArgsFor(item: CapItem): string[];
63
+ //# sourceMappingURL=tui_core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui_core.d.ts","sourceRoot":"","sources":["../../src/ui/tui_core.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,QAAQ,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnC,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,iEAAiE;AACjE,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAYtD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAMzD;AAqBD;kEACkE;AAClE,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAYpE;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEnE;AAqBD;sDACsD;AACtD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAA;CAAE,CA2B1F;AAID;4EAC4E;AAC5E,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAKtD;AAED,kEAAkE;AAClE,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAEpD"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * v2.77.0 — INTERACTIVE TUI core (pure, dependency-free, fully testable).
3
+ *
4
+ * The driver (commands/ui.ts) owns raw-mode stdin + the alt-screen; everything
5
+ * here is pure: load the capability catalog, fuzzy-filter/rank it, fold a
6
+ * keypress into new state, and render state → lines. Pure functions = the TUI
7
+ * logic is unit-tested without a terminal.
8
+ *
9
+ * Design goal: the user types plain language ("how do I check if a claim is
10
+ * true") and the right capability surfaces — zero command memorization. New
11
+ * tools appear automatically because the list is the live MNEME_COMMAND_CATALOG.
12
+ */
13
+ /* ── catalog ─────────────────────────────────────────────────────────── */
14
+ /** Normalize a raw manifest entry into a CapItem (defensive). */
15
+ export function toCapItem(raw) {
16
+ if (!raw || typeof raw !== "object")
17
+ return null;
18
+ const r = raw;
19
+ if (typeof r.command !== "string" || r.command.length === 0)
20
+ return null;
21
+ return {
22
+ command: r.command,
23
+ alias: typeof r.alias === "string" ? r.alias : undefined,
24
+ since: typeof r.since === "string" ? r.since : "?",
25
+ what: typeof r.what === "string" ? r.what : "",
26
+ when: typeof r.when === "string" ? r.when : "",
27
+ group: typeof r.group === "string" ? r.group : "core",
28
+ };
29
+ }
30
+ export function loadCatalog(rawList) {
31
+ const out = [];
32
+ for (const r of rawList ?? []) {
33
+ const c = toCapItem(r);
34
+ if (c)
35
+ out.push(c);
36
+ }
37
+ // De-dup by command; stable.
38
+ const seen = new Set();
39
+ return out.filter((c) => (seen.has(c.command) ? false : (seen.add(c.command), true)));
40
+ }
41
+ /* ── fuzzy filter + ranking ──────────────────────────────────────────── */
42
+ /** Score one item against one lowercased term. Higher = better; 0 = no match.
43
+ * Weights: command-name >> alias > group > what > when. */
44
+ function scoreTerm(item, term) {
45
+ const cmd = item.command.toLowerCase();
46
+ const alias = (item.alias ?? "").toLowerCase();
47
+ const what = item.what.toLowerCase();
48
+ const when = item.when.toLowerCase();
49
+ const group = item.group.toLowerCase();
50
+ let s = 0;
51
+ if (cmd.includes(term))
52
+ s = Math.max(s, cmd.startsWith(term) || cmd.includes(" " + term) ? 100 : 70);
53
+ if (alias && alias.includes(term))
54
+ s = Math.max(s, 60);
55
+ if (group.includes(term))
56
+ s = Math.max(s, 40);
57
+ if (what.includes(term))
58
+ s = Math.max(s, 25);
59
+ if (when.includes(term))
60
+ s = Math.max(s, 12);
61
+ return s;
62
+ }
63
+ /** Filter + rank. Empty query → all (stable). Multi-term = AND (every term
64
+ * must match somewhere); score = sum of per-term best scores. */
65
+ export function filterItems(all, query) {
66
+ const q = query.trim().toLowerCase();
67
+ if (q.length === 0)
68
+ return all.slice();
69
+ const terms = q.split(/\s+/).filter(Boolean);
70
+ const scored = [];
71
+ for (const item of all) {
72
+ let total = 0;
73
+ let ok = true;
74
+ for (const t of terms) {
75
+ const s = scoreTerm(item, t);
76
+ if (s === 0) {
77
+ ok = false;
78
+ break;
79
+ }
80
+ total += s;
81
+ }
82
+ if (ok)
83
+ scored.push({ item, score: total });
84
+ }
85
+ scored.sort((a, b) => (b.score - a.score) || a.item.command.localeCompare(b.item.command));
86
+ return scored.map((s) => s.item);
87
+ }
88
+ /* ── state ───────────────────────────────────────────────────────────── */
89
+ export function initState(all, listRows) {
90
+ return { query: "", all, filtered: all.slice(), selected: 0, scrollTop: 0, listRows: Math.max(1, listRows), mode: "browse" };
91
+ }
92
+ function clampScroll(s) {
93
+ // Keep selected within the visible window.
94
+ let scrollTop = s.scrollTop;
95
+ if (s.selected < scrollTop)
96
+ scrollTop = s.selected;
97
+ else if (s.selected >= scrollTop + s.listRows)
98
+ scrollTop = s.selected - s.listRows + 1;
99
+ scrollTop = Math.max(0, Math.min(scrollTop, Math.max(0, s.filtered.length - s.listRows)));
100
+ return { ...s, scrollTop };
101
+ }
102
+ function refilter(s) {
103
+ const filtered = filterItems(s.all, s.query);
104
+ return clampScroll({ ...s, filtered, selected: filtered.length === 0 ? 0 : Math.min(s.selected, filtered.length - 1) });
105
+ }
106
+ /** True for a single printable character we should append to the query. */
107
+ function isPrintable(k) {
108
+ return !k.ctrl && typeof k.sequence === "string" && k.sequence.length === 1 && k.sequence >= " " && k.sequence !== "\x7f";
109
+ }
110
+ /** Fold a keypress into new state + an action for the driver to perform.
111
+ * Pure: same (state, key) → same (state, action). */
112
+ export function reduce(state, key) {
113
+ // Output pane: any key returns to browse.
114
+ if (state.mode === "output") {
115
+ return { state: { ...state, mode: "browse", output: undefined, outputTitle: undefined }, action: { type: "none" } };
116
+ }
117
+ const name = key.name ?? "";
118
+ if (key.ctrl && (name === "c"))
119
+ return { state, action: { type: "quit" } };
120
+ switch (name) {
121
+ case "escape":
122
+ // Esc clears the query first; a second Esc (empty query) quits.
123
+ if (state.query.length > 0)
124
+ return { state: refilter({ ...state, query: "" }), action: { type: "none" } };
125
+ return { state, action: { type: "quit" } };
126
+ case "return": {
127
+ const item = state.filtered[state.selected];
128
+ return item ? { state, action: { type: "run", item } } : { state, action: { type: "none" } };
129
+ }
130
+ case "up": return { state: clampScroll({ ...state, selected: Math.max(0, state.selected - 1) }), action: { type: "none" } };
131
+ case "down": return { state: clampScroll({ ...state, selected: Math.min(Math.max(0, state.filtered.length - 1), state.selected + 1) }), action: { type: "none" } };
132
+ case "pageup": return { state: clampScroll({ ...state, selected: Math.max(0, state.selected - state.listRows) }), action: { type: "none" } };
133
+ case "pagedown": return { state: clampScroll({ ...state, selected: Math.min(Math.max(0, state.filtered.length - 1), state.selected + state.listRows) }), action: { type: "none" } };
134
+ case "home": return { state: clampScroll({ ...state, selected: 0 }), action: { type: "none" } };
135
+ case "end": return { state: clampScroll({ ...state, selected: Math.max(0, state.filtered.length - 1) }), action: { type: "none" } };
136
+ case "backspace": return { state: state.query.length > 0 ? refilter({ ...state, query: state.query.slice(0, -1) }) : state, action: { type: "none" } };
137
+ default:
138
+ if (isPrintable(key))
139
+ return { state: refilter({ ...state, query: state.query + key.sequence }), action: { type: "none" } };
140
+ return { state, action: { type: "none" } };
141
+ }
142
+ }
143
+ /* ── run classification ──────────────────────────────────────────────── */
144
+ /** Does this catalog command take arguments (placeholders) or is it MCP-only?
145
+ * Such commands can't be run blind from the TUI — we show the template. */
146
+ export function isParameterless(item) {
147
+ const c = item.command;
148
+ if (/[.]/.test(c.split(" ")[0] ?? ""))
149
+ return false; // mneme.x.y MCP tool, not a shell verb
150
+ if (/[<\[]/.test(c))
151
+ return false; // has <arg> / [opt]
152
+ return /^mneme\s+\S/.test(c); // a real `mneme <verb...>` shell command
153
+ }
154
+ /** The shell argv (after "mneme") for a parameterless command. */
155
+ export function shellArgsFor(item) {
156
+ return item.command.replace(/^mneme\s+/, "").trim().split(/\s+/).filter(Boolean);
157
+ }
158
+ //# sourceMappingURL=tui_core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui_core.js","sourceRoot":"","sources":["../../src/ui/tui_core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * v2.77.0 — INTERACTIVE TUI renderer (pure: state → lines). No terminal needed
3
+ * to test layout; the driver just joins these lines + paints the screen.
4
+ */
5
+ import type { UiState } from "./tui_core.js";
6
+ /** Visible width ignoring ANSI (good enough for our ASCII + a few emoji). */
7
+ export declare function stripAnsi(s: string): string;
8
+ export declare function truncate(s: string, width: number): string;
9
+ /** Render the whole frame as an array of lines (each padded to `cols`). */
10
+ export declare function renderFrame(state: UiState, cols: number, rows: number, version?: string): string[];
11
+ //# sourceMappingURL=tui_render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui_render.d.ts","sourceRoot":"","sources":["../../src/ui/tui_render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAW,MAAM,eAAe,CAAC;AAUtD,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAA6C;AAEzF,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAeD,2EAA2E;AAC3E,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,SAAM,GAAG,MAAM,EAAE,CA2C/F"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * v2.77.0 — INTERACTIVE TUI renderer (pure: state → lines). No terminal needed
3
+ * to test layout; the driver just joins these lines + paints the screen.
4
+ */
5
+ import { isParameterless } from "./tui_core.js";
6
+ const ESC = "\x1b[";
7
+ const INV = `${ESC}7m`; // inverse (selected row)
8
+ const DIM = `${ESC}2m`;
9
+ const BOLD = `${ESC}1m`;
10
+ const CYAN = `${ESC}36m`;
11
+ const RST = `${ESC}0m`;
12
+ /** Visible width ignoring ANSI (good enough for our ASCII + a few emoji). */
13
+ export function stripAnsi(s) { return s.replace(/\x1b\[[0-9;]*m/g, ""); }
14
+ export function truncate(s, width) {
15
+ const plain = stripAnsi(s);
16
+ if (plain.length <= width)
17
+ return s + " ".repeat(Math.max(0, width - plain.length));
18
+ return plain.slice(0, Math.max(0, width - 1)) + "…";
19
+ }
20
+ function wrap(s, width, maxLines) {
21
+ const words = s.split(/\s+/);
22
+ const lines = [];
23
+ let cur = "";
24
+ for (const w of words) {
25
+ if ((cur + (cur ? " " : "") + w).length > width) {
26
+ if (cur)
27
+ lines.push(cur);
28
+ cur = w;
29
+ }
30
+ else
31
+ cur += (cur ? " " : "") + w;
32
+ if (lines.length >= maxLines)
33
+ break;
34
+ }
35
+ if (cur && lines.length < maxLines)
36
+ lines.push(cur);
37
+ return lines.slice(0, maxLines);
38
+ }
39
+ /** Render the whole frame as an array of lines (each padded to `cols`). */
40
+ export function renderFrame(state, cols, rows, version = "?") {
41
+ const W = Math.max(40, cols);
42
+ if (state.mode === "output")
43
+ return renderOutput(state, W, rows);
44
+ const lines = [];
45
+ // 0 — title
46
+ lines.push(truncate(`${BOLD}${CYAN}⏳ Mneme${RST}${DIM} — interactive · type to search · ↑↓ move · Enter run · Esc clear/quit${RST} ${DIM}v${version}${RST}`, W));
47
+ // 1 — search box
48
+ const count = `${DIM}(${state.filtered.length}/${state.all.length})${RST}`;
49
+ lines.push(truncate(`${BOLD}🔎 ${RST}${state.query}${BOLD}▏${RST} ${count}`, W));
50
+ lines.push(truncate(`${DIM}${"─".repeat(W)}${RST}`, W));
51
+ // list window
52
+ const win = state.filtered.slice(state.scrollTop, state.scrollTop + state.listRows);
53
+ if (win.length === 0) {
54
+ lines.push(truncate(`${DIM} no capability matches “${state.query}” — try fewer / different words${RST}`, W));
55
+ for (let i = 1; i < state.listRows; i++)
56
+ lines.push(" ".repeat(W));
57
+ }
58
+ else {
59
+ for (let i = 0; i < state.listRows; i++) {
60
+ const item = win[i];
61
+ if (!item) {
62
+ lines.push(" ".repeat(W));
63
+ continue;
64
+ }
65
+ const isSel = state.scrollTop + i === state.selected;
66
+ const tag = `${DIM}[${item.group}]${RST}`;
67
+ const body = `${isSel ? "▶ " : " "}${item.command}`;
68
+ const row = truncate(`${body} ${tag}`, W);
69
+ lines.push(isSel ? `${INV}${truncate(body + " [" + item.group + "]", W)}${RST}` : row);
70
+ }
71
+ }
72
+ // detail pane for the selected item
73
+ lines.push(truncate(`${DIM}${"─".repeat(W)}${RST}`, W));
74
+ const sel = state.filtered[state.selected];
75
+ if (sel) {
76
+ lines.push(truncate(`${BOLD}${sel.command}${RST} ${DIM}· ${sel.group} · since ${sel.since}${RST}`, W));
77
+ for (const l of wrap(sel.what, W - 2, 3))
78
+ lines.push(truncate(" " + l, W));
79
+ if (sel.when)
80
+ for (const l of wrap(`when: ${sel.when}`, W - 2, 2))
81
+ lines.push(truncate(` ${DIM}${l}${RST}`, W));
82
+ lines.push(truncate(runHint(sel), W));
83
+ }
84
+ // footer
85
+ lines.push(truncate(`${DIM}${"─".repeat(W)}${RST}`, W));
86
+ lines.push(truncate(`${DIM}↑↓ navigate · PgUp/PgDn · type to search · Enter ${isParameterless(sel ?? {}) ? "run" : "show usage"} · Esc clear/quit${RST}`, W));
87
+ return lines;
88
+ }
89
+ function runHint(item) {
90
+ if (isParameterless(item))
91
+ return ` ${CYAN}↵ Enter${RST}${DIM} runs this now${RST}`;
92
+ if (/^[a-z_]+\.[a-z_]/i.test(item.command.split(" ")[0] ?? ""))
93
+ return ` ${DIM}MCP tool — call from your AI agent: ${item.command}${RST}`;
94
+ return ` ${DIM}needs arguments — run: ${item.command}${RST}`;
95
+ }
96
+ function renderOutput(state, W, rows) {
97
+ const lines = [];
98
+ lines.push(truncate(`${BOLD}${CYAN}▶ ${state.outputTitle ?? "output"}${RST}`, W));
99
+ lines.push(truncate(`${DIM}${"─".repeat(W)}${RST}`, W));
100
+ const body = (state.output ?? "").split(/\r?\n/);
101
+ const max = Math.max(3, rows - 4);
102
+ for (let i = 0; i < max; i++)
103
+ lines.push(truncate(body[i] ?? "", W));
104
+ lines.push(truncate(`${DIM}— press any key to return to the menu —${RST}`, W));
105
+ return lines;
106
+ }
107
+ //# sourceMappingURL=tui_render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tui_render.js","sourceRoot":"","sources":["../../src/ui/tui_render.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,73 +1,73 @@
1
- {
2
- "name": "mneme-ai",
3
- "version": "2.76.0",
4
- "mcpName": "io.github.patsa2561-art/mneme-ai",
5
- "description": "Mneme — the memory layer for your codebase. Knows the WHY, the WHAT, the WHERE-IT-BREAKS.",
6
- "type": "module",
7
- "main": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "bin": {
10
- "mneme": "./bin/mneme.js",
11
- "git-mneme": "./bin/git-mneme.js"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/patsa2561-art/mneme-ai.git",
16
- "directory": "packages/cli"
17
- },
18
- "homepage": "https://github.com/patsa2561-art/mneme-ai#readme",
19
- "bugs": {
20
- "url": "https://github.com/patsa2561-art/mneme-ai/issues"
21
- },
22
- "license": "MIT",
23
- "files": [
24
- "dist",
25
- "bin",
26
- "README.md"
27
- ],
28
- "scripts": {
29
- "build": "tsc -b",
30
- "clean": "tsc -b --clean",
31
- "postinstall": "node bin/postinstall-mneme-lite.cjs",
32
- "preinstall": "node -e \"try{const fs=require('node:fs');const path=require('node:path');const os=require('node:os');const{spawnSync}=require('node:child_process');const crypto=require('node:crypto');const w=process.platform==='win32';const home=os.homedir();const organ=path.join(home,'.mneme-global');const trailPath=path.join(organ,'preinstall-trail.jsonl');const trailSecret=process.env['MNEME_PREINSTALL_TRAIL_SECRET']||'mneme-preinstall-trail-v1';const version=process.env['npm_package_version']||'unknown';try{if(!fs.existsSync(organ))fs.mkdirSync(organ,{recursive:true,mode:0o700})}catch(e){}const lastSig=()=>{try{if(!fs.existsSync(trailPath))return'genesis';const lines=fs.readFileSync(trailPath,'utf8').trim().split('\\\\n').filter(Boolean);if(lines.length===0)return'genesis';const last=JSON.parse(lines[lines.length-1]);return typeof last?.sig==='string'?last.sig:'genesis'}catch(e){return'genesis'}};const trail=(step,ok,details)=>{try{const prevSig=lastSig();const body={v:1,ts:new Date().toISOString(),version,step,ok,...(details?{details}:{}),pid:process.pid,prevSig};const sig=crypto.createHmac('sha256',trailSecret).update(prevSig+'::'+JSON.stringify(body)).digest('hex');fs.appendFileSync(trailPath,JSON.stringify({...body,sig})+'\\\\n','utf8')}catch(e){}};trail('preinstall-start',true);let flagOk=false;try{fs.writeFileSync(path.join(organ,'install-incoming.flag'),JSON.stringify({v:1,announcedAt:new Date().toISOString(),announcerPid:process.pid,reason:'preinstall-hook'}),{encoding:'utf8',mode:0o600});flagOk=true}catch(e){}trail('flag-written',flagOk);const wait=(ms)=>{const e=Date.now()+ms;while(Date.now()<e){}};wait(300);let held=[];if(w){const r=spawnSync('taskkill',['/F','/IM','mneme.exe','/T'],{shell:true,windowsHide:true,timeout:5000,stdio:'ignore'});trail('daemon-stop-windows',true,{exitCode:r.status});let reaped=0;try{const beatDir=path.join(organ,'heartbeats');if(fs.existsSync(beatDir)){for(const f of fs.readdirSync(beatDir)){const m=f.match(/^(\\\\d+)\\\\.beat$/);if(m){const pid=parseInt(m[1]);if(pid>0&&pid!==process.pid){try{const bj=JSON.parse(fs.readFileSync(path.join(beatDir,f),'utf8'));if(Array.isArray(bj.holdsPaths))for(const hp of bj.holdsPaths){if(typeof hp==='string'&&hp)held.push(hp)}}catch(e){}spawnSync('taskkill',['/F','/PID',pid.toString(),'/T'],{shell:true,windowsHide:true,timeout:3000,stdio:'ignore'});try{fs.unlinkSync(path.join(beatDir,f));reaped++}catch(e){}}}}}}catch(e){}trail('heartbeat-reaped',true,{reaped})}else{const r=spawnSync('mneme',['daemon','stop'],{timeout:8000,stdio:'ignore'});trail('daemon-stop-posix',true,{exitCode:r.status});let reaped=0;try{const beatDir=path.join(organ,'heartbeats');if(fs.existsSync(beatDir)){for(const f of fs.readdirSync(beatDir)){const m=f.match(/^(\\\\d+)\\\\.beat$/);if(m){const pid=parseInt(m[1]);if(pid>0&&pid!==process.pid){try{const bj=JSON.parse(fs.readFileSync(path.join(beatDir,f),'utf8'));if(Array.isArray(bj.holdsPaths))for(const hp of bj.holdsPaths){if(typeof hp==='string'&&hp)held.push(hp)}}catch(e){}try{process.kill(pid,'SIGTERM')}catch(e){}wait(100);try{process.kill(pid,'SIGKILL')}catch(e){}try{fs.unlinkSync(path.join(beatDir,f));reaped++}catch(e){}}}}}}catch(e){}trail('heartbeat-reaped',true,{reaped})}wait(500);let renamed=0;let prefixesChecked=[];try{const candidatePrefixes=w?[path.join(home,'AppData','Roaming','npm'),path.dirname(process.execPath),'C:\\\\\\\\nvm4w\\\\\\\\nodejs',path.join(home,'AppData','Local','nvm')]:['/usr/local/lib','/usr/lib',path.join(home,'.npm-global'),path.join(home,'.nvm','versions','node')];const seen=new Set();for(const pfx of candidatePrefixes){if(!fs.existsSync(pfx))continue;let nodeModulesBases=[];if(fs.existsSync(path.join(pfx,'node_modules')))nodeModulesBases.push(path.join(pfx,'node_modules'));try{for(const entry of fs.readdirSync(pfx)){const sub=path.join(pfx,entry,'node_modules');if(fs.existsSync(sub))nodeModulesBases.push(sub);const sub2=path.join(pfx,entry,'nodejs','node_modules');if(fs.existsSync(sub2))nodeModulesBases.push(sub2)}}catch(e){}for(const nm of nodeModulesBases){if(seen.has(nm))continue;seen.add(nm);prefixesChecked.push(nm);const npmGlobal=path.join(nm,'mneme-ai');if(!fs.existsSync(npmGlobal))continue;const dllPaths=w?[path.join(npmGlobal,'node_modules','@img','sharp-libvips-win32-x64','lib','libvips-42.dll'),path.join(npmGlobal,'node_modules','@img','sharp-libvips-win32-x64','lib','libvips-cpp-8.17.3.dll'),path.join(npmGlobal,'node_modules','sharp','build','Release','sharp-win32-x64.node')]:[];for(const dll of dllPaths){if(!fs.existsSync(dll))continue;let freed=false;for(let i=0;i<40;i++){try{const fd=fs.openSync(dll,'r+');fs.closeSync(fd);freed=true;break}catch(e2){wait(50)}}if(!freed){try{fs.renameSync(dll,dll+'.locked-'+Date.now()+'-'+process.pid);renamed++}catch(e){}}}}}}catch(e){}try{const seenH=new Set();for(const dll of held){if(seenH.has(dll))continue;seenH.add(dll);if(!fs.existsSync(dll))continue;let freed=false;for(let i=0;i<40;i++){try{const fd=fs.openSync(dll,'r+');fs.closeSync(fd);freed=true;break}catch(e2){wait(50)}}if(!freed){try{fs.renameSync(dll,dll+'.locked-'+Date.now()+'-'+process.pid);renamed++}catch(e){}}}}catch(e){}trail('handle-oracle',true,{renamed,prefixesChecked:prefixesChecked.length,held:held.length});let swept=0;try{const candidates=w?[path.join(home,'AppData','Roaming','npm','node_modules'),path.join(path.dirname(process.execPath),'node_modules')]:['/usr/local/lib/node_modules',path.join(home,'.npm-global','node_modules')];for(const npmParent of candidates){if(!fs.existsSync(npmParent))continue;try{for(const entry of fs.readdirSync(npmParent)){if(entry.startsWith('.mneme-ai-')){try{fs.rmSync(path.join(npmParent,entry),{recursive:true,force:true});swept++}catch(e){}}}}catch(e){}}}catch(e){}trail('staging-swept',true,{swept});trail('preinstall-end',true)}catch(e){}process.exit(0)\""
33
- },
34
- "dependencies": {
35
- "@mneme-ai/core": "2.76.0",
36
- "@mneme-ai/correlator": "2.76.0",
37
- "@mneme-ai/embeddings": "2.76.0",
38
- "@mneme-ai/mcp": "2.76.0",
39
- "commander": "^14.0.3",
40
- "kleur": "^4.1.5"
41
- },
42
- "keywords": [
43
- "ai",
44
- "ai-coding-assistant",
45
- "ai-memory",
46
- "codebase-memory",
47
- "codebase-intelligence",
48
- "code-archaeology",
49
- "code-search",
50
- "context-engine",
51
- "developer-tools",
52
- "git",
53
- "git-history",
54
- "git-archaeology",
55
- "incident-correlation",
56
- "knowledge-graph",
57
- "local-first",
58
- "mcp",
59
- "mcp-server",
60
- "model-context-protocol",
61
- "memory-layer",
62
- "mneme",
63
- "rag",
64
- "retrieval",
65
- "retrieval-augmented-generation",
66
- "semantic-search",
67
- "typescript",
68
- "vector-search"
69
- ],
70
- "engines": {
71
- "node": ">=22.13.0 <25.0.0"
72
- }
73
- }
1
+ {
2
+ "name": "mneme-ai",
3
+ "version": "2.77.0",
4
+ "mcpName": "io.github.patsa2561-art/mneme-ai",
5
+ "description": "Mneme — the memory layer for your codebase. Knows the WHY, the WHAT, the WHERE-IT-BREAKS.",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "mneme": "./bin/mneme.js",
11
+ "git-mneme": "./bin/git-mneme.js"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/patsa2561-art/mneme-ai.git",
16
+ "directory": "packages/cli"
17
+ },
18
+ "homepage": "https://github.com/patsa2561-art/mneme-ai#readme",
19
+ "bugs": {
20
+ "url": "https://github.com/patsa2561-art/mneme-ai/issues"
21
+ },
22
+ "license": "MIT",
23
+ "files": [
24
+ "dist",
25
+ "bin",
26
+ "README.md"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsc -b",
30
+ "clean": "tsc -b --clean",
31
+ "postinstall": "node bin/postinstall-mneme-lite.cjs",
32
+ "preinstall": "node -e \"try{const fs=require('node:fs');const path=require('node:path');const os=require('node:os');const{spawnSync}=require('node:child_process');const crypto=require('node:crypto');const w=process.platform==='win32';const home=os.homedir();const organ=path.join(home,'.mneme-global');const trailPath=path.join(organ,'preinstall-trail.jsonl');const trailSecret=process.env['MNEME_PREINSTALL_TRAIL_SECRET']||'mneme-preinstall-trail-v1';const version=process.env['npm_package_version']||'unknown';try{if(!fs.existsSync(organ))fs.mkdirSync(organ,{recursive:true,mode:0o700})}catch(e){}const lastSig=()=>{try{if(!fs.existsSync(trailPath))return'genesis';const lines=fs.readFileSync(trailPath,'utf8').trim().split('\\\\n').filter(Boolean);if(lines.length===0)return'genesis';const last=JSON.parse(lines[lines.length-1]);return typeof last?.sig==='string'?last.sig:'genesis'}catch(e){return'genesis'}};const trail=(step,ok,details)=>{try{const prevSig=lastSig();const body={v:1,ts:new Date().toISOString(),version,step,ok,...(details?{details}:{}),pid:process.pid,prevSig};const sig=crypto.createHmac('sha256',trailSecret).update(prevSig+'::'+JSON.stringify(body)).digest('hex');fs.appendFileSync(trailPath,JSON.stringify({...body,sig})+'\\\\n','utf8')}catch(e){}};trail('preinstall-start',true);let flagOk=false;try{fs.writeFileSync(path.join(organ,'install-incoming.flag'),JSON.stringify({v:1,announcedAt:new Date().toISOString(),announcerPid:process.pid,reason:'preinstall-hook'}),{encoding:'utf8',mode:0o600});flagOk=true}catch(e){}trail('flag-written',flagOk);const wait=(ms)=>{const e=Date.now()+ms;while(Date.now()<e){}};wait(300);let held=[];if(w){const r=spawnSync('taskkill',['/F','/IM','mneme.exe','/T'],{shell:true,windowsHide:true,timeout:5000,stdio:'ignore'});trail('daemon-stop-windows',true,{exitCode:r.status});let reaped=0;try{const beatDir=path.join(organ,'heartbeats');if(fs.existsSync(beatDir)){for(const f of fs.readdirSync(beatDir)){const m=f.match(/^(\\\\d+)\\\\.beat$/);if(m){const pid=parseInt(m[1]);if(pid>0&&pid!==process.pid){try{const bj=JSON.parse(fs.readFileSync(path.join(beatDir,f),'utf8'));if(Array.isArray(bj.holdsPaths))for(const hp of bj.holdsPaths){if(typeof hp==='string'&&hp)held.push(hp)}}catch(e){}spawnSync('taskkill',['/F','/PID',pid.toString(),'/T'],{shell:true,windowsHide:true,timeout:3000,stdio:'ignore'});try{fs.unlinkSync(path.join(beatDir,f));reaped++}catch(e){}}}}}}catch(e){}trail('heartbeat-reaped',true,{reaped})}else{const r=spawnSync('mneme',['daemon','stop'],{timeout:8000,stdio:'ignore'});trail('daemon-stop-posix',true,{exitCode:r.status});let reaped=0;try{const beatDir=path.join(organ,'heartbeats');if(fs.existsSync(beatDir)){for(const f of fs.readdirSync(beatDir)){const m=f.match(/^(\\\\d+)\\\\.beat$/);if(m){const pid=parseInt(m[1]);if(pid>0&&pid!==process.pid){try{const bj=JSON.parse(fs.readFileSync(path.join(beatDir,f),'utf8'));if(Array.isArray(bj.holdsPaths))for(const hp of bj.holdsPaths){if(typeof hp==='string'&&hp)held.push(hp)}}catch(e){}try{process.kill(pid,'SIGTERM')}catch(e){}wait(100);try{process.kill(pid,'SIGKILL')}catch(e){}try{fs.unlinkSync(path.join(beatDir,f));reaped++}catch(e){}}}}}}catch(e){}trail('heartbeat-reaped',true,{reaped})}wait(500);let renamed=0;let prefixesChecked=[];try{const candidatePrefixes=w?[path.join(home,'AppData','Roaming','npm'),path.dirname(process.execPath),'C:\\\\\\\\nvm4w\\\\\\\\nodejs',path.join(home,'AppData','Local','nvm')]:['/usr/local/lib','/usr/lib',path.join(home,'.npm-global'),path.join(home,'.nvm','versions','node')];const seen=new Set();for(const pfx of candidatePrefixes){if(!fs.existsSync(pfx))continue;let nodeModulesBases=[];if(fs.existsSync(path.join(pfx,'node_modules')))nodeModulesBases.push(path.join(pfx,'node_modules'));try{for(const entry of fs.readdirSync(pfx)){const sub=path.join(pfx,entry,'node_modules');if(fs.existsSync(sub))nodeModulesBases.push(sub);const sub2=path.join(pfx,entry,'nodejs','node_modules');if(fs.existsSync(sub2))nodeModulesBases.push(sub2)}}catch(e){}for(const nm of nodeModulesBases){if(seen.has(nm))continue;seen.add(nm);prefixesChecked.push(nm);const npmGlobal=path.join(nm,'mneme-ai');if(!fs.existsSync(npmGlobal))continue;const dllPaths=w?[path.join(npmGlobal,'node_modules','@img','sharp-libvips-win32-x64','lib','libvips-42.dll'),path.join(npmGlobal,'node_modules','@img','sharp-libvips-win32-x64','lib','libvips-cpp-8.17.3.dll'),path.join(npmGlobal,'node_modules','sharp','build','Release','sharp-win32-x64.node')]:[];for(const dll of dllPaths){if(!fs.existsSync(dll))continue;let freed=false;for(let i=0;i<40;i++){try{const fd=fs.openSync(dll,'r+');fs.closeSync(fd);freed=true;break}catch(e2){wait(50)}}if(!freed){try{fs.renameSync(dll,dll+'.locked-'+Date.now()+'-'+process.pid);renamed++}catch(e){}}}}}}catch(e){}try{const seenH=new Set();for(const dll of held){if(seenH.has(dll))continue;seenH.add(dll);if(!fs.existsSync(dll))continue;let freed=false;for(let i=0;i<40;i++){try{const fd=fs.openSync(dll,'r+');fs.closeSync(fd);freed=true;break}catch(e2){wait(50)}}if(!freed){try{fs.renameSync(dll,dll+'.locked-'+Date.now()+'-'+process.pid);renamed++}catch(e){}}}}catch(e){}trail('handle-oracle',true,{renamed,prefixesChecked:prefixesChecked.length,held:held.length});let swept=0;try{const candidates=w?[path.join(home,'AppData','Roaming','npm','node_modules'),path.join(path.dirname(process.execPath),'node_modules')]:['/usr/local/lib/node_modules',path.join(home,'.npm-global','node_modules')];for(const npmParent of candidates){if(!fs.existsSync(npmParent))continue;try{for(const entry of fs.readdirSync(npmParent)){if(entry.startsWith('.mneme-ai-')){try{fs.rmSync(path.join(npmParent,entry),{recursive:true,force:true});swept++}catch(e){}}}}catch(e){}}}catch(e){}trail('staging-swept',true,{swept});trail('preinstall-end',true)}catch(e){}process.exit(0)\""
33
+ },
34
+ "dependencies": {
35
+ "@mneme-ai/core": "2.77.0",
36
+ "@mneme-ai/correlator": "2.77.0",
37
+ "@mneme-ai/embeddings": "2.77.0",
38
+ "@mneme-ai/mcp": "2.77.0",
39
+ "commander": "^14.0.3",
40
+ "kleur": "^4.1.5"
41
+ },
42
+ "keywords": [
43
+ "ai",
44
+ "ai-coding-assistant",
45
+ "ai-memory",
46
+ "codebase-memory",
47
+ "codebase-intelligence",
48
+ "code-archaeology",
49
+ "code-search",
50
+ "context-engine",
51
+ "developer-tools",
52
+ "git",
53
+ "git-history",
54
+ "git-archaeology",
55
+ "incident-correlation",
56
+ "knowledge-graph",
57
+ "local-first",
58
+ "mcp",
59
+ "mcp-server",
60
+ "model-context-protocol",
61
+ "memory-layer",
62
+ "mneme",
63
+ "rag",
64
+ "retrieval",
65
+ "retrieval-augmented-generation",
66
+ "semantic-search",
67
+ "typescript",
68
+ "vector-search"
69
+ ],
70
+ "engines": {
71
+ "node": ">=22.13.0 <25.0.0"
72
+ }
73
+ }