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.
- package/dist/commands/ui.d.ts +16 -0
- package/dist/commands/ui.d.ts.map +1 -0
- package/dist/commands/ui.js +114 -0
- package/dist/commands/ui.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/ui/tui_core.d.ts +63 -0
- package/dist/ui/tui_core.d.ts.map +1 -0
- package/dist/ui/tui_core.js +158 -0
- package/dist/ui/tui_core.js.map +1 -0
- package/dist/ui/tui_render.d.ts +11 -0
- package/dist/ui/tui_render.d.ts.map +1 -0
- package/dist/ui/tui_render.js +107 -0
- package/dist/ui/tui_render.js.map +1 -0
- package/package.json +73 -73
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.77.0 — `mneme ui` : full-screen, arrow-key interactive TUI.
|
|
3
|
+
*
|
|
4
|
+
* Zero-dependency (raw-mode stdin + ANSI), on-brand with Mneme's local-first
|
|
5
|
+
* ethos. Type plain language → the right capability surfaces; ↑↓ to navigate;
|
|
6
|
+
* Enter runs a parameterless command live (or shows how to run a parameterized
|
|
7
|
+
* one); Esc clears the query then quits. New tools appear automatically because
|
|
8
|
+
* the list IS the live MNEME_COMMAND_CATALOG. All UI LOGIC is pure + tested in
|
|
9
|
+
* src/ui/tui_core.ts; this file is just the terminal driver.
|
|
10
|
+
*/
|
|
11
|
+
export interface UiOptions {
|
|
12
|
+
cwd: string;
|
|
13
|
+
version?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function uiCommand(opts: UiOptions): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/commands/ui.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,WAAW,SAAS;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAAE;AAa7D,wBAAsB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF9D"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2.77.0 — `mneme ui` : full-screen, arrow-key interactive TUI.
|
|
3
|
+
*
|
|
4
|
+
* Zero-dependency (raw-mode stdin + ANSI), on-brand with Mneme's local-first
|
|
5
|
+
* ethos. Type plain language → the right capability surfaces; ↑↓ to navigate;
|
|
6
|
+
* Enter runs a parameterless command live (or shows how to run a parameterized
|
|
7
|
+
* one); Esc clears the query then quits. New tools appear automatically because
|
|
8
|
+
* the list IS the live MNEME_COMMAND_CATALOG. All UI LOGIC is pure + tested in
|
|
9
|
+
* src/ui/tui_core.ts; this file is just the terminal driver.
|
|
10
|
+
*/
|
|
11
|
+
import * as readline from "node:readline";
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { initState, reduce, isParameterless, shellArgsFor, loadCatalog } from "../ui/tui_core.js";
|
|
14
|
+
import { renderFrame, stripAnsi } from "../ui/tui_render.js";
|
|
15
|
+
const ALT_ON = "\x1b[?1049h\x1b[?25l"; // enter alt-screen + hide cursor
|
|
16
|
+
const ALT_OFF = "\x1b[?25h\x1b[?1049l"; // show cursor + leave alt-screen
|
|
17
|
+
const HOME_CLEAR = "\x1b[H\x1b[2J";
|
|
18
|
+
async function loadItems() {
|
|
19
|
+
try {
|
|
20
|
+
const core = await import("@mneme-ai/core");
|
|
21
|
+
return loadCatalog(core.agentManifest?.MNEME_COMMAND_CATALOG ?? []);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function uiCommand(opts) {
|
|
28
|
+
const items = await loadItems();
|
|
29
|
+
// Non-interactive fallback — a TUI needs a real TTY. Print a useful pointer
|
|
30
|
+
// instead of corrupting a pipe / CI log.
|
|
31
|
+
if (!process.stdout.isTTY || !process.stdin.isTTY || items.length === 0) {
|
|
32
|
+
process.stdout.write(items.length === 0
|
|
33
|
+
? "mneme ui: capability catalog unavailable.\n"
|
|
34
|
+
: "mneme ui needs an interactive terminal (TTY).\n • Run it in a real shell, or\n • use `mneme atlas` (static capability map) / `mneme <command> --help`.\n");
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const rows = process.stdout.rows || 24;
|
|
38
|
+
const cols = process.stdout.columns || 80;
|
|
39
|
+
// Reserve ~9 rows for title/search/separators/detail/footer; rest is the list.
|
|
40
|
+
let state = initState(items, Math.max(3, rows - 12));
|
|
41
|
+
const paint = () => {
|
|
42
|
+
const r = process.stdout.rows || 24;
|
|
43
|
+
const c = process.stdout.columns || 80;
|
|
44
|
+
if (state.mode === "browse")
|
|
45
|
+
state = { ...state, listRows: Math.max(3, r - 12) };
|
|
46
|
+
const frame = renderFrame(state, c, r, opts.version ?? "?");
|
|
47
|
+
process.stdout.write(HOME_CLEAR + frame.join("\n"));
|
|
48
|
+
};
|
|
49
|
+
const cleanup = () => {
|
|
50
|
+
try {
|
|
51
|
+
process.stdin.setRawMode?.(false);
|
|
52
|
+
}
|
|
53
|
+
catch { /* */ }
|
|
54
|
+
process.stdin.pause();
|
|
55
|
+
process.stdout.write(ALT_OFF);
|
|
56
|
+
};
|
|
57
|
+
// Run a parameterless `mneme <verb>` live; capture output into the pane.
|
|
58
|
+
const runItem = (item) => {
|
|
59
|
+
if (!isParameterless(item)) {
|
|
60
|
+
state = { ...state, mode: "output", outputTitle: `${item.command} (needs arguments)`, output: `This capability takes arguments, so it can't be run blind from the menu.\n\n` +
|
|
61
|
+
`Run it yourself:\n ${item.command}\n\n` +
|
|
62
|
+
(item.when ? `When to use:\n ${item.when}\n` : ""),
|
|
63
|
+
};
|
|
64
|
+
paint();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const args = shellArgsFor(item);
|
|
68
|
+
process.stdout.write(HOME_CLEAR + `\x1b[1m▶ running:\x1b[0m mneme ${args.join(" ")}\n\n(please wait…)`);
|
|
69
|
+
const r = spawnSync(process.execPath, [process.argv[1], ...args], {
|
|
70
|
+
cwd: opts.cwd,
|
|
71
|
+
encoding: "utf8",
|
|
72
|
+
timeout: 60000,
|
|
73
|
+
env: { ...process.env, MNEME_WARMCALL: "0", NO_COLOR: "1" }, // fresh + clean text in the pane
|
|
74
|
+
});
|
|
75
|
+
const out = [r.stdout, r.stderr].filter(Boolean).join("\n").trim();
|
|
76
|
+
state = { ...state, mode: "output", outputTitle: `mneme ${args.join(" ")} ${r.status === 0 ? "✓" : `(exit ${r.status ?? "?"})`}`,
|
|
77
|
+
output: stripAnsi(out || "(no output)") };
|
|
78
|
+
paint();
|
|
79
|
+
};
|
|
80
|
+
return new Promise((resolve) => {
|
|
81
|
+
process.stdout.write(ALT_ON);
|
|
82
|
+
readline.emitKeypressEvents(process.stdin);
|
|
83
|
+
try {
|
|
84
|
+
process.stdin.setRawMode?.(true);
|
|
85
|
+
}
|
|
86
|
+
catch { /* some terminals */ }
|
|
87
|
+
process.stdin.resume();
|
|
88
|
+
paint();
|
|
89
|
+
const onResize = () => paint();
|
|
90
|
+
process.stdout.on("resize", onResize);
|
|
91
|
+
const finish = () => {
|
|
92
|
+
process.stdin.removeListener("keypress", onKey);
|
|
93
|
+
process.stdout.removeListener("resize", onResize);
|
|
94
|
+
cleanup();
|
|
95
|
+
resolve();
|
|
96
|
+
};
|
|
97
|
+
const onKey = (_str, key) => {
|
|
98
|
+
const k = { name: key?.name, ctrl: !!key?.ctrl, sequence: key?.sequence };
|
|
99
|
+
const { state: next, action } = reduce(state, k);
|
|
100
|
+
state = next;
|
|
101
|
+
if (action.type === "quit") {
|
|
102
|
+
finish();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (action.type === "run") {
|
|
106
|
+
runItem(action.item);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
paint();
|
|
110
|
+
};
|
|
111
|
+
process.stdin.on("keypress", onKey);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/commands/ui.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,CAwyMvD"}
|
package/dist/index.js
CHANGED
|
@@ -114,6 +114,18 @@ export async function run(argv) {
|
|
|
114
114
|
}
|
|
115
115
|
catch { /* fall through to commander on failure */ }
|
|
116
116
|
}
|
|
117
|
+
// v2.77.0 — INTERACTIVE-BY-DEFAULT. Bare `mneme` in a real terminal launches
|
|
118
|
+
// the full-screen TUI (type plain language → run any capability, zero
|
|
119
|
+
// memorization). Non-TTY (pipes / CI / scripts) keep the classic behavior, so
|
|
120
|
+
// nothing automated breaks. `MNEME_NO_UI=1` opts out.
|
|
121
|
+
if (slice.length === 0 && process.stdout.isTTY && process.stdin.isTTY && process.env["MNEME_NO_UI"] !== "1") {
|
|
122
|
+
try {
|
|
123
|
+
const { uiCommand } = await import("./commands/ui.js");
|
|
124
|
+
await uiCommand({ cwd: process.cwd(), version: getVersion() });
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
catch { /* fall through to commander default on any failure */ }
|
|
128
|
+
}
|
|
117
129
|
const program = new Command()
|
|
118
130
|
.name("mneme")
|
|
119
131
|
.description("μνήμη — the memory layer of your codebase. Knows the WHY, the WHAT, the WHERE-IT-BREAKS.")
|
|
@@ -4144,6 +4156,16 @@ export async function run(argv) {
|
|
|
4144
4156
|
// command / 14k token blast-radius without deleting any command.
|
|
4145
4157
|
// Default `mneme --help` still works (backward compat); AI agents
|
|
4146
4158
|
// are told to use these layered surfaces instead.
|
|
4159
|
+
// v2.77.0 — INTERACTIVE TUI. Type plain language → the right capability
|
|
4160
|
+
// surfaces; ↑↓ navigate every command; Enter runs it. Zero memorization.
|
|
4161
|
+
program
|
|
4162
|
+
.command("ui")
|
|
4163
|
+
.aliases(["menu", "tui"])
|
|
4164
|
+
.description("🖥 Interactive full-screen menu — type plain language to search every capability, ↑↓ to navigate, Enter to run. Zero command memorization. (Needs a real terminal.)")
|
|
4165
|
+
.action(async () => {
|
|
4166
|
+
const { uiCommand } = await import("./commands/ui.js");
|
|
4167
|
+
await uiCommand({ cwd: process.cwd(), version: getVersion() });
|
|
4168
|
+
});
|
|
4147
4169
|
program
|
|
4148
4170
|
.command("atlas")
|
|
4149
4171
|
.description("🗺 ATLAS HELP — six-layer discovery (TASTE · BLOOM · HOT · TAGS · INTENT · FULL). AI agents read 200 bytes here instead of 14 KB from --help.")
|