codemem 0.28.1 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { DEDUP_KEY_BACKFILL_JOB, DEFAULT_COORDINATOR_DB_PATH, DedupKeyBackfillRunner, MUTATING_TOOL_NAMES, MemoryStore, ObserverClient, REF_BACKFILL_JOB, RawEventSweeper, RefBackfillRunner, SESSION_CONTEXT_BACKFILL_JOB, SUMMARY_DEDUP_BACKFILL_JOB, SessionContextBackfillRunner, SummaryDedupBackfillRunner, SyncRetentionRunner, VERSION, VectorModelMigrationRunner, aiBackfillStructuredContent, applyBootstrapSnapshot, backfillMemoryDedupKeys, backfillNarrativeFromBody, backfillTagsText, backfillVectors, buildAuthHeaders, buildBaseUrl, buildRawEventEnvelopeFromHook, compareMemoryRoleReports, connect, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorDisableDeviceAction, coordinatorEnrollDeviceAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, createBetterSqliteCoordinatorApp, deactivateLowSignalMemories, deactivateLowSignalObservations, dedupNearDuplicateMemories, ensureDeviceIdentity, ensureSchemaBootstrapped, exportMemories, extractApplyPatchPaths, fetchAllSnapshotPages, fingerprintPublicKey, flushRawEvents, getExtractionBenchmarkProfile, getInjectionEvalScenarioPack, getInjectionEvalScenarioPrompts, getMaintenanceJob, getMemoryRoleReport, getRawEventRelinkPlan, getRawEventRelinkReport, getRawEventStatus, getSemanticIndexDiagnostics, getSessionExtractionEval, getSessionExtractionEvalScenario, getWorkspaceCodememConfigPath, hasPendingDedupKeyBackfill, hasPendingRefBackfill, hasPendingSessionContextBackfill, hasPendingSummaryDedupBackfill, hasUnsyncedSharedMemoryChanges, importMemories, initDatabase, isEmbeddingDisabled, loadObserverConfig, loadPublicKey, loadSqliteVec, planReplicationOpsAgePrune, pruneReplicationOpsUntilCaughtUp, rawEventsGate, readCodememConfigFile, readCodememConfigFileAtPath, readCoordinatorSyncConfig, readImportPayload, replayBatchExtraction, replayBatchExtractionWithTierRouting, requestJson, resolveCodememConfigPath, resolveDbPath, resolveHookProject, resolveProject, retryRawEventFailures, runSyncDaemon, runSyncPass, schema, setPeerProjectFilter, stripJsonComments, stripPrivateObj, stripTrailingCommas, syncPassPreflight, updatePeerAddresses, vacuumDatabase, writeCodememConfigFile } from "@codemem/core";
2
+ import { DEDUP_KEY_BACKFILL_JOB, DEFAULT_COORDINATOR_DB_PATH, DedupKeyBackfillRunner, MUTATING_TOOL_NAMES, MemoryStore, ObserverClient, REF_BACKFILL_JOB, RawEventSweeper, RefBackfillRunner, SESSION_CONTEXT_BACKFILL_JOB, SUMMARY_DEDUP_BACKFILL_JOB, SessionContextBackfillRunner, SummaryDedupBackfillRunner, SyncRetentionRunner, VERSION, VectorModelMigrationRunner, aiBackfillStructuredContent, applyBootstrapSnapshot, backfillMemoryDedupKeys, backfillNarrativeFromBody, backfillTagsText, backfillVectors, buildAuthHeaders, buildBaseUrl, buildRawEventEnvelopeFromHook, compareMemoryRoleReports, connect, coordinatorCreateGroupAction, coordinatorCreateInviteAction, coordinatorDisableDeviceAction, coordinatorEnrollDeviceAction, coordinatorImportInviteAction, coordinatorListBootstrapGrantsAction, coordinatorListDevicesAction, coordinatorListGroupsAction, coordinatorListJoinRequestsAction, coordinatorRemoveDeviceAction, coordinatorRenameDeviceAction, coordinatorReviewJoinRequestAction, coordinatorRevokeBootstrapGrantAction, createBetterSqliteCoordinatorApp, deactivateLowSignalMemories, deactivateLowSignalObservations, dedupNearDuplicateMemories, ensureDeviceIdentity, ensureSchemaBootstrapped, exportMemories, extractApplyPatchPaths, fetchAllSnapshotPages, fingerprintPublicKey, flushRawEvents, getExtractionBenchmarkProfile, getInjectionEvalScenarioPack, getInjectionEvalScenarioPrompts, getMaintenanceJob, getMemoryRoleReport, getRawEventRelinkPlan, getRawEventRelinkReport, getRawEventStatus, getSemanticIndexDiagnostics, getSessionExtractionEval, getSessionExtractionEvalScenario, getWorkspaceCodememConfigPath, hasPendingDedupKeyBackfill, hasPendingRefBackfill, hasPendingSessionContextBackfill, hasPendingSummaryDedupBackfill, hasUnsyncedSharedMemoryChanges, importMemories, initDatabase, isEmbeddingDisabled, listMaintenanceJobs, loadObserverConfig, loadPublicKey, loadSqliteVec, mdnsEnabled, planReplicationOpsAgePrune, pruneReplicationOpsUntilCaughtUp, rawEventsGate, readCodememConfigFile, readCodememConfigFileAtPath, readCoordinatorSyncConfig, readImportPayload, replayBatchExtraction, replayBatchExtractionWithTierRouting, requestJson, resolveCodememConfigPath, resolveDbPath, resolveHookProject, resolveProject, retryRawEventFailures, runSyncDaemon, runSyncPass, schema, setPeerProjectFilter, stripJsonComments, stripPrivateObj, stripTrailingCommas, syncPassPreflight, updatePeerAddresses, vacuumDatabase, writeCodememConfigFile } from "@codemem/core";
3
3
  import { Command, Option } from "commander";
