memorix 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -372,6 +372,258 @@ var init_orama_store = __esm({
372
372
  }
373
373
  });
374
374
 
375
+ // src/hooks/installers/index.ts
376
+ var installers_exports = {};
377
+ __export(installers_exports, {
378
+ detectInstalledAgents: () => detectInstalledAgents,
379
+ getHookStatus: () => getHookStatus,
380
+ installHooks: () => installHooks,
381
+ uninstallHooks: () => uninstallHooks
382
+ });
383
+ import * as fs3 from "fs/promises";
384
+ import * as path5 from "path";
385
+ import * as os2 from "os";
386
+ function generateClaudeConfig() {
387
+ const hookEntry = {
388
+ type: "command",
389
+ command: `${HOOK_COMMAND} ${HOOK_ARGS.join(" ")}`,
390
+ timeout: 10
391
+ };
392
+ return {
393
+ hooks: {
394
+ SessionStart: [hookEntry],
395
+ PostToolUse: [hookEntry],
396
+ UserPromptSubmit: [hookEntry],
397
+ PreCompact: [hookEntry],
398
+ Stop: [hookEntry]
399
+ }
400
+ };
401
+ }
402
+ function generateWindsurfConfig() {
403
+ const hookEntry = {
404
+ command: `${HOOK_COMMAND} ${HOOK_ARGS.join(" ")}`,
405
+ timeout: 10
406
+ };
407
+ return {
408
+ hooks: {
409
+ post_write_code: [hookEntry],
410
+ post_run_command: [hookEntry],
411
+ post_mcp_tool_use: [hookEntry],
412
+ pre_user_prompt: [hookEntry],
413
+ post_cascade_response: [hookEntry]
414
+ }
415
+ };
416
+ }
417
+ function generateCursorConfig() {
418
+ return {
419
+ hooks: {
420
+ beforeSubmitPrompt: {
421
+ command: `${HOOK_COMMAND} ${HOOK_ARGS.join(" ")}`
422
+ },
423
+ afterFileEdit: {
424
+ command: `${HOOK_COMMAND} ${HOOK_ARGS.join(" ")}`
425
+ },
426
+ stop: {
427
+ command: `${HOOK_COMMAND} ${HOOK_ARGS.join(" ")}`
428
+ }
429
+ }
430
+ };
431
+ }
432
+ function generateKiroHookFile() {
433
+ return `---
434
+ title: Memorix Auto-Memory
435
+ description: Automatically record development context for cross-agent memory sharing
436
+ event: file_saved
437
+ filePattern: "**/*"
438
+ ---
439
+
440
+ Run the memorix hook command to analyze changes and store relevant memories:
441
+
442
+ \`\`\`bash
443
+ memorix hook
444
+ \`\`\`
445
+ `;
446
+ }
447
+ function getProjectConfigPath(agent, projectRoot) {
448
+ switch (agent) {
449
+ case "claude":
450
+ case "copilot":
451
+ return path5.join(projectRoot, ".github", "hooks", "memorix.json");
452
+ case "windsurf":
453
+ return path5.join(projectRoot, ".windsurf", "hooks.json");
454
+ case "cursor":
455
+ return path5.join(projectRoot, ".cursor", "hooks.json");
456
+ case "kiro":
457
+ return path5.join(projectRoot, ".kiro", "hooks", "memorix.hook.md");
458
+ case "codex":
459
+ return path5.join(projectRoot, ".codex", "hooks.json");
460
+ default:
461
+ return path5.join(projectRoot, ".memorix", "hooks.json");
462
+ }
463
+ }
464
+ function getGlobalConfigPath(agent) {
465
+ const home = os2.homedir();
466
+ switch (agent) {
467
+ case "claude":
468
+ case "copilot":
469
+ return path5.join(home, ".claude", "settings.json");
470
+ case "windsurf":
471
+ return path5.join(home, ".codeium", "windsurf", "hooks.json");
472
+ case "cursor":
473
+ return path5.join(home, ".cursor", "hooks.json");
474
+ default:
475
+ return path5.join(home, ".memorix", "hooks.json");
476
+ }
477
+ }
478
+ async function detectInstalledAgents() {
479
+ const agents = [];
480
+ const home = os2.homedir();
481
+ const claudeDir = path5.join(home, ".claude");
482
+ try {
483
+ await fs3.access(claudeDir);
484
+ agents.push("claude");
485
+ } catch {
486
+ }
487
+ const windsurfDir = path5.join(home, ".codeium", "windsurf");
488
+ try {
489
+ await fs3.access(windsurfDir);
490
+ agents.push("windsurf");
491
+ } catch {
492
+ }
493
+ const cursorDir = path5.join(home, ".cursor");
494
+ try {
495
+ await fs3.access(cursorDir);
496
+ agents.push("cursor");
497
+ } catch {
498
+ }
499
+ if (!agents.includes("claude")) {
500
+ const vscodeDir = path5.join(home, ".vscode");
501
+ try {
502
+ await fs3.access(vscodeDir);
503
+ agents.push("copilot");
504
+ } catch {
505
+ }
506
+ }
507
+ const kiroConfig = path5.join(home, ".kiro");
508
+ try {
509
+ await fs3.access(kiroConfig);
510
+ agents.push("kiro");
511
+ } catch {
512
+ }
513
+ return agents;
514
+ }
515
+ async function installHooks(agent, projectRoot, global = false) {
516
+ const configPath = global ? getGlobalConfigPath(agent) : getProjectConfigPath(agent, projectRoot);
517
+ let generated;
518
+ switch (agent) {
519
+ case "claude":
520
+ case "copilot":
521
+ generated = generateClaudeConfig();
522
+ break;
523
+ case "windsurf":
524
+ generated = generateWindsurfConfig();
525
+ break;
526
+ case "cursor":
527
+ generated = generateCursorConfig();
528
+ break;
529
+ case "kiro":
530
+ generated = generateKiroHookFile();
531
+ break;
532
+ default:
533
+ generated = generateClaudeConfig();
534
+ }
535
+ await fs3.mkdir(path5.dirname(configPath), { recursive: true });
536
+ if (agent === "kiro") {
537
+ await fs3.writeFile(configPath, generated, "utf-8");
538
+ } else {
539
+ let existing = {};
540
+ try {
541
+ const content = await fs3.readFile(configPath, "utf-8");
542
+ existing = JSON.parse(content);
543
+ } catch {
544
+ }
545
+ const merged = {
546
+ ...existing,
547
+ ...generated
548
+ };
549
+ await fs3.writeFile(configPath, JSON.stringify(merged, null, 2), "utf-8");
550
+ }
551
+ const events = [];
552
+ switch (agent) {
553
+ case "claude":
554
+ case "copilot":
555
+ events.push("session_start", "post_tool", "user_prompt", "pre_compact", "session_end");
556
+ break;
557
+ case "windsurf":
558
+ events.push("post_edit", "post_command", "post_tool", "user_prompt", "post_response");
559
+ break;
560
+ case "cursor":
561
+ events.push("user_prompt", "post_edit", "session_end");
562
+ break;
563
+ case "kiro":
564
+ events.push("post_edit");
565
+ break;
566
+ }
567
+ return {
568
+ agent,
569
+ configPath,
570
+ events,
571
+ generated: typeof generated === "string" ? { content: generated } : generated
572
+ };
573
+ }
574
+ async function uninstallHooks(agent, projectRoot, global = false) {
575
+ const configPath = global ? getGlobalConfigPath(agent) : getProjectConfigPath(agent, projectRoot);
576
+ try {
577
+ if (agent === "kiro") {
578
+ await fs3.unlink(configPath);
579
+ } else {
580
+ const content = await fs3.readFile(configPath, "utf-8");
581
+ const config = JSON.parse(content);
582
+ delete config.hooks;
583
+ if (Object.keys(config).length === 0) {
584
+ await fs3.unlink(configPath);
585
+ } else {
586
+ await fs3.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
587
+ }
588
+ }
589
+ return true;
590
+ } catch {
591
+ return false;
592
+ }
593
+ }
594
+ async function getHookStatus(projectRoot) {
595
+ const results = [];
596
+ const agents = ["claude", "copilot", "windsurf", "cursor", "kiro", "codex"];
597
+ for (const agent of agents) {
598
+ const projectPath = getProjectConfigPath(agent, projectRoot);
599
+ const globalPath = getGlobalConfigPath(agent);
600
+ let installed = false;
601
+ let usedPath = projectPath;
602
+ try {
603
+ await fs3.access(projectPath);
604
+ installed = true;
605
+ } catch {
606
+ try {
607
+ await fs3.access(globalPath);
608
+ installed = true;
609
+ usedPath = globalPath;
610
+ } catch {
611
+ }
612
+ }
613
+ results.push({ agent, installed, configPath: usedPath });
614
+ }
615
+ return results;
616
+ }
617
+ var HOOK_COMMAND, HOOK_ARGS;
618
+ var init_installers = __esm({
619
+ "src/hooks/installers/index.ts"() {
620
+ "use strict";
621
+ init_esm_shims();
622
+ HOOK_COMMAND = "memorix";
623
+ HOOK_ARGS = ["hook"];
624
+ }
625
+ });
626
+
375
627
  // src/memory/retention.ts
