claude-memory-explorer 0.1.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/.claude-plugin/plugin.json +19 -0
- package/LICENSE +21 -0
- package/README.md +177 -0
- package/dist/cli/commands/dedupe.d.ts +1 -0
- package/dist/cli/commands/dedupe.js +187 -0
- package/dist/cli/commands/dedupe.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +1 -0
- package/dist/cli/commands/doctor.js +177 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/lint.d.ts +1 -0
- package/dist/cli/commands/lint.js +139 -0
- package/dist/cli/commands/lint.js.map +1 -0
- package/dist/cli/commands/list.d.ts +1 -0
- package/dist/cli/commands/list.js +97 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +1 -0
- package/dist/cli/commands/mcp.js +105 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/merge.d.ts +1 -0
- package/dist/cli/commands/merge.js +111 -0
- package/dist/cli/commands/merge.js.map +1 -0
- package/dist/cli/commands/promote.d.ts +1 -0
- package/dist/cli/commands/promote.js +157 -0
- package/dist/cli/commands/promote.js.map +1 -0
- package/dist/cli/commands/tui.d.ts +1 -0
- package/dist/cli/commands/tui.js +60 -0
- package/dist/cli/commands/tui.js.map +1 -0
- package/dist/cli/commands/undo.d.ts +1 -0
- package/dist/cli/commands/undo.js +157 -0
- package/dist/cli/commands/undo.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +85 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/tui/App.d.ts +8 -0
- package/dist/cli/tui/App.js +333 -0
- package/dist/cli/tui/App.js.map +1 -0
- package/dist/core/apply.d.ts +27 -0
- package/dist/core/apply.js +191 -0
- package/dist/core/apply.js.map +1 -0
- package/dist/core/claudeMd.d.ts +27 -0
- package/dist/core/claudeMd.js +103 -0
- package/dist/core/claudeMd.js.map +1 -0
- package/dist/core/dedupe.d.ts +78 -0
- package/dist/core/dedupe.js +212 -0
- package/dist/core/dedupe.js.map +1 -0
- package/dist/core/doctor.d.ts +35 -0
- package/dist/core/doctor.js +106 -0
- package/dist/core/doctor.js.map +1 -0
- package/dist/core/journal.d.ts +31 -0
- package/dist/core/journal.js +64 -0
- package/dist/core/journal.js.map +1 -0
- package/dist/core/lint.d.ts +26 -0
- package/dist/core/lint.js +254 -0
- package/dist/core/lint.js.map +1 -0
- package/dist/core/memoryIndex.d.ts +42 -0
- package/dist/core/memoryIndex.js +81 -0
- package/dist/core/memoryIndex.js.map +1 -0
- package/dist/core/merge.d.ts +19 -0
- package/dist/core/merge.js +58 -0
- package/dist/core/merge.js.map +1 -0
- package/dist/core/parse.d.ts +2 -0
- package/dist/core/parse.js +84 -0
- package/dist/core/parse.js.map +1 -0
- package/dist/core/plan.d.ts +34 -0
- package/dist/core/plan.js +85 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/core/promote.d.ts +29 -0
- package/dist/core/promote.js +103 -0
- package/dist/core/promote.js.map +1 -0
- package/dist/core/scan.d.ts +16 -0
- package/dist/core/scan.js +81 -0
- package/dist/core/scan.js.map +1 -0
- package/dist/core/types.d.ts +36 -0
- package/dist/core/types.js +4 -0
- package/dist/core/types.js.map +1 -0
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.js +211 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +71 -0
- package/skills/curate-memory/SKILL.md +60 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// `memex tui` — interactive three-pane browser.
|
|
2
|
+
function parseArgs(argv) {
|
|
3
|
+
const out = { help: false };
|
|
4
|
+
for (let i = 0; i < argv.length; i++) {
|
|
5
|
+
const a = argv[i];
|
|
6
|
+
switch (a) {
|
|
7
|
+
case "--root":
|
|
8
|
+
out.root = argv[++i];
|
|
9
|
+
break;
|
|
10
|
+
case "--help":
|
|
11
|
+
case "-h":
|
|
12
|
+
out.help = true;
|
|
13
|
+
break;
|
|
14
|
+
default:
|
|
15
|
+
throw new Error(`unknown flag: ${a}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
const HELP = `memex tui — interactive three-pane browser
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
memex tui [--root PATH]
|
|
24
|
+
|
|
25
|
+
Keybindings (shown also via ? in-app):
|
|
26
|
+
↑/↓ Navigate within a pane
|
|
27
|
+
Tab / ←/→ Switch pane
|
|
28
|
+
/ Search across all memories
|
|
29
|
+
d Dedupe view (cross-project duplicate clusters)
|
|
30
|
+
l Lint view (structural issues)
|
|
31
|
+
? Help
|
|
32
|
+
Esc Back to browse
|
|
33
|
+
q Quit
|
|
34
|
+
|
|
35
|
+
Read-only by design. Mutating actions (merge, promote, undo) stay on
|
|
36
|
+
the CLI, where they have dry-run + journal + undo by default.
|
|
37
|
+
`;
|
|
38
|
+
export async function runTui(argv) {
|
|
39
|
+
let args;
|
|
40
|
+
try {
|
|
41
|
+
args = parseArgs(argv);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
process.stderr.write(`memex tui: ${err instanceof Error ? err.message : String(err)}\n\n${HELP}`);
|
|
45
|
+
return 2;
|
|
46
|
+
}
|
|
47
|
+
if (args.help) {
|
|
48
|
+
process.stdout.write(HELP);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
// Lazy-import ink so the rest of memex doesn't pay the React startup cost
|
|
52
|
+
// when running CLI subcommands.
|
|
53
|
+
const { render } = await import("ink");
|
|
54
|
+
const { App } = await import("../tui/App.js");
|
|
55
|
+
const { createElement } = await import("react");
|
|
56
|
+
const instance = render(createElement(App, { projectsRoot: args.root }));
|
|
57
|
+
await instance.waitUntilExit();
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=tui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui.js","sourceRoot":"","sources":["../../../src/cli/commands/tui.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAOhD,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,GAAG,GAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,QAAQ,CAAC,EAAE,CAAC;YACV,KAAK,QAAQ;gBACX,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrB,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;gBAChB,MAAM;YACR;gBACE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;CAiBZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAc;IACzC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAClG,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,0EAA0E;IAC1E,gCAAgC;IAChC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IAEhD,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACzE,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;IAC/B,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runUndo(argv: string[]): number;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// `memex undo` — revert the most-recent applied plan, or list the journal.
|
|
2
|
+
//
|
|
3
|
+
// Exit codes:
|
|
4
|
+
// 0 success (or nothing to undo, with informative message)
|
|
5
|
+
// 1 undo failed mid-flight
|
|
6
|
+
// 2 bad usage
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { relative } from "node:path";
|
|
9
|
+
import { listJournal, latestJournalEntry } from "../../core/journal.js";
|
|
10
|
+
import { undoPlan } from "../../core/apply.js";
|
|
11
|
+
function parseArgs(argv) {
|
|
12
|
+
const out = { list: false, json: false, dryRun: false, help: false };
|
|
13
|
+
for (let i = 0; i < argv.length; i++) {
|
|
14
|
+
const a = argv[i];
|
|
15
|
+
switch (a) {
|
|
16
|
+
case "--list":
|
|
17
|
+
out.list = true;
|
|
18
|
+
break;
|
|
19
|
+
case "--json":
|
|
20
|
+
out.json = true;
|
|
21
|
+
break;
|
|
22
|
+
case "--id":
|
|
23
|
+
out.id = argv[++i];
|
|
24
|
+
break;
|
|
25
|
+
case "--journal-dir":
|
|
26
|
+
out.journalDir = argv[++i];
|
|
27
|
+
break;
|
|
28
|
+
case "--dry-run":
|
|
29
|
+
out.dryRun = true;
|
|
30
|
+
break;
|
|
31
|
+
case "--help":
|
|
32
|
+
case "-h":
|
|
33
|
+
out.help = true;
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
throw new Error(`unknown flag: ${a}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
const HELP = `memex undo — revert the most recent applied plan
|
|
42
|
+
|
|
43
|
+
Usage:
|
|
44
|
+
memex undo Revert the most recent applied plan
|
|
45
|
+
memex undo --id <plan-id> Revert a specific plan (warn if not most recent)
|
|
46
|
+
memex undo --dry-run Print what would be undone, change nothing
|
|
47
|
+
memex undo --list Show the journal (newest first)
|
|
48
|
+
memex undo --list --json Journal as JSON
|
|
49
|
+
|
|
50
|
+
Flags:
|
|
51
|
+
--id <plan-id> Revert a specific plan instead of the latest
|
|
52
|
+
--dry-run Print what would change, write nothing
|
|
53
|
+
--list Show the journal (newest first)
|
|
54
|
+
--json (with --list) emit journal as JSON
|
|
55
|
+
--journal-dir PATH Override journal location (default: ~/.claude/.memex/log/)
|
|
56
|
+
|
|
57
|
+
Exit codes:
|
|
58
|
+
0 success, or nothing to undo (informative message)
|
|
59
|
+
1 undo failed mid-flight (run --list to see state)
|
|
60
|
+
2 bad usage
|
|
61
|
+
|
|
62
|
+
Journal location: ~/.claude/.memex/log/
|
|
63
|
+
`;
|
|
64
|
+
function shortPath(p) {
|
|
65
|
+
const home = homedir();
|
|
66
|
+
if (p.startsWith(home))
|
|
67
|
+
return "~" + p.slice(home.length);
|
|
68
|
+
try {
|
|
69
|
+
const r = relative(process.cwd(), p);
|
|
70
|
+
return r.length < p.length ? r : p;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return p;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function summarizeEntry(e) {
|
|
77
|
+
const opCount = e.plan.ops.length;
|
|
78
|
+
const ok = e.ops.filter((a) => a.result === "success").length;
|
|
79
|
+
const fail = e.ops.filter((a) => a.result === "failure").length;
|
|
80
|
+
const undoMark = e.undoOf ? ` (undo of ${e.undoOf})` : "";
|
|
81
|
+
return `${e.plan.id} ${e.status.padEnd(8)} ${e.plan.label.padEnd(28)} ${opCount} ops (${ok}✓ ${fail}✗)${undoMark}`;
|
|
82
|
+
}
|
|
83
|
+
export function runUndo(argv) {
|
|
84
|
+
let args;
|
|
85
|
+
try {
|
|
86
|
+
args = parseArgs(argv);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
process.stderr.write(`memex undo: ${err instanceof Error ? err.message : String(err)}\n\n${HELP}`);
|
|
90
|
+
return 2;
|
|
91
|
+
}
|
|
92
|
+
if (args.help) {
|
|
93
|
+
process.stdout.write(HELP);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
const journalOpts = args.journalDir ? { journalDir: args.journalDir } : {};
|
|
97
|
+
// --list mode
|
|
98
|
+
if (args.list) {
|
|
99
|
+
const entries = listJournal(journalOpts);
|
|
100
|
+
if (args.json) {
|
|
101
|
+
process.stdout.write(`${JSON.stringify(entries, null, 2)}\n`);
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
if (entries.length === 0) {
|
|
105
|
+
process.stdout.write("(journal is empty)\n");
|
|
106
|
+
return 0;
|
|
107
|
+
}
|
|
108
|
+
process.stdout.write("Journal (newest first):\n");
|
|
109
|
+
for (const e of entries)
|
|
110
|
+
process.stdout.write(` ${summarizeEntry(e)}\n`);
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
// Find target entry
|
|
114
|
+
const target = args.id ? null : latestJournalEntry(journalOpts);
|
|
115
|
+
if (!args.id && !target) {
|
|
116
|
+
process.stdout.write("Nothing to undo — journal is empty.\n");
|
|
117
|
+
return 0;
|
|
118
|
+
}
|
|
119
|
+
// Dry-run shows what would happen without writing.
|
|
120
|
+
if (args.dryRun) {
|
|
121
|
+
const t = args.id
|
|
122
|
+
? listJournal(journalOpts).find((e) => e.plan.id === args.id)
|
|
123
|
+
: target;
|
|
124
|
+
if (!t) {
|
|
125
|
+
process.stderr.write(`memex undo: no journal entry with id "${args.id}"\n`);
|
|
126
|
+
return 2;
|
|
127
|
+
}
|
|
128
|
+
process.stdout.write(`Would undo: ${t.plan.label} (${t.plan.id})\n`);
|
|
129
|
+
const successOps = t.ops.filter((a) => a.result === "success");
|
|
130
|
+
process.stdout.write(` ${successOps.length} successful op(s) would be reversed:\n`);
|
|
131
|
+
for (const a of successOps.slice().reverse()) {
|
|
132
|
+
const inv = a.inverse;
|
|
133
|
+
const pathInfo = "path" in inv ? ` ${shortPath(inv.path)}` : "";
|
|
134
|
+
process.stdout.write(` ${inv.kind}${pathInfo}\n`);
|
|
135
|
+
}
|
|
136
|
+
return 0;
|
|
137
|
+
}
|
|
138
|
+
const { undone, newEntry } = undoPlan(args.id ?? "latest", {
|
|
139
|
+
...journalOpts,
|
|
140
|
+
onProgress: (m) => process.stdout.write(`${m}\n`),
|
|
141
|
+
});
|
|
142
|
+
if (!undone) {
|
|
143
|
+
process.stderr.write(`memex undo: no journal entry with id "${args.id}"\n`);
|
|
144
|
+
return 2;
|
|
145
|
+
}
|
|
146
|
+
if (!newEntry) {
|
|
147
|
+
process.stdout.write(`Plan ${undone.plan.id} had no successful ops — nothing to reverse.\n`);
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
if (newEntry.status === "complete") {
|
|
151
|
+
process.stdout.write(`✓ Undone: ${undone.plan.label} (was ${undone.plan.id}; recorded ${newEntry.plan.id})\n`);
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
process.stderr.write(`✗ Undo failed mid-flight. Journal at ~/.claude/.memex/log/ — run \`memex undo --list\` for state.\n`);
|
|
155
|
+
return 1;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=undo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"undo.js","sourceRoot":"","sources":["../../../src/cli/commands/undo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Entrypoint for the `memex` CLI. Dispatches subcommands to keep the bin small.
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "..", "package.json"), "utf8"));
|
|
8
|
+
const HELP = `memex ${pkg.version} — Claude Code memory curator
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
memex <command> [options]
|
|
12
|
+
|
|
13
|
+
Commands:
|
|
14
|
+
list List memories across all projects
|
|
15
|
+
lint Report structural problems with memory files
|
|
16
|
+
doctor Health snapshot of your memory tree (run weekly)
|
|
17
|
+
dedupe Find duplicate memories across projects
|
|
18
|
+
merge Collapse a duplicate cluster down to its representative
|
|
19
|
+
promote Promote a memory to ~/.claude/CLAUDE.md as a managed block
|
|
20
|
+
undo Revert the most recent applied plan (memex's mutation log)
|
|
21
|
+
tui Interactive three-pane browser
|
|
22
|
+
mcp Run as an MCP server over stdio (for Claude Code plugins)
|
|
23
|
+
--version Print version
|
|
24
|
+
--help Show this help
|
|
25
|
+
`;
|
|
26
|
+
async function main(argv) {
|
|
27
|
+
const [cmd, ...rest] = argv;
|
|
28
|
+
if (!cmd || cmd === "--help" || cmd === "-h" || cmd === "help") {
|
|
29
|
+
process.stdout.write(HELP);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
if (cmd === "--version" || cmd === "-v") {
|
|
33
|
+
process.stdout.write(`${pkg.version}\n`);
|
|
34
|
+
return 0;
|
|
35
|
+
}
|
|
36
|
+
if (cmd === "list") {
|
|
37
|
+
const { runList } = await import("./commands/list.js");
|
|
38
|
+
return runList(rest);
|
|
39
|
+
}
|
|
40
|
+
if (cmd === "lint") {
|
|
41
|
+
const { runLint } = await import("./commands/lint.js");
|
|
42
|
+
return runLint(rest);
|
|
43
|
+
}
|
|
44
|
+
if (cmd === "doctor") {
|
|
45
|
+
const { runDoctorCli } = await import("./commands/doctor.js");
|
|
46
|
+
return runDoctorCli(rest);
|
|
47
|
+
}
|
|
48
|
+
if (cmd === "dedupe") {
|
|
49
|
+
const { runDedupe } = await import("./commands/dedupe.js");
|
|
50
|
+
return runDedupe(rest);
|
|
51
|
+
}
|
|
52
|
+
if (cmd === "undo") {
|
|
53
|
+
const { runUndo } = await import("./commands/undo.js");
|
|
54
|
+
return runUndo(rest);
|
|
55
|
+
}
|
|
56
|
+
if (cmd === "merge") {
|
|
57
|
+
const { runMerge } = await import("./commands/merge.js");
|
|
58
|
+
return runMerge(rest);
|
|
59
|
+
}
|
|
60
|
+
if (cmd === "promote") {
|
|
61
|
+
const { runPromote } = await import("./commands/promote.js");
|
|
62
|
+
return runPromote(rest);
|
|
63
|
+
}
|
|
64
|
+
if (cmd === "tui") {
|
|
65
|
+
const { runTui } = await import("./commands/tui.js");
|
|
66
|
+
return runTui(rest);
|
|
67
|
+
}
|
|
68
|
+
if (cmd === "mcp") {
|
|
69
|
+
const { runMcp } = await import("./commands/mcp.js");
|
|
70
|
+
return runMcp(rest);
|
|
71
|
+
}
|
|
72
|
+
process.stderr.write(`memex: unknown command "${cmd}"\n\n${HELP}`);
|
|
73
|
+
return 2;
|
|
74
|
+
}
|
|
75
|
+
// Setting process.exitCode (instead of calling process.exit) lets Node drain
|
|
76
|
+
// stdout/stderr buffers before the process terminates. Calling process.exit()
|
|
77
|
+
// with a piped stdout truncates output mid-write — broke `memex list --json |
|
|
78
|
+
// jq` on large outputs (~275 KB stress fixture).
|
|
79
|
+
main(process.argv.slice(2)).then((code) => {
|
|
80
|
+
process.exitCode = code;
|
|
81
|
+
}, (err) => {
|
|
82
|
+
process.stderr.write(`memex: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
83
|
+
process.exitCode = 1;
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProjectMemoryDir } from "../../core/types.js";
|
|
2
|
+
interface AppProps {
|
|
3
|
+
projectsRoot?: string;
|
|
4
|
+
/** Initial data injection — used by tests to avoid disk reads. */
|
|
5
|
+
initialProjects?: ProjectMemoryDir[];
|
|
6
|
+
}
|
|
7
|
+
export declare function App({ projectsRoot, initialProjects }: AppProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|