4
4
  import omelette from "omelette";
5
5
  import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
@@ -102,8 +102,9 @@ var BOOLEAN_TOGGLE_VALUES = new Set([
102
102
  "no"
103
103
  ]);
104
104
  function expandHome$2(value) {
105
- if (value === "~") return homedir();
106
- if (value.startsWith("~/")) return join(homedir(), value.slice(2));
105
+ const home = process.env.HOME?.trim() || homedir();
106
+ if (value === "~") return home;
107
+ if (value.startsWith("~/")) return join(home, value.slice(2));
107
108
  return value;
108
109
  }
109
110
  function pluginLogPath() {
@@ -2575,6 +2576,78 @@ cmd$1.action((inputFile, opts) => {
2575
2576
  });
2576
2577
  var importMemoriesCommand = cmd$1;
2577
2578
  //#endregion
2579
+ //#region src/commands/maintenance.ts
2580
+ var maintenanceCmd = new Command("maintenance").configureHelp(helpStyle).description("Inspect background maintenance / backfill jobs");
2581
+ var statusCmd$1 = new Command("status").configureHelp(helpStyle).description("Print current status of all maintenance jobs");
2582
+ addDbOption(statusCmd$1);
2583
+ addJsonOption(statusCmd$1);
2584
+ statusCmd$1.action((opts) => {
2585
+ const store = new MemoryStore(resolveDbPath(resolveDbOpt(opts)));
2586
+ try {
2587
+ const jobs = listMaintenanceJobs(store.db);
2588
+ if (opts.json) {
2589
+ console.log(JSON.stringify({ jobs }, null, 2));
2590
+ return;
2591
+ }
2592
+ printJobsTable(jobs);
2593
+ } finally {
2594
+ store.close();
2595
+ }
2596
+ });
2597
+ maintenanceCmd.addCommand(statusCmd$1);
2598
+ var maintenanceCommand = maintenanceCmd;
2599
+ function printJobsTable(jobs) {
2600
+ p.intro("codemem maintenance");
2601
+ if (jobs.length === 0) {
2602
+ p.log.info("No maintenance jobs recorded in this database.");
2603
+ p.outro("done");
2604
+ return;
2605
+ }
2606
+ const statusRank = {
2607
+ running: 0,
2608
+ pending: 1,
2609
+ failed: 2,
2610
+ cancelled: 3,
2611
+ completed: 4
2612
+ };
2613
+ const sorted = [...jobs].sort((a, b) => {
2614
+ const rankDiff = (statusRank[a.status] ?? 9) - (statusRank[b.status] ?? 9);
2615
+ if (rankDiff !== 0) return rankDiff;
2616
+ return b.updated_at.localeCompare(a.updated_at);
2617
+ });
2618
+ for (const job of sorted) {
2619
+ const progress = formatProgress(job);
2620
+ const when = job.finished_at ? `finished ${shortAge(job.finished_at)} ago` : job.started_at ? `started ${shortAge(job.started_at)} ago` : `updated ${shortAge(job.updated_at)} ago`;
2621
+ const header = `${job.kind} · ${job.status}${progress ? ` · ${progress}` : ""} · ${when}`;
2622
+ const body = [
2623
+ job.title,
2624
+ job.message,
2625
+ job.error ? `error: ${job.error}` : null
2626
+ ].filter(Boolean).join("\n");
2627
+ (job.status === "failed" ? p.log.error : job.status === "completed" ? p.log.success : p.log.step)(`${header}\n${body}`);
2628
+ }
2629
+ p.outro("done");
2630
+ }
2631
+ function formatProgress(job) {
2632
+ const { current, total, unit } = job.progress;
2633
+ if (!current && !total) return null;
2634
+ const unitLabel = unit || "items";
2635
+ if (total == null || total <= 0) return `${current.toLocaleString()} ${unitLabel}`;
2636
+ const pct = Math.round(100 * current / total);
2637
+ return `${current.toLocaleString()}/${total.toLocaleString()} ${unitLabel} (${pct}%)`;
2638
+ }
2639
+ function shortAge(iso) {
2640
+ const parsed = Date.parse(iso);
2641
+ if (!Number.isFinite(parsed)) return iso;
2642
+ const seconds = Math.max(0, Math.round((Date.now() - parsed) / 1e3));
2643
+ if (seconds < 60) return `${seconds}s`;
2644
+ const minutes = Math.round(seconds / 60);
2645
+ if (minutes < 60) return `${minutes}m`;
2646
+ const hours = Math.round(minutes / 60);
2647
+ if (hours < 48) return `${hours}h`;
2648
+ return `${Math.round(hours / 24)}d`;
2649
+ }
2650
+ //#endregion
2578
2651
  //#region src/commands/mcp.ts
2579
2652
  var mcpCmd = new Command("mcp").configureHelp(helpStyle).description("Start the MCP stdio server");
2580
2653
  addDbOption(mcpCmd);
@@ -3881,7 +3954,10 @@ async function startForegroundViewer(invocation) {
3881
3954
  dbPath,
3882
3955
  signal: retentionAbort.signal
3883
3956
  });