376
628
  var retention_exports = {};
377
629
  __export(retention_exports, {
@@ -917,6 +1169,9 @@ async function reindexObservations() {
917
1169
  return count2;
918
1170
  }
919
1171
 
1172
+ // src/server.ts
1173
+ init_orama_store();
1174
+
920
1175
  // src/memory/auto-relations.ts
921
1176
  init_esm_shims();
922
1177
  function inferRelationType(obs) {
@@ -2215,10 +2470,10 @@ var WorkspaceSyncEngine = class {
2215
2470
  for (const [target, adapter] of this.adapters) {
2216
2471
  const configPath = adapter.getConfigPath(this.projectRoot);
2217
2472
  const globalPath = adapter.getConfigPath();
2218
- for (const path5 of [configPath, globalPath]) {
2219
- if (existsSync3(path5)) {
2473
+ for (const path6 of [configPath, globalPath]) {
2474
+ if (existsSync3(path6)) {
2220
2475
  try {
2221
- const content = readFileSync(path5, "utf-8");
2476
+ const content = readFileSync(path6, "utf-8");
2222
2477
  const servers = adapter.parse(content);
2223
2478
  if (servers.length > 0) {
2224
2479
  mcpConfigs[target] = servers;
@@ -2385,6 +2640,23 @@ async function createMemorixServer(cwd) {
2385
2640
  }
2386
2641
  console.error(`[memorix] Project: ${project.id} (${project.name})`);
2387
2642
  console.error(`[memorix] Data dir: ${projectDir2}`);
2643
+ try {
2644
+ const { getHookStatus: getHookStatus2, installHooks: installHooks2, detectInstalledAgents: detectInstalledAgents2 } = await Promise.resolve().then(() => (init_installers(), installers_exports));
2645
+ const workDir = cwd ?? process.cwd();
2646
+ const statuses = await getHookStatus2(workDir);
2647
+ const anyInstalled = statuses.some((s) => s.installed);
2648
+ if (!anyInstalled) {
2649
+ const agents = await detectInstalledAgents2();
2650
+ for (const agent of agents) {
2651
+ try {
2652
+ const config = await installHooks2(agent, workDir);
2653
+ console.error(`[memorix] Auto-installed hooks for ${agent} \u2192 ${config.configPath}`);
2654
+ } catch {
2655
+ }
2656
+ }
2657
+ }
2658
+ } catch {
2659
+ }
2388
2660
  const observationsFile = projectDir2 + "/observations.json";
2389
2661
  let reloadDebounce = null;
2390
2662
  try {
@@ -2392,6 +2664,7 @@ async function createMemorixServer(cwd) {
2392
2664
  if (reloadDebounce) clearTimeout(reloadDebounce);
2393
2665
  reloadDebounce = setTimeout(async () => {
2394
2666
  try {
2667
+ await resetDb();
2395
2668
  await initObservations(projectDir2);
2396
2669
  const count2 = await reindexObservations();
2397
2670
  if (count2 > 0) {