@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary-sentinel.js","sourceRoot":"","sources":["../src/summary-sentinel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;AAC1C,MAAM,mBAAmB,GAAG,GAAG,YAAY,IAAI,CAAC;AAChD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,SAAS;AAE5C,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,GAAG,YAAY,KAAK,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO,IAAI,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC;IAC7D,IAAI,CAAC,GAAG;QAAE,OAAO,gBAAgB,CAAC;IAClC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACnF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,iBAAiB,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `moe-memory sync` — copy new transcripts into the archive, index them, then
|
|
3
|
+
* run one batch of the embedding migration.
|
|
4
|
+
*
|
|
5
|
+
* Was a standalone script executed by `cli/episodic-memory.js` through
|
|
6
|
+
* `spawn(node, join(__dirname, '../dist/sync-cli.js'))`. It is a function now
|
|
7
|
+
* and `src/cli.ts` calls it in-process: there is one bin, it compiles to
|
|
8
|
+
* `dist/cli.js`, and every `../dist/` prefix in the old shim layer was a
|
|
9
|
+
* resolution that only worked from the right directory.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Exit code, so the dispatcher can propagate it. `null` means "keep going".
|
|
13
|
+
*/
|
|
14
|
+
export declare function runSync(args: string[]): Promise<number>;
|
|
15
|
+
//# sourceMappingURL=sync-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cli.d.ts","sourceRoot":"","sources":["../src/sync-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA4EH;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4I7D"}
|
package/dist/sync-cli.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `moe-memory sync` — copy new transcripts into the archive, index them, then
|
|
3
|
+
* run one batch of the embedding migration.
|
|
4
|
+
*
|
|
5
|
+
* Was a standalone script executed by `cli/episodic-memory.js` through
|
|
6
|
+
* `spawn(node, join(__dirname, '../dist/sync-cli.js'))`. It is a function now
|
|
7
|
+
* and `src/cli.ts` calls it in-process: there is one bin, it compiles to
|
|
8
|
+
* `dist/cli.js`, and every `../dist/` prefix in the old shim layer was a
|
|
9
|
+
* resolution that only worked from the right directory.
|
|
10
|
+
*/
|
|
11
|
+
import { spawn } from "node:child_process";
|
|
12
|
+
import fs from "node:fs";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import { initDatabase } from "./db.js";
|
|
15
|
+
import { countStale, runMigrationBatch } from "./embedding-migration.js";
|
|
16
|
+
import { generateExchangeEmbedding, initEmbeddings } from "./embeddings.js";
|
|
17
|
+
import { acquireFileLock, readLockHolder, releaseFileLock } from "./file-lock.js";
|
|
18
|
+
import { formatLogLine, getSyncLogPath } from "./logging.js";
|
|
19
|
+
import { getArchiveDir, getConversationSourceDirs, getIndexDir } from "./paths.js";
|
|
20
|
+
import { shouldSkipReentrantSync } from "./summarizer.js";
|
|
21
|
+
import { syncConversations } from "./sync.js";
|
|
22
|
+
const HELP = `
|
|
23
|
+
Usage: moe-memory sync [--background]
|
|
24
|
+
|
|
25
|
+
Sync conversations from Claude Code and Codex transcript directories to archive and index them.
|
|
26
|
+
|
|
27
|
+
This command:
|
|
28
|
+
1. Copies new or updated .jsonl files to conversation archive
|
|
29
|
+
2. Generates embeddings for semantic search
|
|
30
|
+
3. Updates the search index
|
|
31
|
+
|
|
32
|
+
Only processes files that are new or have been modified since last sync.
|
|
33
|
+
Safe to run multiple times - subsequent runs are fast no-ops.
|
|
34
|
+
|
|
35
|
+
OPTIONS:
|
|
36
|
+
--background Run sync in background (for hooks, returns immediately)
|
|
37
|
+
|
|
38
|
+
EXAMPLES:
|
|
39
|
+
# Sync all new conversations
|
|
40
|
+
moe-memory sync
|
|
41
|
+
|
|
42
|
+
# Sync in background (for hooks)
|
|
43
|
+
moe-memory sync --background
|
|
44
|
+
|
|
45
|
+
# Use in a Claude Code SessionStart hook
|
|
46
|
+
moe-memory sync --background
|
|
47
|
+
`;
|
|
48
|
+
const MIGRATION_BATCH_SIZE = Number.parseInt(process.env.MOE_MEMORY_MIGRATION_BATCH || "500", 10);
|
|
49
|
+
async function runEmbeddingMigrationPhase() {
|
|
50
|
+
const db = initDatabase();
|
|
51
|
+
try {
|
|
52
|
+
const stale = countStale(db);
|
|
53
|
+
if (stale === 0)
|
|
54
|
+
return;
|
|
55
|
+
console.error(`\nmoe-memory: ${stale} exchange(s) on the old embedding model — migrating up to ${MIGRATION_BATCH_SIZE} this run`);
|
|
56
|
+
await initEmbeddings();
|
|
57
|
+
const indexDir = getIndexDir();
|
|
58
|
+
const done = await runMigrationBatch(db, indexDir, MIGRATION_BATCH_SIZE, generateExchangeEmbedding);
|
|
59
|
+
if (done > 0) {
|
|
60
|
+
const after = countStale(db);
|
|
61
|
+
console.error(`moe-memory: re-embedded ${done} (${after} still stale; will resume on next sync)`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error("moe-memory: migration phase error:", err instanceof Error ? err.message : String(err));
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
db.close();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Exit code, so the dispatcher can propagate it. `null` means "keep going".
|
|
73
|
+
*/
|
|
74
|
+
export async function runSync(args) {
|
|
75
|
+
// Reentrancy guard (#87): if this sync was triggered by a SessionStart hook
|
|
76
|
+
// inside a Claude subprocess that the summarizer just spawned, exit silently.
|
|
77
|
+
// Without this, summarization spawns a Claude subprocess which fires
|
|
78
|
+
// SessionStart which runs sync which spawns more summarization — cascading
|
|
79
|
+
// fanout that pegs CPU and burns API quota.
|
|
80
|
+
if (shouldSkipReentrantSync()) {
|
|
81
|
+
// stderr keeps the message out of any stdout consumers (e.g., MCP)
|
|
82
|
+
// while still being visible in hook logs.
|
|
83
|
+
console.error("moe-memory: skipping sync inside summarizer-spawned subprocess (#87)");
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
87
|
+
console.log(HELP);
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
// If background mode, fork the process and return immediately.
|
|
91
|
+
if (args.includes("--background")) {
|
|
92
|
+
const filteredArgs = args.filter((arg) => arg !== "--background");
|
|
93
|
+
const logPath = getSyncLogPath();
|
|
94
|
+
const logFd = fs.openSync(logPath, "a");
|
|
95
|
+
fs.writeSync(logFd, formatLogLine("info", `Starting background sync from pid ${process.pid}`));
|
|
96
|
+
// Re-spawn this same entry point with the `sync` subcommand. argv[1] is the
|
|
97
|
+
// dispatcher (dist/cli.js, or the bin symlink pointing at it); passing the
|
|
98
|
+
// subcommand back explicitly is what makes that safe under one bin.
|
|
99
|
+
const entry = process.argv[1];
|
|
100
|
+
if (!entry) {
|
|
101
|
+
console.error("moe-memory: cannot determine own entry point; running sync in foreground");
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
const child = spawn(process.execPath, [entry, "sync", ...filteredArgs], {
|
|
105
|
+
detached: true,
|
|
106
|
+
stdio: ["ignore", logFd, logFd],
|
|
107
|
+
});
|
|
108
|
+
child.unref(); // Allow parent to exit
|
|
109
|
+
console.log(`Sync started in background. Log: ${logPath}`);
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const sourceDirs = getConversationSourceDirs();
|
|
114
|
+
const destDir = getArchiveDir();
|
|
115
|
+
if (sourceDirs.length === 0) {
|
|
116
|
+
console.log("⚠️ No conversation source directories found.");
|
|
117
|
+
console.log(" Checked: ~/.claude/projects, ~/.claude/transcripts, and ~/.codex/sessions");
|
|
118
|
+
if (process.env.CLAUDE_CONFIG_DIR) {
|
|
119
|
+
console.log(` CLAUDE_CONFIG_DIR is set to: ${process.env.CLAUDE_CONFIG_DIR}`);
|
|
120
|
+
}
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
// Single-instance lock (#97). Independent SessionStart events from multiple
|
|
124
|
+
// Claude Code sessions each fire `sync --background`; without a lock they race
|
|
125
|
+
// the SQLite write path and pile up Claude subprocesses for summarization. On
|
|
126
|
+
// Windows the latter exhausts the desktop heap and crashes the workers with
|
|
127
|
+
// STATUS_DLL_INIT_FAILED. Acquire after the source-dir check so help/version
|
|
128
|
+
// paths don't touch the filesystem unnecessarily, and release on every exit.
|
|
129
|
+
const syncLockPath = path.join(path.dirname(getSyncLogPath()), "moe-memory-sync.lock");
|
|
130
|
+
const syncLock = acquireFileLock(syncLockPath);
|
|
131
|
+
if (!syncLock) {
|
|
132
|
+
const holder = readLockHolder(syncLockPath);
|
|
133
|
+
const holderLabel = holder !== null ? `pid ${holder}` : "another process";
|
|
134
|
+
console.error(`moe-memory: sync already running (${holderLabel}); skipping`);
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
let released = false;
|
|
138
|
+
const releaseSyncLockOnce = () => {
|
|
139
|
+
if (released)
|
|
140
|
+
return;
|
|
141
|
+
released = true;
|
|
142
|
+
releaseFileLock(syncLock);
|
|
143
|
+
};
|
|
144
|
+
process.on("exit", releaseSyncLockOnce);
|
|
145
|
+
process.on("SIGINT", () => {
|
|
146
|
+
releaseSyncLockOnce();
|
|
147
|
+
process.exit(130);
|
|
148
|
+
});
|
|
149
|
+
process.on("SIGTERM", () => {
|
|
150
|
+
releaseSyncLockOnce();
|
|
151
|
+
process.exit(143);
|
|
152
|
+
});
|
|
153
|
+
process.on("SIGHUP", () => {
|
|
154
|
+
releaseSyncLockOnce();
|
|
155
|
+
process.exit(129);
|
|
156
|
+
});
|
|
157
|
+
console.log("Syncing conversations...");
|
|
158
|
+
console.log(`Sources: ${sourceDirs.join(", ")}`);
|
|
159
|
+
console.log(`Destination: ${destDir}\n`);
|
|
160
|
+
const totals = {
|
|
161
|
+
copied: 0,
|
|
162
|
+
skipped: 0,
|
|
163
|
+
indexed: 0,
|
|
164
|
+
summarized: 0,
|
|
165
|
+
errors: [],
|
|
166
|
+
};
|
|
167
|
+
try {
|
|
168
|
+
for (const sourceDir of sourceDirs) {
|
|
169
|
+
const result = await syncConversations(sourceDir, destDir);
|
|
170
|
+
totals.copied += result.copied;
|
|
171
|
+
totals.skipped += result.skipped;
|
|
172
|
+
totals.indexed += result.indexed;
|
|
173
|
+
totals.summarized += result.summarized;
|
|
174
|
+
totals.errors.push(...result.errors);
|
|
175
|
+
}
|
|
176
|
+
console.log("\n✅ Sync complete!");
|
|
177
|
+
console.log(` Copied: ${totals.copied}`);
|
|
178
|
+
console.log(` Skipped: ${totals.skipped}`);
|
|
179
|
+
console.log(` Indexed: ${totals.indexed}`);
|
|
180
|
+
console.log(` Summarized: ${totals.summarized}`);
|
|
181
|
+
if (totals.errors.length > 0) {
|
|
182
|
+
console.log(`\n⚠️ Errors: ${totals.errors.length}`);
|
|
183
|
+
for (const err of totals.errors)
|
|
184
|
+
console.log(` ${err.file}: ${err.error}`);
|
|
185
|
+
// Help diagnose silent summarization failures (#70)
|
|
186
|
+
const summaryErrors = totals.errors.filter((e) => e.error.startsWith("Summary generation failed"));
|
|
187
|
+
if (summaryErrors.length > 0 && totals.summarized === 0) {
|
|
188
|
+
console.log(`\n💡 All ${summaryErrors.length} summarization attempts failed.`);
|
|
189
|
+
console.log(" Check your API configuration (MOE_MEMORY_API_BASE_URL / ANTHROPIC_API_KEY).");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// After regular sync, do a batch of embedding migration if any rows are
|
|
193
|
+
// still on the old encoder. Lock-protected; if another process is already
|
|
194
|
+
// migrating, this is a no-op.
|
|
195
|
+
await runEmbeddingMigrationPhase();
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
releaseSyncLockOnce();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=sync-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cli.js","sourceRoot":"","sources":["../src/sync-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/sync.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The in-transcript opt-out a user types to keep a conversation out of the index.
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ HIGHEST-RISK RENAME IN THE PACKAGE, and the reason BOTH forms are here
|
|
5
|
+
* permanently. This is a marker people have already typed into transcripts
|
|
6
|
+
* sitting on disk. Renaming it and dropping the old form does not fail loudly —
|
|
7
|
+
* it silently starts indexing every conversation a user had explicitly marked
|
|
8
|
+
* DO-NOT-INDEX. So the upstream marker is honoured forever; it is data, not a
|
|
9
|
+
* brand token, and Zone B reasoning applies to it even though it lives in Zone A
|
|
10
|
+
* code.
|
|
11
|
+
*/
|
|
12
|
+
export declare const EXCLUSION_MARKER = "<INSTRUCTIONS-TO-MOE-MEMORY>DO NOT INDEX THIS CHAT</INSTRUCTIONS-TO-MOE-MEMORY>";
|
|
13
|
+
/** The upstream form. Accepted permanently — see EXCLUSION_MARKER. */
|
|
14
|
+
export declare const LEGACY_EXCLUSION_MARKER = "<INSTRUCTIONS-TO-EPISODIC-MEMORY>DO NOT INDEX THIS CHAT</INSTRUCTIONS-TO-EPISODIC-MEMORY>";
|
|
15
|
+
export declare const EXCLUSION_MARKERS: string[];
|
|
16
|
+
/** True when a transcript carries any marker that keeps it out of the index. */
|
|
17
|
+
export declare function shouldSkipConversation(filePath: string): boolean;
|
|
18
|
+
export interface SyncResult {
|
|
19
|
+
copied: number;
|
|
20
|
+
skipped: number;
|
|
21
|
+
indexed: number;
|
|
22
|
+
summarized: number;
|
|
23
|
+
errors: Array<{
|
|
24
|
+
file: string;
|
|
25
|
+
error: string;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export interface SyncOptions {
|
|
29
|
+
skipIndex?: boolean;
|
|
30
|
+
skipSummaries?: boolean;
|
|
31
|
+
summaryLimit?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare function extractSessionIdFromPath(filePath: string): string | null;
|
|
34
|
+
export declare function syncConversations(sourceDir: string, destDir: string, options?: SyncOptions): Promise<SyncResult>;
|
|
35
|
+
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,oFACsD,CAAC;AAEpF,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,8FACyD,CAAC;AAE9F,eAAO,MAAM,iBAAiB,UAK7B,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQhE;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyBD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxE;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CAkKrB"}
|
package/dist/sync.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { SUMMARIZER_CONTEXT_MARKER } from "./constants.js";
|
|
4
|
+
import { findJsonlFiles, getExcludedProjects } from "./paths.js";
|
|
5
|
+
import { formatErrorSentinel, shouldQueueForSummary } from "./summary-sentinel.js";
|
|
6
|
+
/**
|
|
7
|
+
* The in-transcript opt-out a user types to keep a conversation out of the index.
|
|
8
|
+
*
|
|
9
|
+
* ⚠️ HIGHEST-RISK RENAME IN THE PACKAGE, and the reason BOTH forms are here
|
|
10
|
+
* permanently. This is a marker people have already typed into transcripts
|
|
11
|
+
* sitting on disk. Renaming it and dropping the old form does not fail loudly —
|
|
12
|
+
* it silently starts indexing every conversation a user had explicitly marked
|
|
13
|
+
* DO-NOT-INDEX. So the upstream marker is honoured forever; it is data, not a
|
|
14
|
+
* brand token, and Zone B reasoning applies to it even though it lives in Zone A
|
|
15
|
+
* code.
|
|
16
|
+
*/
|
|
17
|
+
export const EXCLUSION_MARKER = "<INSTRUCTIONS-TO-MOE-MEMORY>DO NOT INDEX THIS CHAT</INSTRUCTIONS-TO-MOE-MEMORY>";
|
|
18
|
+
/** The upstream form. Accepted permanently — see EXCLUSION_MARKER. */
|
|
19
|
+
export const LEGACY_EXCLUSION_MARKER = "<INSTRUCTIONS-TO-EPISODIC-MEMORY>DO NOT INDEX THIS CHAT</INSTRUCTIONS-TO-EPISODIC-MEMORY>";
|
|
20
|
+
export const EXCLUSION_MARKERS = [
|
|
21
|
+
EXCLUSION_MARKER,
|
|
22
|
+
LEGACY_EXCLUSION_MARKER,
|
|
23
|
+
"Only use NO_INSIGHTS_FOUND",
|
|
24
|
+
SUMMARIZER_CONTEXT_MARKER,
|
|
25
|
+
];
|
|
26
|
+
/** True when a transcript carries any marker that keeps it out of the index. */
|
|
27
|
+
export function shouldSkipConversation(filePath) {
|
|
28
|
+
try {
|
|
29
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
30
|
+
return EXCLUSION_MARKERS.some((marker) => content.includes(marker));
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// If we can't read the file, don't skip it
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function copyIfNewer(src, dest) {
|
|
38
|
+
// Ensure destination directory exists
|
|
39
|
+
const destDir = path.dirname(dest);
|
|
40
|
+
if (!fs.existsSync(destDir)) {
|
|
41
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
// Check if destination exists and is up-to-date
|
|
44
|
+
if (fs.existsSync(dest)) {
|
|
45
|
+
const srcStat = fs.statSync(src);
|
|
46
|
+
const destStat = fs.statSync(dest);
|
|
47
|
+
if (destStat.mtimeMs >= srcStat.mtimeMs) {
|
|
48
|
+
return false; // Dest is current, skip
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Atomic copy: temp file + rename
|
|
52
|
+
const tempDest = `${dest}.tmp.${process.pid}`;
|
|
53
|
+
fs.copyFileSync(src, tempDest);
|
|
54
|
+
fs.renameSync(tempDest, dest); // Atomic on same filesystem
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
export function extractSessionIdFromPath(filePath) {
|
|
58
|
+
// Extract session ID from Claude filename or Codex rollout filename.
|
|
59
|
+
const basename = path.basename(filePath, ".jsonl");
|
|
60
|
+
const uuidPattern = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
|
|
61
|
+
const matches = basename.match(uuidPattern);
|
|
62
|
+
return matches?.[matches.length - 1] ?? null;
|
|
63
|
+
}
|
|
64
|
+
export async function syncConversations(sourceDir, destDir, options = {}) {
|
|
65
|
+
const result = {
|
|
66
|
+
copied: 0,
|
|
67
|
+
skipped: 0,
|
|
68
|
+
indexed: 0,
|
|
69
|
+
summarized: 0,
|
|
70
|
+
errors: [],
|
|
71
|
+
};
|
|
72
|
+
// Ensure source directory exists
|
|
73
|
+
if (!fs.existsSync(sourceDir)) {
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
// Collect files to index and summarize
|
|
77
|
+
const filesToIndex = [];
|
|
78
|
+
const filesToSummarize = [];
|
|
79
|
+
// Walk source directory
|
|
80
|
+
const projects = fs.readdirSync(sourceDir);
|
|
81
|
+
const excludedProjects = getExcludedProjects();
|
|
82
|
+
const excludedDirSet = new Set(excludedProjects);
|
|
83
|
+
for (const project of projects) {
|
|
84
|
+
if (excludedProjects.includes(project)) {
|
|
85
|
+
console.log(`\nSkipping excluded project: ${project}`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const projectPath = path.join(sourceDir, project);
|
|
89
|
+
const stat = fs.statSync(projectPath);
|
|
90
|
+
if (!stat.isDirectory())
|
|
91
|
+
continue;
|
|
92
|
+
const files = findJsonlFiles(projectPath, excludedDirSet);
|
|
93
|
+
for (const file of files) {
|
|
94
|
+
const srcFile = path.join(projectPath, file);
|
|
95
|
+
const destFile = path.join(destDir, project, file);
|
|
96
|
+
try {
|
|
97
|
+
const wasCopied = copyIfNewer(srcFile, destFile);
|
|
98
|
+
if (wasCopied) {
|
|
99
|
+
result.copied++;
|
|
100
|
+
filesToIndex.push(destFile);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
result.skipped++;
|
|
104
|
+
}
|
|
105
|
+
// Check if this file needs a summary (whether newly copied or existing).
|
|
106
|
+
// shouldQueueForSummary skips files that already have a real summary or
|
|
107
|
+
// an empty zero-exchange sentinel, and retries stale error sentinels (#96).
|
|
108
|
+
if (!options.skipSummaries) {
|
|
109
|
+
const summaryPath = destFile.replace(".jsonl", "-summary.txt");
|
|
110
|
+
if (shouldQueueForSummary(summaryPath) && !shouldSkipConversation(destFile)) {
|
|
111
|
+
const sessionId = extractSessionIdFromPath(destFile);
|
|
112
|
+
if (sessionId) {
|
|
113
|
+
filesToSummarize.push({ path: destFile, sessionId });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
result.errors.push({
|
|
120
|
+
file: srcFile,
|
|
121
|
+
error: error instanceof Error ? error.message : String(error),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Index copied files (unless skipIndex is set)
|
|
127
|
+
if (!options.skipIndex && filesToIndex.length > 0) {
|
|
128
|
+
const { initDatabase, insertExchange } = await import("./db.js");
|
|
129
|
+
const { initEmbeddings, generateExchangeEmbedding } = await import("./embeddings.js");
|
|
130
|
+
const { parseConversation } = await import("./parser.js");
|
|
131
|
+
const db = initDatabase();
|
|
132
|
+
await initEmbeddings();
|
|
133
|
+
for (const file of filesToIndex) {
|
|
134
|
+
try {
|
|
135
|
+
// Check for DO NOT INDEX marker
|
|
136
|
+
if (shouldSkipConversation(file)) {
|
|
137
|
+
continue; // Skip indexing but file is already copied
|
|
138
|
+
}
|
|
139
|
+
const project = path.basename(path.dirname(file));
|
|
140
|
+
const exchanges = await parseConversation(file, project, file);
|
|
141
|
+
for (const exchange of exchanges) {
|
|
142
|
+
const toolNames = exchange.toolCalls?.map((tc) => tc.toolName);
|
|
143
|
+
const embedding = await generateExchangeEmbedding(exchange.userMessage, exchange.assistantMessage, toolNames);
|
|
144
|
+
insertExchange(db, exchange, embedding, toolNames);
|
|
145
|
+
}
|
|
146
|
+
result.indexed++;
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
result.errors.push({
|
|
150
|
+
file,
|
|
151
|
+
error: error instanceof Error ? error.message : String(error),
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
db.close();
|
|
156
|
+
}
|
|
157
|
+
// Generate summaries for files that need them
|
|
158
|
+
if (!options.skipSummaries && filesToSummarize.length > 0) {
|
|
159
|
+
const { parseConversation } = await import("./parser.js");
|
|
160
|
+
const { summarizeConversation } = await import("./summarizer.js");
|
|
161
|
+
const summaryLimit = options.summaryLimit ?? 10;
|
|
162
|
+
const toSummarize = filesToSummarize.slice(0, summaryLimit);
|
|
163
|
+
const remaining = filesToSummarize.length - toSummarize.length;
|
|
164
|
+
console.log(`Generating summaries for ${toSummarize.length} conversation(s)...`);
|
|
165
|
+
if (remaining > 0) {
|
|
166
|
+
console.log(` (${remaining} more need summaries - will process on next sync)`);
|
|
167
|
+
}
|
|
168
|
+
for (const { path: filePath, sessionId } of toSummarize) {
|
|
169
|
+
try {
|
|
170
|
+
const project = path.basename(path.dirname(filePath));
|
|
171
|
+
const exchanges = await parseConversation(filePath, project, filePath);
|
|
172
|
+
if (exchanges.length === 0) {
|
|
173
|
+
// Skip empty conversations — write an empty -summary.txt sentinel so they aren't re-queued forever
|
|
174
|
+
const summaryPath = filePath.replace(".jsonl", "-summary.txt");
|
|
175
|
+
fs.writeFileSync(summaryPath, "", "utf-8");
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
console.log(` Summarizing ${path.basename(filePath)} (${exchanges.length} exchanges)...`);
|
|
179
|
+
const summary = await summarizeConversation(exchanges, sessionId);
|
|
180
|
+
const summaryPath = filePath.replace(".jsonl", "-summary.txt");
|
|
181
|
+
fs.writeFileSync(summaryPath, summary, "utf-8");
|
|
182
|
+
result.summarized++;
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
// Write a structured error sentinel (#96): distinct from the empty
|
|
186
|
+
// zero-exchange sentinel so a stale failure can self-heal on the next
|
|
187
|
+
// sync run past the retry threshold. The marker also keeps the error
|
|
188
|
+
// text on disk for post-hoc diagnosis. Best-effort — if the sentinel
|
|
189
|
+
// write itself fails, fall through and surface the original error.
|
|
190
|
+
try {
|
|
191
|
+
const summaryPath = filePath.replace(".jsonl", "-summary.txt");
|
|
192
|
+
fs.writeFileSync(summaryPath, formatErrorSentinel(error), "utf-8");
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
result.errors.push({
|
|
196
|
+
file: filePath,
|
|
197
|
+
error: `Summary generation failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=sync.js.map
|
package/dist/sync.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
export interface ToolCall {
|
|
24
|
+
id: string;
|
|
25
|
+
exchangeId: string;
|
|
26
|
+
toolName: string;
|
|
27
|
+
toolInput?: unknown;
|
|
28
|
+
toolResult?: string;
|
|
29
|
+
isError: boolean;
|
|
30
|
+
timestamp: string;
|
|
31
|
+
}
|
|
32
|
+
export type ConversationHarness = "claude" | "codex";
|
|
33
|
+
export interface ConversationExchange {
|
|
34
|
+
id: string;
|
|
35
|
+
project: string;
|
|
36
|
+
timestamp: string;
|
|
37
|
+
userMessage: string;
|
|
38
|
+
assistantMessage: string;
|
|
39
|
+
archivePath: string;
|
|
40
|
+
lineStart: number;
|
|
41
|
+
lineEnd: number;
|
|
42
|
+
parentUuid?: string | undefined;
|
|
43
|
+
isSidechain?: boolean | undefined;
|
|
44
|
+
harness?: ConversationHarness | undefined;
|
|
45
|
+
sessionId?: string | undefined;
|
|
46
|
+
cwd?: string | undefined;
|
|
47
|
+
gitBranch?: string | undefined;
|
|
48
|
+
claudeVersion?: string | undefined;
|
|
49
|
+
agentVersion?: string | undefined;
|
|
50
|
+
model?: string | undefined;
|
|
51
|
+
modelProvider?: string | undefined;
|
|
52
|
+
thinkingLevel?: string | undefined;
|
|
53
|
+
thinkingDisabled?: boolean | undefined;
|
|
54
|
+
thinkingTriggers?: string | undefined;
|
|
55
|
+
toolCalls?: ToolCall[] | undefined;
|
|
56
|
+
}
|
|
57
|
+
/** A conversation-search hit. */
|
|
58
|
+
export interface SearchResult {
|
|
59
|
+
exchange: ConversationExchange;
|
|
60
|
+
/** Cosine similarity, or undefined in `mode: 'text'` where there is no vector. */
|
|
61
|
+
similarity?: number | undefined;
|
|
62
|
+
snippet: string;
|
|
63
|
+
/** The conversation's AI summary sidecar, when one exists and is not an error sentinel. */
|
|
64
|
+
summary?: string | undefined;
|
|
65
|
+
}
|
|
66
|
+
export interface MultiConceptResult {
|
|
67
|
+
exchange: ConversationExchange;
|
|
68
|
+
snippet: string;
|
|
69
|
+
conceptSimilarities: number[];
|
|
70
|
+
averageSimilarity: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Which journal a record belongs to.
|
|
74
|
+
*
|
|
75
|
+
* Upstream this was derived at read time from which directory the file happened
|
|
76
|
+
* to be walked out of, and was not stored. It is a column now: derivation broke
|
|
77
|
+
* the moment both roots resolved to the same directory.
|
|
78
|
+
*/
|
|
79
|
+
export type JournalScope = "project" | "user";
|
|
80
|
+
/**
|
|
81
|
+
* The six thought categories, in the order they are rendered into an entry.
|
|
82
|
+
*
|
|
83
|
+
* `project_notes` routes to the project journal; the other five route to the
|
|
84
|
+
* user journal. Snake_case because these are MCP wire names.
|
|
85
|
+
*/
|
|
86
|
+
export interface JournalThoughts {
|
|
87
|
+
reflections?: string | undefined;
|
|
88
|
+
observations?: string | undefined;
|
|
89
|
+
project_notes?: string | undefined;
|
|
90
|
+
user_context?: string | undefined;
|
|
91
|
+
technical_insights?: string | undefined;
|
|
92
|
+
world_knowledge?: string | undefined;
|
|
93
|
+
}
|
|
94
|
+
/** The rendered `## Heading` for each thought category, in entry order. */
|
|
95
|
+
export declare const JOURNAL_SECTION_HEADINGS: ReadonlyArray<[keyof JournalThoughts, string]>;
|
|
96
|
+
/** One journal entry as it exists on disk and in the index. */
|
|
97
|
+
export interface JournalEntry {
|
|
98
|
+
/** Stable id: the entry's absolute path is not stable, the id is. */
|
|
99
|
+
id: string;
|
|
100
|
+
/** Absolute path of the markdown file, refreshed from the walk on every index. */
|
|
101
|
+
path: string;
|
|
102
|
+
/**
|
|
103
|
+
* Absolute path of the journal root this entry was found under.
|
|
104
|
+
*
|
|
105
|
+
* One database serves every project on the machine, so this is what makes a
|
|
106
|
+
* `project`-scoped entry belong to a repo: retrieval filters on it, and the
|
|
107
|
+
* index prune only considers rows whose root it is currently walking.
|
|
108
|
+
*/
|
|
109
|
+
root: string;
|
|
110
|
+
scope: JournalScope;
|
|
111
|
+
/** Epoch milliseconds. */
|
|
112
|
+
timestamp: number;
|
|
113
|
+
/** Frontmatter-stripped, header-stripped body — what gets embedded. */
|
|
114
|
+
text: string;
|
|
115
|
+
/** Rendered section headings present in the entry, e.g. `['Reflections']`. */
|
|
116
|
+
sections: string[];
|
|
117
|
+
}
|
|
118
|
+
/** A journal-search hit. */
|
|
119
|
+
export interface JournalSearchResult {
|
|
120
|
+
entry: JournalEntry;
|
|
121
|
+
/** Cosine similarity in [-1, 1]. 1 for `list_recent_entries`, which does not rank. */
|
|
122
|
+
score: number;
|
|
123
|
+
excerpt: string;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAGhB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAGlC,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAGnC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAGtC,SAAS,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;CACpC;AAED,iCAAiC;AACjC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAMD;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB,EAAE,aAAa,CAAC,CAAC,MAAM,eAAe,EAAE,MAAM,CAAC,CAOnF,CAAC;AAEF,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;OAMG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,YAAY,CAAC;IACpB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,4BAA4B;AAC5B,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,YAAY,CAAC;IACpB,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB"}
|