codemem 0.20.5-alpha.1 → 0.20.5
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/.opencode/plugins/codemem.js +1 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/index.js +67 -30
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
|
|
16
16
|
const TRUTHY_VALUES = ["1", "true", "yes"];
|
|
17
17
|
const DISABLED_VALUES = ["0", "false", "off"];
|
|
18
|
-
const PINNED_BACKEND_VERSION = "0.20.5
|
|
18
|
+
const PINNED_BACKEND_VERSION = "0.20.5";
|
|
19
19
|
|
|
20
20
|
const normalizeEnvValue = (value) => (value || "").toLowerCase();
|
|
21
21
|
const envHasValue = (value, truthyValues) =>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAEN,KAAK,uBAAuB,EAG5B,MAAM,uBAAuB,CAAC;AAQ/B,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKhE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASjD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAED,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,GAAG,IAAI,CAGf;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAEN,KAAK,uBAAuB,EAG5B,MAAM,uBAAuB,CAAC;AAQ/B,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAKhE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CASjD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAED,wBAAgB,sBAAsB,CACrC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,GAAG,IAAI,CAGf;AAqLD,wBAAgB,yBAAyB,CACxC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,uBAAuB,EACnC,QAAQ,GAAE,MAAM,EAAqB,GACnC,MAAM,EAAE,CAgBV;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAS9D;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAUpF;AAkRD,eAAO,MAAM,YAAY,SAuBtB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1013,12 +1013,13 @@ async function isPortOpen(host, port) {
|
|
|
1013
1013
|
socket.once("error", () => done(false));
|
|
1014
1014
|
});
|
|
1015
1015
|
}
|
|
1016
|
-
async function waitForProcessExit(pid, timeoutMs =
|
|
1016
|
+
async function waitForProcessExit(pid, timeoutMs = 3e4) {
|
|
1017
1017
|
const deadline = Date.now() + timeoutMs;
|
|
1018
1018
|
while (Date.now() < deadline) {
|
|
1019
|
-
if (!isProcessRunning(pid)) return;
|
|
1019
|
+
if (!isProcessRunning(pid)) return true;
|
|
1020
1020
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1021
1021
|
}
|
|
1022
|
+
return !isProcessRunning(pid);
|
|
1022
1023
|
}
|
|
1023
1024
|
async function waitForPortRelease(host, port, timeoutMs = 1e4) {
|
|
1024
1025
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -1029,16 +1030,24 @@ async function waitForPortRelease(host, port, timeoutMs = 1e4) {
|
|
|
1029
1030
|
return false;
|
|
1030
1031
|
}
|
|
1031
1032
|
async function stopExistingViewer(dbPath, target) {
|
|
1033
|
+
const terminatePid = async (pid) => {
|
|
1034
|
+
try {
|
|
1035
|
+
process.kill(pid, "SIGTERM");
|
|
1036
|
+
return await waitForProcessExit(pid);
|
|
1037
|
+
} catch {
|
|
1038
|
+
return true;
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1032
1041
|
const pidPath = pidFilePath(dbPath);
|
|
1033
1042
|
const record = readViewerPidRecord(dbPath);
|
|
1034
1043
|
const viewerPidFromStats = await lookupViewerPidFromStats(target.host, target.port);
|
|
1035
1044
|
const listenerPid = lookupListeningPid(target.host, target.port);
|
|
1036
1045
|
const viewerPid = pickViewerPidCandidate(viewerPidFromStats, listenerPid);
|
|
1037
1046
|
if (viewerPid && isTrustedViewerPid(viewerPid, target, listenerPid)) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1047
|
+
if (!await terminatePid(viewerPid)) return {
|
|
1048
|
+
stopped: false,
|
|
1049
|
+
pid: viewerPid
|
|
1050
|
+
};
|
|
1042
1051
|
try {
|
|
1043
1052
|
rmSync(pidPath);
|
|
1044
1053
|
} catch {}
|
|
@@ -1051,10 +1060,12 @@ async function stopExistingViewer(dbPath, target) {
|
|
|
1051
1060
|
stopped: false,
|
|
1052
1061
|
pid: null
|
|
1053
1062
|
};
|
|
1054
|
-
if (await respondsLikeCodememViewer(record))
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1063
|
+
if (await respondsLikeCodememViewer(record)) {
|
|
1064
|
+
if (!await terminatePid(record.pid)) return {
|
|
1065
|
+
stopped: false,
|
|
1066
|
+
pid: record.pid
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1058
1069
|
try {
|
|
1059
1070
|
rmSync(pidPath);
|
|
1060
1071
|
} catch {}
|
|
@@ -1144,29 +1155,17 @@ async function startForegroundViewer(invocation) {
|
|
|
1144
1155
|
const sweeper = new RawEventSweeper(store, { observer });
|
|
1145
1156
|
sweeper.start();
|
|
1146
1157
|
const syncAbort = new AbortController();
|
|
1147
|
-
let syncRunning = false;
|
|
1148
1158
|
const syncConfig = readCoordinatorSyncConfig(readCodememConfigFile());
|
|
1149
1159
|
const syncEnabled = syncConfig.syncEnabled;
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
dbPath: resolveDbPath(invocation.dbPath ?? void 0),
|
|
1155
|
-
intervalS: syncIntervalS,
|
|
1156
|
-
host: syncConfig.syncHost,
|
|
1157
|
-
port: syncConfig.syncPort,
|
|
1158
|
-
signal: syncAbort.signal
|
|
1159
|
-
}).catch((err) => {
|
|
1160
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1161
|
-
p.log.error(`Sync daemon failed: ${msg}`);
|
|
1162
|
-
}).finally(() => {
|
|
1163
|
-
syncRunning = false;
|
|
1164
|
-
});
|
|
1165
|
-
}
|
|
1160
|
+
const syncRuntimeStatus = {
|
|
1161
|
+
phase: syncEnabled ? "starting" : "disabled",
|
|
1162
|
+
detail: syncEnabled ? "Waiting for viewer startup to finish" : "Sync is disabled"
|
|
1163
|
+
};
|
|
1166
1164
|
const appOpts = {
|
|
1167
1165
|
storeFactory: () => store,
|
|
1168
1166
|
sweeper,
|
|
1169
|
-
observer
|
|
1167
|
+
observer,
|
|
1168
|
+
getSyncRuntimeStatus: () => syncRuntimeStatus
|
|
1170
1169
|
};
|
|
1171
1170
|
const app = createApp(appOpts);
|
|
1172
1171
|
const dbPath = resolveDbPath(invocation.dbPath ?? void 0);
|
|
@@ -1201,7 +1200,40 @@ async function startForegroundViewer(invocation) {
|
|
|
1201
1200
|
p.log.success(`Listening on http://${info.address}:${info.port}`);
|
|
1202
1201
|
p.log.info(`Database: ${dbPath}`);
|
|
1203
1202
|
p.log.step("Raw event sweeper started");
|
|
1204
|
-
if (
|
|
1203
|
+
if (syncEnabled) {
|
|
1204
|
+
const syncStartDelayMs = 3e3;
|
|
1205
|
+
p.log.step(`Sync daemon will start in background (${syncStartDelayMs / 1e3}s delay)`);
|
|
1206
|
+
setTimeout(() => {
|
|
1207
|
+
syncRuntimeStatus.phase = "starting";
|
|
1208
|
+
syncRuntimeStatus.detail = "Starting sync in background";
|
|
1209
|
+
runSyncDaemon({
|
|
1210
|
+
dbPath: resolveDbPath(invocation.dbPath ?? void 0),
|
|
1211
|
+
intervalS: syncConfig.syncIntervalS,
|
|
1212
|
+
host: syncConfig.syncHost,
|
|
1213
|
+
port: syncConfig.syncPort,
|
|
1214
|
+
signal: syncAbort.signal,
|
|
1215
|
+
onPhaseChange: (phase) => {
|
|
1216
|
+
if (phase === "running") {
|
|
1217
|
+
syncRuntimeStatus.phase = null;
|
|
1218
|
+
syncRuntimeStatus.detail = null;
|
|
1219
|
+
} else {
|
|
1220
|
+
syncRuntimeStatus.phase = phase;
|
|
1221
|
+
syncRuntimeStatus.detail = phase === "starting" ? "Running initial sync in background" : "Stopping sync daemon";
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}).catch((err) => {
|
|
1225
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1226
|
+
syncRuntimeStatus.phase = "error";
|
|
1227
|
+
syncRuntimeStatus.detail = msg;
|
|
1228
|
+
p.log.error(`Sync daemon failed: ${msg}`);
|
|
1229
|
+
}).finally(() => {
|
|
1230
|
+
if (syncRuntimeStatus.phase !== "error") {
|
|
1231
|
+
syncRuntimeStatus.phase = syncAbort.signal.aborted ? "stopping" : null;
|
|
1232
|
+
syncRuntimeStatus.detail = syncAbort.signal.aborted ? "Sync stopped" : null;
|
|
1233
|
+
}
|
|
1234
|
+
});
|
|
1235
|
+
}, syncStartDelayMs).unref();
|
|
1236
|
+
}
|
|
1205
1237
|
});
|
|
1206
1238
|
server.on("error", (err) => {
|
|
1207
1239
|
if (err.code === "EADDRINUSE") p.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);
|
|
@@ -1233,7 +1265,7 @@ async function startForegroundViewer(invocation) {
|
|
|
1233
1265
|
} catch {}
|
|
1234
1266
|
closeStore();
|
|
1235
1267
|
process.exit(1);
|
|
1236
|
-
},
|
|
1268
|
+
}, 3e4).unref();
|
|
1237
1269
|
};
|
|
1238
1270
|
process.on("SIGINT", () => {
|
|
1239
1271
|
forceShutdown();
|
|
@@ -1259,6 +1291,11 @@ async function runServeInvocation(invocation) {
|
|
|
1259
1291
|
return;
|
|
1260
1292
|
}
|
|
1261
1293
|
if (!await waitForPortRelease(invocation.host, invocation.port)) p.log.warn(`Port ${invocation.port} still in use after stop — restart may fail`);
|
|
1294
|
+
} else if (result.pid) {
|
|
1295
|
+
p.intro("codemem viewer");
|
|
1296
|
+
p.log.error(`Viewer is still shutting down (pid ${result.pid})`);
|
|
1297
|
+
process.exitCode = 1;
|
|
1298
|
+
return;
|
|
1262
1299
|
} else if (invocation.mode === "stop") {
|
|
1263
1300
|
p.intro("codemem viewer");
|
|
1264
1301
|
p.outro("No background viewer found");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/help-style.ts","../src/commands/claude-hook-ingest.ts","../src/commands/db.ts","../src/commands/embed.ts","../src/commands/enqueue-raw-event.ts","../src/commands/export-memories.ts","../src/commands/import-memories.ts","../src/commands/mcp.ts","../src/commands/memory.ts","../src/commands/pack.ts","../src/commands/recent.ts","../src/commands/search.ts","../src/commands/serve-invocation.ts","../src/commands/serve.ts","../src/commands/setup-config.ts","../src/commands/setup.ts","../src/commands/stats.ts","../src/commands/sync-helpers.ts","../src/commands/sync.ts","../src/commands/version.ts","../src/index.ts"],"sourcesContent":["/**\n * Shared Commander help style configuration.\n *\n * Applied to every Command instance so subcommand --help\n * output gets the same colors as the root.\n */\n\nimport { styleText } from \"node:util\";\nimport type { HelpConfiguration } from \"commander\";\n\nexport const helpStyle: HelpConfiguration = {\n\tstyleTitle: (str) => styleText(\"bold\", str),\n\tstyleCommandText: (str) => styleText(\"cyan\", str),\n\tstyleCommandDescription: (str) => str,\n\tstyleDescriptionText: (str) => styleText(\"dim\", str),\n\tstyleOptionText: (str) => styleText(\"green\", str),\n\tstyleOptionTerm: (str) => styleText(\"green\", str),\n\tstyleSubcommandText: (str) => styleText(\"cyan\", str),\n\tstyleArgumentText: (str) => styleText(\"yellow\", str),\n};\n","/**\n * codemem claude-hook-ingest — read a single Claude Code hook payload\n * from stdin and enqueue it for processing.\n *\n * Ports codemem/commands/claude_hook_runtime_cmds.py with an HTTP-first\n * strategy: try POST /api/claude-hooks (viewer must be running), then\n * fall back to direct raw-event enqueue via the local store.\n *\n * Usage (from Claude hooks config):\n * echo '{\"hook_event_name\":\"Stop\",\"session_id\":\"...\",\"last_assistant_message\":\"...\"}' \\\n * | codemem claude-hook-ingest\n */\n\nimport { readFileSync } from \"node:fs\";\nimport {\n\tbuildRawEventEnvelopeFromHook,\n\tconnect,\n\tloadSqliteVec,\n\tresolveDbPath,\n\tstripPrivateObj,\n} from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\ntype IngestResult = { inserted: number; skipped: number; via: \"http\" | \"direct\" };\n\ntype IngestOpts = {\n\thost: string;\n\tport: number;\n\tdb?: string;\n\tdbPath?: string;\n};\n\ntype IngestDeps = {\n\thttpIngest?: typeof tryHttpIngest;\n\tdirectIngest?: typeof directEnqueue;\n\tresolveDb?: typeof resolveDbPath;\n};\n\n/** Try to POST the hook payload to the running viewer server. */\nasync function tryHttpIngest(\n\tpayload: Record<string, unknown>,\n\thost: string,\n\tport: number,\n): Promise<{ ok: boolean; inserted: number; skipped: number }> {\n\tconst url = `http://${host}:${port}/api/claude-hooks`;\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(() => controller.abort(), 5000);\n\ttry {\n\t\tconst res = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(payload),\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!res.ok) return { ok: false, inserted: 0, skipped: 0 };\n\t\tconst body = (await res.json()) as Record<string, unknown>;\n\t\treturn {\n\t\t\tok: true,\n\t\t\tinserted: Number(body.inserted ?? 0),\n\t\t\tskipped: Number(body.skipped ?? 0),\n\t\t};\n\t} catch {\n\t\treturn { ok: false, inserted: 0, skipped: 0 };\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n}\n\n/** Fall back to direct raw-event enqueue via the local SQLite store. */\nexport function directEnqueue(\n\tpayload: Record<string, unknown>,\n\tdbPath: string,\n): { inserted: number; skipped: number } {\n\tconst envelope = buildRawEventEnvelopeFromHook(payload);\n\tif (!envelope) return { inserted: 0, skipped: 1 };\n\n\tconst db = connect(dbPath);\n\ttry {\n\t\ttry {\n\t\t\tloadSqliteVec(db);\n\t\t} catch {\n\t\t\t// sqlite-vec not available — non-fatal for raw event enqueue\n\t\t}\n\t\tconst strippedPayload = stripPrivateObj(envelope.payload) as Record<string, unknown>;\n\t\tconst existing = db\n\t\t\t.prepare(\n\t\t\t\t\"SELECT 1 FROM raw_events WHERE source = ? AND stream_id = ? AND event_id = ? LIMIT 1\",\n\t\t\t)\n\t\t\t.get(envelope.source, envelope.session_stream_id, envelope.event_id);\n\t\tif (existing) return { inserted: 0, skipped: 0 };\n\n\t\tdb.prepare(\n\t\t\t`INSERT INTO raw_events(\n\t\t\t\tsource, stream_id, opencode_session_id, event_id, event_seq,\n\t\t\t\tevent_type, ts_wall_ms, payload_json, created_at\n\t\t\t) VALUES (?, ?, ?, ?, (\n\t\t\t\tSELECT COALESCE(MAX(event_seq), 0) + 1\n\t\t\t\tFROM raw_events WHERE source = ? AND stream_id = ?\n\t\t\t), ?, ?, ?, datetime('now'))`,\n\t\t).run(\n\t\t\tenvelope.source,\n\t\t\tenvelope.session_stream_id,\n\t\t\tenvelope.opencode_session_id,\n\t\t\tenvelope.event_id,\n\t\t\tenvelope.source,\n\t\t\tenvelope.session_stream_id,\n\t\t\t\"claude.hook\",\n\t\t\tenvelope.ts_wall_ms,\n\t\t\tJSON.stringify(strippedPayload),\n\t\t);\n\n\t\t// Query actual max event_seq for this stream to keep session metadata in sync\n\t\tconst maxSeqRow = db\n\t\t\t.prepare(\n\t\t\t\t\"SELECT COALESCE(MAX(event_seq), 0) AS max_seq FROM raw_events WHERE source = ? AND stream_id = ?\",\n\t\t\t)\n\t\t\t.get(envelope.source, envelope.session_stream_id) as { max_seq: number };\n\t\tconst currentMaxSeq = maxSeqRow.max_seq;\n\n\t\t// Upsert session metadata with accurate sequence tracking\n\t\tdb.prepare(\n\t\t\t`INSERT INTO raw_event_sessions(\n\t\t\t\tsource, stream_id, opencode_session_id, cwd, project, started_at,\n\t\t\t\tlast_seen_ts_wall_ms, last_received_event_seq, last_flushed_event_seq, updated_at\n\t\t\t) VALUES (?, ?, ?, ?, ?, ?, ?, ?, -1, datetime('now'))\n\t\t\tON CONFLICT(source, stream_id) DO UPDATE SET\n\t\t\t\tcwd = COALESCE(excluded.cwd, cwd),\n\t\t\t\tproject = COALESCE(excluded.project, project),\n\t\t\t\tstarted_at = COALESCE(excluded.started_at, started_at),\n\t\t\t\tlast_seen_ts_wall_ms = MAX(COALESCE(excluded.last_seen_ts_wall_ms, 0), COALESCE(last_seen_ts_wall_ms, 0)),\n\t\t\t\tlast_received_event_seq = MAX(excluded.last_received_event_seq, last_received_event_seq),\n\t\t\t\tupdated_at = datetime('now')`,\n\t\t).run(\n\t\t\tenvelope.source,\n\t\t\tenvelope.session_stream_id,\n\t\t\tenvelope.opencode_session_id,\n\t\t\tenvelope.cwd,\n\t\t\tenvelope.project,\n\t\t\tenvelope.started_at,\n\t\t\tenvelope.ts_wall_ms,\n\t\t\tcurrentMaxSeq,\n\t\t);\n\n\t\treturn { inserted: 1, skipped: 0 };\n\t} finally {\n\t\tdb.close();\n\t}\n}\n\n/**\n * Ingest one Claude hook payload using the TS contract:\n * HTTP enqueue first, then direct local enqueue fallback.\n *\n * This path intentionally does not implement file-spool/lock durability.\n */\nexport async function ingestClaudeHookPayload(\n\tpayload: Record<string, unknown>,\n\topts: IngestOpts,\n\tdeps: IngestDeps = {},\n): Promise<IngestResult> {\n\tconst httpIngest = deps.httpIngest ?? tryHttpIngest;\n\tconst directIngest = deps.directIngest ?? directEnqueue;\n\tconst resolveDb = deps.resolveDb ?? resolveDbPath;\n\n\tconst httpResult = await httpIngest(payload, opts.host, opts.port);\n\tif (httpResult.ok) {\n\t\treturn { inserted: httpResult.inserted, skipped: httpResult.skipped, via: \"http\" };\n\t}\n\n\tconst dbPath = resolveDb(opts.db ?? opts.dbPath);\n\tconst directResult = directIngest(payload, dbPath);\n\treturn { ...directResult, via: \"direct\" };\n}\n\nexport const claudeHookIngestCommand = new Command(\"claude-hook-ingest\")\n\t.configureHelp(helpStyle)\n\t.description(\"Ingest Claude hook payload: HTTP first, direct DB fallback\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--host <host>\", \"viewer server host\", \"127.0.0.1\")\n\t.option(\"--port <port>\", \"viewer server port\", \"38888\")\n\t.action(async (opts: { db?: string; dbPath?: string; host: string; port: string }) => {\n\t\t// Read payload from stdin\n\t\tlet raw: string;\n\t\ttry {\n\t\t\traw = readFileSync(0, \"utf8\").trim();\n\t\t} catch {\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tif (!raw) {\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\n\t\tlet payload: Record<string, unknown>;\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\t\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpayload = parsed as Record<string, unknown>;\n\t\t} catch {\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\n\t\tconst port = Number.parseInt(opts.port, 10);\n\t\tconst host = opts.host;\n\n\t\ttry {\n\t\t\tconst result = await ingestClaudeHookPayload(payload, {\n\t\t\t\thost,\n\t\t\t\tport,\n\t\t\t\tdb: opts.db,\n\t\t\t\tdbPath: opts.dbPath,\n\t\t\t});\n\t\t\tconsole.log(JSON.stringify(result));\n\t\t} catch {\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t});\n","import { statSync } from \"node:fs\";\nimport * as p from \"@clack/prompts\";\nimport {\n\tbackfillTagsText,\n\tconnect,\n\tdeactivateLowSignalMemories,\n\tdeactivateLowSignalObservations,\n\tgetRawEventStatus,\n\tinitDatabase,\n\tMemoryStore,\n\trawEventsGate,\n\tresolveDbPath,\n\tresolveProject,\n\tretryRawEventFailures,\n\tvacuumDatabase,\n} from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction parseOptionalPositiveInt(value: string | undefined): number | undefined {\n\tif (!value) return undefined;\n\tconst parsed = Number.parseInt(value, 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\tthrow new Error(`invalid positive integer: ${value}`);\n\t}\n\treturn parsed;\n}\n\nfunction parseKindsCsv(value: string | undefined): string[] | undefined {\n\tif (!value) return undefined;\n\tconst kinds = value\n\t\t.split(\",\")\n\t\t.map((kind) => kind.trim())\n\t\t.filter((kind) => kind.length > 0);\n\treturn kinds.length > 0 ? kinds : undefined;\n}\n\nexport const dbCommand = new Command(\"db\")\n\t.configureHelp(helpStyle)\n\t.description(\"Database maintenance\");\n\ndbCommand\n\t.addCommand(\n\t\tnew Command(\"init\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Verify the SQLite database is present and schema-ready\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.action((opts: { db?: string; dbPath?: string }) => {\n\t\t\t\tconst result = initDatabase(opts.db ?? opts.dbPath);\n\t\t\t\tp.intro(\"codemem db init\");\n\t\t\t\tp.log.success(`Database ready: ${result.path}`);\n\t\t\t\tp.outro(`Size: ${result.sizeBytes.toLocaleString()} bytes`);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"vacuum\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Run VACUUM on the SQLite database\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.action((opts: { db?: string; dbPath?: string }) => {\n\t\t\t\tconst result = vacuumDatabase(opts.db ?? opts.dbPath);\n\t\t\t\tp.intro(\"codemem db vacuum\");\n\t\t\t\tp.log.success(`Vacuumed: ${result.path}`);\n\t\t\t\tp.outro(`Size: ${result.sizeBytes.toLocaleString()} bytes`);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"raw-events-status\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Show pending raw-event backlog by source stream\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"-n, --limit <n>\", \"max rows to show\", \"25\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; limit: string; json?: boolean }) => {\n\t\t\t\tconst result = getRawEventStatus(\n\t\t\t\t\topts.db ?? opts.dbPath,\n\t\t\t\t\tNumber.parseInt(opts.limit, 10) || 25,\n\t\t\t\t);\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem db raw-events-status\");\n\t\t\t\tp.log.info(\n\t\t\t\t\t`Totals: ${result.totals.pending.toLocaleString()} pending across ${result.totals.sessions.toLocaleString()} session(s)`,\n\t\t\t\t);\n\t\t\t\tif (result.items.length === 0) {\n\t\t\t\t\tp.outro(\"No pending raw events\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const item of result.items) {\n\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t`${item.source}:${item.stream_id} pending=${Math.max(0, item.last_received_event_seq - item.last_flushed_event_seq)} ` +\n\t\t\t\t\t\t\t`received=${item.last_received_event_seq} flushed=${item.last_flushed_event_seq} project=${item.project ?? \"\"}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tp.outro(\"done\");\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"raw-events-retry\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Requeue failed raw-event flush batches\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"-n, --limit <n>\", \"max failed batches to requeue\", \"25\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; limit: string }) => {\n\t\t\t\tconst result = retryRawEventFailures(\n\t\t\t\t\topts.db ?? opts.dbPath,\n\t\t\t\t\tNumber.parseInt(opts.limit, 10) || 25,\n\t\t\t\t);\n\t\t\t\tp.intro(\"codemem db raw-events-retry\");\n\t\t\t\tp.outro(`Requeued ${result.retried.toLocaleString()} failed batch(es)`);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"raw-events-gate\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Validate raw-event reliability thresholds (non-zero exit on failure)\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--min-flush-success-rate <rate>\", \"minimum flush success rate\", \"0.95\")\n\t\t\t.option(\"--max-dropped-event-rate <rate>\", \"maximum dropped event rate\", \"0.05\")\n\t\t\t.option(\"--min-session-boundary-accuracy <rate>\", \"minimum session boundary accuracy\", \"0.9\")\n\t\t\t.option(\"--window-hours <hours>\", \"lookback window in hours\", \"24\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tminFlushSuccessRate: string;\n\t\t\t\t\tmaxDroppedEventRate: string;\n\t\t\t\t\tminSessionBoundaryAccuracy: string;\n\t\t\t\t\twindowHours: string;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst result = rawEventsGate(opts.db ?? opts.dbPath, {\n\t\t\t\t\t\tminFlushSuccessRate: Number.parseFloat(opts.minFlushSuccessRate),\n\t\t\t\t\t\tmaxDroppedEventRate: Number.parseFloat(opts.maxDroppedEventRate),\n\t\t\t\t\t\tminSessionBoundaryAccuracy: Number.parseFloat(opts.minSessionBoundaryAccuracy),\n\t\t\t\t\t\twindowHours: Number.parseFloat(opts.windowHours),\n\t\t\t\t\t});\n\n\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\tif (!result.passed) process.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tp.intro(\"codemem db raw-events-gate\");\n\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`flush_success_rate: ${result.metrics.rates.flush_success_rate.toFixed(4)}`,\n\t\t\t\t\t\t\t`dropped_event_rate: ${result.metrics.rates.dropped_event_rate.toFixed(4)}`,\n\t\t\t\t\t\t\t`session_boundary_accuracy: ${result.metrics.rates.session_boundary_accuracy.toFixed(4)}`,\n\t\t\t\t\t\t\t`window_hours: ${result.metrics.window_hours ?? \"all\"}`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (result.passed) {\n\t\t\t\t\t\tp.outro(\"reliability gate passed\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const f of result.failures) {\n\t\t\t\t\t\t\tp.log.error(f);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.outro(\"reliability gate FAILED\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"rename-project\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Rename a project across sessions and related tables\")\n\t\t\t.argument(\"<old-name>\", \"current project name\")\n\t\t\t.argument(\"<new-name>\", \"new project name\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--apply\", \"apply changes (default is dry-run)\")\n\t\t\t.action(\n\t\t\t\t(\n\t\t\t\t\toldName: string,\n\t\t\t\t\tnewName: string,\n\t\t\t\t\topts: { db?: string; dbPath?: string; apply?: boolean },\n\t\t\t\t) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dryRun = !opts.apply;\n\t\t\t\t\t\tconst escapedOld = oldName.replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\");\n\t\t\t\t\t\tconst suffixPattern = `%/${escapedOld}`;\n\t\t\t\t\t\tconst tables = [\"sessions\", \"raw_event_sessions\"] as const;\n\t\t\t\t\t\tconst counts: Record<string, number> = {};\n\t\t\t\t\t\tconst run = () => {\n\t\t\t\t\t\t\tfor (const table of tables) {\n\t\t\t\t\t\t\t\tconst rows = store.db\n\t\t\t\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\t\t\t`SELECT COUNT(*) as cnt FROM ${table} WHERE project = ? OR project LIKE ? ESCAPE '\\\\'`,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.get(oldName, suffixPattern) as { cnt: number };\n\t\t\t\t\t\t\t\tcounts[table] = rows.cnt;\n\t\t\t\t\t\t\t\tif (!dryRun && rows.cnt > 0) {\n\t\t\t\t\t\t\t\t\tstore.db\n\t\t\t\t\t\t\t\t\t\t.prepare(`UPDATE ${table} SET project = ? WHERE project = ?`)\n\t\t\t\t\t\t\t\t\t\t.run(newName, oldName);\n\t\t\t\t\t\t\t\t\tstore.db\n\t\t\t\t\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\t\t\t\t`UPDATE ${table} SET project = ? WHERE project LIKE ? ESCAPE '\\\\' AND project != ?`,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t.run(newName, suffixPattern, newName);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\t\trun();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstore.db.transaction(run)();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst action = dryRun ? \"Will rename\" : \"Renamed\";\n\t\t\t\t\t\tp.intro(\"codemem db rename-project\");\n\t\t\t\t\t\tp.log.info(`${action} ${oldName} → ${newName}`);\n\t\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t`Sessions: ${counts.sessions}`,\n\t\t\t\t\t\t\t\t`Raw event sessions: ${counts.raw_event_sessions}`,\n\t\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\t\tp.outro(\"Pass --apply to execute\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"normalize-projects\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Normalize path-like project identifiers to their basename\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--apply\", \"apply changes (default is dry-run)\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; apply?: boolean }) => {\n\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\ttry {\n\t\t\t\t\tconst dryRun = !opts.apply;\n\t\t\t\t\tconst tables = [\"sessions\", \"raw_event_sessions\"] as const;\n\t\t\t\t\tconst rewrites: Map<string, string> = new Map();\n\t\t\t\t\tconst counts: Record<string, number> = {};\n\n\t\t\t\t\tconst run = () => {\n\t\t\t\t\t\tfor (const table of tables) {\n\t\t\t\t\t\t\tconst projects = store.db\n\t\t\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\t\t`SELECT DISTINCT project FROM ${table} WHERE project IS NOT NULL AND project LIKE '%/%'`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.all() as Array<{ project: string }>;\n\t\t\t\t\t\t\tlet updated = 0;\n\t\t\t\t\t\t\tfor (const row of projects) {\n\t\t\t\t\t\t\t\tconst basename = row.project.split(\"/\").pop() ?? row.project;\n\t\t\t\t\t\t\t\tif (basename !== row.project) {\n\t\t\t\t\t\t\t\t\trewrites.set(row.project, basename);\n\t\t\t\t\t\t\t\t\tif (!dryRun) {\n\t\t\t\t\t\t\t\t\t\tconst info = store.db\n\t\t\t\t\t\t\t\t\t\t\t.prepare(`UPDATE ${table} SET project = ? WHERE project = ?`)\n\t\t\t\t\t\t\t\t\t\t\t.run(basename, row.project);\n\t\t\t\t\t\t\t\t\t\tupdated += info.changes;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst cnt = store.db\n\t\t\t\t\t\t\t\t\t\t\t.prepare(`SELECT COUNT(*) as cnt FROM ${table} WHERE project = ?`)\n\t\t\t\t\t\t\t\t\t\t\t.get(row.project) as { cnt: number };\n\t\t\t\t\t\t\t\t\t\tupdated += cnt.cnt;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcounts[table] = updated;\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\trun();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstore.db.transaction(run)();\n\t\t\t\t\t}\n\n\t\t\t\t\tp.intro(\"codemem db normalize-projects\");\n\t\t\t\t\tp.log.info(`Dry run: ${dryRun}`);\n\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`Sessions to update: ${counts.sessions}`,\n\t\t\t\t\t\t\t`Raw event sessions to update: ${counts.raw_event_sessions}`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t\tif (rewrites.size > 0) {\n\t\t\t\t\t\tp.log.info(\"Rewritten paths:\");\n\t\t\t\t\t\tfor (const [from, to] of [...rewrites.entries()].sort()) {\n\t\t\t\t\t\t\tp.log.message(` ${from} → ${to}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\tp.outro(\"Pass --apply to execute\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tstore.close();\n\t\t\t\t}\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"size-report\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Show SQLite file size and major storage consumers\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"number of largest tables/indexes to show\", \"12\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; limit: string; json?: boolean }) => {\n\t\t\t\tconst dbPath = resolveDbPath(opts.db ?? opts.dbPath);\n\t\t\t\tconst db = connect(dbPath);\n\t\t\t\ttry {\n\t\t\t\t\tconst limit = Math.max(1, Number.parseInt(opts.limit, 10) || 12);\n\t\t\t\t\tconst fileSizeBytes = statSync(dbPath).size;\n\t\t\t\t\tconst pageInfo = db\n\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\"SELECT page_count * page_size as total FROM pragma_page_count, pragma_page_size\",\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.get() as { total: number } | undefined;\n\t\t\t\t\tconst freePages = db.prepare(\"SELECT freelist_count FROM pragma_freelist_count\").get() as\n\t\t\t\t\t\t| { freelist_count: number }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tconst pageSize = db.prepare(\"PRAGMA page_size\").get() as\n\t\t\t\t\t\t| { page_size: number }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tconst tables = db\n\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t`SELECT name, SUM(pgsize) as size_bytes\n\t\t\t\t\t\t\t FROM dbstat\n\t\t\t\t\t\t\t GROUP BY name\n\t\t\t\t\t\t\t ORDER BY size_bytes DESC\n\t\t\t\t\t\t\t LIMIT ?`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.all(limit) as Array<{ name: string; size_bytes: number }>;\n\n\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfile_size_bytes: fileSizeBytes,\n\t\t\t\t\t\t\t\t\tdb_size_bytes: pageInfo?.total ?? 0,\n\t\t\t\t\t\t\t\t\tfree_bytes: (freePages?.freelist_count ?? 0) * (pageSize?.page_size ?? 4096),\n\t\t\t\t\t\t\t\t\ttables: tables.map((t) => ({ name: t.name, size_bytes: t.size_bytes })),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tp.intro(\"codemem db size-report\");\n\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`File size: ${formatBytes(fileSizeBytes)}`,\n\t\t\t\t\t\t\t`DB size: ${formatBytes(pageInfo?.total ?? 0)}`,\n\t\t\t\t\t\t\t`Free space: ${formatBytes((freePages?.freelist_count ?? 0) * (pageSize?.page_size ?? 4096))}`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t\tif (tables.length > 0) {\n\t\t\t\t\t\tp.log.info(\"Largest objects:\");\n\t\t\t\t\t\tfor (const t of tables) {\n\t\t\t\t\t\t\tp.log.message(` ${t.name.padEnd(40)} ${formatBytes(t.size_bytes).padStart(10)}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t} finally {\n\t\t\t\t\tdb.close();\n\t\t\t\t}\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"backfill-tags\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Populate tags_text for memories where tags are empty\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"max memories to check\")\n\t\t\t.option(\"--since <iso>\", \"only memories created at/after this ISO timestamp\")\n\t\t\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t\t\t.option(\"--all-projects\", \"backfill across all projects\")\n\t\t\t.option(\"--inactive\", \"include inactive memories\")\n\t\t\t.option(\"--dry-run\", \"preview updates without writing\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tsince?: string;\n\t\t\t\t\tproject?: string;\n\t\t\t\t\tallProjects?: boolean;\n\t\t\t\t\tinactive?: boolean;\n\t\t\t\t\tdryRun?: boolean;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\t\t\tconst project =\n\t\t\t\t\t\t\topts.allProjects === true\n\t\t\t\t\t\t\t\t? null\n\t\t\t\t\t\t\t\t: opts.project?.trim() ||\n\t\t\t\t\t\t\t\t\tprocess.env.CODEMEM_PROJECT?.trim() ||\n\t\t\t\t\t\t\t\t\tresolveProject(process.cwd(), null);\n\t\t\t\t\t\tconst result = backfillTagsText(store.db, {\n\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\tsince: opts.since ?? null,\n\t\t\t\t\t\t\tproject,\n\t\t\t\t\t\t\tactiveOnly: !opts.inactive,\n\t\t\t\t\t\t\tdryRun: opts.dryRun === true,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst action = opts.dryRun ? \"Would update\" : \"Updated\";\n\t\t\t\t\t\tp.intro(\"codemem db backfill-tags\");\n\t\t\t\t\t\tp.log.success(`${action} ${result.updated} memories (skipped ${result.skipped})`);\n\t\t\t\t\t\tp.outro(`Checked ${result.checked} memories`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"prune-observations\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Deactivate low-signal observations (does not delete rows)\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"max observations to check\")\n\t\t\t.option(\"--dry-run\", \"preview deactivations without writing\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tdryRun?: boolean;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\t\t\tconst result = deactivateLowSignalObservations(\n\t\t\t\t\t\t\tstore.db,\n\t\t\t\t\t\t\tlimit ?? null,\n\t\t\t\t\t\t\topts.dryRun === true,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst action = opts.dryRun ? \"Would deactivate\" : \"Deactivated\";\n\t\t\t\t\t\tp.intro(\"codemem db prune-observations\");\n\t\t\t\t\t\tp.outro(`${action} ${result.deactivated} of ${result.checked} observations`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"prune-memories\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Deactivate low-signal memories across selected kinds\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"max memories to check\")\n\t\t\t.option(\"--kinds <csv>\", \"comma-separated memory kinds (default set when omitted)\")\n\t\t\t.option(\"--dry-run\", \"preview deactivations without writing\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tkinds?: string;\n\t\t\t\t\tdryRun?: boolean;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\t\t\tconst kinds = parseKindsCsv(opts.kinds);\n\t\t\t\t\t\tconst result = deactivateLowSignalMemories(store.db, {\n\t\t\t\t\t\t\tkinds,\n\t\t\t\t\t\t\tlimit: limit ?? null,\n\t\t\t\t\t\t\tdryRun: opts.dryRun === true,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst action = opts.dryRun ? \"Would deactivate\" : \"Deactivated\";\n\t\t\t\t\t\tp.intro(\"codemem db prune-memories\");\n\t\t\t\t\t\tp.outro(`${action} ${result.deactivated} of ${result.checked} memories`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t);\n","import * as p from \"@clack/prompts\";\nimport { backfillVectors, MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction parseOptionalPositiveInt(value: string | undefined): number | undefined {\n\tif (!value) return undefined;\n\tconst parsed = Number.parseInt(value, 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\tthrow new Error(`invalid positive integer: ${value}`);\n\t}\n\treturn parsed;\n}\n\nexport function resolveEmbedProjectScope(\n\tcwd: string,\n\tprojectOpt: string | undefined,\n\tallProjects: boolean | undefined,\n): string | null {\n\tif (allProjects === true) return null;\n\tconst explicit = projectOpt?.trim();\n\tif (explicit) return explicit;\n\tconst envProject = process.env.CODEMEM_PROJECT?.trim();\n\tif (envProject) return envProject;\n\treturn resolveProject(cwd, null);\n}\n\nexport const embedCommand = new Command(\"embed\")\n\t.configureHelp(helpStyle)\n\t.description(\"Backfill semantic embeddings\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--limit <n>\", \"max memories to check\")\n\t.option(\"--since <iso>\", \"only memories created at/after this ISO timestamp\")\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"embed across all projects\")\n\t.option(\"--inactive\", \"include inactive memories\")\n\t.option(\"--dry-run\", \"preview work without writing vectors\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action(\n\t\tasync (opts: {\n\t\t\tdb?: string;\n\t\t\tdbPath?: string;\n\t\t\tlimit?: string;\n\t\t\tsince?: string;\n\t\t\tproject?: string;\n\t\t\tallProjects?: boolean;\n\t\t\tinactive?: boolean;\n\t\t\tdryRun?: boolean;\n\t\t\tjson?: boolean;\n\t\t}) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\tconst project = resolveEmbedProjectScope(process.cwd(), opts.project, opts.allProjects);\n\n\t\t\t\tconst result = await backfillVectors(store.db, {\n\t\t\t\t\tlimit,\n\t\t\t\t\tsince: opts.since ?? null,\n\t\t\t\t\tproject,\n\t\t\t\t\tactiveOnly: !opts.inactive,\n\t\t\t\t\tdryRun: opts.dryRun === true,\n\t\t\t\t});\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst action = opts.dryRun ? \"Would embed\" : \"Embedded\";\n\t\t\t\tp.intro(\"codemem embed\");\n\t\t\t\tp.log.success(\n\t\t\t\t\t`${action} ${result.embedded} vectors (${result.inserted} inserted, ${result.skipped} skipped)`,\n\t\t\t\t);\n\t\t\t\tp.outro(`Checked ${result.checked} memories`);\n\t\t\t} catch (error) {\n\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n","import { MemoryStore, resolveDbPath, stripPrivateObj } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nconst SESSION_ID_KEYS = [\n\t\"session_stream_id\",\n\t\"session_id\",\n\t\"stream_id\",\n\t\"opencode_session_id\",\n] as const;\n\nfunction resolveSessionStreamId(payload: Record<string, unknown>): string | null {\n\tconst values = new Map<string, string>();\n\tfor (const key of SESSION_ID_KEYS) {\n\t\tconst value = payload[key];\n\t\tif (typeof value !== \"string\") continue;\n\t\tconst text = value.trim();\n\t\tif (text) values.set(key, text);\n\t}\n\tif (values.size === 0) return null;\n\tconst unique = new Set(values.values());\n\tif (unique.size > 1) throw new Error(\"conflicting session id fields\");\n\tfor (const key of SESSION_ID_KEYS) {\n\t\tconst value = values.get(key);\n\t\tif (value) return value;\n\t}\n\treturn null;\n}\n\nasync function readStdinJson(): Promise<Record<string, unknown>> {\n\tconst chunks: Buffer[] = [];\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n\t}\n\tconst raw = Buffer.concat(chunks).toString(\"utf-8\").trim();\n\tif (!raw) throw new Error(\"stdin JSON required\");\n\tconst parsed = JSON.parse(raw) as unknown;\n\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(\"payload must be an object\");\n\t}\n\treturn parsed as Record<string, unknown>;\n}\n\nexport const enqueueRawEventCommand = new Command(\"enqueue-raw-event\")\n\t.configureHelp(helpStyle)\n\t.description(\"Enqueue one raw event from stdin into the durable queue\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.action(async (opts: { db?: string; dbPath?: string }) => {\n\t\tconst payload = await readStdinJson();\n\t\tconst sessionId = resolveSessionStreamId(payload);\n\t\tif (!sessionId) throw new Error(\"session id required\");\n\t\tif (sessionId.startsWith(\"msg_\")) throw new Error(\"invalid session id\");\n\n\t\tconst eventType = typeof payload.event_type === \"string\" ? payload.event_type.trim() : \"\";\n\t\tif (!eventType) throw new Error(\"event_type required\");\n\n\t\tconst cwd = typeof payload.cwd === \"string\" ? payload.cwd : null;\n\t\tconst project = typeof payload.project === \"string\" ? payload.project : null;\n\t\tconst startedAt = typeof payload.started_at === \"string\" ? payload.started_at : null;\n\t\tconst tsWallMs = Number.isFinite(Number(payload.ts_wall_ms))\n\t\t\t? Math.floor(Number(payload.ts_wall_ms))\n\t\t\t: null;\n\t\tconst tsMonoMs = Number.isFinite(Number(payload.ts_mono_ms))\n\t\t\t? Number(payload.ts_mono_ms)\n\t\t\t: null;\n\t\tconst eventId = typeof payload.event_id === \"string\" ? payload.event_id.trim() : \"\";\n\t\tconst eventPayload =\n\t\t\tpayload.payload && typeof payload.payload === \"object\" && !Array.isArray(payload.payload)\n\t\t\t\t? (stripPrivateObj(payload.payload) as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\ttry {\n\t\t\tstore.updateRawEventSessionMeta({\n\t\t\t\topencodeSessionId: sessionId,\n\t\t\t\tsource: \"opencode\",\n\t\t\t\tcwd,\n\t\t\t\tproject,\n\t\t\t\tstartedAt,\n\t\t\t\tlastSeenTsWallMs: tsWallMs,\n\t\t\t});\n\t\t\tstore.recordRawEventsBatch(sessionId, [\n\t\t\t\t{\n\t\t\t\t\tevent_id: eventId,\n\t\t\t\t\tevent_type: eventType,\n\t\t\t\t\tpayload: eventPayload,\n\t\t\t\t\tts_wall_ms: tsWallMs,\n\t\t\t\t\tts_mono_ms: tsMonoMs,\n\t\t\t\t},\n\t\t\t]);\n\t\t} finally {\n\t\t\tstore.close();\n\t\t}\n\t});\n","import { writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { exportMemories, resolveDbPath } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction expandUserPath(value: string): string {\n\treturn value.startsWith(\"~/\") ? join(homedir(), value.slice(2)) : value;\n}\n\nexport const exportMemoriesCommand = new Command(\"export-memories\")\n\t.configureHelp(helpStyle)\n\t.description(\"Export memories to a JSON file for sharing or backup\")\n\t.argument(\"<output>\", \"output file path (use '-' for stdout)\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--project <project>\", \"filter by project (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"export all projects\")\n\t.option(\"--include-inactive\", \"include deactivated memories\")\n\t.option(\"--since <iso>\", \"only export memories created after this ISO timestamp\")\n\t.action(\n\t\t(\n\t\t\toutput: string,\n\t\t\topts: {\n\t\t\t\tdb?: string;\n\t\t\t\tdbPath?: string;\n\t\t\t\tproject?: string;\n\t\t\t\tallProjects?: boolean;\n\t\t\t\tincludeInactive?: boolean;\n\t\t\t\tsince?: string;\n\t\t\t},\n\t\t) => {\n\t\t\tconst payload = exportMemories({\n\t\t\t\tdbPath: resolveDbPath(opts.db ?? opts.dbPath),\n\t\t\t\tproject: opts.project,\n\t\t\t\tallProjects: opts.allProjects,\n\t\t\t\tincludeInactive: opts.includeInactive,\n\t\t\t\tsince: opts.since,\n\t\t\t});\n\t\t\tconst text = `${JSON.stringify(payload, null, 2)}\\n`;\n\t\t\tif (output === \"-\") {\n\t\t\t\tprocess.stdout.write(text);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst outputPath = expandUserPath(output);\n\t\t\twriteFileSync(outputPath, text, \"utf8\");\n\t\t\tp.intro(\"codemem export-memories\");\n\t\t\tp.log.success(\n\t\t\t\t[\n\t\t\t\t\t`Output: ${outputPath}`,\n\t\t\t\t\t`Sessions: ${payload.sessions.length.toLocaleString()}`,\n\t\t\t\t\t`Memories: ${payload.memory_items.length.toLocaleString()}`,\n\t\t\t\t\t`Summaries: ${payload.session_summaries.length.toLocaleString()}`,\n\t\t\t\t\t`Prompts: ${payload.user_prompts.length.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tp.outro(\"done\");\n\t\t},\n\t);\n","import * as p from \"@clack/prompts\";\nimport type { ExportPayload } from \"@codemem/core\";\nimport { importMemories, readImportPayload, resolveDbPath } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const importMemoriesCommand = new Command(\"import-memories\")\n\t.configureHelp(helpStyle)\n\t.description(\"Import memories from an exported JSON file\")\n\t.argument(\"<inputFile>\", \"input JSON file (use '-' for stdin)\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--remap-project <path>\", \"remap all projects to this path on import\")\n\t.option(\"--dry-run\", \"preview import without writing\")\n\t.action(\n\t\t(\n\t\t\tinputFile: string,\n\t\t\topts: { db?: string; dbPath?: string; remapProject?: string; dryRun?: boolean },\n\t\t) => {\n\t\t\tlet payload: ExportPayload;\n\t\t\ttry {\n\t\t\t\tpayload = readImportPayload(inputFile);\n\t\t\t} catch (error) {\n\t\t\t\tp.log.error(error instanceof Error ? error.message : \"Invalid import file\");\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tp.intro(\"codemem import-memories\");\n\t\t\tp.log.info(\n\t\t\t\t[\n\t\t\t\t\t`Export version: ${payload.version}`,\n\t\t\t\t\t`Exported at: ${payload.exported_at}`,\n\t\t\t\t\t`Sessions: ${payload.sessions.length.toLocaleString()}`,\n\t\t\t\t\t`Memories: ${payload.memory_items.length.toLocaleString()}`,\n\t\t\t\t\t`Summaries: ${payload.session_summaries.length.toLocaleString()}`,\n\t\t\t\t\t`Prompts: ${payload.user_prompts.length.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\n\t\t\tconst result = importMemories(payload, {\n\t\t\t\tdbPath: resolveDbPath(opts.db ?? opts.dbPath),\n\t\t\t\tremapProject: opts.remapProject,\n\t\t\t\tdryRun: opts.dryRun,\n\t\t\t});\n\n\t\t\tif (result.dryRun) {\n\t\t\t\tp.outro(\"dry run complete\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tp.log.success(\n\t\t\t\t[\n\t\t\t\t\t`Imported sessions: ${result.sessions.toLocaleString()}`,\n\t\t\t\t\t`Imported prompts: ${result.user_prompts.toLocaleString()}`,\n\t\t\t\t\t`Imported memories: ${result.memory_items.toLocaleString()}`,\n\t\t\t\t\t`Imported summaries: ${result.session_summaries.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tp.outro(\"done\");\n\t\t},\n\t);\n","import { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const mcpCommand = new Command(\"mcp\")\n\t.configureHelp(helpStyle)\n\t.description(\"Start the MCP stdio server\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.action(async (opts: { db?: string; dbPath?: string }) => {\n\t\tconst dbPath = opts.db ?? opts.dbPath;\n\t\tif (dbPath) process.env.CODEMEM_DB = dbPath;\n\t\t// Dynamic import — MCP server is its own entry point\n\t\tawait import(\"@codemem/mcp\");\n\t});\n","/**\n * Memory management CLI commands — show, forget, remember.\n *\n * Ports codemem/commands/memory_cmds.py (show_cmd, forget_cmd, remember_cmd).\n * Compact and inject are deferred — compact requires the summarizer pipeline,\n * and inject is just pack_text output which the existing pack command covers.\n */\n\nimport * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction collectWorkingSetFile(value: string, previous: string[]): string[] {\n\treturn [...previous, value];\n}\n\n/** Parse a strict positive integer, rejecting prefixes like \"12abc\". */\nfunction parseStrictPositiveId(value: string): number | null {\n\tif (!/^\\d+$/.test(value.trim())) return null;\n\tconst n = Number(value.trim());\n\treturn Number.isFinite(n) && n >= 1 && Number.isInteger(n) ? n : null;\n}\n\nfunction showMemoryAction(idStr: string, opts: { db?: string; dbPath?: string }): void {\n\tconst memoryId = parseStrictPositiveId(idStr);\n\tif (memoryId === null) {\n\t\tp.log.error(`Invalid memory ID: ${idStr}`);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\ttry {\n\t\tconst item = store.get(memoryId);\n\t\tif (!item) {\n\t\t\tp.log.error(`Memory ${memoryId} not found`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(JSON.stringify(item, null, 2));\n\t} finally {\n\t\tstore.close();\n\t}\n}\n\nfunction forgetMemoryAction(idStr: string, opts: { db?: string; dbPath?: string }): void {\n\tconst memoryId = parseStrictPositiveId(idStr);\n\tif (memoryId === null) {\n\t\tp.log.error(`Invalid memory ID: ${idStr}`);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\ttry {\n\t\tstore.forget(memoryId);\n\t\tp.log.success(`Memory ${memoryId} marked inactive`);\n\t} finally {\n\t\tstore.close();\n\t}\n}\n\ninterface RememberMemoryOptions {\n\tkind: string;\n\ttitle: string;\n\tbody: string;\n\ttags?: string[];\n\tproject?: string;\n\tdb?: string;\n\tdbPath?: string;\n}\n\nasync function rememberMemoryAction(opts: RememberMemoryOptions): Promise<void> {\n\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\tlet sessionId: number | null = null;\n\ttry {\n\t\tconst project = resolveProject(process.cwd(), opts.project ?? null);\n\t\tsessionId = store.startSession({\n\t\t\tcwd: process.cwd(),\n\t\t\tproject,\n\t\t\tuser: process.env.USER ?? \"unknown\",\n\t\t\ttoolVersion: \"manual\",\n\t\t\tmetadata: { manual: true },\n\t\t});\n\t\tconst memId = store.remember(sessionId, opts.kind, opts.title, opts.body, 0.5, opts.tags);\n\t\tawait store.flushPendingVectorWrites();\n\t\tstore.endSession(sessionId, { manual: true });\n\t\tp.log.success(`Stored memory ${memId}`);\n\t} catch (err) {\n\t\tif (sessionId !== null) {\n\t\t\ttry {\n\t\t\t\tstore.endSession(sessionId, { manual: true, error: true });\n\t\t\t} catch {\n\t\t\t\t// ignore — already in error path\n\t\t\t}\n\t\t}\n\t\tthrow err;\n\t} finally {\n\t\tstore.close();\n\t}\n}\n\nfunction createShowMemoryCommand(): Command {\n\treturn new Command(\"show\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Print a memory item as JSON\")\n\t\t.argument(\"<id>\", \"memory ID\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(showMemoryAction);\n}\n\nfunction createForgetMemoryCommand(): Command {\n\treturn new Command(\"forget\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Deactivate a memory item\")\n\t\t.argument(\"<id>\", \"memory ID\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(forgetMemoryAction);\n}\n\nfunction createRememberMemoryCommand(): Command {\n\treturn new Command(\"remember\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Manually add a memory item\")\n\t\t.requiredOption(\"-k, --kind <kind>\", \"memory kind (discovery, decision, feature, bugfix, etc.)\")\n\t\t.requiredOption(\"-t, --title <title>\", \"memory title\")\n\t\t.requiredOption(\"-b, --body <body>\", \"memory body text\")\n\t\t.option(\"--tags <tags...>\", \"tags (space-separated)\")\n\t\t.option(\"--project <project>\", \"project name (defaults to git repo root)\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(rememberMemoryAction);\n}\n\nfunction createInjectMemoryCommand(): Command {\n\treturn new Command(\"inject\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Build raw memory context text for manual prompt injection\")\n\t\t.argument(\"<context>\", \"context string to search for\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"-n, --limit <n>\", \"max items\", \"10\")\n\t\t.option(\"--budget <tokens>\", \"token budget\")\n\t\t.option(\"--token-budget <tokens>\", \"token budget\")\n\t\t.option(\n\t\t\t\"--working-set-file <path>\",\n\t\t\t\"recently modified file path used as ranking hint\",\n\t\t\tcollectWorkingSetFile,\n\t\t\t[],\n\t\t)\n\t\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t\t.option(\"--all-projects\", \"search across all projects\")\n\t\t.allowUnknownOption(true)\n\t\t.allowExcessArguments(true)\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tcontext: string,\n\t\t\t\topts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tbudget?: string;\n\t\t\t\t\ttokenBudget?: string;\n\t\t\t\t\tworkingSetFile?: string[];\n\t\t\t\t\tproject?: string;\n\t\t\t\t\tallProjects?: boolean;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\ttry {\n\t\t\t\t\tconst limit = Number.parseInt(opts.limit ?? \"10\", 10) || 10;\n\t\t\t\t\tconst budgetRaw = opts.tokenBudget ?? opts.budget;\n\t\t\t\t\tconst budget = budgetRaw ? Number.parseInt(budgetRaw, 10) : undefined;\n\t\t\t\t\tconst filters: { project?: string; working_set_paths?: string[] } = {};\n\t\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t\t}\n\t\t\t\t\tif ((opts.workingSetFile?.length ?? 0) > 0) {\n\t\t\t\t\t\tfilters.working_set_paths = opts.workingSetFile;\n\t\t\t\t\t}\n\t\t\t\t\tconst pack = await store.buildMemoryPackAsync(context, limit, budget, filters);\n\t\t\t\t\tconsole.log(pack.pack_text ?? \"\");\n\t\t\t\t} finally {\n\t\t\t\t\tstore.close();\n\t\t\t\t}\n\t\t\t},\n\t\t);\n}\n\nfunction createCompactMemoryCommand(): Command {\n\treturn new Command(\"compact\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Deferred command guidance for memory compaction\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--session-id <id>\", \"session ID\")\n\t\t.option(\"--limit <n>\", \"max sessions to compact\", \"10\")\n\t\t.allowUnknownOption(true)\n\t\t.allowExcessArguments(true)\n\t\t.action(() => {\n\t\t\tp.log.warn(\"`codemem memory compact` is not implemented in the TypeScript CLI yet.\");\n\t\t\tp.log.info(\n\t\t\t\t\"Current workaround: rely on automatic ingestion; for manual context use `codemem memory inject <context>`.\",\n\t\t\t);\n\t\t\tprocess.exitCode = 2;\n\t\t});\n}\n\nexport const showMemoryCommand = createShowMemoryCommand();\nexport const forgetMemoryCommand = createForgetMemoryCommand();\nexport const rememberMemoryCommand = createRememberMemoryCommand();\n\nexport const memoryCommand = new Command(\"memory\")\n\t.configureHelp(helpStyle)\n\t.description(\"Memory item management\");\n\nmemoryCommand.addCommand(createShowMemoryCommand());\nmemoryCommand.addCommand(createForgetMemoryCommand());\nmemoryCommand.addCommand(createRememberMemoryCommand());\nmemoryCommand.addCommand(createInjectMemoryCommand());\nmemoryCommand.addCommand(createCompactMemoryCommand());\n","import * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction collectWorkingSetFile(value: string, previous: string[]): string[] {\n\treturn [...previous, value];\n}\n\nexport const packCommand = new Command(\"pack\")\n\t.configureHelp(helpStyle)\n\t.description(\"Build a context-aware memory pack\")\n\t.argument(\"<context>\", \"context string to search for\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"-n, --limit <n>\", \"max items\", \"10\")\n\t.option(\"--budget <tokens>\", \"token budget\")\n\t.option(\"--token-budget <tokens>\", \"token budget\")\n\t.option(\n\t\t\"--working-set-file <path>\",\n\t\t\"recently modified file path used as ranking hint\",\n\t\tcollectWorkingSetFile,\n\t\t[],\n\t)\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"search across all projects\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action(\n\t\tasync (\n\t\t\tcontext: string,\n\t\t\topts: {\n\t\t\t\tdb?: string;\n\t\t\t\tdbPath?: string;\n\t\t\t\tlimit: string;\n\t\t\t\tbudget?: string;\n\t\t\t\ttokenBudget?: string;\n\t\t\t\tworkingSetFile?: string[];\n\t\t\t\tproject?: string;\n\t\t\t\tallProjects?: boolean;\n\t\t\t\tjson?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = Number.parseInt(opts.limit, 10) || 10;\n\t\t\t\tconst budgetRaw = opts.tokenBudget ?? opts.budget;\n\t\t\t\tconst budget = budgetRaw ? Number.parseInt(budgetRaw, 10) : undefined;\n\t\t\t\tconst filters: { project?: string; working_set_paths?: string[] } = {};\n\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t}\n\t\t\t\tif ((opts.workingSetFile?.length ?? 0) > 0) {\n\t\t\t\t\tfilters.working_set_paths = opts.workingSetFile;\n\t\t\t\t}\n\t\t\t\tconst result = await store.buildMemoryPackAsync(context, limit, budget, filters);\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(`Memory pack for \"${context}\"`);\n\n\t\t\t\tif (result.items.length === 0) {\n\t\t\t\t\tp.log.warn(\"No relevant memories found.\");\n\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst m = result.metrics;\n\t\t\t\tp.log.info(\n\t\t\t\t\t`${m.total_items} items, ~${m.pack_tokens} tokens` +\n\t\t\t\t\t\t(m.fallback_used ? \" (fallback)\" : \"\") +\n\t\t\t\t\t\t` [fts:${m.sources.fts} sem:${m.sources.semantic} fuzzy:${m.sources.fuzzy}]`,\n\t\t\t\t);\n\n\t\t\t\tfor (const item of result.items) {\n\t\t\t\t\tp.log.step(`#${item.id} ${item.kind} ${item.title}`);\n\t\t\t\t}\n\n\t\t\t\tp.note(result.pack_text, \"pack_text\");\n\n\t\t\t\tp.outro(\"done\");\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n","import { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const recentCommand = new Command(\"recent\")\n\t.configureHelp(helpStyle)\n\t.description(\"Show recent memories\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--limit <n>\", \"max results\", \"5\")\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"search across all projects\")\n\t.option(\"--kind <kind>\", \"filter by memory kind\")\n\t.action(\n\t\t(opts: {\n\t\t\tdb?: string;\n\t\t\tdbPath?: string;\n\t\t\tlimit: string;\n\t\t\tproject?: string;\n\t\t\tallProjects?: boolean;\n\t\t\tkind?: string;\n\t\t}) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = Math.max(1, Number.parseInt(opts.limit, 10) || 5);\n\t\t\t\tconst filters: { kind?: string; project?: string } = {};\n\t\t\t\tif (opts.kind) filters.kind = opts.kind;\n\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t}\n\t\t\t\tconst items = store.recent(limit, filters);\n\t\t\t\tfor (const item of items) {\n\t\t\t\t\tconsole.log(`#${item.id} [${item.kind}] ${item.title}`);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n","import * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const searchCommand = new Command(\"search\")\n\t.configureHelp(helpStyle)\n\t.description(\"Search memories by query\")\n\t.argument(\"<query>\", \"search query\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"-n, --limit <n>\", \"max results\", \"5\")\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"search across all projects\")\n\t.option(\"--kind <kind>\", \"filter by memory kind\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action(\n\t\t(\n\t\t\tquery: string,\n\t\t\topts: {\n\t\t\t\tdb?: string;\n\t\t\t\tdbPath?: string;\n\t\t\t\tlimit: string;\n\t\t\t\tproject?: string;\n\t\t\t\tallProjects?: boolean;\n\t\t\t\tkind?: string;\n\t\t\t\tjson?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = Math.max(1, Number.parseInt(opts.limit, 10) || 5);\n\t\t\t\tconst filters: { kind?: string; project?: string } = {};\n\t\t\t\tif (opts.kind) filters.kind = opts.kind;\n\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t}\n\t\t\t\tconst results = store.search(query, limit, filters);\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(results, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (results.length === 0) {\n\t\t\t\t\tp.log.warn(\"No results found.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(`${results.length} result(s) for \"${query}\"`);\n\n\t\t\t\tfor (const item of results) {\n\t\t\t\t\tconst score = item.score.toFixed(3);\n\t\t\t\t\tconst age = timeSince(item.created_at);\n\t\t\t\t\tconst preview =\n\t\t\t\t\t\titem.body_text.length > 120 ? `${item.body_text.slice(0, 120)}…` : item.body_text;\n\n\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t[`#${item.id} ${item.kind} ${age} [${score}]`, item.title, preview].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tp.outro(\"done\");\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n\nfunction timeSince(isoDate: string): string {\n\tconst ms = Date.now() - new Date(isoDate).getTime();\n\tconst days = Math.floor(ms / 86_400_000);\n\tif (days === 0) return \"today\";\n\tif (days === 1) return \"1d ago\";\n\tif (days < 30) return `${days}d ago`;\n\tconst months = Math.floor(days / 30);\n\treturn `${months}mo ago`;\n}\n","export type ServeMode = \"start\" | \"stop\" | \"restart\";\n\nexport type ServeAction = ServeMode | undefined;\n\nexport interface LegacyServeOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost: string;\n\tport: string;\n\tbackground?: boolean;\n\tforeground?: boolean;\n\tstop?: boolean;\n\trestart?: boolean;\n}\n\nexport interface StartServeOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost: string;\n\tport: string;\n\tforeground?: boolean;\n}\n\nexport interface StopRestartServeOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost: string;\n\tport: string;\n}\n\nexport interface ResolvedServeInvocation {\n\tmode: ServeMode;\n\tdbPath: string | null;\n\thost: string;\n\tport: number;\n\tbackground: boolean;\n}\n\nfunction parsePort(rawPort: string): number {\n\tconst port = Number.parseInt(rawPort, 10);\n\tif (!Number.isFinite(port) || port < 1 || port > 65535) {\n\t\tthrow new Error(`Invalid port: ${rawPort}`);\n\t}\n\treturn port;\n}\n\nexport function resolveLegacyServeInvocation(opts: LegacyServeOptions): ResolvedServeInvocation {\n\tif (opts.stop && opts.restart) {\n\t\tthrow new Error(\"Use only one of --stop or --restart\");\n\t}\n\tif (opts.foreground && opts.background) {\n\t\tthrow new Error(\"Use only one of --background or --foreground\");\n\t}\n\tconst dbPath = opts.db ?? opts.dbPath ?? null;\n\treturn {\n\t\tmode: opts.stop ? \"stop\" : opts.restart ? \"restart\" : \"start\",\n\t\tdbPath,\n\t\thost: opts.host,\n\t\tport: parsePort(opts.port),\n\t\tbackground: opts.restart ? true : opts.background ? true : false,\n\t};\n}\n\nexport function resolveServeInvocation(\n\taction: ServeAction,\n\topts: LegacyServeOptions,\n): ResolvedServeInvocation {\n\tif (action === undefined) {\n\t\treturn resolveLegacyServeInvocation(opts);\n\t}\n\tif (opts.stop || opts.restart) {\n\t\tthrow new Error(\"Do not combine lifecycle flags with a serve action\");\n\t}\n\tif (action === \"start\") {\n\t\treturn resolveStartServeInvocation(opts);\n\t}\n\treturn resolveStopRestartInvocation(action, opts);\n}\n\nexport function resolveStartServeInvocation(opts: StartServeOptions): ResolvedServeInvocation {\n\tconst dbPath = opts.db ?? opts.dbPath ?? null;\n\treturn {\n\t\tmode: \"start\",\n\t\tdbPath,\n\t\thost: opts.host,\n\t\tport: parsePort(opts.port),\n\t\tbackground: !opts.foreground,\n\t};\n}\n\nexport function resolveStopRestartInvocation(\n\tmode: \"stop\" | \"restart\",\n\topts: StopRestartServeOptions,\n): ResolvedServeInvocation {\n\tconst dbPath = opts.db ?? opts.dbPath ?? null;\n\treturn {\n\t\tmode,\n\t\tdbPath,\n\t\thost: opts.host,\n\t\tport: parsePort(opts.port),\n\t\tbackground: mode === \"restart\",\n\t};\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport {\n\tisEmbeddingDisabled,\n\ttype MemoryStore,\n\tObserverClient,\n\tRawEventSweeper,\n\treadCodememConfigFile,\n\treadCoordinatorSyncConfig,\n\tresolveDbPath,\n\trunSyncDaemon,\n} from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\nimport {\n\ttype LegacyServeOptions,\n\ttype ResolvedServeInvocation,\n\tresolveServeInvocation,\n\ttype ServeAction,\n} from \"./serve-invocation.js\";\n\ninterface ViewerPidRecord {\n\tpid: number;\n\thost: string;\n\tport: number;\n}\n\nexport function extractViewerPid(payload: unknown): number | null {\n\tif (!payload || typeof payload !== \"object\") return null;\n\tconst rawPid = (payload as { viewer_pid?: unknown }).viewer_pid;\n\tif (typeof rawPid !== \"number\" || !Number.isFinite(rawPid) || rawPid <= 0) return null;\n\treturn Math.trunc(rawPid);\n}\n\nexport function isLocalHost(host: string): boolean {\n\tconst normalized = host.trim().toLowerCase();\n\treturn (\n\t\tnormalized === \"127.0.0.1\" ||\n\t\tnormalized === \"localhost\" ||\n\t\tnormalized === \"::1\" ||\n\t\tnormalized === \"0.0.0.0\" ||\n\t\tnormalized === \"::\"\n\t);\n}\n\nexport function isLikelyViewerCommand(command: string): boolean {\n\tconst lowered = command.toLowerCase();\n\tif (!/\\bserve\\s+start\\b/.test(lowered)) return false;\n\treturn (\n\t\tlowered.includes(\"codemem\") ||\n\t\tlowered.includes(\"packages/cli/dist/index.js\") ||\n\t\tlowered.includes(\"/cli/dist/index.js\")\n\t);\n}\n\nexport function pickViewerPidCandidate(\n\tstatsPid: number | null,\n\tlistenerPid: number | null,\n): number | null {\n\tif (statsPid && listenerPid && statsPid !== listenerPid) return null;\n\treturn statsPid ?? listenerPid ?? null;\n}\n\nfunction lookupListeningPid(host: string, port: number): number | null {\n\tif (!isLocalHost(host)) return null;\n\tconst result = spawnSync(\"lsof\", [\"-nP\", `-iTCP:${port}`, \"-sTCP:LISTEN\", \"-t\"], {\n\t\tencoding: \"utf-8\",\n\t\ttimeout: 1000,\n\t});\n\tif (result.status !== 0) return null;\n\tconst first = (result.stdout || \"\")\n\t\t.split(/\\r?\\n/)\n\t\t.map((line) => line.trim())\n\t\t.find((line) => line.length > 0);\n\tif (!first) return null;\n\tconst parsed = Number.parseInt(first, 10);\n\treturn Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction readProcessCommand(pid: number): string | null {\n\tconst result = spawnSync(\"ps\", [\"-p\", String(pid), \"-o\", \"command=\"], {\n\t\tencoding: \"utf-8\",\n\t\ttimeout: 1000,\n\t});\n\tif (result.status !== 0) return null;\n\tconst cmd = (result.stdout || \"\").trim();\n\treturn cmd.length > 0 ? cmd : null;\n}\n\nfunction isTrustedViewerPid(\n\tpid: number,\n\ttarget: { host: string; port: number },\n\tlistenerPid: number | null,\n): boolean {\n\tif (!isLocalHost(target.host)) return false;\n\tif (listenerPid && listenerPid !== pid) return false;\n\tconst command = readProcessCommand(pid);\n\tif (!command) return false;\n\treturn isLikelyViewerCommand(command);\n}\n\nfunction pidFilePath(dbPath: string): string {\n\treturn join(dirname(dbPath), \"viewer.pid\");\n}\n\nfunction readViewerPidRecord(dbPath: string): ViewerPidRecord | null {\n\tconst pidPath = pidFilePath(dbPath);\n\tif (!existsSync(pidPath)) return null;\n\tconst raw = readFileSync(pidPath, \"utf-8\").trim();\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as Partial<ViewerPidRecord>;\n\t\tif (\n\t\t\ttypeof parsed.pid === \"number\" &&\n\t\t\ttypeof parsed.host === \"string\" &&\n\t\t\ttypeof parsed.port === \"number\"\n\t\t) {\n\t\t\treturn { pid: parsed.pid, host: parsed.host, port: parsed.port };\n\t\t}\n\t} catch {\n\t\tconst pid = Number.parseInt(raw, 10);\n\t\tif (Number.isFinite(pid) && pid > 0) {\n\t\t\treturn { pid, host: \"127.0.0.1\", port: 38888 };\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction isProcessRunning(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function respondsLikeCodememViewer(record: ViewerPidRecord): Promise<boolean> {\n\ttry {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), 1000);\n\t\tconst res = await fetch(`http://${record.host}:${record.port}/api/stats`, {\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tclearTimeout(timer);\n\t\treturn res.ok;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function lookupViewerPidFromStats(host: string, port: number): Promise<number | null> {\n\ttry {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), 1000);\n\t\tconst res = await fetch(`http://${host}:${port}/api/stats`, {\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tclearTimeout(timer);\n\t\tif (!res.ok) return null;\n\t\tconst payload = await res.json();\n\t\treturn extractViewerPid(payload);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function isPortOpen(host: string, port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.createConnection({ host, port });\n\t\tconst done = (open: boolean) => {\n\t\t\tsocket.removeAllListeners();\n\t\t\tsocket.destroy();\n\t\t\tresolve(open);\n\t\t};\n\t\tsocket.setTimeout(300);\n\t\tsocket.once(\"connect\", () => done(true));\n\t\tsocket.once(\"timeout\", () => done(false));\n\t\tsocket.once(\"error\", () => done(false));\n\t});\n}\n\nasync function waitForProcessExit(pid: number, timeoutMs = 5000): Promise<void> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() < deadline) {\n\t\tif (!isProcessRunning(pid)) return;\n\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t}\n}\n\nasync function waitForPortRelease(host: string, port: number, timeoutMs = 10000): Promise<boolean> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() < deadline) {\n\t\tif (!(await isPortOpen(host, port))) return true;\n\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t}\n\treturn false;\n}\n\nasync function stopExistingViewer(\n\tdbPath: string,\n\ttarget: { host: string; port: number },\n): Promise<{ stopped: boolean; pid: number | null }> {\n\tconst pidPath = pidFilePath(dbPath);\n\tconst record = readViewerPidRecord(dbPath);\n\tconst viewerPidFromStats = await lookupViewerPidFromStats(target.host, target.port);\n\tconst listenerPid = lookupListeningPid(target.host, target.port);\n\tconst viewerPid = pickViewerPidCandidate(viewerPidFromStats, listenerPid);\n\tif (viewerPid && isTrustedViewerPid(viewerPid, target, listenerPid)) {\n\t\ttry {\n\t\t\tprocess.kill(viewerPid, \"SIGTERM\");\n\t\t\tawait waitForProcessExit(viewerPid);\n\t\t} catch {\n\t\t\t// process may have already exited\n\t\t}\n\t\ttry {\n\t\t\trmSync(pidPath);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\treturn { stopped: true, pid: viewerPid };\n\t}\n\n\tif (!record) return { stopped: false, pid: null };\n\n\tif (await respondsLikeCodememViewer(record)) {\n\t\ttry {\n\t\t\tprocess.kill(record.pid, \"SIGTERM\");\n\t\t\tawait waitForProcessExit(record.pid);\n\t\t} catch {\n\t\t\t// stale pidfile or already exited\n\t\t}\n\t}\n\ttry {\n\t\trmSync(pidPath);\n\t} catch {\n\t\t// ignore\n\t}\n\treturn { stopped: true, pid: record.pid };\n}\n\nexport function buildForegroundRunnerArgs(\n\tscriptPath: string,\n\tinvocation: ResolvedServeInvocation,\n\texecArgv: string[] = process.execArgv,\n): string[] {\n\tconst args = [\n\t\t...execArgv,\n\t\tscriptPath,\n\t\t\"serve\",\n\t\t\"start\",\n\t\t\"--foreground\",\n\t\t\"--host\",\n\t\tinvocation.host,\n\t\t\"--port\",\n\t\tString(invocation.port),\n\t];\n\tif (invocation.dbPath) {\n\t\targs.push(\"--db-path\", invocation.dbPath);\n\t}\n\treturn args;\n}\n\nexport function isSqliteVecLoadFailure(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst text = error.message.toLowerCase();\n\treturn (\n\t\ttext.includes(\"sqlite-vec\") ||\n\t\ttext.includes(\"vec_version\") ||\n\t\ttext.includes(\"vec0\") ||\n\t\t(text.includes(\"sqlite\") && text.includes(\"vec\"))\n\t);\n}\n\nexport function sqliteVecFailureDiagnostics(error: unknown, dbPath: string): string[] {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn [\n\t\t`db=${dbPath}`,\n\t\t`node=${process.version}`,\n\t\t`exec=${process.execPath}`,\n\t\t`cwd=${process.cwd()}`,\n\t\t`embedding_disabled=${process.env.CODEMEM_EMBEDDING_DISABLED ?? \"\"}`,\n\t\t`error=${message}`,\n\t];\n}\n\nasync function startBackgroundViewer(invocation: ResolvedServeInvocation): Promise<void> {\n\tif (await isPortOpen(invocation.host, invocation.port)) {\n\t\tp.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);\n\t\treturn;\n\t}\n\tconst scriptPath = process.argv[1];\n\tif (!scriptPath) throw new Error(\"Unable to resolve CLI entrypoint for background launch\");\n\tconst child = spawn(process.execPath, buildForegroundRunnerArgs(scriptPath, invocation), {\n\t\tcwd: process.cwd(),\n\t\tdetached: true,\n\t\tstdio: \"ignore\",\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...(invocation.dbPath ? { CODEMEM_DB: invocation.dbPath } : {}),\n\t\t},\n\t});\n\tchild.unref();\n\tif (invocation.dbPath) {\n\t\twriteFileSync(\n\t\t\tpidFilePath(invocation.dbPath),\n\t\t\tJSON.stringify({ pid: child.pid, host: invocation.host, port: invocation.port }),\n\t\t\t\"utf-8\",\n\t\t);\n\t}\n\tp.intro(\"codemem viewer\");\n\tp.outro(\n\t\t`Viewer started in background (pid ${child.pid}) at http://${invocation.host}:${invocation.port}`,\n\t);\n}\n\nasync function startForegroundViewer(invocation: ResolvedServeInvocation): Promise<void> {\n\tconst { createApp, createSyncApp, closeStore, getStore } = await import(\"@codemem/server\");\n\tconst { serve } = await import(\"@hono/node-server\");\n\n\tif (invocation.dbPath) process.env.CODEMEM_DB = invocation.dbPath;\n\tif (await isPortOpen(invocation.host, invocation.port)) {\n\t\tp.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\n\tconst observer = new ObserverClient();\n\tlet store: MemoryStore;\n\ttry {\n\t\tstore = getStore();\n\t} catch (err) {\n\t\tif (isEmbeddingDisabled() || !isSqliteVecLoadFailure(err)) {\n\t\t\tthrow err;\n\t\t}\n\n\t\tp.log.warn(\"sqlite-vec failed to load; retrying viewer startup with embeddings disabled\");\n\t\tfor (const line of sqliteVecFailureDiagnostics(\n\t\t\terr,\n\t\t\tresolveDbPath(invocation.dbPath ?? undefined),\n\t\t)) {\n\t\t\tp.log.warn(`sqlite-vec diagnostic: ${line}`);\n\t\t}\n\t\tprocess.env.CODEMEM_EMBEDDING_DISABLED = \"1\";\n\t\tcloseStore();\n\t\tstore = getStore();\n\t\tp.log.warn(\"Embeddings disabled for this viewer process; raw-event ingestion remains active.\");\n\t}\n\n\tconst sweeper = new RawEventSweeper(store, { observer });\n\tsweeper.start();\n\n\tconst syncAbort = new AbortController();\n\tlet syncRunning = false;\n\tconst config = readCodememConfigFile();\n\tconst syncConfig = readCoordinatorSyncConfig(config);\n\tconst syncEnabled = syncConfig.syncEnabled;\n\n\tif (syncEnabled) {\n\t\tsyncRunning = true;\n\t\tconst syncIntervalS = syncConfig.syncIntervalS;\n\t\trunSyncDaemon({\n\t\t\tdbPath: resolveDbPath(invocation.dbPath ?? undefined),\n\t\t\tintervalS: syncIntervalS,\n\t\t\thost: syncConfig.syncHost,\n\t\t\tport: syncConfig.syncPort,\n\t\t\tsignal: syncAbort.signal,\n\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\t\tp.log.error(`Sync daemon failed: ${msg}`);\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tsyncRunning = false;\n\t\t\t});\n\t}\n\n\tconst appOpts = { storeFactory: () => store, sweeper, observer };\n\tconst app = createApp(appOpts);\n\tconst dbPath = resolveDbPath(invocation.dbPath ?? undefined);\n\tconst pidPath = pidFilePath(dbPath);\n\n\t// Sync protocol listener — separate port, network-accessible for peers.\n\t// syncServerRef is never nulled after creation so shutdown always drains it.\n\tlet syncServer: ReturnType<typeof serve> | null = null;\n\tlet syncListenerReady = false;\n\tif (syncEnabled) {\n\t\tconst syncApp = createSyncApp(appOpts);\n\t\tsyncServer = serve(\n\t\t\t{ fetch: syncApp.fetch, hostname: syncConfig.syncHost, port: syncConfig.syncPort },\n\t\t\t(info) => {\n\t\t\t\tsyncListenerReady = true;\n\t\t\t\tp.log.step(`Sync protocol listening on http://${info.address}:${info.port}`);\n\t\t\t},\n\t\t);\n\t\tsyncServer.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\t\tif (!syncListenerReady && err.code === \"EADDRINUSE\") {\n\t\t\t\tp.log.warn(\n\t\t\t\t\t`Sync port ${syncConfig.syncPort} already in use; peer sync protocol unavailable`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tp.log.warn(`Sync listener error: ${err.message}`);\n\t\t\t}\n\t\t\t// Non-fatal — viewer continues. syncServer ref is kept for shutdown drain.\n\t\t});\n\t}\n\n\tconst server = serve(\n\t\t{ fetch: app.fetch, hostname: invocation.host, port: invocation.port },\n\t\t(info) => {\n\t\t\twriteFileSync(\n\t\t\t\tpidPath,\n\t\t\t\tJSON.stringify({ pid: process.pid, host: invocation.host, port: invocation.port }),\n\t\t\t\t\"utf-8\",\n\t\t\t);\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.log.success(`Listening on http://${info.address}:${info.port}`);\n\t\t\tp.log.info(`Database: ${dbPath}`);\n\t\t\tp.log.step(\"Raw event sweeper started\");\n\t\t\tif (syncRunning) p.log.step(\"Sync daemon started\");\n\t\t},\n\t);\n\n\tserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\tp.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);\n\t\t} else {\n\t\t\tp.log.error(err.message);\n\t\t}\n\t\tprocess.exit(1);\n\t});\n\n\tconst shutdown = async () => {\n\t\tp.outro(\"shutting down\");\n\t\tsyncAbort.abort();\n\t\tawait sweeper.stop();\n\n\t\t// Drain both listeners before closing the shared store.\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tlet remaining = syncServer ? 2 : 1;\n\t\t\tconst done = () => {\n\t\t\t\tif (--remaining === 0) resolve();\n\t\t\t};\n\t\t\tsyncServer?.close(done);\n\t\t\tserver.close(done);\n\t\t}).catch(() => {\n\t\t\t// Best-effort drain — proceed to cleanup.\n\t\t});\n\n\t\ttry {\n\t\t\trmSync(pidPath);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\tcloseStore();\n\t\tprocess.exit(0);\n\t};\n\n\t// Force-exit safety net if graceful shutdown stalls.\n\tconst forceShutdown = () => {\n\t\tsetTimeout(() => {\n\t\t\ttry {\n\t\t\t\trmSync(pidPath);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\tcloseStore();\n\t\t\tprocess.exit(1);\n\t\t}, 5000).unref();\n\t};\n\tprocess.on(\"SIGINT\", () => {\n\t\tforceShutdown();\n\t\tvoid shutdown();\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tforceShutdown();\n\t\tvoid shutdown();\n\t});\n}\n\nasync function runServeInvocation(invocation: ResolvedServeInvocation): Promise<void> {\n\tconst dbPath = resolveDbPath(invocation.dbPath ?? undefined);\n\tif (invocation.mode === \"stop\" || invocation.mode === \"restart\") {\n\t\tconst result = await stopExistingViewer(dbPath, {\n\t\t\thost: invocation.host,\n\t\t\tport: invocation.port,\n\t\t});\n\t\tif (result.stopped) {\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.log.success(`Stopped viewer${result.pid ? ` (pid ${result.pid})` : \"\"}`);\n\t\t\tif (invocation.mode === \"stop\") {\n\t\t\t\tp.outro(\"done\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Wait for port to be fully released before restarting.\n\t\t\tconst released = await waitForPortRelease(invocation.host, invocation.port);\n\t\t\tif (!released) {\n\t\t\t\tp.log.warn(`Port ${invocation.port} still in use after stop — restart may fail`);\n\t\t\t}\n\t\t} else if (invocation.mode === \"stop\") {\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.outro(\"No background viewer found\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (invocation.mode === \"start\" || invocation.mode === \"restart\") {\n\t\tif (invocation.background) {\n\t\t\tawait startBackgroundViewer({ ...invocation, dbPath });\n\t\t\treturn;\n\t\t}\n\t\tawait startForegroundViewer({ ...invocation, dbPath });\n\t}\n}\n\nfunction addSharedServeOptions(command: Command): Command {\n\treturn command\n\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t.option(\"--host <host>\", \"bind host\", \"127.0.0.1\")\n\t\t.option(\"--port <port>\", \"bind port\", \"38888\");\n}\n\nexport const serveCommand = addSharedServeOptions(\n\tnew Command(\"serve\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Run or manage the viewer\")\n\t\t.argument(\"[action]\", \"lifecycle action (start|stop|restart)\"),\n)\n\t.option(\"--background\", \"run viewer in background\")\n\t.option(\"--foreground\", \"run viewer in foreground\")\n\t.option(\"--stop\", \"stop background viewer\")\n\t.option(\"--restart\", \"restart background viewer\")\n\t.action(async (action: string | undefined, opts: LegacyServeOptions) => {\n\t\tconst normalizedAction =\n\t\t\taction === undefined\n\t\t\t\t? undefined\n\t\t\t\t: action === \"start\" || action === \"stop\" || action === \"restart\"\n\t\t\t\t\t? (action as ServeAction)\n\t\t\t\t\t: null;\n\t\tif (normalizedAction === null) {\n\t\t\tp.log.error(`Unknown serve action: ${action}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tawait runServeInvocation(resolveServeInvocation(normalizedAction, opts));\n\t});\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { stripJsonComments, stripTrailingCommas } from \"@codemem/core\";\n\nexport function resolveOpencodeConfigPath(configDir: string): string {\n\tconst jsonPath = join(configDir, \"opencode.json\");\n\tif (existsSync(jsonPath)) return jsonPath;\n\tconst jsoncPath = join(configDir, \"opencode.jsonc\");\n\tif (existsSync(jsoncPath)) return jsoncPath;\n\treturn jsoncPath;\n}\n\nexport function loadJsoncConfig(path: string): Record<string, unknown> {\n\tif (!existsSync(path)) return {};\n\tconst raw = readFileSync(path, \"utf-8\");\n\ttry {\n\t\treturn JSON.parse(raw) as Record<string, unknown>;\n\t} catch {\n\t\tconst cleaned = stripTrailingCommas(stripJsonComments(raw));\n\t\treturn JSON.parse(cleaned) as Record<string, unknown>;\n\t}\n}\n\nexport function writeJsonConfig(path: string, data: Record<string, unknown>): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(data, null, 2)}\\n`, \"utf-8\");\n}\n","/**\n * codemem setup — one-command installation for OpenCode plugin + MCP config.\n *\n * Replaces Python's install_plugin_cmd + install_mcp_cmd.\n *\n * What it does:\n * 1. Adds \"codemem\" to the plugin array in ~/.config/opencode/opencode.jsonc\n * 2. Adds/updates the MCP entry in ~/.config/opencode/opencode.jsonc\n * 3. For Claude Code: installs MCP config and guides marketplace plugin install\n *\n * Designed to be safe to run repeatedly (idempotent unless --force).\n */\n\nimport { existsSync, rmSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { VERSION } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\nimport { loadJsoncConfig, resolveOpencodeConfigPath, writeJsonConfig } from \"./setup-config.js\";\n\nfunction opencodeConfigDir(): string {\n\treturn join(homedir(), \".config\", \"opencode\");\n}\n\nfunction claudeConfigDir(): string {\n\treturn join(homedir(), \".claude\");\n}\n\n/** The npm package name used in the OpenCode plugin array. */\nconst OPENCODE_PLUGIN_SPEC = \"codemem\";\n\n// ---------------------------------------------------------------------------\n// Legacy migration helpers\n// ---------------------------------------------------------------------------\n\n/** Remove legacy copied plugin JS file from ~/.config/opencode/plugins/codemem.js */\nfunction migrateLegacyOpencodePlugin(): void {\n\tconst legacyPlugin = join(opencodeConfigDir(), \"plugins\", \"codemem.js\");\n\tconst legacyCompat = join(opencodeConfigDir(), \"lib\", \"compat.js\");\n\tif (existsSync(legacyPlugin)) {\n\t\ttry {\n\t\t\trmSync(legacyPlugin);\n\t\t\tp.log.step(\"Removed legacy copied plugin: ~/.config/opencode/plugins/codemem.js\");\n\t\t} catch {\n\t\t\tp.log.warn(\"Could not remove legacy plugin file — remove manually if needed\");\n\t\t}\n\t}\n\tif (existsSync(legacyCompat)) {\n\t\ttry {\n\t\t\trmSync(legacyCompat);\n\t\t\tp.log.step(\"Removed legacy compat lib: ~/.config/opencode/lib/compat.js\");\n\t\t} catch {\n\t\t\t// Non-fatal.\n\t\t}\n\t}\n}\n\n/** Detect and upgrade legacy uvx/uv-based MCP entries in OpenCode config. */\nfunction migrateLegacyOpencodeMcp(config: Record<string, unknown>): boolean {\n\tconst mcpConfig = config.mcp as Record<string, unknown> | undefined;\n\tif (!mcpConfig || typeof mcpConfig !== \"object\") return false;\n\tconst entry = mcpConfig.codemem as Record<string, unknown> | undefined;\n\tif (!entry || typeof entry !== \"object\") return false;\n\n\tconst command = entry.command;\n\tconst isLegacy =\n\t\t(Array.isArray(command) &&\n\t\t\tcommand.some((arg) => typeof arg === \"string\" && (arg === \"uvx\" || arg === \"uv\"))) ||\n\t\t(typeof command === \"string\" && (command === \"uvx\" || command === \"uv\"));\n\n\tif (isLegacy) {\n\t\tp.log.step(\"Upgrading legacy uvx MCP entry to npx\");\n\t\tmcpConfig.codemem = {\n\t\t\ttype: \"local\",\n\t\t\tcommand: [\"npx\", \"codemem\", \"mcp\"],\n\t\t\tenabled: true,\n\t\t};\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/** Detect and upgrade legacy uvx-based MCP entries in Claude settings. */\nfunction migrateLegacyClaudeMcp(settings: Record<string, unknown>): boolean {\n\tconst mcpServers = settings.mcpServers as Record<string, unknown> | undefined;\n\tif (!mcpServers || typeof mcpServers !== \"object\") return false;\n\tconst entry = mcpServers.codemem as Record<string, unknown> | undefined;\n\tif (!entry || typeof entry !== \"object\") return false;\n\n\tconst command = entry.command;\n\tconst args = entry.args;\n\tconst isLegacy =\n\t\t(typeof command === \"string\" && (command === \"uvx\" || command === \"uv\")) ||\n\t\t(Array.isArray(args) &&\n\t\t\targs.some(\n\t\t\t\t(arg) => typeof arg === \"string\" && (arg.startsWith(\"codemem==\") || arg === \"uvx\"),\n\t\t\t));\n\n\tif (isLegacy) {\n\t\tp.log.step(\"Upgrading legacy uvx Claude MCP entry to npx\");\n\t\tmcpServers.codemem = {\n\t\t\tcommand: \"npx\",\n\t\t\targs: [\"-y\", \"codemem\", \"mcp\"],\n\t\t};\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n// ---------------------------------------------------------------------------\n// Install functions\n// ---------------------------------------------------------------------------\n\nfunction installPlugin(force: boolean): boolean {\n\t// Clean up legacy copied plugin files first.\n\tmigrateLegacyOpencodePlugin();\n\n\tconst configPath = resolveOpencodeConfigPath(opencodeConfigDir());\n\tlet config: Record<string, unknown>;\n\ttry {\n\t\tconfig = loadJsoncConfig(configPath);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\tlet plugins = config.plugin as unknown;\n\tif (!Array.isArray(plugins)) {\n\t\tplugins = [];\n\t}\n\n\tconst hasCodemem = (plugins as string[]).some(\n\t\t(entry) =>\n\t\t\ttypeof entry === \"string\" &&\n\t\t\t(entry === OPENCODE_PLUGIN_SPEC || entry.startsWith(`${OPENCODE_PLUGIN_SPEC}@`)),\n\t);\n\n\tif (hasCodemem && !force) {\n\t\tp.log.info(`Plugin \"${OPENCODE_PLUGIN_SPEC}\" already in plugin array`);\n\t\treturn true;\n\t}\n\n\tif (hasCodemem && force) {\n\t\t// Remove existing entry so we can re-add the canonical one.\n\t\tplugins = (plugins as string[]).filter(\n\t\t\t(entry) =>\n\t\t\t\ttypeof entry !== \"string\" ||\n\t\t\t\t(entry !== OPENCODE_PLUGIN_SPEC && !entry.startsWith(`${OPENCODE_PLUGIN_SPEC}@`)),\n\t\t);\n\t}\n\n\t(plugins as string[]).push(OPENCODE_PLUGIN_SPEC);\n\tconfig.plugin = plugins;\n\n\ttry {\n\t\twriteJsonConfig(configPath, config);\n\t\tp.log.success(`Plugin \"${OPENCODE_PLUGIN_SPEC}\" added to ${configPath}`);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to write ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nfunction installMcp(force: boolean): boolean {\n\tconst configPath = resolveOpencodeConfigPath(opencodeConfigDir());\n\tlet config: Record<string, unknown>;\n\ttry {\n\t\tconfig = loadJsoncConfig(configPath);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\tlet mcpConfig = config.mcp as Record<string, unknown> | undefined;\n\tif (mcpConfig == null || typeof mcpConfig !== \"object\" || Array.isArray(mcpConfig)) {\n\t\tmcpConfig = {};\n\t}\n\n\t// Auto-upgrade legacy uvx-based MCP entries.\n\tconst migrated = migrateLegacyOpencodeMcp(config);\n\n\tif (\"codemem\" in mcpConfig && !force && !migrated) {\n\t\tp.log.info(`MCP entry already exists in ${configPath}`);\n\t\treturn true;\n\t}\n\n\tif (!migrated) {\n\t\tmcpConfig.codemem = {\n\t\t\ttype: \"local\",\n\t\t\tcommand: [\"npx\", \"codemem\", \"mcp\"],\n\t\t\tenabled: true,\n\t\t};\n\t\tconfig.mcp = mcpConfig;\n\t}\n\n\ttry {\n\t\twriteJsonConfig(configPath, config);\n\t\tp.log.success(`MCP entry installed: ${configPath}`);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to write ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nfunction isClaudeHooksPluginInstalled(): boolean {\n\t// Check if the marketplace hooks plugin is installed by looking for\n\t// the hooks directory — NOT for MCP config (which we write ourselves).\n\tconst pluginDir = join(claudeConfigDir(), \"plugins\", \"codemem\");\n\tif (existsSync(pluginDir)) return true;\n\t// Also check for hook scripts installed by the marketplace plugin.\n\tconst hooksJson = join(pluginDir, \"hooks\", \"hooks.json\");\n\tif (existsSync(hooksJson)) return true;\n\treturn false;\n}\n\nfunction installClaudeMcp(force: boolean): boolean {\n\tconst settingsPath = join(claudeConfigDir(), \"settings.json\");\n\tlet settings: Record<string, unknown>;\n\ttry {\n\t\tsettings = loadJsoncConfig(settingsPath);\n\t} catch {\n\t\tsettings = {};\n\t}\n\n\tlet mcpServers = settings.mcpServers as Record<string, unknown> | undefined;\n\tif (mcpServers == null || typeof mcpServers !== \"object\" || Array.isArray(mcpServers)) {\n\t\tmcpServers = {};\n\t}\n\n\t// Auto-upgrade legacy uvx-based Claude MCP entries.\n\tconst migrated = migrateLegacyClaudeMcp(settings);\n\n\tif (\"codemem\" in mcpServers && !force && !migrated) {\n\t\tp.log.info(`Claude MCP entry already exists in ${settingsPath}`);\n\t} else {\n\t\tif (!migrated) {\n\t\t\tmcpServers.codemem = {\n\t\t\t\tcommand: \"npx\",\n\t\t\t\targs: [\"-y\", \"codemem\", \"mcp\"],\n\t\t\t};\n\t\t\tsettings.mcpServers = mcpServers;\n\t\t}\n\n\t\ttry {\n\t\t\twriteJsonConfig(settingsPath, settings);\n\t\t\tp.log.success(`Claude MCP entry installed: ${settingsPath}`);\n\t\t} catch (err) {\n\t\t\tp.log.error(\n\t\t\t\t`Failed to write ${settingsPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Guide marketplace plugin install for hooks integration.\n\tif (!isClaudeHooksPluginInstalled() || force) {\n\t\tp.log.info(\"To install the Claude Code hooks plugin, run in Claude Code:\");\n\t\tp.log.info(\" /plugin marketplace add kunickiaj/codemem\");\n\t\tp.log.info(\" /plugin install codemem\");\n\t\tp.log.info(\"\");\n\t\tp.log.info(\"To update an existing install:\");\n\t\tp.log.info(\" /plugin marketplace update codemem-marketplace\");\n\t} else {\n\t\tp.log.info(\"Claude Code hooks plugin appears to be installed\");\n\t}\n\n\treturn true;\n}\n\nexport const setupCommand = new Command(\"setup\")\n\t.configureHelp(helpStyle)\n\t.description(\"Install codemem plugin + MCP config for OpenCode and Claude Code\")\n\t.option(\"--force\", \"overwrite existing installations\")\n\t.option(\"--opencode-only\", \"only install for OpenCode\")\n\t.option(\"--claude-only\", \"only install for Claude Code\")\n\t.action((opts: { force?: boolean; opencodeOnly?: boolean; claudeOnly?: boolean }) => {\n\t\tp.intro(`codemem setup v${VERSION}`);\n\t\tconst force = opts.force ?? false;\n\t\tlet ok = true;\n\n\t\tif (!opts.claudeOnly) {\n\t\t\tp.log.step(\"Installing OpenCode plugin...\");\n\t\t\tok = installPlugin(force) && ok;\n\t\t\tp.log.step(\"Installing OpenCode MCP config...\");\n\t\t\tok = installMcp(force) && ok;\n\t\t}\n\n\t\tif (!opts.opencodeOnly) {\n\t\t\tp.log.step(\"Installing Claude Code MCP config...\");\n\t\t\tok = installClaudeMcp(force) && ok;\n\t\t}\n\n\t\tif (ok) {\n\t\t\tp.outro(\"Setup complete — restart your editor to load the plugin\");\n\t\t} else {\n\t\t\tp.outro(\"Setup completed with warnings\");\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t});\n","import * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction fmtPct(n: number): string {\n\treturn `${Math.round(n * 100)}%`;\n}\n\nfunction fmtTokens(n: number): string {\n\tif (n >= 1_000_000_000) return `~${(n / 1_000_000_000).toFixed(1)}B`;\n\tif (n >= 1_000_000) return `~${(n / 1_000_000).toFixed(1)}M`;\n\tif (n >= 1_000) return `~${(n / 1_000).toFixed(0)}K`;\n\treturn `${n}`;\n}\n\nexport const statsCommand = new Command(\"stats\")\n\t.configureHelp(helpStyle)\n\t.description(\"Show database statistics\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action((opts: { db?: string; dbPath?: string; json?: boolean }) => {\n\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\ttry {\n\t\t\tconst result = store.stats();\n\t\t\tif (opts.json) {\n\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst db = result.database;\n\t\t\tconst sizeMb = (db.size_bytes / 1_048_576).toFixed(1);\n\n\t\t\tp.intro(\"codemem stats\");\n\n\t\t\tp.log.info([`Path: ${db.path}`, `Size: ${sizeMb} MB`].join(\"\\n\"));\n\n\t\t\tp.log.success(\n\t\t\t\t[\n\t\t\t\t\t`Sessions: ${db.sessions.toLocaleString()}`,\n\t\t\t\t\t`Memories: ${db.active_memory_items.toLocaleString()} active / ${db.memory_items.toLocaleString()} total`,\n\t\t\t\t\t`Tags: ${db.tags_filled.toLocaleString()} filled (${fmtPct(db.tags_coverage)} of active)`,\n\t\t\t\t\t`Artifacts: ${db.artifacts.toLocaleString()}`,\n\t\t\t\t\t`Vectors: ${db.vector_rows.toLocaleString()} (${fmtPct(db.vector_coverage)} coverage)`,\n\t\t\t\t\t`Raw events: ${db.raw_events.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\n\t\t\tif (result.usage.events.length > 0) {\n\t\t\t\tconst lines = result.usage.events.map((e: (typeof result.usage.events)[number]) => {\n\t\t\t\t\tconst parts = [`${e.event}: ${e.count.toLocaleString()}`];\n\t\t\t\t\tif (e.tokens_read > 0) parts.push(`read ${fmtTokens(e.tokens_read)} tokens`);\n\t\t\t\t\tif (e.tokens_saved > 0) parts.push(`est. saved ${fmtTokens(e.tokens_saved)} tokens`);\n\t\t\t\t\treturn ` ${parts.join(\", \")}`;\n\t\t\t\t});\n\n\t\t\t\tconst t = result.usage.totals;\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(\n\t\t\t\t\t` Total: ${t.events.toLocaleString()} events, read ${fmtTokens(t.tokens_read)} tokens, est. saved ${fmtTokens(t.tokens_saved)} tokens`,\n\t\t\t\t);\n\n\t\t\t\tp.log.step(`Usage\\n${lines.join(\"\\n\")}`);\n\t\t\t}\n\n\t\t\tp.outro(\"done\");\n\t\t} finally {\n\t\t\tstore.close();\n\t\t}\n\t});\n","export interface SyncAttemptRow {\n\tpeer_device_id: string;\n\tok: number;\n\tops_in: number;\n\tops_out: number;\n\terror: string | null;\n\tfinished_at: string | null;\n}\n\nexport function formatSyncAttempt(row: SyncAttemptRow): string {\n\tconst status = row.ok ? \"ok\" : \"error\";\n\tconst error = String(row.error || \"\");\n\tconst suffix = error ? ` | ${error}` : \"\";\n\treturn `${row.peer_device_id}|${status}|in=${row.ops_in}|out=${row.ops_out}|${row.finished_at ?? \"\"}${suffix}`;\n}\n\nexport interface SyncLifecycleOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost?: string;\n\tport?: string;\n\tuser?: boolean;\n\tsystem?: boolean;\n}\n\nexport function buildServeLifecycleArgs(\n\taction: \"start\" | \"stop\" | \"restart\",\n\topts: SyncLifecycleOptions,\n\tscriptPath: string,\n\texecArgv: string[] = [],\n): string[] {\n\tif (!scriptPath) throw new Error(\"Unable to resolve CLI entrypoint for sync lifecycle command\");\n\tconst args = [...execArgv, scriptPath, \"serve\"];\n\tif (action === \"start\") {\n\t\targs.push(\"--restart\");\n\t} else if (action === \"stop\") {\n\t\targs.push(\"--stop\");\n\t} else {\n\t\targs.push(\"--restart\");\n\t}\n\tif (opts.db ?? opts.dbPath) args.push(\"--db-path\", opts.db ?? opts.dbPath ?? \"\");\n\tif (opts.host) args.push(\"--host\", opts.host);\n\tif (opts.port) args.push(\"--port\", opts.port);\n\treturn args;\n}\n\nexport function formatSyncOnceResult(\n\tpeerDeviceId: string,\n\tresult: { ok: boolean; error?: string },\n): string {\n\tif (result.ok) return `- ${peerDeviceId}: ok`;\n\tconst suffix = result.error ? `: ${result.error}` : \"\";\n\treturn `- ${peerDeviceId}: error${suffix}`;\n}\n\nexport function parseProjectList(value: string | undefined): string[] {\n\tif (!value) return [];\n\treturn value\n\t\t.split(\",\")\n\t\t.map((item) => item.trim())\n\t\t.filter(Boolean);\n}\n\ntype InterfaceMap = Record<\n\tstring,\n\tArray<{ address: string; family?: string | number; internal?: boolean }> | undefined\n>;\n\nexport function collectAdvertiseAddresses(\n\texplicitAddress: string | null,\n\tconfiguredHost: string | null,\n\tport: number,\n\tinterfaces: InterfaceMap,\n): string[] {\n\tif (explicitAddress && ![\"auto\", \"default\"].includes(explicitAddress.toLowerCase())) {\n\t\treturn [explicitAddress];\n\t}\n\tif (configuredHost && configuredHost !== \"0.0.0.0\") {\n\t\treturn [`${configuredHost}:${port}`];\n\t}\n\tconst addresses = Object.values(interfaces)\n\t\t.flatMap((entries) => entries ?? [])\n\t\t.filter((entry) => !entry.internal)\n\t\t.map((entry) => entry.address)\n\t\t.filter((address) => address && address !== \"127.0.0.1\" && address !== \"::1\")\n\t\t.map((address) => `${address}:${port}`);\n\treturn [...new Set(addresses)];\n}\n","/**\n * Sync CLI commands — enable/disable/status/peers/connect.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { networkInterfaces } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\nimport {\n\tcoordinatorCreateInviteAction,\n\tcoordinatorImportInviteAction,\n\tcoordinatorListJoinRequestsAction,\n\tcoordinatorReviewJoinRequestAction,\n\tcreateCoordinatorApp,\n\tDEFAULT_COORDINATOR_DB_PATH,\n\tensureDeviceIdentity,\n\tfingerprintPublicKey,\n\tloadPublicKey,\n\tMemoryStore,\n\treadCodememConfigFile,\n\tresolveDbPath,\n\trunSyncPass,\n\tschema,\n\tsetPeerProjectFilter,\n\tsyncPassPreflight,\n\tupdatePeerAddresses,\n\twriteCodememConfigFile,\n} from \"@codemem/core\";\nimport { serve as honoServe } from \"@hono/node-server\";\nimport { Command } from \"commander\";\nimport { desc, eq } from \"drizzle-orm\";\nimport { drizzle } from \"drizzle-orm/better-sqlite3\";\nimport { helpStyle } from \"../help-style.js\";\nimport {\n\tbuildServeLifecycleArgs,\n\tcollectAdvertiseAddresses,\n\tformatSyncAttempt,\n\tformatSyncOnceResult,\n\tparseProjectList,\n\ttype SyncLifecycleOptions,\n} from \"./sync-helpers.js\";\n\nfunction parseAttemptsLimit(value: string): number {\n\tif (!/^\\d+$/.test(value.trim())) {\n\t\tthrow new Error(`Invalid --limit: ${value}`);\n\t}\n\treturn Number.parseInt(value, 10);\n}\n\ninterface SyncOnceOptions {\n\tdb?: string;\n\tdbPath?: string;\n\tpeer?: string;\n}\n\ninterface SyncPairOptions {\n\taccept?: string;\n\tacceptFile?: string;\n\tpayloadOnly?: boolean;\n\tname?: string;\n\taddress?: string;\n\tinclude?: string;\n\texclude?: string;\n\tall?: boolean;\n\tdefault?: boolean;\n\tdbPath?: string;\n}\n\nasync function portOpen(host: string, port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.createConnection({ host, port });\n\t\tconst done = (ok: boolean) => {\n\t\t\tsocket.removeAllListeners();\n\t\t\tsocket.destroy();\n\t\t\tresolve(ok);\n\t\t};\n\t\tsocket.setTimeout(300);\n\t\tsocket.once(\"connect\", () => done(true));\n\t\tsocket.once(\"timeout\", () => done(false));\n\t\tsocket.once(\"error\", () => done(false));\n\t});\n}\n\nfunction readViewerBinding(dbPath: string): { host: string; port: number } | null {\n\ttry {\n\t\tconst raw = readFileSync(join(dirname(dbPath), \"viewer.pid\"), \"utf8\");\n\t\tconst parsed = JSON.parse(raw) as Partial<{ host: string; port: number }>;\n\t\tif (typeof parsed.host === \"string\" && typeof parsed.port === \"number\") {\n\t\t\treturn { host: parsed.host, port: parsed.port };\n\t\t}\n\t} catch {\n\t\t// ignore malformed or missing pidfile\n\t}\n\treturn null;\n}\n\nfunction parseStoredAddressEndpoint(value: string): { host: string; port: number } | null {\n\ttry {\n\t\tconst normalized = value.includes(\"://\") ? value : `http://${value}`;\n\t\tconst url = new URL(normalized);\n\t\tconst port = url.port ? Number.parseInt(url.port, 10) : url.protocol === \"https:\" ? 443 : 80;\n\t\tif (!url.hostname || !Number.isFinite(port)) return null;\n\t\treturn { host: url.hostname, port };\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function runServeLifecycle(\n\taction: \"start\" | \"stop\" | \"restart\",\n\topts: SyncLifecycleOptions,\n): Promise<void> {\n\tif (opts.user === false || opts.system === true) {\n\t\tp.log.warn(\n\t\t\t\"TS sync lifecycle currently manages the local viewer process, not separate user/system services.\",\n\t\t);\n\t}\n\tif (action === \"start\") {\n\t\tconst config = readCodememConfigFile();\n\t\tif (config.sync_enabled !== true) {\n\t\t\tp.log.error(\"Sync is disabled. Run `codemem sync enable` first.\");\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\t// Don't pass sync_host/sync_port as viewer bind values.\n\t\t// The viewer binds its own host/port (default 127.0.0.1:38888)\n\t\t// and the sync protocol listener reads sync_host/sync_port\n\t\t// internally from readCoordinatorSyncConfig().\n\t}\n\tconst args = buildServeLifecycleArgs(action, opts, process.argv[1] ?? \"\", process.execArgv);\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(process.execPath, args, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: \"inherit\",\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\t...((opts.db ?? opts.dbPath) ? { CODEMEM_DB: opts.db ?? opts.dbPath } : {}),\n\t\t\t},\n\t\t});\n\t\tchild.once(\"error\", reject);\n\t\tchild.once(\"exit\", (code) => {\n\t\t\tif (code && code !== 0) {\n\t\t\t\tprocess.exitCode = code;\n\t\t\t}\n\t\t\tresolve();\n\t\t});\n\t});\n}\n\nexport const syncCommand = new Command(\"sync\")\n\t.configureHelp(helpStyle)\n\t.description(\"Sync configuration and peer management\");\n\n// codemem sync attempts\nsyncCommand.addCommand(\n\tnew Command(\"attempts\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Show recent sync attempts\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--limit <n>\", \"max attempts\", \"10\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action((opts: { db?: string; dbPath?: string; limit: string; json?: boolean }) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst limit = parseAttemptsLimit(opts.limit);\n\t\t\t\tconst rows = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncAttempts.peer_device_id,\n\t\t\t\t\t\tok: schema.syncAttempts.ok,\n\t\t\t\t\t\tops_in: schema.syncAttempts.ops_in,\n\t\t\t\t\t\tops_out: schema.syncAttempts.ops_out,\n\t\t\t\t\t\terror: schema.syncAttempts.error,\n\t\t\t\t\t\tfinished_at: schema.syncAttempts.finished_at,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncAttempts)\n\t\t\t\t\t.orderBy(desc(schema.syncAttempts.finished_at))\n\t\t\t\t\t.limit(limit)\n\t\t\t\t\t.all();\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(rows, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconsole.log(formatSyncAttempt(row));\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"start\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Start sync daemon\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"viewer host\")\n\t\t.option(\"--port <port>\", \"viewer port\")\n\t\t.option(\"--user\", \"accepted for compatibility\", true)\n\t\t.option(\"--system\", \"accepted for compatibility\")\n\t\t.action(async (opts: SyncLifecycleOptions) => {\n\t\t\tawait runServeLifecycle(\"start\", opts);\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"stop\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Stop sync daemon\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"viewer host\")\n\t\t.option(\"--port <port>\", \"viewer port\")\n\t\t.option(\"--user\", \"accepted for compatibility\", true)\n\t\t.option(\"--system\", \"accepted for compatibility\")\n\t\t.action(async (opts: SyncLifecycleOptions) => {\n\t\t\tawait runServeLifecycle(\"stop\", opts);\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"restart\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Restart sync daemon\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"viewer host\")\n\t\t.option(\"--port <port>\", \"viewer port\")\n\t\t.option(\"--user\", \"accepted for compatibility\", true)\n\t\t.option(\"--system\", \"accepted for compatibility\")\n\t\t.action(async (opts: SyncLifecycleOptions) => {\n\t\t\tawait runServeLifecycle(\"restart\", opts);\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"once\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Run a single sync pass\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--peer <peer>\", \"peer device id or name\")\n\t\t.action(async (opts: SyncOnceOptions) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tsyncPassPreflight(store.db);\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst rows = opts.peer\n\t\t\t\t\t? (() => {\n\t\t\t\t\t\t\tconst deviceMatches = d\n\t\t\t\t\t\t\t\t.select({ peer_device_id: schema.syncPeers.peer_device_id })\n\t\t\t\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t\t\t\t.where(eq(schema.syncPeers.peer_device_id, opts.peer))\n\t\t\t\t\t\t\t\t.all();\n\t\t\t\t\t\t\tif (deviceMatches.length > 0) return deviceMatches;\n\t\t\t\t\t\t\tconst nameMatches = d\n\t\t\t\t\t\t\t\t.select({ peer_device_id: schema.syncPeers.peer_device_id })\n\t\t\t\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t\t\t\t.where(eq(schema.syncPeers.name, opts.peer))\n\t\t\t\t\t\t\t\t.all();\n\t\t\t\t\t\t\tif (nameMatches.length > 1) {\n\t\t\t\t\t\t\t\tp.log.error(`Peer name is ambiguous: ${opts.peer}`);\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn nameMatches;\n\t\t\t\t\t\t})()\n\t\t\t\t\t: d\n\t\t\t\t\t\t\t.select({ peer_device_id: schema.syncPeers.peer_device_id })\n\t\t\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t\t\t.all();\n\n\t\t\t\tif (rows.length === 0) {\n\t\t\t\t\tp.log.warn(\"No peers available for sync\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet hadFailure = false;\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst result = await runSyncPass(store.db, row.peer_device_id);\n\t\t\t\t\tif (!result.ok) hadFailure = true;\n\t\t\t\t\tconsole.log(formatSyncOnceResult(row.peer_device_id, result));\n\t\t\t\t}\n\t\t\t\tif (hadFailure) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"pair\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Print pairing payload or accept a peer payload\")\n\t\t.option(\"--accept <json>\", \"accept pairing payload JSON from another device\")\n\t\t.option(\"--accept-file <path>\", \"accept pairing payload from file path, or '-' for stdin\")\n\t\t.option(\"--payload-only\", \"when generating pairing payload, print JSON only\")\n\t\t.option(\"--name <name>\", \"label for the peer\")\n\t\t.option(\"--address <host:port>\", \"override peer address (host:port)\")\n\t\t.option(\"--include <projects>\", \"outbound-only allowlist for accepted peer\")\n\t\t.option(\"--exclude <projects>\", \"outbound-only blocklist for accepted peer\")\n\t\t.option(\"--all\", \"with --accept, push all projects to that peer\")\n\t\t.option(\"--default\", \"with --accept, use default/global push filters\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(async (opts: SyncPairOptions) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst acceptModeRequested = opts.accept != null || opts.acceptFile != null;\n\t\t\t\tif (opts.payloadOnly && acceptModeRequested) {\n\t\t\t\t\tp.log.error(\"--payload-only cannot be combined with --accept or --accept-file\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (opts.accept && opts.acceptFile) {\n\t\t\t\t\tp.log.error(\"Use only one of --accept or --accept-file\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet acceptText = opts.accept;\n\t\t\t\tif (opts.acceptFile) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tacceptText =\n\t\t\t\t\t\t\topts.acceptFile === \"-\"\n\t\t\t\t\t\t\t\t? await new Promise<string>((resolve, reject) => {\n\t\t\t\t\t\t\t\t\t\tlet text = \"\";\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\t\t\t\t\ttext += chunk;\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.on(\"end\", () => resolve(text));\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.on(\"error\", reject);\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: readFileSync(opts.acceptFile, \"utf8\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(\n\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t? `Failed to read pairing payload from ${opts.acceptFile}: ${error.message}`\n\t\t\t\t\t\t\t\t: `Failed to read pairing payload from ${opts.acceptFile}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (acceptModeRequested && !(acceptText ?? \"\").trim()) {\n\t\t\t\t\tp.log.error(\"Empty pairing payload; provide JSON via --accept or --accept-file\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!acceptText && (opts.include || opts.exclude || opts.all || opts.default)) {\n\t\t\t\t\tp.log.error(\n\t\t\t\t\t\t\"Project filters are outbound-only and must be set on the device running --accept\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (acceptText?.trim()) {\n\t\t\t\t\tif (opts.all && opts.default) {\n\t\t\t\t\t\tp.log.error(\"Use only one of --all or --default\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ((opts.all || opts.default) && (opts.include || opts.exclude)) {\n\t\t\t\t\t\tp.log.error(\"--include/--exclude cannot be combined with --all/--default\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet payload: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpayload = JSON.parse(acceptText) as Record<string, unknown>;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(\n\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t? `Invalid pairing payload: ${error.message}`\n\t\t\t\t\t\t\t\t: \"Invalid pairing payload\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst deviceId = String(payload.device_id || \"\").trim();\n\t\t\t\t\tconst fingerprint = String(payload.fingerprint || \"\").trim();\n\t\t\t\t\tconst publicKey = String(payload.public_key || \"\").trim();\n\t\t\t\t\tconst resolvedAddresses = opts.address?.trim()\n\t\t\t\t\t\t? [opts.address.trim()]\n\t\t\t\t\t\t: Array.isArray(payload.addresses)\n\t\t\t\t\t\t\t? (payload.addresses as unknown[])\n\t\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t\t(item): item is string => typeof item === \"string\" && item.trim().length > 0,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.map((item) => item.trim())\n\t\t\t\t\t\t\t: [];\n\t\t\t\t\tif (!deviceId || !fingerprint || !publicKey || resolvedAddresses.length === 0) {\n\t\t\t\t\t\tp.log.error(\"Pairing payload missing device_id, fingerprint, public_key, or addresses\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (fingerprintPublicKey(publicKey) !== fingerprint) {\n\t\t\t\t\t\tp.log.error(\"Pairing payload fingerprint mismatch\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tupdatePeerAddresses(store.db, deviceId, resolvedAddresses, {\n\t\t\t\t\t\tname: opts.name,\n\t\t\t\t\t\tpinnedFingerprint: fingerprint,\n\t\t\t\t\t\tpublicKey,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (opts.default) {\n\t\t\t\t\t\tsetPeerProjectFilter(store.db, deviceId, { include: null, exclude: null });\n\t\t\t\t\t} else if (opts.all || opts.include || opts.exclude) {\n\t\t\t\t\t\tsetPeerProjectFilter(store.db, deviceId, {\n\t\t\t\t\t\t\tinclude: opts.all ? [] : parseProjectList(opts.include),\n\t\t\t\t\t\t\texclude: opts.all ? [] : parseProjectList(opts.exclude),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tp.log.success(`Paired with ${deviceId}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst keysDir = process.env.CODEMEM_KEYS_DIR?.trim() || undefined;\n\t\t\t\tconst [deviceId, fingerprint] = ensureDeviceIdentity(store.db, { keysDir });\n\t\t\t\tconst publicKey = loadPublicKey(keysDir);\n\t\t\t\tif (!publicKey) {\n\t\t\t\t\tp.log.error(\"Public key missing\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst config = readCodememConfigFile();\n\t\t\t\tconst explicitAddress = opts.address?.trim();\n\t\t\t\tconst configuredHost = typeof config.sync_host === \"string\" ? config.sync_host : null;\n\t\t\t\tconst configuredPort = typeof config.sync_port === \"number\" ? config.sync_port : 7337;\n\t\t\t\tconst addresses = collectAdvertiseAddresses(\n\t\t\t\t\texplicitAddress ?? null,\n\t\t\t\t\tconfiguredHost,\n\t\t\t\t\tconfiguredPort,\n\t\t\t\t\tnetworkInterfaces(),\n\t\t\t\t);\n\t\t\t\tconst payload = {\n\t\t\t\t\tdevice_id: deviceId,\n\t\t\t\t\tfingerprint,\n\t\t\t\t\tpublic_key: publicKey,\n\t\t\t\t\taddress: addresses[0] ?? \"\",\n\t\t\t\t\taddresses,\n\t\t\t\t};\n\t\t\t\tconst payloadText = JSON.stringify(payload);\n\n\t\t\t\tif (opts.payloadOnly) {\n\t\t\t\t\tprocess.stdout.write(`${payloadText}\\n`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst escaped = payloadText.replaceAll(\"'\", \"'\\\\''\");\n\t\t\t\tconsole.log(\"Pairing payload\");\n\t\t\t\tconsole.log(payloadText);\n\t\t\t\tconsole.log(\"On the other device, save this JSON to pairing.json, then run:\");\n\t\t\t\tconsole.log(\" codemem sync pair --accept-file pairing.json\");\n\t\t\t\tconsole.log(\"If you prefer inline JSON, run:\");\n\t\t\t\tconsole.log(` codemem sync pair --accept '${escaped}'`);\n\t\t\t\tconsole.log(\"For machine-friendly output next time, run:\");\n\t\t\t\tconsole.log(\" codemem sync pair --payload-only\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"On the accepting device, --include/--exclude control both what it sends and what it accepts from that peer.\",\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"doctor\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Diagnose common sync setup and connectivity issues\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(async (opts: { db?: string; dbPath?: string }) => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconst dbPath = resolveDbPath(opts.db ?? opts.dbPath);\n\t\t\tconst store = new MemoryStore(dbPath);\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst device = d\n\t\t\t\t\t.select({ device_id: schema.syncDevice.device_id })\n\t\t\t\t\t.from(schema.syncDevice)\n\t\t\t\t\t.limit(1)\n\t\t\t\t\t.get();\n\t\t\t\tconst daemonState = d\n\t\t\t\t\t.select()\n\t\t\t\t\t.from(schema.syncDaemonState)\n\t\t\t\t\t.where(eq(schema.syncDaemonState.id, 1))\n\t\t\t\t\t.get();\n\t\t\t\tconst peers = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncPeers.peer_device_id,\n\t\t\t\t\t\taddresses_json: schema.syncPeers.addresses_json,\n\t\t\t\t\t\tpinned_fingerprint: schema.syncPeers.pinned_fingerprint,\n\t\t\t\t\t\tpublic_key: schema.syncPeers.public_key,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t.all();\n\n\t\t\t\tconst issues: string[] = [];\n\t\t\t\tconst syncHost = typeof config.sync_host === \"string\" ? config.sync_host : \"0.0.0.0\";\n\t\t\t\tconst syncPort = typeof config.sync_port === \"number\" ? config.sync_port : 7337;\n\t\t\t\tconst viewerBinding = readViewerBinding(dbPath);\n\n\t\t\t\tconsole.log(\"Sync doctor\");\n\t\t\t\tconsole.log(`- Enabled: ${config.sync_enabled === true}`);\n\t\t\t\tconsole.log(`- Listen: ${syncHost}:${syncPort}`);\n\t\t\t\tconsole.log(`- mDNS: ${process.env.CODEMEM_SYNC_MDNS ? \"env-configured\" : \"default/off\"}`);\n\n\t\t\t\tconst reachable = viewerBinding\n\t\t\t\t\t? await portOpen(viewerBinding.host, viewerBinding.port)\n\t\t\t\t\t: false;\n\t\t\t\tconsole.log(`- Daemon: ${reachable ? \"running\" : \"not running\"}`);\n\t\t\t\tif (!reachable) issues.push(\"daemon not running\");\n\n\t\t\t\tif (!device) {\n\t\t\t\t\tconsole.log(\"- Identity: missing (run `codemem sync enable`)\");\n\t\t\t\t\tissues.push(\"identity missing\");\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`- Identity: ${device.device_id}`);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tdaemonState?.last_error &&\n\t\t\t\t\t(!daemonState.last_ok_at || daemonState.last_ok_at < (daemonState.last_error_at ?? \"\"))\n\t\t\t\t) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`- Daemon error: ${daemonState.last_error} (at ${daemonState.last_error_at ?? \"unknown\"})`,\n\t\t\t\t\t);\n\t\t\t\t\tissues.push(\"daemon error\");\n\t\t\t\t}\n\n\t\t\t\tif (peers.length === 0) {\n\t\t\t\t\tconsole.log(\"- Peers: none (pair a device first)\");\n\t\t\t\t\tissues.push(\"no peers\");\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`- Peers: ${peers.length}`);\n\t\t\t\t\tfor (const peer of peers) {\n\t\t\t\t\t\tconst addresses = peer.addresses_json\n\t\t\t\t\t\t\t? (JSON.parse(peer.addresses_json) as string[])\n\t\t\t\t\t\t\t: [];\n\t\t\t\t\t\tconst endpoint = parseStoredAddressEndpoint(addresses[0] ?? \"\");\n\t\t\t\t\t\tconst reach = endpoint\n\t\t\t\t\t\t\t? (await portOpen(endpoint.host, endpoint.port))\n\t\t\t\t\t\t\t\t? \"ok\"\n\t\t\t\t\t\t\t\t: \"unreachable\"\n\t\t\t\t\t\t\t: \"unknown\";\n\t\t\t\t\t\tconst pinned = Boolean(peer.pinned_fingerprint);\n\t\t\t\t\t\tconst hasKey = Boolean(peer.public_key);\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t` - ${peer.peer_device_id}: addresses=${addresses.length} reach=${reach} pinned=${pinned} public_key=${hasKey}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (reach !== \"ok\") issues.push(`peer ${peer.peer_device_id} unreachable`);\n\t\t\t\t\t\tif (!pinned || !hasKey) issues.push(`peer ${peer.peer_device_id} not pinned`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!config.sync_enabled) issues.push(\"sync is disabled\");\n\n\t\t\t\tif (issues.length > 0) {\n\t\t\t\t\tconsole.log(`WARN: ${[...new Set(issues)].slice(0, 3).join(\", \")}`);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"OK: sync looks healthy\");\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\n// codemem sync status\nsyncCommand.addCommand(\n\tnew Command(\"status\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Show sync configuration and peer summary\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action((opts: { db?: string; dbPath?: string; json?: boolean }) => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst deviceRow = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tdevice_id: schema.syncDevice.device_id,\n\t\t\t\t\t\tfingerprint: schema.syncDevice.fingerprint,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncDevice)\n\t\t\t\t\t.limit(1)\n\t\t\t\t\t.get();\n\t\t\t\tconst peers = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncPeers.peer_device_id,\n\t\t\t\t\t\tname: schema.syncPeers.name,\n\t\t\t\t\t\tlast_sync_at: schema.syncPeers.last_sync_at,\n\t\t\t\t\t\tlast_error: schema.syncPeers.last_error,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t.all();\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tenabled: config.sync_enabled === true,\n\t\t\t\t\t\t\t\thost: config.sync_host ?? \"0.0.0.0\",\n\t\t\t\t\t\t\t\tport: config.sync_port ?? 7337,\n\t\t\t\t\t\t\t\tinterval_s: config.sync_interval_s ?? 120,\n\t\t\t\t\t\t\t\tdevice_id: deviceRow?.device_id ?? null,\n\t\t\t\t\t\t\t\tfingerprint: deviceRow?.fingerprint ?? null,\n\t\t\t\t\t\t\t\tcoordinator_url: config.sync_coordinator_url ?? null,\n\t\t\t\t\t\t\t\tpeers: peers.map((peer) => ({\n\t\t\t\t\t\t\t\t\tdevice_id: peer.peer_device_id,\n\t\t\t\t\t\t\t\t\tname: peer.name,\n\t\t\t\t\t\t\t\t\tlast_sync: peer.last_sync_at,\n\t\t\t\t\t\t\t\t\tstatus: peer.last_error ?? \"ok\",\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(\"codemem sync status\");\n\t\t\t\tp.log.info(\n\t\t\t\t\t[\n\t\t\t\t\t\t`Enabled: ${config.sync_enabled === true ? \"yes\" : \"no\"}`,\n\t\t\t\t\t\t`Host: ${config.sync_host ?? \"0.0.0.0\"}`,\n\t\t\t\t\t\t`Port: ${config.sync_port ?? 7337}`,\n\t\t\t\t\t\t`Interval: ${config.sync_interval_s ?? 120}s`,\n\t\t\t\t\t\t`Coordinator: ${config.sync_coordinator_url ?? \"(not configured)\"}`,\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t);\n\t\t\t\tif (deviceRow) {\n\t\t\t\t\tp.log.info(`Device ID: ${deviceRow.device_id}\\nFingerprint: ${deviceRow.fingerprint}`);\n\t\t\t\t} else {\n\t\t\t\t\tp.log.warn(\"Device identity not initialized (run `codemem sync enable`)\");\n\t\t\t\t}\n\t\t\t\tif (peers.length === 0) {\n\t\t\t\t\tp.log.info(\"Peers: none\");\n\t\t\t\t} else {\n\t\t\t\t\tfor (const peer of peers) {\n\t\t\t\t\t\tconst label = peer.name || peer.peer_device_id;\n\t\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t\t` ${label}: last_sync=${peer.last_sync_at ?? \"never\"}, status=${peer.last_error ?? \"ok\"}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.outro(`${peers.length} peer(s)`);\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\n// codemem sync enable\nsyncCommand.addCommand(\n\tnew Command(\"enable\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Enable sync and initialize device identity\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"sync listen host\")\n\t\t.option(\"--port <port>\", \"sync listen port\")\n\t\t.option(\"--interval <seconds>\", \"sync interval in seconds\")\n\t\t.action(\n\t\t\t(opts: { db?: string; dbPath?: string; host?: string; port?: string; interval?: string }) => {\n\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\ttry {\n\t\t\t\t\tconst [deviceId, fingerprint] = ensureDeviceIdentity(store.db);\n\t\t\t\t\tconst config = readCodememConfigFile();\n\t\t\t\t\tconfig.sync_enabled = true;\n\t\t\t\t\tif (opts.host) config.sync_host = opts.host;\n\t\t\t\t\tif (opts.port) config.sync_port = Number.parseInt(opts.port, 10);\n\t\t\t\t\tif (opts.interval) config.sync_interval_s = Number.parseInt(opts.interval, 10);\n\t\t\t\t\twriteCodememConfigFile(config);\n\n\t\t\t\t\tp.intro(\"codemem sync enable\");\n\t\t\t\t\tp.log.success(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`Device ID: ${deviceId}`,\n\t\t\t\t\t\t\t`Fingerprint: ${fingerprint}`,\n\t\t\t\t\t\t\t`Host: ${config.sync_host ?? \"0.0.0.0\"}`,\n\t\t\t\t\t\t\t`Port: ${config.sync_port ?? 7337}`,\n\t\t\t\t\t\t\t`Interval: ${config.sync_interval_s ?? 120}s`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t\tp.outro(\"Sync enabled — restart `codemem serve` to activate\");\n\t\t\t\t} finally {\n\t\t\t\t\tstore.close();\n\t\t\t\t}\n\t\t\t},\n\t\t),\n);\n\n// codemem sync disable\nsyncCommand.addCommand(\n\tnew Command(\"disable\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Disable sync without deleting keys or peers\")\n\t\t.action(() => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconfig.sync_enabled = false;\n\t\t\twriteCodememConfigFile(config);\n\t\t\tp.intro(\"codemem sync disable\");\n\t\t\tp.outro(\"Sync disabled — restart `codemem serve` to take effect\");\n\t\t}),\n);\n\n// codemem sync peers\nsyncCommand.addCommand(\n\tnew Command(\"peers\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"List known sync peers\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action((opts: { db?: string; dbPath?: string; json?: boolean }) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst peers = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncPeers.peer_device_id,\n\t\t\t\t\t\tname: schema.syncPeers.name,\n\t\t\t\t\t\taddresses: schema.syncPeers.addresses_json,\n\t\t\t\t\t\tlast_sync_at: schema.syncPeers.last_sync_at,\n\t\t\t\t\t\tlast_error: schema.syncPeers.last_error,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t.orderBy(desc(schema.syncPeers.last_sync_at))\n\t\t\t\t\t.all();\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(peers, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(\"codemem sync peers\");\n\t\t\t\tif (peers.length === 0) {\n\t\t\t\t\tp.outro(\"No peers configured\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const peer of peers) {\n\t\t\t\t\tconst label = peer.name || peer.peer_device_id;\n\t\t\t\t\tconst addrs = peer.addresses || \"(no addresses)\";\n\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t`${label}\\n addresses: ${addrs}\\n last_sync: ${peer.last_sync_at ?? \"never\"}\\n status: ${peer.last_error ?? \"ok\"}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tp.outro(`${peers.length} peer(s)`);\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\n// codemem sync connect <coordinator-url>\nsyncCommand.addCommand(\n\tnew Command(\"connect\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Configure coordinator URL for cloud sync\")\n\t\t.argument(\"<url>\", \"coordinator URL (e.g. https://coordinator.example.com)\")\n\t\t.option(\"--group <group>\", \"sync group ID\")\n\t\t.action((url: string, opts: { group?: string }) => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconfig.sync_coordinator_url = url.trim();\n\t\t\tif (opts.group) config.sync_coordinator_group = opts.group.trim();\n\t\t\twriteCodememConfigFile(config);\n\t\t\tp.intro(\"codemem sync connect\");\n\t\t\tp.log.success(`Coordinator: ${url.trim()}`);\n\t\t\tif (opts.group) p.log.info(`Group: ${opts.group.trim()}`);\n\t\t\tp.outro(\"Restart `codemem serve` to activate coordinator sync\");\n\t\t}),\n);\n\nconst coordinatorCommand = new Command(\"coordinator\")\n\t.configureHelp(helpStyle)\n\t.description(\"Manage coordinator invites, join requests, and relay server\");\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"serve\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Run the coordinator relay HTTP server\")\n\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t.option(\"--host <host>\", \"bind host\", \"127.0.0.1\")\n\t\t.option(\"--port <port>\", \"bind port\", \"7340\")\n\t\t.action(async (opts: { db?: string; dbPath?: string; host?: string; port?: string }) => {\n\t\t\tconst host = String(opts.host ?? \"127.0.0.1\").trim() || \"127.0.0.1\";\n\t\t\tconst port = Number.parseInt(String(opts.port ?? \"7340\"), 10);\n\t\t\tconst dbPath = opts.db ?? opts.dbPath ?? DEFAULT_COORDINATOR_DB_PATH;\n\t\t\tconst app = createCoordinatorApp({ dbPath });\n\t\t\tp.intro(\"codemem sync coordinator serve\");\n\t\t\tp.log.success(`Coordinator listening at http://${host}:${port}`);\n\t\t\tp.log.info(`DB: ${dbPath}`);\n\t\t\thonoServe({ fetch: app.fetch, hostname: host, port });\n\t\t}),\n);\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"create-invite\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Create a coordinator team invite\")\n\t\t.argument(\"[group]\", \"group id\")\n\t\t.option(\"--group <group>\", \"group id\")\n\t\t.option(\"--coordinator-url <url>\", \"coordinator URL override\")\n\t\t.option(\"--policy <policy>\", \"invite policy\", \"auto_admit\")\n\t\t.option(\"--ttl-hours <hours>\", \"invite TTL hours\", \"24\")\n\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t.option(\"--remote-url <url>\", \"remote coordinator URL override\")\n\t\t.option(\"--admin-secret <secret>\", \"remote coordinator admin secret override\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tgroupArg: string | undefined,\n\t\t\t\topts: {\n\t\t\t\t\tgroup?: string;\n\t\t\t\t\tcoordinatorUrl?: string;\n\t\t\t\t\tpolicy?: string;\n\t\t\t\t\tttlHours?: string;\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tremoteUrl?: string;\n\t\t\t\t\tadminSecret?: string;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst ttlHours = Number.parseInt(String(opts.ttlHours ?? \"24\"), 10);\n\t\t\t\tconst groupId = String(opts.group ?? \"\").trim() || String(groupArg ?? \"\").trim();\n\t\t\t\tconst result = await coordinatorCreateInviteAction({\n\t\t\t\t\tgroupId,\n\t\t\t\t\tcoordinatorUrl: opts.coordinatorUrl?.trim() || null,\n\t\t\t\t\tpolicy: String(opts.policy ?? \"auto_admit\").trim(),\n\t\t\t\t\tttlHours,\n\t\t\t\t\tcreatedBy: null,\n\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\tremoteUrl: opts.remoteUrl?.trim() || null,\n\t\t\t\t\tadminSecret: opts.adminSecret?.trim() || null,\n\t\t\t\t});\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem sync coordinator create-invite\");\n\t\t\t\tp.log.success(`Invite created for ${groupId}`);\n\t\t\t\tif (typeof result.link === \"string\") p.log.message(`- link: ${result.link}`);\n\t\t\t\tif (typeof result.encoded === \"string\") p.log.message(`- invite: ${result.encoded}`);\n\t\t\t\tp.outro(\"Invite ready\");\n\t\t\t},\n\t\t),\n);\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"import-invite\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Import a coordinator invite\")\n\t\t.argument(\"<invite>\", \"invite value or link\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--keys-dir <path>\", \"keys directory\")\n\t\t.option(\"--config <path>\", \"config path\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tinvite: string,\n\t\t\t\topts: { db?: string; dbPath?: string; keysDir?: string; config?: string; json?: boolean },\n\t\t\t) => {\n\t\t\t\tconst result = await coordinatorImportInviteAction({\n\t\t\t\t\tinviteValue: invite,\n\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\tkeysDir: opts.keysDir ?? null,\n\t\t\t\t\tconfigPath: opts.config ?? null,\n\t\t\t\t});\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem sync coordinator import-invite\");\n\t\t\t\tp.log.success(`Invite imported for ${result.group_id}`);\n\t\t\t\tp.log.message(`- coordinator: ${result.coordinator_url}`);\n\t\t\t\tp.log.message(`- status: ${result.status}`);\n\t\t\t\tp.outro(\"Coordinator config updated\");\n\t\t\t},\n\t\t),\n);\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"list-join-requests\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"List pending coordinator join requests\")\n\t\t.argument(\"[group]\", \"group id\")\n\t\t.option(\"--group <group>\", \"group id\")\n\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t.option(\"--remote-url <url>\", \"remote coordinator URL override\")\n\t\t.option(\"--admin-secret <secret>\", \"remote coordinator admin secret override\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tgroupArg: string | undefined,\n\t\t\t\topts: {\n\t\t\t\t\tgroup?: string;\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tremoteUrl?: string;\n\t\t\t\t\tadminSecret?: string;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst groupId = String(opts.group ?? \"\").trim() || String(groupArg ?? \"\").trim();\n\t\t\t\tconst rows = await coordinatorListJoinRequestsAction({\n\t\t\t\t\tgroupId,\n\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\tremoteUrl: opts.remoteUrl?.trim() || null,\n\t\t\t\t\tadminSecret: opts.adminSecret?.trim() || null,\n\t\t\t\t});\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(rows, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem sync coordinator list-join-requests\");\n\t\t\t\tif (rows.length === 0) {\n\t\t\t\t\tp.outro(`No pending join requests for ${groupId}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst displayName = row.display_name || row.device_id;\n\t\t\t\t\tp.log.message(`- ${displayName} (${row.device_id}) request_id=${row.request_id}`);\n\t\t\t\t}\n\t\t\t\tp.outro(`${rows.length} pending join request(s)`);\n\t\t\t},\n\t\t),\n);\n\nfunction addReviewJoinRequestCommand(\n\tname: \"approve-join-request\" | \"deny-join-request\",\n\tapprove: boolean,\n) {\n\tcoordinatorCommand.addCommand(\n\t\tnew Command(name)\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(`${approve ? \"Approve\" : \"Deny\"} a coordinator join request`)\n\t\t\t.argument(\"<request-id>\", \"join request id\")\n\t\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t\t.option(\"--remote-url <url>\", \"remote coordinator URL override\")\n\t\t\t.option(\"--admin-secret <secret>\", \"remote coordinator admin secret override\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\tasync (\n\t\t\t\t\trequestId: string,\n\t\t\t\t\topts: {\n\t\t\t\t\t\tdb?: string;\n\t\t\t\t\t\tdbPath?: string;\n\t\t\t\t\t\tremoteUrl?: string;\n\t\t\t\t\t\tadminSecret?: string;\n\t\t\t\t\t\tjson?: boolean;\n\t\t\t\t\t},\n\t\t\t\t) => {\n\t\t\t\t\tconst request = await coordinatorReviewJoinRequestAction({\n\t\t\t\t\t\trequestId: requestId.trim(),\n\t\t\t\t\t\tapprove,\n\t\t\t\t\t\treviewedBy: null,\n\t\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\t\tremoteUrl: opts.remoteUrl?.trim() || null,\n\t\t\t\t\t\tadminSecret: opts.adminSecret?.trim() || null,\n\t\t\t\t\t});\n\t\t\t\t\tif (!request) {\n\t\t\t\t\t\tp.log.error(`Join request not found: ${requestId.trim()}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\tconsole.log(JSON.stringify(request, null, 2));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tp.intro(`codemem sync coordinator ${name}`);\n\t\t\t\t\tp.log.success(`${approve ? \"Approved\" : \"Denied\"} join request ${requestId.trim()}`);\n\t\t\t\t\tp.outro(String(request.status ?? \"updated\"));\n\t\t\t\t},\n\t\t\t),\n\t);\n}\n\naddReviewJoinRequestCommand(\"approve-join-request\", true);\naddReviewJoinRequestCommand(\"deny-join-request\", false);\n\nsyncCommand.addCommand(coordinatorCommand);\n","import { VERSION } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const versionCommand = new Command(\"version\")\n\t.configureHelp(helpStyle)\n\t.description(\"Print codemem version\")\n\t.action(() => {\n\t\tconsole.log(VERSION);\n\t});\n","#!/usr/bin/env node\n\n/**\n * @codemem/cli — CLI entry point.\n *\n * Commands:\n * codemem stats → database statistics\n * codemem search → FTS5 memory search\n * codemem pack → context-aware memory pack\n * codemem serve → viewer server\n * codemem mcp → MCP stdio server\n */\n\nimport { VERSION } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport omelette from \"omelette\";\nimport { claudeHookIngestCommand } from \"./commands/claude-hook-ingest.js\";\nimport { dbCommand } from \"./commands/db.js\";\nimport { embedCommand } from \"./commands/embed.js\";\nimport { enqueueRawEventCommand } from \"./commands/enqueue-raw-event.js\";\nimport { exportMemoriesCommand } from \"./commands/export-memories.js\";\nimport { importMemoriesCommand } from \"./commands/import-memories.js\";\nimport { mcpCommand } from \"./commands/mcp.js\";\nimport {\n\tforgetMemoryCommand,\n\tmemoryCommand,\n\trememberMemoryCommand,\n\tshowMemoryCommand,\n} from \"./commands/memory.js\";\nimport { packCommand } from \"./commands/pack.js\";\nimport { recentCommand } from \"./commands/recent.js\";\nimport { searchCommand } from \"./commands/search.js\";\nimport { serveCommand } from \"./commands/serve.js\";\nimport { setupCommand } from \"./commands/setup.js\";\nimport { statsCommand } from \"./commands/stats.js\";\nimport { syncCommand } from \"./commands/sync.js\";\nimport { versionCommand } from \"./commands/version.js\";\nimport { helpStyle } from \"./help-style.js\";\n\ntype CompletionWithScriptGenerators = ReturnType<typeof omelette> & {\n\tgenerateCompletionCode: () => string;\n\tgenerateCompletionCodeFish: () => string;\n};\n\n// Shell completion (bash/zsh/fish)\nconst completion = omelette(\"codemem <command>\") as CompletionWithScriptGenerators;\ncompletion.on(\"command\", ({ reply }) => {\n\treply([\n\t\t\"claude-hook-ingest\",\n\t\t\"db\",\n\t\t\"embed\",\n\t\t\"export-memories\",\n\t\t\"forget\",\n\t\t\"memory\",\n\t\t\"import-memories\",\n\t\t\"setup\",\n\t\t\"show\",\n\t\t\"sync\",\n\t\t\"stats\",\n\t\t\"recent\",\n\t\t\"remember\",\n\t\t\"search\",\n\t\t\"pack\",\n\t\t\"serve\",\n\t\t\"mcp\",\n\t\t\"enqueue-raw-event\",\n\t\t\"version\",\n\t\t\"help\",\n\t\t\"--help\",\n\t\t\"--version\",\n\t]);\n});\ncompletion.init();\n\nfunction hasRootFlag(flag: string): boolean {\n\tfor (const arg of process.argv.slice(2)) {\n\t\tif (arg === \"--\") return false;\n\t\tif (arg === flag) return true;\n\t\tif (!arg.startsWith(\"-\")) return false;\n\t}\n\treturn false;\n}\n\nfunction getShellCompletionScript(): string {\n\tconst shellPath = process.env.SHELL ?? \"\";\n\tif (shellPath.includes(\"fish\")) {\n\t\treturn completion.generateCompletionCodeFish();\n\t}\n\treturn completion.generateCompletionCode();\n}\n\nconst program = new Command();\n\nprogram\n\t.name(\"codemem\")\n\t.description(\"codemem — persistent memory for AI coding agents\")\n\t.option(\"--install-completion\", \"install shell completion\")\n\t.option(\"--show-completion\", \"show shell completion install guidance\")\n\t.version(VERSION)\n\t.configureHelp(helpStyle);\n\nif (hasRootFlag(\"--setup-completion\") || hasRootFlag(\"--install-completion\")) {\n\tcompletion.setupShellInitFile();\n\tprocess.exit(0);\n}\n\nif (hasRootFlag(\"--show-completion\")) {\n\tconsole.log(getShellCompletionScript());\n\tprocess.exit(0);\n}\n\nif (hasRootFlag(\"--cleanup-completion\")) {\n\tcompletion.cleanupShellInitFile();\n\tprocess.exit(0);\n}\n\nprogram.addCommand(serveCommand);\nprogram.addCommand(mcpCommand);\nprogram.addCommand(claudeHookIngestCommand);\nprogram.addCommand(dbCommand);\nprogram.addCommand(exportMemoriesCommand);\nprogram.addCommand(importMemoriesCommand);\nprogram.addCommand(statsCommand);\nprogram.addCommand(embedCommand);\nprogram.addCommand(recentCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(packCommand);\nprogram.addCommand(showMemoryCommand);\nprogram.addCommand(forgetMemoryCommand);\nprogram.addCommand(rememberMemoryCommand);\nprogram.addCommand(memoryCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(setupCommand);\nprogram.addCommand(enqueueRawEventCommand);\nprogram.addCommand(versionCommand);\n\nprogram.parse();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAUA,IAAa,YAA+B;CAC3C,aAAa,QAAQ,UAAU,QAAQ,IAAI;CAC3C,mBAAmB,QAAQ,UAAU,QAAQ,IAAI;CACjD,0BAA0B,QAAQ;CAClC,uBAAuB,QAAQ,UAAU,OAAO,IAAI;CACpD,kBAAkB,QAAQ,UAAU,SAAS,IAAI;CACjD,kBAAkB,QAAQ,UAAU,SAAS,IAAI;CACjD,sBAAsB,QAAQ,UAAU,QAAQ,IAAI;CACpD,oBAAoB,QAAQ,UAAU,UAAU,IAAI;CACpD;;;;;;;;;;;;;;;;ACqBD,eAAe,cACd,SACA,MACA,MAC8D;CAC9D,MAAM,MAAM,UAAU,KAAK,GAAG,KAAK;CACnC,MAAM,aAAa,IAAI,iBAAiB;CACxC,MAAM,UAAU,iBAAiB,WAAW,OAAO,EAAE,IAAK;AAC1D,KAAI;EACH,MAAM,MAAM,MAAM,MAAM,KAAK;GAC5B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,QAAQ;GAC7B,QAAQ,WAAW;GACnB,CAAC;AACF,MAAI,CAAC,IAAI,GAAI,QAAO;GAAE,IAAI;GAAO,UAAU;GAAG,SAAS;GAAG;EAC1D,MAAM,OAAQ,MAAM,IAAI,MAAM;AAC9B,SAAO;GACN,IAAI;GACJ,UAAU,OAAO,KAAK,YAAY,EAAE;GACpC,SAAS,OAAO,KAAK,WAAW,EAAE;GAClC;SACM;AACP,SAAO;GAAE,IAAI;GAAO,UAAU;GAAG,SAAS;GAAG;WACpC;AACT,eAAa,QAAQ;;;;AAKvB,SAAgB,cACf,SACA,QACwC;CACxC,MAAM,WAAW,8BAA8B,QAAQ;AACvD,KAAI,CAAC,SAAU,QAAO;EAAE,UAAU;EAAG,SAAS;EAAG;CAEjD,MAAM,KAAK,QAAQ,OAAO;AAC1B,KAAI;AACH,MAAI;AACH,iBAAc,GAAG;UACV;EAGR,MAAM,kBAAkB,gBAAgB,SAAS,QAAQ;AAMzD,MALiB,GACf,QACA,uFACA,CACA,IAAI,SAAS,QAAQ,SAAS,mBAAmB,SAAS,SAAS,CACvD,QAAO;GAAE,UAAU;GAAG,SAAS;GAAG;AAEhD,KAAG,QACF;;;;;;iCAOA,CAAC,IACD,SAAS,QACT,SAAS,mBACT,SAAS,qBACT,SAAS,UACT,SAAS,QACT,SAAS,mBACT,eACA,SAAS,YACT,KAAK,UAAU,gBAAgB,CAC/B;EAQD,MAAM,gBALY,GAChB,QACA,mGACA,CACA,IAAI,SAAS,QAAQ,SAAS,kBAAkB,CAClB;AAGhC,KAAG,QACF;;;;;;;;;;kCAWA,CAAC,IACD,SAAS,QACT,SAAS,mBACT,SAAS,qBACT,SAAS,KACT,SAAS,SACT,SAAS,YACT,SAAS,YACT,cACA;AAED,SAAO;GAAE,UAAU;GAAG,SAAS;GAAG;WACzB;AACT,KAAG,OAAO;;;;;;;;;AAUZ,eAAsB,wBACrB,SACA,MACA,OAAmB,EAAE,EACG;CACxB,MAAM,aAAa,KAAK,cAAc;CACtC,MAAM,eAAe,KAAK,gBAAgB;CAC1C,MAAM,YAAY,KAAK,aAAa;CAEpC,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK,MAAM,KAAK,KAAK;AAClE,KAAI,WAAW,GACd,QAAO;EAAE,UAAU,WAAW;EAAU,SAAS,WAAW;EAAS,KAAK;EAAQ;AAKnF,QAAO;EAAE,GADY,aAAa,SADnB,UAAU,KAAK,MAAM,KAAK,OAAO,CACE;EACxB,KAAK;EAAU;;AAG1C,IAAa,0BAA0B,IAAI,QAAQ,qBAAqB,CACtE,cAAc,UAAU,CACxB,YAAY,6DAA6D,CACzE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,iBAAiB,sBAAsB,YAAY,CAC1D,OAAO,iBAAiB,sBAAsB,QAAQ,CACtD,OAAO,OAAO,SAAuE;CAErF,IAAI;AACJ,KAAI;AACH,QAAM,aAAa,GAAG,OAAO,CAAC,MAAM;SAC7B;AACP,UAAQ,WAAW;AACnB;;AAED,KAAI,CAAC,KAAK;AACT,UAAQ,WAAW;AACnB;;CAGD,IAAI;AACJ,KAAI;EACH,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,UAAU,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,EAAE;AAC1E,WAAQ,WAAW;AACnB;;AAED,YAAU;SACH;AACP,UAAQ,WAAW;AACnB;;CAGD,MAAM,OAAO,OAAO,SAAS,KAAK,MAAM,GAAG;CAC3C,MAAM,OAAO,KAAK;AAElB,KAAI;EACH,MAAM,SAAS,MAAM,wBAAwB,SAAS;GACrD;GACA;GACA,IAAI,KAAK;GACT,QAAQ,KAAK;GACb,CAAC;AACF,UAAQ,IAAI,KAAK,UAAU,OAAO,CAAC;SAC5B;AACP,UAAQ,WAAW;;EAEnB;;;AC5MH,SAAS,YAAY,OAAuB;AAC3C,KAAI,QAAQ,KAAM,QAAO,GAAG,MAAM;AAClC,KAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,EAAE,CAAC;AAC7D,QAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,EAAE,CAAC;;AAG9C,SAAS,2BAAyB,OAA+C;AAChF,KAAI,CAAC,MAAO,QAAO,KAAA;CACnB,MAAM,SAAS,OAAO,SAAS,OAAO,GAAG;AACzC,KAAI,CAAC,OAAO,SAAS,OAAO,IAAI,UAAU,EACzC,OAAM,IAAI,MAAM,6BAA6B,QAAQ;AAEtD,QAAO;;AAGR,SAAS,cAAc,OAAiD;AACvE,KAAI,CAAC,MAAO,QAAO,KAAA;CACnB,MAAM,QAAQ,MACZ,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,EAAE;AACnC,QAAO,MAAM,SAAS,IAAI,QAAQ,KAAA;;AAGnC,IAAa,YAAY,IAAI,QAAQ,KAAK,CACxC,cAAc,UAAU,CACxB,YAAY,uBAAuB;AAErC,UACE,WACA,IAAI,QAAQ,OAAO,CACjB,cAAc,UAAU,CACxB,YAAY,yDAAyD,CACrE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,QAAQ,SAA2C;CACnD,MAAM,SAAS,aAAa,KAAK,MAAM,KAAK,OAAO;AACnD,GAAE,MAAM,kBAAkB;AAC1B,GAAE,IAAI,QAAQ,mBAAmB,OAAO,OAAO;AAC/C,GAAE,MAAM,SAAS,OAAO,UAAU,gBAAgB,CAAC,QAAQ;EAC1D,CACH,CACA,WACA,IAAI,QAAQ,SAAS,CACnB,cAAc,UAAU,CACxB,YAAY,oCAAoC,CAChD,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,QAAQ,SAA2C;CACnD,MAAM,SAAS,eAAe,KAAK,MAAM,KAAK,OAAO;AACrD,GAAE,MAAM,oBAAoB;AAC5B,GAAE,IAAI,QAAQ,aAAa,OAAO,OAAO;AACzC,GAAE,MAAM,SAAS,OAAO,UAAU,gBAAgB,CAAC,QAAQ;EAC1D,CACH,CACA,WACA,IAAI,QAAQ,oBAAoB,CAC9B,cAAc,UAAU,CACxB,YAAY,kDAAkD,CAC9D,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,mBAAmB,oBAAoB,KAAK,CACnD,OAAO,UAAU,iBAAiB,CAClC,QAAQ,SAA0E;CAClF,MAAM,SAAS,kBACd,KAAK,MAAM,KAAK,QAChB,OAAO,SAAS,KAAK,OAAO,GAAG,IAAI,GACnC;AACD,KAAI,KAAK,MAAM;AACd,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;AAED,GAAE,MAAM,+BAA+B;AACvC,GAAE,IAAI,KACL,WAAW,OAAO,OAAO,QAAQ,gBAAgB,CAAC,kBAAkB,OAAO,OAAO,SAAS,gBAAgB,CAAC,aAC5G;AACD,KAAI,OAAO,MAAM,WAAW,GAAG;AAC9B,IAAE,MAAM,wBAAwB;AAChC;;AAED,MAAK,MAAM,QAAQ,OAAO,MACzB,GAAE,IAAI,QACL,GAAG,KAAK,OAAO,GAAG,KAAK,UAAU,WAAW,KAAK,IAAI,GAAG,KAAK,0BAA0B,KAAK,uBAAuB,CAAC,YACvG,KAAK,wBAAwB,WAAW,KAAK,uBAAuB,WAAW,KAAK,WAAW,KAC5G;AAEF,GAAE,MAAM,OAAO;EACd,CACH,CACA,WACA,IAAI,QAAQ,mBAAmB,CAC7B,cAAc,UAAU,CACxB,YAAY,yCAAyC,CACrD,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,mBAAmB,iCAAiC,KAAK,CAChE,QAAQ,SAA0D;CAClE,MAAM,SAAS,sBACd,KAAK,MAAM,KAAK,QAChB,OAAO,SAAS,KAAK,OAAO,GAAG,IAAI,GACnC;AACD,GAAE,MAAM,8BAA8B;AACtC,GAAE,MAAM,YAAY,OAAO,QAAQ,gBAAgB,CAAC,mBAAmB;EACtE,CACH,CACA,WACA,IAAI,QAAQ,kBAAkB,CAC5B,cAAc,UAAU,CACxB,YAAY,uEAAuE,CACnF,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,mCAAmC,8BAA8B,OAAO,CAC/E,OAAO,mCAAmC,8BAA8B,OAAO,CAC/E,OAAO,0CAA0C,qCAAqC,MAAM,CAC5F,OAAO,0BAA0B,4BAA4B,KAAK,CAClE,OAAO,UAAU,iBAAiB,CAClC,QACC,SAQK;CACL,MAAM,SAAS,cAAc,KAAK,MAAM,KAAK,QAAQ;EACpD,qBAAqB,OAAO,WAAW,KAAK,oBAAoB;EAChE,qBAAqB,OAAO,WAAW,KAAK,oBAAoB;EAChE,4BAA4B,OAAO,WAAW,KAAK,2BAA2B;EAC9E,aAAa,OAAO,WAAW,KAAK,YAAY;EAChD,CAAC;AAEF,KAAI,KAAK,MAAM;AACd,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C,MAAI,CAAC,OAAO,OAAQ,SAAQ,WAAW;AACvC;;AAGD,GAAE,MAAM,6BAA6B;AACrC,GAAE,IAAI,KACL;EACC,gCAAgC,OAAO,QAAQ,MAAM,mBAAmB,QAAQ,EAAE;EAClF,gCAAgC,OAAO,QAAQ,MAAM,mBAAmB,QAAQ,EAAE;EAClF,gCAAgC,OAAO,QAAQ,MAAM,0BAA0B,QAAQ,EAAE;EACzF,gCAAgC,OAAO,QAAQ,gBAAgB;EAC/D,CAAC,KAAK,KAAK,CACZ;AAED,KAAI,OAAO,OACV,GAAE,MAAM,0BAA0B;MAC5B;AACN,OAAK,MAAM,KAAK,OAAO,SACtB,GAAE,IAAI,MAAM,EAAE;AAEf,IAAE,MAAM,0BAA0B;AAClC,UAAQ,WAAW;;EAGrB,CACF,CACA,WACA,IAAI,QAAQ,iBAAiB,CAC3B,cAAc,UAAU,CACxB,YAAY,sDAAsD,CAClE,SAAS,cAAc,uBAAuB,CAC9C,SAAS,cAAc,mBAAmB,CAC1C,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,WAAW,qCAAqC,CACvD,QAEC,SACA,SACA,SACI;CACJ,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,SAAS,CAAC,KAAK;EAErB,MAAM,gBAAgB,KADH,QAAQ,QAAQ,MAAM,MAAM,CAAC,QAAQ,MAAM,MAAM;EAEpE,MAAM,SAAS,CAAC,YAAY,qBAAqB;EACjD,MAAM,SAAiC,EAAE;EACzC,MAAM,YAAY;AACjB,QAAK,MAAM,SAAS,QAAQ;IAC3B,MAAM,OAAO,MAAM,GACjB,QACA,+BAA+B,MAAM,kDACrC,CACA,IAAI,SAAS,cAAc;AAC7B,WAAO,SAAS,KAAK;AACrB,QAAI,CAAC,UAAU,KAAK,MAAM,GAAG;AAC5B,WAAM,GACJ,QAAQ,UAAU,MAAM,oCAAoC,CAC5D,IAAI,SAAS,QAAQ;AACvB,WAAM,GACJ,QACA,UAAU,MAAM,oEAChB,CACA,IAAI,SAAS,eAAe,QAAQ;;;;AAIzC,MAAI,OACH,MAAK;MAEL,OAAM,GAAG,YAAY,IAAI,EAAE;EAE5B,MAAM,SAAS,SAAS,gBAAgB;AACxC,IAAE,MAAM,4BAA4B;AACpC,IAAE,IAAI,KAAK,GAAG,OAAO,GAAG,QAAQ,KAAK,UAAU;AAC/C,IAAE,IAAI,KACL,CACC,aAAa,OAAO,YACpB,uBAAuB,OAAO,qBAC9B,CAAC,KAAK,KAAK,CACZ;AACD,MAAI,OACH,GAAE,MAAM,0BAA0B;MAElC,GAAE,MAAM,OAAO;WAEP;AACT,QAAM,OAAO;;EAGf,CACF,CACA,WACA,IAAI,QAAQ,qBAAqB,CAC/B,cAAc,UAAU,CACxB,YAAY,4DAA4D,CACxE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,WAAW,qCAAqC,CACvD,QAAQ,SAA4D;CACpE,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,SAAS,CAAC,KAAK;EACrB,MAAM,SAAS,CAAC,YAAY,qBAAqB;EACjD,MAAM,2BAAgC,IAAI,KAAK;EAC/C,MAAM,SAAiC,EAAE;EAEzC,MAAM,YAAY;AACjB,QAAK,MAAM,SAAS,QAAQ;IAC3B,MAAM,WAAW,MAAM,GACrB,QACA,gCAAgC,MAAM,mDACtC,CACA,KAAK;IACP,IAAI,UAAU;AACd,SAAK,MAAM,OAAO,UAAU;KAC3B,MAAM,WAAW,IAAI,QAAQ,MAAM,IAAI,CAAC,KAAK,IAAI,IAAI;AACrD,SAAI,aAAa,IAAI,SAAS;AAC7B,eAAS,IAAI,IAAI,SAAS,SAAS;AACnC,UAAI,CAAC,QAAQ;OACZ,MAAM,OAAO,MAAM,GACjB,QAAQ,UAAU,MAAM,oCAAoC,CAC5D,IAAI,UAAU,IAAI,QAAQ;AAC5B,kBAAW,KAAK;aACV;OACN,MAAM,MAAM,MAAM,GAChB,QAAQ,+BAA+B,MAAM,oBAAoB,CACjE,IAAI,IAAI,QAAQ;AAClB,kBAAW,IAAI;;;;AAIlB,WAAO,SAAS;;;AAGlB,MAAI,OACH,MAAK;MAEL,OAAM,GAAG,YAAY,IAAI,EAAE;AAG5B,IAAE,MAAM,gCAAgC;AACxC,IAAE,IAAI,KAAK,YAAY,SAAS;AAChC,IAAE,IAAI,KACL,CACC,uBAAuB,OAAO,YAC9B,iCAAiC,OAAO,qBACxC,CAAC,KAAK,KAAK,CACZ;AACD,MAAI,SAAS,OAAO,GAAG;AACtB,KAAE,IAAI,KAAK,mBAAmB;AAC9B,QAAK,MAAM,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC,MAAM,CACtD,GAAE,IAAI,QAAQ,KAAK,KAAK,KAAK,KAAK;;AAGpC,MAAI,OACH,GAAE,MAAM,0BAA0B;MAElC,GAAE,MAAM,OAAO;WAEP;AACT,QAAM,OAAO;;EAEb,CACH,CACA,WACA,IAAI,QAAQ,cAAc,CACxB,cAAc,UAAU,CACxB,YAAY,oDAAoD,CAChE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,eAAe,4CAA4C,KAAK,CACvE,OAAO,UAAU,iBAAiB,CAClC,QAAQ,SAA0E;CAClF,MAAM,SAAS,cAAc,KAAK,MAAM,KAAK,OAAO;CACpD,MAAM,KAAK,QAAQ,OAAO;AAC1B,KAAI;EACH,MAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,SAAS,KAAK,OAAO,GAAG,IAAI,GAAG;EAChE,MAAM,gBAAgB,SAAS,OAAO,CAAC;EACvC,MAAM,WAAW,GACf,QACA,kFACA,CACA,KAAK;EACP,MAAM,YAAY,GAAG,QAAQ,mDAAmD,CAAC,KAAK;EAGtF,MAAM,WAAW,GAAG,QAAQ,mBAAmB,CAAC,KAAK;EAGrD,MAAM,SAAS,GACb,QACA;;;;iBAKA,CACA,IAAI,MAAM;AAEZ,MAAI,KAAK,MAAM;AACd,WAAQ,IACP,KAAK,UACJ;IACC,iBAAiB;IACjB,eAAe,UAAU,SAAS;IAClC,aAAa,WAAW,kBAAkB,MAAM,UAAU,aAAa;IACvE,QAAQ,OAAO,KAAK,OAAO;KAAE,MAAM,EAAE;KAAM,YAAY,EAAE;KAAY,EAAE;IACvE,EACD,MACA,EACA,CACD;AACD;;AAGD,IAAE,MAAM,yBAAyB;AACjC,IAAE,IAAI,KACL;GACC,kBAAkB,YAAY,cAAc;GAC5C,kBAAkB,YAAY,UAAU,SAAS,EAAE;GACnD,kBAAkB,aAAa,WAAW,kBAAkB,MAAM,UAAU,aAAa,MAAM;GAC/F,CAAC,KAAK,KAAK,CACZ;AACD,MAAI,OAAO,SAAS,GAAG;AACtB,KAAE,IAAI,KAAK,mBAAmB;AAC9B,QAAK,MAAM,KAAK,OACf,GAAE,IAAI,QAAQ,KAAK,EAAE,KAAK,OAAO,GAAG,CAAC,GAAG,YAAY,EAAE,WAAW,CAAC,SAAS,GAAG,GAAG;;AAGnF,IAAE,MAAM,OAAO;WACN;AACT,KAAG,OAAO;;EAEV,CACH,CACA,WACA,IAAI,QAAQ,gBAAgB,CAC1B,cAAc,UAAU,CACxB,YAAY,uDAAuD,CACnE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,eAAe,wBAAwB,CAC9C,OAAO,iBAAiB,oDAAoD,CAC5E,OAAO,uBAAuB,iDAAiD,CAC/E,OAAO,kBAAkB,+BAA+B,CACxD,OAAO,cAAc,4BAA4B,CACjD,OAAO,aAAa,kCAAkC,CACtD,OAAO,UAAU,iBAAiB,CAClC,QACC,SAUK;CACL,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,2BAAyB,KAAK,MAAM;EAClD,MAAM,UACL,KAAK,gBAAgB,OAClB,OACA,KAAK,SAAS,MAAM,IACrB,QAAQ,IAAI,iBAAiB,MAAM,IACnC,eAAe,QAAQ,KAAK,EAAE,KAAK;EACtC,MAAM,SAAS,iBAAiB,MAAM,IAAI;GACzC;GACA,OAAO,KAAK,SAAS;GACrB;GACA,YAAY,CAAC,KAAK;GAClB,QAAQ,KAAK,WAAW;GACxB,CAAC;AAEF,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;EAGD,MAAM,SAAS,KAAK,SAAS,iBAAiB;AAC9C,IAAE,MAAM,2BAA2B;AACnC,IAAE,IAAI,QAAQ,GAAG,OAAO,GAAG,OAAO,QAAQ,qBAAqB,OAAO,QAAQ,GAAG;AACjF,IAAE,MAAM,WAAW,OAAO,QAAQ,WAAW;UACrC,OAAO;AACf,IAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;AACnE,UAAQ,WAAW;WACV;AACT,QAAM,OAAO;;EAGf,CACF,CACA,WACA,IAAI,QAAQ,qBAAqB,CAC/B,cAAc,UAAU,CACxB,YAAY,4DAA4D,CACxE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,eAAe,4BAA4B,CAClD,OAAO,aAAa,wCAAwC,CAC5D,OAAO,UAAU,iBAAiB,CAClC,QACC,SAMK;CACL,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,2BAAyB,KAAK,MAAM;EAClD,MAAM,SAAS,gCACd,MAAM,IACN,SAAS,MACT,KAAK,WAAW,KAChB;AAED,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;EAGD,MAAM,SAAS,KAAK,SAAS,qBAAqB;AAClD,IAAE,MAAM,gCAAgC;AACxC,IAAE,MAAM,GAAG,OAAO,GAAG,OAAO,YAAY,MAAM,OAAO,QAAQ,eAAe;UACpE,OAAO;AACf,IAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;AACnE,UAAQ,WAAW;WACV;AACT,QAAM,OAAO;;EAGf,CACF,CACA,WACA,IAAI,QAAQ,iBAAiB,CAC3B,cAAc,UAAU,CACxB,YAAY,uDAAuD,CACnE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,eAAe,wBAAwB,CAC9C,OAAO,iBAAiB,0DAA0D,CAClF,OAAO,aAAa,wCAAwC,CAC5D,OAAO,UAAU,iBAAiB,CAClC,QACC,SAOK;CACL,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,2BAAyB,KAAK,MAAM;EAClD,MAAM,QAAQ,cAAc,KAAK,MAAM;EACvC,MAAM,SAAS,4BAA4B,MAAM,IAAI;GACpD;GACA,OAAO,SAAS;GAChB,QAAQ,KAAK,WAAW;GACxB,CAAC;AAEF,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;EAGD,MAAM,SAAS,KAAK,SAAS,qBAAqB;AAClD,IAAE,MAAM,4BAA4B;AACpC,IAAE,MAAM,GAAG,OAAO,GAAG,OAAO,YAAY,MAAM,OAAO,QAAQ,WAAW;UAChE,OAAO;AACf,IAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;AACnE,UAAQ,WAAW;WACV;AACT,QAAM,OAAO;;EAGf,CACF;;;ACthBF,SAAS,yBAAyB,OAA+C;AAChF,KAAI,CAAC,MAAO,QAAO,KAAA;CACnB,MAAM,SAAS,OAAO,SAAS,OAAO,GAAG;AACzC,KAAI,CAAC,OAAO,SAAS,OAAO,IAAI,UAAU,EACzC,OAAM,IAAI,MAAM,6BAA6B,QAAQ;AAEtD,QAAO;;AAGR,SAAgB,yBACf,KACA,YACA,aACgB;AAChB,KAAI,gBAAgB,KAAM,QAAO;CACjC,MAAM,WAAW,YAAY,MAAM;AACnC,KAAI,SAAU,QAAO;CACrB,MAAM,aAAa,QAAQ,IAAI,iBAAiB,MAAM;AACtD,KAAI,WAAY,QAAO;AACvB,QAAO,eAAe,KAAK,KAAK;;AAGjC,IAAa,eAAe,IAAI,QAAQ,QAAQ,CAC9C,cAAc,UAAU,CACxB,YAAY,+BAA+B,CAC3C,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,eAAe,wBAAwB,CAC9C,OAAO,iBAAiB,oDAAoD,CAC5E,OAAO,uBAAuB,iDAAiD,CAC/E,OAAO,kBAAkB,4BAA4B,CACrD,OAAO,cAAc,4BAA4B,CACjD,OAAO,aAAa,uCAAuC,CAC3D,OAAO,UAAU,iBAAiB,CAClC,OACA,OAAO,SAUD;CACL,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,yBAAyB,KAAK,MAAM;EAClD,MAAM,UAAU,yBAAyB,QAAQ,KAAK,EAAE,KAAK,SAAS,KAAK,YAAY;EAEvF,MAAM,SAAS,MAAM,gBAAgB,MAAM,IAAI;GAC9C;GACA,OAAO,KAAK,SAAS;GACrB;GACA,YAAY,CAAC,KAAK;GAClB,QAAQ,KAAK,WAAW;GACxB,CAAC;AAEF,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;EAGD,MAAM,SAAS,KAAK,SAAS,gBAAgB;AAC7C,IAAE,MAAM,gBAAgB;AACxB,IAAE,IAAI,QACL,GAAG,OAAO,GAAG,OAAO,SAAS,YAAY,OAAO,SAAS,aAAa,OAAO,QAAQ,WACrF;AACD,IAAE,MAAM,WAAW,OAAO,QAAQ,WAAW;UACrC,OAAO;AACf,IAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,CAAC;AACnE,UAAQ,WAAW;WACV;AACT,QAAM,OAAO;;EAGf;;;AC9EF,IAAM,kBAAkB;CACvB;CACA;CACA;CACA;CACA;AAED,SAAS,uBAAuB,SAAiD;CAChF,MAAM,yBAAS,IAAI,KAAqB;AACxC,MAAK,MAAM,OAAO,iBAAiB;EAClC,MAAM,QAAQ,QAAQ;AACtB,MAAI,OAAO,UAAU,SAAU;EAC/B,MAAM,OAAO,MAAM,MAAM;AACzB,MAAI,KAAM,QAAO,IAAI,KAAK,KAAK;;AAEhC,KAAI,OAAO,SAAS,EAAG,QAAO;AAE9B,KADe,IAAI,IAAI,OAAO,QAAQ,CAAC,CAC5B,OAAO,EAAG,OAAM,IAAI,MAAM,gCAAgC;AACrE,MAAK,MAAM,OAAO,iBAAiB;EAClC,MAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,MAAI,MAAO,QAAO;;AAEnB,QAAO;;AAGR,eAAe,gBAAkD;CAChE,MAAM,SAAmB,EAAE;AAC3B,YAAW,MAAM,SAAS,QAAQ,MACjC,QAAO,KAAK,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,OAAO,MAAM,CAAC,CAAC;CAEzE,MAAM,MAAM,OAAO,OAAO,OAAO,CAAC,SAAS,QAAQ,CAAC,MAAM;AAC1D,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,sBAAsB;CAChD,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,KAAI,UAAU,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,CACxE,OAAM,IAAI,MAAM,4BAA4B;AAE7C,QAAO;;AAGR,IAAa,yBAAyB,IAAI,QAAQ,oBAAoB,CACpE,cAAc,UAAU,CACxB,YAAY,0DAA0D,CACtE,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,OAAO,SAA2C;CACzD,MAAM,UAAU,MAAM,eAAe;CACrC,MAAM,YAAY,uBAAuB,QAAQ;AACjD,KAAI,CAAC,UAAW,OAAM,IAAI,MAAM,sBAAsB;AACtD,KAAI,UAAU,WAAW,OAAO,CAAE,OAAM,IAAI,MAAM,qBAAqB;CAEvE,MAAM,YAAY,OAAO,QAAQ,eAAe,WAAW,QAAQ,WAAW,MAAM,GAAG;AACvF,KAAI,CAAC,UAAW,OAAM,IAAI,MAAM,sBAAsB;CAEtD,MAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,QAAQ,MAAM;CAC5D,MAAM,UAAU,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;CACxE,MAAM,YAAY,OAAO,QAAQ,eAAe,WAAW,QAAQ,aAAa;CAChF,MAAM,WAAW,OAAO,SAAS,OAAO,QAAQ,WAAW,CAAC,GACzD,KAAK,MAAM,OAAO,QAAQ,WAAW,CAAC,GACtC;CACH,MAAM,WAAW,OAAO,SAAS,OAAO,QAAQ,WAAW,CAAC,GACzD,OAAO,QAAQ,WAAW,GAC1B;CACH,MAAM,UAAU,OAAO,QAAQ,aAAa,WAAW,QAAQ,SAAS,MAAM,GAAG;CACjF,MAAM,eACL,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,CAAC,MAAM,QAAQ,QAAQ,QAAQ,GACrF,gBAAgB,QAAQ,QAAQ,GACjC,EAAE;CAEN,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;AACH,QAAM,0BAA0B;GAC/B,mBAAmB;GACnB,QAAQ;GACR;GACA;GACA;GACA,kBAAkB;GAClB,CAAC;AACF,QAAM,qBAAqB,WAAW,CACrC;GACC,UAAU;GACV,YAAY;GACZ,SAAS;GACT,YAAY;GACZ,YAAY;GACZ,CACD,CAAC;WACO;AACT,QAAM,OAAO;;EAEb;;;ACtFH,SAAS,eAAe,OAAuB;AAC9C,QAAO,MAAM,WAAW,KAAK,GAAG,KAAK,SAAS,EAAE,MAAM,MAAM,EAAE,CAAC,GAAG;;AAGnE,IAAa,wBAAwB,IAAI,QAAQ,kBAAkB,CACjE,cAAc,UAAU,CACxB,YAAY,uDAAuD,CACnE,SAAS,YAAY,wCAAwC,CAC7D,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,uBAAuB,gDAAgD,CAC9E,OAAO,kBAAkB,sBAAsB,CAC/C,OAAO,sBAAsB,+BAA+B,CAC5D,OAAO,iBAAiB,wDAAwD,CAChF,QAEC,QACA,SAQI;CACJ,MAAM,UAAU,eAAe;EAC9B,QAAQ,cAAc,KAAK,MAAM,KAAK,OAAO;EAC7C,SAAS,KAAK;EACd,aAAa,KAAK;EAClB,iBAAiB,KAAK;EACtB,OAAO,KAAK;EACZ,CAAC;CACF,MAAM,OAAO,GAAG,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AACjD,KAAI,WAAW,KAAK;AACnB,UAAQ,OAAO,MAAM,KAAK;AAC1B;;CAED,MAAM,aAAa,eAAe,OAAO;AACzC,eAAc,YAAY,MAAM,OAAO;AACvC,GAAE,MAAM,0BAA0B;AAClC,GAAE,IAAI,QACL;EACC,cAAc;EACd,cAAc,QAAQ,SAAS,OAAO,gBAAgB;EACtD,cAAc,QAAQ,aAAa,OAAO,gBAAgB;EAC1D,cAAc,QAAQ,kBAAkB,OAAO,gBAAgB;EAC/D,cAAc,QAAQ,aAAa,OAAO,gBAAgB;EAC1D,CAAC,KAAK,KAAK,CACZ;AACD,GAAE,MAAM,OAAO;EAEhB;;;ACtDF,IAAa,wBAAwB,IAAI,QAAQ,kBAAkB,CACjE,cAAc,UAAU,CACxB,YAAY,6CAA6C,CACzD,SAAS,eAAe,sCAAsC,CAC9D,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,0BAA0B,4CAA4C,CAC7E,OAAO,aAAa,iCAAiC,CACrD,QAEC,WACA,SACI;CACJ,IAAI;AACJ,KAAI;AACH,YAAU,kBAAkB,UAAU;UAC9B,OAAO;AACf,IAAE,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,sBAAsB;AAC3E,UAAQ,WAAW;AACnB;;AAGD,GAAE,MAAM,0BAA0B;AAClC,GAAE,IAAI,KACL;EACC,mBAAmB,QAAQ;EAC3B,mBAAmB,QAAQ;EAC3B,mBAAmB,QAAQ,SAAS,OAAO,gBAAgB;EAC3D,mBAAmB,QAAQ,aAAa,OAAO,gBAAgB;EAC/D,mBAAmB,QAAQ,kBAAkB,OAAO,gBAAgB;EACpE,mBAAmB,QAAQ,aAAa,OAAO,gBAAgB;EAC/D,CAAC,KAAK,KAAK,CACZ;CAED,MAAM,SAAS,eAAe,SAAS;EACtC,QAAQ,cAAc,KAAK,MAAM,KAAK,OAAO;EAC7C,cAAc,KAAK;EACnB,QAAQ,KAAK;EACb,CAAC;AAEF,KAAI,OAAO,QAAQ;AAClB,IAAE,MAAM,mBAAmB;AAC3B;;AAED,GAAE,IAAI,QACL;EACC,uBAAuB,OAAO,SAAS,gBAAgB;EACvD,uBAAuB,OAAO,aAAa,gBAAgB;EAC3D,uBAAuB,OAAO,aAAa,gBAAgB;EAC3D,uBAAuB,OAAO,kBAAkB,gBAAgB;EAChE,CAAC,KAAK,KAAK,CACZ;AACD,GAAE,MAAM,OAAO;EAEhB;;;ACzDF,IAAa,aAAa,IAAI,QAAQ,MAAM,CAC1C,cAAc,UAAU,CACxB,YAAY,6BAA6B,CACzC,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,OAAO,SAA2C;CACzD,MAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,KAAI,OAAQ,SAAQ,IAAI,aAAa;AAErC,OAAM,OAAO;EACZ;;;;;;;;;;ACAH,SAAS,wBAAsB,OAAe,UAA8B;AAC3E,QAAO,CAAC,GAAG,UAAU,MAAM;;;AAI5B,SAAS,sBAAsB,OAA8B;AAC5D,KAAI,CAAC,QAAQ,KAAK,MAAM,MAAM,CAAC,CAAE,QAAO;CACxC,MAAM,IAAI,OAAO,MAAM,MAAM,CAAC;AAC9B,QAAO,OAAO,SAAS,EAAE,IAAI,KAAK,KAAK,OAAO,UAAU,EAAE,GAAG,IAAI;;AAGlE,SAAS,iBAAiB,OAAe,MAA8C;CACtF,MAAM,WAAW,sBAAsB,MAAM;AAC7C,KAAI,aAAa,MAAM;AACtB,IAAE,IAAI,MAAM,sBAAsB,QAAQ;AAC1C,UAAQ,WAAW;AACnB;;CAED,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,OAAO,MAAM,IAAI,SAAS;AAChC,MAAI,CAAC,MAAM;AACV,KAAE,IAAI,MAAM,UAAU,SAAS,YAAY;AAC3C,WAAQ,WAAW;AACnB;;AAED,UAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;WACjC;AACT,QAAM,OAAO;;;AAIf,SAAS,mBAAmB,OAAe,MAA8C;CACxF,MAAM,WAAW,sBAAsB,MAAM;AAC7C,KAAI,aAAa,MAAM;AACtB,IAAE,IAAI,MAAM,sBAAsB,QAAQ;AAC1C,UAAQ,WAAW;AACnB;;CAED,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;AACH,QAAM,OAAO,SAAS;AACtB,IAAE,IAAI,QAAQ,UAAU,SAAS,kBAAkB;WAC1C;AACT,QAAM,OAAO;;;AAcf,eAAe,qBAAqB,MAA4C;CAC/E,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;CACpE,IAAI,YAA2B;AAC/B,KAAI;EACH,MAAM,UAAU,eAAe,QAAQ,KAAK,EAAE,KAAK,WAAW,KAAK;AACnE,cAAY,MAAM,aAAa;GAC9B,KAAK,QAAQ,KAAK;GAClB;GACA,MAAM,QAAQ,IAAI,QAAQ;GAC1B,aAAa;GACb,UAAU,EAAE,QAAQ,MAAM;GAC1B,CAAC;EACF,MAAM,QAAQ,MAAM,SAAS,WAAW,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,IAAK,KAAK,KAAK;AACzF,QAAM,MAAM,0BAA0B;AACtC,QAAM,WAAW,WAAW,EAAE,QAAQ,MAAM,CAAC;AAC7C,IAAE,IAAI,QAAQ,iBAAiB,QAAQ;UAC/B,KAAK;AACb,MAAI,cAAc,KACjB,KAAI;AACH,SAAM,WAAW,WAAW;IAAE,QAAQ;IAAM,OAAO;IAAM,CAAC;UACnD;AAIT,QAAM;WACG;AACT,QAAM,OAAO;;;AAIf,SAAS,0BAAmC;AAC3C,QAAO,IAAI,QAAQ,OAAO,CACxB,cAAc,UAAU,CACxB,YAAY,8BAA8B,CAC1C,SAAS,QAAQ,YAAY,CAC7B,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,iBAAiB;;AAG3B,SAAS,4BAAqC;AAC7C,QAAO,IAAI,QAAQ,SAAS,CAC1B,cAAc,UAAU,CACxB,YAAY,2BAA2B,CACvC,SAAS,QAAQ,YAAY,CAC7B,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,mBAAmB;;AAG7B,SAAS,8BAAuC;AAC/C,QAAO,IAAI,QAAQ,WAAW,CAC5B,cAAc,UAAU,CACxB,YAAY,6BAA6B,CACzC,eAAe,qBAAqB,2DAA2D,CAC/F,eAAe,uBAAuB,eAAe,CACrD,eAAe,qBAAqB,mBAAmB,CACvD,OAAO,oBAAoB,yBAAyB,CACpD,OAAO,uBAAuB,2CAA2C,CACzE,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,qBAAqB;;AAG/B,SAAS,4BAAqC;AAC7C,QAAO,IAAI,QAAQ,SAAS,CAC1B,cAAc,UAAU,CACxB,YAAY,4DAA4D,CACxE,SAAS,aAAa,+BAA+B,CACrD,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,mBAAmB,aAAa,KAAK,CAC5C,OAAO,qBAAqB,eAAe,CAC3C,OAAO,2BAA2B,eAAe,CACjD,OACA,6BACA,oDACA,yBACA,EAAE,CACF,CACA,OAAO,uBAAuB,iDAAiD,CAC/E,OAAO,kBAAkB,6BAA6B,CACtD,mBAAmB,KAAK,CACxB,qBAAqB,KAAK,CAC1B,OACA,OACC,SACA,SAUI;EACJ,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,MAAI;GACH,MAAM,QAAQ,OAAO,SAAS,KAAK,SAAS,MAAM,GAAG,IAAI;GACzD,MAAM,YAAY,KAAK,eAAe,KAAK;GAC3C,MAAM,SAAS,YAAY,OAAO,SAAS,WAAW,GAAG,GAAG,KAAA;GAC5D,MAAM,UAA8D,EAAE;AACtE,OAAI,CAAC,KAAK,aAAa;IAEtB,MAAM,UADiB,QAAQ,IAAI,iBAAiB,MAAM,IACxB,eAAe,QAAQ,KAAK,EAAE,KAAK,WAAW,KAAK;AACrF,QAAI,QAAS,SAAQ,UAAU;;AAEhC,QAAK,KAAK,gBAAgB,UAAU,KAAK,EACxC,SAAQ,oBAAoB,KAAK;GAElC,MAAM,OAAO,MAAM,MAAM,qBAAqB,SAAS,OAAO,QAAQ,QAAQ;AAC9E,WAAQ,IAAI,KAAK,aAAa,GAAG;YACxB;AACT,SAAM,OAAO;;GAGf;;AAGH,SAAS,6BAAsC;AAC9C,QAAO,IAAI,QAAQ,UAAU,CAC3B,cAAc,UAAU,CACxB,YAAY,kDAAkD,CAC9D,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,qBAAqB,aAAa,CACzC,OAAO,eAAe,2BAA2B,KAAK,CACtD,mBAAmB,KAAK,CACxB,qBAAqB,KAAK,CAC1B,aAAa;AACb,IAAE,IAAI,KAAK,yEAAyE;AACpF,IAAE,IAAI,KACL,6GACA;AACD,UAAQ,WAAW;GAClB;;AAGJ,IAAa,oBAAoB,yBAAyB;AAC1D,IAAa,sBAAsB,2BAA2B;AAC9D,IAAa,wBAAwB,6BAA6B;AAElE,IAAa,gBAAgB,IAAI,QAAQ,SAAS,CAChD,cAAc,UAAU,CACxB,YAAY,yBAAyB;AAEvC,cAAc,WAAW,yBAAyB,CAAC;AACnD,cAAc,WAAW,2BAA2B,CAAC;AACrD,cAAc,WAAW,6BAA6B,CAAC;AACvD,cAAc,WAAW,2BAA2B,CAAC;AACrD,cAAc,WAAW,4BAA4B,CAAC;;;AC1NtD,SAAS,sBAAsB,OAAe,UAA8B;AAC3E,QAAO,CAAC,GAAG,UAAU,MAAM;;AAG5B,IAAa,cAAc,IAAI,QAAQ,OAAO,CAC5C,cAAc,UAAU,CACxB,YAAY,oCAAoC,CAChD,SAAS,aAAa,+BAA+B,CACrD,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,mBAAmB,aAAa,KAAK,CAC5C,OAAO,qBAAqB,eAAe,CAC3C,OAAO,2BAA2B,eAAe,CACjD,OACA,6BACA,oDACA,uBACA,EAAE,CACF,CACA,OAAO,uBAAuB,iDAAiD,CAC/E,OAAO,kBAAkB,6BAA6B,CACtD,OAAO,UAAU,iBAAiB,CAClC,OACA,OACC,SACA,SAWI;CACJ,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,OAAO,SAAS,KAAK,OAAO,GAAG,IAAI;EACjD,MAAM,YAAY,KAAK,eAAe,KAAK;EAC3C,MAAM,SAAS,YAAY,OAAO,SAAS,WAAW,GAAG,GAAG,KAAA;EAC5D,MAAM,UAA8D,EAAE;AACtE,MAAI,CAAC,KAAK,aAAa;GAEtB,MAAM,UADiB,QAAQ,IAAI,iBAAiB,MAAM,IACxB,eAAe,QAAQ,KAAK,EAAE,KAAK,WAAW,KAAK;AACrF,OAAI,QAAS,SAAQ,UAAU;;AAEhC,OAAK,KAAK,gBAAgB,UAAU,KAAK,EACxC,SAAQ,oBAAoB,KAAK;EAElC,MAAM,SAAS,MAAM,MAAM,qBAAqB,SAAS,OAAO,QAAQ,QAAQ;AAEhF,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;AAGD,IAAE,MAAM,oBAAoB,QAAQ,GAAG;AAEvC,MAAI,OAAO,MAAM,WAAW,GAAG;AAC9B,KAAE,IAAI,KAAK,8BAA8B;AACzC,KAAE,MAAM,OAAO;AACf;;EAGD,MAAM,IAAI,OAAO;AACjB,IAAE,IAAI,KACL,GAAG,EAAE,YAAY,WAAW,EAAE,YAAY,YACxC,EAAE,gBAAgB,gBAAgB,MACnC,UAAU,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,SAAS,SAAS,EAAE,QAAQ,MAAM,GAC5E;AAED,OAAK,MAAM,QAAQ,OAAO,MACzB,GAAE,IAAI,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,KAAK,QAAQ;AAGvD,IAAE,KAAK,OAAO,WAAW,YAAY;AAErC,IAAE,MAAM,OAAO;WACN;AACT,QAAM,OAAO;;EAGf;;;ACrFF,IAAa,gBAAgB,IAAI,QAAQ,SAAS,CAChD,cAAc,UAAU,CACxB,YAAY,uBAAuB,CACnC,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,eAAe,eAAe,IAAI,CACzC,OAAO,uBAAuB,iDAAiD,CAC/E,OAAO,kBAAkB,6BAA6B,CACtD,OAAO,iBAAiB,wBAAwB,CAChD,QACC,SAOK;CACL,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,SAAS,KAAK,OAAO,GAAG,IAAI,EAAE;EAC/D,MAAM,UAA+C,EAAE;AACvD,MAAI,KAAK,KAAM,SAAQ,OAAO,KAAK;AACnC,MAAI,CAAC,KAAK,aAAa;GAEtB,MAAM,UADiB,QAAQ,IAAI,iBAAiB,MAAM,IACxB,eAAe,QAAQ,KAAK,EAAE,KAAK,WAAW,KAAK;AACrF,OAAI,QAAS,SAAQ,UAAU;;EAEhC,MAAM,QAAQ,MAAM,OAAO,OAAO,QAAQ;AAC1C,OAAK,MAAM,QAAQ,MAClB,SAAQ,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,KAAK,QAAQ;WAE/C;AACT,QAAM,OAAO;;EAGf;;;ACnCF,IAAa,gBAAgB,IAAI,QAAQ,SAAS,CAChD,cAAc,UAAU,CACxB,YAAY,2BAA2B,CACvC,SAAS,WAAW,eAAe,CACnC,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,mBAAmB,eAAe,IAAI,CAC7C,OAAO,uBAAuB,iDAAiD,CAC/E,OAAO,kBAAkB,6BAA6B,CACtD,OAAO,iBAAiB,wBAAwB,CAChD,OAAO,UAAU,iBAAiB,CAClC,QAEC,OACA,SASI;CACJ,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,SAAS,KAAK,OAAO,GAAG,IAAI,EAAE;EAC/D,MAAM,UAA+C,EAAE;AACvD,MAAI,KAAK,KAAM,SAAQ,OAAO,KAAK;AACnC,MAAI,CAAC,KAAK,aAAa;GAEtB,MAAM,UADiB,QAAQ,IAAI,iBAAiB,MAAM,IACxB,eAAe,QAAQ,KAAK,EAAE,KAAK,WAAW,KAAK;AACrF,OAAI,QAAS,SAAQ,UAAU;;EAEhC,MAAM,UAAU,MAAM,OAAO,OAAO,OAAO,QAAQ;AAEnD,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AAC7C;;AAGD,MAAI,QAAQ,WAAW,GAAG;AACzB,KAAE,IAAI,KAAK,oBAAoB;AAC/B;;AAGD,IAAE,MAAM,GAAG,QAAQ,OAAO,kBAAkB,MAAM,GAAG;AAErD,OAAK,MAAM,QAAQ,SAAS;GAC3B,MAAM,QAAQ,KAAK,MAAM,QAAQ,EAAE;GACnC,MAAM,MAAM,UAAU,KAAK,WAAW;GACtC,MAAM,UACL,KAAK,UAAU,SAAS,MAAM,GAAG,KAAK,UAAU,MAAM,GAAG,IAAI,CAAC,KAAK,KAAK;AAEzE,KAAE,IAAI,QACL;IAAC,IAAI,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM;IAAI,KAAK;IAAO;IAAQ,CAAC,KAAK,KAAK,CACjF;;AAGF,IAAE,MAAM,OAAO;WACN;AACT,QAAM,OAAO;;EAGf;AAEF,SAAS,UAAU,SAAyB;CAC3C,MAAM,KAAK,KAAK,KAAK,GAAG,IAAI,KAAK,QAAQ,CAAC,SAAS;CACnD,MAAM,OAAO,KAAK,MAAM,KAAK,MAAW;AACxC,KAAI,SAAS,EAAG,QAAO;AACvB,KAAI,SAAS,EAAG,QAAO;AACvB,KAAI,OAAO,GAAI,QAAO,GAAG,KAAK;AAE9B,QAAO,GADQ,KAAK,MAAM,OAAO,GAAG,CACnB;;;;ACxClB,SAAS,UAAU,SAAyB;CAC3C,MAAM,OAAO,OAAO,SAAS,SAAS,GAAG;AACzC,KAAI,CAAC,OAAO,SAAS,KAAK,IAAI,OAAO,KAAK,OAAO,MAChD,OAAM,IAAI,MAAM,iBAAiB,UAAU;AAE5C,QAAO;;AAGR,SAAgB,6BAA6B,MAAmD;AAC/F,KAAI,KAAK,QAAQ,KAAK,QACrB,OAAM,IAAI,MAAM,sCAAsC;AAEvD,KAAI,KAAK,cAAc,KAAK,WAC3B,OAAM,IAAI,MAAM,+CAA+C;CAEhE,MAAM,SAAS,KAAK,MAAM,KAAK,UAAU;AACzC,QAAO;EACN,MAAM,KAAK,OAAO,SAAS,KAAK,UAAU,YAAY;EACtD;EACA,MAAM,KAAK;EACX,MAAM,UAAU,KAAK,KAAK;EAC1B,YAAY,KAAK,UAAU,OAAO,KAAK,aAAa,OAAO;EAC3D;;AAGF,SAAgB,uBACf,QACA,MAC0B;AAC1B,KAAI,WAAW,KAAA,EACd,QAAO,6BAA6B,KAAK;AAE1C,KAAI,KAAK,QAAQ,KAAK,QACrB,OAAM,IAAI,MAAM,qDAAqD;AAEtE,KAAI,WAAW,QACd,QAAO,4BAA4B,KAAK;AAEzC,QAAO,6BAA6B,QAAQ,KAAK;;AAGlD,SAAgB,4BAA4B,MAAkD;AAE7F,QAAO;EACN,MAAM;EACN,QAHc,KAAK,MAAM,KAAK,UAAU;EAIxC,MAAM,KAAK;EACX,MAAM,UAAU,KAAK,KAAK;EAC1B,YAAY,CAAC,KAAK;EAClB;;AAGF,SAAgB,6BACf,MACA,MAC0B;AAE1B,QAAO;EACN;EACA,QAHc,KAAK,MAAM,KAAK,UAAU;EAIxC,MAAM,KAAK;EACX,MAAM,UAAU,KAAK,KAAK;EAC1B,YAAY,SAAS;EACrB;;;;ACvEF,SAAgB,iBAAiB,SAAiC;AACjE,KAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;CACpD,MAAM,SAAU,QAAqC;AACrD,KAAI,OAAO,WAAW,YAAY,CAAC,OAAO,SAAS,OAAO,IAAI,UAAU,EAAG,QAAO;AAClF,QAAO,KAAK,MAAM,OAAO;;AAG1B,SAAgB,YAAY,MAAuB;CAClD,MAAM,aAAa,KAAK,MAAM,CAAC,aAAa;AAC5C,QACC,eAAe,eACf,eAAe,eACf,eAAe,SACf,eAAe,aACf,eAAe;;AAIjB,SAAgB,sBAAsB,SAA0B;CAC/D,MAAM,UAAU,QAAQ,aAAa;AACrC,KAAI,CAAC,oBAAoB,KAAK,QAAQ,CAAE,QAAO;AAC/C,QACC,QAAQ,SAAS,UAAU,IAC3B,QAAQ,SAAS,6BAA6B,IAC9C,QAAQ,SAAS,qBAAqB;;AAIxC,SAAgB,uBACf,UACA,aACgB;AAChB,KAAI,YAAY,eAAe,aAAa,YAAa,QAAO;AAChE,QAAO,YAAY,eAAe;;AAGnC,SAAS,mBAAmB,MAAc,MAA6B;AACtE,KAAI,CAAC,YAAY,KAAK,CAAE,QAAO;CAC/B,MAAM,SAAS,UAAU,QAAQ;EAAC;EAAO,SAAS;EAAQ;EAAgB;EAAK,EAAE;EAChF,UAAU;EACV,SAAS;EACT,CAAC;AACF,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,SAAS,OAAO,UAAU,IAC9B,MAAM,QAAQ,CACd,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,MAAM,SAAS,KAAK,SAAS,EAAE;AACjC,KAAI,CAAC,MAAO,QAAO;CACnB,MAAM,SAAS,OAAO,SAAS,OAAO,GAAG;AACzC,QAAO,OAAO,SAAS,OAAO,IAAI,SAAS,IAAI,SAAS;;AAGzD,SAAS,mBAAmB,KAA4B;CACvD,MAAM,SAAS,UAAU,MAAM;EAAC;EAAM,OAAO,IAAI;EAAE;EAAM;EAAW,EAAE;EACrE,UAAU;EACV,SAAS;EACT,CAAC;AACF,KAAI,OAAO,WAAW,EAAG,QAAO;CAChC,MAAM,OAAO,OAAO,UAAU,IAAI,MAAM;AACxC,QAAO,IAAI,SAAS,IAAI,MAAM;;AAG/B,SAAS,mBACR,KACA,QACA,aACU;AACV,KAAI,CAAC,YAAY,OAAO,KAAK,CAAE,QAAO;AACtC,KAAI,eAAe,gBAAgB,IAAK,QAAO;CAC/C,MAAM,UAAU,mBAAmB,IAAI;AACvC,KAAI,CAAC,QAAS,QAAO;AACrB,QAAO,sBAAsB,QAAQ;;AAGtC,SAAS,YAAY,QAAwB;AAC5C,QAAO,KAAK,QAAQ,OAAO,EAAE,aAAa;;AAG3C,SAAS,oBAAoB,QAAwC;CACpE,MAAM,UAAU,YAAY,OAAO;AACnC,KAAI,CAAC,WAAW,QAAQ,CAAE,QAAO;CACjC,MAAM,MAAM,aAAa,SAAS,QAAQ,CAAC,MAAM;AACjD,KAAI;EACH,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MACC,OAAO,OAAO,QAAQ,YACtB,OAAO,OAAO,SAAS,YACvB,OAAO,OAAO,SAAS,SAEvB,QAAO;GAAE,KAAK,OAAO;GAAK,MAAM,OAAO;GAAM,MAAM,OAAO;GAAM;SAE1D;EACP,MAAM,MAAM,OAAO,SAAS,KAAK,GAAG;AACpC,MAAI,OAAO,SAAS,IAAI,IAAI,MAAM,EACjC,QAAO;GAAE;GAAK,MAAM;GAAa,MAAM;GAAO;;AAGhD,QAAO;;AAGR,SAAS,iBAAiB,KAAsB;AAC/C,KAAI;AACH,UAAQ,KAAK,KAAK,EAAE;AACpB,SAAO;SACA;AACP,SAAO;;;AAIT,eAAe,0BAA0B,QAA2C;AACnF,KAAI;EACH,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,QAAQ,iBAAiB,WAAW,OAAO,EAAE,IAAK;EACxD,MAAM,MAAM,MAAM,MAAM,UAAU,OAAO,KAAK,GAAG,OAAO,KAAK,aAAa,EACzE,QAAQ,WAAW,QACnB,CAAC;AACF,eAAa,MAAM;AACnB,SAAO,IAAI;SACJ;AACP,SAAO;;;AAIT,eAAe,yBAAyB,MAAc,MAAsC;AAC3F,KAAI;EACH,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,QAAQ,iBAAiB,WAAW,OAAO,EAAE,IAAK;EACxD,MAAM,MAAM,MAAM,MAAM,UAAU,KAAK,GAAG,KAAK,aAAa,EAC3D,QAAQ,WAAW,QACnB,CAAC;AACF,eAAa,MAAM;AACnB,MAAI,CAAC,IAAI,GAAI,QAAO;AAEpB,SAAO,iBADS,MAAM,IAAI,MAAM,CACA;SACzB;AACP,SAAO;;;AAIT,eAAe,WAAW,MAAc,MAAgC;AACvE,QAAO,IAAI,SAAS,YAAY;EAC/B,MAAM,SAAS,IAAI,iBAAiB;GAAE;GAAM;GAAM,CAAC;EACnD,MAAM,QAAQ,SAAkB;AAC/B,UAAO,oBAAoB;AAC3B,UAAO,SAAS;AAChB,WAAQ,KAAK;;AAEd,SAAO,WAAW,IAAI;AACtB,SAAO,KAAK,iBAAiB,KAAK,KAAK,CAAC;AACxC,SAAO,KAAK,iBAAiB,KAAK,MAAM,CAAC;AACzC,SAAO,KAAK,eAAe,KAAK,MAAM,CAAC;GACtC;;AAGH,eAAe,mBAAmB,KAAa,YAAY,KAAqB;CAC/E,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,QAAO,KAAK,KAAK,GAAG,UAAU;AAC7B,MAAI,CAAC,iBAAiB,IAAI,CAAE;AAC5B,QAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;;;AAI1D,eAAe,mBAAmB,MAAc,MAAc,YAAY,KAAyB;CAClG,MAAM,WAAW,KAAK,KAAK,GAAG;AAC9B,QAAO,KAAK,KAAK,GAAG,UAAU;AAC7B,MAAI,CAAE,MAAM,WAAW,MAAM,KAAK,CAAG,QAAO;AAC5C,QAAM,IAAI,SAAS,YAAY,WAAW,SAAS,IAAI,CAAC;;AAEzD,QAAO;;AAGR,eAAe,mBACd,QACA,QACoD;CACpD,MAAM,UAAU,YAAY,OAAO;CACnC,MAAM,SAAS,oBAAoB,OAAO;CAC1C,MAAM,qBAAqB,MAAM,yBAAyB,OAAO,MAAM,OAAO,KAAK;CACnF,MAAM,cAAc,mBAAmB,OAAO,MAAM,OAAO,KAAK;CAChE,MAAM,YAAY,uBAAuB,oBAAoB,YAAY;AACzE,KAAI,aAAa,mBAAmB,WAAW,QAAQ,YAAY,EAAE;AACpE,MAAI;AACH,WAAQ,KAAK,WAAW,UAAU;AAClC,SAAM,mBAAmB,UAAU;UAC5B;AAGR,MAAI;AACH,UAAO,QAAQ;UACR;AAGR,SAAO;GAAE,SAAS;GAAM,KAAK;GAAW;;AAGzC,KAAI,CAAC,OAAQ,QAAO;EAAE,SAAS;EAAO,KAAK;EAAM;AAEjD,KAAI,MAAM,0BAA0B,OAAO,CAC1C,KAAI;AACH,UAAQ,KAAK,OAAO,KAAK,UAAU;AACnC,QAAM,mBAAmB,OAAO,IAAI;SAC7B;AAIT,KAAI;AACH,SAAO,QAAQ;SACR;AAGR,QAAO;EAAE,SAAS;EAAM,KAAK,OAAO;EAAK;;AAG1C,SAAgB,0BACf,YACA,YACA,WAAqB,QAAQ,UAClB;CACX,MAAM,OAAO;EACZ,GAAG;EACH;EACA;EACA;EACA;EACA;EACA,WAAW;EACX;EACA,OAAO,WAAW,KAAK;EACvB;AACD,KAAI,WAAW,OACd,MAAK,KAAK,aAAa,WAAW,OAAO;AAE1C,QAAO;;AAGR,SAAgB,uBAAuB,OAAyB;AAC/D,KAAI,EAAE,iBAAiB,OAAQ,QAAO;CACtC,MAAM,OAAO,MAAM,QAAQ,aAAa;AACxC,QACC,KAAK,SAAS,aAAa,IAC3B,KAAK,SAAS,cAAc,IAC5B,KAAK,SAAS,OAAO,IACpB,KAAK,SAAS,SAAS,IAAI,KAAK,SAAS,MAAM;;AAIlD,SAAgB,4BAA4B,OAAgB,QAA0B;CACrF,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AACtE,QAAO;EACN,MAAM;EACN,QAAQ,QAAQ;EAChB,QAAQ,QAAQ;EAChB,OAAO,QAAQ,KAAK;EACpB,sBAAsB,QAAQ,IAAI,8BAA8B;EAChE,SAAS;EACT;;AAGF,eAAe,sBAAsB,YAAoD;AACxF,KAAI,MAAM,WAAW,WAAW,MAAM,WAAW,KAAK,EAAE;AACvD,IAAE,IAAI,KAAK,oCAAoC,WAAW,KAAK,GAAG,WAAW,OAAO;AACpF;;CAED,MAAM,aAAa,QAAQ,KAAK;AAChC,KAAI,CAAC,WAAY,OAAM,IAAI,MAAM,yDAAyD;CAC1F,MAAM,QAAQ,MAAM,QAAQ,UAAU,0BAA0B,YAAY,WAAW,EAAE;EACxF,KAAK,QAAQ,KAAK;EAClB,UAAU;EACV,OAAO;EACP,KAAK;GACJ,GAAG,QAAQ;GACX,GAAI,WAAW,SAAS,EAAE,YAAY,WAAW,QAAQ,GAAG,EAAE;GAC9D;EACD,CAAC;AACF,OAAM,OAAO;AACb,KAAI,WAAW,OACd,eACC,YAAY,WAAW,OAAO,EAC9B,KAAK,UAAU;EAAE,KAAK,MAAM;EAAK,MAAM,WAAW;EAAM,MAAM,WAAW;EAAM,CAAC,EAChF,QACA;AAEF,GAAE,MAAM,iBAAiB;AACzB,GAAE,MACD,qCAAqC,MAAM,IAAI,cAAc,WAAW,KAAK,GAAG,WAAW,OAC3F;;AAGF,eAAe,sBAAsB,YAAoD;CACxF,MAAM,EAAE,WAAW,eAAe,YAAY,aAAa,MAAM,OAAO;CACxE,MAAM,EAAE,UAAU,MAAM,OAAO;AAE/B,KAAI,WAAW,OAAQ,SAAQ,IAAI,aAAa,WAAW;AAC3D,KAAI,MAAM,WAAW,WAAW,MAAM,WAAW,KAAK,EAAE;AACvD,IAAE,IAAI,KAAK,oCAAoC,WAAW,KAAK,GAAG,WAAW,OAAO;AACpF,UAAQ,WAAW;AACnB;;CAGD,MAAM,WAAW,IAAI,gBAAgB;CACrC,IAAI;AACJ,KAAI;AACH,UAAQ,UAAU;UACV,KAAK;AACb,MAAI,qBAAqB,IAAI,CAAC,uBAAuB,IAAI,CACxD,OAAM;AAGP,IAAE,IAAI,KAAK,8EAA8E;AACzF,OAAK,MAAM,QAAQ,4BAClB,KACA,cAAc,WAAW,UAAU,KAAA,EAAU,CAC7C,CACA,GAAE,IAAI,KAAK,0BAA0B,OAAO;AAE7C,UAAQ,IAAI,6BAA6B;AACzC,cAAY;AACZ,UAAQ,UAAU;AAClB,IAAE,IAAI,KAAK,mFAAmF;;CAG/F,MAAM,UAAU,IAAI,gBAAgB,OAAO,EAAE,UAAU,CAAC;AACxD,SAAQ,OAAO;CAEf,MAAM,YAAY,IAAI,iBAAiB;CACvC,IAAI,cAAc;CAElB,MAAM,aAAa,0BADJ,uBAAuB,CACc;CACpD,MAAM,cAAc,WAAW;AAE/B,KAAI,aAAa;AAChB,gBAAc;EACd,MAAM,gBAAgB,WAAW;AACjC,gBAAc;GACb,QAAQ,cAAc,WAAW,UAAU,KAAA,EAAU;GACrD,WAAW;GACX,MAAM,WAAW;GACjB,MAAM,WAAW;GACjB,QAAQ,UAAU;GAClB,CAAC,CACA,OAAO,QAAiB;GACxB,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;AAC5D,KAAE,IAAI,MAAM,uBAAuB,MAAM;IACxC,CACD,cAAc;AACd,iBAAc;IACb;;CAGJ,MAAM,UAAU;EAAE,oBAAoB;EAAO;EAAS;EAAU;CAChE,MAAM,MAAM,UAAU,QAAQ;CAC9B,MAAM,SAAS,cAAc,WAAW,UAAU,KAAA,EAAU;CAC5D,MAAM,UAAU,YAAY,OAAO;CAInC,IAAI,aAA8C;CAClD,IAAI,oBAAoB;AACxB,KAAI,aAAa;AAEhB,eAAa,MACZ;GAAE,OAFa,cAAc,QAAQ,CAEpB;GAAO,UAAU,WAAW;GAAU,MAAM,WAAW;GAAU,GACjF,SAAS;AACT,uBAAoB;AACpB,KAAE,IAAI,KAAK,qCAAqC,KAAK,QAAQ,GAAG,KAAK,OAAO;IAE7E;AACD,aAAW,GAAG,UAAU,QAA+B;AACtD,OAAI,CAAC,qBAAqB,IAAI,SAAS,aACtC,GAAE,IAAI,KACL,aAAa,WAAW,SAAS,iDACjC;OAED,GAAE,IAAI,KAAK,wBAAwB,IAAI,UAAU;IAGjD;;CAGH,MAAM,SAAS,MACd;EAAE,OAAO,IAAI;EAAO,UAAU,WAAW;EAAM,MAAM,WAAW;EAAM,GACrE,SAAS;AACT,gBACC,SACA,KAAK,UAAU;GAAE,KAAK,QAAQ;GAAK,MAAM,WAAW;GAAM,MAAM,WAAW;GAAM,CAAC,EAClF,QACA;AACD,IAAE,MAAM,iBAAiB;AACzB,IAAE,IAAI,QAAQ,uBAAuB,KAAK,QAAQ,GAAG,KAAK,OAAO;AACjE,IAAE,IAAI,KAAK,aAAa,SAAS;AACjC,IAAE,IAAI,KAAK,4BAA4B;AACvC,MAAI,YAAa,GAAE,IAAI,KAAK,sBAAsB;GAEnD;AAED,QAAO,GAAG,UAAU,QAA+B;AAClD,MAAI,IAAI,SAAS,aAChB,GAAE,IAAI,KAAK,oCAAoC,WAAW,KAAK,GAAG,WAAW,OAAO;MAEpF,GAAE,IAAI,MAAM,IAAI,QAAQ;AAEzB,UAAQ,KAAK,EAAE;GACd;CAEF,MAAM,WAAW,YAAY;AAC5B,IAAE,MAAM,gBAAgB;AACxB,YAAU,OAAO;AACjB,QAAM,QAAQ,MAAM;AAGpB,QAAM,IAAI,SAAe,YAAY;GACpC,IAAI,YAAY,aAAa,IAAI;GACjC,MAAM,aAAa;AAClB,QAAI,EAAE,cAAc,EAAG,UAAS;;AAEjC,eAAY,MAAM,KAAK;AACvB,UAAO,MAAM,KAAK;IACjB,CAAC,YAAY,GAEb;AAEF,MAAI;AACH,UAAO,QAAQ;UACR;AAGR,cAAY;AACZ,UAAQ,KAAK,EAAE;;CAIhB,MAAM,sBAAsB;AAC3B,mBAAiB;AAChB,OAAI;AACH,WAAO,QAAQ;WACR;AAGR,eAAY;AACZ,WAAQ,KAAK,EAAE;KACb,IAAK,CAAC,OAAO;;AAEjB,SAAQ,GAAG,gBAAgB;AAC1B,iBAAe;AACV,YAAU;GACd;AACF,SAAQ,GAAG,iBAAiB;AAC3B,iBAAe;AACV,YAAU;GACd;;AAGH,eAAe,mBAAmB,YAAoD;CACrF,MAAM,SAAS,cAAc,WAAW,UAAU,KAAA,EAAU;AAC5D,KAAI,WAAW,SAAS,UAAU,WAAW,SAAS,WAAW;EAChE,MAAM,SAAS,MAAM,mBAAmB,QAAQ;GAC/C,MAAM,WAAW;GACjB,MAAM,WAAW;GACjB,CAAC;AACF,MAAI,OAAO,SAAS;AACnB,KAAE,MAAM,iBAAiB;AACzB,KAAE,IAAI,QAAQ,iBAAiB,OAAO,MAAM,SAAS,OAAO,IAAI,KAAK,KAAK;AAC1E,OAAI,WAAW,SAAS,QAAQ;AAC/B,MAAE,MAAM,OAAO;AACf;;AAID,OAAI,CADa,MAAM,mBAAmB,WAAW,MAAM,WAAW,KAAK,CAE1E,GAAE,IAAI,KAAK,QAAQ,WAAW,KAAK,6CAA6C;aAEvE,WAAW,SAAS,QAAQ;AACtC,KAAE,MAAM,iBAAiB;AACzB,KAAE,MAAM,6BAA6B;AACrC;;;AAIF,KAAI,WAAW,SAAS,WAAW,WAAW,SAAS,WAAW;AACjE,MAAI,WAAW,YAAY;AAC1B,SAAM,sBAAsB;IAAE,GAAG;IAAY;IAAQ,CAAC;AACtD;;AAED,QAAM,sBAAsB;GAAE,GAAG;GAAY;GAAQ,CAAC;;;AAIxD,SAAS,sBAAsB,SAA2B;AACzD,QAAO,QACL,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,iBAAiB,aAAa,YAAY,CACjD,OAAO,iBAAiB,aAAa,QAAQ;;AAGhD,IAAa,eAAe,sBAC3B,IAAI,QAAQ,QAAQ,CAClB,cAAc,UAAU,CACxB,YAAY,2BAA2B,CACvC,SAAS,YAAY,wCAAwC,CAC/D,CACC,OAAO,gBAAgB,2BAA2B,CAClD,OAAO,gBAAgB,2BAA2B,CAClD,OAAO,UAAU,yBAAyB,CAC1C,OAAO,aAAa,4BAA4B,CAChD,OAAO,OAAO,QAA4B,SAA6B;CACvE,MAAM,mBACL,WAAW,KAAA,IACR,KAAA,IACA,WAAW,WAAW,WAAW,UAAU,WAAW,YACpD,SACD;AACL,KAAI,qBAAqB,MAAM;AAC9B,IAAE,IAAI,MAAM,yBAAyB,SAAS;AAC9C,UAAQ,WAAW;AACnB;;AAED,OAAM,mBAAmB,uBAAuB,kBAAkB,KAAK,CAAC;EACvE;;;AChiBH,SAAgB,0BAA0B,WAA2B;CACpE,MAAM,WAAW,KAAK,WAAW,gBAAgB;AACjD,KAAI,WAAW,SAAS,CAAE,QAAO;CACjC,MAAM,YAAY,KAAK,WAAW,iBAAiB;AACnD,KAAI,WAAW,UAAU,CAAE,QAAO;AAClC,QAAO;;AAGR,SAAgB,gBAAgB,MAAuC;AACtE,KAAI,CAAC,WAAW,KAAK,CAAE,QAAO,EAAE;CAChC,MAAM,MAAM,aAAa,MAAM,QAAQ;AACvC,KAAI;AACH,SAAO,KAAK,MAAM,IAAI;SACf;EACP,MAAM,UAAU,oBAAoB,kBAAkB,IAAI,CAAC;AAC3D,SAAO,KAAK,MAAM,QAAQ;;;AAI5B,SAAgB,gBAAgB,MAAc,MAAqC;AAClF,WAAU,QAAQ,KAAK,EAAE,EAAE,WAAW,MAAM,CAAC;AAC7C,eAAc,MAAM,GAAG,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC,KAAK,QAAQ;;;;;;;;;;;;;;;;ACHnE,SAAS,oBAA4B;AACpC,QAAO,KAAK,SAAS,EAAE,WAAW,WAAW;;AAG9C,SAAS,kBAA0B;AAClC,QAAO,KAAK,SAAS,EAAE,UAAU;;;AAIlC,IAAM,uBAAuB;;AAO7B,SAAS,8BAAoC;CAC5C,MAAM,eAAe,KAAK,mBAAmB,EAAE,WAAW,aAAa;CACvE,MAAM,eAAe,KAAK,mBAAmB,EAAE,OAAO,YAAY;AAClE,KAAI,WAAW,aAAa,CAC3B,KAAI;AACH,SAAO,aAAa;AACpB,IAAE,IAAI,KAAK,sEAAsE;SAC1E;AACP,IAAE,IAAI,KAAK,kEAAkE;;AAG/E,KAAI,WAAW,aAAa,CAC3B,KAAI;AACH,SAAO,aAAa;AACpB,IAAE,IAAI,KAAK,8DAA8D;SAClE;;;AAOV,SAAS,yBAAyB,QAA0C;CAC3E,MAAM,YAAY,OAAO;AACzB,KAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO;CACxD,MAAM,QAAQ,UAAU;AACxB,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAEhD,MAAM,UAAU,MAAM;AAMtB,KAJE,MAAM,QAAQ,QAAQ,IACtB,QAAQ,MAAM,QAAQ,OAAO,QAAQ,aAAa,QAAQ,SAAS,QAAQ,MAAM,IACjF,OAAO,YAAY,aAAa,YAAY,SAAS,YAAY,OAErD;AACb,IAAE,IAAI,KAAK,wCAAwC;AACnD,YAAU,UAAU;GACnB,MAAM;GACN,SAAS;IAAC;IAAO;IAAW;IAAM;GAClC,SAAS;GACT;AACD,SAAO;;AAER,QAAO;;;AAIR,SAAS,uBAAuB,UAA4C;CAC3E,MAAM,aAAa,SAAS;AAC5B,KAAI,CAAC,cAAc,OAAO,eAAe,SAAU,QAAO;CAC1D,MAAM,QAAQ,WAAW;AACzB,KAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;CAEhD,MAAM,UAAU,MAAM;CACtB,MAAM,OAAO,MAAM;AAQnB,KANE,OAAO,YAAY,aAAa,YAAY,SAAS,YAAY,SACjE,MAAM,QAAQ,KAAK,IACnB,KAAK,MACH,QAAQ,OAAO,QAAQ,aAAa,IAAI,WAAW,YAAY,IAAI,QAAQ,OAC5E,EAEW;AACb,IAAE,IAAI,KAAK,+CAA+C;AAC1D,aAAW,UAAU;GACpB,SAAS;GACT,MAAM;IAAC;IAAM;IAAW;IAAM;GAC9B;AACD,SAAO;;AAER,QAAO;;AAOR,SAAS,cAAc,OAAyB;AAE/C,8BAA6B;CAE7B,MAAM,aAAa,0BAA0B,mBAAmB,CAAC;CACjE,IAAI;AACJ,KAAI;AACH,WAAS,gBAAgB,WAAW;UAC5B,KAAK;AACb,IAAE,IAAI,MACL,mBAAmB,WAAW,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAClF;AACD,SAAO;;CAGR,IAAI,UAAU,OAAO;AACrB,KAAI,CAAC,MAAM,QAAQ,QAAQ,CAC1B,WAAU,EAAE;CAGb,MAAM,aAAc,QAAqB,MACvC,UACA,OAAO,UAAU,aAChB,UAAU,wBAAwB,MAAM,WAAW,GAAG,qBAAqB,GAAG,EAChF;AAED,KAAI,cAAc,CAAC,OAAO;AACzB,IAAE,IAAI,KAAK,WAAW,qBAAqB,2BAA2B;AACtE,SAAO;;AAGR,KAAI,cAAc,MAEjB,WAAW,QAAqB,QAC9B,UACA,OAAO,UAAU,YAChB,UAAU,wBAAwB,CAAC,MAAM,WAAW,GAAG,qBAAqB,GAAG,CACjF;AAGD,SAAqB,KAAK,qBAAqB;AAChD,QAAO,SAAS;AAEhB,KAAI;AACH,kBAAgB,YAAY,OAAO;AACnC,IAAE,IAAI,QAAQ,WAAW,qBAAqB,aAAa,aAAa;UAChE,KAAK;AACb,IAAE,IAAI,MACL,mBAAmB,WAAW,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAClF;AACD,SAAO;;AAGR,QAAO;;AAGR,SAAS,WAAW,OAAyB;CAC5C,MAAM,aAAa,0BAA0B,mBAAmB,CAAC;CACjE,IAAI;AACJ,KAAI;AACH,WAAS,gBAAgB,WAAW;UAC5B,KAAK;AACb,IAAE,IAAI,MACL,mBAAmB,WAAW,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAClF;AACD,SAAO;;CAGR,IAAI,YAAY,OAAO;AACvB,KAAI,aAAa,QAAQ,OAAO,cAAc,YAAY,MAAM,QAAQ,UAAU,CACjF,aAAY,EAAE;CAIf,MAAM,WAAW,yBAAyB,OAAO;AAEjD,KAAI,aAAa,aAAa,CAAC,SAAS,CAAC,UAAU;AAClD,IAAE,IAAI,KAAK,+BAA+B,aAAa;AACvD,SAAO;;AAGR,KAAI,CAAC,UAAU;AACd,YAAU,UAAU;GACnB,MAAM;GACN,SAAS;IAAC;IAAO;IAAW;IAAM;GAClC,SAAS;GACT;AACD,SAAO,MAAM;;AAGd,KAAI;AACH,kBAAgB,YAAY,OAAO;AACnC,IAAE,IAAI,QAAQ,wBAAwB,aAAa;UAC3C,KAAK;AACb,IAAE,IAAI,MACL,mBAAmB,WAAW,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GAClF;AACD,SAAO;;AAGR,QAAO;;AAGR,SAAS,+BAAwC;CAGhD,MAAM,YAAY,KAAK,iBAAiB,EAAE,WAAW,UAAU;AAC/D,KAAI,WAAW,UAAU,CAAE,QAAO;AAGlC,KAAI,WADc,KAAK,WAAW,SAAS,aAAa,CAC/B,CAAE,QAAO;AAClC,QAAO;;AAGR,SAAS,iBAAiB,OAAyB;CAClD,MAAM,eAAe,KAAK,iBAAiB,EAAE,gBAAgB;CAC7D,IAAI;AACJ,KAAI;AACH,aAAW,gBAAgB,aAAa;SACjC;AACP,aAAW,EAAE;;CAGd,IAAI,aAAa,SAAS;AAC1B,KAAI,cAAc,QAAQ,OAAO,eAAe,YAAY,MAAM,QAAQ,WAAW,CACpF,cAAa,EAAE;CAIhB,MAAM,WAAW,uBAAuB,SAAS;AAEjD,KAAI,aAAa,cAAc,CAAC,SAAS,CAAC,SACzC,GAAE,IAAI,KAAK,sCAAsC,eAAe;MAC1D;AACN,MAAI,CAAC,UAAU;AACd,cAAW,UAAU;IACpB,SAAS;IACT,MAAM;KAAC;KAAM;KAAW;KAAM;IAC9B;AACD,YAAS,aAAa;;AAGvB,MAAI;AACH,mBAAgB,cAAc,SAAS;AACvC,KAAE,IAAI,QAAQ,+BAA+B,eAAe;WACpD,KAAK;AACb,KAAE,IAAI,MACL,mBAAmB,aAAa,IAAI,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,GACpF;AACD,UAAO;;;AAKT,KAAI,CAAC,8BAA8B,IAAI,OAAO;AAC7C,IAAE,IAAI,KAAK,+DAA+D;AAC1E,IAAE,IAAI,KAAK,8CAA8C;AACzD,IAAE,IAAI,KAAK,4BAA4B;AACvC,IAAE,IAAI,KAAK,GAAG;AACd,IAAE,IAAI,KAAK,iCAAiC;AAC5C,IAAE,IAAI,KAAK,mDAAmD;OAE9D,GAAE,IAAI,KAAK,mDAAmD;AAG/D,QAAO;;AAGR,IAAa,eAAe,IAAI,QAAQ,QAAQ,CAC9C,cAAc,UAAU,CACxB,YAAY,mEAAmE,CAC/E,OAAO,WAAW,mCAAmC,CACrD,OAAO,mBAAmB,4BAA4B,CACtD,OAAO,iBAAiB,+BAA+B,CACvD,QAAQ,SAA4E;AACpF,GAAE,MAAM,kBAAkB,UAAU;CACpC,MAAM,QAAQ,KAAK,SAAS;CAC5B,IAAI,KAAK;AAET,KAAI,CAAC,KAAK,YAAY;AACrB,IAAE,IAAI,KAAK,gCAAgC;AAC3C,OAAK,cAAc,MAAM,IAAI;AAC7B,IAAE,IAAI,KAAK,oCAAoC;AAC/C,OAAK,WAAW,MAAM,IAAI;;AAG3B,KAAI,CAAC,KAAK,cAAc;AACvB,IAAE,IAAI,KAAK,uCAAuC;AAClD,OAAK,iBAAiB,MAAM,IAAI;;AAGjC,KAAI,GACH,GAAE,MAAM,0DAA0D;MAC5D;AACN,IAAE,MAAM,gCAAgC;AACxC,UAAQ,WAAW;;EAEnB;;;ACnTH,SAAS,OAAO,GAAmB;AAClC,QAAO,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC;;AAG/B,SAAS,UAAU,GAAmB;AACrC,KAAI,KAAK,IAAe,QAAO,KAAK,IAAI,KAAe,QAAQ,EAAE,CAAC;AAClE,KAAI,KAAK,IAAW,QAAO,KAAK,IAAI,KAAW,QAAQ,EAAE,CAAC;AAC1D,KAAI,KAAK,IAAO,QAAO,KAAK,IAAI,KAAO,QAAQ,EAAE,CAAC;AAClD,QAAO,GAAG;;AAGX,IAAa,eAAe,IAAI,QAAQ,QAAQ,CAC9C,cAAc,UAAU,CACxB,YAAY,2BAA2B,CACvC,OAAO,eAAe,gEAAgE,CACtF,OAAO,oBAAoB,gEAAgE,CAC3F,OAAO,UAAU,iBAAiB,CAClC,QAAQ,SAA2D;CACnE,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,SAAS,MAAM,OAAO;AAC5B,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;EAGD,MAAM,KAAK,OAAO;EAClB,MAAM,UAAU,GAAG,aAAa,SAAW,QAAQ,EAAE;AAErD,IAAE,MAAM,gBAAgB;AAExB,IAAE,IAAI,KAAK,CAAC,gBAAgB,GAAG,QAAQ,gBAAgB,OAAO,KAAK,CAAC,KAAK,KAAK,CAAC;AAE/E,IAAE,IAAI,QACL;GACC,gBAAgB,GAAG,SAAS,gBAAgB;GAC5C,gBAAgB,GAAG,oBAAoB,gBAAgB,CAAC,YAAY,GAAG,aAAa,gBAAgB,CAAC;GACrG,gBAAgB,GAAG,YAAY,gBAAgB,CAAC,WAAW,OAAO,GAAG,cAAc,CAAC;GACpF,gBAAgB,GAAG,UAAU,gBAAgB;GAC7C,gBAAgB,GAAG,YAAY,gBAAgB,CAAC,IAAI,OAAO,GAAG,gBAAgB,CAAC;GAC/E,gBAAgB,GAAG,WAAW,gBAAgB;GAC9C,CAAC,KAAK,KAAK,CACZ;AAED,MAAI,OAAO,MAAM,OAAO,SAAS,GAAG;GACnC,MAAM,QAAQ,OAAO,MAAM,OAAO,KAAK,MAA4C;IAClF,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,MAAM,gBAAgB,GAAG;AACzD,QAAI,EAAE,cAAc,EAAG,OAAM,KAAK,QAAQ,UAAU,EAAE,YAAY,CAAC,SAAS;AAC5E,QAAI,EAAE,eAAe,EAAG,OAAM,KAAK,cAAc,UAAU,EAAE,aAAa,CAAC,SAAS;AACpF,WAAO,KAAK,MAAM,KAAK,KAAK;KAC3B;GAEF,MAAM,IAAI,OAAO,MAAM;AACvB,SAAM,KAAK,GAAG;AACd,SAAM,KACL,YAAY,EAAE,OAAO,gBAAgB,CAAC,gBAAgB,UAAU,EAAE,YAAY,CAAC,sBAAsB,UAAU,EAAE,aAAa,CAAC,SAC/H;AAED,KAAE,IAAI,KAAK,UAAU,MAAM,KAAK,KAAK,GAAG;;AAGzC,IAAE,MAAM,OAAO;WACN;AACT,QAAM,OAAO;;EAEb;;;AC7DH,SAAgB,kBAAkB,KAA6B;CAC9D,MAAM,SAAS,IAAI,KAAK,OAAO;CAC/B,MAAM,QAAQ,OAAO,IAAI,SAAS,GAAG;CACrC,MAAM,SAAS,QAAQ,MAAM,UAAU;AACvC,QAAO,GAAG,IAAI,eAAe,GAAG,OAAO,MAAM,IAAI,OAAO,OAAO,IAAI,QAAQ,GAAG,IAAI,eAAe,KAAK;;AAYvG,SAAgB,wBACf,QACA,MACA,YACA,WAAqB,EAAE,EACZ;AACX,KAAI,CAAC,WAAY,OAAM,IAAI,MAAM,8DAA8D;CAC/F,MAAM,OAAO;EAAC,GAAG;EAAU;EAAY;EAAQ;AAC/C,KAAI,WAAW,QACd,MAAK,KAAK,YAAY;UACZ,WAAW,OACrB,MAAK,KAAK,SAAS;KAEnB,MAAK,KAAK,YAAY;AAEvB,KAAI,KAAK,MAAM,KAAK,OAAQ,MAAK,KAAK,aAAa,KAAK,MAAM,KAAK,UAAU,GAAG;AAChF,KAAI,KAAK,KAAM,MAAK,KAAK,UAAU,KAAK,KAAK;AAC7C,KAAI,KAAK,KAAM,MAAK,KAAK,UAAU,KAAK,KAAK;AAC7C,QAAO;;AAGR,SAAgB,qBACf,cACA,QACS;AACT,KAAI,OAAO,GAAI,QAAO,KAAK,aAAa;AAExC,QAAO,KAAK,aAAa,SADV,OAAO,QAAQ,KAAK,OAAO,UAAU;;AAIrD,SAAgB,iBAAiB,OAAqC;AACrE,KAAI,CAAC,MAAO,QAAO,EAAE;AACrB,QAAO,MACL,MAAM,IAAI,CACV,KAAK,SAAS,KAAK,MAAM,CAAC,CAC1B,OAAO,QAAQ;;AAQlB,SAAgB,0BACf,iBACA,gBACA,MACA,YACW;AACX,KAAI,mBAAmB,CAAC,CAAC,QAAQ,UAAU,CAAC,SAAS,gBAAgB,aAAa,CAAC,CAClF,QAAO,CAAC,gBAAgB;AAEzB,KAAI,kBAAkB,mBAAmB,UACxC,QAAO,CAAC,GAAG,eAAe,GAAG,OAAO;CAErC,MAAM,YAAY,OAAO,OAAO,WAAW,CACzC,SAAS,YAAY,WAAW,EAAE,CAAC,CACnC,QAAQ,UAAU,CAAC,MAAM,SAAS,CAClC,KAAK,UAAU,MAAM,QAAQ,CAC7B,QAAQ,YAAY,WAAW,YAAY,eAAe,YAAY,MAAM,CAC5E,KAAK,YAAY,GAAG,QAAQ,GAAG,OAAO;AACxC,QAAO,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC;;;;;;;ACzC/B,SAAS,mBAAmB,OAAuB;AAClD,KAAI,CAAC,QAAQ,KAAK,MAAM,MAAM,CAAC,CAC9B,OAAM,IAAI,MAAM,oBAAoB,QAAQ;AAE7C,QAAO,OAAO,SAAS,OAAO,GAAG;;AAsBlC,eAAe,SAAS,MAAc,MAAgC;AACrE,QAAO,IAAI,SAAS,YAAY;EAC/B,MAAM,SAAS,IAAI,iBAAiB;GAAE;GAAM;GAAM,CAAC;EACnD,MAAM,QAAQ,OAAgB;AAC7B,UAAO,oBAAoB;AAC3B,UAAO,SAAS;AAChB,WAAQ,GAAG;;AAEZ,SAAO,WAAW,IAAI;AACtB,SAAO,KAAK,iBAAiB,KAAK,KAAK,CAAC;AACxC,SAAO,KAAK,iBAAiB,KAAK,MAAM,CAAC;AACzC,SAAO,KAAK,eAAe,KAAK,MAAM,CAAC;GACtC;;AAGH,SAAS,kBAAkB,QAAuD;AACjF,KAAI;EACH,MAAM,MAAM,aAAa,KAAK,QAAQ,OAAO,EAAE,aAAa,EAAE,OAAO;EACrE,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,MAAI,OAAO,OAAO,SAAS,YAAY,OAAO,OAAO,SAAS,SAC7D,QAAO;GAAE,MAAM,OAAO;GAAM,MAAM,OAAO;GAAM;SAEzC;AAGR,QAAO;;AAGR,SAAS,2BAA2B,OAAsD;AACzF,KAAI;EACH,MAAM,aAAa,MAAM,SAAS,MAAM,GAAG,QAAQ,UAAU;EAC7D,MAAM,MAAM,IAAI,IAAI,WAAW;EAC/B,MAAM,OAAO,IAAI,OAAO,OAAO,SAAS,IAAI,MAAM,GAAG,GAAG,IAAI,aAAa,WAAW,MAAM;AAC1F,MAAI,CAAC,IAAI,YAAY,CAAC,OAAO,SAAS,KAAK,CAAE,QAAO;AACpD,SAAO;GAAE,MAAM,IAAI;GAAU;GAAM;SAC5B;AACP,SAAO;;;AAIT,eAAe,kBACd,QACA,MACgB;AAChB,KAAI,KAAK,SAAS,SAAS,KAAK,WAAW,KAC1C,GAAE,IAAI,KACL,mGACA;AAEF,KAAI,WAAW;MACC,uBAAuB,CAC3B,iBAAiB,MAAM;AACjC,KAAE,IAAI,MAAM,qDAAqD;AACjE,WAAQ,WAAW;AACnB;;;CAOF,MAAM,OAAO,wBAAwB,QAAQ,MAAM,QAAQ,KAAK,MAAM,IAAI,QAAQ,SAAS;AAC3F,OAAM,IAAI,SAAe,SAAS,WAAW;EAC5C,MAAM,QAAQ,MAAM,QAAQ,UAAU,MAAM;GAC3C,KAAK,QAAQ,KAAK;GAClB,OAAO;GACP,KAAK;IACJ,GAAG,QAAQ;IACX,GAAK,KAAK,MAAM,KAAK,SAAU,EAAE,YAAY,KAAK,MAAM,KAAK,QAAQ,GAAG,EAAE;IAC1E;GACD,CAAC;AACF,QAAM,KAAK,SAAS,OAAO;AAC3B,QAAM,KAAK,SAAS,SAAS;AAC5B,OAAI,QAAQ,SAAS,EACpB,SAAQ,WAAW;AAEpB,YAAS;IACR;GACD;;AAGH,IAAa,cAAc,IAAI,QAAQ,OAAO,CAC5C,cAAc,UAAU,CACxB,YAAY,yCAAyC;AAGvD,YAAY,WACX,IAAI,QAAQ,WAAW,CACrB,cAAc,UAAU,CACxB,YAAY,4BAA4B,CACxC,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,eAAe,gBAAgB,KAAK,CAC3C,OAAO,UAAU,iBAAiB,CAClC,QAAQ,SAA0E;CAClF,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,IAAI,QAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC;EACvC,MAAM,QAAQ,mBAAmB,KAAK,MAAM;EAC5C,MAAM,OAAO,EACX,OAAO;GACP,gBAAgB,OAAO,aAAa;GACpC,IAAI,OAAO,aAAa;GACxB,QAAQ,OAAO,aAAa;GAC5B,SAAS,OAAO,aAAa;GAC7B,OAAO,OAAO,aAAa;GAC3B,aAAa,OAAO,aAAa;GACjC,CAAC,CACD,KAAK,OAAO,aAAa,CACzB,QAAQ,KAAK,OAAO,aAAa,YAAY,CAAC,CAC9C,MAAM,MAAM,CACZ,KAAK;AAEP,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;AAC1C;;AAGD,OAAK,MAAM,OAAO,KACjB,SAAQ,IAAI,kBAAkB,IAAI,CAAC;WAE3B;AACT,QAAM,OAAO;;EAEb,CACH;AAED,YAAY,WACX,IAAI,QAAQ,QAAQ,CAClB,cAAc,UAAU,CACxB,YAAY,oBAAoB,CAChC,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,iBAAiB,cAAc,CACtC,OAAO,iBAAiB,cAAc,CACtC,OAAO,UAAU,8BAA8B,KAAK,CACpD,OAAO,YAAY,6BAA6B,CAChD,OAAO,OAAO,SAA+B;AAC7C,OAAM,kBAAkB,SAAS,KAAK;EACrC,CACH;AAED,YAAY,WACX,IAAI,QAAQ,OAAO,CACjB,cAAc,UAAU,CACxB,YAAY,mBAAmB,CAC/B,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,iBAAiB,cAAc,CACtC,OAAO,iBAAiB,cAAc,CACtC,OAAO,UAAU,8BAA8B,KAAK,CACpD,OAAO,YAAY,6BAA6B,CAChD,OAAO,OAAO,SAA+B;AAC7C,OAAM,kBAAkB,QAAQ,KAAK;EACpC,CACH;AAED,YAAY,WACX,IAAI,QAAQ,UAAU,CACpB,cAAc,UAAU,CACxB,YAAY,sBAAsB,CAClC,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,iBAAiB,cAAc,CACtC,OAAO,iBAAiB,cAAc,CACtC,OAAO,UAAU,8BAA8B,KAAK,CACpD,OAAO,YAAY,6BAA6B,CAChD,OAAO,OAAO,SAA+B;AAC7C,OAAM,kBAAkB,WAAW,KAAK;EACvC,CACH;AAED,YAAY,WACX,IAAI,QAAQ,OAAO,CACjB,cAAc,UAAU,CACxB,YAAY,yBAAyB,CACrC,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,iBAAiB,yBAAyB,CACjD,OAAO,OAAO,SAA0B;CACxC,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;AACH,oBAAkB,MAAM,GAAG;EAC3B,MAAM,IAAI,QAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC;EACvC,MAAM,OAAO,KAAK,cACR;GACP,MAAM,gBAAgB,EACpB,OAAO,EAAE,gBAAgB,OAAO,UAAU,gBAAgB,CAAC,CAC3D,KAAK,OAAO,UAAU,CACtB,MAAM,GAAG,OAAO,UAAU,gBAAgB,KAAK,KAAK,CAAC,CACrD,KAAK;AACP,OAAI,cAAc,SAAS,EAAG,QAAO;GACrC,MAAM,cAAc,EAClB,OAAO,EAAE,gBAAgB,OAAO,UAAU,gBAAgB,CAAC,CAC3D,KAAK,OAAO,UAAU,CACtB,MAAM,GAAG,OAAO,UAAU,MAAM,KAAK,KAAK,CAAC,CAC3C,KAAK;AACP,OAAI,YAAY,SAAS,GAAG;AAC3B,MAAE,IAAI,MAAM,2BAA2B,KAAK,OAAO;AACnD,YAAQ,WAAW;AACnB,WAAO,EAAE;;AAEV,UAAO;MACJ,GACH,EACC,OAAO,EAAE,gBAAgB,OAAO,UAAU,gBAAgB,CAAC,CAC3D,KAAK,OAAO,UAAU,CACtB,KAAK;AAET,MAAI,KAAK,WAAW,GAAG;AACtB,KAAE,IAAI,KAAK,8BAA8B;AACzC,WAAQ,WAAW;AACnB;;EAGD,IAAI,aAAa;AACjB,OAAK,MAAM,OAAO,MAAM;GACvB,MAAM,SAAS,MAAM,YAAY,MAAM,IAAI,IAAI,eAAe;AAC9D,OAAI,CAAC,OAAO,GAAI,cAAa;AAC7B,WAAQ,IAAI,qBAAqB,IAAI,gBAAgB,OAAO,CAAC;;AAE9D,MAAI,WACH,SAAQ,WAAW;WAEX;AACT,QAAM,OAAO;;EAEb,CACH;AAED,YAAY,WACX,IAAI,QAAQ,OAAO,CACjB,cAAc,UAAU,CACxB,YAAY,iDAAiD,CAC7D,OAAO,mBAAmB,kDAAkD,CAC5E,OAAO,wBAAwB,0DAA0D,CACzF,OAAO,kBAAkB,mDAAmD,CAC5E,OAAO,iBAAiB,qBAAqB,CAC7C,OAAO,yBAAyB,oCAAoC,CACpE,OAAO,wBAAwB,4CAA4C,CAC3E,OAAO,wBAAwB,4CAA4C,CAC3E,OAAO,SAAS,gDAAgD,CAChE,OAAO,aAAa,iDAAiD,CACrE,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,OAAO,SAA0B;CACxC,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,OAAO,CAAC;AACzD,KAAI;EACH,MAAM,sBAAsB,KAAK,UAAU,QAAQ,KAAK,cAAc;AACtE,MAAI,KAAK,eAAe,qBAAqB;AAC5C,KAAE,IAAI,MAAM,mEAAmE;AAC/E,WAAQ,WAAW;AACnB;;AAED,MAAI,KAAK,UAAU,KAAK,YAAY;AACnC,KAAE,IAAI,MAAM,4CAA4C;AACxD,WAAQ,WAAW;AACnB;;EAGD,IAAI,aAAa,KAAK;AACtB,MAAI,KAAK,WACR,KAAI;AACH,gBACC,KAAK,eAAe,MACjB,MAAM,IAAI,SAAiB,SAAS,WAAW;IAC/C,IAAI,OAAO;AACX,YAAQ,MAAM,YAAY,OAAO;AACjC,YAAQ,MAAM,GAAG,SAAS,UAAU;AACnC,aAAQ;MACP;AACF,YAAQ,MAAM,GAAG,aAAa,QAAQ,KAAK,CAAC;AAC5C,YAAQ,MAAM,GAAG,SAAS,OAAO;KAChC,GACD,aAAa,KAAK,YAAY,OAAO;WACjC,OAAO;AACf,KAAE,IAAI,MACL,iBAAiB,QACd,uCAAuC,KAAK,WAAW,IAAI,MAAM,YACjE,uCAAuC,KAAK,aAC/C;AACD,WAAQ,WAAW;AACnB;;AAIF,MAAI,uBAAuB,EAAE,cAAc,IAAI,MAAM,EAAE;AACtD,KAAE,IAAI,MAAM,oEAAoE;AAChF,WAAQ,WAAW;AACnB;;AAGD,MAAI,CAAC,eAAe,KAAK,WAAW,KAAK,WAAW,KAAK,OAAO,KAAK,UAAU;AAC9E,KAAE,IAAI,MACL,mFACA;AACD,WAAQ,WAAW;AACnB;;AAGD,MAAI,YAAY,MAAM,EAAE;AACvB,OAAI,KAAK,OAAO,KAAK,SAAS;AAC7B,MAAE,IAAI,MAAM,qCAAqC;AACjD,YAAQ,WAAW;AACnB;;AAED,QAAK,KAAK,OAAO,KAAK,aAAa,KAAK,WAAW,KAAK,UAAU;AACjE,MAAE,IAAI,MAAM,8DAA8D;AAC1E,YAAQ,WAAW;AACnB;;GAGD,IAAI;AACJ,OAAI;AACH,cAAU,KAAK,MAAM,WAAW;YACxB,OAAO;AACf,MAAE,IAAI,MACL,iBAAiB,QACd,4BAA4B,MAAM,YAClC,0BACH;AACD,YAAQ,WAAW;AACnB;;GAGD,MAAM,WAAW,OAAO,QAAQ,aAAa,GAAG,CAAC,MAAM;GACvD,MAAM,cAAc,OAAO,QAAQ,eAAe,GAAG,CAAC,MAAM;GAC5D,MAAM,YAAY,OAAO,QAAQ,cAAc,GAAG,CAAC,MAAM;GACzD,MAAM,oBAAoB,KAAK,SAAS,MAAM,GAC3C,CAAC,KAAK,QAAQ,MAAM,CAAC,GACrB,MAAM,QAAQ,QAAQ,UAAU,GAC9B,QAAQ,UACR,QACC,SAAyB,OAAO,SAAS,YAAY,KAAK,MAAM,CAAC,SAAS,EAC3E,CACA,KAAK,SAAS,KAAK,MAAM,CAAC,GAC3B,EAAE;AACN,OAAI,CAAC,YAAY,CAAC,eAAe,CAAC,aAAa,kBAAkB,WAAW,GAAG;AAC9E,MAAE,IAAI,MAAM,2EAA2E;AACvF,YAAQ,WAAW;AACnB;;AAED,OAAI,qBAAqB,UAAU,KAAK,aAAa;AACpD,MAAE,IAAI,MAAM,uCAAuC;AACnD,YAAQ,WAAW;AACnB;;AAGD,uBAAoB,MAAM,IAAI,UAAU,mBAAmB;IAC1D,MAAM,KAAK;IACX,mBAAmB;IACnB;IACA,CAAC;AAEF,OAAI,KAAK,QACR,sBAAqB,MAAM,IAAI,UAAU;IAAE,SAAS;IAAM,SAAS;IAAM,CAAC;YAChE,KAAK,OAAO,KAAK,WAAW,KAAK,QAC3C,sBAAqB,MAAM,IAAI,UAAU;IACxC,SAAS,KAAK,MAAM,EAAE,GAAG,iBAAiB,KAAK,QAAQ;IACvD,SAAS,KAAK,MAAM,EAAE,GAAG,iBAAiB,KAAK,QAAQ;IACvD,CAAC;AAGH,KAAE,IAAI,QAAQ,eAAe,WAAW;AACxC;;EAGD,MAAM,UAAU,QAAQ,IAAI,kBAAkB,MAAM,IAAI,KAAA;EACxD,MAAM,CAAC,UAAU,eAAe,qBAAqB,MAAM,IAAI,EAAE,SAAS,CAAC;EAC3E,MAAM,YAAY,cAAc,QAAQ;AACxC,MAAI,CAAC,WAAW;AACf,KAAE,IAAI,MAAM,qBAAqB;AACjC,WAAQ,WAAW;AACnB;;EAGD,MAAM,SAAS,uBAAuB;EACtC,MAAM,kBAAkB,KAAK,SAAS,MAAM;EAC5C,MAAM,iBAAiB,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;EACjF,MAAM,iBAAiB,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;EACjF,MAAM,YAAY,0BACjB,mBAAmB,MACnB,gBACA,gBACA,mBAAmB,CACnB;EACD,MAAM,UAAU;GACf,WAAW;GACX;GACA,YAAY;GACZ,SAAS,UAAU,MAAM;GACzB;GACA;EACD,MAAM,cAAc,KAAK,UAAU,QAAQ;AAE3C,MAAI,KAAK,aAAa;AACrB,WAAQ,OAAO,MAAM,GAAG,YAAY,IAAI;AACxC;;EAGD,MAAM,UAAU,YAAY,WAAW,KAAK,QAAQ;AACpD,UAAQ,IAAI,kBAAkB;AAC9B,UAAQ,IAAI,YAAY;AACxB,UAAQ,IAAI,iEAAiE;AAC7E,UAAQ,IAAI,iDAAiD;AAC7D,UAAQ,IAAI,kCAAkC;AAC9C,UAAQ,IAAI,iCAAiC,QAAQ,GAAG;AACxD,UAAQ,IAAI,8CAA8C;AAC1D,UAAQ,IAAI,qCAAqC;AACjD,UAAQ,IACP,8GACA;WACQ;AACT,QAAM,OAAO;;EAEb,CACH;AAED,YAAY,WACX,IAAI,QAAQ,SAAS,CACnB,cAAc,UAAU,CACxB,YAAY,qDAAqD,CACjE,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,OAAO,SAA2C;CACzD,MAAM,SAAS,uBAAuB;CACtC,MAAM,SAAS,cAAc,KAAK,MAAM,KAAK,OAAO;CACpD,MAAM,QAAQ,IAAI,YAAY,OAAO;AACrC,KAAI;EACH,MAAM,IAAI,QAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC;EACvC,MAAM,SAAS,EACb,OAAO,EAAE,WAAW,OAAO,WAAW,WAAW,CAAC,CAClD,KAAK,OAAO,WAAW,CACvB,MAAM,EAAE,CACR,KAAK;EACP,MAAM,cAAc,EAClB,QAAQ,CACR,KAAK,OAAO,gBAAgB,CAC5B,MAAM,GAAG,OAAO,gBAAgB,IAAI,EAAE,CAAC,CACvC,KAAK;EACP,MAAM,QAAQ,EACZ,OAAO;GACP,gBAAgB,OAAO,UAAU;GACjC,gBAAgB,OAAO,UAAU;GACjC,oBAAoB,OAAO,UAAU;GACrC,YAAY,OAAO,UAAU;GAC7B,CAAC,CACD,KAAK,OAAO,UAAU,CACtB,KAAK;EAEP,MAAM,SAAmB,EAAE;EAC3B,MAAM,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;EAC3E,MAAM,WAAW,OAAO,OAAO,cAAc,WAAW,OAAO,YAAY;EAC3E,MAAM,gBAAgB,kBAAkB,OAAO;AAE/C,UAAQ,IAAI,cAAc;AAC1B,UAAQ,IAAI,cAAc,OAAO,iBAAiB,OAAO;AACzD,UAAQ,IAAI,aAAa,SAAS,GAAG,WAAW;AAChD,UAAQ,IAAI,WAAW,QAAQ,IAAI,oBAAoB,mBAAmB,gBAAgB;EAE1F,MAAM,YAAY,gBACf,MAAM,SAAS,cAAc,MAAM,cAAc,KAAK,GACtD;AACH,UAAQ,IAAI,aAAa,YAAY,YAAY,gBAAgB;AACjE,MAAI,CAAC,UAAW,QAAO,KAAK,qBAAqB;AAEjD,MAAI,CAAC,QAAQ;AACZ,WAAQ,IAAI,kDAAkD;AAC9D,UAAO,KAAK,mBAAmB;QAE/B,SAAQ,IAAI,eAAe,OAAO,YAAY;AAG/C,MACC,aAAa,eACZ,CAAC,YAAY,cAAc,YAAY,cAAc,YAAY,iBAAiB,MAClF;AACD,WAAQ,IACP,mBAAmB,YAAY,WAAW,OAAO,YAAY,iBAAiB,UAAU,GACxF;AACD,UAAO,KAAK,eAAe;;AAG5B,MAAI,MAAM,WAAW,GAAG;AACvB,WAAQ,IAAI,sCAAsC;AAClD,UAAO,KAAK,WAAW;SACjB;AACN,WAAQ,IAAI,YAAY,MAAM,SAAS;AACvC,QAAK,MAAM,QAAQ,OAAO;IACzB,MAAM,YAAY,KAAK,iBACnB,KAAK,MAAM,KAAK,eAAe,GAChC,EAAE;IACL,MAAM,WAAW,2BAA2B,UAAU,MAAM,GAAG;IAC/D,MAAM,QAAQ,WACV,MAAM,SAAS,SAAS,MAAM,SAAS,KAAK,GAC5C,OACA,gBACD;IACH,MAAM,SAAS,QAAQ,KAAK,mBAAmB;IAC/C,MAAM,SAAS,QAAQ,KAAK,WAAW;AACvC,YAAQ,IACP,OAAO,KAAK,eAAe,cAAc,UAAU,OAAO,SAAS,MAAM,UAAU,OAAO,cAAc,SACxG;AACD,QAAI,UAAU,KAAM,QAAO,KAAK,QAAQ,KAAK,eAAe,cAAc;AAC1E,QAAI,CAAC,UAAU,CAAC,OAAQ,QAAO,KAAK,QAAQ,KAAK,eAAe,aAAa;;;AAI/E,MAAI,CAAC,OAAO,aAAc,QAAO,KAAK,mBAAmB;AAEzD,MAAI,OAAO,SAAS,EACnB,SAAQ,IAAI,SAAS,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,KAAK,KAAK,GAAG;MAEnE,SAAQ,IAAI,yBAAyB;WAE7B;AACT,QAAM,OAAO;;EAEb,CACH;AAGD,YAAY,WACX,IAAI,QAAQ,SAAS,CACnB,cAAc,UAAU,CACxB,YAAY,2CAA2C,CACvD,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,UAAU,iBAAiB,CAClC,QAAQ,SAA2D;CACnE,MAAM,SAAS,uBAAuB;CACtC,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,IAAI,QAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC;EACvC,MAAM,YAAY,EAChB,OAAO;GACP,WAAW,OAAO,WAAW;GAC7B,aAAa,OAAO,WAAW;GAC/B,CAAC,CACD,KAAK,OAAO,WAAW,CACvB,MAAM,EAAE,CACR,KAAK;EACP,MAAM,QAAQ,EACZ,OAAO;GACP,gBAAgB,OAAO,UAAU;GACjC,MAAM,OAAO,UAAU;GACvB,cAAc,OAAO,UAAU;GAC/B,YAAY,OAAO,UAAU;GAC7B,CAAC,CACD,KAAK,OAAO,UAAU,CACtB,KAAK;AAEP,MAAI,KAAK,MAAM;AACd,WAAQ,IACP,KAAK,UACJ;IACC,SAAS,OAAO,iBAAiB;IACjC,MAAM,OAAO,aAAa;IAC1B,MAAM,OAAO,aAAa;IAC1B,YAAY,OAAO,mBAAmB;IACtC,WAAW,WAAW,aAAa;IACnC,aAAa,WAAW,eAAe;IACvC,iBAAiB,OAAO,wBAAwB;IAChD,OAAO,MAAM,KAAK,UAAU;KAC3B,WAAW,KAAK;KAChB,MAAM,KAAK;KACX,WAAW,KAAK;KAChB,QAAQ,KAAK,cAAc;KAC3B,EAAE;IACH,EACD,MACA,EACA,CACD;AACD;;AAGD,IAAE,MAAM,sBAAsB;AAC9B,IAAE,IAAI,KACL;GACC,eAAe,OAAO,iBAAiB,OAAO,QAAQ;GACtD,eAAe,OAAO,aAAa;GACnC,eAAe,OAAO,aAAa;GACnC,eAAe,OAAO,mBAAmB,IAAI;GAC7C,gBAAgB,OAAO,wBAAwB;GAC/C,CAAC,KAAK,KAAK,CACZ;AACD,MAAI,UACH,GAAE,IAAI,KAAK,gBAAgB,UAAU,UAAU,iBAAiB,UAAU,cAAc;MAExF,GAAE,IAAI,KAAK,8DAA8D;AAE1E,MAAI,MAAM,WAAW,EACpB,GAAE,IAAI,KAAK,cAAc;MAEzB,MAAK,MAAM,QAAQ,OAAO;GACzB,MAAM,QAAQ,KAAK,QAAQ,KAAK;AAChC,KAAE,IAAI,QACL,KAAK,MAAM,cAAc,KAAK,gBAAgB,QAAQ,WAAW,KAAK,cAAc,OACpF;;AAGH,IAAE,MAAM,GAAG,MAAM,OAAO,UAAU;WACzB;AACT,QAAM,OAAO;;EAEb,CACH;AAGD,YAAY,WACX,IAAI,QAAQ,SAAS,CACnB,cAAc,UAAU,CACxB,YAAY,6CAA6C,CACzD,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,iBAAiB,mBAAmB,CAC3C,OAAO,iBAAiB,mBAAmB,CAC3C,OAAO,wBAAwB,2BAA2B,CAC1D,QACC,SAA4F;CAC5F,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EACH,MAAM,CAAC,UAAU,eAAe,qBAAqB,MAAM,GAAG;EAC9D,MAAM,SAAS,uBAAuB;AACtC,SAAO,eAAe;AACtB,MAAI,KAAK,KAAM,QAAO,YAAY,KAAK;AACvC,MAAI,KAAK,KAAM,QAAO,YAAY,OAAO,SAAS,KAAK,MAAM,GAAG;AAChE,MAAI,KAAK,SAAU,QAAO,kBAAkB,OAAO,SAAS,KAAK,UAAU,GAAG;AAC9E,yBAAuB,OAAO;AAE9B,IAAE,MAAM,sBAAsB;AAC9B,IAAE,IAAI,QACL;GACC,gBAAgB;GAChB,gBAAgB;GAChB,gBAAgB,OAAO,aAAa;GACpC,gBAAgB,OAAO,aAAa;GACpC,gBAAgB,OAAO,mBAAmB,IAAI;GAC9C,CAAC,KAAK,KAAK,CACZ;AACD,IAAE,MAAM,qDAAqD;WACpD;AACT,QAAM,OAAO;;EAGf,CACF;AAGD,YAAY,WACX,IAAI,QAAQ,UAAU,CACpB,cAAc,UAAU,CACxB,YAAY,8CAA8C,CAC1D,aAAa;CACb,MAAM,SAAS,uBAAuB;AACtC,QAAO,eAAe;AACtB,wBAAuB,OAAO;AAC9B,GAAE,MAAM,uBAAuB;AAC/B,GAAE,MAAM,yDAAyD;EAChE,CACH;AAGD,YAAY,WACX,IAAI,QAAQ,QAAQ,CAClB,cAAc,UAAU,CACxB,YAAY,wBAAwB,CACpC,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,UAAU,iBAAiB,CAClC,QAAQ,SAA2D;CACnE,MAAM,QAAQ,IAAI,YAAY,cAAc,KAAK,MAAM,KAAK,OAAO,CAAC;AACpE,KAAI;EAEH,MAAM,QADI,QAAQ,MAAM,IAAI,EAAE,QAAQ,CAAC,CAErC,OAAO;GACP,gBAAgB,OAAO,UAAU;GACjC,MAAM,OAAO,UAAU;GACvB,WAAW,OAAO,UAAU;GAC5B,cAAc,OAAO,UAAU;GAC/B,YAAY,OAAO,UAAU;GAC7B,CAAC,CACD,KAAK,OAAO,UAAU,CACtB,QAAQ,KAAK,OAAO,UAAU,aAAa,CAAC,CAC5C,KAAK;AAEP,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,OAAO,MAAM,EAAE,CAAC;AAC3C;;AAGD,IAAE,MAAM,qBAAqB;AAC7B,MAAI,MAAM,WAAW,GAAG;AACvB,KAAE,MAAM,sBAAsB;AAC9B;;AAED,OAAK,MAAM,QAAQ,OAAO;GACzB,MAAM,QAAQ,KAAK,QAAQ,KAAK;GAChC,MAAM,QAAQ,KAAK,aAAa;AAChC,KAAE,IAAI,QACL,GAAG,MAAM,iBAAiB,MAAM,iBAAiB,KAAK,gBAAgB,QAAQ,cAAc,KAAK,cAAc,OAC/G;;AAEF,IAAE,MAAM,GAAG,MAAM,OAAO,UAAU;WACzB;AACT,QAAM,OAAO;;EAEb,CACH;AAGD,YAAY,WACX,IAAI,QAAQ,UAAU,CACpB,cAAc,UAAU,CACxB,YAAY,2CAA2C,CACvD,SAAS,SAAS,yDAAyD,CAC3E,OAAO,mBAAmB,gBAAgB,CAC1C,QAAQ,KAAa,SAA6B;CAClD,MAAM,SAAS,uBAAuB;AACtC,QAAO,uBAAuB,IAAI,MAAM;AACxC,KAAI,KAAK,MAAO,QAAO,yBAAyB,KAAK,MAAM,MAAM;AACjE,wBAAuB,OAAO;AAC9B,GAAE,MAAM,uBAAuB;AAC/B,GAAE,IAAI,QAAQ,gBAAgB,IAAI,MAAM,GAAG;AAC3C,KAAI,KAAK,MAAO,GAAE,IAAI,KAAK,UAAU,KAAK,MAAM,MAAM,GAAG;AACzD,GAAE,MAAM,uDAAuD;EAC9D,CACH;AAED,IAAM,qBAAqB,IAAI,QAAQ,cAAc,CACnD,cAAc,UAAU,CACxB,YAAY,8DAA8D;AAE5E,mBAAmB,WAClB,IAAI,QAAQ,QAAQ,CAClB,cAAc,UAAU,CACxB,YAAY,wCAAwC,CACpD,OAAO,eAAe,4BAA4B,CAClD,OAAO,oBAAoB,4BAA4B,CACvD,OAAO,iBAAiB,aAAa,YAAY,CACjD,OAAO,iBAAiB,aAAa,OAAO,CAC5C,OAAO,OAAO,SAAyE;CACvF,MAAM,OAAO,OAAO,KAAK,QAAQ,YAAY,CAAC,MAAM,IAAI;CACxD,MAAM,OAAO,OAAO,SAAS,OAAO,KAAK,QAAQ,OAAO,EAAE,GAAG;CAC7D,MAAM,SAAS,KAAK,MAAM,KAAK,UAAU;CACzC,MAAM,MAAM,qBAAqB,EAAE,QAAQ,CAAC;AAC5C,GAAE,MAAM,iCAAiC;AACzC,GAAE,IAAI,QAAQ,mCAAmC,KAAK,GAAG,OAAO;AAChE,GAAE,IAAI,KAAK,OAAO,SAAS;AAC3B,OAAU;EAAE,OAAO,IAAI;EAAO,UAAU;EAAM;EAAM,CAAC;EACpD,CACH;AAED,mBAAmB,WAClB,IAAI,QAAQ,gBAAgB,CAC1B,cAAc,UAAU,CACxB,YAAY,mCAAmC,CAC/C,SAAS,WAAW,WAAW,CAC/B,OAAO,mBAAmB,WAAW,CACrC,OAAO,2BAA2B,2BAA2B,CAC7D,OAAO,qBAAqB,iBAAiB,aAAa,CAC1D,OAAO,uBAAuB,oBAAoB,KAAK,CACvD,OAAO,eAAe,4BAA4B,CAClD,OAAO,oBAAoB,4BAA4B,CACvD,OAAO,sBAAsB,kCAAkC,CAC/D,OAAO,2BAA2B,2CAA2C,CAC7E,OAAO,UAAU,iBAAiB,CAClC,OACA,OACC,UACA,SAWI;CACJ,MAAM,WAAW,OAAO,SAAS,OAAO,KAAK,YAAY,KAAK,EAAE,GAAG;CACnE,MAAM,UAAU,OAAO,KAAK,SAAS,GAAG,CAAC,MAAM,IAAI,OAAO,YAAY,GAAG,CAAC,MAAM;CAChF,MAAM,SAAS,MAAM,8BAA8B;EAClD;EACA,gBAAgB,KAAK,gBAAgB,MAAM,IAAI;EAC/C,QAAQ,OAAO,KAAK,UAAU,aAAa,CAAC,MAAM;EAClD;EACA,WAAW;EACX,QAAQ,KAAK,MAAM,KAAK,UAAU;EAClC,WAAW,KAAK,WAAW,MAAM,IAAI;EACrC,aAAa,KAAK,aAAa,MAAM,IAAI;EACzC,CAAC;AACF,KAAI,KAAK,MAAM;AACd,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;AAED,GAAE,MAAM,yCAAyC;AACjD,GAAE,IAAI,QAAQ,sBAAsB,UAAU;AAC9C,KAAI,OAAO,OAAO,SAAS,SAAU,GAAE,IAAI,QAAQ,WAAW,OAAO,OAAO;AAC5E,KAAI,OAAO,OAAO,YAAY,SAAU,GAAE,IAAI,QAAQ,aAAa,OAAO,UAAU;AACpF,GAAE,MAAM,eAAe;EAExB,CACF;AAED,mBAAmB,WAClB,IAAI,QAAQ,gBAAgB,CAC1B,cAAc,UAAU,CACxB,YAAY,8BAA8B,CAC1C,SAAS,YAAY,uBAAuB,CAC5C,OAAO,eAAe,gBAAgB,CACtC,OAAO,oBAAoB,gBAAgB,CAC3C,OAAO,qBAAqB,iBAAiB,CAC7C,OAAO,mBAAmB,cAAc,CACxC,OAAO,UAAU,iBAAiB,CAClC,OACA,OACC,QACA,SACI;CACJ,MAAM,SAAS,MAAM,8BAA8B;EAClD,aAAa;EACb,QAAQ,KAAK,MAAM,KAAK,UAAU;EAClC,SAAS,KAAK,WAAW;EACzB,YAAY,KAAK,UAAU;EAC3B,CAAC;AACF,KAAI,KAAK,MAAM;AACd,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;AAC5C;;AAED,GAAE,MAAM,yCAAyC;AACjD,GAAE,IAAI,QAAQ,uBAAuB,OAAO,WAAW;AACvD,GAAE,IAAI,QAAQ,kBAAkB,OAAO,kBAAkB;AACzD,GAAE,IAAI,QAAQ,aAAa,OAAO,SAAS;AAC3C,GAAE,MAAM,6BAA6B;EAEtC,CACF;AAED,mBAAmB,WAClB,IAAI,QAAQ,qBAAqB,CAC/B,cAAc,UAAU,CACxB,YAAY,yCAAyC,CACrD,SAAS,WAAW,WAAW,CAC/B,OAAO,mBAAmB,WAAW,CACrC,OAAO,eAAe,4BAA4B,CAClD,OAAO,oBAAoB,4BAA4B,CACvD,OAAO,sBAAsB,kCAAkC,CAC/D,OAAO,2BAA2B,2CAA2C,CAC7E,OAAO,UAAU,iBAAiB,CAClC,OACA,OACC,UACA,SAQI;CACJ,MAAM,UAAU,OAAO,KAAK,SAAS,GAAG,CAAC,MAAM,IAAI,OAAO,YAAY,GAAG,CAAC,MAAM;CAChF,MAAM,OAAO,MAAM,kCAAkC;EACpD;EACA,QAAQ,KAAK,MAAM,KAAK,UAAU;EAClC,WAAW,KAAK,WAAW,MAAM,IAAI;EACrC,aAAa,KAAK,aAAa,MAAM,IAAI;EACzC,CAAC;AACF,KAAI,KAAK,MAAM;AACd,UAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,EAAE,CAAC;AAC1C;;AAED,GAAE,MAAM,8CAA8C;AACtD,KAAI,KAAK,WAAW,GAAG;AACtB,IAAE,MAAM,gCAAgC,UAAU;AAClD;;AAED,MAAK,MAAM,OAAO,MAAM;EACvB,MAAM,cAAc,IAAI,gBAAgB,IAAI;AAC5C,IAAE,IAAI,QAAQ,KAAK,YAAY,IAAI,IAAI,UAAU,eAAe,IAAI,aAAa;;AAElF,GAAE,MAAM,GAAG,KAAK,OAAO,0BAA0B;EAElD,CACF;AAED,SAAS,4BACR,MACA,SACC;AACD,oBAAmB,WAClB,IAAI,QAAQ,KAAK,CACf,cAAc,UAAU,CACxB,YAAY,GAAG,UAAU,YAAY,OAAO,6BAA6B,CACzE,SAAS,gBAAgB,kBAAkB,CAC3C,OAAO,eAAe,4BAA4B,CAClD,OAAO,oBAAoB,4BAA4B,CACvD,OAAO,sBAAsB,kCAAkC,CAC/D,OAAO,2BAA2B,2CAA2C,CAC7E,OAAO,UAAU,iBAAiB,CAClC,OACA,OACC,WACA,SAOI;EACJ,MAAM,UAAU,MAAM,mCAAmC;GACxD,WAAW,UAAU,MAAM;GAC3B;GACA,YAAY;GACZ,QAAQ,KAAK,MAAM,KAAK,UAAU;GAClC,WAAW,KAAK,WAAW,MAAM,IAAI;GACrC,aAAa,KAAK,aAAa,MAAM,IAAI;GACzC,CAAC;AACF,MAAI,CAAC,SAAS;AACb,KAAE,IAAI,MAAM,2BAA2B,UAAU,MAAM,GAAG;AAC1D,WAAQ,WAAW;AACnB;;AAED,MAAI,KAAK,MAAM;AACd,WAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,EAAE,CAAC;AAC7C;;AAED,IAAE,MAAM,4BAA4B,OAAO;AAC3C,IAAE,IAAI,QAAQ,GAAG,UAAU,aAAa,SAAS,gBAAgB,UAAU,MAAM,GAAG;AACpF,IAAE,MAAM,OAAO,QAAQ,UAAU,UAAU,CAAC;GAE7C,CACF;;AAGF,4BAA4B,wBAAwB,KAAK;AACzD,4BAA4B,qBAAqB,MAAM;AAEvD,YAAY,WAAW,mBAAmB;;;ACj/B1C,IAAa,iBAAiB,IAAI,QAAQ,UAAU,CAClD,cAAc,UAAU,CACxB,YAAY,wBAAwB,CACpC,aAAa;AACb,SAAQ,IAAI,QAAQ;EACnB;;;;;;;;;;;;;ACoCH,IAAM,aAAa,SAAS,oBAAoB;AAChD,WAAW,GAAG,YAAY,EAAE,YAAY;AACvC,OAAM;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,CAAC;EACD;AACF,WAAW,MAAM;AAEjB,SAAS,YAAY,MAAuB;AAC3C,MAAK,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE,EAAE;AACxC,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,QAAQ,KAAM,QAAO;AACzB,MAAI,CAAC,IAAI,WAAW,IAAI,CAAE,QAAO;;AAElC,QAAO;;AAGR,SAAS,2BAAmC;AAE3C,MADkB,QAAQ,IAAI,SAAS,IACzB,SAAS,OAAO,CAC7B,QAAO,WAAW,4BAA4B;AAE/C,QAAO,WAAW,wBAAwB;;AAG3C,IAAM,UAAU,IAAI,SAAS;AAE7B,QACE,KAAK,UAAU,CACf,YAAY,mDAAmD,CAC/D,OAAO,wBAAwB,2BAA2B,CAC1D,OAAO,qBAAqB,yCAAyC,CACrE,QAAQ,QAAQ,CAChB,cAAc,UAAU;AAE1B,IAAI,YAAY,qBAAqB,IAAI,YAAY,uBAAuB,EAAE;AAC7E,YAAW,oBAAoB;AAC/B,SAAQ,KAAK,EAAE;;AAGhB,IAAI,YAAY,oBAAoB,EAAE;AACrC,SAAQ,IAAI,0BAA0B,CAAC;AACvC,SAAQ,KAAK,EAAE;;AAGhB,IAAI,YAAY,uBAAuB,EAAE;AACxC,YAAW,sBAAsB;AACjC,SAAQ,KAAK,EAAE;;AAGhB,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,wBAAwB;AAC3C,QAAQ,WAAW,UAAU;AAC7B,QAAQ,WAAW,sBAAsB;AACzC,QAAQ,WAAW,sBAAsB;AACzC,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,kBAAkB;AACrC,QAAQ,WAAW,oBAAoB;AACvC,QAAQ,WAAW,sBAAsB;AACzC,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,uBAAuB;AAC1C,QAAQ,WAAW,eAAe;AAElC,QAAQ,OAAO"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/help-style.ts","../src/commands/claude-hook-ingest.ts","../src/commands/db.ts","../src/commands/embed.ts","../src/commands/enqueue-raw-event.ts","../src/commands/export-memories.ts","../src/commands/import-memories.ts","../src/commands/mcp.ts","../src/commands/memory.ts","../src/commands/pack.ts","../src/commands/recent.ts","../src/commands/search.ts","../src/commands/serve-invocation.ts","../src/commands/serve.ts","../src/commands/setup-config.ts","../src/commands/setup.ts","../src/commands/stats.ts","../src/commands/sync-helpers.ts","../src/commands/sync.ts","../src/commands/version.ts","../src/index.ts"],"sourcesContent":["/**\n * Shared Commander help style configuration.\n *\n * Applied to every Command instance so subcommand --help\n * output gets the same colors as the root.\n */\n\nimport { styleText } from \"node:util\";\nimport type { HelpConfiguration } from \"commander\";\n\nexport const helpStyle: HelpConfiguration = {\n\tstyleTitle: (str) => styleText(\"bold\", str),\n\tstyleCommandText: (str) => styleText(\"cyan\", str),\n\tstyleCommandDescription: (str) => str,\n\tstyleDescriptionText: (str) => styleText(\"dim\", str),\n\tstyleOptionText: (str) => styleText(\"green\", str),\n\tstyleOptionTerm: (str) => styleText(\"green\", str),\n\tstyleSubcommandText: (str) => styleText(\"cyan\", str),\n\tstyleArgumentText: (str) => styleText(\"yellow\", str),\n};\n","/**\n * codemem claude-hook-ingest — read a single Claude Code hook payload\n * from stdin and enqueue it for processing.\n *\n * Ports codemem/commands/claude_hook_runtime_cmds.py with an HTTP-first\n * strategy: try POST /api/claude-hooks (viewer must be running), then\n * fall back to direct raw-event enqueue via the local store.\n *\n * Usage (from Claude hooks config):\n * echo '{\"hook_event_name\":\"Stop\",\"session_id\":\"...\",\"last_assistant_message\":\"...\"}' \\\n * | codemem claude-hook-ingest\n */\n\nimport { readFileSync } from \"node:fs\";\nimport {\n\tbuildRawEventEnvelopeFromHook,\n\tconnect,\n\tloadSqliteVec,\n\tresolveDbPath,\n\tstripPrivateObj,\n} from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\ntype IngestResult = { inserted: number; skipped: number; via: \"http\" | \"direct\" };\n\ntype IngestOpts = {\n\thost: string;\n\tport: number;\n\tdb?: string;\n\tdbPath?: string;\n};\n\ntype IngestDeps = {\n\thttpIngest?: typeof tryHttpIngest;\n\tdirectIngest?: typeof directEnqueue;\n\tresolveDb?: typeof resolveDbPath;\n};\n\n/** Try to POST the hook payload to the running viewer server. */\nasync function tryHttpIngest(\n\tpayload: Record<string, unknown>,\n\thost: string,\n\tport: number,\n): Promise<{ ok: boolean; inserted: number; skipped: number }> {\n\tconst url = `http://${host}:${port}/api/claude-hooks`;\n\tconst controller = new AbortController();\n\tconst timeout = setTimeout(() => controller.abort(), 5000);\n\ttry {\n\t\tconst res = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify(payload),\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!res.ok) return { ok: false, inserted: 0, skipped: 0 };\n\t\tconst body = (await res.json()) as Record<string, unknown>;\n\t\treturn {\n\t\t\tok: true,\n\t\t\tinserted: Number(body.inserted ?? 0),\n\t\t\tskipped: Number(body.skipped ?? 0),\n\t\t};\n\t} catch {\n\t\treturn { ok: false, inserted: 0, skipped: 0 };\n\t} finally {\n\t\tclearTimeout(timeout);\n\t}\n}\n\n/** Fall back to direct raw-event enqueue via the local SQLite store. */\nexport function directEnqueue(\n\tpayload: Record<string, unknown>,\n\tdbPath: string,\n): { inserted: number; skipped: number } {\n\tconst envelope = buildRawEventEnvelopeFromHook(payload);\n\tif (!envelope) return { inserted: 0, skipped: 1 };\n\n\tconst db = connect(dbPath);\n\ttry {\n\t\ttry {\n\t\t\tloadSqliteVec(db);\n\t\t} catch {\n\t\t\t// sqlite-vec not available — non-fatal for raw event enqueue\n\t\t}\n\t\tconst strippedPayload = stripPrivateObj(envelope.payload) as Record<string, unknown>;\n\t\tconst existing = db\n\t\t\t.prepare(\n\t\t\t\t\"SELECT 1 FROM raw_events WHERE source = ? AND stream_id = ? AND event_id = ? LIMIT 1\",\n\t\t\t)\n\t\t\t.get(envelope.source, envelope.session_stream_id, envelope.event_id);\n\t\tif (existing) return { inserted: 0, skipped: 0 };\n\n\t\tdb.prepare(\n\t\t\t`INSERT INTO raw_events(\n\t\t\t\tsource, stream_id, opencode_session_id, event_id, event_seq,\n\t\t\t\tevent_type, ts_wall_ms, payload_json, created_at\n\t\t\t) VALUES (?, ?, ?, ?, (\n\t\t\t\tSELECT COALESCE(MAX(event_seq), 0) + 1\n\t\t\t\tFROM raw_events WHERE source = ? AND stream_id = ?\n\t\t\t), ?, ?, ?, datetime('now'))`,\n\t\t).run(\n\t\t\tenvelope.source,\n\t\t\tenvelope.session_stream_id,\n\t\t\tenvelope.opencode_session_id,\n\t\t\tenvelope.event_id,\n\t\t\tenvelope.source,\n\t\t\tenvelope.session_stream_id,\n\t\t\t\"claude.hook\",\n\t\t\tenvelope.ts_wall_ms,\n\t\t\tJSON.stringify(strippedPayload),\n\t\t);\n\n\t\t// Query actual max event_seq for this stream to keep session metadata in sync\n\t\tconst maxSeqRow = db\n\t\t\t.prepare(\n\t\t\t\t\"SELECT COALESCE(MAX(event_seq), 0) AS max_seq FROM raw_events WHERE source = ? AND stream_id = ?\",\n\t\t\t)\n\t\t\t.get(envelope.source, envelope.session_stream_id) as { max_seq: number };\n\t\tconst currentMaxSeq = maxSeqRow.max_seq;\n\n\t\t// Upsert session metadata with accurate sequence tracking\n\t\tdb.prepare(\n\t\t\t`INSERT INTO raw_event_sessions(\n\t\t\t\tsource, stream_id, opencode_session_id, cwd, project, started_at,\n\t\t\t\tlast_seen_ts_wall_ms, last_received_event_seq, last_flushed_event_seq, updated_at\n\t\t\t) VALUES (?, ?, ?, ?, ?, ?, ?, ?, -1, datetime('now'))\n\t\t\tON CONFLICT(source, stream_id) DO UPDATE SET\n\t\t\t\tcwd = COALESCE(excluded.cwd, cwd),\n\t\t\t\tproject = COALESCE(excluded.project, project),\n\t\t\t\tstarted_at = COALESCE(excluded.started_at, started_at),\n\t\t\t\tlast_seen_ts_wall_ms = MAX(COALESCE(excluded.last_seen_ts_wall_ms, 0), COALESCE(last_seen_ts_wall_ms, 0)),\n\t\t\t\tlast_received_event_seq = MAX(excluded.last_received_event_seq, last_received_event_seq),\n\t\t\t\tupdated_at = datetime('now')`,\n\t\t).run(\n\t\t\tenvelope.source,\n\t\t\tenvelope.session_stream_id,\n\t\t\tenvelope.opencode_session_id,\n\t\t\tenvelope.cwd,\n\t\t\tenvelope.project,\n\t\t\tenvelope.started_at,\n\t\t\tenvelope.ts_wall_ms,\n\t\t\tcurrentMaxSeq,\n\t\t);\n\n\t\treturn { inserted: 1, skipped: 0 };\n\t} finally {\n\t\tdb.close();\n\t}\n}\n\n/**\n * Ingest one Claude hook payload using the TS contract:\n * HTTP enqueue first, then direct local enqueue fallback.\n *\n * This path intentionally does not implement file-spool/lock durability.\n */\nexport async function ingestClaudeHookPayload(\n\tpayload: Record<string, unknown>,\n\topts: IngestOpts,\n\tdeps: IngestDeps = {},\n): Promise<IngestResult> {\n\tconst httpIngest = deps.httpIngest ?? tryHttpIngest;\n\tconst directIngest = deps.directIngest ?? directEnqueue;\n\tconst resolveDb = deps.resolveDb ?? resolveDbPath;\n\n\tconst httpResult = await httpIngest(payload, opts.host, opts.port);\n\tif (httpResult.ok) {\n\t\treturn { inserted: httpResult.inserted, skipped: httpResult.skipped, via: \"http\" };\n\t}\n\n\tconst dbPath = resolveDb(opts.db ?? opts.dbPath);\n\tconst directResult = directIngest(payload, dbPath);\n\treturn { ...directResult, via: \"direct\" };\n}\n\nexport const claudeHookIngestCommand = new Command(\"claude-hook-ingest\")\n\t.configureHelp(helpStyle)\n\t.description(\"Ingest Claude hook payload: HTTP first, direct DB fallback\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--host <host>\", \"viewer server host\", \"127.0.0.1\")\n\t.option(\"--port <port>\", \"viewer server port\", \"38888\")\n\t.action(async (opts: { db?: string; dbPath?: string; host: string; port: string }) => {\n\t\t// Read payload from stdin\n\t\tlet raw: string;\n\t\ttry {\n\t\t\traw = readFileSync(0, \"utf8\").trim();\n\t\t} catch {\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tif (!raw) {\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\n\t\tlet payload: Record<string, unknown>;\n\t\ttry {\n\t\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\t\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tpayload = parsed as Record<string, unknown>;\n\t\t} catch {\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\n\t\tconst port = Number.parseInt(opts.port, 10);\n\t\tconst host = opts.host;\n\n\t\ttry {\n\t\t\tconst result = await ingestClaudeHookPayload(payload, {\n\t\t\t\thost,\n\t\t\t\tport,\n\t\t\t\tdb: opts.db,\n\t\t\t\tdbPath: opts.dbPath,\n\t\t\t});\n\t\t\tconsole.log(JSON.stringify(result));\n\t\t} catch {\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t});\n","import { statSync } from \"node:fs\";\nimport * as p from \"@clack/prompts\";\nimport {\n\tbackfillTagsText,\n\tconnect,\n\tdeactivateLowSignalMemories,\n\tdeactivateLowSignalObservations,\n\tgetRawEventStatus,\n\tinitDatabase,\n\tMemoryStore,\n\trawEventsGate,\n\tresolveDbPath,\n\tresolveProject,\n\tretryRawEventFailures,\n\tvacuumDatabase,\n} from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nfunction parseOptionalPositiveInt(value: string | undefined): number | undefined {\n\tif (!value) return undefined;\n\tconst parsed = Number.parseInt(value, 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\tthrow new Error(`invalid positive integer: ${value}`);\n\t}\n\treturn parsed;\n}\n\nfunction parseKindsCsv(value: string | undefined): string[] | undefined {\n\tif (!value) return undefined;\n\tconst kinds = value\n\t\t.split(\",\")\n\t\t.map((kind) => kind.trim())\n\t\t.filter((kind) => kind.length > 0);\n\treturn kinds.length > 0 ? kinds : undefined;\n}\n\nexport const dbCommand = new Command(\"db\")\n\t.configureHelp(helpStyle)\n\t.description(\"Database maintenance\");\n\ndbCommand\n\t.addCommand(\n\t\tnew Command(\"init\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Verify the SQLite database is present and schema-ready\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.action((opts: { db?: string; dbPath?: string }) => {\n\t\t\t\tconst result = initDatabase(opts.db ?? opts.dbPath);\n\t\t\t\tp.intro(\"codemem db init\");\n\t\t\t\tp.log.success(`Database ready: ${result.path}`);\n\t\t\t\tp.outro(`Size: ${result.sizeBytes.toLocaleString()} bytes`);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"vacuum\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Run VACUUM on the SQLite database\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.action((opts: { db?: string; dbPath?: string }) => {\n\t\t\t\tconst result = vacuumDatabase(opts.db ?? opts.dbPath);\n\t\t\t\tp.intro(\"codemem db vacuum\");\n\t\t\t\tp.log.success(`Vacuumed: ${result.path}`);\n\t\t\t\tp.outro(`Size: ${result.sizeBytes.toLocaleString()} bytes`);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"raw-events-status\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Show pending raw-event backlog by source stream\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"-n, --limit <n>\", \"max rows to show\", \"25\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; limit: string; json?: boolean }) => {\n\t\t\t\tconst result = getRawEventStatus(\n\t\t\t\t\topts.db ?? opts.dbPath,\n\t\t\t\t\tNumber.parseInt(opts.limit, 10) || 25,\n\t\t\t\t);\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem db raw-events-status\");\n\t\t\t\tp.log.info(\n\t\t\t\t\t`Totals: ${result.totals.pending.toLocaleString()} pending across ${result.totals.sessions.toLocaleString()} session(s)`,\n\t\t\t\t);\n\t\t\t\tif (result.items.length === 0) {\n\t\t\t\t\tp.outro(\"No pending raw events\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const item of result.items) {\n\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t`${item.source}:${item.stream_id} pending=${Math.max(0, item.last_received_event_seq - item.last_flushed_event_seq)} ` +\n\t\t\t\t\t\t\t`received=${item.last_received_event_seq} flushed=${item.last_flushed_event_seq} project=${item.project ?? \"\"}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tp.outro(\"done\");\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"raw-events-retry\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Requeue failed raw-event flush batches\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"-n, --limit <n>\", \"max failed batches to requeue\", \"25\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; limit: string }) => {\n\t\t\t\tconst result = retryRawEventFailures(\n\t\t\t\t\topts.db ?? opts.dbPath,\n\t\t\t\t\tNumber.parseInt(opts.limit, 10) || 25,\n\t\t\t\t);\n\t\t\t\tp.intro(\"codemem db raw-events-retry\");\n\t\t\t\tp.outro(`Requeued ${result.retried.toLocaleString()} failed batch(es)`);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"raw-events-gate\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Validate raw-event reliability thresholds (non-zero exit on failure)\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--min-flush-success-rate <rate>\", \"minimum flush success rate\", \"0.95\")\n\t\t\t.option(\"--max-dropped-event-rate <rate>\", \"maximum dropped event rate\", \"0.05\")\n\t\t\t.option(\"--min-session-boundary-accuracy <rate>\", \"minimum session boundary accuracy\", \"0.9\")\n\t\t\t.option(\"--window-hours <hours>\", \"lookback window in hours\", \"24\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tminFlushSuccessRate: string;\n\t\t\t\t\tmaxDroppedEventRate: string;\n\t\t\t\t\tminSessionBoundaryAccuracy: string;\n\t\t\t\t\twindowHours: string;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst result = rawEventsGate(opts.db ?? opts.dbPath, {\n\t\t\t\t\t\tminFlushSuccessRate: Number.parseFloat(opts.minFlushSuccessRate),\n\t\t\t\t\t\tmaxDroppedEventRate: Number.parseFloat(opts.maxDroppedEventRate),\n\t\t\t\t\t\tminSessionBoundaryAccuracy: Number.parseFloat(opts.minSessionBoundaryAccuracy),\n\t\t\t\t\t\twindowHours: Number.parseFloat(opts.windowHours),\n\t\t\t\t\t});\n\n\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\tif (!result.passed) process.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tp.intro(\"codemem db raw-events-gate\");\n\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`flush_success_rate: ${result.metrics.rates.flush_success_rate.toFixed(4)}`,\n\t\t\t\t\t\t\t`dropped_event_rate: ${result.metrics.rates.dropped_event_rate.toFixed(4)}`,\n\t\t\t\t\t\t\t`session_boundary_accuracy: ${result.metrics.rates.session_boundary_accuracy.toFixed(4)}`,\n\t\t\t\t\t\t\t`window_hours: ${result.metrics.window_hours ?? \"all\"}`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (result.passed) {\n\t\t\t\t\t\tp.outro(\"reliability gate passed\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor (const f of result.failures) {\n\t\t\t\t\t\t\tp.log.error(f);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.outro(\"reliability gate FAILED\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"rename-project\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Rename a project across sessions and related tables\")\n\t\t\t.argument(\"<old-name>\", \"current project name\")\n\t\t\t.argument(\"<new-name>\", \"new project name\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--apply\", \"apply changes (default is dry-run)\")\n\t\t\t.action(\n\t\t\t\t(\n\t\t\t\t\toldName: string,\n\t\t\t\t\tnewName: string,\n\t\t\t\t\topts: { db?: string; dbPath?: string; apply?: boolean },\n\t\t\t\t) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst dryRun = !opts.apply;\n\t\t\t\t\t\tconst escapedOld = oldName.replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\");\n\t\t\t\t\t\tconst suffixPattern = `%/${escapedOld}`;\n\t\t\t\t\t\tconst tables = [\"sessions\", \"raw_event_sessions\"] as const;\n\t\t\t\t\t\tconst counts: Record<string, number> = {};\n\t\t\t\t\t\tconst run = () => {\n\t\t\t\t\t\t\tfor (const table of tables) {\n\t\t\t\t\t\t\t\tconst rows = store.db\n\t\t\t\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\t\t\t`SELECT COUNT(*) as cnt FROM ${table} WHERE project = ? OR project LIKE ? ESCAPE '\\\\'`,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.get(oldName, suffixPattern) as { cnt: number };\n\t\t\t\t\t\t\t\tcounts[table] = rows.cnt;\n\t\t\t\t\t\t\t\tif (!dryRun && rows.cnt > 0) {\n\t\t\t\t\t\t\t\t\tstore.db\n\t\t\t\t\t\t\t\t\t\t.prepare(`UPDATE ${table} SET project = ? WHERE project = ?`)\n\t\t\t\t\t\t\t\t\t\t.run(newName, oldName);\n\t\t\t\t\t\t\t\t\tstore.db\n\t\t\t\t\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\t\t\t\t`UPDATE ${table} SET project = ? WHERE project LIKE ? ESCAPE '\\\\' AND project != ?`,\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t.run(newName, suffixPattern, newName);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\t\trun();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstore.db.transaction(run)();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst action = dryRun ? \"Will rename\" : \"Renamed\";\n\t\t\t\t\t\tp.intro(\"codemem db rename-project\");\n\t\t\t\t\t\tp.log.info(`${action} ${oldName} → ${newName}`);\n\t\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t`Sessions: ${counts.sessions}`,\n\t\t\t\t\t\t\t\t`Raw event sessions: ${counts.raw_event_sessions}`,\n\t\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\t\tp.outro(\"Pass --apply to execute\");\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t\t\t}\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"normalize-projects\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Normalize path-like project identifiers to their basename\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--apply\", \"apply changes (default is dry-run)\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; apply?: boolean }) => {\n\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\ttry {\n\t\t\t\t\tconst dryRun = !opts.apply;\n\t\t\t\t\tconst tables = [\"sessions\", \"raw_event_sessions\"] as const;\n\t\t\t\t\tconst rewrites: Map<string, string> = new Map();\n\t\t\t\t\tconst counts: Record<string, number> = {};\n\n\t\t\t\t\tconst run = () => {\n\t\t\t\t\t\tfor (const table of tables) {\n\t\t\t\t\t\t\tconst projects = store.db\n\t\t\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\t\t`SELECT DISTINCT project FROM ${table} WHERE project IS NOT NULL AND project LIKE '%/%'`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.all() as Array<{ project: string }>;\n\t\t\t\t\t\t\tlet updated = 0;\n\t\t\t\t\t\t\tfor (const row of projects) {\n\t\t\t\t\t\t\t\tconst basename = row.project.split(\"/\").pop() ?? row.project;\n\t\t\t\t\t\t\t\tif (basename !== row.project) {\n\t\t\t\t\t\t\t\t\trewrites.set(row.project, basename);\n\t\t\t\t\t\t\t\t\tif (!dryRun) {\n\t\t\t\t\t\t\t\t\t\tconst info = store.db\n\t\t\t\t\t\t\t\t\t\t\t.prepare(`UPDATE ${table} SET project = ? WHERE project = ?`)\n\t\t\t\t\t\t\t\t\t\t\t.run(basename, row.project);\n\t\t\t\t\t\t\t\t\t\tupdated += info.changes;\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tconst cnt = store.db\n\t\t\t\t\t\t\t\t\t\t\t.prepare(`SELECT COUNT(*) as cnt FROM ${table} WHERE project = ?`)\n\t\t\t\t\t\t\t\t\t\t\t.get(row.project) as { cnt: number };\n\t\t\t\t\t\t\t\t\t\tupdated += cnt.cnt;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcounts[table] = updated;\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\trun();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstore.db.transaction(run)();\n\t\t\t\t\t}\n\n\t\t\t\t\tp.intro(\"codemem db normalize-projects\");\n\t\t\t\t\tp.log.info(`Dry run: ${dryRun}`);\n\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`Sessions to update: ${counts.sessions}`,\n\t\t\t\t\t\t\t`Raw event sessions to update: ${counts.raw_event_sessions}`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t\tif (rewrites.size > 0) {\n\t\t\t\t\t\tp.log.info(\"Rewritten paths:\");\n\t\t\t\t\t\tfor (const [from, to] of [...rewrites.entries()].sort()) {\n\t\t\t\t\t\t\tp.log.message(` ${from} → ${to}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\tp.outro(\"Pass --apply to execute\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t\t}\n\t\t\t\t} finally {\n\t\t\t\t\tstore.close();\n\t\t\t\t}\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"size-report\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Show SQLite file size and major storage consumers\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"number of largest tables/indexes to show\", \"12\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action((opts: { db?: string; dbPath?: string; limit: string; json?: boolean }) => {\n\t\t\t\tconst dbPath = resolveDbPath(opts.db ?? opts.dbPath);\n\t\t\t\tconst db = connect(dbPath);\n\t\t\t\ttry {\n\t\t\t\t\tconst limit = Math.max(1, Number.parseInt(opts.limit, 10) || 12);\n\t\t\t\t\tconst fileSizeBytes = statSync(dbPath).size;\n\t\t\t\t\tconst pageInfo = db\n\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t\"SELECT page_count * page_size as total FROM pragma_page_count, pragma_page_size\",\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.get() as { total: number } | undefined;\n\t\t\t\t\tconst freePages = db.prepare(\"SELECT freelist_count FROM pragma_freelist_count\").get() as\n\t\t\t\t\t\t| { freelist_count: number }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tconst pageSize = db.prepare(\"PRAGMA page_size\").get() as\n\t\t\t\t\t\t| { page_size: number }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tconst tables = db\n\t\t\t\t\t\t.prepare(\n\t\t\t\t\t\t\t`SELECT name, SUM(pgsize) as size_bytes\n\t\t\t\t\t\t\t FROM dbstat\n\t\t\t\t\t\t\t GROUP BY name\n\t\t\t\t\t\t\t ORDER BY size_bytes DESC\n\t\t\t\t\t\t\t LIMIT ?`,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.all(limit) as Array<{ name: string; size_bytes: number }>;\n\n\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfile_size_bytes: fileSizeBytes,\n\t\t\t\t\t\t\t\t\tdb_size_bytes: pageInfo?.total ?? 0,\n\t\t\t\t\t\t\t\t\tfree_bytes: (freePages?.freelist_count ?? 0) * (pageSize?.page_size ?? 4096),\n\t\t\t\t\t\t\t\t\ttables: tables.map((t) => ({ name: t.name, size_bytes: t.size_bytes })),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tp.intro(\"codemem db size-report\");\n\t\t\t\t\tp.log.info(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`File size: ${formatBytes(fileSizeBytes)}`,\n\t\t\t\t\t\t\t`DB size: ${formatBytes(pageInfo?.total ?? 0)}`,\n\t\t\t\t\t\t\t`Free space: ${formatBytes((freePages?.freelist_count ?? 0) * (pageSize?.page_size ?? 4096))}`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t\tif (tables.length > 0) {\n\t\t\t\t\t\tp.log.info(\"Largest objects:\");\n\t\t\t\t\t\tfor (const t of tables) {\n\t\t\t\t\t\t\tp.log.message(` ${t.name.padEnd(40)} ${formatBytes(t.size_bytes).padStart(10)}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t} finally {\n\t\t\t\t\tdb.close();\n\t\t\t\t}\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"backfill-tags\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Populate tags_text for memories where tags are empty\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"max memories to check\")\n\t\t\t.option(\"--since <iso>\", \"only memories created at/after this ISO timestamp\")\n\t\t\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t\t\t.option(\"--all-projects\", \"backfill across all projects\")\n\t\t\t.option(\"--inactive\", \"include inactive memories\")\n\t\t\t.option(\"--dry-run\", \"preview updates without writing\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tsince?: string;\n\t\t\t\t\tproject?: string;\n\t\t\t\t\tallProjects?: boolean;\n\t\t\t\t\tinactive?: boolean;\n\t\t\t\t\tdryRun?: boolean;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\t\t\tconst project =\n\t\t\t\t\t\t\topts.allProjects === true\n\t\t\t\t\t\t\t\t? null\n\t\t\t\t\t\t\t\t: opts.project?.trim() ||\n\t\t\t\t\t\t\t\t\tprocess.env.CODEMEM_PROJECT?.trim() ||\n\t\t\t\t\t\t\t\t\tresolveProject(process.cwd(), null);\n\t\t\t\t\t\tconst result = backfillTagsText(store.db, {\n\t\t\t\t\t\t\tlimit,\n\t\t\t\t\t\t\tsince: opts.since ?? null,\n\t\t\t\t\t\t\tproject,\n\t\t\t\t\t\t\tactiveOnly: !opts.inactive,\n\t\t\t\t\t\t\tdryRun: opts.dryRun === true,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst action = opts.dryRun ? \"Would update\" : \"Updated\";\n\t\t\t\t\t\tp.intro(\"codemem db backfill-tags\");\n\t\t\t\t\t\tp.log.success(`${action} ${result.updated} memories (skipped ${result.skipped})`);\n\t\t\t\t\t\tp.outro(`Checked ${result.checked} memories`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"prune-observations\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Deactivate low-signal observations (does not delete rows)\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"max observations to check\")\n\t\t\t.option(\"--dry-run\", \"preview deactivations without writing\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tdryRun?: boolean;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\t\t\tconst result = deactivateLowSignalObservations(\n\t\t\t\t\t\t\tstore.db,\n\t\t\t\t\t\t\tlimit ?? null,\n\t\t\t\t\t\t\topts.dryRun === true,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst action = opts.dryRun ? \"Would deactivate\" : \"Deactivated\";\n\t\t\t\t\t\tp.intro(\"codemem db prune-observations\");\n\t\t\t\t\t\tp.outro(`${action} ${result.deactivated} of ${result.checked} observations`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t)\n\t.addCommand(\n\t\tnew Command(\"prune-memories\")\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(\"Deactivate low-signal memories across selected kinds\")\n\t\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t\t.option(\"--limit <n>\", \"max memories to check\")\n\t\t\t.option(\"--kinds <csv>\", \"comma-separated memory kinds (default set when omitted)\")\n\t\t\t.option(\"--dry-run\", \"preview deactivations without writing\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\t(opts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tkinds?: string;\n\t\t\t\t\tdryRun?: boolean;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t}) => {\n\t\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\t\t\tconst kinds = parseKindsCsv(opts.kinds);\n\t\t\t\t\t\tconst result = deactivateLowSignalMemories(store.db, {\n\t\t\t\t\t\t\tkinds,\n\t\t\t\t\t\t\tlimit: limit ?? null,\n\t\t\t\t\t\t\tdryRun: opts.dryRun === true,\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst action = opts.dryRun ? \"Would deactivate\" : \"Deactivated\";\n\t\t\t\t\t\tp.intro(\"codemem db prune-memories\");\n\t\t\t\t\t\tp.outro(`${action} ${result.deactivated} of ${result.checked} memories`);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tstore.close();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t);\n","import * as p from \"@clack/prompts\";\nimport { backfillVectors, MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction parseOptionalPositiveInt(value: string | undefined): number | undefined {\n\tif (!value) return undefined;\n\tconst parsed = Number.parseInt(value, 10);\n\tif (!Number.isFinite(parsed) || parsed <= 0) {\n\t\tthrow new Error(`invalid positive integer: ${value}`);\n\t}\n\treturn parsed;\n}\n\nexport function resolveEmbedProjectScope(\n\tcwd: string,\n\tprojectOpt: string | undefined,\n\tallProjects: boolean | undefined,\n): string | null {\n\tif (allProjects === true) return null;\n\tconst explicit = projectOpt?.trim();\n\tif (explicit) return explicit;\n\tconst envProject = process.env.CODEMEM_PROJECT?.trim();\n\tif (envProject) return envProject;\n\treturn resolveProject(cwd, null);\n}\n\nexport const embedCommand = new Command(\"embed\")\n\t.configureHelp(helpStyle)\n\t.description(\"Backfill semantic embeddings\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--limit <n>\", \"max memories to check\")\n\t.option(\"--since <iso>\", \"only memories created at/after this ISO timestamp\")\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"embed across all projects\")\n\t.option(\"--inactive\", \"include inactive memories\")\n\t.option(\"--dry-run\", \"preview work without writing vectors\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action(\n\t\tasync (opts: {\n\t\t\tdb?: string;\n\t\t\tdbPath?: string;\n\t\t\tlimit?: string;\n\t\t\tsince?: string;\n\t\t\tproject?: string;\n\t\t\tallProjects?: boolean;\n\t\t\tinactive?: boolean;\n\t\t\tdryRun?: boolean;\n\t\t\tjson?: boolean;\n\t\t}) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = parseOptionalPositiveInt(opts.limit);\n\t\t\t\tconst project = resolveEmbedProjectScope(process.cwd(), opts.project, opts.allProjects);\n\n\t\t\t\tconst result = await backfillVectors(store.db, {\n\t\t\t\t\tlimit,\n\t\t\t\t\tsince: opts.since ?? null,\n\t\t\t\t\tproject,\n\t\t\t\t\tactiveOnly: !opts.inactive,\n\t\t\t\t\tdryRun: opts.dryRun === true,\n\t\t\t\t});\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst action = opts.dryRun ? \"Would embed\" : \"Embedded\";\n\t\t\t\tp.intro(\"codemem embed\");\n\t\t\t\tp.log.success(\n\t\t\t\t\t`${action} ${result.embedded} vectors (${result.inserted} inserted, ${result.skipped} skipped)`,\n\t\t\t\t);\n\t\t\t\tp.outro(`Checked ${result.checked} memories`);\n\t\t\t} catch (error) {\n\t\t\t\tp.log.error(error instanceof Error ? error.message : String(error));\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n","import { MemoryStore, resolveDbPath, stripPrivateObj } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nconst SESSION_ID_KEYS = [\n\t\"session_stream_id\",\n\t\"session_id\",\n\t\"stream_id\",\n\t\"opencode_session_id\",\n] as const;\n\nfunction resolveSessionStreamId(payload: Record<string, unknown>): string | null {\n\tconst values = new Map<string, string>();\n\tfor (const key of SESSION_ID_KEYS) {\n\t\tconst value = payload[key];\n\t\tif (typeof value !== \"string\") continue;\n\t\tconst text = value.trim();\n\t\tif (text) values.set(key, text);\n\t}\n\tif (values.size === 0) return null;\n\tconst unique = new Set(values.values());\n\tif (unique.size > 1) throw new Error(\"conflicting session id fields\");\n\tfor (const key of SESSION_ID_KEYS) {\n\t\tconst value = values.get(key);\n\t\tif (value) return value;\n\t}\n\treturn null;\n}\n\nasync function readStdinJson(): Promise<Record<string, unknown>> {\n\tconst chunks: Buffer[] = [];\n\tfor await (const chunk of process.stdin) {\n\t\tchunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n\t}\n\tconst raw = Buffer.concat(chunks).toString(\"utf-8\").trim();\n\tif (!raw) throw new Error(\"stdin JSON required\");\n\tconst parsed = JSON.parse(raw) as unknown;\n\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(\"payload must be an object\");\n\t}\n\treturn parsed as Record<string, unknown>;\n}\n\nexport const enqueueRawEventCommand = new Command(\"enqueue-raw-event\")\n\t.configureHelp(helpStyle)\n\t.description(\"Enqueue one raw event from stdin into the durable queue\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.action(async (opts: { db?: string; dbPath?: string }) => {\n\t\tconst payload = await readStdinJson();\n\t\tconst sessionId = resolveSessionStreamId(payload);\n\t\tif (!sessionId) throw new Error(\"session id required\");\n\t\tif (sessionId.startsWith(\"msg_\")) throw new Error(\"invalid session id\");\n\n\t\tconst eventType = typeof payload.event_type === \"string\" ? payload.event_type.trim() : \"\";\n\t\tif (!eventType) throw new Error(\"event_type required\");\n\n\t\tconst cwd = typeof payload.cwd === \"string\" ? payload.cwd : null;\n\t\tconst project = typeof payload.project === \"string\" ? payload.project : null;\n\t\tconst startedAt = typeof payload.started_at === \"string\" ? payload.started_at : null;\n\t\tconst tsWallMs = Number.isFinite(Number(payload.ts_wall_ms))\n\t\t\t? Math.floor(Number(payload.ts_wall_ms))\n\t\t\t: null;\n\t\tconst tsMonoMs = Number.isFinite(Number(payload.ts_mono_ms))\n\t\t\t? Number(payload.ts_mono_ms)\n\t\t\t: null;\n\t\tconst eventId = typeof payload.event_id === \"string\" ? payload.event_id.trim() : \"\";\n\t\tconst eventPayload =\n\t\t\tpayload.payload && typeof payload.payload === \"object\" && !Array.isArray(payload.payload)\n\t\t\t\t? (stripPrivateObj(payload.payload) as Record<string, unknown>)\n\t\t\t\t: {};\n\n\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\ttry {\n\t\t\tstore.updateRawEventSessionMeta({\n\t\t\t\topencodeSessionId: sessionId,\n\t\t\t\tsource: \"opencode\",\n\t\t\t\tcwd,\n\t\t\t\tproject,\n\t\t\t\tstartedAt,\n\t\t\t\tlastSeenTsWallMs: tsWallMs,\n\t\t\t});\n\t\t\tstore.recordRawEventsBatch(sessionId, [\n\t\t\t\t{\n\t\t\t\t\tevent_id: eventId,\n\t\t\t\t\tevent_type: eventType,\n\t\t\t\t\tpayload: eventPayload,\n\t\t\t\t\tts_wall_ms: tsWallMs,\n\t\t\t\t\tts_mono_ms: tsMonoMs,\n\t\t\t\t},\n\t\t\t]);\n\t\t} finally {\n\t\t\tstore.close();\n\t\t}\n\t});\n","import { writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { exportMemories, resolveDbPath } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction expandUserPath(value: string): string {\n\treturn value.startsWith(\"~/\") ? join(homedir(), value.slice(2)) : value;\n}\n\nexport const exportMemoriesCommand = new Command(\"export-memories\")\n\t.configureHelp(helpStyle)\n\t.description(\"Export memories to a JSON file for sharing or backup\")\n\t.argument(\"<output>\", \"output file path (use '-' for stdout)\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--project <project>\", \"filter by project (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"export all projects\")\n\t.option(\"--include-inactive\", \"include deactivated memories\")\n\t.option(\"--since <iso>\", \"only export memories created after this ISO timestamp\")\n\t.action(\n\t\t(\n\t\t\toutput: string,\n\t\t\topts: {\n\t\t\t\tdb?: string;\n\t\t\t\tdbPath?: string;\n\t\t\t\tproject?: string;\n\t\t\t\tallProjects?: boolean;\n\t\t\t\tincludeInactive?: boolean;\n\t\t\t\tsince?: string;\n\t\t\t},\n\t\t) => {\n\t\t\tconst payload = exportMemories({\n\t\t\t\tdbPath: resolveDbPath(opts.db ?? opts.dbPath),\n\t\t\t\tproject: opts.project,\n\t\t\t\tallProjects: opts.allProjects,\n\t\t\t\tincludeInactive: opts.includeInactive,\n\t\t\t\tsince: opts.since,\n\t\t\t});\n\t\t\tconst text = `${JSON.stringify(payload, null, 2)}\\n`;\n\t\t\tif (output === \"-\") {\n\t\t\t\tprocess.stdout.write(text);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst outputPath = expandUserPath(output);\n\t\t\twriteFileSync(outputPath, text, \"utf8\");\n\t\t\tp.intro(\"codemem export-memories\");\n\t\t\tp.log.success(\n\t\t\t\t[\n\t\t\t\t\t`Output: ${outputPath}`,\n\t\t\t\t\t`Sessions: ${payload.sessions.length.toLocaleString()}`,\n\t\t\t\t\t`Memories: ${payload.memory_items.length.toLocaleString()}`,\n\t\t\t\t\t`Summaries: ${payload.session_summaries.length.toLocaleString()}`,\n\t\t\t\t\t`Prompts: ${payload.user_prompts.length.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tp.outro(\"done\");\n\t\t},\n\t);\n","import * as p from \"@clack/prompts\";\nimport type { ExportPayload } from \"@codemem/core\";\nimport { importMemories, readImportPayload, resolveDbPath } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const importMemoriesCommand = new Command(\"import-memories\")\n\t.configureHelp(helpStyle)\n\t.description(\"Import memories from an exported JSON file\")\n\t.argument(\"<inputFile>\", \"input JSON file (use '-' for stdin)\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--remap-project <path>\", \"remap all projects to this path on import\")\n\t.option(\"--dry-run\", \"preview import without writing\")\n\t.action(\n\t\t(\n\t\t\tinputFile: string,\n\t\t\topts: { db?: string; dbPath?: string; remapProject?: string; dryRun?: boolean },\n\t\t) => {\n\t\t\tlet payload: ExportPayload;\n\t\t\ttry {\n\t\t\t\tpayload = readImportPayload(inputFile);\n\t\t\t} catch (error) {\n\t\t\t\tp.log.error(error instanceof Error ? error.message : \"Invalid import file\");\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tp.intro(\"codemem import-memories\");\n\t\t\tp.log.info(\n\t\t\t\t[\n\t\t\t\t\t`Export version: ${payload.version}`,\n\t\t\t\t\t`Exported at: ${payload.exported_at}`,\n\t\t\t\t\t`Sessions: ${payload.sessions.length.toLocaleString()}`,\n\t\t\t\t\t`Memories: ${payload.memory_items.length.toLocaleString()}`,\n\t\t\t\t\t`Summaries: ${payload.session_summaries.length.toLocaleString()}`,\n\t\t\t\t\t`Prompts: ${payload.user_prompts.length.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\n\t\t\tconst result = importMemories(payload, {\n\t\t\t\tdbPath: resolveDbPath(opts.db ?? opts.dbPath),\n\t\t\t\tremapProject: opts.remapProject,\n\t\t\t\tdryRun: opts.dryRun,\n\t\t\t});\n\n\t\t\tif (result.dryRun) {\n\t\t\t\tp.outro(\"dry run complete\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tp.log.success(\n\t\t\t\t[\n\t\t\t\t\t`Imported sessions: ${result.sessions.toLocaleString()}`,\n\t\t\t\t\t`Imported prompts: ${result.user_prompts.toLocaleString()}`,\n\t\t\t\t\t`Imported memories: ${result.memory_items.toLocaleString()}`,\n\t\t\t\t\t`Imported summaries: ${result.session_summaries.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\t\t\tp.outro(\"done\");\n\t\t},\n\t);\n","import { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const mcpCommand = new Command(\"mcp\")\n\t.configureHelp(helpStyle)\n\t.description(\"Start the MCP stdio server\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.action(async (opts: { db?: string; dbPath?: string }) => {\n\t\tconst dbPath = opts.db ?? opts.dbPath;\n\t\tif (dbPath) process.env.CODEMEM_DB = dbPath;\n\t\t// Dynamic import — MCP server is its own entry point\n\t\tawait import(\"@codemem/mcp\");\n\t});\n","/**\n * Memory management CLI commands — show, forget, remember.\n *\n * Ports codemem/commands/memory_cmds.py (show_cmd, forget_cmd, remember_cmd).\n * Compact and inject are deferred — compact requires the summarizer pipeline,\n * and inject is just pack_text output which the existing pack command covers.\n */\n\nimport * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction collectWorkingSetFile(value: string, previous: string[]): string[] {\n\treturn [...previous, value];\n}\n\n/** Parse a strict positive integer, rejecting prefixes like \"12abc\". */\nfunction parseStrictPositiveId(value: string): number | null {\n\tif (!/^\\d+$/.test(value.trim())) return null;\n\tconst n = Number(value.trim());\n\treturn Number.isFinite(n) && n >= 1 && Number.isInteger(n) ? n : null;\n}\n\nfunction showMemoryAction(idStr: string, opts: { db?: string; dbPath?: string }): void {\n\tconst memoryId = parseStrictPositiveId(idStr);\n\tif (memoryId === null) {\n\t\tp.log.error(`Invalid memory ID: ${idStr}`);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\ttry {\n\t\tconst item = store.get(memoryId);\n\t\tif (!item) {\n\t\t\tp.log.error(`Memory ${memoryId} not found`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(JSON.stringify(item, null, 2));\n\t} finally {\n\t\tstore.close();\n\t}\n}\n\nfunction forgetMemoryAction(idStr: string, opts: { db?: string; dbPath?: string }): void {\n\tconst memoryId = parseStrictPositiveId(idStr);\n\tif (memoryId === null) {\n\t\tp.log.error(`Invalid memory ID: ${idStr}`);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\ttry {\n\t\tstore.forget(memoryId);\n\t\tp.log.success(`Memory ${memoryId} marked inactive`);\n\t} finally {\n\t\tstore.close();\n\t}\n}\n\ninterface RememberMemoryOptions {\n\tkind: string;\n\ttitle: string;\n\tbody: string;\n\ttags?: string[];\n\tproject?: string;\n\tdb?: string;\n\tdbPath?: string;\n}\n\nasync function rememberMemoryAction(opts: RememberMemoryOptions): Promise<void> {\n\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\tlet sessionId: number | null = null;\n\ttry {\n\t\tconst project = resolveProject(process.cwd(), opts.project ?? null);\n\t\tsessionId = store.startSession({\n\t\t\tcwd: process.cwd(),\n\t\t\tproject,\n\t\t\tuser: process.env.USER ?? \"unknown\",\n\t\t\ttoolVersion: \"manual\",\n\t\t\tmetadata: { manual: true },\n\t\t});\n\t\tconst memId = store.remember(sessionId, opts.kind, opts.title, opts.body, 0.5, opts.tags);\n\t\tawait store.flushPendingVectorWrites();\n\t\tstore.endSession(sessionId, { manual: true });\n\t\tp.log.success(`Stored memory ${memId}`);\n\t} catch (err) {\n\t\tif (sessionId !== null) {\n\t\t\ttry {\n\t\t\t\tstore.endSession(sessionId, { manual: true, error: true });\n\t\t\t} catch {\n\t\t\t\t// ignore — already in error path\n\t\t\t}\n\t\t}\n\t\tthrow err;\n\t} finally {\n\t\tstore.close();\n\t}\n}\n\nfunction createShowMemoryCommand(): Command {\n\treturn new Command(\"show\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Print a memory item as JSON\")\n\t\t.argument(\"<id>\", \"memory ID\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(showMemoryAction);\n}\n\nfunction createForgetMemoryCommand(): Command {\n\treturn new Command(\"forget\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Deactivate a memory item\")\n\t\t.argument(\"<id>\", \"memory ID\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(forgetMemoryAction);\n}\n\nfunction createRememberMemoryCommand(): Command {\n\treturn new Command(\"remember\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Manually add a memory item\")\n\t\t.requiredOption(\"-k, --kind <kind>\", \"memory kind (discovery, decision, feature, bugfix, etc.)\")\n\t\t.requiredOption(\"-t, --title <title>\", \"memory title\")\n\t\t.requiredOption(\"-b, --body <body>\", \"memory body text\")\n\t\t.option(\"--tags <tags...>\", \"tags (space-separated)\")\n\t\t.option(\"--project <project>\", \"project name (defaults to git repo root)\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(rememberMemoryAction);\n}\n\nfunction createInjectMemoryCommand(): Command {\n\treturn new Command(\"inject\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Build raw memory context text for manual prompt injection\")\n\t\t.argument(\"<context>\", \"context string to search for\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"-n, --limit <n>\", \"max items\", \"10\")\n\t\t.option(\"--budget <tokens>\", \"token budget\")\n\t\t.option(\"--token-budget <tokens>\", \"token budget\")\n\t\t.option(\n\t\t\t\"--working-set-file <path>\",\n\t\t\t\"recently modified file path used as ranking hint\",\n\t\t\tcollectWorkingSetFile,\n\t\t\t[],\n\t\t)\n\t\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t\t.option(\"--all-projects\", \"search across all projects\")\n\t\t.allowUnknownOption(true)\n\t\t.allowExcessArguments(true)\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tcontext: string,\n\t\t\t\topts: {\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tlimit?: string;\n\t\t\t\t\tbudget?: string;\n\t\t\t\t\ttokenBudget?: string;\n\t\t\t\t\tworkingSetFile?: string[];\n\t\t\t\t\tproject?: string;\n\t\t\t\t\tallProjects?: boolean;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\ttry {\n\t\t\t\t\tconst limit = Number.parseInt(opts.limit ?? \"10\", 10) || 10;\n\t\t\t\t\tconst budgetRaw = opts.tokenBudget ?? opts.budget;\n\t\t\t\t\tconst budget = budgetRaw ? Number.parseInt(budgetRaw, 10) : undefined;\n\t\t\t\t\tconst filters: { project?: string; working_set_paths?: string[] } = {};\n\t\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t\t}\n\t\t\t\t\tif ((opts.workingSetFile?.length ?? 0) > 0) {\n\t\t\t\t\t\tfilters.working_set_paths = opts.workingSetFile;\n\t\t\t\t\t}\n\t\t\t\t\tconst pack = await store.buildMemoryPackAsync(context, limit, budget, filters);\n\t\t\t\t\tconsole.log(pack.pack_text ?? \"\");\n\t\t\t\t} finally {\n\t\t\t\t\tstore.close();\n\t\t\t\t}\n\t\t\t},\n\t\t);\n}\n\nfunction createCompactMemoryCommand(): Command {\n\treturn new Command(\"compact\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Deferred command guidance for memory compaction\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--session-id <id>\", \"session ID\")\n\t\t.option(\"--limit <n>\", \"max sessions to compact\", \"10\")\n\t\t.allowUnknownOption(true)\n\t\t.allowExcessArguments(true)\n\t\t.action(() => {\n\t\t\tp.log.warn(\"`codemem memory compact` is not implemented in the TypeScript CLI yet.\");\n\t\t\tp.log.info(\n\t\t\t\t\"Current workaround: rely on automatic ingestion; for manual context use `codemem memory inject <context>`.\",\n\t\t\t);\n\t\t\tprocess.exitCode = 2;\n\t\t});\n}\n\nexport const showMemoryCommand = createShowMemoryCommand();\nexport const forgetMemoryCommand = createForgetMemoryCommand();\nexport const rememberMemoryCommand = createRememberMemoryCommand();\n\nexport const memoryCommand = new Command(\"memory\")\n\t.configureHelp(helpStyle)\n\t.description(\"Memory item management\");\n\nmemoryCommand.addCommand(createShowMemoryCommand());\nmemoryCommand.addCommand(createForgetMemoryCommand());\nmemoryCommand.addCommand(createRememberMemoryCommand());\nmemoryCommand.addCommand(createInjectMemoryCommand());\nmemoryCommand.addCommand(createCompactMemoryCommand());\n","import * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction collectWorkingSetFile(value: string, previous: string[]): string[] {\n\treturn [...previous, value];\n}\n\nexport const packCommand = new Command(\"pack\")\n\t.configureHelp(helpStyle)\n\t.description(\"Build a context-aware memory pack\")\n\t.argument(\"<context>\", \"context string to search for\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"-n, --limit <n>\", \"max items\", \"10\")\n\t.option(\"--budget <tokens>\", \"token budget\")\n\t.option(\"--token-budget <tokens>\", \"token budget\")\n\t.option(\n\t\t\"--working-set-file <path>\",\n\t\t\"recently modified file path used as ranking hint\",\n\t\tcollectWorkingSetFile,\n\t\t[],\n\t)\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"search across all projects\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action(\n\t\tasync (\n\t\t\tcontext: string,\n\t\t\topts: {\n\t\t\t\tdb?: string;\n\t\t\t\tdbPath?: string;\n\t\t\t\tlimit: string;\n\t\t\t\tbudget?: string;\n\t\t\t\ttokenBudget?: string;\n\t\t\t\tworkingSetFile?: string[];\n\t\t\t\tproject?: string;\n\t\t\t\tallProjects?: boolean;\n\t\t\t\tjson?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = Number.parseInt(opts.limit, 10) || 10;\n\t\t\t\tconst budgetRaw = opts.tokenBudget ?? opts.budget;\n\t\t\t\tconst budget = budgetRaw ? Number.parseInt(budgetRaw, 10) : undefined;\n\t\t\t\tconst filters: { project?: string; working_set_paths?: string[] } = {};\n\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t}\n\t\t\t\tif ((opts.workingSetFile?.length ?? 0) > 0) {\n\t\t\t\t\tfilters.working_set_paths = opts.workingSetFile;\n\t\t\t\t}\n\t\t\t\tconst result = await store.buildMemoryPackAsync(context, limit, budget, filters);\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(`Memory pack for \"${context}\"`);\n\n\t\t\t\tif (result.items.length === 0) {\n\t\t\t\t\tp.log.warn(\"No relevant memories found.\");\n\t\t\t\t\tp.outro(\"done\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst m = result.metrics;\n\t\t\t\tp.log.info(\n\t\t\t\t\t`${m.total_items} items, ~${m.pack_tokens} tokens` +\n\t\t\t\t\t\t(m.fallback_used ? \" (fallback)\" : \"\") +\n\t\t\t\t\t\t` [fts:${m.sources.fts} sem:${m.sources.semantic} fuzzy:${m.sources.fuzzy}]`,\n\t\t\t\t);\n\n\t\t\t\tfor (const item of result.items) {\n\t\t\t\t\tp.log.step(`#${item.id} ${item.kind} ${item.title}`);\n\t\t\t\t}\n\n\t\t\t\tp.note(result.pack_text, \"pack_text\");\n\n\t\t\t\tp.outro(\"done\");\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n","import { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const recentCommand = new Command(\"recent\")\n\t.configureHelp(helpStyle)\n\t.description(\"Show recent memories\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--limit <n>\", \"max results\", \"5\")\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"search across all projects\")\n\t.option(\"--kind <kind>\", \"filter by memory kind\")\n\t.action(\n\t\t(opts: {\n\t\t\tdb?: string;\n\t\t\tdbPath?: string;\n\t\t\tlimit: string;\n\t\t\tproject?: string;\n\t\t\tallProjects?: boolean;\n\t\t\tkind?: string;\n\t\t}) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = Math.max(1, Number.parseInt(opts.limit, 10) || 5);\n\t\t\t\tconst filters: { kind?: string; project?: string } = {};\n\t\t\t\tif (opts.kind) filters.kind = opts.kind;\n\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t}\n\t\t\t\tconst items = store.recent(limit, filters);\n\t\t\t\tfor (const item of items) {\n\t\t\t\t\tconsole.log(`#${item.id} [${item.kind}] ${item.title}`);\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n","import * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath, resolveProject } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const searchCommand = new Command(\"search\")\n\t.configureHelp(helpStyle)\n\t.description(\"Search memories by query\")\n\t.argument(\"<query>\", \"search query\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"-n, --limit <n>\", \"max results\", \"5\")\n\t.option(\"--project <project>\", \"project identifier (defaults to git repo root)\")\n\t.option(\"--all-projects\", \"search across all projects\")\n\t.option(\"--kind <kind>\", \"filter by memory kind\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action(\n\t\t(\n\t\t\tquery: string,\n\t\t\topts: {\n\t\t\t\tdb?: string;\n\t\t\t\tdbPath?: string;\n\t\t\t\tlimit: string;\n\t\t\t\tproject?: string;\n\t\t\t\tallProjects?: boolean;\n\t\t\t\tkind?: string;\n\t\t\t\tjson?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst limit = Math.max(1, Number.parseInt(opts.limit, 10) || 5);\n\t\t\t\tconst filters: { kind?: string; project?: string } = {};\n\t\t\t\tif (opts.kind) filters.kind = opts.kind;\n\t\t\t\tif (!opts.allProjects) {\n\t\t\t\t\tconst defaultProject = process.env.CODEMEM_PROJECT?.trim() || null;\n\t\t\t\t\tconst project = defaultProject || resolveProject(process.cwd(), opts.project ?? null);\n\t\t\t\t\tif (project) filters.project = project;\n\t\t\t\t}\n\t\t\t\tconst results = store.search(query, limit, filters);\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(results, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (results.length === 0) {\n\t\t\t\t\tp.log.warn(\"No results found.\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(`${results.length} result(s) for \"${query}\"`);\n\n\t\t\t\tfor (const item of results) {\n\t\t\t\t\tconst score = item.score.toFixed(3);\n\t\t\t\t\tconst age = timeSince(item.created_at);\n\t\t\t\t\tconst preview =\n\t\t\t\t\t\titem.body_text.length > 120 ? `${item.body_text.slice(0, 120)}…` : item.body_text;\n\n\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t[`#${item.id} ${item.kind} ${age} [${score}]`, item.title, preview].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tp.outro(\"done\");\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t},\n\t);\n\nfunction timeSince(isoDate: string): string {\n\tconst ms = Date.now() - new Date(isoDate).getTime();\n\tconst days = Math.floor(ms / 86_400_000);\n\tif (days === 0) return \"today\";\n\tif (days === 1) return \"1d ago\";\n\tif (days < 30) return `${days}d ago`;\n\tconst months = Math.floor(days / 30);\n\treturn `${months}mo ago`;\n}\n","export type ServeMode = \"start\" | \"stop\" | \"restart\";\n\nexport type ServeAction = ServeMode | undefined;\n\nexport interface LegacyServeOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost: string;\n\tport: string;\n\tbackground?: boolean;\n\tforeground?: boolean;\n\tstop?: boolean;\n\trestart?: boolean;\n}\n\nexport interface StartServeOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost: string;\n\tport: string;\n\tforeground?: boolean;\n}\n\nexport interface StopRestartServeOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost: string;\n\tport: string;\n}\n\nexport interface ResolvedServeInvocation {\n\tmode: ServeMode;\n\tdbPath: string | null;\n\thost: string;\n\tport: number;\n\tbackground: boolean;\n}\n\nfunction parsePort(rawPort: string): number {\n\tconst port = Number.parseInt(rawPort, 10);\n\tif (!Number.isFinite(port) || port < 1 || port > 65535) {\n\t\tthrow new Error(`Invalid port: ${rawPort}`);\n\t}\n\treturn port;\n}\n\nexport function resolveLegacyServeInvocation(opts: LegacyServeOptions): ResolvedServeInvocation {\n\tif (opts.stop && opts.restart) {\n\t\tthrow new Error(\"Use only one of --stop or --restart\");\n\t}\n\tif (opts.foreground && opts.background) {\n\t\tthrow new Error(\"Use only one of --background or --foreground\");\n\t}\n\tconst dbPath = opts.db ?? opts.dbPath ?? null;\n\treturn {\n\t\tmode: opts.stop ? \"stop\" : opts.restart ? \"restart\" : \"start\",\n\t\tdbPath,\n\t\thost: opts.host,\n\t\tport: parsePort(opts.port),\n\t\tbackground: opts.restart ? true : opts.background ? true : false,\n\t};\n}\n\nexport function resolveServeInvocation(\n\taction: ServeAction,\n\topts: LegacyServeOptions,\n): ResolvedServeInvocation {\n\tif (action === undefined) {\n\t\treturn resolveLegacyServeInvocation(opts);\n\t}\n\tif (opts.stop || opts.restart) {\n\t\tthrow new Error(\"Do not combine lifecycle flags with a serve action\");\n\t}\n\tif (action === \"start\") {\n\t\treturn resolveStartServeInvocation(opts);\n\t}\n\treturn resolveStopRestartInvocation(action, opts);\n}\n\nexport function resolveStartServeInvocation(opts: StartServeOptions): ResolvedServeInvocation {\n\tconst dbPath = opts.db ?? opts.dbPath ?? null;\n\treturn {\n\t\tmode: \"start\",\n\t\tdbPath,\n\t\thost: opts.host,\n\t\tport: parsePort(opts.port),\n\t\tbackground: !opts.foreground,\n\t};\n}\n\nexport function resolveStopRestartInvocation(\n\tmode: \"stop\" | \"restart\",\n\topts: StopRestartServeOptions,\n): ResolvedServeInvocation {\n\tconst dbPath = opts.db ?? opts.dbPath ?? null;\n\treturn {\n\t\tmode,\n\t\tdbPath,\n\t\thost: opts.host,\n\t\tport: parsePort(opts.port),\n\t\tbackground: mode === \"restart\",\n\t};\n}\n","import { spawn, spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport {\n\tisEmbeddingDisabled,\n\ttype MemoryStore,\n\tObserverClient,\n\tRawEventSweeper,\n\treadCodememConfigFile,\n\treadCoordinatorSyncConfig,\n\tresolveDbPath,\n\trunSyncDaemon,\n} from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\nimport {\n\ttype LegacyServeOptions,\n\ttype ResolvedServeInvocation,\n\tresolveServeInvocation,\n\ttype ServeAction,\n} from \"./serve-invocation.js\";\n\ninterface ViewerPidRecord {\n\tpid: number;\n\thost: string;\n\tport: number;\n}\n\nexport function extractViewerPid(payload: unknown): number | null {\n\tif (!payload || typeof payload !== \"object\") return null;\n\tconst rawPid = (payload as { viewer_pid?: unknown }).viewer_pid;\n\tif (typeof rawPid !== \"number\" || !Number.isFinite(rawPid) || rawPid <= 0) return null;\n\treturn Math.trunc(rawPid);\n}\n\nexport function isLocalHost(host: string): boolean {\n\tconst normalized = host.trim().toLowerCase();\n\treturn (\n\t\tnormalized === \"127.0.0.1\" ||\n\t\tnormalized === \"localhost\" ||\n\t\tnormalized === \"::1\" ||\n\t\tnormalized === \"0.0.0.0\" ||\n\t\tnormalized === \"::\"\n\t);\n}\n\nexport function isLikelyViewerCommand(command: string): boolean {\n\tconst lowered = command.toLowerCase();\n\tif (!/\\bserve\\s+start\\b/.test(lowered)) return false;\n\treturn (\n\t\tlowered.includes(\"codemem\") ||\n\t\tlowered.includes(\"packages/cli/dist/index.js\") ||\n\t\tlowered.includes(\"/cli/dist/index.js\")\n\t);\n}\n\nexport function pickViewerPidCandidate(\n\tstatsPid: number | null,\n\tlistenerPid: number | null,\n): number | null {\n\tif (statsPid && listenerPid && statsPid !== listenerPid) return null;\n\treturn statsPid ?? listenerPid ?? null;\n}\n\nfunction lookupListeningPid(host: string, port: number): number | null {\n\tif (!isLocalHost(host)) return null;\n\tconst result = spawnSync(\"lsof\", [\"-nP\", `-iTCP:${port}`, \"-sTCP:LISTEN\", \"-t\"], {\n\t\tencoding: \"utf-8\",\n\t\ttimeout: 1000,\n\t});\n\tif (result.status !== 0) return null;\n\tconst first = (result.stdout || \"\")\n\t\t.split(/\\r?\\n/)\n\t\t.map((line) => line.trim())\n\t\t.find((line) => line.length > 0);\n\tif (!first) return null;\n\tconst parsed = Number.parseInt(first, 10);\n\treturn Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction readProcessCommand(pid: number): string | null {\n\tconst result = spawnSync(\"ps\", [\"-p\", String(pid), \"-o\", \"command=\"], {\n\t\tencoding: \"utf-8\",\n\t\ttimeout: 1000,\n\t});\n\tif (result.status !== 0) return null;\n\tconst cmd = (result.stdout || \"\").trim();\n\treturn cmd.length > 0 ? cmd : null;\n}\n\nfunction isTrustedViewerPid(\n\tpid: number,\n\ttarget: { host: string; port: number },\n\tlistenerPid: number | null,\n): boolean {\n\tif (!isLocalHost(target.host)) return false;\n\tif (listenerPid && listenerPid !== pid) return false;\n\tconst command = readProcessCommand(pid);\n\tif (!command) return false;\n\treturn isLikelyViewerCommand(command);\n}\n\nfunction pidFilePath(dbPath: string): string {\n\treturn join(dirname(dbPath), \"viewer.pid\");\n}\n\nfunction readViewerPidRecord(dbPath: string): ViewerPidRecord | null {\n\tconst pidPath = pidFilePath(dbPath);\n\tif (!existsSync(pidPath)) return null;\n\tconst raw = readFileSync(pidPath, \"utf-8\").trim();\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as Partial<ViewerPidRecord>;\n\t\tif (\n\t\t\ttypeof parsed.pid === \"number\" &&\n\t\t\ttypeof parsed.host === \"string\" &&\n\t\t\ttypeof parsed.port === \"number\"\n\t\t) {\n\t\t\treturn { pid: parsed.pid, host: parsed.host, port: parsed.port };\n\t\t}\n\t} catch {\n\t\tconst pid = Number.parseInt(raw, 10);\n\t\tif (Number.isFinite(pid) && pid > 0) {\n\t\t\treturn { pid, host: \"127.0.0.1\", port: 38888 };\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction isProcessRunning(pid: number): boolean {\n\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function respondsLikeCodememViewer(record: ViewerPidRecord): Promise<boolean> {\n\ttry {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), 1000);\n\t\tconst res = await fetch(`http://${record.host}:${record.port}/api/stats`, {\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tclearTimeout(timer);\n\t\treturn res.ok;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nasync function lookupViewerPidFromStats(host: string, port: number): Promise<number | null> {\n\ttry {\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), 1000);\n\t\tconst res = await fetch(`http://${host}:${port}/api/stats`, {\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tclearTimeout(timer);\n\t\tif (!res.ok) return null;\n\t\tconst payload = await res.json();\n\t\treturn extractViewerPid(payload);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function isPortOpen(host: string, port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.createConnection({ host, port });\n\t\tconst done = (open: boolean) => {\n\t\t\tsocket.removeAllListeners();\n\t\t\tsocket.destroy();\n\t\t\tresolve(open);\n\t\t};\n\t\tsocket.setTimeout(300);\n\t\tsocket.once(\"connect\", () => done(true));\n\t\tsocket.once(\"timeout\", () => done(false));\n\t\tsocket.once(\"error\", () => done(false));\n\t});\n}\n\nasync function waitForProcessExit(pid: number, timeoutMs = 30000): Promise<boolean> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() < deadline) {\n\t\tif (!isProcessRunning(pid)) return true;\n\t\tawait new Promise((resolve) => setTimeout(resolve, 100));\n\t}\n\treturn !isProcessRunning(pid);\n}\n\nasync function waitForPortRelease(host: string, port: number, timeoutMs = 10000): Promise<boolean> {\n\tconst deadline = Date.now() + timeoutMs;\n\twhile (Date.now() < deadline) {\n\t\tif (!(await isPortOpen(host, port))) return true;\n\t\tawait new Promise((resolve) => setTimeout(resolve, 200));\n\t}\n\treturn false;\n}\n\nasync function stopExistingViewer(\n\tdbPath: string,\n\ttarget: { host: string; port: number },\n): Promise<{ stopped: boolean; pid: number | null }> {\n\tconst terminatePid = async (pid: number): Promise<boolean> => {\n\t\ttry {\n\t\t\tprocess.kill(pid, \"SIGTERM\");\n\t\t\treturn await waitForProcessExit(pid);\n\t\t} catch {\n\t\t\treturn true;\n\t\t}\n\t};\n\n\tconst pidPath = pidFilePath(dbPath);\n\tconst record = readViewerPidRecord(dbPath);\n\tconst viewerPidFromStats = await lookupViewerPidFromStats(target.host, target.port);\n\tconst listenerPid = lookupListeningPid(target.host, target.port);\n\tconst viewerPid = pickViewerPidCandidate(viewerPidFromStats, listenerPid);\n\tif (viewerPid && isTrustedViewerPid(viewerPid, target, listenerPid)) {\n\t\tconst stopped = await terminatePid(viewerPid);\n\t\tif (!stopped) return { stopped: false, pid: viewerPid };\n\t\ttry {\n\t\t\trmSync(pidPath);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\treturn { stopped: true, pid: viewerPid };\n\t}\n\n\tif (!record) return { stopped: false, pid: null };\n\n\tif (await respondsLikeCodememViewer(record)) {\n\t\tconst stopped = await terminatePid(record.pid);\n\t\tif (!stopped) return { stopped: false, pid: record.pid };\n\t}\n\ttry {\n\t\trmSync(pidPath);\n\t} catch {\n\t\t// ignore\n\t}\n\treturn { stopped: true, pid: record.pid };\n}\n\nexport function buildForegroundRunnerArgs(\n\tscriptPath: string,\n\tinvocation: ResolvedServeInvocation,\n\texecArgv: string[] = process.execArgv,\n): string[] {\n\tconst args = [\n\t\t...execArgv,\n\t\tscriptPath,\n\t\t\"serve\",\n\t\t\"start\",\n\t\t\"--foreground\",\n\t\t\"--host\",\n\t\tinvocation.host,\n\t\t\"--port\",\n\t\tString(invocation.port),\n\t];\n\tif (invocation.dbPath) {\n\t\targs.push(\"--db-path\", invocation.dbPath);\n\t}\n\treturn args;\n}\n\nexport function isSqliteVecLoadFailure(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst text = error.message.toLowerCase();\n\treturn (\n\t\ttext.includes(\"sqlite-vec\") ||\n\t\ttext.includes(\"vec_version\") ||\n\t\ttext.includes(\"vec0\") ||\n\t\t(text.includes(\"sqlite\") && text.includes(\"vec\"))\n\t);\n}\n\nexport function sqliteVecFailureDiagnostics(error: unknown, dbPath: string): string[] {\n\tconst message = error instanceof Error ? error.message : String(error);\n\treturn [\n\t\t`db=${dbPath}`,\n\t\t`node=${process.version}`,\n\t\t`exec=${process.execPath}`,\n\t\t`cwd=${process.cwd()}`,\n\t\t`embedding_disabled=${process.env.CODEMEM_EMBEDDING_DISABLED ?? \"\"}`,\n\t\t`error=${message}`,\n\t];\n}\n\nasync function startBackgroundViewer(invocation: ResolvedServeInvocation): Promise<void> {\n\tif (await isPortOpen(invocation.host, invocation.port)) {\n\t\tp.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);\n\t\treturn;\n\t}\n\tconst scriptPath = process.argv[1];\n\tif (!scriptPath) throw new Error(\"Unable to resolve CLI entrypoint for background launch\");\n\tconst child = spawn(process.execPath, buildForegroundRunnerArgs(scriptPath, invocation), {\n\t\tcwd: process.cwd(),\n\t\tdetached: true,\n\t\tstdio: \"ignore\",\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t...(invocation.dbPath ? { CODEMEM_DB: invocation.dbPath } : {}),\n\t\t},\n\t});\n\tchild.unref();\n\tif (invocation.dbPath) {\n\t\twriteFileSync(\n\t\t\tpidFilePath(invocation.dbPath),\n\t\t\tJSON.stringify({ pid: child.pid, host: invocation.host, port: invocation.port }),\n\t\t\t\"utf-8\",\n\t\t);\n\t}\n\tp.intro(\"codemem viewer\");\n\tp.outro(\n\t\t`Viewer started in background (pid ${child.pid}) at http://${invocation.host}:${invocation.port}`,\n\t);\n}\n\nasync function startForegroundViewer(invocation: ResolvedServeInvocation): Promise<void> {\n\tconst { createApp, createSyncApp, closeStore, getStore } = await import(\"@codemem/server\");\n\tconst { serve } = await import(\"@hono/node-server\");\n\n\tif (invocation.dbPath) process.env.CODEMEM_DB = invocation.dbPath;\n\tif (await isPortOpen(invocation.host, invocation.port)) {\n\t\tp.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\n\tconst observer = new ObserverClient();\n\tlet store: MemoryStore;\n\ttry {\n\t\tstore = getStore();\n\t} catch (err) {\n\t\tif (isEmbeddingDisabled() || !isSqliteVecLoadFailure(err)) {\n\t\t\tthrow err;\n\t\t}\n\n\t\tp.log.warn(\"sqlite-vec failed to load; retrying viewer startup with embeddings disabled\");\n\t\tfor (const line of sqliteVecFailureDiagnostics(\n\t\t\terr,\n\t\t\tresolveDbPath(invocation.dbPath ?? undefined),\n\t\t)) {\n\t\t\tp.log.warn(`sqlite-vec diagnostic: ${line}`);\n\t\t}\n\t\tprocess.env.CODEMEM_EMBEDDING_DISABLED = \"1\";\n\t\tcloseStore();\n\t\tstore = getStore();\n\t\tp.log.warn(\"Embeddings disabled for this viewer process; raw-event ingestion remains active.\");\n\t}\n\n\tconst sweeper = new RawEventSweeper(store, { observer });\n\tsweeper.start();\n\n\tconst syncAbort = new AbortController();\n\tconst config = readCodememConfigFile();\n\tconst syncConfig = readCoordinatorSyncConfig(config);\n\tconst syncEnabled = syncConfig.syncEnabled;\n\tconst syncRuntimeStatus: {\n\t\tphase: \"starting\" | \"running\" | \"stopping\" | \"error\" | \"disabled\" | null;\n\t\tdetail: string | null;\n\t} = {\n\t\tphase: syncEnabled ? \"starting\" : \"disabled\",\n\t\tdetail: syncEnabled ? \"Waiting for viewer startup to finish\" : \"Sync is disabled\",\n\t};\n\n\tconst appOpts = {\n\t\tstoreFactory: () => store,\n\t\tsweeper,\n\t\tobserver,\n\t\tgetSyncRuntimeStatus: () => syncRuntimeStatus,\n\t};\n\tconst app = createApp(appOpts);\n\tconst dbPath = resolveDbPath(invocation.dbPath ?? undefined);\n\tconst pidPath = pidFilePath(dbPath);\n\n\t// Sync protocol listener — separate port, network-accessible for peers.\n\t// syncServerRef is never nulled after creation so shutdown always drains it.\n\tlet syncServer: ReturnType<typeof serve> | null = null;\n\tlet syncListenerReady = false;\n\tif (syncEnabled) {\n\t\tconst syncApp = createSyncApp(appOpts);\n\t\tsyncServer = serve(\n\t\t\t{ fetch: syncApp.fetch, hostname: syncConfig.syncHost, port: syncConfig.syncPort },\n\t\t\t(info) => {\n\t\t\t\tsyncListenerReady = true;\n\t\t\t\tp.log.step(`Sync protocol listening on http://${info.address}:${info.port}`);\n\t\t\t},\n\t\t);\n\t\tsyncServer.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\t\tif (!syncListenerReady && err.code === \"EADDRINUSE\") {\n\t\t\t\tp.log.warn(\n\t\t\t\t\t`Sync port ${syncConfig.syncPort} already in use; peer sync protocol unavailable`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tp.log.warn(`Sync listener error: ${err.message}`);\n\t\t\t}\n\t\t\t// Non-fatal — viewer continues. syncServer ref is kept for shutdown drain.\n\t\t});\n\t}\n\n\tconst server = serve(\n\t\t{ fetch: app.fetch, hostname: invocation.host, port: invocation.port },\n\t\t(info) => {\n\t\t\twriteFileSync(\n\t\t\t\tpidPath,\n\t\t\t\tJSON.stringify({ pid: process.pid, host: invocation.host, port: invocation.port }),\n\t\t\t\t\"utf-8\",\n\t\t\t);\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.log.success(`Listening on http://${info.address}:${info.port}`);\n\t\t\tp.log.info(`Database: ${dbPath}`);\n\t\t\tp.log.step(\"Raw event sweeper started\");\n\t\t\tif (syncEnabled) {\n\t\t\t\tconst syncStartDelayMs = 3000;\n\t\t\t\tp.log.step(`Sync daemon will start in background (${syncStartDelayMs / 1000}s delay)`);\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tsyncRuntimeStatus.phase = \"starting\";\n\t\t\t\t\tsyncRuntimeStatus.detail = \"Starting sync in background\";\n\t\t\t\t\tvoid runSyncDaemon({\n\t\t\t\t\t\tdbPath: resolveDbPath(invocation.dbPath ?? undefined),\n\t\t\t\t\t\tintervalS: syncConfig.syncIntervalS,\n\t\t\t\t\t\thost: syncConfig.syncHost,\n\t\t\t\t\t\tport: syncConfig.syncPort,\n\t\t\t\t\t\tsignal: syncAbort.signal,\n\t\t\t\t\t\tonPhaseChange: (phase) => {\n\t\t\t\t\t\t\tif (phase === \"running\") {\n\t\t\t\t\t\t\t\tsyncRuntimeStatus.phase = null;\n\t\t\t\t\t\t\t\tsyncRuntimeStatus.detail = null;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsyncRuntimeStatus.phase = phase;\n\t\t\t\t\t\t\t\tsyncRuntimeStatus.detail =\n\t\t\t\t\t\t\t\t\tphase === \"starting\"\n\t\t\t\t\t\t\t\t\t\t? \"Running initial sync in background\"\n\t\t\t\t\t\t\t\t\t\t: \"Stopping sync daemon\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\t\tsyncRuntimeStatus.phase = \"error\";\n\t\t\t\t\t\t\tsyncRuntimeStatus.detail = msg;\n\t\t\t\t\t\t\tp.log.error(`Sync daemon failed: ${msg}`);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.finally(() => {\n\t\t\t\t\t\t\tif (syncRuntimeStatus.phase !== \"error\") {\n\t\t\t\t\t\t\t\tsyncRuntimeStatus.phase = syncAbort.signal.aborted ? \"stopping\" : null;\n\t\t\t\t\t\t\t\tsyncRuntimeStatus.detail = syncAbort.signal.aborted ? \"Sync stopped\" : null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t}, syncStartDelayMs).unref();\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.on(\"error\", (err: NodeJS.ErrnoException) => {\n\t\tif (err.code === \"EADDRINUSE\") {\n\t\t\tp.log.warn(`Viewer already running at http://${invocation.host}:${invocation.port}`);\n\t\t} else {\n\t\t\tp.log.error(err.message);\n\t\t}\n\t\tprocess.exit(1);\n\t});\n\n\tconst shutdown = async () => {\n\t\tp.outro(\"shutting down\");\n\t\tsyncAbort.abort();\n\t\tawait sweeper.stop();\n\n\t\t// Drain both listeners before closing the shared store.\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tlet remaining = syncServer ? 2 : 1;\n\t\t\tconst done = () => {\n\t\t\t\tif (--remaining === 0) resolve();\n\t\t\t};\n\t\t\tsyncServer?.close(done);\n\t\t\tserver.close(done);\n\t\t}).catch(() => {\n\t\t\t// Best-effort drain — proceed to cleanup.\n\t\t});\n\n\t\ttry {\n\t\t\trmSync(pidPath);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t\tcloseStore();\n\t\tprocess.exit(0);\n\t};\n\n\t// Force-exit safety net if graceful shutdown stalls for an unusually long time.\n\tconst forceShutdown = () => {\n\t\tsetTimeout(() => {\n\t\t\ttry {\n\t\t\t\trmSync(pidPath);\n\t\t\t} catch {\n\t\t\t\t// ignore\n\t\t\t}\n\t\t\tcloseStore();\n\t\t\tprocess.exit(1);\n\t\t}, 30000).unref();\n\t};\n\tprocess.on(\"SIGINT\", () => {\n\t\tforceShutdown();\n\t\tvoid shutdown();\n\t});\n\tprocess.on(\"SIGTERM\", () => {\n\t\tforceShutdown();\n\t\tvoid shutdown();\n\t});\n}\n\nasync function runServeInvocation(invocation: ResolvedServeInvocation): Promise<void> {\n\tconst dbPath = resolveDbPath(invocation.dbPath ?? undefined);\n\tif (invocation.mode === \"stop\" || invocation.mode === \"restart\") {\n\t\tconst result = await stopExistingViewer(dbPath, {\n\t\t\thost: invocation.host,\n\t\t\tport: invocation.port,\n\t\t});\n\t\tif (result.stopped) {\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.log.success(`Stopped viewer${result.pid ? ` (pid ${result.pid})` : \"\"}`);\n\t\t\tif (invocation.mode === \"stop\") {\n\t\t\t\tp.outro(\"done\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Wait for port to be fully released before restarting.\n\t\t\tconst released = await waitForPortRelease(invocation.host, invocation.port);\n\t\t\tif (!released) {\n\t\t\t\tp.log.warn(`Port ${invocation.port} still in use after stop — restart may fail`);\n\t\t\t}\n\t\t} else if (result.pid) {\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.log.error(`Viewer is still shutting down (pid ${result.pid})`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t} else if (invocation.mode === \"stop\") {\n\t\t\tp.intro(\"codemem viewer\");\n\t\t\tp.outro(\"No background viewer found\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (invocation.mode === \"start\" || invocation.mode === \"restart\") {\n\t\tif (invocation.background) {\n\t\t\tawait startBackgroundViewer({ ...invocation, dbPath });\n\t\t\treturn;\n\t\t}\n\t\tawait startForegroundViewer({ ...invocation, dbPath });\n\t}\n}\n\nfunction addSharedServeOptions(command: Command): Command {\n\treturn command\n\t\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t\t.option(\"--host <host>\", \"bind host\", \"127.0.0.1\")\n\t\t.option(\"--port <port>\", \"bind port\", \"38888\");\n}\n\nexport const serveCommand = addSharedServeOptions(\n\tnew Command(\"serve\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Run or manage the viewer\")\n\t\t.argument(\"[action]\", \"lifecycle action (start|stop|restart)\"),\n)\n\t.option(\"--background\", \"run viewer in background\")\n\t.option(\"--foreground\", \"run viewer in foreground\")\n\t.option(\"--stop\", \"stop background viewer\")\n\t.option(\"--restart\", \"restart background viewer\")\n\t.action(async (action: string | undefined, opts: LegacyServeOptions) => {\n\t\tconst normalizedAction =\n\t\t\taction === undefined\n\t\t\t\t? undefined\n\t\t\t\t: action === \"start\" || action === \"stop\" || action === \"restart\"\n\t\t\t\t\t? (action as ServeAction)\n\t\t\t\t\t: null;\n\t\tif (normalizedAction === null) {\n\t\t\tp.log.error(`Unknown serve action: ${action}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tawait runServeInvocation(resolveServeInvocation(normalizedAction, opts));\n\t});\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { stripJsonComments, stripTrailingCommas } from \"@codemem/core\";\n\nexport function resolveOpencodeConfigPath(configDir: string): string {\n\tconst jsonPath = join(configDir, \"opencode.json\");\n\tif (existsSync(jsonPath)) return jsonPath;\n\tconst jsoncPath = join(configDir, \"opencode.jsonc\");\n\tif (existsSync(jsoncPath)) return jsoncPath;\n\treturn jsoncPath;\n}\n\nexport function loadJsoncConfig(path: string): Record<string, unknown> {\n\tif (!existsSync(path)) return {};\n\tconst raw = readFileSync(path, \"utf-8\");\n\ttry {\n\t\treturn JSON.parse(raw) as Record<string, unknown>;\n\t} catch {\n\t\tconst cleaned = stripTrailingCommas(stripJsonComments(raw));\n\t\treturn JSON.parse(cleaned) as Record<string, unknown>;\n\t}\n}\n\nexport function writeJsonConfig(path: string, data: Record<string, unknown>): void {\n\tmkdirSync(dirname(path), { recursive: true });\n\twriteFileSync(path, `${JSON.stringify(data, null, 2)}\\n`, \"utf-8\");\n}\n","/**\n * codemem setup — one-command installation for OpenCode plugin + MCP config.\n *\n * Replaces Python's install_plugin_cmd + install_mcp_cmd.\n *\n * What it does:\n * 1. Adds \"codemem\" to the plugin array in ~/.config/opencode/opencode.jsonc\n * 2. Adds/updates the MCP entry in ~/.config/opencode/opencode.jsonc\n * 3. For Claude Code: installs MCP config and guides marketplace plugin install\n *\n * Designed to be safe to run repeatedly (idempotent unless --force).\n */\n\nimport { existsSync, rmSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as p from \"@clack/prompts\";\nimport { VERSION } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\nimport { loadJsoncConfig, resolveOpencodeConfigPath, writeJsonConfig } from \"./setup-config.js\";\n\nfunction opencodeConfigDir(): string {\n\treturn join(homedir(), \".config\", \"opencode\");\n}\n\nfunction claudeConfigDir(): string {\n\treturn join(homedir(), \".claude\");\n}\n\n/** The npm package name used in the OpenCode plugin array. */\nconst OPENCODE_PLUGIN_SPEC = \"codemem\";\n\n// ---------------------------------------------------------------------------\n// Legacy migration helpers\n// ---------------------------------------------------------------------------\n\n/** Remove legacy copied plugin JS file from ~/.config/opencode/plugins/codemem.js */\nfunction migrateLegacyOpencodePlugin(): void {\n\tconst legacyPlugin = join(opencodeConfigDir(), \"plugins\", \"codemem.js\");\n\tconst legacyCompat = join(opencodeConfigDir(), \"lib\", \"compat.js\");\n\tif (existsSync(legacyPlugin)) {\n\t\ttry {\n\t\t\trmSync(legacyPlugin);\n\t\t\tp.log.step(\"Removed legacy copied plugin: ~/.config/opencode/plugins/codemem.js\");\n\t\t} catch {\n\t\t\tp.log.warn(\"Could not remove legacy plugin file — remove manually if needed\");\n\t\t}\n\t}\n\tif (existsSync(legacyCompat)) {\n\t\ttry {\n\t\t\trmSync(legacyCompat);\n\t\t\tp.log.step(\"Removed legacy compat lib: ~/.config/opencode/lib/compat.js\");\n\t\t} catch {\n\t\t\t// Non-fatal.\n\t\t}\n\t}\n}\n\n/** Detect and upgrade legacy uvx/uv-based MCP entries in OpenCode config. */\nfunction migrateLegacyOpencodeMcp(config: Record<string, unknown>): boolean {\n\tconst mcpConfig = config.mcp as Record<string, unknown> | undefined;\n\tif (!mcpConfig || typeof mcpConfig !== \"object\") return false;\n\tconst entry = mcpConfig.codemem as Record<string, unknown> | undefined;\n\tif (!entry || typeof entry !== \"object\") return false;\n\n\tconst command = entry.command;\n\tconst isLegacy =\n\t\t(Array.isArray(command) &&\n\t\t\tcommand.some((arg) => typeof arg === \"string\" && (arg === \"uvx\" || arg === \"uv\"))) ||\n\t\t(typeof command === \"string\" && (command === \"uvx\" || command === \"uv\"));\n\n\tif (isLegacy) {\n\t\tp.log.step(\"Upgrading legacy uvx MCP entry to npx\");\n\t\tmcpConfig.codemem = {\n\t\t\ttype: \"local\",\n\t\t\tcommand: [\"npx\", \"codemem\", \"mcp\"],\n\t\t\tenabled: true,\n\t\t};\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/** Detect and upgrade legacy uvx-based MCP entries in Claude settings. */\nfunction migrateLegacyClaudeMcp(settings: Record<string, unknown>): boolean {\n\tconst mcpServers = settings.mcpServers as Record<string, unknown> | undefined;\n\tif (!mcpServers || typeof mcpServers !== \"object\") return false;\n\tconst entry = mcpServers.codemem as Record<string, unknown> | undefined;\n\tif (!entry || typeof entry !== \"object\") return false;\n\n\tconst command = entry.command;\n\tconst args = entry.args;\n\tconst isLegacy =\n\t\t(typeof command === \"string\" && (command === \"uvx\" || command === \"uv\")) ||\n\t\t(Array.isArray(args) &&\n\t\t\targs.some(\n\t\t\t\t(arg) => typeof arg === \"string\" && (arg.startsWith(\"codemem==\") || arg === \"uvx\"),\n\t\t\t));\n\n\tif (isLegacy) {\n\t\tp.log.step(\"Upgrading legacy uvx Claude MCP entry to npx\");\n\t\tmcpServers.codemem = {\n\t\t\tcommand: \"npx\",\n\t\t\targs: [\"-y\", \"codemem\", \"mcp\"],\n\t\t};\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n// ---------------------------------------------------------------------------\n// Install functions\n// ---------------------------------------------------------------------------\n\nfunction installPlugin(force: boolean): boolean {\n\t// Clean up legacy copied plugin files first.\n\tmigrateLegacyOpencodePlugin();\n\n\tconst configPath = resolveOpencodeConfigPath(opencodeConfigDir());\n\tlet config: Record<string, unknown>;\n\ttry {\n\t\tconfig = loadJsoncConfig(configPath);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\tlet plugins = config.plugin as unknown;\n\tif (!Array.isArray(plugins)) {\n\t\tplugins = [];\n\t}\n\n\tconst hasCodemem = (plugins as string[]).some(\n\t\t(entry) =>\n\t\t\ttypeof entry === \"string\" &&\n\t\t\t(entry === OPENCODE_PLUGIN_SPEC || entry.startsWith(`${OPENCODE_PLUGIN_SPEC}@`)),\n\t);\n\n\tif (hasCodemem && !force) {\n\t\tp.log.info(`Plugin \"${OPENCODE_PLUGIN_SPEC}\" already in plugin array`);\n\t\treturn true;\n\t}\n\n\tif (hasCodemem && force) {\n\t\t// Remove existing entry so we can re-add the canonical one.\n\t\tplugins = (plugins as string[]).filter(\n\t\t\t(entry) =>\n\t\t\t\ttypeof entry !== \"string\" ||\n\t\t\t\t(entry !== OPENCODE_PLUGIN_SPEC && !entry.startsWith(`${OPENCODE_PLUGIN_SPEC}@`)),\n\t\t);\n\t}\n\n\t(plugins as string[]).push(OPENCODE_PLUGIN_SPEC);\n\tconfig.plugin = plugins;\n\n\ttry {\n\t\twriteJsonConfig(configPath, config);\n\t\tp.log.success(`Plugin \"${OPENCODE_PLUGIN_SPEC}\" added to ${configPath}`);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to write ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nfunction installMcp(force: boolean): boolean {\n\tconst configPath = resolveOpencodeConfigPath(opencodeConfigDir());\n\tlet config: Record<string, unknown>;\n\ttry {\n\t\tconfig = loadJsoncConfig(configPath);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\tlet mcpConfig = config.mcp as Record<string, unknown> | undefined;\n\tif (mcpConfig == null || typeof mcpConfig !== \"object\" || Array.isArray(mcpConfig)) {\n\t\tmcpConfig = {};\n\t}\n\n\t// Auto-upgrade legacy uvx-based MCP entries.\n\tconst migrated = migrateLegacyOpencodeMcp(config);\n\n\tif (\"codemem\" in mcpConfig && !force && !migrated) {\n\t\tp.log.info(`MCP entry already exists in ${configPath}`);\n\t\treturn true;\n\t}\n\n\tif (!migrated) {\n\t\tmcpConfig.codemem = {\n\t\t\ttype: \"local\",\n\t\t\tcommand: [\"npx\", \"codemem\", \"mcp\"],\n\t\t\tenabled: true,\n\t\t};\n\t\tconfig.mcp = mcpConfig;\n\t}\n\n\ttry {\n\t\twriteJsonConfig(configPath, config);\n\t\tp.log.success(`MCP entry installed: ${configPath}`);\n\t} catch (err) {\n\t\tp.log.error(\n\t\t\t`Failed to write ${configPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nfunction isClaudeHooksPluginInstalled(): boolean {\n\t// Check if the marketplace hooks plugin is installed by looking for\n\t// the hooks directory — NOT for MCP config (which we write ourselves).\n\tconst pluginDir = join(claudeConfigDir(), \"plugins\", \"codemem\");\n\tif (existsSync(pluginDir)) return true;\n\t// Also check for hook scripts installed by the marketplace plugin.\n\tconst hooksJson = join(pluginDir, \"hooks\", \"hooks.json\");\n\tif (existsSync(hooksJson)) return true;\n\treturn false;\n}\n\nfunction installClaudeMcp(force: boolean): boolean {\n\tconst settingsPath = join(claudeConfigDir(), \"settings.json\");\n\tlet settings: Record<string, unknown>;\n\ttry {\n\t\tsettings = loadJsoncConfig(settingsPath);\n\t} catch {\n\t\tsettings = {};\n\t}\n\n\tlet mcpServers = settings.mcpServers as Record<string, unknown> | undefined;\n\tif (mcpServers == null || typeof mcpServers !== \"object\" || Array.isArray(mcpServers)) {\n\t\tmcpServers = {};\n\t}\n\n\t// Auto-upgrade legacy uvx-based Claude MCP entries.\n\tconst migrated = migrateLegacyClaudeMcp(settings);\n\n\tif (\"codemem\" in mcpServers && !force && !migrated) {\n\t\tp.log.info(`Claude MCP entry already exists in ${settingsPath}`);\n\t} else {\n\t\tif (!migrated) {\n\t\t\tmcpServers.codemem = {\n\t\t\t\tcommand: \"npx\",\n\t\t\t\targs: [\"-y\", \"codemem\", \"mcp\"],\n\t\t\t};\n\t\t\tsettings.mcpServers = mcpServers;\n\t\t}\n\n\t\ttry {\n\t\t\twriteJsonConfig(settingsPath, settings);\n\t\t\tp.log.success(`Claude MCP entry installed: ${settingsPath}`);\n\t\t} catch (err) {\n\t\t\tp.log.error(\n\t\t\t\t`Failed to write ${settingsPath}: ${err instanceof Error ? err.message : String(err)}`,\n\t\t\t);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t// Guide marketplace plugin install for hooks integration.\n\tif (!isClaudeHooksPluginInstalled() || force) {\n\t\tp.log.info(\"To install the Claude Code hooks plugin, run in Claude Code:\");\n\t\tp.log.info(\" /plugin marketplace add kunickiaj/codemem\");\n\t\tp.log.info(\" /plugin install codemem\");\n\t\tp.log.info(\"\");\n\t\tp.log.info(\"To update an existing install:\");\n\t\tp.log.info(\" /plugin marketplace update codemem-marketplace\");\n\t} else {\n\t\tp.log.info(\"Claude Code hooks plugin appears to be installed\");\n\t}\n\n\treturn true;\n}\n\nexport const setupCommand = new Command(\"setup\")\n\t.configureHelp(helpStyle)\n\t.description(\"Install codemem plugin + MCP config for OpenCode and Claude Code\")\n\t.option(\"--force\", \"overwrite existing installations\")\n\t.option(\"--opencode-only\", \"only install for OpenCode\")\n\t.option(\"--claude-only\", \"only install for Claude Code\")\n\t.action((opts: { force?: boolean; opencodeOnly?: boolean; claudeOnly?: boolean }) => {\n\t\tp.intro(`codemem setup v${VERSION}`);\n\t\tconst force = opts.force ?? false;\n\t\tlet ok = true;\n\n\t\tif (!opts.claudeOnly) {\n\t\t\tp.log.step(\"Installing OpenCode plugin...\");\n\t\t\tok = installPlugin(force) && ok;\n\t\t\tp.log.step(\"Installing OpenCode MCP config...\");\n\t\t\tok = installMcp(force) && ok;\n\t\t}\n\n\t\tif (!opts.opencodeOnly) {\n\t\t\tp.log.step(\"Installing Claude Code MCP config...\");\n\t\t\tok = installClaudeMcp(force) && ok;\n\t\t}\n\n\t\tif (ok) {\n\t\t\tp.outro(\"Setup complete — restart your editor to load the plugin\");\n\t\t} else {\n\t\t\tp.outro(\"Setup completed with warnings\");\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\t});\n","import * as p from \"@clack/prompts\";\nimport { MemoryStore, resolveDbPath } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nfunction fmtPct(n: number): string {\n\treturn `${Math.round(n * 100)}%`;\n}\n\nfunction fmtTokens(n: number): string {\n\tif (n >= 1_000_000_000) return `~${(n / 1_000_000_000).toFixed(1)}B`;\n\tif (n >= 1_000_000) return `~${(n / 1_000_000).toFixed(1)}M`;\n\tif (n >= 1_000) return `~${(n / 1_000).toFixed(0)}K`;\n\treturn `${n}`;\n}\n\nexport const statsCommand = new Command(\"stats\")\n\t.configureHelp(helpStyle)\n\t.description(\"Show database statistics\")\n\t.option(\"--db <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--db-path <path>\", \"database path (default: $CODEMEM_DB or ~/.codemem/mem.sqlite)\")\n\t.option(\"--json\", \"output as JSON\")\n\t.action((opts: { db?: string; dbPath?: string; json?: boolean }) => {\n\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\ttry {\n\t\t\tconst result = store.stats();\n\t\t\tif (opts.json) {\n\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst db = result.database;\n\t\t\tconst sizeMb = (db.size_bytes / 1_048_576).toFixed(1);\n\n\t\t\tp.intro(\"codemem stats\");\n\n\t\t\tp.log.info([`Path: ${db.path}`, `Size: ${sizeMb} MB`].join(\"\\n\"));\n\n\t\t\tp.log.success(\n\t\t\t\t[\n\t\t\t\t\t`Sessions: ${db.sessions.toLocaleString()}`,\n\t\t\t\t\t`Memories: ${db.active_memory_items.toLocaleString()} active / ${db.memory_items.toLocaleString()} total`,\n\t\t\t\t\t`Tags: ${db.tags_filled.toLocaleString()} filled (${fmtPct(db.tags_coverage)} of active)`,\n\t\t\t\t\t`Artifacts: ${db.artifacts.toLocaleString()}`,\n\t\t\t\t\t`Vectors: ${db.vector_rows.toLocaleString()} (${fmtPct(db.vector_coverage)} coverage)`,\n\t\t\t\t\t`Raw events: ${db.raw_events.toLocaleString()}`,\n\t\t\t\t].join(\"\\n\"),\n\t\t\t);\n\n\t\t\tif (result.usage.events.length > 0) {\n\t\t\t\tconst lines = result.usage.events.map((e: (typeof result.usage.events)[number]) => {\n\t\t\t\t\tconst parts = [`${e.event}: ${e.count.toLocaleString()}`];\n\t\t\t\t\tif (e.tokens_read > 0) parts.push(`read ${fmtTokens(e.tokens_read)} tokens`);\n\t\t\t\t\tif (e.tokens_saved > 0) parts.push(`est. saved ${fmtTokens(e.tokens_saved)} tokens`);\n\t\t\t\t\treturn ` ${parts.join(\", \")}`;\n\t\t\t\t});\n\n\t\t\t\tconst t = result.usage.totals;\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(\n\t\t\t\t\t` Total: ${t.events.toLocaleString()} events, read ${fmtTokens(t.tokens_read)} tokens, est. saved ${fmtTokens(t.tokens_saved)} tokens`,\n\t\t\t\t);\n\n\t\t\t\tp.log.step(`Usage\\n${lines.join(\"\\n\")}`);\n\t\t\t}\n\n\t\t\tp.outro(\"done\");\n\t\t} finally {\n\t\t\tstore.close();\n\t\t}\n\t});\n","export interface SyncAttemptRow {\n\tpeer_device_id: string;\n\tok: number;\n\tops_in: number;\n\tops_out: number;\n\terror: string | null;\n\tfinished_at: string | null;\n}\n\nexport function formatSyncAttempt(row: SyncAttemptRow): string {\n\tconst status = row.ok ? \"ok\" : \"error\";\n\tconst error = String(row.error || \"\");\n\tconst suffix = error ? ` | ${error}` : \"\";\n\treturn `${row.peer_device_id}|${status}|in=${row.ops_in}|out=${row.ops_out}|${row.finished_at ?? \"\"}${suffix}`;\n}\n\nexport interface SyncLifecycleOptions {\n\tdb?: string;\n\tdbPath?: string;\n\thost?: string;\n\tport?: string;\n\tuser?: boolean;\n\tsystem?: boolean;\n}\n\nexport function buildServeLifecycleArgs(\n\taction: \"start\" | \"stop\" | \"restart\",\n\topts: SyncLifecycleOptions,\n\tscriptPath: string,\n\texecArgv: string[] = [],\n): string[] {\n\tif (!scriptPath) throw new Error(\"Unable to resolve CLI entrypoint for sync lifecycle command\");\n\tconst args = [...execArgv, scriptPath, \"serve\"];\n\tif (action === \"start\") {\n\t\targs.push(\"--restart\");\n\t} else if (action === \"stop\") {\n\t\targs.push(\"--stop\");\n\t} else {\n\t\targs.push(\"--restart\");\n\t}\n\tif (opts.db ?? opts.dbPath) args.push(\"--db-path\", opts.db ?? opts.dbPath ?? \"\");\n\tif (opts.host) args.push(\"--host\", opts.host);\n\tif (opts.port) args.push(\"--port\", opts.port);\n\treturn args;\n}\n\nexport function formatSyncOnceResult(\n\tpeerDeviceId: string,\n\tresult: { ok: boolean; error?: string },\n): string {\n\tif (result.ok) return `- ${peerDeviceId}: ok`;\n\tconst suffix = result.error ? `: ${result.error}` : \"\";\n\treturn `- ${peerDeviceId}: error${suffix}`;\n}\n\nexport function parseProjectList(value: string | undefined): string[] {\n\tif (!value) return [];\n\treturn value\n\t\t.split(\",\")\n\t\t.map((item) => item.trim())\n\t\t.filter(Boolean);\n}\n\ntype InterfaceMap = Record<\n\tstring,\n\tArray<{ address: string; family?: string | number; internal?: boolean }> | undefined\n>;\n\nexport function collectAdvertiseAddresses(\n\texplicitAddress: string | null,\n\tconfiguredHost: string | null,\n\tport: number,\n\tinterfaces: InterfaceMap,\n): string[] {\n\tif (explicitAddress && ![\"auto\", \"default\"].includes(explicitAddress.toLowerCase())) {\n\t\treturn [explicitAddress];\n\t}\n\tif (configuredHost && configuredHost !== \"0.0.0.0\") {\n\t\treturn [`${configuredHost}:${port}`];\n\t}\n\tconst addresses = Object.values(interfaces)\n\t\t.flatMap((entries) => entries ?? [])\n\t\t.filter((entry) => !entry.internal)\n\t\t.map((entry) => entry.address)\n\t\t.filter((address) => address && address !== \"127.0.0.1\" && address !== \"::1\")\n\t\t.map((address) => `${address}:${port}`);\n\treturn [...new Set(addresses)];\n}\n","/**\n * Sync CLI commands — enable/disable/status/peers/connect.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport net from \"node:net\";\nimport { networkInterfaces } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport * as p from \"@clack/prompts\";\nimport {\n\tcoordinatorCreateInviteAction,\n\tcoordinatorImportInviteAction,\n\tcoordinatorListJoinRequestsAction,\n\tcoordinatorReviewJoinRequestAction,\n\tcreateCoordinatorApp,\n\tDEFAULT_COORDINATOR_DB_PATH,\n\tensureDeviceIdentity,\n\tfingerprintPublicKey,\n\tloadPublicKey,\n\tMemoryStore,\n\treadCodememConfigFile,\n\tresolveDbPath,\n\trunSyncPass,\n\tschema,\n\tsetPeerProjectFilter,\n\tsyncPassPreflight,\n\tupdatePeerAddresses,\n\twriteCodememConfigFile,\n} from \"@codemem/core\";\nimport { serve as honoServe } from \"@hono/node-server\";\nimport { Command } from \"commander\";\nimport { desc, eq } from \"drizzle-orm\";\nimport { drizzle } from \"drizzle-orm/better-sqlite3\";\nimport { helpStyle } from \"../help-style.js\";\nimport {\n\tbuildServeLifecycleArgs,\n\tcollectAdvertiseAddresses,\n\tformatSyncAttempt,\n\tformatSyncOnceResult,\n\tparseProjectList,\n\ttype SyncLifecycleOptions,\n} from \"./sync-helpers.js\";\n\nfunction parseAttemptsLimit(value: string): number {\n\tif (!/^\\d+$/.test(value.trim())) {\n\t\tthrow new Error(`Invalid --limit: ${value}`);\n\t}\n\treturn Number.parseInt(value, 10);\n}\n\ninterface SyncOnceOptions {\n\tdb?: string;\n\tdbPath?: string;\n\tpeer?: string;\n}\n\ninterface SyncPairOptions {\n\taccept?: string;\n\tacceptFile?: string;\n\tpayloadOnly?: boolean;\n\tname?: string;\n\taddress?: string;\n\tinclude?: string;\n\texclude?: string;\n\tall?: boolean;\n\tdefault?: boolean;\n\tdbPath?: string;\n}\n\nasync function portOpen(host: string, port: number): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst socket = net.createConnection({ host, port });\n\t\tconst done = (ok: boolean) => {\n\t\t\tsocket.removeAllListeners();\n\t\t\tsocket.destroy();\n\t\t\tresolve(ok);\n\t\t};\n\t\tsocket.setTimeout(300);\n\t\tsocket.once(\"connect\", () => done(true));\n\t\tsocket.once(\"timeout\", () => done(false));\n\t\tsocket.once(\"error\", () => done(false));\n\t});\n}\n\nfunction readViewerBinding(dbPath: string): { host: string; port: number } | null {\n\ttry {\n\t\tconst raw = readFileSync(join(dirname(dbPath), \"viewer.pid\"), \"utf8\");\n\t\tconst parsed = JSON.parse(raw) as Partial<{ host: string; port: number }>;\n\t\tif (typeof parsed.host === \"string\" && typeof parsed.port === \"number\") {\n\t\t\treturn { host: parsed.host, port: parsed.port };\n\t\t}\n\t} catch {\n\t\t// ignore malformed or missing pidfile\n\t}\n\treturn null;\n}\n\nfunction parseStoredAddressEndpoint(value: string): { host: string; port: number } | null {\n\ttry {\n\t\tconst normalized = value.includes(\"://\") ? value : `http://${value}`;\n\t\tconst url = new URL(normalized);\n\t\tconst port = url.port ? Number.parseInt(url.port, 10) : url.protocol === \"https:\" ? 443 : 80;\n\t\tif (!url.hostname || !Number.isFinite(port)) return null;\n\t\treturn { host: url.hostname, port };\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function runServeLifecycle(\n\taction: \"start\" | \"stop\" | \"restart\",\n\topts: SyncLifecycleOptions,\n): Promise<void> {\n\tif (opts.user === false || opts.system === true) {\n\t\tp.log.warn(\n\t\t\t\"TS sync lifecycle currently manages the local viewer process, not separate user/system services.\",\n\t\t);\n\t}\n\tif (action === \"start\") {\n\t\tconst config = readCodememConfigFile();\n\t\tif (config.sync_enabled !== true) {\n\t\t\tp.log.error(\"Sync is disabled. Run `codemem sync enable` first.\");\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\t// Don't pass sync_host/sync_port as viewer bind values.\n\t\t// The viewer binds its own host/port (default 127.0.0.1:38888)\n\t\t// and the sync protocol listener reads sync_host/sync_port\n\t\t// internally from readCoordinatorSyncConfig().\n\t}\n\tconst args = buildServeLifecycleArgs(action, opts, process.argv[1] ?? \"\", process.execArgv);\n\tawait new Promise<void>((resolve, reject) => {\n\t\tconst child = spawn(process.execPath, args, {\n\t\t\tcwd: process.cwd(),\n\t\t\tstdio: \"inherit\",\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\t...((opts.db ?? opts.dbPath) ? { CODEMEM_DB: opts.db ?? opts.dbPath } : {}),\n\t\t\t},\n\t\t});\n\t\tchild.once(\"error\", reject);\n\t\tchild.once(\"exit\", (code) => {\n\t\t\tif (code && code !== 0) {\n\t\t\t\tprocess.exitCode = code;\n\t\t\t}\n\t\t\tresolve();\n\t\t});\n\t});\n}\n\nexport const syncCommand = new Command(\"sync\")\n\t.configureHelp(helpStyle)\n\t.description(\"Sync configuration and peer management\");\n\n// codemem sync attempts\nsyncCommand.addCommand(\n\tnew Command(\"attempts\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Show recent sync attempts\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--limit <n>\", \"max attempts\", \"10\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action((opts: { db?: string; dbPath?: string; limit: string; json?: boolean }) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst limit = parseAttemptsLimit(opts.limit);\n\t\t\t\tconst rows = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncAttempts.peer_device_id,\n\t\t\t\t\t\tok: schema.syncAttempts.ok,\n\t\t\t\t\t\tops_in: schema.syncAttempts.ops_in,\n\t\t\t\t\t\tops_out: schema.syncAttempts.ops_out,\n\t\t\t\t\t\terror: schema.syncAttempts.error,\n\t\t\t\t\t\tfinished_at: schema.syncAttempts.finished_at,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncAttempts)\n\t\t\t\t\t.orderBy(desc(schema.syncAttempts.finished_at))\n\t\t\t\t\t.limit(limit)\n\t\t\t\t\t.all();\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(rows, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconsole.log(formatSyncAttempt(row));\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"start\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Start sync daemon\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"viewer host\")\n\t\t.option(\"--port <port>\", \"viewer port\")\n\t\t.option(\"--user\", \"accepted for compatibility\", true)\n\t\t.option(\"--system\", \"accepted for compatibility\")\n\t\t.action(async (opts: SyncLifecycleOptions) => {\n\t\t\tawait runServeLifecycle(\"start\", opts);\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"stop\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Stop sync daemon\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"viewer host\")\n\t\t.option(\"--port <port>\", \"viewer port\")\n\t\t.option(\"--user\", \"accepted for compatibility\", true)\n\t\t.option(\"--system\", \"accepted for compatibility\")\n\t\t.action(async (opts: SyncLifecycleOptions) => {\n\t\t\tawait runServeLifecycle(\"stop\", opts);\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"restart\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Restart sync daemon\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"viewer host\")\n\t\t.option(\"--port <port>\", \"viewer port\")\n\t\t.option(\"--user\", \"accepted for compatibility\", true)\n\t\t.option(\"--system\", \"accepted for compatibility\")\n\t\t.action(async (opts: SyncLifecycleOptions) => {\n\t\t\tawait runServeLifecycle(\"restart\", opts);\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"once\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Run a single sync pass\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--peer <peer>\", \"peer device id or name\")\n\t\t.action(async (opts: SyncOnceOptions) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tsyncPassPreflight(store.db);\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst rows = opts.peer\n\t\t\t\t\t? (() => {\n\t\t\t\t\t\t\tconst deviceMatches = d\n\t\t\t\t\t\t\t\t.select({ peer_device_id: schema.syncPeers.peer_device_id })\n\t\t\t\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t\t\t\t.where(eq(schema.syncPeers.peer_device_id, opts.peer))\n\t\t\t\t\t\t\t\t.all();\n\t\t\t\t\t\t\tif (deviceMatches.length > 0) return deviceMatches;\n\t\t\t\t\t\t\tconst nameMatches = d\n\t\t\t\t\t\t\t\t.select({ peer_device_id: schema.syncPeers.peer_device_id })\n\t\t\t\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t\t\t\t.where(eq(schema.syncPeers.name, opts.peer))\n\t\t\t\t\t\t\t\t.all();\n\t\t\t\t\t\t\tif (nameMatches.length > 1) {\n\t\t\t\t\t\t\t\tp.log.error(`Peer name is ambiguous: ${opts.peer}`);\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn nameMatches;\n\t\t\t\t\t\t})()\n\t\t\t\t\t: d\n\t\t\t\t\t\t\t.select({ peer_device_id: schema.syncPeers.peer_device_id })\n\t\t\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t\t\t.all();\n\n\t\t\t\tif (rows.length === 0) {\n\t\t\t\t\tp.log.warn(\"No peers available for sync\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet hadFailure = false;\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst result = await runSyncPass(store.db, row.peer_device_id);\n\t\t\t\t\tif (!result.ok) hadFailure = true;\n\t\t\t\t\tconsole.log(formatSyncOnceResult(row.peer_device_id, result));\n\t\t\t\t}\n\t\t\t\tif (hadFailure) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"pair\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Print pairing payload or accept a peer payload\")\n\t\t.option(\"--accept <json>\", \"accept pairing payload JSON from another device\")\n\t\t.option(\"--accept-file <path>\", \"accept pairing payload from file path, or '-' for stdin\")\n\t\t.option(\"--payload-only\", \"when generating pairing payload, print JSON only\")\n\t\t.option(\"--name <name>\", \"label for the peer\")\n\t\t.option(\"--address <host:port>\", \"override peer address (host:port)\")\n\t\t.option(\"--include <projects>\", \"outbound-only allowlist for accepted peer\")\n\t\t.option(\"--exclude <projects>\", \"outbound-only blocklist for accepted peer\")\n\t\t.option(\"--all\", \"with --accept, push all projects to that peer\")\n\t\t.option(\"--default\", \"with --accept, use default/global push filters\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(async (opts: SyncPairOptions) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst acceptModeRequested = opts.accept != null || opts.acceptFile != null;\n\t\t\t\tif (opts.payloadOnly && acceptModeRequested) {\n\t\t\t\t\tp.log.error(\"--payload-only cannot be combined with --accept or --accept-file\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (opts.accept && opts.acceptFile) {\n\t\t\t\t\tp.log.error(\"Use only one of --accept or --accept-file\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tlet acceptText = opts.accept;\n\t\t\t\tif (opts.acceptFile) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tacceptText =\n\t\t\t\t\t\t\topts.acceptFile === \"-\"\n\t\t\t\t\t\t\t\t? await new Promise<string>((resolve, reject) => {\n\t\t\t\t\t\t\t\t\t\tlet text = \"\";\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\t\t\t\t\t\t\t\t\ttext += chunk;\n\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.on(\"end\", () => resolve(text));\n\t\t\t\t\t\t\t\t\t\tprocess.stdin.on(\"error\", reject);\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t: readFileSync(opts.acceptFile, \"utf8\");\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(\n\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t? `Failed to read pairing payload from ${opts.acceptFile}: ${error.message}`\n\t\t\t\t\t\t\t\t: `Failed to read pairing payload from ${opts.acceptFile}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (acceptModeRequested && !(acceptText ?? \"\").trim()) {\n\t\t\t\t\tp.log.error(\"Empty pairing payload; provide JSON via --accept or --accept-file\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!acceptText && (opts.include || opts.exclude || opts.all || opts.default)) {\n\t\t\t\t\tp.log.error(\n\t\t\t\t\t\t\"Project filters are outbound-only and must be set on the device running --accept\",\n\t\t\t\t\t);\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (acceptText?.trim()) {\n\t\t\t\t\tif (opts.all && opts.default) {\n\t\t\t\t\t\tp.log.error(\"Use only one of --all or --default\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ((opts.all || opts.default) && (opts.include || opts.exclude)) {\n\t\t\t\t\t\tp.log.error(\"--include/--exclude cannot be combined with --all/--default\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet payload: Record<string, unknown>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpayload = JSON.parse(acceptText) as Record<string, unknown>;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tp.log.error(\n\t\t\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t\t\t? `Invalid pairing payload: ${error.message}`\n\t\t\t\t\t\t\t\t: \"Invalid pairing payload\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst deviceId = String(payload.device_id || \"\").trim();\n\t\t\t\t\tconst fingerprint = String(payload.fingerprint || \"\").trim();\n\t\t\t\t\tconst publicKey = String(payload.public_key || \"\").trim();\n\t\t\t\t\tconst resolvedAddresses = opts.address?.trim()\n\t\t\t\t\t\t? [opts.address.trim()]\n\t\t\t\t\t\t: Array.isArray(payload.addresses)\n\t\t\t\t\t\t\t? (payload.addresses as unknown[])\n\t\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t\t(item): item is string => typeof item === \"string\" && item.trim().length > 0,\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.map((item) => item.trim())\n\t\t\t\t\t\t\t: [];\n\t\t\t\t\tif (!deviceId || !fingerprint || !publicKey || resolvedAddresses.length === 0) {\n\t\t\t\t\t\tp.log.error(\"Pairing payload missing device_id, fingerprint, public_key, or addresses\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (fingerprintPublicKey(publicKey) !== fingerprint) {\n\t\t\t\t\t\tp.log.error(\"Pairing payload fingerprint mismatch\");\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tupdatePeerAddresses(store.db, deviceId, resolvedAddresses, {\n\t\t\t\t\t\tname: opts.name,\n\t\t\t\t\t\tpinnedFingerprint: fingerprint,\n\t\t\t\t\t\tpublicKey,\n\t\t\t\t\t});\n\n\t\t\t\t\tif (opts.default) {\n\t\t\t\t\t\tsetPeerProjectFilter(store.db, deviceId, { include: null, exclude: null });\n\t\t\t\t\t} else if (opts.all || opts.include || opts.exclude) {\n\t\t\t\t\t\tsetPeerProjectFilter(store.db, deviceId, {\n\t\t\t\t\t\t\tinclude: opts.all ? [] : parseProjectList(opts.include),\n\t\t\t\t\t\t\texclude: opts.all ? [] : parseProjectList(opts.exclude),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tp.log.success(`Paired with ${deviceId}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst keysDir = process.env.CODEMEM_KEYS_DIR?.trim() || undefined;\n\t\t\t\tconst [deviceId, fingerprint] = ensureDeviceIdentity(store.db, { keysDir });\n\t\t\t\tconst publicKey = loadPublicKey(keysDir);\n\t\t\t\tif (!publicKey) {\n\t\t\t\t\tp.log.error(\"Public key missing\");\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst config = readCodememConfigFile();\n\t\t\t\tconst explicitAddress = opts.address?.trim();\n\t\t\t\tconst configuredHost = typeof config.sync_host === \"string\" ? config.sync_host : null;\n\t\t\t\tconst configuredPort = typeof config.sync_port === \"number\" ? config.sync_port : 7337;\n\t\t\t\tconst addresses = collectAdvertiseAddresses(\n\t\t\t\t\texplicitAddress ?? null,\n\t\t\t\t\tconfiguredHost,\n\t\t\t\t\tconfiguredPort,\n\t\t\t\t\tnetworkInterfaces(),\n\t\t\t\t);\n\t\t\t\tconst payload = {\n\t\t\t\t\tdevice_id: deviceId,\n\t\t\t\t\tfingerprint,\n\t\t\t\t\tpublic_key: publicKey,\n\t\t\t\t\taddress: addresses[0] ?? \"\",\n\t\t\t\t\taddresses,\n\t\t\t\t};\n\t\t\t\tconst payloadText = JSON.stringify(payload);\n\n\t\t\t\tif (opts.payloadOnly) {\n\t\t\t\t\tprocess.stdout.write(`${payloadText}\\n`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst escaped = payloadText.replaceAll(\"'\", \"'\\\\''\");\n\t\t\t\tconsole.log(\"Pairing payload\");\n\t\t\t\tconsole.log(payloadText);\n\t\t\t\tconsole.log(\"On the other device, save this JSON to pairing.json, then run:\");\n\t\t\t\tconsole.log(\" codemem sync pair --accept-file pairing.json\");\n\t\t\t\tconsole.log(\"If you prefer inline JSON, run:\");\n\t\t\t\tconsole.log(` codemem sync pair --accept '${escaped}'`);\n\t\t\t\tconsole.log(\"For machine-friendly output next time, run:\");\n\t\t\t\tconsole.log(\" codemem sync pair --payload-only\");\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"On the accepting device, --include/--exclude control both what it sends and what it accepts from that peer.\",\n\t\t\t\t);\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\nsyncCommand.addCommand(\n\tnew Command(\"doctor\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Diagnose common sync setup and connectivity issues\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.action(async (opts: { db?: string; dbPath?: string }) => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconst dbPath = resolveDbPath(opts.db ?? opts.dbPath);\n\t\t\tconst store = new MemoryStore(dbPath);\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst device = d\n\t\t\t\t\t.select({ device_id: schema.syncDevice.device_id })\n\t\t\t\t\t.from(schema.syncDevice)\n\t\t\t\t\t.limit(1)\n\t\t\t\t\t.get();\n\t\t\t\tconst daemonState = d\n\t\t\t\t\t.select()\n\t\t\t\t\t.from(schema.syncDaemonState)\n\t\t\t\t\t.where(eq(schema.syncDaemonState.id, 1))\n\t\t\t\t\t.get();\n\t\t\t\tconst peers = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncPeers.peer_device_id,\n\t\t\t\t\t\taddresses_json: schema.syncPeers.addresses_json,\n\t\t\t\t\t\tpinned_fingerprint: schema.syncPeers.pinned_fingerprint,\n\t\t\t\t\t\tpublic_key: schema.syncPeers.public_key,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t.all();\n\n\t\t\t\tconst issues: string[] = [];\n\t\t\t\tconst syncHost = typeof config.sync_host === \"string\" ? config.sync_host : \"0.0.0.0\";\n\t\t\t\tconst syncPort = typeof config.sync_port === \"number\" ? config.sync_port : 7337;\n\t\t\t\tconst viewerBinding = readViewerBinding(dbPath);\n\n\t\t\t\tconsole.log(\"Sync doctor\");\n\t\t\t\tconsole.log(`- Enabled: ${config.sync_enabled === true}`);\n\t\t\t\tconsole.log(`- Listen: ${syncHost}:${syncPort}`);\n\t\t\t\tconsole.log(`- mDNS: ${process.env.CODEMEM_SYNC_MDNS ? \"env-configured\" : \"default/off\"}`);\n\n\t\t\t\tconst reachable = viewerBinding\n\t\t\t\t\t? await portOpen(viewerBinding.host, viewerBinding.port)\n\t\t\t\t\t: false;\n\t\t\t\tconsole.log(`- Daemon: ${reachable ? \"running\" : \"not running\"}`);\n\t\t\t\tif (!reachable) issues.push(\"daemon not running\");\n\n\t\t\t\tif (!device) {\n\t\t\t\t\tconsole.log(\"- Identity: missing (run `codemem sync enable`)\");\n\t\t\t\t\tissues.push(\"identity missing\");\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`- Identity: ${device.device_id}`);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tdaemonState?.last_error &&\n\t\t\t\t\t(!daemonState.last_ok_at || daemonState.last_ok_at < (daemonState.last_error_at ?? \"\"))\n\t\t\t\t) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`- Daemon error: ${daemonState.last_error} (at ${daemonState.last_error_at ?? \"unknown\"})`,\n\t\t\t\t\t);\n\t\t\t\t\tissues.push(\"daemon error\");\n\t\t\t\t}\n\n\t\t\t\tif (peers.length === 0) {\n\t\t\t\t\tconsole.log(\"- Peers: none (pair a device first)\");\n\t\t\t\t\tissues.push(\"no peers\");\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(`- Peers: ${peers.length}`);\n\t\t\t\t\tfor (const peer of peers) {\n\t\t\t\t\t\tconst addresses = peer.addresses_json\n\t\t\t\t\t\t\t? (JSON.parse(peer.addresses_json) as string[])\n\t\t\t\t\t\t\t: [];\n\t\t\t\t\t\tconst endpoint = parseStoredAddressEndpoint(addresses[0] ?? \"\");\n\t\t\t\t\t\tconst reach = endpoint\n\t\t\t\t\t\t\t? (await portOpen(endpoint.host, endpoint.port))\n\t\t\t\t\t\t\t\t? \"ok\"\n\t\t\t\t\t\t\t\t: \"unreachable\"\n\t\t\t\t\t\t\t: \"unknown\";\n\t\t\t\t\t\tconst pinned = Boolean(peer.pinned_fingerprint);\n\t\t\t\t\t\tconst hasKey = Boolean(peer.public_key);\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t` - ${peer.peer_device_id}: addresses=${addresses.length} reach=${reach} pinned=${pinned} public_key=${hasKey}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (reach !== \"ok\") issues.push(`peer ${peer.peer_device_id} unreachable`);\n\t\t\t\t\t\tif (!pinned || !hasKey) issues.push(`peer ${peer.peer_device_id} not pinned`);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!config.sync_enabled) issues.push(\"sync is disabled\");\n\n\t\t\t\tif (issues.length > 0) {\n\t\t\t\t\tconsole.log(`WARN: ${[...new Set(issues)].slice(0, 3).join(\", \")}`);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\"OK: sync looks healthy\");\n\t\t\t\t}\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\n// codemem sync status\nsyncCommand.addCommand(\n\tnew Command(\"status\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Show sync configuration and peer summary\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action((opts: { db?: string; dbPath?: string; json?: boolean }) => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst deviceRow = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tdevice_id: schema.syncDevice.device_id,\n\t\t\t\t\t\tfingerprint: schema.syncDevice.fingerprint,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncDevice)\n\t\t\t\t\t.limit(1)\n\t\t\t\t\t.get();\n\t\t\t\tconst peers = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncPeers.peer_device_id,\n\t\t\t\t\t\tname: schema.syncPeers.name,\n\t\t\t\t\t\tlast_sync_at: schema.syncPeers.last_sync_at,\n\t\t\t\t\t\tlast_error: schema.syncPeers.last_error,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t.all();\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tenabled: config.sync_enabled === true,\n\t\t\t\t\t\t\t\thost: config.sync_host ?? \"0.0.0.0\",\n\t\t\t\t\t\t\t\tport: config.sync_port ?? 7337,\n\t\t\t\t\t\t\t\tinterval_s: config.sync_interval_s ?? 120,\n\t\t\t\t\t\t\t\tdevice_id: deviceRow?.device_id ?? null,\n\t\t\t\t\t\t\t\tfingerprint: deviceRow?.fingerprint ?? null,\n\t\t\t\t\t\t\t\tcoordinator_url: config.sync_coordinator_url ?? null,\n\t\t\t\t\t\t\t\tpeers: peers.map((peer) => ({\n\t\t\t\t\t\t\t\t\tdevice_id: peer.peer_device_id,\n\t\t\t\t\t\t\t\t\tname: peer.name,\n\t\t\t\t\t\t\t\t\tlast_sync: peer.last_sync_at,\n\t\t\t\t\t\t\t\t\tstatus: peer.last_error ?? \"ok\",\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t2,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(\"codemem sync status\");\n\t\t\t\tp.log.info(\n\t\t\t\t\t[\n\t\t\t\t\t\t`Enabled: ${config.sync_enabled === true ? \"yes\" : \"no\"}`,\n\t\t\t\t\t\t`Host: ${config.sync_host ?? \"0.0.0.0\"}`,\n\t\t\t\t\t\t`Port: ${config.sync_port ?? 7337}`,\n\t\t\t\t\t\t`Interval: ${config.sync_interval_s ?? 120}s`,\n\t\t\t\t\t\t`Coordinator: ${config.sync_coordinator_url ?? \"(not configured)\"}`,\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t);\n\t\t\t\tif (deviceRow) {\n\t\t\t\t\tp.log.info(`Device ID: ${deviceRow.device_id}\\nFingerprint: ${deviceRow.fingerprint}`);\n\t\t\t\t} else {\n\t\t\t\t\tp.log.warn(\"Device identity not initialized (run `codemem sync enable`)\");\n\t\t\t\t}\n\t\t\t\tif (peers.length === 0) {\n\t\t\t\t\tp.log.info(\"Peers: none\");\n\t\t\t\t} else {\n\t\t\t\t\tfor (const peer of peers) {\n\t\t\t\t\t\tconst label = peer.name || peer.peer_device_id;\n\t\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t\t` ${label}: last_sync=${peer.last_sync_at ?? \"never\"}, status=${peer.last_error ?? \"ok\"}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.outro(`${peers.length} peer(s)`);\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\n// codemem sync enable\nsyncCommand.addCommand(\n\tnew Command(\"enable\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Enable sync and initialize device identity\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--host <host>\", \"sync listen host\")\n\t\t.option(\"--port <port>\", \"sync listen port\")\n\t\t.option(\"--interval <seconds>\", \"sync interval in seconds\")\n\t\t.action(\n\t\t\t(opts: { db?: string; dbPath?: string; host?: string; port?: string; interval?: string }) => {\n\t\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\t\ttry {\n\t\t\t\t\tconst [deviceId, fingerprint] = ensureDeviceIdentity(store.db);\n\t\t\t\t\tconst config = readCodememConfigFile();\n\t\t\t\t\tconfig.sync_enabled = true;\n\t\t\t\t\tif (opts.host) config.sync_host = opts.host;\n\t\t\t\t\tif (opts.port) config.sync_port = Number.parseInt(opts.port, 10);\n\t\t\t\t\tif (opts.interval) config.sync_interval_s = Number.parseInt(opts.interval, 10);\n\t\t\t\t\twriteCodememConfigFile(config);\n\n\t\t\t\t\tp.intro(\"codemem sync enable\");\n\t\t\t\t\tp.log.success(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t`Device ID: ${deviceId}`,\n\t\t\t\t\t\t\t`Fingerprint: ${fingerprint}`,\n\t\t\t\t\t\t\t`Host: ${config.sync_host ?? \"0.0.0.0\"}`,\n\t\t\t\t\t\t\t`Port: ${config.sync_port ?? 7337}`,\n\t\t\t\t\t\t\t`Interval: ${config.sync_interval_s ?? 120}s`,\n\t\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t\t);\n\t\t\t\t\tp.outro(\"Sync enabled — restart `codemem serve` to activate\");\n\t\t\t\t} finally {\n\t\t\t\t\tstore.close();\n\t\t\t\t}\n\t\t\t},\n\t\t),\n);\n\n// codemem sync disable\nsyncCommand.addCommand(\n\tnew Command(\"disable\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Disable sync without deleting keys or peers\")\n\t\t.action(() => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconfig.sync_enabled = false;\n\t\t\twriteCodememConfigFile(config);\n\t\t\tp.intro(\"codemem sync disable\");\n\t\t\tp.outro(\"Sync disabled — restart `codemem serve` to take effect\");\n\t\t}),\n);\n\n// codemem sync peers\nsyncCommand.addCommand(\n\tnew Command(\"peers\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"List known sync peers\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action((opts: { db?: string; dbPath?: string; json?: boolean }) => {\n\t\t\tconst store = new MemoryStore(resolveDbPath(opts.db ?? opts.dbPath));\n\t\t\ttry {\n\t\t\t\tconst d = drizzle(store.db, { schema });\n\t\t\t\tconst peers = d\n\t\t\t\t\t.select({\n\t\t\t\t\t\tpeer_device_id: schema.syncPeers.peer_device_id,\n\t\t\t\t\t\tname: schema.syncPeers.name,\n\t\t\t\t\t\taddresses: schema.syncPeers.addresses_json,\n\t\t\t\t\t\tlast_sync_at: schema.syncPeers.last_sync_at,\n\t\t\t\t\t\tlast_error: schema.syncPeers.last_error,\n\t\t\t\t\t})\n\t\t\t\t\t.from(schema.syncPeers)\n\t\t\t\t\t.orderBy(desc(schema.syncPeers.last_sync_at))\n\t\t\t\t\t.all();\n\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(peers, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tp.intro(\"codemem sync peers\");\n\t\t\t\tif (peers.length === 0) {\n\t\t\t\t\tp.outro(\"No peers configured\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const peer of peers) {\n\t\t\t\t\tconst label = peer.name || peer.peer_device_id;\n\t\t\t\t\tconst addrs = peer.addresses || \"(no addresses)\";\n\t\t\t\t\tp.log.message(\n\t\t\t\t\t\t`${label}\\n addresses: ${addrs}\\n last_sync: ${peer.last_sync_at ?? \"never\"}\\n status: ${peer.last_error ?? \"ok\"}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tp.outro(`${peers.length} peer(s)`);\n\t\t\t} finally {\n\t\t\t\tstore.close();\n\t\t\t}\n\t\t}),\n);\n\n// codemem sync connect <coordinator-url>\nsyncCommand.addCommand(\n\tnew Command(\"connect\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Configure coordinator URL for cloud sync\")\n\t\t.argument(\"<url>\", \"coordinator URL (e.g. https://coordinator.example.com)\")\n\t\t.option(\"--group <group>\", \"sync group ID\")\n\t\t.action((url: string, opts: { group?: string }) => {\n\t\t\tconst config = readCodememConfigFile();\n\t\t\tconfig.sync_coordinator_url = url.trim();\n\t\t\tif (opts.group) config.sync_coordinator_group = opts.group.trim();\n\t\t\twriteCodememConfigFile(config);\n\t\t\tp.intro(\"codemem sync connect\");\n\t\t\tp.log.success(`Coordinator: ${url.trim()}`);\n\t\t\tif (opts.group) p.log.info(`Group: ${opts.group.trim()}`);\n\t\t\tp.outro(\"Restart `codemem serve` to activate coordinator sync\");\n\t\t}),\n);\n\nconst coordinatorCommand = new Command(\"coordinator\")\n\t.configureHelp(helpStyle)\n\t.description(\"Manage coordinator invites, join requests, and relay server\");\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"serve\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Run the coordinator relay HTTP server\")\n\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t.option(\"--host <host>\", \"bind host\", \"127.0.0.1\")\n\t\t.option(\"--port <port>\", \"bind port\", \"7340\")\n\t\t.action(async (opts: { db?: string; dbPath?: string; host?: string; port?: string }) => {\n\t\t\tconst host = String(opts.host ?? \"127.0.0.1\").trim() || \"127.0.0.1\";\n\t\t\tconst port = Number.parseInt(String(opts.port ?? \"7340\"), 10);\n\t\t\tconst dbPath = opts.db ?? opts.dbPath ?? DEFAULT_COORDINATOR_DB_PATH;\n\t\t\tconst app = createCoordinatorApp({ dbPath });\n\t\t\tp.intro(\"codemem sync coordinator serve\");\n\t\t\tp.log.success(`Coordinator listening at http://${host}:${port}`);\n\t\t\tp.log.info(`DB: ${dbPath}`);\n\t\t\thonoServe({ fetch: app.fetch, hostname: host, port });\n\t\t}),\n);\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"create-invite\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Create a coordinator team invite\")\n\t\t.argument(\"[group]\", \"group id\")\n\t\t.option(\"--group <group>\", \"group id\")\n\t\t.option(\"--coordinator-url <url>\", \"coordinator URL override\")\n\t\t.option(\"--policy <policy>\", \"invite policy\", \"auto_admit\")\n\t\t.option(\"--ttl-hours <hours>\", \"invite TTL hours\", \"24\")\n\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t.option(\"--remote-url <url>\", \"remote coordinator URL override\")\n\t\t.option(\"--admin-secret <secret>\", \"remote coordinator admin secret override\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tgroupArg: string | undefined,\n\t\t\t\topts: {\n\t\t\t\t\tgroup?: string;\n\t\t\t\t\tcoordinatorUrl?: string;\n\t\t\t\t\tpolicy?: string;\n\t\t\t\t\tttlHours?: string;\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tremoteUrl?: string;\n\t\t\t\t\tadminSecret?: string;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst ttlHours = Number.parseInt(String(opts.ttlHours ?? \"24\"), 10);\n\t\t\t\tconst groupId = String(opts.group ?? \"\").trim() || String(groupArg ?? \"\").trim();\n\t\t\t\tconst result = await coordinatorCreateInviteAction({\n\t\t\t\t\tgroupId,\n\t\t\t\t\tcoordinatorUrl: opts.coordinatorUrl?.trim() || null,\n\t\t\t\t\tpolicy: String(opts.policy ?? \"auto_admit\").trim(),\n\t\t\t\t\tttlHours,\n\t\t\t\t\tcreatedBy: null,\n\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\tremoteUrl: opts.remoteUrl?.trim() || null,\n\t\t\t\t\tadminSecret: opts.adminSecret?.trim() || null,\n\t\t\t\t});\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem sync coordinator create-invite\");\n\t\t\t\tp.log.success(`Invite created for ${groupId}`);\n\t\t\t\tif (typeof result.link === \"string\") p.log.message(`- link: ${result.link}`);\n\t\t\t\tif (typeof result.encoded === \"string\") p.log.message(`- invite: ${result.encoded}`);\n\t\t\t\tp.outro(\"Invite ready\");\n\t\t\t},\n\t\t),\n);\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"import-invite\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"Import a coordinator invite\")\n\t\t.argument(\"<invite>\", \"invite value or link\")\n\t\t.option(\"--db <path>\", \"database path\")\n\t\t.option(\"--db-path <path>\", \"database path\")\n\t\t.option(\"--keys-dir <path>\", \"keys directory\")\n\t\t.option(\"--config <path>\", \"config path\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tinvite: string,\n\t\t\t\topts: { db?: string; dbPath?: string; keysDir?: string; config?: string; json?: boolean },\n\t\t\t) => {\n\t\t\t\tconst result = await coordinatorImportInviteAction({\n\t\t\t\t\tinviteValue: invite,\n\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\tkeysDir: opts.keysDir ?? null,\n\t\t\t\t\tconfigPath: opts.config ?? null,\n\t\t\t\t});\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(result, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem sync coordinator import-invite\");\n\t\t\t\tp.log.success(`Invite imported for ${result.group_id}`);\n\t\t\t\tp.log.message(`- coordinator: ${result.coordinator_url}`);\n\t\t\t\tp.log.message(`- status: ${result.status}`);\n\t\t\t\tp.outro(\"Coordinator config updated\");\n\t\t\t},\n\t\t),\n);\n\ncoordinatorCommand.addCommand(\n\tnew Command(\"list-join-requests\")\n\t\t.configureHelp(helpStyle)\n\t\t.description(\"List pending coordinator join requests\")\n\t\t.argument(\"[group]\", \"group id\")\n\t\t.option(\"--group <group>\", \"group id\")\n\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t.option(\"--remote-url <url>\", \"remote coordinator URL override\")\n\t\t.option(\"--admin-secret <secret>\", \"remote coordinator admin secret override\")\n\t\t.option(\"--json\", \"output as JSON\")\n\t\t.action(\n\t\t\tasync (\n\t\t\t\tgroupArg: string | undefined,\n\t\t\t\topts: {\n\t\t\t\t\tgroup?: string;\n\t\t\t\t\tdb?: string;\n\t\t\t\t\tdbPath?: string;\n\t\t\t\t\tremoteUrl?: string;\n\t\t\t\t\tadminSecret?: string;\n\t\t\t\t\tjson?: boolean;\n\t\t\t\t},\n\t\t\t) => {\n\t\t\t\tconst groupId = String(opts.group ?? \"\").trim() || String(groupArg ?? \"\").trim();\n\t\t\t\tconst rows = await coordinatorListJoinRequestsAction({\n\t\t\t\t\tgroupId,\n\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\tremoteUrl: opts.remoteUrl?.trim() || null,\n\t\t\t\t\tadminSecret: opts.adminSecret?.trim() || null,\n\t\t\t\t});\n\t\t\t\tif (opts.json) {\n\t\t\t\t\tconsole.log(JSON.stringify(rows, null, 2));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tp.intro(\"codemem sync coordinator list-join-requests\");\n\t\t\t\tif (rows.length === 0) {\n\t\t\t\t\tp.outro(`No pending join requests for ${groupId}`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const row of rows) {\n\t\t\t\t\tconst displayName = row.display_name || row.device_id;\n\t\t\t\t\tp.log.message(`- ${displayName} (${row.device_id}) request_id=${row.request_id}`);\n\t\t\t\t}\n\t\t\t\tp.outro(`${rows.length} pending join request(s)`);\n\t\t\t},\n\t\t),\n);\n\nfunction addReviewJoinRequestCommand(\n\tname: \"approve-join-request\" | \"deny-join-request\",\n\tapprove: boolean,\n) {\n\tcoordinatorCommand.addCommand(\n\t\tnew Command(name)\n\t\t\t.configureHelp(helpStyle)\n\t\t\t.description(`${approve ? \"Approve\" : \"Deny\"} a coordinator join request`)\n\t\t\t.argument(\"<request-id>\", \"join request id\")\n\t\t\t.option(\"--db <path>\", \"coordinator database path\")\n\t\t\t.option(\"--db-path <path>\", \"coordinator database path\")\n\t\t\t.option(\"--remote-url <url>\", \"remote coordinator URL override\")\n\t\t\t.option(\"--admin-secret <secret>\", \"remote coordinator admin secret override\")\n\t\t\t.option(\"--json\", \"output as JSON\")\n\t\t\t.action(\n\t\t\t\tasync (\n\t\t\t\t\trequestId: string,\n\t\t\t\t\topts: {\n\t\t\t\t\t\tdb?: string;\n\t\t\t\t\t\tdbPath?: string;\n\t\t\t\t\t\tremoteUrl?: string;\n\t\t\t\t\t\tadminSecret?: string;\n\t\t\t\t\t\tjson?: boolean;\n\t\t\t\t\t},\n\t\t\t\t) => {\n\t\t\t\t\tconst request = await coordinatorReviewJoinRequestAction({\n\t\t\t\t\t\trequestId: requestId.trim(),\n\t\t\t\t\t\tapprove,\n\t\t\t\t\t\treviewedBy: null,\n\t\t\t\t\t\tdbPath: opts.db ?? opts.dbPath ?? null,\n\t\t\t\t\t\tremoteUrl: opts.remoteUrl?.trim() || null,\n\t\t\t\t\t\tadminSecret: opts.adminSecret?.trim() || null,\n\t\t\t\t\t});\n\t\t\t\t\tif (!request) {\n\t\t\t\t\t\tp.log.error(`Join request not found: ${requestId.trim()}`);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (opts.json) {\n\t\t\t\t\t\tconsole.log(JSON.stringify(request, null, 2));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tp.intro(`codemem sync coordinator ${name}`);\n\t\t\t\t\tp.log.success(`${approve ? \"Approved\" : \"Denied\"} join request ${requestId.trim()}`);\n\t\t\t\t\tp.outro(String(request.status ?? \"updated\"));\n\t\t\t\t},\n\t\t\t),\n\t);\n}\n\naddReviewJoinRequestCommand(\"approve-join-request\", true);\naddReviewJoinRequestCommand(\"deny-join-request\", false);\n\nsyncCommand.addCommand(coordinatorCommand);\n","import { VERSION } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport { helpStyle } from \"../help-style.js\";\n\nexport const versionCommand = new Command(\"version\")\n\t.configureHelp(helpStyle)\n\t.description(\"Print codemem version\")\n\t.action(() => {\n\t\tconsole.log(VERSION);\n\t});\n","#!/usr/bin/env node\n\n/**\n * @codemem/cli — CLI entry point.\n *\n * Commands:\n * codemem stats → database statistics\n * codemem search → FTS5 memory search\n * codemem pack → context-aware memory pack\n * codemem serve → viewer server\n * codemem mcp → MCP stdio server\n */\n\nimport { VERSION } from \"@codemem/core\";\nimport { Command } from \"commander\";\nimport omelette from \"omelette\";\nimport { claudeHookIngestCommand } from \"./commands/claude-hook-ingest.js\";\nimport { dbCommand } from \"./commands/db.js\";\nimport { embedCommand } from \"./commands/embed.js\";\nimport { enqueueRawEventCommand } from \"./commands/enqueue-raw-event.js\";\nimport { exportMemoriesCommand } from \"./commands/export-memories.js\";\nimport { importMemoriesCommand } from \"./commands/import-memories.js\";\nimport { mcpCommand } from \"./commands/mcp.js\";\nimport {\n\tforgetMemoryCommand,\n\tmemoryCommand,\n\trememberMemoryCommand,\n\tshowMemoryCommand,\n} from \"./commands/memory.js\";\nimport { packCommand } from \"./commands/pack.js\";\nimport { recentCommand } from \"./commands/recent.js\";\nimport { searchCommand } from \"./commands/search.js\";\nimport { serveCommand } from \"./commands/serve.js\";\nimport { setupCommand } from \"./commands/setup.js\";\nimport { statsCommand } from \"./commands/stats.js\";\nimport { syncCommand } from \"./commands/sync.js\";\nimport { versionCommand } from \"./commands/version.js\";\nimport { helpStyle } from \"./help-style.js\";\n\ntype CompletionWithScriptGenerators = ReturnType<typeof omelette> & {\n\tgenerateCompletionCode: () => string;\n\tgenerateCompletionCodeFish: () => string;\n};\n\n// Shell completion (bash/zsh/fish)\nconst completion = omelette(\"codemem <command>\") as CompletionWithScriptGenerators;\ncompletion.on(\"command\", ({ reply }) => {\n\treply([\n\t\t\"claude-hook-ingest\",\n\t\t\"db\",\n\t\t\"embed\",\n\t\t\"export-memories\",\n\t\t\"forget\",\n\t\t\"memory\",\n\t\t\"import-memories\",\n\t\t\"setup\",\n\t\t\"show\",\n\t\t\"sync\",\n\t\t\"stats\",\n\t\t\"recent\",\n\t\t\"remember\",\n\t\t\"search\",\n\t\t\"pack\",\n\t\t\"serve\",\n\t\t\"mcp\",\n\t\t\"enqueue-raw-event\",\n\t\t\"version\",\n\t\t\"help\",\n\t\t\"--help\",\n\t\t\"--version\",\n\t]);\n});\ncompletion.init();\n\nfunction hasRootFlag(flag: string): boolean {\n\tfor (const arg of process.argv.slice(2)) {\n\t\tif (arg === \"--\") return false;\n\t\tif (arg === flag) return true;\n\t\tif (!arg.startsWith(\"-\")) return false;\n\t}\n\treturn false;\n}\n\nfunction getShellCompletionScript(): string {\n\tconst shellPath = process.env.SHELL ?? \"\";\n\tif (shellPath.includes(\"fish\")) {\n\t\treturn completion.generateCompletionCodeFish();\n\t}\n\treturn completion.generateCompletionCode();\n}\n\nconst program = new Command();\n\nprogram\n\t.name(\"codemem\")\n\t.description(\"codemem — persistent memory for AI coding agents\")\n\t.option(\"--install-completion\", \"install shell completion\")\n\t.option(\"--show-completion\", \"show shell completion install guidance\")\n\t.version(VERSION)\n\t.configureHelp(helpStyle);\n\nif (hasRootFlag(\"--setup-completion\") || hasRootFlag(\"--install-completion\")) {\n\tcompletion.setupShellInitFile();\n\tprocess.exit(0);\n}\n\nif (hasRootFlag(\"--show-completion\")) {\n\tconsole.log(getShellCompletionScript());\n\tprocess.exit(0);\n}\n\nif (hasRootFlag(\"--cleanup-completion\")) {\n\tcompletion.cleanupShellInitFile();\n\tprocess.exit(0);\n}\n\nprogram.addCommand(serveCommand);\nprogram.addCommand(mcpCommand);\nprogram.addCommand(claudeHookIngestCommand);\nprogram.addCommand(dbCommand);\nprogram.addCommand(exportMemoriesCommand);\nprogram.addCommand(importMemoriesCommand);\nprogram.addCommand(statsCommand);\nprogram.addCommand(embedCommand);\nprogram.addCommand(recentCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(packCommand);\nprogram.addCommand(showMemoryCommand);\nprogram.addCommand(forgetMemoryCommand);\nprogram.addCommand(rememberMemoryCommand);\nprogram.addCommand(memoryCommand);\nprogram.addCommand(syncCommand);\nprogram.addCommand(setupCommand);\nprogram.addCommand(enqueueRawEventCommand);\nprogram.addCommand(versionCommand);\n\nprogram.parse();\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codemem",
|
|
3
|
-
"version": "0.20.5
|
|
3
|
+
"version": "0.20.5",
|
|
4
4
|
"description": "Memory layer for AI coding agents — search, recall, and sync context across sessions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"commander": "^14.0.3",
|
|
21
21
|
"drizzle-orm": "^0.45.1",
|
|
22
22
|
"omelette": "^0.4.17",
|
|
23
|
-
"@codemem/core": "^0.20.5
|
|
24
|
-
"@codemem/
|
|
25
|
-
"@codemem/
|
|
23
|
+
"@codemem/core": "^0.20.5",
|
|
24
|
+
"@codemem/mcp": "^0.20.5",
|
|
25
|
+
"@codemem/server": "^0.20.5"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^25.5.0",
|