@memories.sh/cli 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +837 -550
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -32,7 +32,8 @@ import { Command as Command29 } from "commander";
32
32
 
33
33
  // src/commands/init.ts
34
34
  import { Command } from "commander";
35
- import chalk2 from "chalk";
35
+ import chalk3 from "chalk";
36
+ import { confirm, checkbox } from "@inquirer/prompts";
36
37
 
37
38
  // src/lib/auth.ts
38
39
  import { readFile, writeFile, mkdir, unlink } from "fs/promises";
@@ -76,8 +77,123 @@ function getApiClient(auth) {
76
77
  };
77
78
  }
78
79
 
79
- // src/lib/ui.ts
80
+ // src/lib/setup.ts
81
+ import { existsSync as existsSync2 } from "fs";
82
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
83
+ import { join as join2, dirname } from "path";
84
+ import { homedir as homedir2 } from "os";
80
85
  import chalk from "chalk";
86
+ var TOOLS = [
87
+ {
88
+ name: "Cursor",
89
+ configDir: ".cursor",
90
+ mcpConfigPath: ".cursor/mcp.json",
91
+ mcpConfigFormat: "cursor",
92
+ instructionFile: ".cursor/rules/memories.mdc",
93
+ generateCmd: "cursor"
94
+ },
95
+ {
96
+ name: "Claude Code",
97
+ configDir: ".claude",
98
+ mcpConfigPath: ".mcp.json",
99
+ mcpConfigFormat: "claude",
100
+ instructionFile: "CLAUDE.md",
101
+ generateCmd: "claude"
102
+ },
103
+ {
104
+ name: "Windsurf",
105
+ configDir: ".windsurf",
106
+ mcpConfigPath: ".windsurf/mcp.json",
107
+ mcpConfigFormat: "cursor",
108
+ instructionFile: ".windsurf/rules/memories.md",
109
+ generateCmd: "windsurf"
110
+ },
111
+ {
112
+ name: "VS Code",
113
+ configDir: ".vscode",
114
+ mcpConfigPath: ".vscode/mcp.json",
115
+ mcpConfigFormat: "vscode",
116
+ instructionFile: ".github/copilot-instructions.md",
117
+ generateCmd: "copilot"
118
+ }
119
+ ];
120
+ var MEMORIES_MCP_CONFIG = {
121
+ command: "npx",
122
+ args: ["-y", "@memories.sh/cli", "serve"]
123
+ };
124
+ function getAllTools() {
125
+ return [...TOOLS];
126
+ }
127
+ function detectTools(cwd = process.cwd()) {
128
+ const home = homedir2();
129
+ const detected = [];
130
+ for (const tool of TOOLS) {
131
+ const projectConfigDir = join2(cwd, tool.configDir);
132
+ const projectMcpPath = join2(cwd, tool.mcpConfigPath);
133
+ const projectInstructionPath = join2(cwd, tool.instructionFile);
134
+ const globalConfigDir = join2(home, tool.configDir);
135
+ const globalMcpPath = join2(home, tool.mcpConfigPath);
136
+ const hasProjectConfig = existsSync2(projectConfigDir);
137
+ const hasGlobalConfig = existsSync2(globalConfigDir);
138
+ if (hasProjectConfig || hasGlobalConfig) {
139
+ detected.push({
140
+ tool,
141
+ hasConfig: hasProjectConfig || hasGlobalConfig,
142
+ hasMcp: existsSync2(projectMcpPath) || existsSync2(globalMcpPath),
143
+ hasInstructions: existsSync2(projectInstructionPath),
144
+ globalConfig: !hasProjectConfig && hasGlobalConfig
145
+ });
146
+ }
147
+ }
148
+ return detected;
149
+ }
150
+ async function setupMcp(tool, options = {}) {
151
+ const { cwd = process.cwd(), global: useGlobal = false, dryRun = false } = options;
152
+ const home = homedir2();
153
+ const configPath = useGlobal ? join2(home, tool.mcpConfigPath) : join2(cwd, tool.mcpConfigPath);
154
+ try {
155
+ let config = {};
156
+ if (existsSync2(configPath)) {
157
+ const content = await readFile2(configPath, "utf-8");
158
+ config = JSON.parse(content);
159
+ }
160
+ const serversKey = tool.mcpConfigFormat === "vscode" ? "servers" : "mcpServers";
161
+ const servers = config[serversKey] ?? {};
162
+ if (servers.memories) {
163
+ return {
164
+ success: true,
165
+ message: "MCP already configured",
166
+ path: configPath
167
+ };
168
+ }
169
+ config[serversKey] = {
170
+ ...servers,
171
+ memories: MEMORIES_MCP_CONFIG
172
+ };
173
+ if (dryRun) {
174
+ return {
175
+ success: true,
176
+ message: `Would add MCP config to ${configPath}`,
177
+ path: configPath
178
+ };
179
+ }
180
+ await mkdir2(dirname(configPath), { recursive: true });
181
+ await writeFile2(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
182
+ return {
183
+ success: true,
184
+ message: "MCP configured",
185
+ path: configPath
186
+ };
187
+ } catch (error2) {
188
+ return {
189
+ success: false,
190
+ message: `Failed to setup MCP: ${error2 instanceof Error ? error2.message : "Unknown error"}`
191
+ };
192
+ }
193
+ }
194
+
195
+ // src/lib/ui.ts
196
+ import chalk2 from "chalk";
81
197
  import figlet from "figlet";
82
198
  import gradient from "gradient-string";
83
199
  import boxen from "boxen";
@@ -88,25 +204,25 @@ function banner() {
88
204
  horizontalLayout: "fitted"
89
205
  });
90
206
  console.log(memoriesGradient(text));
91
- console.log(chalk.dim(" One memory, every AI tool\n"));
207
+ console.log(chalk2.dim(" One memory, every AI tool\n"));
92
208
  }
93
209
  function success(message) {
94
- console.log(chalk.green("\u2713") + " " + message);
210
+ console.log(chalk2.green("\u2713") + " " + message);
95
211
  }
96
212
  function warn(message) {
97
- console.log(chalk.yellow("\u26A0") + " " + message);
213
+ console.log(chalk2.yellow("\u26A0") + " " + message);
98
214
  }
99
215
  function error(message) {
100
- console.log(chalk.red("\u2717") + " " + message);
216
+ console.log(chalk2.red("\u2717") + " " + message);
101
217
  }
102
218
  function info(message) {
103
- console.log(chalk.blue("\u2139") + " " + message);
219
+ console.log(chalk2.blue("\u2139") + " " + message);
104
220
  }
105
221
  function step(num, total, message) {
106
- console.log(chalk.dim(`[${num}/${total}]`) + " " + message);
222
+ console.log(chalk2.dim(`[${num}/${total}]`) + " " + message);
107
223
  }
108
224
  function dim(message) {
109
- console.log(chalk.dim(" " + message));
225
+ console.log(chalk2.dim(" " + message));
110
226
  }