3884
- const vectorMigrationRunner = new VectorModelMigrationRunner({ dbPath });
3957
+ const vectorMigrationRunner = new VectorModelMigrationRunner({
3958
+ dbPath,
3959
+ signal: backfillAbort.signal
3960
+ });
3885
3961
  const backfillCoordinator = createSequentialBackfillCoordinator(store, [
3886
3962
  {
3887
3963
  name: "Dedup-key",
@@ -4123,10 +4199,12 @@ serveCmd.addOption(new Option("--stop", "stop background viewer").hideHelp());
4123
4199
  serveCmd.addOption(new Option("--restart", "restart background viewer").hideHelp());
4124
4200
  var serveCommand = serveCmd.action(async (action, opts) => {
4125
4201
  try {
4126
- if (opts.stop) emitDeprecationWarning("--stop", "codemem serve stop");
4127
- if (opts.restart) emitDeprecationWarning("--restart", "codemem serve restart");
4128
- if (opts.background) emitDeprecationWarning("--background", "codemem serve start");
4129
- if (opts.foreground) emitDeprecationWarning("--foreground", "codemem serve start --foreground");
4202
+ if (action === void 0) {
4203
+ if (opts.stop) emitDeprecationWarning("--stop", "codemem serve stop");
4204
+ if (opts.restart) emitDeprecationWarning("--restart", "codemem serve restart");
4205
+ if (opts.background) emitDeprecationWarning("--background", "codemem serve start");
4206
+ if (opts.foreground) emitDeprecationWarning("--foreground", "codemem serve start --foreground");
4207
+ }
4130
4208
  const normalizedAction = action === void 0 ? void 0 : action === "start" || action === "stop" || action === "restart" ? action : null;
4131
4209
  if (normalizedAction === null) {
4132
4210
  p.log.error(`Unknown serve action: ${action}`);
@@ -4907,11 +4985,15 @@ doctorCmd.action(async (opts) => {
4907
4985
  if (reach !== "ok") issues.push(`peer ${peer.peer_device_id} unreachable`);
4908
4986
  if (!pinned || !hasKey) issues.push(`peer ${peer.peer_device_id} not pinned`);
4909
4987
  }
4988
+ const mdnsActive = mdnsEnabled();
4989
+ const mdnsSource = process.env.CODEMEM_SYNC_MDNS ? "env" : config.sync_mdns ? "config" : null;
4990
+ const mdnsLabel = mdnsActive ? mdnsSource === "env" ? "enabled (env)" : "enabled (config)" : "disabled";
4910
4991
  if (opts.json) {
4911
4992
  console.log(JSON.stringify({
4912
4993
  enabled: config.sync_enabled === true,
4913
4994
  listen: `${syncHost}:${syncPort}`,
4914
- mdns: process.env.CODEMEM_SYNC_MDNS ? "env-configured" : "default/off",
4995
+ mdns: mdnsLabel,
4996
+ mdns_source: mdnsSource,
4915
4997
  daemon: reachable ? "running" : "not running",
4916
4998
  identity: device?.device_id ?? null,
4917
4999
  daemon_error: daemonState?.last_error ?? null,
@@ -4924,7 +5006,7 @@ doctorCmd.action(async (opts) => {
4924
5006
  console.log("Sync doctor");
4925
5007
  console.log(`- Enabled: ${config.sync_enabled === true}`);
4926
5008
  console.log(`- Listen: ${syncHost}:${syncPort}`);
4927
- console.log(`- mDNS: ${process.env.CODEMEM_SYNC_MDNS ? "env-configured" : "default/off"}`);
5009
+ console.log(`- mDNS: ${mdnsLabel}`);
4928
5010
  console.log(`- Daemon: ${reachable ? "running" : "not running"}`);
4929
5011
  if (!device) console.log("- Identity: missing (run `codemem sync enable`)");
4930
5012
  else console.log(`- Identity: ${device.device_id}`);
@@ -5417,6 +5499,7 @@ program.addCommand(dbCommand);
5417
5499
  program.addCommand(exportMemoriesCommand);
5418
5500
  program.addCommand(importMemoriesCommand);
5419
5501
  program.addCommand(statsCommand);
5502
+ program.addCommand(maintenanceCommand);
5420
5503
  program.addCommand(embedCommand);
5421
5504
  program.addCommand(recentCommand);
5422
5505
  program.addCommand(searchCommand);