memorix 0.3.0 → 0.3.2

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
@@ -283,11 +283,14 @@ async function getObservationsByIds(ids, projectId) {
283
283
  }
284
284
  async function getTimeline(anchorId, projectId, depthBefore = 3, depthAfter = 3) {
285
285
  const database = await getDb();
286
- const allResults = await search(database, {
286
+ const searchParams = {
287
287
  term: "",
288
- where: { projectId },
289
288
  limit: 1e3
290
- });
289
+ };
290
+ if (projectId) {
291
+ searchParams.where = { projectId };
292
+ }
293
+ const allResults = await search(database, searchParams);
291
294
  const docs = allResults.hits.map((h) => h.document).sort((a, b) => a.createdAt.localeCompare(b.createdAt));
292
295
  const anchorIndex = docs.findIndex((d) => d.observationId === anchorId);
293
296
  if (anchorIndex === -1) {
@@ -2598,8 +2601,8 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2598
2601
  rulesCount = rules.length;
2599
2602
  } catch {
2600
2603
  }
2601
- const skills = this.scanSkills();
2602
- return { mcpConfigs, workflows, rulesCount, skills };
2604
+ const { skills, conflicts: skillConflicts } = this.scanSkills();
2605
+ return { mcpConfigs, workflows, rulesCount, skills, skillConflicts };
2603
2606
  }
2604
2607
  /**
2605
2608
  * Migrate workspace configs to a target agent format.
@@ -2610,7 +2613,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2610
2613
  mcpServers: { scanned: [], generated: [] },
2611
2614
  workflows: { scanned: [], generated: [] },
2612
2615
  rules: { scanned: 0, generated: 0 },
2613
- skills: { scanned: [], copied: [] }
2616
+ skills: { scanned: [], conflicts: [], copied: [], skipped: [] }
2614
2617
  };
2615
2618
  const allServers = /* @__PURE__ */ new Map();
2616
2619
  for (const servers of Object.values(scan.mcpConfigs)) {
@@ -2648,6 +2651,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2648
2651
  } catch {
2649
2652
  }
2650
2653
  result.skills.scanned = scan.skills;
2654
+ result.skills.conflicts = scan.skillConflicts;
2651
2655
  return result;
2652
2656
  }
2653
2657
  // ---- Private helpers ----
@@ -2668,7 +2672,8 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2668
2672
  */
2669
2673
  scanSkills() {
2670
2674
  const skills = [];
2671
- const seen = /* @__PURE__ */ new Set();
2675
+ const conflicts = [];
2676
+ const seen = /* @__PURE__ */ new Map();
2672
2677
  const home = homedir5();
2673
2678
  for (const [agent, dirs] of Object.entries(_WorkspaceSyncEngine.SKILLS_DIRS)) {
2674
2679
  for (const dir of dirs) {
@@ -2682,7 +2687,6 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2682
2687
  const entries = readdirSync(skillsRoot, { withFileTypes: true });
2683
2688
  for (const entry of entries) {
2684
2689
  if (!entry.isDirectory()) continue;
2685
- if (seen.has(entry.name)) continue;
2686
2690
  const skillMd = join6(skillsRoot, entry.name, "SKILL.md");
2687
2691
  if (!existsSync3(skillMd)) continue;
2688
2692
  let description = "";
@@ -2692,20 +2696,32 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2692
2696
  if (match) description = match[1];
2693
2697
  } catch {
2694
2698
  }
2695
- seen.add(entry.name);
2696
- skills.push({
2699
+ const newEntry = {
2697
2700
  name: entry.name,
2698
2701
  description,
2699
2702
  sourcePath: join6(skillsRoot, entry.name),
2700
2703
  sourceAgent: agent
2701
- });
2704
+ };
2705
+ const existing = seen.get(entry.name);
2706
+ if (existing) {
2707
+ if (existing.sourceAgent !== agent) {
2708
+ conflicts.push({
2709
+ name: entry.name,
2710
+ kept: existing,
2711
+ skipped: newEntry
2712
+ });
2713
+ }
2714
+ continue;
2715
+ }
2716
+ seen.set(entry.name, newEntry);
2717
+ skills.push(newEntry);
2702
2718
  }
2703
2719
  } catch {
2704
2720
  }
2705
2721
  }
2706
2722
  }
2707
2723
  }
2708
- return skills;
2724
+ return { skills, conflicts };
2709
2725
  }