111
227
  function box(content, title) {
112
228
  console.log(
@@ -121,33 +237,28 @@ function box(content, title) {
121
237
  );
122
238
  }
123
239
  function nextSteps(steps) {
124
- const content = steps.map((s) => chalk.dim("\u2192 ") + s).join("\n");
125
- box(content, chalk.bold("Next steps"));
240
+ const content = steps.map((s) => chalk2.dim("\u2192 ") + s).join("\n");
241
+ box(content, chalk2.bold("Next steps"));
126
242
  }
127
243
  function proFeature(feature) {
128
244
  console.log(
129
- chalk.yellow("\u2B50") + " " + chalk.dim(`${feature} requires `) + chalk.bold("Pro") + chalk.dim(". Run ") + chalk.cyan("memories login") + chalk.dim(" to upgrade.")
245
+ chalk2.yellow("\u2B50") + " " + chalk2.dim(`${feature} requires `) + chalk2.bold("Pro") + chalk2.dim(". Run ") + chalk2.cyan("memories login") + chalk2.dim(" to upgrade.")
130
246
  );
131
247
  }
132
248
 
133
249
  // src/commands/init.ts
134
- var SUPPORTED_TOOLS = [
135
- { name: "Cursor", cmd: "cursor" },
136
- { name: "Claude Code", cmd: "claude" },
137
- { name: "GitHub Copilot", cmd: "copilot" },
138
- { name: "Windsurf", cmd: "windsurf" },
139
- { name: "Gemini CLI", cmd: "gemini" }
140
- ];
141
- var initCommand = new Command("init").description("Initialize memories - one place for all your AI coding tools").option("-g, --global", "Initialize global rules (apply to all projects)").option("-r, --rule <rule>", "Add an initial rule", (val, acc) => [...acc, val], []).action(async (opts) => {
250
+ import { execSync } from "child_process";
251
+ var initCommand = new Command("init").description("Initialize memories - set up MCP and instruction files for your AI tools").option("-g, --global", "Initialize global rules (apply to all projects)").option("-r, --rule <rule>", "Add an initial rule", (val, acc) => [...acc, val], []).option("--skip-mcp", "Skip MCP configuration").option("--skip-generate", "Skip generating instruction files").option("-y, --yes", "Auto-confirm all prompts").action(async (opts) => {
142
252
  try {
143
253
  banner();
144
- console.log(chalk2.dim(" One place for your rules. Works with every tool.\n"));
145
- step(1, 3, "Setting up rule storage...");
254
+ console.log(chalk3.dim(" One place for your rules. Works with every tool.\n"));
255
+ step(1, 4, "Setting up local storage...");
146
256
  await getDb();
147
257
  const configDir = getConfigDir();
148
- dim(`Location: ${configDir}/local.db`);
149
- step(2, 3, "Detecting scope...");
258
+ dim(`Database: ${configDir}/local.db`);
259
+ step(2, 4, "Detecting scope...");
150
260
  let useGlobal = opts.global;
261
+ const cwd = process.cwd();
151
262
  if (!useGlobal) {
152
263
  const projectId = getProjectId();
153
264
  const gitRoot = getGitRoot();
@@ -158,48 +269,123 @@ var initCommand = new Command("init").description("Initialize memories - one pla
158
269
  success("Project scope detected");
159
270
  dim(`Project: ${projectId}`);
160
271
  dim(`Root: ${gitRoot}`);
161
- dim("Use --global for rules that apply everywhere");
162
272
  }
163
273
  } else {
164
274
  success("Global scope (rules apply to all projects)");
165
275
  }
166
- step(3, 3, "Supported tools...");
167
- const toolList = SUPPORTED_TOOLS.map((t) => t.name).join(", ");
168
- success(`${toolList}, + any MCP client`);
276
+ step(3, 4, "Detecting AI coding tools...");
277
+ let detected = detectTools(cwd);
278
+ if (detected.length === 0) {
279
+ dim("No AI coding tools auto-detected.");
280
+ if (!opts.skipMcp) {
281
+ const allTools = getAllTools();
282
+ const selected = await checkbox({
283
+ message: "Which tools do you want to configure?",
284
+ choices: allTools.map((t) => ({
285
+ name: t.name,
286
+ value: t,
287
+ checked: false
288
+ }))
289
+ });
290
+ if (selected.length > 0) {
291
+ detected = selected.map((tool) => ({
292
+ tool,
293
+ hasConfig: false,
294
+ hasMcp: false,
295
+ hasInstructions: false,
296
+ globalConfig: false
297
+ }));
298
+ }
299
+ }
300
+ }
301
+ if (detected.length === 0) {
302
+ dim("No tools selected. MCP will work with any tool that supports it.");
303
+ } else {
304
+ for (const d of detected) {
305
+ const scope = d.globalConfig ? chalk3.dim(" [global]") : "";
306
+ const mcpStatus = d.hasMcp ? chalk3.green("\u2713 MCP") : chalk3.dim("\u25CB MCP");
307
+ const rulesStatus = d.hasInstructions ? chalk3.green("\u2713 Rules") : chalk3.dim("\u25CB Rules");
308
+ console.log(` ${chalk3.white(d.tool.name)}${scope} ${mcpStatus} ${rulesStatus}`);
309
+ }
310
+ if (!opts.skipMcp) {
311
+ const toolsNeedingMcp = detected.filter((d) => !d.hasMcp);
312
+ if (toolsNeedingMcp.length > 0) {
313
+ console.log("");
314
+ const shouldSetupMcp = opts.yes || await confirm({
315
+ message: `Configure MCP for ${toolsNeedingMcp.map((d) => d.tool.name).join(", ")}?`,
316
+ default: true
317
+ });
318
+ if (shouldSetupMcp) {
319
+ for (const d of toolsNeedingMcp) {
320
+ const result = await setupMcp(d.tool, {
321
+ cwd,
322
+ global: d.globalConfig
323
+ });
324
+ if (result.success) {
325
+ success(`${d.tool.name}: ${result.message}`);
326
+ if (result.path) dim(` \u2192 ${result.path}`);
327
+ } else {
328
+ warn(`${d.tool.name}: ${result.message}`);
329
+ }
330
+ }
331
+ }
332
+ }
333
+ }
334
+ if (!opts.skipGenerate) {
335
+ const toolsNeedingInstructions = detected.filter((d) => !d.hasInstructions);
336
+ const memories = await listMemories({ limit: 1 });
337
+ if (toolsNeedingInstructions.length > 0 && memories.length > 0) {
338
+ console.log("");
339
+ const shouldGenerate = opts.yes || await confirm({
340
+ message: `Generate instruction files for ${toolsNeedingInstructions.map((d) => d.tool.name).join(", ")}?`,
341
+ default: true
342
+ });
343
+ if (shouldGenerate) {
344
+ for (const d of toolsNeedingInstructions) {
345
+ try {
346
+ execSync(`node ${process.argv[1]} generate ${d.tool.generateCmd} --force`, {
347
+ cwd,
348
+ stdio: "pipe"
349
+ });
350
+ success(`${d.tool.name}: Generated ${d.tool.instructionFile}`);
351
+ } catch {
352
+ warn(`${d.tool.name}: Failed to generate instructions`);
353
+ }
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+ step(4, 4, "Finalizing...");
169
360
  if (opts.rule?.length) {
170
- console.log("");
171
361
  info("Adding rules...");
172
362
  for (const rule of opts.rule) {
173
- const memory = await addMemory(rule, {
363
+ await addMemory(rule, {
174
364
  type: "rule",
175
365
  global: useGlobal
176
366
  });
177
367
  dim(`+ ${rule}`);
178
368
  }
179
369
  }
180
- console.log("");
181
370
  const auth = await readAuth();
182
371
  if (auth) {
183
- success(`Syncing as ${chalk2.bold(auth.email)}`);
372
+ success(`Syncing as ${chalk3.bold(auth.email)}`);
184
373
  } else {
185
- dim("Local only. Run " + chalk2.cyan("memories login") + " to sync across machines.");
374
+ dim("Local only. Run " + chalk3.cyan("memories login") + " to sync across machines.");
186
375
  }
187
376
  console.log("");
188
- console.log(chalk2.bold(" Quick Start:"));
377
+ console.log(chalk3.bold(" Quick Start:"));
189
378
  console.log("");
190
- console.log(chalk2.dim(" 1. Add your rules:"));
191
- console.log(` ${chalk2.cyan("memories add --rule")} ${chalk2.dim('"Always use TypeScript strict mode"')}`);
192
- console.log(` ${chalk2.cyan("memories add --rule")} ${chalk2.dim('"Prefer functional components in React"')}`);
379
+ console.log(chalk3.dim(" Add rules:"));
380
+ console.log(` ${chalk3.cyan("memories add --rule")} ${chalk3.dim('"Always use TypeScript strict mode"')}`);
193
381
  console.log("");
194
- console.log(chalk2.dim(" 2. Generate for your tools:"));
195
- console.log(` ${chalk2.cyan("memories generate cursor")} ${chalk2.dim("\u2192 .cursor/rules/memories.mdc")}`);
196
- console.log(` ${chalk2.cyan("memories generate claude")} ${chalk2.dim("\u2192 CLAUDE.md")}`);
197
- console.log(` ${chalk2.cyan("memories generate copilot")} ${chalk2.dim("\u2192 .github/copilot-instructions.md")}`);
198
- console.log(` ${chalk2.cyan("memories generate all")} ${chalk2.dim("\u2192 all tools at once")}`);
382
+ console.log(chalk3.dim(" Regenerate instruction files after adding rules:"));
383
+ console.log(` ${chalk3.cyan("memories generate all")}`);
199
384
  console.log("");
200
- console.log(chalk2.dim(" 3. Switch tools anytime - your rules follow you."));
385
+ console.log(chalk3.dim(" Your rules will be available via MCP and in generated files."));
201
386
  console.log("");
202
387
  } catch (error2) {
388
+ if (error2.name === "ExitPromptError") return;
203
389
  error("Failed to initialize: " + (error2 instanceof Error ? error2.message : "Unknown error"));
204
390
  process.exit(1);
205
391
  }
@@ -207,7 +393,7 @@ var initCommand = new Command("init").description("Initialize memories - one pla
207
393
 
208
394
  // src/commands/add.ts
209
395
  import { Command as Command2 } from "commander";
210
- import chalk3 from "chalk";
396
+ import chalk4 from "chalk";
211
397
 
212
398
  // src/lib/templates.ts
213
399
  import { input } from "@inquirer/prompts";
@@ -370,7 +556,7 @@ var addCommand = new Command2("add").description("Add a new memory").argument("[
370
556
  else if (opts.fact) type = "fact";
371
557
  else if (opts.type) {
372
558
  if (!VALID_TYPES.includes(opts.type)) {
373
- console.error(chalk3.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES.join(", ")}`);
559
+ console.error(chalk4.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES.join(", ")}`);
374
560
  process.exit(1);
375
561
  }
376
562
  type = opts.type;
@@ -378,11 +564,11 @@ var addCommand = new Command2("add").description("Add a new memory").argument("[
378
564
  const memory = await addMemory(content, { tags, global: opts.global, type });
379
565
  const typeLabel = type === "rule" ? "Rule" : type === "decision" ? "Decision" : type === "fact" ? "Fact" : "Note";
380
566
  const scopeInfo = memory.scope === "global" ? "global" : "project";
381
- success(`Stored ${chalk3.bold(typeLabel.toLowerCase())} ${chalk3.dim(memory.id)}`);
567
+ success(`Stored ${chalk4.bold(typeLabel.toLowerCase())} ${chalk4.dim(memory.id)}`);
382
568
  dim(`Scope: ${scopeInfo}${tags?.length ? ` \u2022 Tags: ${tags.join(", ")}` : ""}`);
383
569
  if (type === "rule") {
384
570
  console.log("");
385
- dim(`Run ${chalk3.cyan("memories generate")} to update your IDE rule files`);
571
+ dim(`Run ${chalk4.cyan("memories generate")} to update your IDE rule files`);
386
572
  }
387
573
  } catch (error2) {
388
574
  error("Failed to add memory: " + (error2 instanceof Error ? error2.message : "Unknown error"));
@@ -392,7 +578,7 @@ var addCommand = new Command2("add").description("Add a new memory").argument("[
392
578
 
393
579
  // src/commands/recall.ts
394
580
  import { Command as Command3 } from "commander";
395
- import chalk4 from "chalk";
581
+ import chalk5 from "chalk";
396
582
  var TYPE_ICONS = {
397
583
  rule: "\u{1F4CC}",
398
584
  decision: "\u{1F4A1}",
@@ -400,18 +586,18 @@ var TYPE_ICONS = {
400
586
  note: "\u{1F4DD}"
401
587
  };
402
588
  var TYPE_COLORS = {
403
- rule: chalk4.yellow,
404
- decision: chalk4.cyan,
405
- fact: chalk4.green,
406
- note: chalk4.white
589
+ rule: chalk5.yellow,
590
+ decision: chalk5.cyan,
591
+ fact: chalk5.green,
592
+ note: chalk5.white
407
593
  };
408
594
  function formatMemory(m, verbose) {
409
595
  const icon = TYPE_ICONS[m.type] || "\u{1F4DD}";
410
- const colorFn = TYPE_COLORS[m.type] || chalk4.white;
411
- const scope = m.scope === "global" ? chalk4.dim("G") : chalk4.dim("P");
412
- const tags = m.tags ? chalk4.dim(` [${m.tags}]`) : "";
596
+ const colorFn = TYPE_COLORS[m.type] || chalk5.white;
597
+ const scope = m.scope === "global" ? chalk5.dim("G") : chalk5.dim("P");
598
+ const tags = m.tags ? chalk5.dim(` [${m.tags}]`) : "";
413
599
  if (verbose) {
414
- return `${icon} ${scope} ${chalk4.dim(m.id)} ${colorFn(m.content)}${tags}`;
600
+ return `${icon} ${scope} ${chalk5.dim(m.id)} ${colorFn(m.content)}${tags}`;
415
601
  }
416
602
  return `${icon} ${colorFn(m.content)}`;
417
603
  }
@@ -425,11 +611,11 @@ var recallCommand = new Command3("recall").description("Recall context - get rul
425
611
  return;
426
612
  }
427
613
  if (rules2.length === 0) {
428
- console.log(chalk4.dim("No rules defined."));
429
- console.log(chalk4.dim('Add one with: memories add --rule "Your rule here"'));
614
+ console.log(chalk5.dim("No rules defined."));
615
+ console.log(chalk5.dim('Add one with: memories add --rule "Your rule here"'));
430
616
  return;
431
617
  }
432
- console.log(chalk4.bold("Rules:"));
618
+ console.log(chalk5.bold("Rules:"));
433
619
  for (const rule of rules2) {
434
620
  console.log(formatMemory(rule, opts.verbose ?? false));
435
621
  }
@@ -444,26 +630,26 @@ var recallCommand = new Command3("recall").description("Recall context - get rul
444
630
  return;
445
631
  }
446
632
  if (rules.length > 0) {
447
- console.log(chalk4.bold("Rules:"));
633
+ console.log(chalk5.bold("Rules:"));
448
634
  for (const rule of rules) {
449
635
  console.log(formatMemory(rule, opts.verbose ?? false));
450
636
  }
451
637
  console.log("");
452
638
  }
453
639
  if (memories.length > 0) {
454
- console.log(chalk4.bold(query ? `Relevant to "${query}":` : "Recent memories:"));
640
+ console.log(chalk5.bold(query ? `Relevant to "${query}":` : "Recent memories:"));
455
641
  for (const m of memories) {
456
642
  console.log(formatMemory(m, opts.verbose ?? false));
457
643
  }
458
644
  } else if (query) {
459
- console.log(chalk4.dim(`No memories found matching "${query}"`));
645
+ console.log(chalk5.dim(`No memories found matching "${query}"`));
460
646
  }
461
647
  if (rules.length === 0 && memories.length === 0) {
462
- console.log(chalk4.dim("No memories found."));
463
- console.log(chalk4.dim('Add some with: memories add "Your memory here"'));
648
+ console.log(chalk5.dim("No memories found."));
649
+ console.log(chalk5.dim('Add some with: memories add "Your memory here"'));
464
650
  }
465
651
  } catch (error2) {
466
- console.error(chalk4.red("\u2717") + " Failed to recall:", error2 instanceof Error ? error2.message : "Unknown error");
652
+ console.error(chalk5.red("\u2717") + " Failed to recall:", error2 instanceof Error ? error2.message : "Unknown error");
467
653
  process.exit(1);
468
654
  }
469
655
  });
@@ -471,7 +657,7 @@ var recallCommand = new Command3("recall").description("Recall context - get rul
471
657
  // src/commands/prompt.ts
472
658
  import { Command as Command4 } from "commander";
473
659
  import { execFileSync } from "child_process";
474
- import chalk5 from "chalk";
660
+ import chalk6 from "chalk";
475
661
  var VALID_TYPES2 = ["rule", "decision", "fact", "note"];
476
662
  function formatMarkdown(sections) {
477
663
  return sections.map(({ title, memories }) => {
@@ -514,7 +700,7 @@ var promptCommand = new Command4("prompt").description("Output memories formatte
514
700
  try {
515
701
  const format = opts.format ?? "markdown";
516
702
  if (!["markdown", "xml", "plain"].includes(format)) {
517
- console.error(chalk5.red("\u2717") + ` Invalid format "${opts.format}". Use: markdown, xml, plain`);
703
+ console.error(chalk6.red("\u2717") + ` Invalid format "${opts.format}". Use: markdown, xml, plain`);
518
704
  process.exit(1);
519
705
  }
520
706
  const projectId = getProjectId() ?? void 0;
@@ -526,7 +712,7 @@ var promptCommand = new Command4("prompt").description("Output memories formatte
526
712
  for (const t of opts.include.split(",").map((s) => s.trim())) {
527
713
  const normalized = t.replace(/s$/, "");
528
714
  if (!VALID_TYPES2.includes(normalized)) {
529
- console.error(chalk5.red("\u2717") + ` Invalid type "${t}". Valid: decisions, facts, notes`);
715
+ console.error(chalk6.red("\u2717") + ` Invalid type "${t}". Valid: decisions, facts, notes`);
530
716
  process.exit(1);
531
717
  }
532
718
  if (normalized !== "rule") extraTypes.push(normalized);
@@ -555,7 +741,7 @@ var promptCommand = new Command4("prompt").description("Output memories formatte
555
741
  }
556
742
  if (sections.length === 0) {
557
743
  if (!opts.quiet) {
558
- console.error(chalk5.dim('No memories found. Add rules with: memories add --rule "Your rule"'));
744
+ console.error(chalk6.dim('No memories found. Add rules with: memories add --rule "Your rule"'));
559
745
  }
560
746
  return;
561
747
  }
@@ -575,26 +761,26 @@ var promptCommand = new Command4("prompt").description("Output memories formatte
575
761
  if (copied) {
576
762
  console.log(output);
577
763
  if (!opts.quiet) {
578
- console.error(chalk5.green("\u2713") + " Copied to clipboard");
764
+ console.error(chalk6.green("\u2713") + " Copied to clipboard");
579
765
  }
580
766
  } else {
581
767
  console.log(output);
582
768
  if (!opts.quiet) {
583
- console.error(chalk5.yellow("\u26A0") + " Could not copy to clipboard (unsupported platform)");
769
+ console.error(chalk6.yellow("\u26A0") + " Could not copy to clipboard (unsupported platform)");
584
770
  }
585
771
  }
586
772
  } else {
587
773
  console.log(output);
588
774
  }
589
775
  } catch (error2) {
590
- console.error(chalk5.red("\u2717") + " Failed to generate prompt:", error2 instanceof Error ? error2.message : "Unknown error");
776
+ console.error(chalk6.red("\u2717") + " Failed to generate prompt:", error2 instanceof Error ? error2.message : "Unknown error");
591
777
  process.exit(1);
592
778
  }
593
779
  });
594
780
 
595
781
  // src/commands/search.ts
596
782
  import { Command as Command5 } from "commander";
597
- import chalk6 from "chalk";
783
+ import chalk7 from "chalk";
598
784
  var TYPE_ICONS2 = {
599
785
  rule: "\u{1F4CC}",
600
786
  decision: "\u{1F4A1}",
@@ -604,17 +790,17 @@ var TYPE_ICONS2 = {
604
790
  var VALID_TYPES3 = ["rule", "decision", "fact", "note"];
605
791
  function formatMemory2(m, score) {
606
792
  const icon = TYPE_ICONS2[m.type] || "\u{1F4DD}";
607
- const scope = m.scope === "global" ? chalk6.dim("G") : chalk6.dim("P");
608
- const tags = m.tags ? chalk6.dim(` [${m.tags}]`) : "";
609
- const scoreStr = score !== void 0 ? chalk6.cyan(` (${Math.round(score * 100)}%)`) : "";
610
- return `${icon} ${scope} ${chalk6.dim(m.id)} ${m.content}${tags}${scoreStr}`;
793
+ const scope = m.scope === "global" ? chalk7.dim("G") : chalk7.dim("P");
794
+ const tags = m.tags ? chalk7.dim(` [${m.tags}]`) : "";
795
+ const scoreStr = score !== void 0 ? chalk7.cyan(` (${Math.round(score * 100)}%)`) : "";
796
+ return `${icon} ${scope} ${chalk7.dim(m.id)} ${m.content}${tags}${scoreStr}`;
611
797
  }
612
798
  var searchCommand = new Command5("search").description("Search memories using full-text or semantic search").argument("<query>", "Search query").option("-l, --limit <n>", "Max results", "20").option("--type <type>", "Filter by type: rule, decision, fact, note").option("-g, --global", "Search only global memories").option("--project-only", "Search only project memories (exclude global)").option("-s, --semantic", "Use semantic (AI) search instead of keyword search").option("--json", "Output as JSON").action(async (query, opts) => {
613
799
  try {
614
800
  let types;
615
801
  if (opts.type) {
616
802
  if (!VALID_TYPES3.includes(opts.type)) {
617
- console.error(chalk6.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES3.join(", ")}`);
803
+ console.error(chalk7.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES3.join(", ")}`);
618
804
  process.exit(1);
619
805
  }
620
806
  types = [opts.type];
@@ -628,7 +814,7 @@ var searchCommand = new Command5("search").description("Search memories using fu
628
814
  includeGlobal = false;
629
815
  projectId = getProjectId() ?? void 0;
630
816
  if (!projectId) {
631
- console.log(chalk6.yellow("\u26A0") + " Not in a git repository. No project memories to search.");
817
+ console.log(chalk7.yellow("\u26A0") + " Not in a git repository. No project memories to search.");
632
818
  return;
633
819
  }
634
820
  }
@@ -636,7 +822,7 @@ var searchCommand = new Command5("search").description("Search memories using fu
636
822
  try {
637
823
  const { semanticSearch, isModelAvailable } = await import("./embeddings-6N2NZPRX.js");
638
824
  if (!await isModelAvailable()) {
639
- console.log(chalk6.yellow("\u26A0") + " Loading embedding model for first time (this may take a moment)...");
825
+ console.log(chalk7.yellow("\u26A0") + " Loading embedding model for first time (this may take a moment)...");
640
826
  }
641
827
  const results = await semanticSearch(query, {
642
828
  limit: parseInt(opts.limit, 10),
@@ -647,11 +833,11 @@ var searchCommand = new Command5("search").description("Search memories using fu
647
833
  return;
648
834
  }
649
835
  if (results.length === 0) {
650
- console.log(chalk6.dim(`No semantically similar memories found for "${query}"`));
651
- console.log(chalk6.dim("Try running 'memories embed' to generate embeddings for existing memories."));
836
+ console.log(chalk7.dim(`No semantically similar memories found for "${query}"`));
837
+ console.log(chalk7.dim("Try running 'memories embed' to generate embeddings for existing memories."));
652
838
  return;
653
839
  }
654
- console.log(chalk6.bold(`Semantic results for "${query}":`));
840
+ console.log(chalk7.bold(`Semantic results for "${query}":`));
655
841
  console.log("");
656
842
  for (const r of results) {
657
843
  const { getMemoryById: getMemoryById2 } = await import("./memory-B4NNFKXV.js");
@@ -660,12 +846,12 @@ var searchCommand = new Command5("search").description("Search memories using fu
660
846
  console.log(formatMemory2(m, r.score));
661
847
  }
662
848
  }
663
- console.log(chalk6.dim(`
849
+ console.log(chalk7.dim(`
664
850
  ${results.length} results (semantic search)`));
665
851
  return;
666
852
  } catch (error2) {
667
- console.error(chalk6.red("\u2717") + " Semantic search failed:", error2 instanceof Error ? error2.message : "Unknown error");
668
- console.log(chalk6.dim("Falling back to keyword search..."));
853
+ console.error(chalk7.red("\u2717") + " Semantic search failed:", error2 instanceof Error ? error2.message : "Unknown error");
854
+ console.log(chalk7.dim("Falling back to keyword search..."));
669
855
  }
670
856
  }
671
857
  const memories = await searchMemories(query, {
@@ -680,30 +866,30 @@ ${results.length} results (semantic search)`));
680
866
  return;
681
867
  }
682
868
  if (memories.length === 0) {
683
- console.log(chalk6.dim(`No memories found matching "${query}"`));
869
+ console.log(chalk7.dim(`No memories found matching "${query}"`));
684
870
  return;
685
871
  }
686
- console.log(chalk6.bold(`Results for "${query}":`));
872
+ console.log(chalk7.bold(`Results for "${query}":`));
687
873
  console.log("");
688
874
  for (const m of memories) {
689
875
  console.log(formatMemory2(m));
690
876
  }
691
- console.log(chalk6.dim(`
877
+ console.log(chalk7.dim(`
692
878
  ${memories.length} results`));
693
879
  } catch (error2) {
694
- console.error(chalk6.red("\u2717") + " Failed to search:", error2 instanceof Error ? error2.message : "Unknown error");
880
+ console.error(chalk7.red("\u2717") + " Failed to search:", error2 instanceof Error ? error2.message : "Unknown error");
695
881
  process.exit(1);
696
882
  }
697
883
  });
698
884
 
699
885
  // src/commands/list.ts
700
886
  import { Command as Command6 } from "commander";
701
- import chalk7 from "chalk";
887
+ import chalk8 from "chalk";
702
888
  var TYPE_COLORS2 = {
703
- rule: chalk7.blue,
704
- decision: chalk7.yellow,
705
- fact: chalk7.green,
706
- note: chalk7.dim
889
+ rule: chalk8.blue,
890
+ decision: chalk8.yellow,
891
+ fact: chalk8.green,
892
+ note: chalk8.dim
707
893
  };
708
894
  var TYPE_LABELS = {
709
895
  rule: "rule",
@@ -718,12 +904,12 @@ function truncate(str, max) {
718
904
  return str.slice(0, max - 1) + "\u2026";
719
905
  }
720
906
  function formatMemory3(m) {
721
- const typeColor = TYPE_COLORS2[m.type] ?? chalk7.dim;
907
+ const typeColor = TYPE_COLORS2[m.type] ?? chalk8.dim;
722
908
  const typeLabel = typeColor(TYPE_LABELS[m.type].padEnd(9));
723
- const scope = m.scope === "global" ? chalk7.magenta("G") : chalk7.cyan("P");
724
- const id = chalk7.dim(m.id);
909
+ const scope = m.scope === "global" ? chalk8.magenta("G") : chalk8.cyan("P");
910
+ const id = chalk8.dim(m.id);
725
911
  const content = truncate(m.content, MAX_CONTENT_WIDTH);
726
- const tags = m.tags ? chalk7.dim(` [${m.tags}]`) : "";
912
+ const tags = m.tags ? chalk8.dim(` [${m.tags}]`) : "";
727
913
  return ` ${scope} ${typeLabel} ${id} ${content}${tags}`;
728
914
  }
729
915
  var listCommand = new Command6("list").description("List memories").option("-l, --limit <n>", "Max results", "50").option("-t, --tags <tags>", "Filter by comma-separated tags").option("--type <type>", "Filter by type: rule, decision, fact, note").option("-g, --global", "Show only global memories").option("--project-only", "Show only project memories (exclude global)").option("--json", "Output as JSON").action(async (opts) => {
@@ -732,7 +918,7 @@ var listCommand = new Command6("list").description("List memories").option("-l,
732
918
  let types;
733
919
  if (opts.type) {
734
920
  if (!VALID_TYPES4.includes(opts.type)) {
735
- console.error(chalk7.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES4.join(", ")}`);
921
+ console.error(chalk8.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES4.join(", ")}`);
736
922
  process.exit(1);
737
923
  }
738
924
  types = [opts.type];
@@ -746,7 +932,7 @@ var listCommand = new Command6("list").description("List memories").option("-l,
746
932
  includeGlobal = false;
747
933
  projectId = getProjectId() ?? void 0;
748
934
  if (!projectId) {
749
- console.log(chalk7.yellow("\u26A0") + " Not in a git repository. No project memories to show.");
935
+ console.log(chalk8.yellow("\u26A0") + " Not in a git repository. No project memories to show.");
750
936
  return;
751
937
  }
752
938
  }
@@ -763,21 +949,21 @@ var listCommand = new Command6("list").description("List memories").option("-l,
763
949
  return;
764
950
  }
765
951
  if (memories.length === 0) {
766
- console.log(chalk7.dim("No memories found."));
952
+ console.log(chalk8.dim("No memories found."));
767
953
  return;
768
954
  }
769
955
  const currentProject = getProjectId();
770
956
  if (currentProject && !opts.global) {
771
- console.log(chalk7.dim(` Project: ${currentProject}
957
+ console.log(chalk8.dim(` Project: ${currentProject}
772
958
  `));
773
959
  }
774
960
  for (const m of memories) {
775
961
  console.log(formatMemory3(m));
776
962
  }
777
- console.log(chalk7.dim(`
963
+ console.log(chalk8.dim(`
778
964
  ${memories.length} memories`));
779
965
  } catch (error2) {
780
- console.error(chalk7.red("\u2717") + " Failed to list memories:", error2 instanceof Error ? error2.message : "Unknown error");
966
+ console.error(chalk8.red("\u2717") + " Failed to list memories:", error2 instanceof Error ? error2.message : "Unknown error");
781
967
  process.exit(1);
782
968
  }
783
969
  });
@@ -785,7 +971,7 @@ var listCommand = new Command6("list").description("List memories").option("-l,
785
971
  // src/commands/forget.ts
786
972
  import { Command as Command7 } from "commander";
787
973
  import { createInterface } from "readline";
788
- import chalk8 from "chalk";
974
+ import chalk9 from "chalk";
789
975
  var VALID_TYPES5 = ["rule", "decision", "fact", "note"];
790
976
  var TYPE_ICONS3 = {
791
977
  rule: "\u{1F4CC}",
@@ -793,7 +979,7 @@ var TYPE_ICONS3 = {
793
979
  fact: "\u{1F4CB}",
794
980
  note: "\u{1F4DD}"
795
981
  };
796
- async function confirm(message) {
982
+ async function confirm2(message) {
797
983
  const rl = createInterface({ input: process.stdin, output: process.stderr });
798
984
  return new Promise((resolve3) => {
799
985
  rl.question(message, (answer) => {
@@ -807,28 +993,28 @@ var forgetCommand = new Command7("forget").description("Soft-delete memories by
807
993
  if (id) {
808
994
  const deleted = await forgetMemory(id);
809
995
  if (deleted) {
810
- console.log(chalk8.green("\u2713") + ` Forgot memory ${chalk8.dim(id)}`);
996
+ console.log(chalk9.green("\u2713") + ` Forgot memory ${chalk9.dim(id)}`);
811
997
  } else {
812
- console.error(chalk8.red("\u2717") + ` Memory ${id} not found or already forgotten.`);
998
+ console.error(chalk9.red("\u2717") + ` Memory ${id} not found or already forgotten.`);
813
999
  process.exit(1);
814
1000
  }
815
1001
  return;
816
1002
  }
817
1003
  const hasBulkFilter = opts.type || opts.tag || opts.olderThan || opts.pattern || opts.all;
818
1004
  if (!hasBulkFilter) {
819
- console.error(chalk8.red("\u2717") + " Provide a memory ID or a bulk filter (--type, --tag, --older-than, --pattern, --all)");
1005
+ console.error(chalk9.red("\u2717") + " Provide a memory ID or a bulk filter (--type, --tag, --older-than, --pattern, --all)");
820
1006
  process.exit(1);
821
1007
  }
822
1008
  if (opts.all && (opts.type || opts.tag || opts.olderThan || opts.pattern)) {
823
- console.error(chalk8.red("\u2717") + " --all cannot be combined with other filters. Use --all alone to delete everything.");
1009
+ console.error(chalk9.red("\u2717") + " --all cannot be combined with other filters. Use --all alone to delete everything.");
824
1010
  process.exit(1);
825
1011
  }
826
1012
  if (opts.type && !VALID_TYPES5.includes(opts.type)) {
827
- console.error(chalk8.red("\u2717") + ` Invalid type "${opts.type}". Valid: ${VALID_TYPES5.join(", ")}`);
1013
+ console.error(chalk9.red("\u2717") + ` Invalid type "${opts.type}". Valid: ${VALID_TYPES5.join(", ")}`);
828
1014
  process.exit(1);
829
1015
  }
830
1016
  if (opts.olderThan && (isNaN(parseInt(opts.olderThan, 10)) || parseInt(opts.olderThan, 10) <= 0)) {
831
- console.error(chalk8.red("\u2717") + " --older-than must be a positive number of days");
1017
+ console.error(chalk9.red("\u2717") + " --older-than must be a positive number of days");
832
1018
  process.exit(1);
833
1019
  }
834
1020
  const filter = {
@@ -841,27 +1027,27 @@ var forgetCommand = new Command7("forget").description("Soft-delete memories by
841
1027
  };
842
1028
  const matches = await findMemoriesToForget(filter);
843
1029
  if (matches.length === 0) {
844
- console.log(chalk8.dim("No memories match the filter."));
1030
+ console.log(chalk9.dim("No memories match the filter."));
845
1031
  return;
846
1032
  }
847
- console.log(chalk8.bold(`${matches.length} memories will be forgotten:
1033
+ console.log(chalk9.bold(`${matches.length} memories will be forgotten:
848
1034
  `));
849
1035
  for (const m of matches.slice(0, 30)) {
850
1036
  const icon = TYPE_ICONS3[m.type] || "\u{1F4DD}";
851
- const scope = m.scope === "global" ? chalk8.dim("G") : chalk8.dim("P");
852
- console.log(` ${icon} ${scope} ${chalk8.dim(m.id)} ${m.content}`);
1037
+ const scope = m.scope === "global" ? chalk9.dim("G") : chalk9.dim("P");
1038
+ console.log(` ${icon} ${scope} ${chalk9.dim(m.id)} ${m.content}`);
853
1039
  }
854
1040
  if (matches.length > 30) {
855
- console.log(chalk8.dim(` ... and ${matches.length - 30} more`));
1041
+ console.log(chalk9.dim(` ... and ${matches.length - 30} more`));
856
1042
  }
857
1043
  console.log("");
858
1044
  if (opts.dryRun) {
859
- console.log(chalk8.yellow("Dry run") + " \u2014 no memories were deleted.");
1045
+ console.log(chalk9.yellow("Dry run") + " \u2014 no memories were deleted.");
860
1046
  return;
861
1047
  }
862
1048
  if (!opts.force) {
863
- const proceed = await confirm(
864
- chalk8.yellow(`Forget ${matches.length} memories? This is a soft-delete. [y/N] `)
1049
+ const proceed = await confirm2(
1050
+ chalk9.yellow(`Forget ${matches.length} memories? This is a soft-delete. [y/N] `)
865
1051
  );
866
1052
  if (!proceed) {
867
1053
  console.log("Cancelled.");
@@ -870,17 +1056,17 @@ var forgetCommand = new Command7("forget").description("Soft-delete memories by
870
1056
  }
871
1057
  const ids = matches.map((m) => m.id);
872
1058
  const count = await bulkForgetByIds(ids);
873
- console.log(chalk8.green("\u2713") + ` Forgot ${count} memories.`);
1059
+ console.log(chalk9.green("\u2713") + ` Forgot ${count} memories.`);
874
1060
  } catch (error2) {
875
- console.error(chalk8.red("\u2717") + " Failed to forget:", error2 instanceof Error ? error2.message : "Unknown error");
1061
+ console.error(chalk9.red("\u2717") + " Failed to forget:", error2 instanceof Error ? error2.message : "Unknown error");
876
1062
  process.exit(1);
877
1063
  }
878
1064
  });
879
1065
 
880
1066
  // src/commands/export.ts
881
1067
  import { Command as Command8 } from "commander";
882
- import chalk9 from "chalk";
883
- import { writeFile as writeFile2 } from "fs/promises";
1068
+ import chalk10 from "chalk";
1069
+ import { writeFile as writeFile3 } from "fs/promises";
884
1070
  var exportCommand = new Command8("export").description("Export memories to JSON or YAML file").option("-o, --output <file>", "Output file path (default: stdout)").option("-f, --format <format>", "Output format: json, yaml (default: json)", "json").option("-g, --global", "Export only global memories").option("--project-only", "Export only project memories").option("--type <type>", "Filter by type: rule, decision, fact, note").action(async (opts) => {
885
1071
  try {
886
1072
  const projectId = getProjectId();
@@ -893,7 +1079,7 @@ var exportCommand = new Command8("export").description("Export memories to JSON
893
1079
  includeGlobal = false;
894
1080
  queryProjectId = projectId ?? void 0;
895
1081
  if (!queryProjectId) {
896
- console.error(chalk9.red("\u2717") + " Not in a git repository. No project memories to export.");
1082
+ console.error(chalk10.red("\u2717") + " Not in a git repository. No project memories to export.");
897
1083
  process.exit(1);
898
1084
  }
899
1085
  }
@@ -927,24 +1113,24 @@ var exportCommand = new Command8("export").description("Export memories to JSON
927
1113
  output = JSON.stringify(exportData, null, 2);
928
1114
  }
929
1115
  if (opts.output) {
930
- await writeFile2(opts.output, output, "utf-8");
931
- console.log(chalk9.green("\u2713") + ` Exported ${memories.length} memories to ${chalk9.dim(opts.output)}`);
1116
+ await writeFile3(opts.output, output, "utf-8");
1117
+ console.log(chalk10.green("\u2713") + ` Exported ${memories.length} memories to ${chalk10.dim(opts.output)}`);
932
1118
  } else {
933
1119
  console.log(output);
934
1120
  }
935
1121
  } catch (error2) {
936
- console.error(chalk9.red("\u2717") + " Failed to export:", error2 instanceof Error ? error2.message : "Unknown error");
1122
+ console.error(chalk10.red("\u2717") + " Failed to export:", error2 instanceof Error ? error2.message : "Unknown error");
937
1123
  process.exit(1);
938
1124
  }
939
1125
  });
940
1126
 
941
1127
  // src/commands/import.ts
942
1128
  import { Command as Command9 } from "commander";
943
- import chalk10 from "chalk";
944
- import { readFile as readFile2 } from "fs/promises";
1129
+ import chalk11 from "chalk";
1130
+ import { readFile as readFile3 } from "fs/promises";
945
1131
  var importCommand = new Command9("import").description("Import memories from JSON or YAML file").argument("<file>", "Input file path").option("-f, --format <format>", "Input format: json, yaml (auto-detected from extension)").option("-g, --global", "Import all as global memories (override file scope)").option("--dry-run", "Show what would be imported without actually importing").action(async (file, opts) => {
946
1132
  try {
947
- const content = await readFile2(file, "utf-8");
1133
+ const content = await readFile3(file, "utf-8");
948
1134
  let format = opts.format;
949
1135
  if (!format) {
950
1136
  if (file.endsWith(".yaml") || file.endsWith(".yml")) {
@@ -961,7 +1147,7 @@ var importCommand = new Command9("import").description("Import memories from JSO
961
1147
  data = JSON.parse(content);
962
1148
  }
963
1149
  if (!data || typeof data !== "object" || !("memories" in data) || !Array.isArray(data.memories)) {
964
- console.error(chalk10.red("\u2717") + " Invalid import file: missing 'memories' array");
1150
+ console.error(chalk11.red("\u2717") + " Invalid import file: missing 'memories' array");
965
1151
  process.exit(1);
966
1152
  }
967
1153
  const VALID_TYPES11 = ["rule", "decision", "fact", "note"];
@@ -974,23 +1160,23 @@ var importCommand = new Command9("import").description("Import memories from JSO
974
1160
  continue;
975
1161
  }
976
1162
  if (m.type && !VALID_TYPES11.includes(m.type)) {
977
- console.error(chalk10.yellow("\u26A0") + ` Skipping memory with invalid type "${m.type}": ${m.content.slice(0, 50)}`);
1163
+ console.error(chalk11.yellow("\u26A0") + ` Skipping memory with invalid type "${m.type}": ${m.content.slice(0, 50)}`);
978
1164
  skipped++;
979
1165
  continue;
980
1166
  }
981
1167
  validMemories.push(m);
982
1168
  }
983
1169
  if (opts.dryRun) {
984
- console.log(chalk10.blue("Dry run - would import:"));
1170
+ console.log(chalk11.blue("Dry run - would import:"));
985
1171
  for (const m of validMemories) {
986
1172
  const type = m.type || "note";
987
1173
  const scope = opts.global ? "global" : m.scope || "project";
988
1174
  const tags = m.tags?.length ? ` [${m.tags.join(", ")}]` : "";
989
1175
  console.log(` ${type} (${scope}): ${m.content}${tags}`);
990
1176
  }
991
- console.log(chalk10.dim(`
1177
+ console.log(chalk11.dim(`
992
1178
  ${validMemories.length} memories would be imported`));
993
- if (skipped > 0) console.log(chalk10.dim(`${skipped} entries skipped (invalid)`));
1179
+ if (skipped > 0) console.log(chalk11.dim(`${skipped} entries skipped (invalid)`));
994
1180
  return;
995
1181
  }
996
1182
  let imported = 0;
@@ -1004,19 +1190,19 @@ ${validMemories.length} memories would be imported`));
1004
1190
  });
1005
1191
  imported++;
1006
1192
  } catch (error2) {
1007
- console.error(chalk10.yellow("\u26A0") + ` Failed to import: ${m.content.slice(0, 50)}...`);
1193
+ console.error(chalk11.yellow("\u26A0") + ` Failed to import: ${m.content.slice(0, 50)}...`);
1008
1194
  failed++;
1009
1195
  }
1010
1196
  }
1011
- console.log(chalk10.green("\u2713") + ` Imported ${imported} memories`);
1197
+ console.log(chalk11.green("\u2713") + ` Imported ${imported} memories`);
1012
1198
  if (failed > 0) {
1013
- console.log(chalk10.yellow("\u26A0") + ` ${failed} memories failed to import`);
1199
+ console.log(chalk11.yellow("\u26A0") + ` ${failed} memories failed to import`);
1014
1200
  }
1015
1201
  if (skipped > 0) {
1016
- console.log(chalk10.dim(`${skipped} entries skipped (invalid content or type)`));
1202
+ console.log(chalk11.dim(`${skipped} entries skipped (invalid content or type)`));
1017
1203
  }
1018
1204
  } catch (error2) {
1019
- console.error(chalk10.red("\u2717") + " Failed to import:", error2 instanceof Error ? error2.message : "Unknown error");
1205
+ console.error(chalk11.red("\u2717") + " Failed to import:", error2 instanceof Error ? error2.message : "Unknown error");
1020
1206
  process.exit(1);
1021
1207
  }
1022
1208
  });
@@ -1025,17 +1211,17 @@ ${validMemories.length} memories would be imported`));
1025
1211
  import { Command as Command10 } from "commander";
1026
1212
 
1027
1213
  // src/lib/config.ts
1028
- import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir2 } from "fs/promises";
1029
- import { join as join2 } from "path";
1030
- import { existsSync as existsSync2 } from "fs";
1214
+ import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir3 } from "fs/promises";
1215
+ import { join as join3 } from "path";
1216
+ import { existsSync as existsSync3 } from "fs";
1031
1217
  import { parse, stringify } from "yaml";
1032
1218
  var AGENTS_DIR = ".agents";
1033
1219
  var CONFIG_FILE = "config.yaml";
1034
1220
  async function initConfig(dir) {
1035
- const agentsDir = join2(dir, AGENTS_DIR);
1036
- await mkdir2(agentsDir, { recursive: true });
1037
- const configPath = join2(agentsDir, CONFIG_FILE);
1038
- if (!existsSync2(configPath)) {
1221
+ const agentsDir = join3(dir, AGENTS_DIR);
1222
+ await mkdir3(agentsDir, { recursive: true });
1223
+ const configPath = join3(agentsDir, CONFIG_FILE);
1224
+ if (!existsSync3(configPath)) {
1039
1225
  const defaultConfig = {
1040
1226
  name: "my-project",
1041
1227
  description: "Agent memory configuration",
@@ -1045,14 +1231,14 @@ async function initConfig(dir) {
1045
1231
  store: "~/.config/memories/local.db"
1046
1232
  }
1047
1233
  };
1048
- await writeFile3(configPath, stringify(defaultConfig), "utf-8");
1234
+ await writeFile4(configPath, stringify(defaultConfig), "utf-8");
1049
1235
  }
1050
1236
  return configPath;
1051
1237
  }
1052
1238
  async function readConfig(dir) {
1053
- const configPath = join2(dir, AGENTS_DIR, CONFIG_FILE);
1054
- if (!existsSync2(configPath)) return null;
1055
- const raw = await readFile3(configPath, "utf-8");
1239
+ const configPath = join3(dir, AGENTS_DIR, CONFIG_FILE);
1240
+ if (!existsSync3(configPath)) return null;
1241
+ const raw = await readFile4(configPath, "utf-8");
1056
1242
  return parse(raw);
1057
1243
  }
1058
1244
 
@@ -1077,6 +1263,8 @@ import { Command as Command11 } from "commander";
1077
1263
  // src/mcp/index.ts
1078
1264
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
1079
1265
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1266
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
1267
+ import { createServer } from "http";
1080
1268
  import { z } from "zod";
1081
1269
  var TYPE_LABELS2 = {
1082
1270
  rule: "\u{1F4CC} RULE",
@@ -1100,7 +1288,7 @@ function formatMemoriesSection(memories, title) {
1100
1288
  return `## ${title}
1101
1289
  ${memories.map(formatMemory4).join("\n")}`;
1102
1290
  }
1103
- async function startMcpServer() {
1291
+ async function createMcpServer() {
1104
1292
  const projectId = getProjectId();
1105
1293
  const server = new McpServer({
1106
1294
  name: "memories",
@@ -1458,19 +1646,93 @@ Find the memory ID first with search_memories or list_memories.`,
1458
1646
  }
1459
1647
  }
1460
1648
  );
1649
+ return server;
1650
+ }
1651
+ async function startMcpServer() {
1652
+ const server = await createMcpServer();
1461
1653
  const transport = new StdioServerTransport();
1462
1654
  await server.connect(transport);
1463
1655
  }
1656
+ async function startMcpHttpServer(options) {
1657
+ const { port, host, cors } = options;
1658
+ const server = await createMcpServer();
1659
+ const transport = new StreamableHTTPServerTransport({
1660
+ sessionIdGenerator: void 0
1661
+ // Stateless mode
1662
+ });
1663
+ await server.connect(transport);
1664
+ const httpServer = createServer(async (req, res) => {
1665
+ if (cors) {
1666
+ res.setHeader("Access-Control-Allow-Origin", "*");
1667
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
1668
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
1669
+ }
1670
+ if (req.method === "OPTIONS") {
1671
+ res.writeHead(204);
1672
+ res.end();
1673
+ return;
1674
+ }
1675
+ const url = new URL(req.url || "/", `http://${host}:${port}`);
1676
+ if (url.pathname === "/health") {
1677
+ res.writeHead(200, { "Content-Type": "application/json" });
1678
+ res.end(JSON.stringify({ status: "ok" }));
1679
+ return;
1680
+ }
1681
+ if (url.pathname === "/mcp" || url.pathname === "/") {
1682
+ try {
1683
+ let body = void 0;
1684
+ if (req.method === "POST") {
1685
+ const chunks = [];
1686
+ for await (const chunk of req) {
1687
+ chunks.push(chunk);
1688
+ }
1689
+ const rawBody = Buffer.concat(chunks).toString("utf-8");
1690
+ if (rawBody) {
1691
+ body = JSON.parse(rawBody);
1692
+ }
1693
+ }
1694
+ await transport.handleRequest(req, res, body);
1695
+ } catch (error2) {
1696
+ console.error("[memories] Error handling MCP request:", error2);
1697
+ res.writeHead(500, { "Content-Type": "application/json" });
1698
+ res.end(JSON.stringify({ error: "Internal server error" }));
1699
+ }
1700
+ return;
1701
+ }
1702
+ res.writeHead(404, { "Content-Type": "application/json" });
1703
+ res.end(JSON.stringify({ error: "Not found" }));
1704
+ });
1705
+ httpServer.listen(port, host);
1706
+ await new Promise(() => {
1707
+ });
1708
+ }
1464
1709
 
1465
1710
  // src/commands/serve.ts
1466
- var serveCommand = new Command11("serve").description("Start the MCP server (stdio transport)").action(async () => {
1711
+ var serveCommand = new Command11("serve").description("Start the MCP server").option("--sse", "Use SSE/HTTP transport instead of stdio (for web clients like v0)").option("-p, --port <port>", "Port for SSE server", "3030").option("--host <host>", "Host to bind to", "127.0.0.1").option("--cors", "Enable CORS for cross-origin requests").action(async (opts) => {
1467
1712
  const projectId = getProjectId();
1468
- if (projectId) {
1469
- console.error(`[memories] MCP server starting (project: ${projectId})`);
1713
+ if (opts.sse) {
1714
+ const port = parseInt(opts.port || "3030", 10);
1715
+ const host = opts.host || "127.0.0.1";
1716
+ console.log(`[memories] Starting MCP server with SSE transport`);
1717
+ console.log(`[memories] Listening on http://${host}:${port}`);
1718
+ if (projectId) {
1719
+ console.log(`[memories] Project: ${projectId}`);
1720
+ } else {
1721
+ console.log(`[memories] Global only (not in a git repo)`);
1722
+ }
1723
+ if (opts.cors) {
1724
+ console.log(`[memories] CORS enabled`);
1725
+ }
1726
+ console.log(`[memories] Connect v0 or other clients to: http://${host}:${port}/mcp`);
1727
+ await startMcpHttpServer({ port, host, cors: opts.cors });
1470
1728
  } else {
1471
- console.error("[memories] MCP server starting (global only - not in a git repo)");
1729
+ if (projectId) {
1730
+ console.error(`[memories] MCP server starting (project: ${projectId})`);
1731
+ } else {
1732
+ console.error("[memories] MCP server starting (global only - not in a git repo)");
1733
+ }
1734
+ await startMcpServer();
1472
1735
  }
1473
- await startMcpServer();
1474
1736
  });
1475
1737
 
1476
1738
  // src/commands/sync.ts
@@ -1528,10 +1790,10 @@ async function createDatabaseToken(org, dbName) {
1528
1790
  }
1529
1791
 
1530
1792
  // src/commands/sync.ts
1531
- import { unlinkSync, existsSync as existsSync3 } from "fs";
1532
- import { join as join3 } from "path";
1533
- import { homedir as homedir2 } from "os";
1534
- var DB_PATH = join3(homedir2(), ".config", "memories", "local.db");
1793
+ import { unlinkSync, existsSync as existsSync4 } from "fs";
1794
+ import { join as join4 } from "path";
1795
+ import { homedir as homedir3 } from "os";
1796
+ var DB_PATH = join4(homedir3(), ".config", "memories", "local.db");
1535
1797
  var syncCommand = new Command12("sync").description(
1536
1798
  "Manage remote sync"
1537
1799
  );
@@ -1554,7 +1816,7 @@ syncCommand.command("enable").description("Provision a cloud database and enable
1554
1816
  const profileRes = await apiFetch("/api/db/credentials");
1555
1817
  if (profileRes.ok) {
1556
1818
  const creds = await profileRes.json();
1557
- if (existsSync3(DB_PATH)) {
1819
+ if (existsSync4(DB_PATH)) {
1558
1820
  resetDb();
1559
1821
  unlinkSync(DB_PATH);
1560
1822
  }
@@ -1590,7 +1852,7 @@ syncCommand.command("enable").description("Provision a cloud database and enable
1590
1852
  spinner.text = "Generating auth token...";
1591
1853
  const token = await createDatabaseToken(opts.org, db.name);
1592
1854
  const syncUrl = `libsql://${db.hostname}`;
1593
- if (existsSync3(DB_PATH)) {
1855
+ if (existsSync4(DB_PATH)) {
1594
1856
  resetDb();
1595
1857
  unlinkSync(DB_PATH);
1596
1858
  }
@@ -1637,12 +1899,12 @@ syncCommand.command("status").description("Show sync configuration").action(asyn
1637
1899
 
1638
1900
  // src/commands/generate.ts
1639
1901
  import { Command as Command13 } from "commander";
1640
- import chalk11 from "chalk";
1641
- import { writeFile as writeFile4, readFile as readFile4, mkdir as mkdir3 } from "fs/promises";
1642
- import { existsSync as existsSync4, watch as fsWatch } from "fs";
1643
- import { dirname, resolve, join as join4 } from "path";
1644
- import { homedir as homedir3 } from "os";
1645
- import { checkbox } from "@inquirer/prompts";
1902
+ import chalk12 from "chalk";
1903
+ import { writeFile as writeFile5, readFile as readFile5, mkdir as mkdir4 } from "fs/promises";
1904
+ import { existsSync as existsSync5, watch as fsWatch } from "fs";
1905
+ import { dirname as dirname2, resolve, join as join5 } from "path";
1906
+ import { homedir as homedir4 } from "os";
1907
+ import { checkbox as checkbox2 } from "@inquirer/prompts";
1646
1908
  var MARKER = "Generated by memories.sh";
1647
1909
  var VALID_TYPES6 = ["rule", "decision", "fact", "note"];
1648
1910
  function groupByType(memories) {
@@ -1778,7 +2040,7 @@ function makeFooter() {
1778
2040
  }
1779
2041
  async function hasOurMarker(filePath) {
1780
2042
  try {
1781
- const content = await readFile4(filePath, "utf-8");
2043
+ const content = await readFile5(filePath, "utf-8");
1782
2044
  return content.includes(MARKER);
1783
2045
  } catch {
1784
2046
  return false;
@@ -1789,13 +2051,13 @@ async function checkGitignore(filePath) {
1789
2051
  if (TRACK_BY_DEFAULT.has(filePath)) return;
1790
2052
  const gitignorePath = resolve(".gitignore");
1791
2053
  try {
1792
- const content = existsSync4(gitignorePath) ? await readFile4(gitignorePath, "utf-8") : "";
2054
+ const content = existsSync5(gitignorePath) ? await readFile5(gitignorePath, "utf-8") : "";
1793
2055
  const lines = content.split("\n");
1794
2056
  const parentDir = filePath.split("/")[0];
1795
2057
  if (lines.some((l) => l.trim() === filePath || l.trim() === parentDir || l.trim() === `${parentDir}/`)) {
1796
2058
  return;
1797
2059
  }
1798
- console.log(chalk11.dim(` hint: add "${filePath}" to .gitignore if you don't want it tracked`));
2060
+ console.log(chalk12.dim(` hint: add "${filePath}" to .gitignore if you don't want it tracked`));
1799
2061
  } catch {
1800
2062
  }
1801
2063
  }
@@ -1803,23 +2065,23 @@ async function writeTarget(target, memories, opts) {
1803
2065
  const outPath = resolve(opts.output ?? target.defaultPath);
1804
2066
  const content = target.format(memories) + makeFooter();
1805
2067
  if (opts.dryRun) {
1806
- console.log(chalk11.dim(`\u2500\u2500 ${target.name} \u2192 ${outPath} \u2500\u2500`));
2068
+ console.log(chalk12.dim(`\u2500\u2500 ${target.name} \u2192 ${outPath} \u2500\u2500`));
1807
2069
  console.log(content);
1808
2070
  console.log();
1809
2071
  return;
1810
2072
  }
1811
- if (existsSync4(outPath)) {
2073
+ if (existsSync5(outPath)) {
1812
2074
  const ours = await hasOurMarker(outPath);
1813
2075
  if (!ours && !opts.force) {
1814
2076
  console.error(
1815
- chalk11.yellow("\u26A0") + ` ${outPath} exists and was not generated by memories.sh. Use ${chalk11.bold("--force")} to overwrite.`
2077
+ chalk12.yellow("\u26A0") + ` ${outPath} exists and was not generated by memories.sh. Use ${chalk12.bold("--force")} to overwrite.`
1816
2078
  );
1817
2079
  return;
1818
2080
  }
1819
2081
  }
1820
- await mkdir3(dirname(outPath), { recursive: true });
1821
- await writeFile4(outPath, content, "utf-8");
1822
- console.log(chalk11.green("\u2713") + ` Wrote ${target.name} \u2192 ${chalk11.dim(outPath)}`);
2082
+ await mkdir4(dirname2(outPath), { recursive: true });
2083
+ await writeFile5(outPath, content, "utf-8");
2084
+ console.log(chalk12.green("\u2713") + ` Wrote ${target.name} \u2192 ${chalk12.dim(outPath)}`);
1823
2085
  await checkGitignore(opts.output ?? target.defaultPath);
1824
2086
  }
1825
2087
  async function fetchMemories(types) {
@@ -1835,23 +2097,23 @@ function parseTypes(raw) {
1835
2097
  const types = raw.split(",").map((s) => s.trim());
1836
2098
  for (const t of types) {
1837
2099
  if (!VALID_TYPES6.includes(t)) {
1838
- console.error(chalk11.red("\u2717") + ` Invalid type "${t}". Valid: ${VALID_TYPES6.join(", ")}`);
2100
+ console.error(chalk12.red("\u2717") + ` Invalid type "${t}". Valid: ${VALID_TYPES6.join(", ")}`);
1839
2101
  process.exit(1);
1840
2102
  }
1841
2103
  }
1842
2104
  return types;
1843
2105
  }
1844
2106
  function getDbPath() {
1845
- const dataDir = process.env.MEMORIES_DATA_DIR ?? join4(homedir3(), ".config", "memories");
1846
- return join4(dataDir, "local.db");
2107
+ const dataDir = process.env.MEMORIES_DATA_DIR ?? join5(homedir4(), ".config", "memories");
2108
+ return join5(dataDir, "local.db");
1847
2109
  }
1848
2110
  async function runWatch(targets, memories, opts) {
1849
2111
  const dbPath = getDbPath();
1850
- if (!existsSync4(dbPath)) {
1851
- console.error(chalk11.red("\u2717") + " Database not found. Run: memories init");
2112
+ if (!existsSync5(dbPath)) {
2113
+ console.error(chalk12.red("\u2717") + " Database not found. Run: memories init");
1852
2114
  process.exit(1);
1853
2115
  }
1854
- console.log(chalk11.dim(`Watching ${dbPath} for changes... (Ctrl+C to stop)
2116
+ console.log(chalk12.dim(`Watching ${dbPath} for changes... (Ctrl+C to stop)
1855
2117
  `));
1856
2118
  const mems = await memories();
1857
2119
  if (mems.length > 0) {
@@ -1871,7 +2133,7 @@ async function runWatch(targets, memories, opts) {
1871
2133
  }
1872
2134
  }
1873
2135
  } catch (err) {
1874
- console.error(chalk11.red("\u2717") + " Watch error:", err.message);
2136
+ console.error(chalk12.red("\u2717") + " Watch error:", err.message);
1875
2137
  }
1876
2138
  }, 500);
1877
2139
  });
@@ -1884,22 +2146,22 @@ var generateCommand = new Command13("generate").description("Generate IDE rule/i
1884
2146
  generateCommand.outputHelp();
1885
2147
  return;
1886
2148
  }
1887
- const selected = await checkbox({
2149
+ const selected = await checkbox2({
1888
2150
  message: "Select targets to generate",
1889
2151
  choices: TARGETS.map((t) => ({
1890
- name: `${t.name} ${chalk11.dim(`\u2192 ${t.defaultPath}`)}`,
2152
+ name: `${t.name} ${chalk12.dim(`\u2192 ${t.defaultPath}`)}`,
1891
2153
  value: t.name,
1892
2154
  checked: true
1893
2155
  }))
1894
2156
  });
1895
2157
  if (selected.length === 0) {
1896
- console.log(chalk11.dim("No targets selected."));
2158
+ console.log(chalk12.dim("No targets selected."));
1897
2159
  return;
1898
2160
  }
1899
2161
  const types = parseTypes(opts.types);
1900
2162
  const memories = await fetchMemories(types);
1901
2163
  if (memories.length === 0) {
1902
- console.error(chalk11.dim('No memories found. Add some with: memories add --rule "Your rule"'));
2164
+ console.error(chalk12.dim('No memories found. Add some with: memories add --rule "Your rule"'));
1903
2165
  return;
1904
2166
  }
1905
2167
  const selectedSet = new Set(selected);
@@ -1911,7 +2173,7 @@ var generateCommand = new Command13("generate").description("Generate IDE rule/i
1911
2173
  }
1912
2174
  } catch (error2) {
1913
2175
  if (error2.name === "ExitPromptError") return;
1914
- console.error(chalk11.red("\u2717") + " Failed to generate:", error2 instanceof Error ? error2.message : "Unknown error");
2176
+ console.error(chalk12.red("\u2717") + " Failed to generate:", error2 instanceof Error ? error2.message : "Unknown error");
1915
2177
  process.exit(1);
1916
2178
  }
1917
2179
  });
@@ -1922,12 +2184,12 @@ for (const target of TARGETS) {
1922
2184
  const types = parseTypes(opts.types);
1923
2185
  const memories = await fetchMemories(types);
1924
2186
  if (memories.length === 0) {
1925
- console.error(chalk11.dim('No memories found. Add some with: memories add --rule "Your rule"'));
2187
+ console.error(chalk12.dim('No memories found. Add some with: memories add --rule "Your rule"'));
1926
2188
  return;
1927
2189
  }
1928
2190
  await writeTarget(target, memories, opts);
1929
2191
  } catch (error2) {
1930
- console.error(chalk11.red("\u2717") + ` Failed to generate ${target.name}:`, error2 instanceof Error ? error2.message : "Unknown error");
2192
+ console.error(chalk12.red("\u2717") + ` Failed to generate ${target.name}:`, error2 instanceof Error ? error2.message : "Unknown error");
1931
2193
  process.exit(1);
1932
2194
  }
1933
2195
  })
@@ -1943,14 +2205,14 @@ generateCommand.addCommand(
1943
2205
  }
1944
2206
  const memories = await fetchMemories(types);
1945
2207
  if (memories.length === 0) {
1946
- console.error(chalk11.dim('No memories found. Add some with: memories add --rule "Your rule"'));
2208
+ console.error(chalk12.dim('No memories found. Add some with: memories add --rule "Your rule"'));
1947
2209
  return;
1948
2210
  }
1949
2211
  for (const target of TARGETS) {
1950
2212
  await writeTarget(target, memories, opts);
1951
2213
  }
1952
2214
  } catch (error2) {
1953
- console.error(chalk11.red("\u2717") + " Failed to generate:", error2 instanceof Error ? error2.message : "Unknown error");
2215
+ console.error(chalk12.red("\u2717") + " Failed to generate:", error2 instanceof Error ? error2.message : "Unknown error");
1954
2216
  process.exit(1);
1955
2217
  }
1956
2218
  })
@@ -1958,11 +2220,11 @@ generateCommand.addCommand(
1958
2220
 
1959
2221
  // src/commands/edit.ts
1960
2222
  import { Command as Command14 } from "commander";
1961
- import chalk12 from "chalk";
2223
+ import chalk13 from "chalk";
1962
2224
  import { execFileSync as execFileSync2 } from "child_process";
1963
2225
  import { writeFileSync, readFileSync, unlinkSync as unlinkSync2 } from "fs";
1964
2226
  import { tmpdir } from "os";
1965
- import { join as join5 } from "path";
2227
+ import { join as join6 } from "path";
1966
2228
  import { nanoid as nanoid2 } from "nanoid";
1967
2229
  import { select } from "@inquirer/prompts";
1968
2230
  var VALID_TYPES7 = ["rule", "decision", "fact", "note"];
@@ -1974,13 +2236,13 @@ async function pickMemory() {
1974
2236
  const projectId = getProjectId() ?? void 0;
1975
2237
  const memories = await listMemories({ limit: 100, projectId });
1976
2238
  if (memories.length === 0) {
1977
- console.error(chalk12.dim("No memories found."));
2239
+ console.error(chalk13.dim("No memories found."));
1978
2240
  process.exit(0);
1979
2241
  }
1980
2242
  const id = await select({
1981
2243
  message: "Select a memory to edit",
1982
2244
  choices: memories.map((m) => ({
1983
- name: `${chalk12.dim(m.type.padEnd(9))} ${truncate2(m.content, 60)} ${chalk12.dim(m.id)}`,
2245
+ name: `${chalk13.dim(m.type.padEnd(9))} ${truncate2(m.content, 60)} ${chalk13.dim(m.id)}`,
1984
2246
  value: m.id
1985
2247
  }))
1986
2248
  });
@@ -1990,7 +2252,7 @@ var editCommand = new Command14("edit").description("Edit an existing memory").a
1990
2252
  try {
1991
2253
  if (!id) {
1992
2254
  if (!process.stdin.isTTY) {
1993
- console.error(chalk12.red("\u2717") + " Memory ID required in non-interactive mode");
2255
+ console.error(chalk13.red("\u2717") + " Memory ID required in non-interactive mode");
1994
2256
  process.exit(1);
1995
2257
  }
1996
2258
  id = await pickMemory();
@@ -2001,18 +2263,18 @@ var editCommand = new Command14("edit").description("Edit an existing memory").a
2001
2263
  args: [id]
2002
2264
  });
2003
2265
  if (result.rows.length === 0) {
2004
- console.error(chalk12.red("\u2717") + ` Memory ${chalk12.dim(id)} not found`);
2266
+ console.error(chalk13.red("\u2717") + ` Memory ${chalk13.dim(id)} not found`);
2005
2267
  process.exit(1);
2006
2268
  }
2007
2269
  const memory = result.rows[0];
2008
2270
  if (opts.type && !VALID_TYPES7.includes(opts.type)) {
2009
- console.error(chalk12.red("\u2717") + ` Invalid type "${opts.type}". Valid: ${VALID_TYPES7.join(", ")}`);
2271
+ console.error(chalk13.red("\u2717") + ` Invalid type "${opts.type}". Valid: ${VALID_TYPES7.join(", ")}`);
2010
2272
  process.exit(1);
2011
2273
  }
2012
2274
  let newContent = opts.content;
2013
2275
  if (newContent === void 0 && opts.tags === void 0 && opts.type === void 0) {
2014
2276
  const editor = process.env.EDITOR || process.env.VISUAL || "vi";
2015
- const tmpFile = join5(tmpdir(), `memories-edit-${nanoid2(6)}.md`);
2277
+ const tmpFile = join6(tmpdir(), `memories-edit-${nanoid2(6)}.md`);
2016
2278
  writeFileSync(tmpFile, memory.content, "utf-8");
2017
2279
  try {
2018
2280
  execFileSync2(editor, [tmpFile], { stdio: "inherit" });
@@ -2024,7 +2286,7 @@ var editCommand = new Command14("edit").description("Edit an existing memory").a
2024
2286
  }
2025
2287
  }
2026
2288
  if (newContent === memory.content) {
2027
- console.log(chalk12.dim("No changes made."));
2289
+ console.log(chalk13.dim("No changes made."));
2028
2290
  return;
2029
2291
  }
2030
2292
  }
@@ -2034,24 +2296,24 @@ var editCommand = new Command14("edit").description("Edit an existing memory").a
2034
2296
  if (opts.type !== void 0) updates.type = opts.type;
2035
2297
  const updated = await updateMemory(id, updates);
2036
2298
  if (!updated) {
2037
- console.error(chalk12.red("\u2717") + ` Failed to update memory ${chalk12.dim(id)}`);
2299
+ console.error(chalk13.red("\u2717") + ` Failed to update memory ${chalk13.dim(id)}`);
2038
2300
  process.exit(1);
2039
2301
  }
2040
2302
  const changes = [];
2041
2303
  if (updates.content !== void 0) changes.push("content");
2042
2304
  if (updates.tags !== void 0) changes.push("tags");
2043
2305
  if (updates.type !== void 0) changes.push(`type\u2192${updates.type}`);
2044
- console.log(chalk12.green("\u2713") + ` Updated ${chalk12.dim(id)} (${changes.join(", ")})`);
2306
+ console.log(chalk13.green("\u2713") + ` Updated ${chalk13.dim(id)} (${changes.join(", ")})`);
2045
2307
  } catch (error2) {
2046
2308
  if (error2.name === "ExitPromptError") return;
2047
- console.error(chalk12.red("\u2717") + " Failed to edit memory:", error2 instanceof Error ? error2.message : "Unknown error");
2309
+ console.error(chalk13.red("\u2717") + " Failed to edit memory:", error2 instanceof Error ? error2.message : "Unknown error");
2048
2310
  process.exit(1);
2049
2311
  }
2050
2312
  });
2051
2313
 
2052
2314
  // src/commands/stats.ts
2053
2315
  import { Command as Command15 } from "commander";
2054
- import chalk13 from "chalk";
2316
+ import chalk14 from "chalk";
2055
2317
  var statsCommand = new Command15("stats").description("Show memory statistics").option("--json", "Output as JSON").action(async (opts) => {
2056
2318
  try {
2057
2319
  const db = await getDb();
@@ -2088,46 +2350,46 @@ var statsCommand = new Command15("stats").description("Show memory statistics").
2088
2350
  console.log(JSON.stringify(data, null, 2));
2089
2351
  return;
2090
2352
  }
2091
- console.log(chalk13.bold("Memory Statistics\n"));
2353
+ console.log(chalk14.bold("Memory Statistics\n"));
2092
2354
  if (projectId) {
2093
- console.log(` Project: ${chalk13.dim(projectId)}`);
2355
+ console.log(` Project: ${chalk14.dim(projectId)}`);
2094
2356
  }
2095
- console.log(` Total: ${chalk13.bold(String(total))} active, ${chalk13.dim(String(deleted))} deleted
2357
+ console.log(` Total: ${chalk14.bold(String(total))} active, ${chalk14.dim(String(deleted))} deleted
2096
2358
  `);
2097
2359
  if (rows.length === 0) {
2098
- console.log(chalk13.dim(' No memories yet. Add one with: memories add "Your memory"'));
2360
+ console.log(chalk14.dim(' No memories yet. Add one with: memories add "Your memory"'));
2099
2361
  return;
2100
2362
  }
2101
2363
  const typeWidths = { rule: 8, decision: 8, fact: 8, note: 8 };
2102
2364
  console.log(
2103
- ` ${chalk13.dim("Type".padEnd(12))}${chalk13.dim("Scope".padEnd(10))}${chalk13.dim("Count")}`
2365
+ ` ${chalk14.dim("Type".padEnd(12))}${chalk14.dim("Scope".padEnd(10))}${chalk14.dim("Count")}`
2104
2366
  );
2105
- console.log(chalk13.dim(" " + "\u2500".repeat(30)));
2367
+ console.log(chalk14.dim(" " + "\u2500".repeat(30)));
2106
2368
  for (const row of rows) {
2107
2369
  const type = row.type.padEnd(12);
2108
2370
  const scope = row.scope.padEnd(10);
2109
2371
  console.log(` ${type}${scope}${Number(row.count)}`);
2110
2372
  }
2111
2373
  } catch (error2) {
2112
- console.error(chalk13.red("\u2717") + " Failed to get stats:", error2 instanceof Error ? error2.message : "Unknown error");
2374
+ console.error(chalk14.red("\u2717") + " Failed to get stats:", error2 instanceof Error ? error2.message : "Unknown error");
2113
2375
  process.exit(1);
2114
2376
  }
2115
2377
  });
2116
2378
 
2117
2379
  // src/commands/doctor.ts
2118
2380
  import { Command as Command16 } from "commander";
2119
- import chalk14 from "chalk";
2120
- import { existsSync as existsSync5 } from "fs";
2121
- import { join as join6 } from "path";
2381
+ import chalk15 from "chalk";
2382
+ import { existsSync as existsSync6 } from "fs";
2383
+ import { join as join7 } from "path";
2122
2384
  var doctorCommand = new Command16("doctor").description("Check memories health and diagnose issues").option("--fix", "Attempt to fix issues found").action(async (opts) => {
2123
2385
  try {
2124
- console.log(chalk14.bold("memories doctor\n"));
2386
+ console.log(chalk15.bold("memories doctor\n"));
2125
2387
  const checks = [
2126
2388
  {
2127
2389
  name: "Database file",
2128
2390
  run: async () => {
2129
- const dbPath = join6(getConfigDir(), "local.db");
2130
- if (existsSync5(dbPath)) {
2391
+ const dbPath = join7(getConfigDir(), "local.db");
2392
+ if (existsSync6(dbPath)) {
2131
2393
  return { ok: true, message: `Found at ${dbPath}` };
2132
2394
  }
2133
2395
  return { ok: false, message: `Not found at ${dbPath}. Run: memories init` };
@@ -2225,43 +2487,43 @@ var doctorCommand = new Command16("doctor").description("Check memories health a
2225
2487
  let hasIssues = false;
2226
2488
  for (const check of checks) {
2227
2489
  const { ok, message } = await check.run();
2228
- const icon = ok ? chalk14.green("\u2713") : chalk14.red("\u2717");
2229
- console.log(` ${icon} ${chalk14.bold(check.name)}: ${message}`);
2490
+ const icon = ok ? chalk15.green("\u2713") : chalk15.red("\u2717");
2491
+ console.log(` ${icon} ${chalk15.bold(check.name)}: ${message}`);
2230
2492
  if (!ok) hasIssues = true;
2231
2493
  }
2232
2494
  if (opts.fix) {
2233
- console.log(chalk14.bold("\nRunning fixes...\n"));
2495
+ console.log(chalk15.bold("\nRunning fixes...\n"));
2234
2496
  const db = await getDb();
2235
2497
  const purged = await db.execute(
2236
2498
  "DELETE FROM memories WHERE deleted_at IS NOT NULL"
2237
2499
  );
2238
- console.log(` ${chalk14.green("\u2713")} Purged ${purged.rowsAffected} soft-deleted records`);
2500
+ console.log(` ${chalk15.green("\u2713")} Purged ${purged.rowsAffected} soft-deleted records`);
2239
2501
  try {
2240
2502
  await db.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
2241
- console.log(` ${chalk14.green("\u2713")} Rebuilt FTS index`);
2503
+ console.log(` ${chalk15.green("\u2713")} Rebuilt FTS index`);
2242
2504
  } catch {
2243
- console.log(` ${chalk14.yellow("\u26A0")} Could not rebuild FTS index`);
2505
+ console.log(` ${chalk15.yellow("\u26A0")} Could not rebuild FTS index`);
2244
2506
  }
2245
2507
  }
2246
2508
  console.log();
2247
2509
  if (hasIssues) {
2248
- console.log(chalk14.yellow("Some issues detected.") + (opts.fix ? "" : " Run with --fix to attempt repairs."));
2510
+ console.log(chalk15.yellow("Some issues detected.") + (opts.fix ? "" : " Run with --fix to attempt repairs."));
2249
2511
  } else {
2250
- console.log(chalk14.green("All checks passed."));
2512
+ console.log(chalk15.green("All checks passed."));
2251
2513
  }
2252
2514
  } catch (error2) {
2253
- console.error(chalk14.red("\u2717") + " Doctor failed:", error2 instanceof Error ? error2.message : "Unknown error");
2515
+ console.error(chalk15.red("\u2717") + " Doctor failed:", error2 instanceof Error ? error2.message : "Unknown error");
2254
2516
  process.exit(1);
2255
2517
  }
2256
2518
  });
2257
2519
 
2258
2520
  // src/commands/hook.ts
2259
2521
  import { Command as Command17 } from "commander";
2260
- import chalk15 from "chalk";
2261
- import { readFile as readFile5, writeFile as writeFile5, chmod } from "fs/promises";
2262
- import { existsSync as existsSync6, readFileSync as readFileSync2 } from "fs";
2522
+ import chalk16 from "chalk";
2523
+ import { readFile as readFile6, writeFile as writeFile6, chmod } from "fs/promises";
2524
+ import { existsSync as existsSync7, readFileSync as readFileSync2 } from "fs";
2263
2525
  import { execFileSync as execFileSync3 } from "child_process";
2264
- import { join as join7 } from "path";
2526
+ import { join as join8 } from "path";
2265
2527
  var HOOK_MARKER_START = "# >>> memories.sh hook >>>";
2266
2528
  var HOOK_MARKER_END = "# <<< memories.sh hook <<<";
2267
2529
  var HOOK_SNIPPET = `
@@ -2282,22 +2544,22 @@ function getGitDir() {
2282
2544
  function getHookLocation(hookName) {
2283
2545
  const gitDir = getGitDir();
2284
2546
  if (!gitDir) return null;
2285
- const huskyPath = join7(".husky", hookName);
2286
- if (existsSync6(".husky") && !existsSync6(join7(".husky", "_"))) {
2547
+ const huskyPath = join8(".husky", hookName);
2548
+ if (existsSync7(".husky") && !existsSync7(join8(".husky", "_"))) {
2287
2549
  return { path: huskyPath, type: "husky" };
2288
2550
  }
2289
- const huskyLegacyPath = join7(".husky", "_", hookName);
2290
- if (existsSync6(join7(".husky", "_"))) {
2551
+ const huskyLegacyPath = join8(".husky", "_", hookName);
2552
+ if (existsSync7(join8(".husky", "_"))) {
2291
2553
  return { path: huskyLegacyPath, type: "husky" };
2292
2554
  }
2293
- if (existsSync6(huskyPath)) {
2555
+ if (existsSync7(huskyPath)) {
2294
2556
  return { path: huskyPath, type: "husky" };
2295
2557
  }
2296
- return { path: join7(gitDir, "hooks", hookName), type: "git" };
2558
+ return { path: join8(gitDir, "hooks", hookName), type: "git" };
2297
2559
  }
2298
2560
  function detectLintStaged() {
2299
2561
  try {
2300
- if (!existsSync6("package.json")) return false;
2562
+ if (!existsSync7("package.json")) return false;
2301
2563
  const pkg = JSON.parse(readFileSync2("package.json", "utf-8"));
2302
2564
  return !!(pkg["lint-staged"] || pkg.devDependencies?.["lint-staged"] || pkg.dependencies?.["lint-staged"]);
2303
2565
  } catch {
@@ -2310,31 +2572,31 @@ hookCommand.addCommand(
2310
2572
  try {
2311
2573
  const location = getHookLocation(opts.hook);
2312
2574
  if (!location) {
2313
- console.error(chalk15.red("\u2717") + " Not in a git repository");
2575
+ console.error(chalk16.red("\u2717") + " Not in a git repository");
2314
2576
  process.exit(1);
2315
2577
  }
2316
2578
  const hookPath = location.path;
2317
- if (existsSync6(hookPath)) {
2318
- const content = await readFile5(hookPath, "utf-8");
2579
+ if (existsSync7(hookPath)) {
2580
+ const content = await readFile6(hookPath, "utf-8");
2319
2581
  if (content.includes(HOOK_MARKER_START)) {
2320
- console.log(chalk15.dim("Hook already installed. Use 'memories hook uninstall' first to reinstall."));
2582
+ console.log(chalk16.dim("Hook already installed. Use 'memories hook uninstall' first to reinstall."));
2321
2583
  return;
2322
2584
  }
2323
- await writeFile5(hookPath, content.trimEnd() + "\n" + HOOK_SNIPPET + "\n", "utf-8");
2585
+ await writeFile6(hookPath, content.trimEnd() + "\n" + HOOK_SNIPPET + "\n", "utf-8");
2324
2586
  } else {
2325
- await writeFile5(hookPath, "#!/bin/sh\n" + HOOK_SNIPPET + "\n", "utf-8");
2587
+ await writeFile6(hookPath, "#!/bin/sh\n" + HOOK_SNIPPET + "\n", "utf-8");
2326
2588
  }
2327
2589
  await chmod(hookPath, 493);
2328
2590
  const locationLabel = location.type === "husky" ? "Husky" : ".git/hooks";
2329
- console.log(chalk15.green("\u2713") + ` Installed memories hook in ${chalk15.dim(opts.hook)} (${locationLabel})`);
2330
- console.log(chalk15.dim(" Rule files will auto-generate on each commit."));
2591
+ console.log(chalk16.green("\u2713") + ` Installed memories hook in ${chalk16.dim(opts.hook)} (${locationLabel})`);
2592
+ console.log(chalk16.dim(" Rule files will auto-generate on each commit."));
2331
2593
  if (detectLintStaged()) {
2332
2594
  console.log(
2333
- chalk15.dim("\n lint-staged detected. You can also add to your lint-staged config:") + chalk15.dim('\n "*.md": "memories generate all --force"')
2595
+ chalk16.dim("\n lint-staged detected. You can also add to your lint-staged config:") + chalk16.dim('\n "*.md": "memories generate all --force"')
2334
2596
  );
2335
2597
  }
2336
2598
  } catch (error2) {
2337
- console.error(chalk15.red("\u2717") + " Failed to install hook:", error2 instanceof Error ? error2.message : "Unknown error");
2599
+ console.error(chalk16.red("\u2717") + " Failed to install hook:", error2 instanceof Error ? error2.message : "Unknown error");
2338
2600
  process.exit(1);
2339
2601
  }
2340
2602
  })
@@ -2344,17 +2606,17 @@ hookCommand.addCommand(
2344
2606
  try {
2345
2607
  const location = getHookLocation(opts.hook);
2346
2608
  if (!location) {
2347
- console.error(chalk15.red("\u2717") + " Not in a git repository");
2609
+ console.error(chalk16.red("\u2717") + " Not in a git repository");
2348
2610
  process.exit(1);
2349
2611
  }
2350
2612
  const hookPath = location.path;
2351
- if (!existsSync6(hookPath)) {
2352
- console.log(chalk15.dim("No hook file found."));
2613
+ if (!existsSync7(hookPath)) {
2614
+ console.log(chalk16.dim("No hook file found."));
2353
2615
  return;
2354
2616
  }
2355
- const content = await readFile5(hookPath, "utf-8");
2617
+ const content = await readFile6(hookPath, "utf-8");
2356
2618
  if (!content.includes(HOOK_MARKER_START)) {
2357
- console.log(chalk15.dim("No memories hook found in " + opts.hook));
2619
+ console.log(chalk16.dim("No memories hook found in " + opts.hook));
2358
2620
  return;
2359
2621
  }
2360
2622
  const regex = new RegExp(
@@ -2364,13 +2626,13 @@ hookCommand.addCommand(
2364
2626
  if (cleaned.trim() === "#!/bin/sh" || cleaned.trim() === "") {
2365
2627
  const { unlink: unlink2 } = await import("fs/promises");
2366
2628
  await unlink2(hookPath);
2367
- console.log(chalk15.green("\u2713") + ` Removed ${chalk15.dim(opts.hook)} hook (was memories-only)`);
2629
+ console.log(chalk16.green("\u2713") + ` Removed ${chalk16.dim(opts.hook)} hook (was memories-only)`);
2368
2630
  } else {
2369
- await writeFile5(hookPath, cleaned, "utf-8");
2370
- console.log(chalk15.green("\u2713") + ` Removed memories section from ${chalk15.dim(opts.hook)}`);
2631
+ await writeFile6(hookPath, cleaned, "utf-8");
2632
+ console.log(chalk16.green("\u2713") + ` Removed memories section from ${chalk16.dim(opts.hook)}`);
2371
2633
  }
2372
2634
  } catch (error2) {
2373
- console.error(chalk15.red("\u2717") + " Failed to uninstall hook:", error2 instanceof Error ? error2.message : "Unknown error");
2635
+ console.error(chalk16.red("\u2717") + " Failed to uninstall hook:", error2 instanceof Error ? error2.message : "Unknown error");
2374
2636
  process.exit(1);
2375
2637
  }
2376
2638
  })
@@ -2380,21 +2642,21 @@ hookCommand.addCommand(
2380
2642
  try {
2381
2643
  const hookPath = getHookLocation(opts.hook)?.path;
2382
2644
  if (!hookPath) {
2383
- console.error(chalk15.red("\u2717") + " Not in a git repository");
2645
+ console.error(chalk16.red("\u2717") + " Not in a git repository");
2384
2646
  process.exit(1);
2385
2647
  }
2386
- if (!existsSync6(hookPath)) {
2387
- console.log(chalk15.dim("Not installed") + ` \u2014 no ${opts.hook} hook found`);
2648
+ if (!existsSync7(hookPath)) {
2649
+ console.log(chalk16.dim("Not installed") + ` \u2014 no ${opts.hook} hook found`);
2388
2650
  return;
2389
2651
  }
2390
- const content = await readFile5(hookPath, "utf-8");
2652
+ const content = await readFile6(hookPath, "utf-8");
2391
2653
  if (content.includes(HOOK_MARKER_START)) {
2392
- console.log(chalk15.green("\u2713") + ` Installed in ${chalk15.dim(hookPath)}`);
2654
+ console.log(chalk16.green("\u2713") + ` Installed in ${chalk16.dim(hookPath)}`);
2393
2655
  } else {
2394
- console.log(chalk15.dim("Not installed") + ` \u2014 ${opts.hook} exists but has no memories section`);
2656
+ console.log(chalk16.dim("Not installed") + ` \u2014 ${opts.hook} exists but has no memories section`);
2395
2657
  }
2396
2658
  } catch (error2) {
2397
- console.error(chalk15.red("\u2717") + " Failed to check hook:", error2 instanceof Error ? error2.message : "Unknown error");
2659
+ console.error(chalk16.red("\u2717") + " Failed to check hook:", error2 instanceof Error ? error2.message : "Unknown error");
2398
2660
  process.exit(1);
2399
2661
  }
2400
2662
  })
@@ -2405,9 +2667,9 @@ function escapeRegex(str) {
2405
2667
 
2406
2668
  // src/commands/ingest.ts
2407
2669
  import { Command as Command18 } from "commander";
2408
- import chalk16 from "chalk";
2409
- import { readFile as readFile6 } from "fs/promises";
2410
- import { existsSync as existsSync7 } from "fs";
2670
+ import chalk17 from "chalk";
2671
+ import { readFile as readFile7 } from "fs/promises";
2672
+ import { existsSync as existsSync8 } from "fs";
2411
2673
  var SOURCES = [
2412
2674
  { name: "cursor", paths: [".cursor/rules/memories.mdc", ".cursorrules"], description: "Cursor rules" },
2413
2675
  { name: "claude", paths: ["CLAUDE.md"], description: "Claude Code instructions" },
@@ -2467,14 +2729,14 @@ function normalize(s) {
2467
2729
  var ingestCommand = new Command18("ingest").description("Import memories from existing IDE rule files").argument("[source]", "Source to import from (cursor, claude, agents, copilot, windsurf, cline, roo, gemini, or file path)").option("--type <type>", "Override type for all imported memories").option("--dry-run", "Preview without importing").option("--all", "Scan all known IDE rule file locations").option("--no-dedup", "Skip duplicate detection").action(async (source, opts) => {
2468
2730
  try {
2469
2731
  if (opts.type && !VALID_TYPES8.includes(opts.type)) {
2470
- console.error(chalk16.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES8.join(", ")}`);
2732
+ console.error(chalk17.red("\u2717") + ` Invalid type "${opts.type}". Valid types: ${VALID_TYPES8.join(", ")}`);
2471
2733
  process.exit(1);
2472
2734
  }
2473
2735
  const filesToProcess = [];
2474
2736
  if (opts.all) {
2475
2737
  for (const src of SOURCES) {
2476
2738
  for (const p of src.paths) {
2477
- if (existsSync7(p)) {
2739
+ if (existsSync8(p)) {
2478
2740
  filesToProcess.push({ name: src.name, path: p });
2479
2741
  }
2480
2742
  }
@@ -2483,27 +2745,27 @@ var ingestCommand = new Command18("ingest").description("Import memories from ex
2483
2745
  const known = SOURCES.find((s) => s.name === source);
2484
2746
  if (known) {
2485
2747
  for (const p of known.paths) {
2486
- if (existsSync7(p)) {
2748
+ if (existsSync8(p)) {
2487
2749
  filesToProcess.push({ name: known.name, path: p });
2488
2750
  break;
2489
2751
  }
2490
2752
  }
2491
2753
  if (filesToProcess.length === 0) {
2492
- console.error(chalk16.red("\u2717") + ` No ${known.description} file found at: ${known.paths.join(", ")}`);
2754
+ console.error(chalk17.red("\u2717") + ` No ${known.description} file found at: ${known.paths.join(", ")}`);
2493
2755
  process.exit(1);
2494
2756
  }
2495
- } else if (existsSync7(source)) {
2757
+ } else if (existsSync8(source)) {
2496
2758
  filesToProcess.push({ name: "file", path: source });
2497
2759
  } else {
2498
- console.error(chalk16.red("\u2717") + ` Unknown source "${source}". Valid: ${SOURCES.map((s) => s.name).join(", ")}, or a file path`);
2760
+ console.error(chalk17.red("\u2717") + ` Unknown source "${source}". Valid: ${SOURCES.map((s) => s.name).join(", ")}, or a file path`);
2499
2761
  process.exit(1);
2500
2762
  }
2501
2763
  } else {
2502
- console.error(chalk16.red("\u2717") + " Specify a source or use --all");
2764
+ console.error(chalk17.red("\u2717") + " Specify a source or use --all");
2503
2765
  process.exit(1);
2504
2766
  }
2505
2767
  if (filesToProcess.length === 0) {
2506
- console.log(chalk16.dim("No IDE rule files found."));
2768
+ console.log(chalk17.dim("No IDE rule files found."));
2507
2769
  return;
2508
2770
  }
2509
2771
  const existingSet = /* @__PURE__ */ new Set();
@@ -2517,29 +2779,29 @@ var ingestCommand = new Command18("ingest").description("Import memories from ex
2517
2779
  let totalImported = 0;
2518
2780
  let totalSkipped = 0;
2519
2781
  for (const file of filesToProcess) {
2520
- const content = await readFile6(file.path, "utf-8");
2782
+ const content = await readFile7(file.path, "utf-8");
2521
2783
  if (content.includes(MARKER2)) {
2522
- console.log(chalk16.dim(` Skipping ${file.path} (generated by memories.sh)`));
2784
+ console.log(chalk17.dim(` Skipping ${file.path} (generated by memories.sh)`));
2523
2785
  continue;
2524
2786
  }
2525
2787
  const memories = extractMemories(content);
2526
2788
  if (memories.length === 0) {
2527
- console.log(chalk16.dim(` No importable memories found in ${file.path}`));
2789
+ console.log(chalk17.dim(` No importable memories found in ${file.path}`));
2528
2790
  continue;
2529
2791
  }
2530
- console.log(chalk16.bold(`
2531
- ${file.name}`) + chalk16.dim(` (${file.path}) \u2014 ${memories.length} items`));
2792
+ console.log(chalk17.bold(`
2793
+ ${file.name}`) + chalk17.dim(` (${file.path}) \u2014 ${memories.length} items`));
2532
2794
  for (const mem of memories) {
2533
2795
  const type = opts.type ?? mem.type;
2534
2796
  if (opts.dedup !== false && existingSet.has(normalize(mem.content))) {
2535
2797
  if (opts.dryRun) {
2536
- console.log(` ${chalk16.dim("skip")} ${chalk16.dim(mem.content)}`);
2798
+ console.log(` ${chalk17.dim("skip")} ${chalk17.dim(mem.content)}`);
2537
2799
  }
2538
2800
  totalSkipped++;
2539
2801
  continue;
2540
2802
  }
2541
2803
  if (opts.dryRun) {
2542
- const typeColor = type === "rule" ? chalk16.blue : type === "decision" ? chalk16.yellow : type === "fact" ? chalk16.green : chalk16.dim;
2804
+ const typeColor = type === "rule" ? chalk17.blue : type === "decision" ? chalk17.yellow : type === "fact" ? chalk17.green : chalk17.dim;
2543
2805
  console.log(` ${typeColor(type.padEnd(9))} ${mem.content}`);
2544
2806
  } else {
2545
2807
  await addMemory(mem.content, { type });
@@ -2550,23 +2812,23 @@ var ingestCommand = new Command18("ingest").description("Import memories from ex
2550
2812
  }
2551
2813
  if (opts.dryRun) {
2552
2814
  const skipMsg = totalSkipped > 0 ? ` (${totalSkipped} duplicates skipped)` : "";
2553
- console.log(chalk16.dim(`
2815
+ console.log(chalk17.dim(`
2554
2816
  Dry run \u2014 no memories imported.${skipMsg} Remove --dry-run to import.`));
2555
2817
  } else {
2556
- const skipMsg = totalSkipped > 0 ? chalk16.dim(` (${totalSkipped} duplicates skipped)`) : "";
2557
- console.log(chalk16.green("\n\u2713") + ` Imported ${totalImported} memories` + skipMsg);
2818
+ const skipMsg = totalSkipped > 0 ? chalk17.dim(` (${totalSkipped} duplicates skipped)`) : "";
2819
+ console.log(chalk17.green("\n\u2713") + ` Imported ${totalImported} memories` + skipMsg);
2558
2820
  }
2559
2821
  } catch (error2) {
2560
- console.error(chalk16.red("\u2717") + " Failed to ingest:", error2 instanceof Error ? error2.message : "Unknown error");
2822
+ console.error(chalk17.red("\u2717") + " Failed to ingest:", error2 instanceof Error ? error2.message : "Unknown error");
2561
2823
  process.exit(1);
2562
2824
  }
2563
2825
  });
2564
2826
 
2565
2827
  // src/commands/diff.ts
2566
2828
  import { Command as Command19 } from "commander";
2567
- import chalk17 from "chalk";
2568
- import { readFile as readFile7 } from "fs/promises";
2569
- import { existsSync as existsSync8 } from "fs";
2829
+ import chalk18 from "chalk";
2830
+ import { readFile as readFile8 } from "fs/promises";
2831
+ import { existsSync as existsSync9 } from "fs";
2570
2832
  import { resolve as resolve2 } from "path";
2571
2833
  var MARKER3 = "Generated by memories.sh";
2572
2834
  var VALID_TYPES9 = ["rule", "decision", "fact", "note"];
@@ -2599,7 +2861,7 @@ function parseTypes2(raw) {
2599
2861
  const types = raw.split(",").map((s) => s.trim());
2600
2862
  for (const t of types) {
2601
2863
  if (!VALID_TYPES9.includes(t)) {
2602
- console.error(chalk17.red("\u2717") + ` Invalid type "${t}". Valid: ${VALID_TYPES9.join(", ")}`);
2864
+ console.error(chalk18.red("\u2717") + ` Invalid type "${t}". Valid: ${VALID_TYPES9.join(", ")}`);
2603
2865
  process.exit(1);
2604
2866
  }
2605
2867
  }
@@ -2611,7 +2873,7 @@ async function fetchMemories2(types) {
2611
2873
  }
2612
2874
  async function diffTarget(target, currentMemories, outputPath) {
2613
2875
  const filePath = resolve2(outputPath ?? target.defaultPath);
2614
- if (!existsSync8(filePath)) {
2876
+ if (!existsSync9(filePath)) {
2615
2877
  return {
2616
2878
  added: currentMemories.map((m) => m.content),
2617
2879
  removed: [],
@@ -2622,7 +2884,7 @@ async function diffTarget(target, currentMemories, outputPath) {
2622
2884
  generatedAt: null
2623
2885
  };
2624
2886
  }
2625
- const content = await readFile7(filePath, "utf-8");
2887
+ const content = await readFile8(filePath, "utf-8");
2626
2888
  const isOurs = content.includes(MARKER3);
2627
2889
  const generatedAt = extractTimestamp(content);
2628
2890
  const fileMemories = extractFileMemories(content);
@@ -2638,7 +2900,7 @@ var diffCommand = new Command19("diff").description("Show what changed since las
2638
2900
  const memories = await fetchMemories2(types);
2639
2901
  const targetsToCheck = target && target !== "all" ? TARGETS2.filter((t) => t.name === target) : TARGETS2;
2640
2902
  if (target && target !== "all" && targetsToCheck.length === 0) {
2641
- console.error(chalk17.red("\u2717") + ` Unknown target "${target}". Valid: ${TARGETS2.map((t) => t.name).join(", ")}`);
2903
+ console.error(chalk18.red("\u2717") + ` Unknown target "${target}". Valid: ${TARGETS2.map((t) => t.name).join(", ")}`);
2642
2904
  process.exit(1);
2643
2905
  }
2644
2906
  let anyStale = false;
@@ -2647,54 +2909,54 @@ var diffCommand = new Command19("diff").description("Show what changed since las
2647
2909
  if (!result.exists && !target) continue;
2648
2910
  const hasChanges = result.added.length > 0 || result.removed.length > 0;
2649
2911
  if (!result.exists) {
2650
- console.log(chalk17.bold(`
2651
- ${t.name}`) + chalk17.dim(` \u2192 ${result.filePath}`));
2652
- console.log(chalk17.yellow(" Not generated yet.") + chalk17.dim(` Run: memories generate ${t.name}`));
2912
+ console.log(chalk18.bold(`
2913
+ ${t.name}`) + chalk18.dim(` \u2192 ${result.filePath}`));
2914
+ console.log(chalk18.yellow(" Not generated yet.") + chalk18.dim(` Run: memories generate ${t.name}`));
2653
2915
  anyStale = true;
2654
2916
  continue;
2655
2917
  }
2656
2918
  if (!result.isOurs) {
2657
- console.log(chalk17.bold(`
2658
- ${t.name}`) + chalk17.dim(` \u2192 ${result.filePath}`));
2659
- console.log(chalk17.dim(" Not managed by memories.sh (no marker found)"));
2919
+ console.log(chalk18.bold(`
2920
+ ${t.name}`) + chalk18.dim(` \u2192 ${result.filePath}`));
2921
+ console.log(chalk18.dim(" Not managed by memories.sh (no marker found)"));
2660
2922
  continue;
2661
2923
  }
2662
2924
  if (!hasChanges) {
2663
2925
  if (target) {
2664
- console.log(chalk17.bold(`
2665
- ${t.name}`) + chalk17.dim(` \u2192 ${result.filePath}`));
2666
- const since = result.generatedAt ? chalk17.dim(` (generated ${formatRelative(result.generatedAt)})`) : "";
2667
- console.log(chalk17.green(" Up to date.") + since);
2926
+ console.log(chalk18.bold(`
2927
+ ${t.name}`) + chalk18.dim(` \u2192 ${result.filePath}`));
2928
+ const since = result.generatedAt ? chalk18.dim(` (generated ${formatRelative(result.generatedAt)})`) : "";
2929
+ console.log(chalk18.green(" Up to date.") + since);
2668
2930
  }
2669
2931
  continue;
2670
2932
  }
2671
2933
  anyStale = true;
2672
- console.log(chalk17.bold(`
2673
- ${t.name}`) + chalk17.dim(` \u2192 ${result.filePath}`));
2934
+ console.log(chalk18.bold(`
2935
+ ${t.name}`) + chalk18.dim(` \u2192 ${result.filePath}`));
2674
2936
  if (result.generatedAt) {
2675
- console.log(chalk17.dim(` Generated ${formatRelative(result.generatedAt)}`));
2937
+ console.log(chalk18.dim(` Generated ${formatRelative(result.generatedAt)}`));
2676
2938
  }
2677
2939
  for (const a of result.added) {
2678
- console.log(chalk17.green(` + ${a}`));
2940
+ console.log(chalk18.green(` + ${a}`));
2679
2941
  }
2680
2942
  for (const r of result.removed) {
2681
- console.log(chalk17.red(` - ${r}`));
2943
+ console.log(chalk18.red(` - ${r}`));
2682
2944
  }
2683
2945
  if (result.unchanged > 0) {
2684
- console.log(chalk17.dim(` ${result.unchanged} unchanged`));
2946
+ console.log(chalk18.dim(` ${result.unchanged} unchanged`));
2685
2947
  }
2686
2948
  }
2687
2949
  if (!anyStale) {
2688
2950
  if (target) {
2689
2951
  } else {
2690
- console.log(chalk17.green("\n All generated files are up to date."));
2952
+ console.log(chalk18.green("\n All generated files are up to date."));
2691
2953
  }
2692
2954
  } else {
2693
- console.log(chalk17.dim(`
2694
- Run ${chalk17.bold("memories generate")} to update stale files.`));
2955
+ console.log(chalk18.dim(`
2956
+ Run ${chalk18.bold("memories generate")} to update stale files.`));
2695
2957
  }
2696
2958
  } catch (error2) {
2697
- console.error(chalk17.red("\u2717") + " Diff failed:", error2 instanceof Error ? error2.message : "Unknown error");
2959
+ console.error(chalk18.red("\u2717") + " Diff failed:", error2 instanceof Error ? error2.message : "Unknown error");
2698
2960
  process.exit(1);
2699
2961
  }
2700
2962
  });
@@ -2715,7 +2977,7 @@ function formatRelative(isoDate) {
2715
2977
 
2716
2978
  // src/commands/tag.ts
2717
2979
  import { Command as Command20 } from "commander";
2718
- import chalk18 from "chalk";
2980
+ import chalk19 from "chalk";
2719
2981
  var VALID_TYPES10 = ["rule", "decision", "fact", "note"];
2720
2982
  function buildWhere(filters) {
2721
2983
  const conditions = ["deleted_at IS NULL"];
@@ -2767,12 +3029,12 @@ tagCommand.addCommand(
2767
3029
  updated++;
2768
3030
  }
2769
3031
  if (opts.dryRun) {
2770
- console.log(chalk18.dim(`Dry run \u2014 would tag ${updated} memories with "${tag}" (${skipped} already tagged)`));
3032
+ console.log(chalk19.dim(`Dry run \u2014 would tag ${updated} memories with "${tag}" (${skipped} already tagged)`));
2771
3033
  } else {
2772
- console.log(chalk18.green("\u2713") + ` Tagged ${updated} memories with "${tag}"` + (skipped > 0 ? chalk18.dim(` (${skipped} already tagged)`) : ""));
3034
+ console.log(chalk19.green("\u2713") + ` Tagged ${updated} memories with "${tag}"` + (skipped > 0 ? chalk19.dim(` (${skipped} already tagged)`) : ""));
2773
3035
  }
2774
3036
  } catch (error2) {
2775
- console.error(chalk18.red("\u2717") + ` Failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
3037
+ console.error(chalk19.red("\u2717") + ` Failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2776
3038
  process.exit(1);
2777
3039
  }
2778
3040
  })
@@ -2801,12 +3063,12 @@ tagCommand.addCommand(
2801
3063
  updated++;
2802
3064
  }
2803
3065
  if (opts.dryRun) {
2804
- console.log(chalk18.dim(`Dry run \u2014 would remove "${tag}" from ${updated} memories`));
3066
+ console.log(chalk19.dim(`Dry run \u2014 would remove "${tag}" from ${updated} memories`));
2805
3067
  } else {
2806
- console.log(chalk18.green("\u2713") + ` Removed "${tag}" from ${updated} memories`);
3068
+ console.log(chalk19.green("\u2713") + ` Removed "${tag}" from ${updated} memories`);
2807
3069
  }
2808
3070
  } catch (error2) {
2809
- console.error(chalk18.red("\u2717") + ` Failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
3071
+ console.error(chalk19.red("\u2717") + ` Failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2810
3072
  process.exit(1);
2811
3073
  }
2812
3074
  })
@@ -2827,15 +3089,15 @@ tagCommand.addCommand(
2827
3089
  }
2828
3090
  }
2829
3091
  if (counts.size === 0) {
2830
- console.log(chalk18.dim("No tags found."));
3092
+ console.log(chalk19.dim("No tags found."));
2831
3093
  return;
2832
3094
  }
2833
3095
  const sorted = [...counts.entries()].sort((a, b) => b[1] - a[1]);
2834
3096
  for (const [tag, count] of sorted) {
2835
- console.log(` ${chalk18.bold(tag)} ${chalk18.dim(`(${count})`)}`);
3097
+ console.log(` ${chalk19.bold(tag)} ${chalk19.dim(`(${count})`)}`);
2836
3098
  }
2837
3099
  } catch (error2) {
2838
- console.error(chalk18.red("\u2717") + ` Failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
3100
+ console.error(chalk19.red("\u2717") + ` Failed: ${error2 instanceof Error ? error2.message : "Unknown error"}`);
2839
3101
  process.exit(1);
2840
3102
  }
2841
3103
  })
@@ -2843,7 +3105,7 @@ tagCommand.addCommand(
2843
3105
 
2844
3106
  // src/commands/validate.ts
2845
3107
  import { Command as Command21 } from "commander";
2846
- import chalk19 from "chalk";
3108
+ import chalk20 from "chalk";
2847
3109
  function levenshtein(a, b) {
2848
3110
  const m = a.length, n = b.length;
2849
3111
  const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
@@ -2904,10 +3166,10 @@ var validateCommand = new Command21("validate").description("Check for conflicti
2904
3166
  const projectId = getProjectId() ?? void 0;
2905
3167
  const rules = await getRules({ projectId });
2906
3168
  if (rules.length === 0) {
2907
- console.log(chalk19.dim("No rules to validate."));
3169
+ console.log(chalk20.dim("No rules to validate."));
2908
3170
  return;
2909
3171
  }
2910
- console.log(chalk19.bold("\u{1F50D} Validating rules...\n"));
3172
+ console.log(chalk20.bold("\u{1F50D} Validating rules...\n"));
2911
3173
  const issues = [];
2912
3174
  for (let i = 0; i < rules.length; i++) {
2913
3175
  for (let j = i + 1; j < rules.length; j++) {
@@ -2939,41 +3201,41 @@ var validateCommand = new Command21("validate").description("Check for conflicti
2939
3201
  }
2940
3202
  }
2941
3203
  if (issues.length === 0) {
2942
- console.log(chalk19.green("\u2713") + ` ${rules.length} rules validated, no issues found.`);
3204
+ console.log(chalk20.green("\u2713") + ` ${rules.length} rules validated, no issues found.`);
2943
3205
  return;
2944
3206
  }
2945
- console.log(chalk19.yellow("\u26A0\uFE0F Potential Issues Found:\n"));
3207
+ console.log(chalk20.yellow("\u26A0\uFE0F Potential Issues Found:\n"));
2946
3208
  let num = 1;
2947
3209
  for (const issue of issues) {
2948
3210
  const typeLabel = issue.type === "duplicate" ? "Exact duplicate" : issue.type === "near-duplicate" ? "Near duplicate" : "Potential conflict";
2949
- const color = issue.type === "conflict" ? chalk19.red : chalk19.yellow;
3211
+ const color = issue.type === "conflict" ? chalk20.red : chalk20.yellow;
2950
3212
  console.log(color(`${num}. ${typeLabel}${issue.detail ? ` (${issue.detail})` : ""}:`));
2951
3213
  console.log(` \u{1F4CC} "${issue.memory1.content}"`);
2952
3214
  console.log(` \u{1F4CC} "${issue.memory2.content}"`);
2953
3215
  if (issue.type === "duplicate" || issue.type === "near-duplicate") {
2954
- console.log(chalk19.dim(" \u2192 Consider merging these rules\n"));
3216
+ console.log(chalk20.dim(" \u2192 Consider merging these rules\n"));
2955
3217
  } else {
2956
- console.log(chalk19.dim(" \u2192 These rules may contradict each other\n"));
3218
+ console.log(chalk20.dim(" \u2192 These rules may contradict each other\n"));
2957
3219
  }
2958
3220
  num++;
2959
3221
  }
2960
3222
  const duplicates = issues.filter((i) => i.type === "duplicate" || i.type === "near-duplicate").length;
2961
3223
  const conflicts = issues.filter((i) => i.type === "conflict").length;
2962
- console.log(chalk19.bold(`${rules.length} rules validated, ${issues.length} issues found`));
2963
- if (duplicates > 0) console.log(chalk19.dim(` ${duplicates} duplicate(s)`));
2964
- if (conflicts > 0) console.log(chalk19.dim(` ${conflicts} conflict(s)`));
3224
+ console.log(chalk20.bold(`${rules.length} rules validated, ${issues.length} issues found`));
3225
+ if (duplicates > 0) console.log(chalk20.dim(` ${duplicates} duplicate(s)`));
3226
+ if (conflicts > 0) console.log(chalk20.dim(` ${conflicts} conflict(s)`));
2965
3227
  if (opts.fix) {
2966
- console.log(chalk19.dim("\n--fix mode not yet implemented. Review issues above manually."));
3228
+ console.log(chalk20.dim("\n--fix mode not yet implemented. Review issues above manually."));
2967
3229
  }
2968
3230
  } catch (error2) {
2969
- console.error(chalk19.red("\u2717") + " Validation failed:", error2 instanceof Error ? error2.message : "Unknown error");
3231
+ console.error(chalk20.red("\u2717") + " Validation failed:", error2 instanceof Error ? error2.message : "Unknown error");
2970
3232
  process.exit(1);
2971
3233
  }
2972
3234
  });
2973
3235
 
2974
3236
  // src/commands/stale.ts
2975
3237
  import { Command as Command22 } from "commander";
2976
- import chalk20 from "chalk";
3238
+ import chalk21 from "chalk";
2977
3239
  import { createInterface as createInterface2 } from "readline";
2978
3240
  var TYPE_ICONS4 = {
2979
3241
  rule: "\u{1F4CC}",
@@ -2996,7 +3258,7 @@ var staleCommand = new Command22("stale").description("Find memories that haven'
2996
3258
  const days = parseInt(opts.days, 10);
2997
3259
  const projectId = getProjectId() ?? void 0;
2998
3260
  if (isNaN(days) || days <= 0) {
2999
- console.error(chalk20.red("\u2717") + " --days must be a positive number");
3261
+ console.error(chalk21.red("\u2717") + " --days must be a positive number");
3000
3262
  process.exit(1);
3001
3263
  }
3002
3264
  let sql = `
@@ -3019,25 +3281,25 @@ var staleCommand = new Command22("stale").description("Find memories that haven'
3019
3281
  return;
3020
3282
  }
3021
3283
  if (stale.length === 0) {
3022
- console.log(chalk20.green("\u2713") + ` No memories older than ${days} days.`);
3284
+ console.log(chalk21.green("\u2713") + ` No memories older than ${days} days.`);
3023
3285
  return;
3024
3286
  }
3025
- console.log(chalk20.bold(`\u23F0 Stale Memories (not updated in ${days}+ days)
3287
+ console.log(chalk21.bold(`\u23F0 Stale Memories (not updated in ${days}+ days)
3026
3288
  `));
3027
3289
  for (const m of stale.slice(0, 30)) {
3028
3290
  const icon = TYPE_ICONS4[m.type] || "\u{1F4DD}";
3029
- const scope = m.scope === "global" ? chalk20.dim("G") : chalk20.dim("P");
3291
+ const scope = m.scope === "global" ? chalk21.dim("G") : chalk21.dim("P");
3030
3292
  const preview = m.content.length > 50 ? m.content.slice(0, 47) + "..." : m.content;
3031
- console.log(` ${icon} ${scope} ${chalk20.dim(m.id)} ${preview} ${chalk20.yellow(`${m.days_old}d`)}`);
3293
+ console.log(` ${icon} ${scope} ${chalk21.dim(m.id)} ${preview} ${chalk21.yellow(`${m.days_old}d`)}`);
3032
3294
  }
3033
3295
  if (stale.length > 30) {
3034
- console.log(chalk20.dim(` ... and ${stale.length - 30} more`));
3296
+ console.log(chalk21.dim(` ... and ${stale.length - 30} more`));
3035
3297
  }
3036
3298
  console.log("");
3037
3299
  console.log(`${stale.length} stale ${stale.length === 1 ? "memory" : "memories"} found`);
3038
- console.log(chalk20.dim("Run 'memories review' to clean up interactively"));
3300
+ console.log(chalk21.dim("Run 'memories review' to clean up interactively"));
3039
3301
  } catch (error2) {
3040
- console.error(chalk20.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3302
+ console.error(chalk21.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3041
3303
  process.exit(1);
3042
3304
  }
3043
3305
  });
@@ -3058,18 +3320,18 @@ var reviewCommand = new Command22("review").description("Interactively review an
3058
3320
  });
3059
3321
  const stale = result.rows;
3060
3322
  if (stale.length === 0) {
3061
- console.log(chalk20.green("\u2713") + ` No stale memories to review.`);
3323
+ console.log(chalk21.green("\u2713") + ` No stale memories to review.`);
3062
3324
  return;
3063
3325
  }
3064
- console.log(chalk20.bold(`
3326
+ console.log(chalk21.bold(`
3065
3327
  Reviewing ${stale.length} stale memories...
3066
3328
  `));
3067
3329
  let kept = 0, deleted = 0, skipped = 0;
3068
3330
  for (const m of stale) {
3069
3331
  const icon = TYPE_ICONS4[m.type] || "\u{1F4DD}";
3070
- console.log(`${icon} ${chalk20.bold(m.type.toUpperCase())} (${m.scope})`);
3332
+ console.log(`${icon} ${chalk21.bold(m.type.toUpperCase())} (${m.scope})`);
3071
3333
  console.log(` "${m.content}"`);
3072
- console.log(chalk20.dim(` Last updated: ${m.days_old} days ago`));
3334
+ console.log(chalk21.dim(` Last updated: ${m.days_old} days ago`));
3073
3335
  console.log("");
3074
3336
  const answer = await prompt(" [k]eep [d]elete [s]kip [q]uit > ");
3075
3337
  if (answer === "q") {
@@ -3077,31 +3339,31 @@ Reviewing ${stale.length} stale memories...
3077
3339
  break;
3078
3340
  } else if (answer === "d") {
3079
3341
  await forgetMemory(m.id);
3080
- console.log(chalk20.green(" \u2713 Deleted\n"));
3342
+ console.log(chalk21.green(" \u2713 Deleted\n"));
3081
3343
  deleted++;
3082
3344
  } else if (answer === "k") {
3083
3345
  await db.execute({
3084
3346
  sql: "UPDATE memories SET updated_at = datetime('now') WHERE id = ?",
3085
3347
  args: [m.id]
3086
3348
  });
3087
- console.log(chalk20.green(" \u2713 Kept (marked as reviewed)\n"));
3349
+ console.log(chalk21.green(" \u2713 Kept (marked as reviewed)\n"));
3088
3350
  kept++;
3089
3351
  } else {
3090
- console.log(chalk20.dim(" Skipped\n"));
3352
+ console.log(chalk21.dim(" Skipped\n"));
3091
3353
  skipped++;
3092
3354
  }
3093
3355
  }
3094
- console.log(chalk20.bold("\nReview Summary:"));
3356
+ console.log(chalk21.bold("\nReview Summary:"));
3095
3357
  console.log(` Kept: ${kept}, Deleted: ${deleted}, Skipped: ${skipped}`);
3096
3358
  } catch (error2) {
3097
- console.error(chalk20.red("\u2717") + " Review failed:", error2 instanceof Error ? error2.message : "Unknown error");
3359
+ console.error(chalk21.red("\u2717") + " Review failed:", error2 instanceof Error ? error2.message : "Unknown error");
3098
3360
  process.exit(1);
3099
3361
  }
3100
3362
  });
3101
3363
 
3102
3364
  // src/commands/link.ts
3103
3365
  import { Command as Command23 } from "commander";
3104
- import chalk21 from "chalk";
3366
+ import chalk22 from "chalk";
3105
3367
  import { nanoid as nanoid3 } from "nanoid";
3106
3368
  var LINK_TYPES = ["related", "supports", "supersedes", "contradicts"];
3107
3369
  var TYPE_ICONS5 = {
@@ -3167,17 +3429,17 @@ var linkCommand = new Command23("link").description("Link two related memories t
3167
3429
  await ensureLinksTable();
3168
3430
  const db = await getDb();
3169
3431
  if (!LINK_TYPES.includes(opts.type)) {
3170
- console.error(chalk21.red("\u2717") + ` Invalid link type. Valid: ${LINK_TYPES.join(", ")}`);
3432
+ console.error(chalk22.red("\u2717") + ` Invalid link type. Valid: ${LINK_TYPES.join(", ")}`);
3171
3433
  process.exit(1);
3172
3434
  }
3173
3435
  const m1 = await getMemoryById(id1);
3174
3436
  const m2 = await getMemoryById(id2);
3175
3437
  if (!m1) {
3176
- console.error(chalk21.red("\u2717") + ` Memory ${id1} not found`);
3438
+ console.error(chalk22.red("\u2717") + ` Memory ${id1} not found`);
3177
3439
  process.exit(1);
3178
3440
  }
3179
3441
  if (!m2) {
3180
- console.error(chalk21.red("\u2717") + ` Memory ${id2} not found`);
3442
+ console.error(chalk22.red("\u2717") + ` Memory ${id2} not found`);
3181
3443
  process.exit(1);
3182
3444
  }
3183
3445
  const existing = await db.execute({
@@ -3186,7 +3448,7 @@ var linkCommand = new Command23("link").description("Link two related memories t
3186
3448
  args: [id1, id2, id2, id1]
3187
3449
  });
3188
3450
  if (existing.rows.length > 0) {
3189
- console.log(chalk21.yellow("!") + " These memories are already linked");
3451
+ console.log(chalk22.yellow("!") + " These memories are already linked");
3190
3452
  return;
3191
3453
  }
3192
3454
  const linkId = nanoid3(12);
@@ -3196,12 +3458,12 @@ var linkCommand = new Command23("link").description("Link two related memories t
3196
3458
  });
3197
3459
  const icon1 = TYPE_ICONS5[m1.type] || "\u{1F4DD}";
3198
3460
  const icon2 = TYPE_ICONS5[m2.type] || "\u{1F4DD}";
3199
- console.log(chalk21.green("\u2713") + " Linked memories:");
3200
- console.log(` ${icon1} ${chalk21.dim(id1)} "${m1.content.slice(0, 40)}..."`);
3201
- console.log(` \u2193 ${chalk21.cyan(opts.type)}`);
3202
- console.log(` ${icon2} ${chalk21.dim(id2)} "${m2.content.slice(0, 40)}..."`);
3461
+ console.log(chalk22.green("\u2713") + " Linked memories:");
3462
+ console.log(` ${icon1} ${chalk22.dim(id1)} "${m1.content.slice(0, 40)}..."`);
3463
+ console.log(` \u2193 ${chalk22.cyan(opts.type)}`);
3464
+ console.log(` ${icon2} ${chalk22.dim(id2)} "${m2.content.slice(0, 40)}..."`);
3203
3465
  } catch (error2) {
3204
- console.error(chalk21.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3466
+ console.error(chalk22.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3205
3467
  process.exit(1);
3206
3468
  }
3207
3469
  });
@@ -3215,12 +3477,12 @@ var unlinkCommand = new Command23("unlink").description("Remove link between two
3215
3477
  args: [id1, id2, id2, id1]
3216
3478
  });
3217
3479
  if (result.rowsAffected === 0) {
3218
- console.log(chalk21.yellow("!") + " No link found between these memories");
3480
+ console.log(chalk22.yellow("!") + " No link found between these memories");
3219
3481
  } else {
3220
- console.log(chalk21.green("\u2713") + ` Unlinked ${id1} and ${id2}`);
3482
+ console.log(chalk22.green("\u2713") + ` Unlinked ${id1} and ${id2}`);
3221
3483
  }
3222
3484
  } catch (error2) {
3223
- console.error(chalk21.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3485
+ console.error(chalk22.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3224
3486
  process.exit(1);
3225
3487
  }
3226
3488
  });
@@ -3228,16 +3490,16 @@ var showCommand = new Command23("show").description("Show a memory with its link
3228
3490
  try {
3229
3491
  const memory = await getMemoryById(id);
3230
3492
  if (!memory) {
3231
- console.error(chalk21.red("\u2717") + ` Memory ${id} not found`);
3493
+ console.error(chalk22.red("\u2717") + ` Memory ${id} not found`);
3232
3494
  process.exit(1);
3233
3495
  }
3234
3496
  const icon = TYPE_ICONS5[memory.type] || "\u{1F4DD}";
3235
3497
  const scope = memory.scope === "global" ? "Global" : "Project";
3236
3498
  console.log("");
3237
- console.log(`${icon} ${chalk21.bold(memory.type.toUpperCase())} (${scope})`);
3238
- console.log(chalk21.dim(`ID: ${memory.id}`));
3239
- console.log(chalk21.dim(`Created: ${memory.created_at}`));
3240
- if (memory.tags) console.log(chalk21.dim(`Tags: ${memory.tags}`));
3499
+ console.log(`${icon} ${chalk22.bold(memory.type.toUpperCase())} (${scope})`);
3500
+ console.log(chalk22.dim(`ID: ${memory.id}`));
3501
+ console.log(chalk22.dim(`Created: ${memory.created_at}`));
3502
+ if (memory.tags) console.log(chalk22.dim(`Tags: ${memory.tags}`));
3241
3503
  console.log("");
3242
3504
  console.log(memory.content);
3243
3505
  if (opts.links) {
@@ -3245,52 +3507,52 @@ var showCommand = new Command23("show").description("Show a memory with its link
3245
3507
  const linked = await getLinkedMemories(id);
3246
3508
  if (linked.length > 0) {
3247
3509
  console.log("");
3248
- console.log(chalk21.bold("Linked Memories:"));
3510
+ console.log(chalk22.bold("Linked Memories:"));
3249
3511
  for (const { memory: m, linkType, direction } of linked) {
3250
3512
  const mIcon = TYPE_ICONS5[m.type] || "\u{1F4DD}";
3251
3513
  const arrow = direction === "to" ? "\u2192" : "\u2190";
3252
3514
  const preview = m.content.length > 50 ? m.content.slice(0, 47) + "..." : m.content;
3253
- console.log(` ${arrow} ${chalk21.cyan(linkType)}: ${mIcon} ${preview}`);
3515
+ console.log(` ${arrow} ${chalk22.cyan(linkType)}: ${mIcon} ${preview}`);
3254
3516
  }
3255
3517
  }
3256
3518
  }
3257
3519
  console.log("");
3258
3520
  } catch (error2) {
3259
- console.error(chalk21.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3521
+ console.error(chalk22.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3260
3522
  process.exit(1);
3261
3523
  }
3262
3524
  });
3263
3525
 
3264
3526
  // src/commands/template.ts
3265
3527
  import { Command as Command24 } from "commander";
3266
- import chalk22 from "chalk";
3528
+ import chalk23 from "chalk";
3267
3529
  var templateCommand = new Command24("template").description("Manage and use memory templates");
3268
3530
  templateCommand.command("list").description("List available templates").action(() => {
3269
3531
  const templates = listTemplates();
3270
- console.log(chalk22.bold("\nAvailable Templates:\n"));
3532
+ console.log(chalk23.bold("\nAvailable Templates:\n"));
3271
3533
  for (const t of templates) {
3272
3534
  const typeIcon = t.type === "rule" ? "\u{1F4CC}" : t.type === "decision" ? "\u{1F4A1}" : t.type === "fact" ? "\u{1F4CB}" : "\u{1F4DD}";
3273
- console.log(` ${chalk22.cyan(t.name.padEnd(15))} ${typeIcon} ${t.description}`);
3535
+ console.log(` ${chalk23.cyan(t.name.padEnd(15))} ${typeIcon} ${t.description}`);
3274
3536
  }
3275
3537
  console.log("");
3276
- console.log(chalk22.dim("Use: memories template use <name>"));
3538
+ console.log(chalk23.dim("Use: memories template use <name>"));
3277
3539
  console.log("");
3278
3540
  });
3279
3541
  templateCommand.command("show <name>").description("Show template details and fields").action((name) => {
3280
3542
  const template = getTemplate(name);
3281
3543
  if (!template) {
3282
- console.error(chalk22.red("\u2717") + ` Template "${name}" not found`);
3283
- console.log(chalk22.dim("Run 'memories template list' to see available templates"));
3544
+ console.error(chalk23.red("\u2717") + ` Template "${name}" not found`);
3545
+ console.log(chalk23.dim("Run 'memories template list' to see available templates"));
3284
3546
  process.exit(1);
3285
3547
  }
3286
3548
  const typeIcon = template.type === "rule" ? "\u{1F4CC}" : template.type === "decision" ? "\u{1F4A1}" : template.type === "fact" ? "\u{1F4CB}" : "\u{1F4DD}";
3287
3549
  console.log("");
3288
- console.log(chalk22.bold(template.name) + ` ${typeIcon} ${template.type}`);
3289
- console.log(chalk22.dim(template.description));
3550
+ console.log(chalk23.bold(template.name) + ` ${typeIcon} ${template.type}`);
3551
+ console.log(chalk23.dim(template.description));
3290
3552
  console.log("");
3291
- console.log(chalk22.bold("Fields:"));
3553
+ console.log(chalk23.bold("Fields:"));
3292
3554
  for (const field of template.fields) {
3293
- const required = field.required ? chalk22.red("*") : chalk22.dim("(optional)");
3555
+ const required = field.required ? chalk23.red("*") : chalk23.dim("(optional)");
3294
3556
  console.log(` ${field.name.padEnd(15)} ${required} ${field.prompt}`);
3295
3557
  }
3296
3558
  console.log("");
@@ -3298,13 +3560,13 @@ templateCommand.command("show <name>").description("Show template details and fi
3298
3560
  templateCommand.command("use <name>").description("Create a memory using a template").option("-g, --global", "Store as global memory").action(async (name, opts) => {
3299
3561
  const template = getTemplate(name);
3300
3562
  if (!template) {
3301
- console.error(chalk22.red("\u2717") + ` Template "${name}" not found`);
3302
- console.log(chalk22.dim("Run 'memories template list' to see available templates"));
3563
+ console.error(chalk23.red("\u2717") + ` Template "${name}" not found`);
3564
+ console.log(chalk23.dim("Run 'memories template list' to see available templates"));
3303
3565
  process.exit(1);
3304
3566
  }
3305
3567
  console.log("");
3306
- console.log(chalk22.bold(`Using template: ${template.name}`));
3307
- console.log(chalk22.dim(template.description));
3568
+ console.log(chalk23.bold(`Using template: ${template.name}`));
3569
+ console.log(chalk23.dim(template.description));
3308
3570
  console.log("");
3309
3571
  try {
3310
3572
  const content = await fillTemplate(template);
@@ -3313,8 +3575,8 @@ templateCommand.command("use <name>").description("Create a memory using a templ
3313
3575
  global: opts.global
3314
3576
  });
3315
3577
  console.log("");
3316
- console.log(chalk22.green("\u2713") + ` Created ${template.type}: ${chalk22.dim(memory.id)}`);
3317
- console.log(chalk22.dim(` "${content}"`));
3578
+ console.log(chalk23.green("\u2713") + ` Created ${template.type}: ${chalk23.dim(memory.id)}`);
3579
+ console.log(chalk23.dim(` "${content}"`));
3318
3580
  } catch (error2) {
3319
3581
  if (error2.message?.includes("User force closed")) {
3320
3582
  console.log("\nCancelled.");
@@ -3326,7 +3588,7 @@ templateCommand.command("use <name>").description("Create a memory using a templ
3326
3588
 
3327
3589
  // src/commands/history.ts
3328
3590
  import { Command as Command25 } from "commander";
3329
- import chalk23 from "chalk";
3591
+ import chalk24 from "chalk";
3330
3592
  var TYPE_ICONS6 = {
3331
3593
  rule: "\u{1F4CC}",
3332
3594
  decision: "\u{1F4A1}",
@@ -3375,38 +3637,38 @@ var historyCommand = new Command25("history").description("View version history
3375
3637
  return;
3376
3638
  }
3377
3639
  if (!memory && history.length === 0) {
3378
- console.error(chalk23.red("\u2717") + ` Memory ${id} not found`);
3640
+ console.error(chalk24.red("\u2717") + ` Memory ${id} not found`);
3379
3641
  process.exit(1);
3380
3642
  }
3381
3643
  const icon = memory ? TYPE_ICONS6[memory.type] || "\u{1F4DD}" : "\u{1F4DD}";
3382
3644
  console.log("");
3383
3645
  if (memory) {
3384
- console.log(`${icon} ${chalk23.bold(memory.content)}`);
3385
- console.log(chalk23.dim(`ID: ${id}`));
3646
+ console.log(`${icon} ${chalk24.bold(memory.content)}`);
3647
+ console.log(chalk24.dim(`ID: ${id}`));
3386
3648
  } else {
3387
- console.log(chalk23.dim(`Memory ${id} (deleted)`));
3649
+ console.log(chalk24.dim(`Memory ${id} (deleted)`));
3388
3650
  }
3389
3651
  console.log("");
3390
3652
  if (history.length === 0) {
3391
- console.log(chalk23.dim("No version history recorded."));
3392
- console.log(chalk23.dim("History is recorded when memories are updated."));
3653
+ console.log(chalk24.dim("No version history recorded."));
3654
+ console.log(chalk24.dim("History is recorded when memories are updated."));
3393
3655
  return;
3394
3656
  }
3395
- console.log(chalk23.bold("History:"));
3396
- console.log(chalk23.dim("\u2500".repeat(60)));
3657
+ console.log(chalk24.bold("History:"));
3658
+ console.log(chalk24.dim("\u2500".repeat(60)));
3397
3659
  for (const entry of history) {
3398
3660
  const changeIcon = entry.change_type === "created" ? "+" : entry.change_type === "updated" ? "~" : "-";
3399
- const changeColor = entry.change_type === "created" ? chalk23.green : entry.change_type === "updated" ? chalk23.yellow : chalk23.red;
3661
+ const changeColor = entry.change_type === "created" ? chalk24.green : entry.change_type === "updated" ? chalk24.yellow : chalk24.red;
3400
3662
  const date = new Date(entry.changed_at).toLocaleDateString();
3401
3663
  const time = new Date(entry.changed_at).toLocaleTimeString();
3402
- console.log(` ${changeColor(changeIcon)} v${entry.version} ${chalk23.dim(date + " " + time)}`);
3664
+ console.log(` ${changeColor(changeIcon)} v${entry.version} ${chalk24.dim(date + " " + time)}`);
3403
3665
  console.log(` "${entry.content.slice(0, 60)}${entry.content.length > 60 ? "..." : ""}"`);
3404
3666
  }
3405
- console.log(chalk23.dim("\u2500".repeat(60)));
3406
- console.log(chalk23.dim(`
3667
+ console.log(chalk24.dim("\u2500".repeat(60)));
3668
+ console.log(chalk24.dim(`
3407
3669
  Use 'memories revert ${id} --to <version>' to restore a previous version`));
3408
3670
  } catch (error2) {
3409
- console.error(chalk23.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3671
+ console.error(chalk24.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3410
3672
  process.exit(1);
3411
3673
  }
3412
3674
  });
@@ -3416,7 +3678,7 @@ var revertCommand = new Command25("revert").description("Revert a memory to a pr
3416
3678
  const db = await getDb();
3417
3679
  const version = parseInt(opts.to.replace("v", ""), 10);
3418
3680
  if (isNaN(version) || version < 1) {
3419
- console.error(chalk23.red("\u2717") + " Invalid version number");
3681
+ console.error(chalk24.red("\u2717") + " Invalid version number");
3420
3682
  process.exit(1);
3421
3683
  }
3422
3684
  const result = await db.execute({
@@ -3428,7 +3690,7 @@ var revertCommand = new Command25("revert").description("Revert a memory to a pr
3428
3690
  const history = result.rows;
3429
3691
  const targetEntry = history.find((h) => h.version === version);
3430
3692
  if (!targetEntry) {
3431
- console.error(chalk23.red("\u2717") + ` Version ${version} not found for memory ${id}`);
3693
+ console.error(chalk24.red("\u2717") + ` Version ${version} not found for memory ${id}`);
3432
3694
  process.exit(1);
3433
3695
  }
3434
3696
  const current = await getMemoryById(id);
@@ -3440,20 +3702,20 @@ var revertCommand = new Command25("revert").description("Revert a memory to a pr
3440
3702
  tags: targetEntry.tags ? targetEntry.tags.split(",") : void 0
3441
3703
  });
3442
3704
  if (!updated) {
3443
- console.error(chalk23.red("\u2717") + ` Failed to revert memory ${id}`);
3705
+ console.error(chalk24.red("\u2717") + ` Failed to revert memory ${id}`);
3444
3706
  process.exit(1);
3445
3707
  }
3446
- console.log(chalk23.green("\u2713") + ` Reverted memory ${chalk23.dim(id)} to version ${version}`);
3447
- console.log(chalk23.dim(` "${targetEntry.content.slice(0, 60)}${targetEntry.content.length > 60 ? "..." : ""}"`));
3708
+ console.log(chalk24.green("\u2713") + ` Reverted memory ${chalk24.dim(id)} to version ${version}`);
3709
+ console.log(chalk24.dim(` "${targetEntry.content.slice(0, 60)}${targetEntry.content.length > 60 ? "..." : ""}"`));
3448
3710
  } catch (error2) {
3449
- console.error(chalk23.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3711
+ console.error(chalk24.red("\u2717") + " Failed:", error2 instanceof Error ? error2.message : "Unknown error");
3450
3712
  process.exit(1);
3451
3713
  }
3452
3714
  });
3453
3715
 
3454
3716
  // src/commands/embed.ts
3455
3717
  import { Command as Command26 } from "commander";
3456
- import chalk24 from "chalk";
3718
+ import chalk25 from "chalk";
3457
3719
  import ora2 from "ora";
3458
3720
  var embedCommand = new Command26("embed").description("Generate embeddings for memories (enables semantic search)").option("--all", "Re-embed all memories, even those with existing embeddings").option("--dry-run", "Show what would be embedded without doing it").action(async (opts) => {
3459
3721
  try {
@@ -3466,24 +3728,24 @@ var embedCommand = new Command26("embed").description("Generate embeddings for m
3466
3728
  const result = await db.execute(sql);
3467
3729
  const memories = result.rows;
3468
3730
  if (memories.length === 0) {
3469
- console.log(chalk24.green("\u2713") + " All memories already have embeddings.");
3731
+ console.log(chalk25.green("\u2713") + " All memories already have embeddings.");
3470
3732
  return;
3471
3733
  }
3472
3734
  if (opts.dryRun) {
3473
- console.log(chalk24.bold(`Would embed ${memories.length} memories:
3735
+ console.log(chalk25.bold(`Would embed ${memories.length} memories:
3474
3736
  `));
3475
3737
  for (const m of memories.slice(0, 10)) {
3476
3738
  const preview = m.content.length > 60 ? m.content.slice(0, 57) + "..." : m.content;
3477
- console.log(` ${chalk24.dim(m.id)} ${preview}`);
3739
+ console.log(` ${chalk25.dim(m.id)} ${preview}`);
3478
3740
  }
3479
3741
  if (memories.length > 10) {
3480
- console.log(chalk24.dim(` ... and ${memories.length - 10} more`));
3742
+ console.log(chalk25.dim(` ... and ${memories.length - 10} more`));
3481
3743
  }
3482
3744
  return;
3483
3745
  }
3484
- console.log(chalk24.bold(`Embedding ${memories.length} memories...
3746
+ console.log(chalk25.bold(`Embedding ${memories.length} memories...
3485
3747
  `));
3486
- console.log(chalk24.dim("First run downloads the model (~30MB). Subsequent runs are faster.\n"));
3748
+ console.log(chalk25.dim("First run downloads the model (~30MB). Subsequent runs are faster.\n"));
3487
3749
  const spinner = ora2("Loading embedding model...").start();
3488
3750
  let embedded = 0;
3489
3751
  let failed = 0;
@@ -3498,22 +3760,22 @@ var embedCommand = new Command26("embed").description("Generate embeddings for m
3498
3760
  }
3499
3761
  }
3500
3762
  spinner.stop();
3501
- console.log(chalk24.green("\u2713") + ` Embedded ${embedded} memories`);
3763
+ console.log(chalk25.green("\u2713") + ` Embedded ${embedded} memories`);
3502
3764
  if (failed > 0) {
3503
- console.log(chalk24.yellow("\u26A0") + ` ${failed} memories failed to embed`);
3765
+ console.log(chalk25.yellow("\u26A0") + ` ${failed} memories failed to embed`);
3504
3766
  }
3505
3767
  console.log("");
3506
- console.log(chalk24.dim("Now you can use semantic search:"));
3507
- console.log(chalk24.cyan(' memories search --semantic "your query"'));
3768
+ console.log(chalk25.dim("Now you can use semantic search:"));
3769
+ console.log(chalk25.cyan(' memories search --semantic "your query"'));
3508
3770
  } catch (error2) {
3509
- console.error(chalk24.red("\u2717") + " Embedding failed:", error2 instanceof Error ? error2.message : "Unknown error");
3771
+ console.error(chalk25.red("\u2717") + " Embedding failed:", error2 instanceof Error ? error2.message : "Unknown error");
3510
3772
  process.exit(1);
3511
3773
  }
3512
3774
  });
3513
3775
 
3514
3776
  // src/commands/login.ts
3515
3777
  import { Command as Command27 } from "commander";
3516
- import chalk25 from "chalk";
3778
+ import chalk26 from "chalk";
3517
3779
  import ora3 from "ora";
3518
3780
  import { randomBytes } from "crypto";
3519
3781
  import { execFile } from "child_process";
@@ -3528,18 +3790,18 @@ var loginCommand = new Command27("login").description("Log in to memories.sh to
3528
3790
  banner();
3529
3791
  const existing = await readAuth();
3530
3792
  if (existing) {
3531
- warn(`Already logged in as ${chalk25.bold(existing.email)}`);
3532
- dim(`Run ${chalk25.cyan("memories logout")} to sign out first.`);
3793
+ warn(`Already logged in as ${chalk26.bold(existing.email)}`);
3794
+ dim(`Run ${chalk26.cyan("memories logout")} to sign out first.`);
3533
3795
  return;
3534
3796
  }
3535
3797
  box(
3536
- chalk25.bold("Pro features include:\n\n") + chalk25.dim("\u2192 ") + "Cloud sync & backup\n" + chalk25.dim("\u2192 ") + "Cross-device access\n" + chalk25.dim("\u2192 ") + "Web dashboard\n" + chalk25.dim("\u2192 ") + "Priority support",
3798
+ chalk26.bold("Pro features include:\n\n") + chalk26.dim("\u2192 ") + "Cloud sync & backup\n" + chalk26.dim("\u2192 ") + "Cross-device access\n" + chalk26.dim("\u2192 ") + "Web dashboard\n" + chalk26.dim("\u2192 ") + "Priority support",
3537
3799
  "Upgrade to Pro"
3538
3800
  );
3539
3801
  const code = randomBytes(16).toString("hex");
3540
3802
  const authUrl = `${opts.apiUrl}/app/auth/cli?code=${code}`;
3541
- console.log(chalk25.bold("Open this URL in your browser:\n"));
3542
- console.log(` ${chalk25.cyan(authUrl)}
3803
+ console.log(chalk26.bold("Open this URL in your browser:\n"));
3804
+ console.log(` ${chalk26.cyan(authUrl)}
3543
3805
  `);
3544
3806
  try {
3545
3807
  openBrowser(authUrl);
@@ -3569,11 +3831,11 @@ var loginCommand = new Command27("login").description("Log in to memories.sh to
3569
3831
  });
3570
3832
  spinner.stop();
3571
3833
  console.log("");
3572
- success(`Logged in as ${chalk25.bold(data.email)}`);
3834
+ success(`Logged in as ${chalk26.bold(data.email)}`);
3573
3835
  dim("Your cloud database has been provisioned automatically.");
3574
3836
  nextSteps([
3575
- `${chalk25.cyan("memories sync")} ${chalk25.dim("to sync your memories")}`,
3576
- `${chalk25.cyan("memories.sh/app")} ${chalk25.dim("to view your dashboard")}`
3837
+ `${chalk26.cyan("memories sync")} ${chalk26.dim("to sync your memories")}`,
3838
+ `${chalk26.cyan("memories.sh/app")} ${chalk26.dim("to view your dashboard")}`
3577
3839
  ]);
3578
3840
  return;
3579
3841
  }
@@ -3601,77 +3863,112 @@ var logoutCommand = new Command27("logout").description("Log out of memories.sh"
3601
3863
 
3602
3864
  // src/commands/files.ts
3603
3865
  import { Command as Command28 } from "commander";
3604
- import chalk26 from "chalk";
3866
+ import chalk27 from "chalk";
3605
3867
  import ora4 from "ora";
3606
3868
  import { nanoid as nanoid4 } from "nanoid";
3607
3869
  import { createHash } from "crypto";
3608
- import { readFile as readFile8, writeFile as writeFile6, mkdir as mkdir4, readdir } from "fs/promises";
3609
- import { existsSync as existsSync9 } from "fs";
3610
- import { join as join8, dirname as dirname2 } from "path";
3611
- import { homedir as homedir4 } from "os";
3870
+ import { readFile as readFile9, writeFile as writeFile7, mkdir as mkdir5, readdir, stat } from "fs/promises";
3871
+ import { existsSync as existsSync10 } from "fs";
3872
+ import { join as join9, dirname as dirname3 } from "path";
3873
+ import { homedir as homedir5 } from "os";
3612
3874
  function hashContent(content) {
3613
3875
  return createHash("sha256").update(content).digest("hex").slice(0, 16);
3614
3876
  }
3615
- var CONFIG_DIRS = [
3616
- { dir: ".agents", name: "Agents" },
3617
- { dir: ".claude", name: "Claude" },
3618
- { dir: ".cursor", name: "Cursor" },
3619
- { dir: ".github/copilot", name: "Copilot" },
3620
- { dir: ".windsurf", name: "Windsurf" },
3621
- { dir: ".cline", name: "Cline" },
3622
- { dir: ".codex", name: "Codex" },
3623
- { dir: ".gemini", name: "Gemini" },
3624
- { dir: ".roo", name: "Roo" },
3625
- { dir: ".amp", name: "Amp" }
3877
+ var SYNC_TARGETS = [
3878
+ // .agents - Agent instruction files, commands, tasks, and skills
3879
+ { dir: ".agents", files: ["AGENTS.md"] },
3880
+ { dir: ".agents/commands", pattern: /\.md$/ },
3881
+ { dir: ".agents/tasks", pattern: /\.(md|txt)$/ },
3882
+ { dir: ".agents/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3883
+ // .claude - Claude Code instructions, commands, rules, hooks, and tasks
3884
+ { dir: ".claude", files: ["CLAUDE.md", "settings.json", "settings.local.json"] },
3885
+ { dir: ".claude/commands", pattern: /\.md$/ },
3886
+ { dir: ".claude/rules", pattern: /\.(md|rules)$/ },
3887
+ { dir: ".claude/hooks", pattern: /\.(json|sh)$/ },
3888
+ { dir: ".claude/tasks", pattern: /\.(md|txt)$/ },
3889
+ { dir: ".claude/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3890
+ // .cursor - Cursor rules and MCP config
3891
+ { dir: ".cursor", files: ["mcp.json", "rules.md"] },
3892
+ { dir: ".cursor/rules", pattern: /\.(md|mdc|txt)$/ },
3893
+ { dir: ".cursor/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3894
+ // .codex - Codex config, rules, and tasks
3895
+ { dir: ".codex", files: ["config.toml", "AGENTS.md", "instructions.md"] },
3896
+ { dir: ".codex/rules", pattern: /\.(md|rules)$/ },
3897
+ { dir: ".codex/tasks", pattern: /\.(md|txt)$/ },
3898
+ { dir: ".codex/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3899
+ // .windsurf - Windsurf rules
3900
+ { dir: ".windsurf", files: ["rules.md", "cascade.json"] },
3901
+ { dir: ".windsurf/rules", pattern: /\.(md|txt)$/ },
3902
+ { dir: ".windsurf/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3903
+ // .cline - Cline rules
3904
+ { dir: ".cline", files: ["rules.md", "CLINE.md", "cline_rules.md"] },
3905
+ { dir: ".cline/rules", pattern: /\.(md|txt)$/ },
3906
+ { dir: ".cline/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3907
+ // .github/copilot - Copilot instructions
3908
+ { dir: ".github/copilot", files: ["instructions.md"] },
3909
+ // .gemini - Gemini instructions
3910
+ { dir: ".gemini", files: ["GEMINI.md", "settings.json"] },
3911
+ { dir: ".gemini/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3912
+ // .roo - Roo config and rules
3913
+ { dir: ".roo", files: ["config.json", "rules.md"] },
3914
+ { dir: ".roo/rules", pattern: /\.(md|txt)$/ },
3915
+ { dir: ".roo/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3916
+ // .amp - Amp rules
3917
+ { dir: ".amp", files: ["AGENTS.md", "rules.md"] },
3918
+ { dir: ".amp/rules", pattern: /\.(md|txt)$/ },
3919
+ { dir: ".amp/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3920
+ // .opencode - OpenCode instructions
3921
+ { dir: ".opencode", files: ["instructions.md"] },
3922
+ { dir: ".opencode/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true },
3923
+ // .factory - Factory/Droid config
3924
+ { dir: ".factory", files: ["config.json", "instructions.md"] },
3925
+ { dir: ".factory/droids", pattern: /\.(md|yaml|yml)$/ },
3926
+ { dir: ".factory/tasks", pattern: /\.(md|txt)$/ },
3927
+ { dir: ".factory/skills", pattern: /\.(md|json|yaml|yml|toml|txt)$/, recurse: true }
3626
3928
  ];
3627
- var INCLUDE_PATTERNS = [
3628
- /\.md$/,
3629
- /\.txt$/,
3630
- /\.json$/,
3631
- /\.yaml$/,
3632
- /\.yml$/,
3633
- /\.toml$/,
3634
- /rules$/,
3635
- /config$/
3636
- ];
3637
- var EXCLUDE_PATTERNS = [
3638
- /node_modules/,
3639
- /\.git\//,
3640
- /\.DS_Store/,
3641
- /\.log$/,
3642
- /cache/i,
3643
- /history/i,
3644
- /session/i,
3645
- /debug/i,
3646
- /\.lock$/,
3647
- /stats-cache/,
3648
- /telemetry/,
3649
- /todos/
3650
- ];
3651
- function shouldIncludeFile(filePath) {
3652
- for (const pattern of EXCLUDE_PATTERNS) {
3653
- if (pattern.test(filePath)) return false;
3654
- }
3655
- for (const pattern of INCLUDE_PATTERNS) {
3656
- if (pattern.test(filePath)) return true;
3929
+ async function scanTarget(baseDir, target, relativeTo = "") {
3930
+ const results = [];
3931
+ const targetDir = join9(baseDir, target.dir);
3932
+ if (!existsSync10(targetDir)) return results;
3933
+ const source = target.dir.split("/")[0].replace(/^\./, "").replace(/^(.)/, (_, c) => c.toUpperCase());
3934
+ if (target.files) {
3935
+ for (const file of target.files) {
3936
+ const fullPath = join9(targetDir, file);
3937
+ if (existsSync10(fullPath)) {
3938
+ const stats = await stat(fullPath);
3939
+ if (stats.isFile()) {
3940
+ results.push({
3941
+ path: join9(target.dir, file),
3942
+ fullPath,
3943
+ source
3944
+ });
3945
+ }
3946
+ }
3947
+ }
3948
+ return results;
3657
3949
  }
3658
- return false;
3659
- }
3660
- async function scanDirectory(dir, basePath = "") {
3661
- const files = [];
3662
- if (!existsSync9(dir)) return files;
3663
- const entries = await readdir(dir, { withFileTypes: true });
3950
+ if (!target.pattern) return results;
3951
+ const entries = await readdir(targetDir, { withFileTypes: true });
3664
3952
  for (const entry of entries) {
3665
- const fullPath = join8(dir, entry.name);
3666
- const relativePath = basePath ? join8(basePath, entry.name) : entry.name;
3667
- if (entry.isDirectory()) {
3668
- const subFiles = await scanDirectory(fullPath, relativePath);
3669
- files.push(...subFiles);
3670
- } else if (entry.isFile() && shouldIncludeFile(relativePath)) {
3671
- files.push({ path: relativePath, fullPath });
3953
+ const fullPath = join9(targetDir, entry.name);
3954
+ const relativePath = join9(target.dir, entry.name);
3955
+ if (entry.isDirectory() && target.recurse) {
3956
+ const subTarget = { dir: relativePath, pattern: target.pattern, recurse: true };
3957
+ const subResults = await scanTarget(baseDir, subTarget, relativeTo);
3958
+ results.push(...subResults);
3959
+ } else if (entry.isFile() && target.pattern.test(entry.name)) {
3960
+ results.push({ path: relativePath, fullPath, source });
3672
3961
  }
3673
3962
  }
3674
- return files;
3963
+ return results;
3964
+ }
3965
+ async function scanAllTargets(baseDir) {
3966
+ const results = [];
3967
+ for (const target of SYNC_TARGETS) {
3968
+ const targetResults = await scanTarget(baseDir, target);
3969
+ results.push(...targetResults);
3970
+ }
3971
+ return results;
3675
3972
  }
3676
3973
  var filesCommand = new Command28("files").description("Manage synced config files (.agents, .cursor, .claude, etc.)");
3677
3974
  filesCommand.command("list").alias("ls").description("List synced files").option("-s, --scope <scope>", "Filter by scope (global or project path)").action(async (opts) => {
@@ -3686,8 +3983,8 @@ filesCommand.command("list").alias("ls").description("List synced files").option
3686
3983
  const result = await db.execute({ sql, args });
3687
3984
  const files = result.rows;
3688
3985
  if (files.length === 0) {
3689
- console.log(chalk26.dim("No synced files yet."));
3690
- console.log(chalk26.dim(`Run ${chalk26.cyan("memories files ingest")} to import config files.`));
3986
+ console.log(chalk27.dim("No synced files yet."));
3987
+ console.log(chalk27.dim(`Run ${chalk27.cyan("memories files ingest")} to import config files.`));
3691
3988
  return;
3692
3989
  }
3693
3990
  const byScope = /* @__PURE__ */ new Map();
@@ -3697,61 +3994,51 @@ filesCommand.command("list").alias("ls").description("List synced files").option
3697
3994
  byScope.get(scope).push(file);
3698
3995
  }
3699
3996
  for (const [scope, scopeFiles] of byScope) {
3700
- const scopeLabel = scope === "global" ? chalk26.blue("Global") : chalk26.yellow(scope.replace("github.com/", ""));
3997
+ const scopeLabel = scope === "global" ? chalk27.blue("Global") : chalk27.yellow(scope.replace("github.com/", ""));
3701
3998
  console.log(`
3702
- ${scopeLabel} ${chalk26.dim(`(${scopeFiles.length} files)`)}`);
3703
- console.log(chalk26.dim("\u2500".repeat(50)));
3999
+ ${scopeLabel} ${chalk27.dim(`(${scopeFiles.length} files)`)}`);
4000
+ console.log(chalk27.dim("\u2500".repeat(50)));
3704
4001
  for (const file of scopeFiles) {
3705
- const source = file.source ? chalk26.dim(` [${file.source}]`) : "";
3706
- console.log(` ${chalk26.white(file.path)}${source}`);
4002
+ const source = file.source ? chalk27.dim(` [${file.source}]`) : "";
4003
+ console.log(` ${chalk27.white(file.path)}${source}`);
3707
4004
  }
3708
4005
  }
3709
4006
  console.log();
3710
4007
  });
3711
4008
  filesCommand.command("ingest").description("Import files from .agents, .cursor, .claude and other config directories").option("-g, --global", "Ingest global configs from home directory", true).option("-p, --project", "Ingest project configs from current directory").option("--dry-run", "Show what would be imported without making changes").action(async (opts) => {
3712
4009
  const db = await getDb();
3713
- const home = homedir4();
4010
+ const home = homedir5();
3714
4011
  const cwd = process.cwd();
3715
4012
  const filesToIngest = [];
3716
4013
  if (opts.global !== false) {
3717
- for (const { dir, name } of CONFIG_DIRS) {
3718
- const globalDir = join8(home, dir);
3719
- const files = await scanDirectory(globalDir);
3720
- for (const file of files) {
3721
- filesToIngest.push({
3722
- path: join8(dir, file.path),
3723
- fullPath: file.fullPath,
3724
- scope: "global",
3725
- source: name
3726
- });
3727
- }
4014
+ const files = await scanAllTargets(home);
4015
+ for (const file of files) {
4016
+ filesToIngest.push({
4017
+ ...file,
4018
+ scope: "global"
4019
+ });
3728
4020
  }
3729
4021
  }
3730
4022
  if (opts.project) {
3731
- for (const { dir, name } of CONFIG_DIRS) {
3732
- const projectDir = join8(cwd, dir);
3733
- const files = await scanDirectory(projectDir);
3734
- for (const file of files) {
3735
- filesToIngest.push({
3736
- path: join8(dir, file.path),
3737
- fullPath: file.fullPath,
3738
- scope: "project",
3739
- // Will be resolved to git remote
3740
- source: name
3741
- });
3742
- }
4023
+ const files = await scanAllTargets(cwd);
4024
+ for (const file of files) {
4025
+ filesToIngest.push({
4026
+ ...file,
4027
+ scope: "project"
4028
+ // Will be resolved to git remote
4029
+ });
3743
4030
  }
3744
4031
  }
3745
4032
  if (filesToIngest.length === 0) {
3746
- console.log(chalk26.dim("No config files found to import."));
4033
+ console.log(chalk27.dim("No config files found to import."));
3747
4034
  return;
3748
4035
  }
3749
4036
  if (opts.dryRun) {
3750
- console.log(chalk26.bold(`Would import ${filesToIngest.length} files:
4037
+ console.log(chalk27.bold(`Would import ${filesToIngest.length} files:
3751
4038
  `));
3752
4039
  for (const file of filesToIngest) {
3753
- const scopeLabel = file.scope === "global" ? chalk26.blue("G") : chalk26.yellow("P");
3754
- console.log(` ${scopeLabel} ${file.path} ${chalk26.dim(`[${file.source}]`)}`);
4040
+ const scopeLabel = file.scope === "global" ? chalk27.blue("G") : chalk27.yellow("P");
4041
+ console.log(` ${scopeLabel} ${file.path} ${chalk27.dim(`[${file.source}]`)}`);
3755
4042
  }
3756
4043
  return;
3757
4044
  }
@@ -3761,7 +4048,7 @@ filesCommand.command("ingest").description("Import files from .agents, .cursor,
3761
4048
  let skipped = 0;
3762
4049
  for (const file of filesToIngest) {
3763
4050
  try {
3764
- const content = await readFile8(file.fullPath, "utf-8");
4051
+ const content = await readFile9(file.fullPath, "utf-8");
3765
4052
  const hash = hashContent(content);
3766
4053
  const existing = await db.execute({
3767
4054
  sql: "SELECT id, hash FROM files WHERE path = ? AND scope = ? AND deleted_at IS NULL",
@@ -3798,7 +4085,7 @@ filesCommand.command("ingest").description("Import files from .agents, .cursor,
3798
4085
  });
3799
4086
  filesCommand.command("apply").description("Write synced files to disk (restore from cloud)").option("-g, --global", "Apply global files to home directory").option("-p, --project", "Apply project files to current directory").option("--dry-run", "Show what would be written without making changes").option("-f, --force", "Overwrite existing files without prompting").action(async (opts) => {
3800
4087
  const db = await getDb();
3801
- const home = homedir4();
4088
+ const home = homedir5();
3802
4089
  const cwd = process.cwd();
3803
4090
  let sql = "SELECT id, path, content, scope, source FROM files WHERE deleted_at IS NULL";
3804
4091
  const args = [];
@@ -3810,17 +4097,17 @@ filesCommand.command("apply").description("Write synced files to disk (restore f
3810
4097
  const result = await db.execute({ sql, args });
3811
4098
  const files = result.rows;
3812
4099
  if (files.length === 0) {
3813
- console.log(chalk26.dim("No files to apply."));
4100
+ console.log(chalk27.dim("No files to apply."));
3814
4101
  return;
3815
4102
  }
3816
4103
  if (opts.dryRun) {
3817
- console.log(chalk26.bold(`Would write ${files.length} files:
4104
+ console.log(chalk27.bold(`Would write ${files.length} files:
3818
4105
  `));
3819
4106
  for (const file of files) {
3820
4107
  const baseDir = file.scope === "global" ? home : cwd;
3821
- const targetPath = join8(baseDir, file.path);
3822
- const exists = existsSync9(targetPath);
3823
- const status = exists ? chalk26.yellow("(overwrite)") : chalk26.green("(new)");
4108
+ const targetPath = join9(baseDir, file.path);
4109
+ const exists = existsSync10(targetPath);
4110
+ const status = exists ? chalk27.yellow("(overwrite)") : chalk27.green("(new)");
3824
4111
  console.log(` ${targetPath} ${status}`);
3825
4112
  }
3826
4113
  return;
@@ -3830,9 +4117,9 @@ filesCommand.command("apply").description("Write synced files to disk (restore f
3830
4117
  let skippedExisting = 0;
3831
4118
  for (const file of files) {
3832
4119
  const baseDir = file.scope === "global" ? home : cwd;
3833
- const targetPath = join8(baseDir, file.path);
3834
- if (existsSync9(targetPath) && !opts.force) {
3835
- const existingContent = await readFile8(targetPath, "utf-8");
4120
+ const targetPath = join9(baseDir, file.path);
4121
+ if (existsSync10(targetPath) && !opts.force) {
4122
+ const existingContent = await readFile9(targetPath, "utf-8");
3836
4123
  const existingHash = hashContent(existingContent);
3837
4124
  const newHash = hashContent(file.content);
3838
4125
  if (existingHash !== newHash) {
@@ -3840,8 +4127,8 @@ filesCommand.command("apply").description("Write synced files to disk (restore f
3840
4127
  continue;
3841
4128
  }
3842
4129
  }
3843
- await mkdir4(dirname2(targetPath), { recursive: true });
3844
- await writeFile6(targetPath, file.content, "utf-8");
4130
+ await mkdir5(dirname3(targetPath), { recursive: true });
4131
+ await writeFile7(targetPath, file.content, "utf-8");
3845
4132
  written++;
3846
4133
  }
3847
4134
  if (skippedExisting > 0) {
@@ -3857,14 +4144,14 @@ filesCommand.command("show <path>").description("Show content of a synced file")
3857
4144
  args: [path]
3858
4145
  });
3859
4146
  if (result.rows.length === 0) {
3860
- console.log(chalk26.red(`File not found: ${path}`));
4147
+ console.log(chalk27.red(`File not found: ${path}`));
3861
4148
  return;
3862
4149
  }
3863
4150
  const file = result.rows[0];
3864
- console.log(chalk26.dim(`# ${path}`));
3865
- console.log(chalk26.dim(`# Scope: ${file.scope} | Source: ${file.source || "unknown"}`));
3866
- console.log(chalk26.dim(`# Updated: ${file.updated_at}`));
3867
- console.log(chalk26.dim("\u2500".repeat(50)));
4151
+ console.log(chalk27.dim(`# ${path}`));
4152
+ console.log(chalk27.dim(`# Scope: ${file.scope} | Source: ${file.source || "unknown"}`));
4153
+ console.log(chalk27.dim(`# Updated: ${file.updated_at}`));
4154
+ console.log(chalk27.dim("\u2500".repeat(50)));
3868
4155
  console.log(file.content);
3869
4156
  });
3870
4157
  filesCommand.command("forget <path>").description("Remove a file from sync (soft delete)").action(async (path) => {
@@ -3874,14 +4161,14 @@ filesCommand.command("forget <path>").description("Remove a file from sync (soft
3874
4161
  args: [path]
3875
4162
  });
3876
4163
  if (result.rowsAffected === 0) {
3877
- console.log(chalk26.red(`File not found: ${path}`));
4164
+ console.log(chalk27.red(`File not found: ${path}`));
3878
4165
  return;
3879
4166
  }
3880
4167
  const sync = await readSyncConfig();
3881
4168
  if (sync) {
3882
4169
  await syncDb();
3883
4170
  }
3884
- console.log(chalk26.green(`\u2713 Removed ${path} from sync`));
4171
+ console.log(chalk27.green(`\u2713 Removed ${path} from sync`));
3885
4172
  });
3886
4173
 
3887
4174
  // src/index.ts