@bubstack/moe-memory 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/.mcp.json +18 -0
- package/README.md +47 -0
- package/agents/search-conversations.md +171 -0
- package/dist/LICENSE +25 -0
- package/dist/cli.d.ts +25 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +125 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-hook-trust.d.ts +4 -0
- package/dist/codex-hook-trust.d.ts.map +1 -0
- package/dist/codex-hook-trust.js +114 -0
- package/dist/codex-hook-trust.js.map +1 -0
- package/dist/codex-support.d.ts +6 -0
- package/dist/codex-support.d.ts.map +1 -0
- package/dist/codex-support.js +29 -0
- package/dist/codex-support.js.map +1 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -0
- package/dist/db.d.ts +103 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +430 -0
- package/dist/db.js.map +1 -0
- package/dist/doctor-cli.d.ts +3 -0
- package/dist/doctor-cli.d.ts.map +1 -0
- package/dist/doctor-cli.js +43 -0
- package/dist/doctor-cli.js.map +1 -0
- package/dist/doctor.d.ts +17 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +98 -0
- package/dist/doctor.js.map +1 -0
- package/dist/embedding-migration.d.ts +73 -0
- package/dist/embedding-migration.d.ts.map +1 -0
- package/dist/embedding-migration.js +120 -0
- package/dist/embedding-migration.js.map +1 -0
- package/dist/embeddings.d.ts +78 -0
- package/dist/embeddings.d.ts.map +1 -0
- package/dist/embeddings.js +180 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/file-lock.d.ts +39 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +91 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/index-cli.d.ts +10 -0
- package/dist/index-cli.d.ts.map +1 -0
- package/dist/index-cli.js +195 -0
- package/dist/index-cli.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +4 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +318 -0
- package/dist/indexer.js.map +1 -0
- package/dist/install-check.d.ts +48 -0
- package/dist/install-check.d.ts.map +1 -0
- package/dist/install-check.js +82 -0
- package/dist/install-check.js.map +1 -0
- package/dist/journal/index.d.ts +5 -0
- package/dist/journal/index.d.ts.map +1 -0
- package/dist/journal/index.js +5 -0
- package/dist/journal/index.js.map +1 -0
- package/dist/journal/legacy-sidecars.d.ts +74 -0
- package/dist/journal/legacy-sidecars.d.ts.map +1 -0
- package/dist/journal/legacy-sidecars.js +151 -0
- package/dist/journal/legacy-sidecars.js.map +1 -0
- package/dist/journal/markdown.d.ts +91 -0
- package/dist/journal/markdown.d.ts.map +1 -0
- package/dist/journal/markdown.js +234 -0
- package/dist/journal/markdown.js.map +1 -0
- package/dist/journal/search.d.ts +91 -0
- package/dist/journal/search.d.ts.map +1 -0
- package/dist/journal/search.js +203 -0
- package/dist/journal/search.js.map +1 -0
- package/dist/journal/store.d.ts +96 -0
- package/dist/journal/store.d.ts.map +1 -0
- package/dist/journal/store.js +270 -0
- package/dist/journal/store.js.map +1 -0
- package/dist/journal-cli.d.ts +19 -0
- package/dist/journal-cli.d.ts.map +1 -0
- package/dist/journal-cli.js +153 -0
- package/dist/journal-cli.js.map +1 -0
- package/dist/logging.d.ts +6 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +20 -0
- package/dist/logging.js.map +1 -0
- package/dist/mcp-server.d.ts +34 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +607 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +445 -0
- package/dist/parser.js.map +1 -0
- package/dist/paths.d.ts +103 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +258 -0
- package/dist/paths.js.map +1 -0
- package/dist/search-cli.d.ts +3 -0
- package/dist/search-cli.d.ts.map +1 -0
- package/dist/search-cli.js +138 -0
- package/dist/search-cli.js.map +1 -0
- package/dist/search.d.ts +36 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +371 -0
- package/dist/search.js.map +1 -0
- package/dist/show-cli.d.ts +3 -0
- package/dist/show-cli.d.ts.map +1 -0
- package/dist/show-cli.js +60 -0
- package/dist/show-cli.js.map +1 -0
- package/dist/show.d.ts +3 -0
- package/dist/show.d.ts.map +1 -0
- package/dist/show.js +984 -0
- package/dist/show.js.map +1 -0
- package/dist/stats-cli.d.ts +3 -0
- package/dist/stats-cli.d.ts.map +1 -0
- package/dist/stats-cli.js +51 -0
- package/dist/stats-cli.js.map +1 -0
- package/dist/stats.d.ts +19 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +116 -0
- package/dist/stats.js.map +1 -0
- package/dist/summarizer.d.ts +83 -0
- package/dist/summarizer.d.ts.map +1 -0
- package/dist/summarizer.js +526 -0
- package/dist/summarizer.js.map +1 -0
- package/dist/summary-sentinel.d.ts +31 -0
- package/dist/summary-sentinel.d.ts.map +1 -0
- package/dist/summary-sentinel.js +80 -0
- package/dist/summary-sentinel.js.map +1 -0
- package/dist/sync-cli.d.ts +15 -0
- package/dist/sync-cli.d.ts.map +1 -0
- package/dist/sync-cli.js +202 -0
- package/dist/sync-cli.js.map +1 -0
- package/dist/sync.d.ts +35 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +204 -0
- package/dist/sync.js.map +1 -0
- package/dist/types.d.ts +125 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/dist/verify.d.ts +30 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +174 -0
- package/dist/verify.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +13 -0
- package/dist/version.js.map +1 -0
- package/hooks/hooks.json +15 -0
- package/package.json +71 -0
- package/prompts/search-agent.md +160 -0
- package/skills/remembering-conversations/MCP-TOOLS.md +147 -0
- package/skills/remembering-conversations/SKILL.md +97 -0
package/dist/types.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The two record types.
|
|
3
|
+
*
|
|
4
|
+
* A **conversation exchange** is harvested: sync copies a transcript out of
|
|
5
|
+
* `~/.claude/projects` or `~/.codex/sessions` and the indexer derives rows from
|
|
6
|
+
* it. Nobody chose to write it down.
|
|
7
|
+
*
|
|
8
|
+
* A **journal entry** is deliberate: the model called `process_thoughts` and a
|
|
9
|
+
* markdown file was written. It is authored content with different privacy
|
|
10
|
+
* properties — a project entry belongs to the codebase, a user entry belongs to
|
|
11
|
+
* the person.
|
|
12
|
+
*
|
|
13
|
+
* They share one encoder and one SQLite file and nothing else. Distinct tables,
|
|
14
|
+
* distinct MCP tools, distinct result types. This file is where that boundary
|
|
15
|
+
* is stated.
|
|
16
|
+
*
|
|
17
|
+
* Reconciliation note: private-journal-mcp's own `types.ts` was entirely dead —
|
|
18
|
+
* `JournalEntry`, `ServerConfig` and `ProcessThoughtsRequest` had zero importers
|
|
19
|
+
* anywhere in its src or tests, while its live journal shape was retyped inline
|
|
20
|
+
* in four places. The names below are re-established as the single declaration
|
|
21
|
+
* those four sites now share.
|
|
22
|
+
*/
|
|
23
|
+
/** The rendered `## Heading` for each thought category, in entry order. */
|
|
24
|
+
export const JOURNAL_SECTION_HEADINGS = [
|
|
25
|
+
["reflections", "Reflections"],
|
|
26
|
+
["observations", "Observations"],
|
|
27
|
+
["project_notes", "Project Notes"],
|
|
28
|
+
["user_context", "User Context"],
|
|
29
|
+
["technical_insights", "Technical Insights"],
|
|
30
|
+
["world_knowledge", "World Knowledge"],
|
|
31
|
+
];
|
|
32
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AA4FH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,wBAAwB,GAAmD;IACtF,CAAC,aAAa,EAAE,aAAa,CAAC;IAC9B,CAAC,cAAc,EAAE,cAAc,CAAC;IAChC,CAAC,eAAe,EAAE,eAAe,CAAC;IAClC,CAAC,cAAc,EAAE,cAAc,CAAC;IAChC,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IAC5C,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;CACvC,CAAC"}
|
package/dist/verify.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface VerificationResult {
|
|
2
|
+
missing: Array<{
|
|
3
|
+
path: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
}>;
|
|
6
|
+
orphaned: Array<{
|
|
7
|
+
uuid: string;
|
|
8
|
+
path: string;
|
|
9
|
+
}>;
|
|
10
|
+
outdated: Array<{
|
|
11
|
+
path: string;
|
|
12
|
+
fileTime: number;
|
|
13
|
+
dbTime: number;
|
|
14
|
+
}>;
|
|
15
|
+
corrupted: Array<{
|
|
16
|
+
path: string;
|
|
17
|
+
error: string;
|
|
18
|
+
}>;
|
|
19
|
+
}
|
|
20
|
+
export declare function verifyIndex(): Promise<VerificationResult>;
|
|
21
|
+
export interface RepairOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Skip AI summary generation. Mirrors `moe-memory index --no-summaries`, which
|
|
24
|
+
* every other indexing entry point already had; `repair` did not, so its only
|
|
25
|
+
* code path required live Claude auth.
|
|
26
|
+
*/
|
|
27
|
+
noSummaries?: boolean | undefined;
|
|
28
|
+
}
|
|
29
|
+
export declare function repairIndex(issues: VerificationResult, options?: RepairOptions): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,kBAAkB,CAAC,CA2G/D;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACnC;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA6Ff"}
|
package/dist/verify.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { getAllExchanges, getFileLastIndexed, initDatabase } from "./db.js";
|
|
4
|
+
import { parseConversation } from "./parser.js";
|
|
5
|
+
import { findJsonlFiles, getArchiveDir, getExcludedProjects } from "./paths.js";
|
|
6
|
+
import { isErroredSentinel } from "./summary-sentinel.js";
|
|
7
|
+
export async function verifyIndex() {
|
|
8
|
+
const result = {
|
|
9
|
+
missing: [],
|
|
10
|
+
orphaned: [],
|
|
11
|
+
outdated: [],
|
|
12
|
+
corrupted: [],
|
|
13
|
+
};
|
|
14
|
+
const archiveDir = getArchiveDir();
|
|
15
|
+
// Track all files we find
|
|
16
|
+
const foundFiles = new Set();
|
|
17
|
+
// Find all conversation files
|
|
18
|
+
if (!fs.existsSync(archiveDir)) {
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
// Initialize database once for all checks
|
|
22
|
+
const db = initDatabase();
|
|
23
|
+
const projects = fs.readdirSync(archiveDir);
|
|
24
|
+
const excludedProjects = getExcludedProjects();
|
|
25
|
+
const excludedDirSet = new Set(excludedProjects);
|
|
26
|
+
let totalChecked = 0;
|
|
27
|
+
for (const project of projects) {
|
|
28
|
+
if (excludedProjects.includes(project)) {
|
|
29
|
+
console.log(`\nSkipping excluded project: ${project}`);
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const projectPath = path.join(archiveDir, project);
|
|
33
|
+
const stat = fs.statSync(projectPath);
|
|
34
|
+
if (!stat.isDirectory())
|
|
35
|
+
continue;
|
|
36
|
+
const files = findJsonlFiles(projectPath, excludedDirSet);
|
|
37
|
+
for (const file of files) {
|
|
38
|
+
totalChecked++;
|
|
39
|
+
if (totalChecked % 100 === 0) {
|
|
40
|
+
console.log(` Checked ${totalChecked} conversations...`);
|
|
41
|
+
}
|
|
42
|
+
const conversationPath = path.join(projectPath, file);
|
|
43
|
+
foundFiles.add(conversationPath);
|
|
44
|
+
const summaryPath = conversationPath.replace(".jsonl", "-summary.txt");
|
|
45
|
+
// Check for missing or errored summary. An error sentinel (#96) means a
|
|
46
|
+
// previous summarization failed — verify treats it as "missing" so repair
|
|
47
|
+
// re-attempts it rather than reporting the conversation as healthy.
|
|
48
|
+
if (!fs.existsSync(summaryPath)) {
|
|
49
|
+
result.missing.push({ path: conversationPath, reason: "No summary file" });
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (isErroredSentinel(fs.readFileSync(summaryPath, "utf-8"))) {
|
|
53
|
+
result.missing.push({
|
|
54
|
+
path: conversationPath,
|
|
55
|
+
reason: "Previous summarization failed (error sentinel)",
|
|
56
|
+
});
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Check if file is outdated (modified after last_indexed)
|
|
60
|
+
const lastIndexed = getFileLastIndexed(db, conversationPath);
|
|
61
|
+
if (lastIndexed !== null) {
|
|
62
|
+
const fileStat = fs.statSync(conversationPath);
|
|
63
|
+
if (fileStat.mtimeMs > lastIndexed) {
|
|
64
|
+
result.outdated.push({
|
|
65
|
+
path: conversationPath,
|
|
66
|
+
fileTime: fileStat.mtimeMs,
|
|
67
|
+
dbTime: lastIndexed,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Try parsing to detect corruption
|
|
72
|
+
try {
|
|
73
|
+
await parseConversation(conversationPath, project, conversationPath);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
result.corrupted.push({
|
|
77
|
+
path: conversationPath,
|
|
78
|
+
error: error instanceof Error ? error.message : String(error),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
console.log(`Verified ${totalChecked} conversations.`);
|
|
84
|
+
// Check for orphaned database entries
|
|
85
|
+
const dbExchanges = getAllExchanges(db);
|
|
86
|
+
db.close();
|
|
87
|
+
for (const exchange of dbExchanges) {
|
|
88
|
+
if (!foundFiles.has(exchange.archivePath)) {
|
|
89
|
+
result.orphaned.push({
|
|
90
|
+
uuid: exchange.id,
|
|
91
|
+
path: exchange.archivePath,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
export async function repairIndex(issues, options = {}) {
|
|
98
|
+
console.log("Repairing index...");
|
|
99
|
+
// To avoid circular dependencies, we import the indexer functions dynamically
|
|
100
|
+
const { initDatabase, insertExchange, deleteExchange } = await import("./db.js");
|
|
101
|
+
const { parseConversation } = await import("./parser.js");
|
|
102
|
+
const { initEmbeddings, generateExchangeEmbedding } = await import("./embeddings.js");
|
|
103
|
+
const { summarizeConversation } = await import("./summarizer.js");
|
|
104
|
+
const { formatErrorSentinel } = await import("./summary-sentinel.js");
|
|
105
|
+
const db = initDatabase();
|
|
106
|
+
await initEmbeddings();
|
|
107
|
+
// Remove orphaned entries first
|
|
108
|
+
for (const orphan of issues.orphaned) {
|
|
109
|
+
console.log(`Removing orphaned entry: ${orphan.uuid}`);
|
|
110
|
+
deleteExchange(db, orphan.uuid);
|
|
111
|
+
}
|
|
112
|
+
// Re-index missing and outdated conversations
|
|
113
|
+
const toReindex = [...issues.missing.map((m) => m.path), ...issues.outdated.map((o) => o.path)];
|
|
114
|
+
for (const conversationPath of toReindex) {
|
|
115
|
+
console.log(`Re-indexing: ${conversationPath}`);
|
|
116
|
+
try {
|
|
117
|
+
// Extract project name from path
|
|
118
|
+
const archiveDir = getArchiveDir();
|
|
119
|
+
const relativePath = conversationPath.replace(archiveDir + path.sep, "");
|
|
120
|
+
const project = relativePath.split(path.sep)[0] ?? "unknown";
|
|
121
|
+
// Parse conversation
|
|
122
|
+
const exchanges = await parseConversation(conversationPath, project, conversationPath);
|
|
123
|
+
if (exchanges.length === 0) {
|
|
124
|
+
console.log(` Skipped (no exchanges)`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
// Generate/update summary.
|
|
128
|
+
//
|
|
129
|
+
// A summarizer failure no longer aborts the re-index. Upstream this whole
|
|
130
|
+
// block was one try/catch, so a transient API error meant the exchanges
|
|
131
|
+
// were never indexed either — which made repair the one indexing path that
|
|
132
|
+
// could not run without live Claude auth. It now writes the same error
|
|
133
|
+
// sentinel the indexer and sync write (#96) and carries on.
|
|
134
|
+
const summaryPath = conversationPath.replace(".jsonl", "-summary.txt");
|
|
135
|
+
if (options.noSummaries) {
|
|
136
|
+
console.log(" Skipping summary (--no-summaries)");
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
try {
|
|
140
|
+
const summary = await summarizeConversation(exchanges);
|
|
141
|
+
fs.writeFileSync(summaryPath, summary, "utf-8");
|
|
142
|
+
console.log(` Created summary: ${summary.split(/\s+/).length} words`);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
try {
|
|
146
|
+
fs.writeFileSync(summaryPath, formatErrorSentinel(error), "utf-8");
|
|
147
|
+
}
|
|
148
|
+
catch { }
|
|
149
|
+
console.log(` Summary failed, continuing with index: ${error instanceof Error ? error.message : String(error)}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Index exchanges
|
|
153
|
+
for (const exchange of exchanges) {
|
|
154
|
+
const toolNames = exchange.toolCalls?.map((tc) => tc.toolName);
|
|
155
|
+
const embedding = await generateExchangeEmbedding(exchange.userMessage, exchange.assistantMessage, toolNames);
|
|
156
|
+
insertExchange(db, exchange, embedding, toolNames);
|
|
157
|
+
}
|
|
158
|
+
console.log(` Indexed ${exchanges.length} exchanges`);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
console.error(`Failed to re-index ${conversationPath}:`, error);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
db.close();
|
|
165
|
+
// Report corrupted files (manual intervention needed)
|
|
166
|
+
if (issues.corrupted.length > 0) {
|
|
167
|
+
console.log("\n⚠️ Corrupted files (manual review needed):");
|
|
168
|
+
for (const c of issues.corrupted) {
|
|
169
|
+
console.log(` ${c.path}: ${c.error}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
console.log("✅ Repair complete.");
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package version, reported to MCP clients and to `moe-memory --version`.
|
|
3
|
+
*
|
|
4
|
+
* Upstream this file was GENERATED by `scripts/generate-version.js`, wired in
|
|
5
|
+
* through npm's `prebuild` and `pretest` lifecycle hooks, and gitignored — so it
|
|
6
|
+
* was absent from the pinned snapshot and a fresh checkout could neither
|
|
7
|
+
* typecheck nor test until the generator had run. Under turbo and `tsc -b` there
|
|
8
|
+
* is no npm lifecycle hook to hang a generator on, so it is a checked-in
|
|
9
|
+
* constant instead. `test/version-consistency.test.ts` asserts it equals
|
|
10
|
+
* package.json, which is the invariant the generator existed to guarantee.
|
|
11
|
+
*/
|
|
12
|
+
export declare const VERSION = "0.1.0";
|
|
13
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The package version, reported to MCP clients and to `moe-memory --version`.
|
|
3
|
+
*
|
|
4
|
+
* Upstream this file was GENERATED by `scripts/generate-version.js`, wired in
|
|
5
|
+
* through npm's `prebuild` and `pretest` lifecycle hooks, and gitignored — so it
|
|
6
|
+
* was absent from the pinned snapshot and a fresh checkout could neither
|
|
7
|
+
* typecheck nor test until the generator had run. Under turbo and `tsc -b` there
|
|
8
|
+
* is no npm lifecycle hook to hang a generator on, so it is a checked-in
|
|
9
|
+
* constant instead. `test/version-consistency.test.ts` asserts it equals
|
|
10
|
+
* package.json, which is the invariant the generator existed to guarantee.
|
|
11
|
+
*/
|
|
12
|
+
export const VERSION = "0.1.0";
|
|
13
|
+
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
package/hooks/hooks.json
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bubstack/moe-memory",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Semantic recall over past sessions and journal entries. One MCP server.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Zak Keown",
|
|
9
|
+
"email": "zak.keown@outlook.com"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://gitlab.com/moe-ai/moe",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://gitlab.com/moe-ai/moe.git"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"claude-code",
|
|
18
|
+
"codex",
|
|
19
|
+
"conversations",
|
|
20
|
+
"journal",
|
|
21
|
+
"search",
|
|
22
|
+
"semantic-search",
|
|
23
|
+
"embeddings"
|
|
24
|
+
],
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=24"
|
|
27
|
+
},
|
|
28
|
+
"main": "dist/index.js",
|
|
29
|
+
"types": "dist/index.d.ts",
|
|
30
|
+
"bin": {
|
|
31
|
+
"moe-memory": "./dist/cli.js"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public",
|
|
35
|
+
"registry": "https://registry.npmjs.org/"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"agents",
|
|
40
|
+
"hooks",
|
|
41
|
+
"prompts",
|
|
42
|
+
"skills",
|
|
43
|
+
".mcp.json"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@anthropic-ai/claude-agent-sdk": "^0.2.126",
|
|
47
|
+
"@huggingface/transformers": "^4.2.0",
|
|
48
|
+
"@modelcontextprotocol/sdk": "^1.20.0",
|
|
49
|
+
"better-sqlite3": "^12.4.1",
|
|
50
|
+
"marked": "^16.4.0",
|
|
51
|
+
"proper-lockfile": "^4.1.2",
|
|
52
|
+
"sqlite-vec": "^0.1.7-alpha.2",
|
|
53
|
+
"zod": "^4.4.2"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
57
|
+
"@types/node": "^24.7.0",
|
|
58
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
59
|
+
"typescript": "^5.9.0",
|
|
60
|
+
"vitest": "^3.2.4"
|
|
61
|
+
},
|
|
62
|
+
"scripts": {
|
|
63
|
+
"build": "tsc -b && node ../../scripts/copy-license.mjs MIT dist/LICENSE",
|
|
64
|
+
"typecheck": "tsc -b --pretty && tsc -p tsconfig.tests.json --pretty",
|
|
65
|
+
"test": "vitest run --project unit",
|
|
66
|
+
"test:model": "vitest run --project model",
|
|
67
|
+
"test:claude-e2e": "node test/manual/claude-e2e.js",
|
|
68
|
+
"test:codex-e2e": "node test/manual/codex-e2e.js",
|
|
69
|
+
"lint": "biome check ."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Conversation Search Agent
|
|
2
|
+
|
|
3
|
+
You are searching historical Claude Code and Codex conversations for relevant context.
|
|
4
|
+
|
|
5
|
+
**Your task:**
|
|
6
|
+
1. Search conversations for: {TOPIC}
|
|
7
|
+
2. Read the top 2-5 most relevant results
|
|
8
|
+
3. Synthesize key findings (max 1000 words)
|
|
9
|
+
4. Return synthesis + source pointers (so main agent can dig deeper)
|
|
10
|
+
|
|
11
|
+
## Search Query
|
|
12
|
+
|
|
13
|
+
{SEARCH_QUERY}
|
|
14
|
+
|
|
15
|
+
## What to Look For
|
|
16
|
+
|
|
17
|
+
{FOCUS_AREAS}
|
|
18
|
+
|
|
19
|
+
Example focus areas:
|
|
20
|
+
- What was the problem or question?
|
|
21
|
+
- What solution was chosen and why?
|
|
22
|
+
- What alternatives were considered and rejected?
|
|
23
|
+
- Any gotchas, edge cases, or lessons learned?
|
|
24
|
+
- Relevant code patterns, APIs, or approaches used
|
|
25
|
+
- Architectural decisions and rationale
|
|
26
|
+
|
|
27
|
+
## How to Search
|
|
28
|
+
|
|
29
|
+
Use the MCP tool `search_conversations`:
|
|
30
|
+
```
|
|
31
|
+
mcp__plugin_moe-memory_moe-memory__search_conversations
|
|
32
|
+
query: "{SEARCH_QUERY}"
|
|
33
|
+
mode: "both" # or "vector" (default) or "text"
|
|
34
|
+
limit: 10
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
This returns:
|
|
38
|
+
- Project name and date
|
|
39
|
+
- Conversation summary (AI-generated)
|
|
40
|
+
- Matched exchange with similarity score
|
|
41
|
+
- File path and line numbers
|
|
42
|
+
|
|
43
|
+
Read the full conversations for top 2-5 results using `read_conversation` to get complete context.
|
|
44
|
+
|
|
45
|
+
## Output Format
|
|
46
|
+
|
|
47
|
+
**Required structure:**
|
|
48
|
+
|
|
49
|
+
### Summary
|
|
50
|
+
[Synthesize findings in 200-1000 words. Adapt structure to what you found:
|
|
51
|
+
- Quick answer? 1-2 paragraphs.
|
|
52
|
+
- Complex topic? Use sections (Context/Solution/Rationale/Lessons/Code).
|
|
53
|
+
- Multiple approaches? Compare and contrast.
|
|
54
|
+
- Historical evolution? Show progression chronologically.
|
|
55
|
+
|
|
56
|
+
Focus on actionable insights for the current task.]
|
|
57
|
+
|
|
58
|
+
### Sources
|
|
59
|
+
[List ALL conversations examined, in order of relevance:]
|
|
60
|
+
|
|
61
|
+
**1. [project-name, YYYY-MM-DD]** - X% match
|
|
62
|
+
Conversation summary: [One sentence - what was this conversation about?]
|
|
63
|
+
File: ~/.config/moe/memory/conversation-archive/.../uuid.jsonl:start-end
|
|
64
|
+
Status: [Read in detail | Reviewed summary only | Skimmed]
|
|
65
|
+
|
|
66
|
+
**2. [project-name, YYYY-MM-DD]** - X% match
|
|
67
|
+
Conversation summary: ...
|
|
68
|
+
File: ...
|
|
69
|
+
Status: ...
|
|
70
|
+
|
|
71
|
+
[Continue for all examined sources...]
|
|
72
|
+
|
|
73
|
+
### For Follow-Up
|
|
74
|
+
|
|
75
|
+
Main agent can:
|
|
76
|
+
- Ask you to dig deeper into specific source (#1, #2, etc.)
|
|
77
|
+
- Ask you to read adjacent exchanges in a conversation
|
|
78
|
+
- Ask you to search with refined query
|
|
79
|
+
- Read sources directly (discouraged - risks context bloat)
|
|
80
|
+
|
|
81
|
+
## Critical Rules
|
|
82
|
+
|
|
83
|
+
**DO:**
|
|
84
|
+
- Search using the provided query
|
|
85
|
+
- Read full conversations for top results
|
|
86
|
+
- Synthesize into actionable insights (200-1000 words)
|
|
87
|
+
- Include ALL sources with metadata (project, date, summary, file, status)
|
|
88
|
+
- Focus on what will help the current task
|
|
89
|
+
- Include specific details (function names, error messages, line numbers)
|
|
90
|
+
|
|
91
|
+
**DO NOT:**
|
|
92
|
+
- Include raw conversation excerpts (synthesize instead)
|
|
93
|
+
- Paste full file contents
|
|
94
|
+
- Add meta-commentary ("I searched and found...")
|
|
95
|
+
- Exceed 1000 words in Summary section
|
|
96
|
+
- Return search results verbatim
|
|
97
|
+
|
|
98
|
+
## Example Output
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
### Summary
|
|
102
|
+
|
|
103
|
+
developer needed to handle authentication errors in React Router 7 data loaders
|
|
104
|
+
without crashing the app. The solution uses RR7's errorElement + useRouteError()
|
|
105
|
+
to catch 401s and redirect to login.
|
|
106
|
+
|
|
107
|
+
**Key implementation:**
|
|
108
|
+
Protected route wrapper catches loader errors, checks error.status === 401.
|
|
109
|
+
If 401, redirects to /login with return URL. Otherwise shows error boundary.
|
|
110
|
+
|
|
111
|
+
**Why this works:**
|
|
112
|
+
Loaders can't use hooks (tried useNavigate, failed). Throwing redirect()
|
|
113
|
+
bypasses error handling. Final approach lets errors bubble to errorElement
|
|
114
|
+
where component context is available.
|
|
115
|
+
|
|
116
|
+
**Critical gotchas:**
|
|
117
|
+
- Test with expired tokens, not just missing tokens
|
|
118
|
+
- Error boundaries need unique keys per route or won't reset
|
|
119
|
+
- Always include return URL in redirect
|
|
120
|
+
- Loaders execute before components, no hook access
|
|
121
|
+
|
|
122
|
+
**Code pattern:**
|
|
123
|
+
```typescript
|
|
124
|
+
// In loader
|
|
125
|
+
if (!response.ok) throw { status: response.status, message: 'Failed' };
|
|
126
|
+
|
|
127
|
+
// In ErrorBoundary
|
|
128
|
+
const error = useRouteError();
|
|
129
|
+
if (error.status === 401) navigate('/login?return=' + location.pathname);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Sources
|
|
133
|
+
|
|
134
|
+
**1. [react-router-7-starter, 2024-09-17]** - 92% match
|
|
135
|
+
Conversation summary: Built authentication system with JWT, implemented protected routes
|
|
136
|
+
File: ~/.config/moe/memory/conversation-archive/react-router-7-starter/19df92b9.jsonl:145-289
|
|
137
|
+
Status: Read in detail (multiple exchanges on error handling evolution)
|
|
138
|
+
|
|
139
|
+
**2. [react-router-docs-reading, 2024-09-10]** - 78% match
|
|
140
|
+
Conversation summary: Read RR7 docs, discussed new loader patterns and errorElement
|
|
141
|
+
File: ~/.config/moe/memory/conversation-archive/react-router-docs-reading/a3c871f2.jsonl:56-98
|
|
142
|
+
Status: Reviewed summary only (confirmed errorElement usage)
|
|
143
|
+
|
|
144
|
+
**3. [auth-debugging, 2024-09-18]** - 73% match
|
|
145
|
+
Conversation summary: Fixed token expiration handling and error boundary reset issues
|
|
146
|
+
File: ~/.config/moe/memory/conversation-archive/react-router-7-starter/7b2e8d91.jsonl:201-345
|
|
147
|
+
Status: Read in detail (discovered gotchas about keys and expired tokens)
|
|
148
|
+
|
|
149
|
+
### For Follow-Up
|
|
150
|
+
|
|
151
|
+
Main agent can ask me to:
|
|
152
|
+
- Dig deeper into source #1 (full error handling evolution)
|
|
153
|
+
- Read adjacent exchanges in #3 (more debugging context)
|
|
154
|
+
- Search for "React Router error boundary patterns" more broadly
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
This output:
|
|
158
|
+
- Synthesis: ~350 words (actionable, specific)
|
|
159
|
+
- Sources: Full metadata for 3 conversations
|
|
160
|
+
- Enables iteration without context bloat
|