mneme-ai 2.48.0 → 2.49.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/dist/alias_resolver.d.ts +50 -0
- package/dist/alias_resolver.d.ts.map +1 -0
- package/dist/alias_resolver.js +129 -0
- package/dist/alias_resolver.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +105 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.49.0 — AUTO-ALIAS RESOLVER.
|
|
3
|
+
*
|
|
4
|
+
* Wild idea: the WIRING LAG class isn't just "feature shipped but CLI verb
|
|
5
|
+
* missing" — it's ALSO "feature shipped but user typed a NATURAL ALIAS
|
|
6
|
+
* that doesn't exist". v2.48 shipped `mneme dev_tooling detect`; user
|
|
7
|
+
* tried `mneme dev` / `mneme detect` / `mneme tool_detect` and got
|
|
8
|
+
* cryptic `unknown command`. That's wiring lag at the keyboard surface.
|
|
9
|
+
*
|
|
10
|
+
* This module kills the class STRUCTURALLY:
|
|
11
|
+
* 1. Levenshtein-based fuzzy match against all known top-level verbs
|
|
12
|
+
* 2. Top-3 suggestions printed when user types unknown verb
|
|
13
|
+
* 3. Heat-map ledger of misses → next release adds them as real aliases
|
|
14
|
+
* 4. Intent-router fallback for natural-language phrases
|
|
15
|
+
*
|
|
16
|
+
* Pure deterministic except for the file-write to the heat-map ledger.
|
|
17
|
+
* Defensive — never throws.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Classic Levenshtein with single-char + transposition + similar-key
|
|
21
|
+
* discounts. O(m·n) DP — fine for command names (typically ≤ 20 chars).
|
|
22
|
+
*/
|
|
23
|
+
export declare function levenshteinDistance(a: string, b: string): number;
|
|
24
|
+
export interface Suggestion {
|
|
25
|
+
command: string;
|
|
26
|
+
distance: number;
|
|
27
|
+
/** Heuristic: does user's verb START WITH the command (or vice versa)? */
|
|
28
|
+
prefixMatch: boolean;
|
|
29
|
+
/** Distance normalized to candidate length (0=identical, 1=totally different). */
|
|
30
|
+
normalizedDistance: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Return top-N suggestions for `typed` from `known` commands, sorted by
|
|
34
|
+
* (prefixMatch desc, distance asc, normalizedDistance asc).
|
|
35
|
+
*/
|
|
36
|
+
export declare function suggestCommands(typed: string, known: ReadonlyArray<string>, opts?: {
|
|
37
|
+
topN?: number;
|
|
38
|
+
maxDistance?: number;
|
|
39
|
+
}): Suggestion[];
|
|
40
|
+
/**
|
|
41
|
+
* Append a missed-verb to the heat-map ledger so future releases can
|
|
42
|
+
* pre-add as a real alias. Never throws; best-effort write only.
|
|
43
|
+
*/
|
|
44
|
+
export declare function logMissedAlias(repoRoot: string, verb: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Print a friendly suggestion block to stderr. Returns the suggested
|
|
47
|
+
* command if there's a clear winner (distance ≤ 2), else null.
|
|
48
|
+
*/
|
|
49
|
+
export declare function printSuggestions(typed: string, suggestions: Suggestion[]): string | null;
|
|
50
|
+
//# sourceMappingURL=alias_resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias_resolver.d.ts","sourceRoot":"","sources":["../src/alias_resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAyBhE;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,WAAW,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,EAC5B,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,UAAU,EAAE,CAoBd;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAQnE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,IAAI,CA0BxF"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.49.0 — AUTO-ALIAS RESOLVER.
|
|
3
|
+
*
|
|
4
|
+
* Wild idea: the WIRING LAG class isn't just "feature shipped but CLI verb
|
|
5
|
+
* missing" — it's ALSO "feature shipped but user typed a NATURAL ALIAS
|
|
6
|
+
* that doesn't exist". v2.48 shipped `mneme dev_tooling detect`; user
|
|
7
|
+
* tried `mneme dev` / `mneme detect` / `mneme tool_detect` and got
|
|
8
|
+
* cryptic `unknown command`. That's wiring lag at the keyboard surface.
|
|
9
|
+
*
|
|
10
|
+
* This module kills the class STRUCTURALLY:
|
|
11
|
+
* 1. Levenshtein-based fuzzy match against all known top-level verbs
|
|
12
|
+
* 2. Top-3 suggestions printed when user types unknown verb
|
|
13
|
+
* 3. Heat-map ledger of misses → next release adds them as real aliases
|
|
14
|
+
* 4. Intent-router fallback for natural-language phrases
|
|
15
|
+
*
|
|
16
|
+
* Pure deterministic except for the file-write to the heat-map ledger.
|
|
17
|
+
* Defensive — never throws.
|
|
18
|
+
*/
|
|
19
|
+
import { existsSync, mkdirSync, appendFileSync } from "node:fs";
|
|
20
|
+
import { join } from "node:path";
|
|
21
|
+
/**
|
|
22
|
+
* Classic Levenshtein with single-char + transposition + similar-key
|
|
23
|
+
* discounts. O(m·n) DP — fine for command names (typically ≤ 20 chars).
|
|
24
|
+
*/
|
|
25
|
+
export function levenshteinDistance(a, b) {
|
|
26
|
+
if (!a || !b)
|
|
27
|
+
return Math.max(a?.length ?? 0, b?.length ?? 0);
|
|
28
|
+
a = a.toLowerCase();
|
|
29
|
+
b = b.toLowerCase();
|
|
30
|
+
if (a === b)
|
|
31
|
+
return 0;
|
|
32
|
+
const m = a.length;
|
|
33
|
+
const n = b.length;
|
|
34
|
+
const d = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
35
|
+
for (let i = 0; i <= m; i++)
|
|
36
|
+
d[i][0] = i;
|
|
37
|
+
for (let j = 0; j <= n; j++)
|
|
38
|
+
d[0][j] = j;
|
|
39
|
+
for (let i = 1; i <= m; i++) {
|
|
40
|
+
for (let j = 1; j <= n; j++) {
|
|
41
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
42
|
+
d[i][j] = Math.min(d[i - 1][j] + 1, // deletion
|
|
43
|
+
d[i][j - 1] + 1, // insertion
|
|
44
|
+
d[i - 1][j - 1] + cost);
|
|
45
|
+
// Damerau transposition discount
|
|
46
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
47
|
+
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return d[m][n];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Return top-N suggestions for `typed` from `known` commands, sorted by
|
|
55
|
+
* (prefixMatch desc, distance asc, normalizedDistance asc).
|
|
56
|
+
*/
|
|
57
|
+
export function suggestCommands(typed, known, opts = {}) {
|
|
58
|
+
const topN = opts.topN ?? 5;
|
|
59
|
+
const maxDistance = opts.maxDistance ?? 10;
|
|
60
|
+
const t = (typed ?? "").toLowerCase();
|
|
61
|
+
if (!t)
|
|
62
|
+
return [];
|
|
63
|
+
const scored = [];
|
|
64
|
+
for (const cmd of known) {
|
|
65
|
+
const c = cmd.toLowerCase();
|
|
66
|
+
const dist = levenshteinDistance(t, c);
|
|
67
|
+
if (dist > maxDistance)
|
|
68
|
+
continue;
|
|
69
|
+
const prefixMatch = c.startsWith(t) || t.startsWith(c);
|
|
70
|
+
const normalizedDistance = c.length === 0 ? 1 : dist / Math.max(c.length, t.length);
|
|
71
|
+
scored.push({ command: cmd, distance: dist, prefixMatch, normalizedDistance });
|
|
72
|
+
}
|
|
73
|
+
scored.sort((a, b) => {
|
|
74
|
+
if (a.prefixMatch !== b.prefixMatch)
|
|
75
|
+
return a.prefixMatch ? -1 : 1;
|
|
76
|
+
if (a.distance !== b.distance)
|
|
77
|
+
return a.distance - b.distance;
|
|
78
|
+
return a.normalizedDistance - b.normalizedDistance;
|
|
79
|
+
});
|
|
80
|
+
return scored.slice(0, topN);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Append a missed-verb to the heat-map ledger so future releases can
|
|
84
|
+
* pre-add as a real alias. Never throws; best-effort write only.
|
|
85
|
+
*/
|
|
86
|
+
export function logMissedAlias(repoRoot, verb) {
|
|
87
|
+
if (!repoRoot || !verb)
|
|
88
|
+
return;
|
|
89
|
+
try {
|
|
90
|
+
const dir = join(repoRoot, ".mneme");
|
|
91
|
+
if (!existsSync(dir))
|
|
92
|
+
mkdirSync(dir, { recursive: true });
|
|
93
|
+
const path = join(dir, "alias_misses.jsonl");
|
|
94
|
+
appendFileSync(path, JSON.stringify({ at: new Date().toISOString(), verb }) + "\n");
|
|
95
|
+
}
|
|
96
|
+
catch { /* defensive */ }
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Print a friendly suggestion block to stderr. Returns the suggested
|
|
100
|
+
* command if there's a clear winner (distance ≤ 2), else null.
|
|
101
|
+
*/
|
|
102
|
+
export function printSuggestions(typed, suggestions) {
|
|
103
|
+
if (suggestions.length === 0) {
|
|
104
|
+
process.stderr.write(`\n❓ Unknown command: ${JSON.stringify(typed)}\n`);
|
|
105
|
+
process.stderr.write(` Run \`mneme --help\` to see all available commands.\n\n`);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const winner = suggestions[0];
|
|
109
|
+
if (winner.distance <= 2 || winner.prefixMatch) {
|
|
110
|
+
process.stderr.write(`\n❓ Unknown command: ${JSON.stringify(typed)}\n\n`);
|
|
111
|
+
process.stderr.write(` Did you mean \`mneme ${winner.command}\`?\n`);
|
|
112
|
+
if (suggestions.length > 1) {
|
|
113
|
+
process.stderr.write(`\n Other closest matches:\n`);
|
|
114
|
+
for (const s of suggestions.slice(1, 4)) {
|
|
115
|
+
process.stderr.write(` • mneme ${s.command} (distance ${s.distance})\n`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
process.stderr.write(`\n Tip: set MNEME_AUTO_ALIAS=1 to auto-run the best match next time.\n\n`);
|
|
119
|
+
return winner.command;
|
|
120
|
+
}
|
|
121
|
+
process.stderr.write(`\n❓ Unknown command: ${JSON.stringify(typed)}\n`);
|
|
122
|
+
process.stderr.write(` Closest matches:\n`);
|
|
123
|
+
for (const s of suggestions.slice(0, 4)) {
|
|
124
|
+
process.stderr.write(` • mneme ${s.command} (distance ${s.distance})\n`);
|
|
125
|
+
}
|
|
126
|
+
process.stderr.write(`\n Run \`mneme --help\` for the full command list.\n\n`);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=alias_resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias_resolver.js","sourceRoot":"","sources":["../src/alias_resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuIA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuIA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA6yJvD"}
|
package/dist/index.js
CHANGED
|
@@ -4526,6 +4526,73 @@ export async function run(argv) {
|
|
|
4526
4526
|
registerArgusCommand(program);
|
|
4527
4527
|
// v2.46.0 — NEMESIS (Anti-Identity-Lie Engine + EU AI Act Article 50)
|
|
4528
4528
|
registerNemesisCommand(program);
|
|
4529
|
+
// v2.49.0 — B5 MULTI-ALIAS + F7 probe-coverage CLI + AUTO-ALIAS RESOLVER.
|
|
4530
|
+
// Closes wiring-lag-of-wiring-lag-fix: v2.48 shipped one verb; users
|
|
4531
|
+
// typed natural aliases (dev/detect/tool_detect) — all unknown. v2.49
|
|
4532
|
+
// wires every alias to the same handler.
|
|
4533
|
+
const devToolingDetect = async (path) => {
|
|
4534
|
+
try {
|
|
4535
|
+
const core = await import("@mneme-ai/core");
|
|
4536
|
+
const r = core.autoInit.detectDevTooling(path);
|
|
4537
|
+
process.stdout.write(JSON.stringify({ ok: true, path, result: r }, null, 2) + "\n");
|
|
4538
|
+
}
|
|
4539
|
+
catch (e) {
|
|
4540
|
+
process.stdout.write(JSON.stringify({ ok: false, error: e.message }) + "\n");
|
|
4541
|
+
process.exitCode = 1;
|
|
4542
|
+
}
|
|
4543
|
+
};
|
|
4544
|
+
// Aliases: `mneme detect`, `mneme tool_detect`, `mneme dev` (with no
|
|
4545
|
+
// sub) — all route to dev-tooling detect on current CWD.
|
|
4546
|
+
for (const alias of ["detect", "tool_detect"]) {
|
|
4547
|
+
program
|
|
4548
|
+
.command(alias)
|
|
4549
|
+
.description(`v2.49 alias for \`mneme dev_tooling detect\` — detect AI-dev scratch folder vs customer git repo.`)
|
|
4550
|
+
.option("--path <dir>", "Folder to check (default cwd).")
|
|
4551
|
+
.action(async (opts) => devToolingDetect(opts.path ?? process.cwd()));
|
|
4552
|
+
}
|
|
4553
|
+
// `mneme dev` parent — has `detect` subcommand AND default action.
|
|
4554
|
+
const devParent = program
|
|
4555
|
+
.command("dev")
|
|
4556
|
+
.description("v2.49 short alias for `mneme dev_tooling` — short-form access to DEV-TOOLING DETECTOR + RETROACTIVE CLEANSE.")
|
|
4557
|
+
.option("--path <dir>", "Folder to check (default cwd).")
|
|
4558
|
+
.action(async (opts) => devToolingDetect(opts.path ?? process.cwd()));
|
|
4559
|
+
devParent.command("detect")
|
|
4560
|
+
.description("Detect AI-dev folder.")
|
|
4561
|
+
.option("--path <dir>", "Folder.")
|
|
4562
|
+
.action(async (opts) => devToolingDetect(opts.path ?? process.cwd()));
|
|
4563
|
+
// v2.49.0 — F7 surface: `mneme release check` + `mneme probe coverage`.
|
|
4564
|
+
const releaseParent = program.command("release").description("v2.49 — release-time gates including MANDATORY probe-coverage check.");
|
|
4565
|
+
releaseParent.command("check")
|
|
4566
|
+
.description("Run the probe-coverage gate (refuses tag when new tool lacks TRUTH GATE probe binding).")
|
|
4567
|
+
.action(async () => {
|
|
4568
|
+
try {
|
|
4569
|
+
const core = await import("@mneme-ai/core");
|
|
4570
|
+
const r = core.releaseGate.crossCheckFromDisk(process.cwd());
|
|
4571
|
+
process.stdout.write(JSON.stringify(r, null, 2) + "\n");
|
|
4572
|
+
if (!r.ok)
|
|
4573
|
+
process.exitCode = 1;
|
|
4574
|
+
}
|
|
4575
|
+
catch (e) {
|
|
4576
|
+
process.stdout.write(JSON.stringify({ ok: false, error: e.message }) + "\n");
|
|
4577
|
+
process.exitCode = 1;
|
|
4578
|
+
}
|
|
4579
|
+
});
|
|
4580
|
+
const probeParent = program.command("probe").description("v2.49 — TRUTH GATE probe utilities.");
|
|
4581
|
+
probeParent.command("coverage")
|
|
4582
|
+
.description("Cross-check tool catalog vs claim catalog; report uncovered tools.")
|
|
4583
|
+
.action(async () => {
|
|
4584
|
+
try {
|
|
4585
|
+
const core = await import("@mneme-ai/core");
|
|
4586
|
+
const r = core.releaseGate.crossCheckFromDisk(process.cwd());
|
|
4587
|
+
process.stdout.write(JSON.stringify(r, null, 2) + "\n");
|
|
4588
|
+
if (!r.ok)
|
|
4589
|
+
process.exitCode = 1;
|
|
4590
|
+
}
|
|
4591
|
+
catch (e) {
|
|
4592
|
+
process.stdout.write(JSON.stringify({ ok: false, error: e.message }) + "\n");
|
|
4593
|
+
process.exitCode = 1;
|
|
4594
|
+
}
|
|
4595
|
+
});
|
|
4529
4596
|
// v2.48.0 — Top-level `mneme dev_tooling` CLI (B5 fix: WIRING LAG class).
|
|
4530
4597
|
// v2.45 shipped detectDevTooling() in core; v2.47 exposed it as MCP +
|
|
4531
4598
|
// `mneme nemesis detect_tooling` subcommand — but users expect the
|
|
@@ -4753,8 +4820,45 @@ export async function run(argv) {
|
|
|
4753
4820
|
}
|
|
4754
4821
|
}
|
|
4755
4822
|
}
|
|
4756
|
-
//
|
|
4823
|
+
// v2.49.0 — AUTO-ALIAS RESOLVER. Before bailing with a cryptic
|
|
4824
|
+
// "unknown command" error, intercept the message + run Levenshtein
|
|
4825
|
+
// fuzzy match against all registered top-level verbs + print
|
|
4826
|
+
// suggestions. Closes the wiring-lag-at-keyboard-surface class.
|
|
4757
4827
|
restoreWriteErr();
|
|
4828
|
+
const unknownMatch = /unknown command (?:'|")([^'"]+)(?:'|")/i.exec(message);
|
|
4829
|
+
if (unknownMatch && unknownMatch[1]) {
|
|
4830
|
+
const typed = unknownMatch[1];
|
|
4831
|
+
try {
|
|
4832
|
+
const { suggestCommands, printSuggestions, logMissedAlias } = await import("./alias_resolver.js");
|
|
4833
|
+
// Gather all registered top-level command names.
|
|
4834
|
+
const known = [];
|
|
4835
|
+
for (const c of program.commands) {
|
|
4836
|
+
const name = (c.name?.() ?? c._name);
|
|
4837
|
+
if (name)
|
|
4838
|
+
known.push(name);
|
|
4839
|
+
}
|
|
4840
|
+
const suggestions = suggestCommands(typed, known, { topN: 5 });
|
|
4841
|
+
const winner = printSuggestions(typed, suggestions);
|
|
4842
|
+
try {
|
|
4843
|
+
logMissedAlias(process.cwd(), typed);
|
|
4844
|
+
}
|
|
4845
|
+
catch { /* */ }
|
|
4846
|
+
// Optional auto-run via env var
|
|
4847
|
+
if (winner && process.env["MNEME_AUTO_ALIAS"] === "1") {
|
|
4848
|
+
process.stderr.write(`\n→ MNEME_AUTO_ALIAS=1 set — auto-running \`mneme ${winner}\`...\n\n`);
|
|
4849
|
+
const restArgs = argv.slice(argv.findIndex((a) => a === typed) + 1);
|
|
4850
|
+
try {
|
|
4851
|
+
await program.parseAsync(["node", "mneme", winner, ...restArgs]);
|
|
4852
|
+
process.exit(0);
|
|
4853
|
+
}
|
|
4854
|
+
catch {
|
|
4855
|
+
process.exit(1);
|
|
4856
|
+
}
|
|
4857
|
+
}
|
|
4858
|
+
process.exit(1);
|
|
4859
|
+
}
|
|
4860
|
+
catch { /* fall through to generic error */ }
|
|
4861
|
+
}
|
|
4758
4862
|
ui.error(message);
|
|
4759
4863
|
process.exit(1);
|
|
4760
4864
|
}
|