2710
2726
  /**
2711
2727
  * Copy skills to a target agent's skills directory.
@@ -2714,9 +2730,14 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2714
2730
  copySkills(skills, target) {
2715
2731
  const targetDir = this.getTargetSkillsDir(target);
2716
2732
  const copied = [];
2733
+ const skipped = [];
2717
2734
  for (const skill of skills) {
2735
+ if (skill.sourceAgent === target) continue;
2718
2736
  const dest = join6(targetDir, skill.name);
2719
- if (existsSync3(dest)) continue;
2737
+ if (existsSync3(dest)) {
2738
+ skipped.push(`${skill.name} (already exists in ${target})`);
2739
+ continue;
2740
+ }
2720
2741
  try {
2721
2742
  mkdirSync2(targetDir, { recursive: true });
2722
2743
  cpSync(skill.sourcePath, dest, { recursive: true });
@@ -2724,7 +2745,7 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2724
2745
  } catch {
2725
2746
  }
2726
2747
  }
2727
- return copied;
2748
+ return { copied, skipped };
2728
2749
  }
2729
2750
  scanWorkflows() {
2730
2751
  const workflows = [];
@@ -2760,9 +2781,9 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2760
2781
  ...syncResult.workflows.generated
2761
2782
  ];
2762
2783
  const applyResult = await applier.apply(filesToWrite);
2763
- let copiedSkills = [];
2784
+ let skillResult = { copied: [], skipped: [] };
2764
2785
  if (syncResult.skills.scanned.length > 0) {
2765
- copiedSkills = this.copySkills(syncResult.skills.scanned, target);
2786
+ skillResult = this.copySkills(syncResult.skills.scanned, target);
2766
2787
  }
2767
2788
  const lines = [];
2768
2789
  if (applyResult.success) {
@@ -2770,13 +2791,27 @@ var WorkspaceSyncEngine = class _WorkspaceSyncEngine {
2770
2791
  for (const f of applyResult.filesWritten) {
2771
2792
  lines.push(` \u2192 ${f}`);
2772
2793
  }
2773
- if (copiedSkills.length > 0) {
2794
+ if (skillResult.copied.length > 0) {
2774
2795
  lines.push(`
2775
- \u{1F9E9} Copied ${copiedSkills.length} skill(s):`);
2776
- for (const sk of copiedSkills) {
2796
+ \u{1F9E9} Copied ${skillResult.copied.length} skill(s):`);
2797
+ for (const sk of skillResult.copied) {
2777
2798
  lines.push(` \u2192 ${sk}`);
2778
2799
  }
2779
2800
  }
2801
+ if (skillResult.skipped.length > 0) {
2802
+ lines.push(`
2803
+ \u23ED\uFE0F Skipped ${skillResult.skipped.length} skill(s):`);
2804
+ for (const sk of skillResult.skipped) {
2805
+ lines.push(` \u2192 ${sk}`);
2806
+ }
2807
+ }
2808
+ if (syncResult.skills.conflicts.length > 0) {
2809
+ lines.push(`
2810
+ \u26A0\uFE0F Name conflicts (${syncResult.skills.conflicts.length}):`);
2811
+ for (const c of syncResult.skills.conflicts) {
2812
+ lines.push(` \u2192 "${c.name}": kept ${c.kept.sourceAgent}, skipped ${c.skipped.sourceAgent}`);
2813
+ }
2814
+ }
2780
2815
  if (applyResult.backups.length > 0) {
2781
2816
  lines.push(`
2782
2817
  \u{1F4E6} Backups created (${applyResult.backups.length}):`);
@@ -3331,6 +3366,12 @@ Entity: ${entityName} | Type: ${type} | Project: ${project.id}${enrichment}`
3331
3366
  } else {
3332
3367
  lines2.push("- No skills found");
3333
3368
  }
3369
+ if (scan.skillConflicts.length > 0) {
3370
+ lines2.push("", `### \u26A0\uFE0F Skill Name Conflicts`);
3371
+ for (const c of scan.skillConflicts) {
3372
+ lines2.push(`- **${c.name}**: kept from ${c.kept.sourceAgent}, duplicate in ${c.skipped.sourceAgent}`);
3373
+ }
3374
+ }
3334
3375
  return {
3335
3376
  content: [{ type: "text", text: lines2.join("\n") }]
3336
3377
  };